glDrawArrays意外行为 - 错误的参数顺序产生所需的图像

时间:2017-10-26 09:19:37

标签: c++ opengl

我正在处理其他人编写的代码,目前我对代码库的理解相当有限。这就是为什么我不确定如何正确地表达我的问题,以及它是OpenGL问题还是调试策略问题。此外,我显然不能真正分享整个代码库,并且原因不起作用的原因很可能根植于那里。无论如何,也许有人可能会知道可能会发生什么,或者我应该在哪里看。

我有一个以下列方式定义的顶点结构:

struct Vertex {
    Vertex(glm::vec3 position, glm::vec3 normal):
        _position(position), _normal(normal) {};
    glm::vec3 _position;
    glm::vec3 _normal;
};

我有一个std矢量顶点,我用从某个结构中提取的顶点数据填充。为简单起见,我们假设它是另一个向量:

// std::vector<Vertex> data - contains vertex data
std::vector<Vertex> Vertices;    
Vertices.reserve(data.size()); 
for (int i = 0; i < data.size(); i++) {
    Vertices.emplace_back(Vertex(data[i]._position, data[i]._normal));
}

然后我生成一个顶点缓冲区对象,缓冲我的数据并启用顶点属性:

GLuint VB;
glGenBuffers(1, &VB);
glBindBuffer(GL_ARRAY_BUFFER, VB);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*Vertices.size(), &Vertices[0], 
             GL_DYNAMIC_DRAW);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3,GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(1, 3,GL_FLOAT, GL_FALSE, sizeof(Vertex), (const void*)
                     (sizeof(GL_FLOAT)*3));

最后,我绑定一个着色器并设置制服,然后我调用glDrawArrays

glDrawArrays(GL_TRIANGLES, 0, Vertices.size());
// clean-up
// swap buffers (comes at some point in code, I haven't figure out where yet)

此时不会渲染任何内容。但是,最初我犯了一个错误并交换了绘制调用的参数,这样偏移就在绘制的元素数量之前:

glDrawArrays(GL_TRIANGLES, Vertices.size(), 0);

令人惊讶的是,这实际上首先呈现了我想渲染的内容。但是,documentation明确表示首先是偏移量,然后是元素数量。这意味着glDrawArrays(GL_TRIANGLES, Vertices.size(), 0)应该没有显示任何内容,因为我指定要绘制的元素数为“零”。

现在应用程序和共享顶点缓冲区对象中有多个窗口。在某些时候,我认为我生成的顶点缓冲区对象以某种方式在我尚未探索的代码部分中传递,并使用它来绘制我不希望绘制的几何体。然而,这仍然无法解释当我使用glDrawArrays(GL_TRIANGLES, Vertices.size(), 0)和'零'作为要绘制的元素的数量时 - 我看到了几何;而当我根据文档交换参数时 - 没有显示任何内容。

鉴于我分享的这些稀缺信息,是否有人有机会了解可能发生的事情?如果没有,您将如何解决这个问题,您将如何调试(或理解)它?

编辑:顶点和片段着色器

请注意,这是一个虚拟着色器,只是简单地将整个几何体绘制成红色。无论如何,着色器不是我问题的原因,因为几何绘制取决于我如何使用绘制调用(见上文)。

编辑编辑:请注意,只要我不激活混合,alpha组件(着色器中为“零”)就不会对生成的图像产生任何影响。

顶点着色器:

#version 440
layout (location=0) in vec3 position;
layout (location=1) in vec3 normal;

uniform mat4 MVP; // model-view-projection matrix 

void main() {
    gl_Position = MVP*vec4(position, 1.0);    
}

片段着色器:

#version 440
out vec4 outColor;

void main()
{
    outColor = vec4(1, 0, 0, 0);
})glsl";

1 个答案:

答案 0 :(得分:1)

关于glDrawArrays参数反转,您是否尝试过进入该函数调用?也许您正在使用某种类型的OpenGL包装器来修改顺序或参数。但我可以确认您引用的文档对参数顺序没有错误!