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

标签 c++ opengl

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

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

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

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

// 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));

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

最佳答案

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

关于c++ - glDrawArrays 意外行为 - 错误的参数顺序产生所需的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46950409/

相关文章:

c++ - 接口(interface)的菱形问题

c++ - 错误 : ISO C++ forbids conversion from string constant to char*

c++ - 游戏引擎中的对象层次结构实现

C++ 指向使用随机指针归档的其他类对象的指针 vector

c++ - 在Allegro 5中使用多个计时器

c++ - 访问读取冲突错误 - C++ Obj Loader

c++ - QGLWidget上下文破坏

c++ - 如何让各向异性过滤扩展起作用?

c++ - 如何在我的 OpenGL 应用程序中实现准确(但可变)的 FPS 限制/上限?

c# - 使用 C# 截取任何外部应用程序的屏幕截图