画一个立方体和金字塔
Draw a cube and a pyramid
我正在学习OpenGL,并且正在使用QT 5.12。我目前需要画一个带有三角形的金字塔。
我认为顶点类和三角形结构很好,但不幸的是,并非所有三角形都正确显示。我仍然是OpenGL的新手,所以我可能在VBO/VAO绑定部分中缺少一些东西,但我不知道什么。
我已经创建了一个带有6个浮子的Mervertex类: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();
}
我希望看到这样的数字:预期
但是现在我看到了:我的结果
我多次审查了代码,但我不明白出了什么问题。
如果命名的非零数组缓冲区对象是绑定的,则glVertexAttribPointer
的最后一个参数被视为字节偏移到缓冲区的数据存储中。
通用顶点属性数据的定义和引用的缓冲区的名称在顶点数组对象状态向量中。
通过glVertexAttribPointer
的调用定义了通用顶点属性数据的数组,即Vertex数组对象的呼叫,该对象应将其存储到其中,必须绑定到顶点规范。适当的缓冲对象也必须绑定:
// 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)));
相关文章:
- 如何使用 std::累积在 C++ 中计算总和立方体
- 如何有效地计算将单位立方体映射到自身的反射和旋转?
- 如何使用采样器立方体作为数组
- OpenGL,为什么这不是一个立方体?
- 在具有 MPI 的超立方体中广播
- C++星纹金字塔
- 我想通过OpenGL创建3D金字塔
- Opengl 和 c++ 绘制多个立方体
- 现代OpenGL纹理金字塔
- C++没有标准功能的立方体根查找器
- 3D金字塔与OPENGL
- 现代OpenGL:如何获得立方体的矢量位置
- 使用此网格函数的立方体的正确顶点和索引是什么
- 为什么在GLFW窗口中没有用这个代码在我的屏幕上绘制立方体
- OpenGL中立方体的位置
- 对我的 c++ 金字塔分配进行小调整?我应该怎么做?
- 有没有办法用单行逻辑代码打印金字塔星形图案?面试官向我的朋友问了这个问题
- 在犰狳立方体中添加一列 1 的有效方法
- 使用犰狳时无法加载犰狳立方体<uword>
- 画一个立方体和金字塔