我正在学习OpenGL,正在使用Qt 5.12。我目前需要绘制一个立方体和一个带有三角形的金字塔。
我认为顶点类和三角形结构都不错,但是不幸的是,并非所有三角形都正确显示。我对OpenGL还是很陌生,所以我可能在VBO / VAO绑定部分中缺少某些内容,但是我不知道是什么。
我创建了一个myVertex类,该类具有6个浮点数:3个表示位置,3个表示颜色:
class myVertex{
public:
GLfloat _x;
GLfloat _y;
GLfloat _z;
GLfloat _r;
GLfloat _g;
GLfloat _b;
myVertex(GLfloat x, GLfloat y, GLfloat z, GLfloat r, GLfloat g, GLfloat b){
_x=x;
_y=y;
_z=z;
_r=r;
_g=g;
_b=b;
}
};
然后我定义了三角形的结构:
struct triangle {
myVertex a;
myVertex b;
myVertex c;
};
在MainView :: initializeGL()中,我定义每个顶点的3D颜色和位置,然后构建三角形:
// Cube
myVertex CUBE_LEFT_FRONT_DOWN = myVertex(-1.0f,-1.0f,-1.0f,1.0f,0.0f,0.0f);
myVertex CUBE_RIGHT_FRONT_DOWN = myVertex( 1.0f,-1.0f,-1.0f,0.0f,1.0f,0.0f);
myVertex CUBE_LEFT_BACK_DOWN = myVertex(-1.0f, 1.0f,-1.0f,0.0f,0.0f,1.0f);
myVertex CUBE_RIGHT_BACK_DOWN = myVertex( 1.0f, 1.0f,-1.0f,1.0f,1.0f,0.0f);
myVertex CUBE_LEFT_FRONT_UP = myVertex(-1.0f,-1.0f, 1.0f,1.0f,0.0f,1.0f);
myVertex CUBE_RIGHT_FRONT_UP = myVertex( 1.0f,-1.0f, 1.0f,0.0f,1.0f,1.0f);
myVertex CUBE_LEFT_BACK_UP = myVertex(-1.0f, 1.0f, 1.0f,0.2f,0.5f,0.7f);
myVertex CUBE_RIGHT_BACK_UP = myVertex( 1.0f, 1.0f, 1.0f,0.7f,0.2f,0.5f);
// Every face is made of 2 triangles
triangle left1 = {CUBE_LEFT_BACK_DOWN, CUBE_LEFT_FRONT_DOWN, CUBE_LEFT_BACK_UP};
triangle left2 = {CUBE_LEFT_FRONT_UP, CUBE_LEFT_FRONT_DOWN, CUBE_LEFT_BACK_UP};
triangle right1 = {CUBE_RIGHT_BACK_DOWN, CUBE_RIGHT_BACK_UP, CUBE_RIGHT_FRONT_DOWN};
triangle right2 = {CUBE_RIGHT_FRONT_UP, CUBE_RIGHT_BACK_UP, CUBE_RIGHT_FRONT_DOWN};
triangle back1 = {CUBE_LEFT_BACK_DOWN, CUBE_RIGHT_BACK_DOWN, CUBE_LEFT_BACK_UP};
triangle back2 = {CUBE_RIGHT_BACK_UP, CUBE_RIGHT_BACK_DOWN, CUBE_LEFT_BACK_UP};
triangle front1 = {CUBE_LEFT_FRONT_DOWN, CUBE_RIGHT_FRONT_DOWN, CUBE_LEFT_FRONT_UP};
triangle front2 = {CUBE_RIGHT_FRONT_UP, CUBE_RIGHT_FRONT_DOWN, CUBE_LEFT_FRONT_UP};
triangle down1 = {CUBE_LEFT_FRONT_DOWN, CUBE_RIGHT_FRONT_DOWN, CUBE_LEFT_BACK_DOWN};
triangle down2 = {CUBE_RIGHT_BACK_DOWN, CUBE_RIGHT_FRONT_DOWN, CUBE_LEFT_BACK_DOWN};
triangle up1 = {CUBE_RIGHT_BACK_UP, CUBE_RIGHT_FRONT_UP, CUBE_LEFT_BACK_UP};
triangle up2 = {CUBE_LEFT_FRONT_UP, CUBE_RIGHT_FRONT_UP, CUBE_LEFT_BACK_UP};
triangle cube[] = {left1, left2, right1, right2, back1, back2, front1, front2, down1, down2, up1, up2};
// Pyramid
myVertex PYR_LEFT_FRONT = myVertex(-1.0f,-1.0f,-1.0f,0.0f,1.0f,0.0f);
myVertex PYR_RIGHT_FRONT = myVertex( 1.0f,-1.0f,-1.0f,0.0f,0.0f,1.0f);
myVertex PYR_LEFT_BACK = myVertex(-1.0f, 1.0f,-1.0f,1.0f,0.0f,0.0f);
myVertex PYR_RIGHT_BACK = myVertex( 1.0f, 1.0f,-1.0f,0.5f,0.8f,0.0f);
myVertex PYR_TOP = myVertex( 0.0f, 0.0f, 1.0f,0.3f,0.1f,0.4f);
// Base need 2 triangles
triangle leftside = {PYR_LEFT_FRONT, PYR_LEFT_BACK, PYR_TOP};
triangle rightside = {PYR_RIGHT_FRONT, PYR_RIGHT_BACK, PYR_TOP};
triangle frontside = {PYR_LEFT_FRONT, PYR_RIGHT_FRONT, PYR_TOP};
triangle backside = {PYR_LEFT_BACK, PYR_RIGHT_BACK, PYR_TOP};
triangle base1 = {PYR_LEFT_FRONT, PYR_LEFT_BACK, PYR_RIGHT_FRONT};
triangle base2 = {PYR_RIGHT_BACK, PYR_LEFT_BACK, PYR_RIGHT_FRONT};
triangle pyramid[] = {leftside, rightside, frontside, backside, base1, base2};
现在,我定义VBO和VAO,启用属性等:
GLuint cubeVBO;
GLuint cubeVAO;
GLuint pyrVBO;
GLuint pyrVAO;
glGenBuffers(1, &cubeVBO);
glGenVertexArrays(1, &cubeVAO);
glBindVertexArray(cubeVAO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW);
glGenBuffers(1, &pyrVBO);
glGenVertexArrays(1, &pyrVAO);
glBindVertexArray(pyrVAO);
glBindBuffer(GL_ARRAY_BUFFER, pyrVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(pyramid), pyramid, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)(3*sizeof(GLfloat)));
最后我画到屏幕上
MainView::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shaderProgram.bind();
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glDrawArrays(GL_TRIANGLES,0,36);
glBindBuffer(GL_ARRAY_BUFFER, pyrVBO);
glDrawArrays(GL_TRIANGLES,0,18);
shaderProgram.release();
}
我希望看到这样的数字: Expected
但是现在我看到了: My result
我多次检查了代码,但我不明白出了什么问题。
答案 0 :(得分:0)
如果绑定了一个非零命名数组缓冲区对象,则glVertexAttribPointer
的最后一个参数将被视为缓冲区对象数据存储区中的字节偏移。
通用顶点属性数据的定义和所引用缓冲区的名称在Vertex Array Object的状态向量中不正确。
在定义通用顶点属性数据的数组之前,必须通过调用glVertexAttribPointer
来绑定顶点规范对象(应将顶点规范存储到该顶点对象)。正确的缓冲对象也必须被绑定:
// vertex array buffer for cube
GLuint cubeVBO;
glGenBuffers(1, &cubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube), cube, GL_STATIC_DRAW);
// vertex array buffer for pyramid
GLuint pyrVBO;
glGenBuffers(1, &pyrVBO);
glBindBuffer(GL_ARRAY_BUFFER, pyrVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(pyramid), pyramid, GL_STATIC_DRAW);
// vertex array object for cube
GLuint cubeVAO;
glGenVertexArrays(1, &cubeVAO);
glBindVertexArray(cubeVAO);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)(3*sizeof(GLfloat)));
// vertex array object for pyramid
GLuint pyrVAO;
glGenVertexArrays(1, &pyrVAO);
glBindVertexArray(pyrVAO);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, pyrVBO);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)0);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,sizeof(myVertex),(void *)(3*sizeof(GLfloat)));