C++ glDrawArrays意外行为-参数顺序错误会生成所需的图像

C++ glDrawArrays意外行为-参数顺序错误会生成所需的图像,c++,opengl,C++,Opengl,我正在编写其他人编写的代码,目前我对代码库的理解相当有限。这就是为什么我不确定如何正确地表述我的问题,以及它是OpenGL问题还是调试策略问题。此外,我显然不能真正共享整个代码库,而这些东西不起作用的原因很可能就在这里。不管怎样,也许有人只是知道可能发生了什么,或者我应该去哪里看看 我用以下方式定义了顶点结构: struct Vertex { Vertex(glm::vec3 position, glm::vec3 normal): _position(position)

我正在编写其他人编写的代码,目前我对代码库的理解相当有限。这就是为什么我不确定如何正确地表述我的问题,以及它是OpenGL问题还是调试策略问题。此外,我显然不能真正共享整个代码库,而这些东西不起作用的原因很可能就在这里。不管怎样,也许有人只是知道可能发生了什么,或者我应该去哪里看看

我用以下方式定义了顶点结构:

struct Vertex {
    Vertex(glm::vec3 position, glm::vec3 normal):
        _position(position), _normal(normal) {};
    glm::vec3 _position;
    glm::vec3 _normal;
};
我有一个顶点的标准向量,我用从特定结构中提取的顶点数据来填充它。为了简单起见,我们假设它是另一个向量:

// 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));
}
最后,我绑定一个着色器并设置制服,然后调用gldrawArray:

此时不会渲染任何内容。但是,最初我犯了一个错误,交换了draw调用的参数,使得offset位于要绘制的元素数之前:

glDrawArrays(GL_TRIANGLES, Vertices.size(), 0);
令人惊讶的是,这实际上呈现了我最初想要呈现的内容。然而,这个函数清楚地表明偏移量是第一位的,并且后面的元素数量也是第一位的。这意味着glDrawArraysGL_三角形,顶点.size,0应该没有显示任何内容,因为我指定了要绘制的元素数为“零”

现在,应用程序中有多个窗口和共享顶点缓冲区对象。在某种程度上,我认为我生成的顶点缓冲区对象以某种方式在我尚未探索的代码部分得到传递,并使用它来绘制我不希望绘制的几何体。然而,这仍然不能解释这样一个事实:当我使用glDrawArraysGL_三角形、顶点.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包装器来修改顺序或参数。但是,我可以确认您引用的文档中的参数顺序没有错误

不知道glDrawArrays出了什么问题,但是对GLVertexAttributePointer的调用看起来也是错误的-两者都使用索引0配置属性,因此第二个会覆盖第一个。glGetError返回什么?@rabbi76是的,遗憾的是,代码中的这一点也正确。我将代码块复制到堆栈溢出中,但没有复制到堆栈溢出中。很抱歉,我仔细检查了一下,现在一切都应该就绪。@VTT glGetError返回GLU NO_ERROR,或者换句话说,返回零。您使用的是顶点数组对象吗?现在开始。事实证明,前一个编写代码的人确实制作了一个包装器,因此它类似于GLDrainElements的参数顺序,即“count”在参数列表中排名第二。事实上,他的函数调用类似于drawElements和DrawArray,这应该已经告诉我了,让我更仔细地检查东西。因此,这只是我公然的疏忽。我为浪费人们的时间而道歉。我不确定我是否应该删除这个问题,还是保留它作为对那些可能落入同样陷阱的人的警告。
#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";