将步幅应用于glVertexAttribPointer时,顶点位置显示不正确

时间:2017-01-13 17:05:39

标签: c++ opengl

我遇到了一个问题,我的顶点是在屏幕外绘制的。我将所有顶点属性指针的步幅更改为0,现在它们在正确的位置绘制。

以下是一些启动此功能的代码:

glGenVertexArrays(1, &vertexID);
glBindVertexArray(vertexID);

glGenBuffers(1, &bufferID);
glBindBuffer(GL_ARRAY_BUFFER, bufferID);


GLfloat verts[4 * 2 * 3] = { -0.5, -0.5, 0.0, 1.0,// bottom left
                        .5, -.5, 0.0, 1.0,    // bottom right
                        -.5, .5, 0.0, 1.0,    // top left
                        0.5, 0.5, 0.0, 1.0,
                        .5, -.5, 0.0, 1.0,    // bottom right
                        -.5, .5, 0.0, 1.0,    // top left// top right
                        };
GLfloat color[4 * 3 * 2] = {
    1.0f, 1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f, 1.0f };

GLfloat tex[8] = {
1.0f, 1.0f, 
1.0f, 0.0f,
0.0f, 0.0f,
0.0f, 1.0f
};

glBufferData(GL_ARRAY_BUFFER, sizeof(verts) + sizeof(color) + sizeof(tex), nullptr, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts), sizeof(color), color);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts) + sizeof(color), sizeof(tex), tex);


glClearColor(0.05f, 0.05f, 0.05f, 1.0f);







glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, NULL);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, (const GLvoid *)(sizeof(GLfloat) * 4));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, (const GLvoid *)(sizeof(GLfloat) * 8));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);


glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

GLuint indices[4] = {
    0,2,1,3
};
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);

然后是渲染代码

   glClear(GL_COLOR_BUFFER_BIT);

glBindTexture(GL_TEXTURE_2D, texture);

glBindVertexArray(vertexID);

glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
//glDrawArrays(GL_TRIANGLES, 0, 6);
glFlush();

SDL_GL_SwapWindow(window);

好的,这就是我感到困惑的地方:

glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, NULL);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, (const GLvoid *)(sizeof(GLfloat) * 4));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 10, (const GLvoid *)(sizeof(GLfloat) * 8));

使用上面的代码,程序不会渲染我正在尝试渲染的正确方块。如果我将所有这些步幅更改为0,那么它将呈现在正确的位置。我对它的理解是我子缓冲了3组信息:位置,颜色和tex坐标。因此我认为数据如下所示: enter image description here

我将步幅设置为sizeof(GLFloat)* 10,但是,这不起作用。这使我假设我也没有正确设置偏移值。 那么为什么我的步伐会弄乱顶点位置?

2 个答案:

答案 0 :(得分:2)

您正在以块为单位上传顶点数据:

Build:Cannot find module './src/directive_wrapper_compiler'.           
\node_modules\@angular\compiler\index.d.ts  45  

所以最终结果如下:

glBufferData(GL_ARRAY_BUFFER, sizeof(verts) + sizeof(color) + sizeof(tex), nullptr, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts), sizeof(color), color);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts) + sizeof(color), sizeof(tex), tex);

但是你的<vert 0, ... vert N><color 0, ..., color N><tex 0, ..., tex N> 调用声称缓冲区是这样交错的:

glVertexAttribPointer()

在上传时交错数据或调整<vert 0><color 0><tex 0><vert 1><color1><tex 1>... 来电,以考虑块布局。

答案 1 :(得分:2)

  

因此我认为数据如下所示:

但那不是你告诉OpenGL的。

glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts);

这告诉OpenGL获取数组verts并将其复制到缓冲区对象的开头。

glBufferSubData(GL_ARRAY_BUFFER, sizeof(verts), sizeof(color), color);

这告诉OpengL获取数组color,并将其复制到缓冲区对象中,但在所有verts 之后。

这里没有交错。您缓存存储所有verts,然后存储所有color,然后存储所有tex。它不存储4个verts个浮点数,后跟4个color个浮点数,然后存储4个tex个浮点数。

glBufferSubData无法为您交错数据(嗯,您可以通过一系列长时间的通话来完成,但这很荒谬)。如果你想上传交错的顶点数据,必须在CPU上交错它,然后上传它。

将步幅设置为0并不能使这项工作成功。好吧,它没有使它正确。相对于您实际上传的数据,您的基本偏移量仍然是错误的。您将获得正确的位置数据,但颜色和纹理坐标将是错误的。