【问题标题】:Vertex positions appearing incorrectly when applying a stride to glVertexAttribPointer将步幅应用于 glVertexAttribPointer 时顶点位置显示不正确
【发布时间】:2017-01-14 01:44:28
【问题描述】:

我遇到了顶点被绘制到屏幕外的问题。我将所有顶点属性指针的步幅更改为 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 坐标。因此,我认为数据如下所示:

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

【问题讨论】:

    标签: c++ opengl


    【解决方案1】:

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

    但这不是你告诉 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。它不存储 verts 的 4 个浮点数,然后是 color 的 4 个浮点数,然后是 tex 的 4 个浮点数。

    glBufferSubData 无法为您交错数据(好吧,您可以通过一长串调用来完成,但这太荒谬了)。如果要上传交错的顶点数据,必须在 CPU 上交错,然后再上传。

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

    【讨论】:

    • 是的,我没有意识到由于某种原因更改为 subBuffer 并没有交错数据。所以现在我做 sizeof(verts) 然后 sizeof(verts) + sizeof(color) 为我的偏移量.. . 谢谢!
    【解决方案2】:

    您正在以块的形式上传顶点数据:

    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>...
    

    在上传时交错数据或调整您的 glVertexAttribPointer() 调用以考虑块布局。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-29
      • 2016-09-08
      • 2021-02-02
      • 1970-01-01
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多