简体   繁体   中英

glDrawArrays unexpected behavior - wrong order of arguments produces desired image

I am working on the code written by someone else and at the moment I have a fairly limited understanding of the codebase. Which is why I wasn't sure how to formulate my question properly, and whether it is an OpenGL question, or debugging strategy question. Furthermore, I obviously can't really share the whole code base, and the reason stuff is not working is most likely rooted in there. Regardless, perhaps someone just might have an idea of what might be going on, or where should I look at.

I have a vertex structure defined in the following way:

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

I have a std vector of vertices which I fill out with vertex data extracted from a certain structure. For the sake of simplicity, let's assume it's another 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));
}

Then I generate a vertex buffer object, buffer my data and enable vertex attributes:

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

Finally, I bind a shader and set up uniforms, then I call glDrawArrays :

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

At this point nothing gets rendered. However, initially I made a mistake and swapped the parameters of the draw call, such that offset comes before the number of elements to draw:

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

And surprisingly, that actually rendered what I wanted to render in the first place. However, the documentation clearly says that the offset comes first, and the number of elements after this. Which means that glDrawArrays(GL_TRIANGLES, Vertices.size(), 0) should have shown nothing, since I specified 'zero' number of elements to be drawn.

Now there are multiple windows in the application and shared vertex buffer objects. At some point I thought that the vertex buffer object I generated somehow gets passed around in the part of the code I haven't explored yet, and uses it to draw the geometry I didn't expect to be drawn. However that still doesn't explain the fact that when I use glDrawArrays(GL_TRIANGLES, Vertices.size(), 0) with 'zero' as the number of elements to be drawn - I see the geometry; whereas when I swap the parameters according to the documentation - nothing gets shown.

Given this scarce information that I shared, does someone by any chance have an idea of what might be going on? If not, how would you tackle this, how would you go about debugging (or understanding) it?

EDIT: Vertex and Fragment shader

Mind that this is a dummy shader that simply paints the whole geometry red. Regardless, shader is not the cause of my problems, given how geometry gets drawn depending on how I use the draw call (see above).

EDIT EDIT: Note that as long as I don't activate blending, the alpha component (which is 'zero' in the shader), won't have any effect on the produced image.

vertex shader:

#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);    
}

fragment shader:

#version 440
out vec4 outColor;

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

Regarding the glDrawArrays parameter inversion, have you tried stepping into that function call? Perhaps you are using an OpenGL wrapper of some sort which modifies the order or the arguments. I can confirm however that the documentation you quote is not wrong about the parameter order!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM