我正在研究其他人编写的代码,目前对代码库的理解还很有限。这就是为什么我不确定如何正确表达我的问题,以及它是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)


在这一点上,什么都没有呈现。但是,最初我犯了一个错误,交换了draw调用的参数,使得offset出现在要绘制的元素数之前:

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";

最佳答案

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

09-10 12:45
查看更多