Reputation:
I'm trying to get a handle on OpenGL VAOs/VBOs, and conceptually I'm there, but for whatever reason, this application isn't drawing anything to the screen. I'm working in a 4.2 context, but I'm writing for core-only 3.3.
Here are declarations for relevant variables:
// Tetrahedron vertices
GLfloat tetra_vertices[12];
GLuint tetra_vao;
GLuint tetra_vbo;
In a function called init_scene
I have the following:
glGenVertexArrays(1, &tetra_vao);
glBindVertexArray(tetra_vao);
glGenBuffers(1, &tetra_vbo); // One for vertex locations
glBindBuffer(GL_ARRAY_BUFFER, tetra_vbo); // Bind vertex locations buffer
glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), tetra_vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
And where my GLSL program is linked:
for (int i = 0; i < num_shaders; ++i)
glAttachShader(program, shaders[i]);
glBindAttribLocation(program, 0, "in_position");
glLinkProgram(program);
I'm only using one attribute, and that's vertex position. The program links without errors.
Here's the draw_scene
function itself:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(tetra_vao);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 12);
glBindVertexArray(0);
And for good measure, my vertex shader:
#version 330
in vec3 in_position;
uniform mat4 modelview_matrix;
void main(void) {
gl_Position = vec4(in_position, 1.0f) * modelview_matrix;
}
modelview_matrix
is a uniform that's for the moment just passing in an identity matrix. I thought for a moment that something might be drawn that I simply couldn't see, so I set my clear color to grey, and here's the fragment shader that should just output white:
#version 330
out vec4 vFragColor;
void main(void)
{
vFragColor = vec4(1.0f);
}
Everything I've read, most notably this tutorial and the Superbible, make the chain of events pretty clear:
I used glDEBugger to try and get a clearer picture into why this isn't working. I have break on GL errors set, so I know there are no errors being raised by the GL functions themselves. I can see the contents of the VBO, and it's the vertex data I'd expect. The only thing I'm not sure about is how to make sure that VBO is associated as vertex location data with the VAO, and that the VAO is actually correctly bound when I call the draw function.
If there's anything I've left out that's necessary, please let me know. Thanks!
Update 1:
Here is the array that provides the vertex data loaded into the VBO:
tetra_vertices = {
0.7f, 0.7f, 0.7f,
-0.7f, -0.7f, 0.7f,
-0.7f, -0.7f, -0.7f,
0.7f, -0.7f, 0.7f
};
Here's what all of my context setup stuff looks like:
glClearColor(0.2,0.2,0.2,0.0);
glClearDepth(1.0);
glViewport(0, 0, properties.size_x, properties.size_y);
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_VERTEX_ARRAY);
glEnable(GL_MULTISAMPLE);
Update 2:
Nicol Bolas' answer below brought up a good point about orthographic visibility which I hadn't thought about. Unfortunately, it doesn't seem as though that's the problem. I tried his vertex list, and turned off any culling, and tried these vertices:
tetra_vertices = {
-0.7f, -0.7f, 0.0f,
-0.7f, 0.7f, 0.0f,
0.7f, -0.7f, 0.0f,
0.7f, 0.7f, 0.0f
};
Which should, I think, draw a square, but still nothing. I also noticed that I was calling glDrawArrays
with 12 elements when it should have been four (12 coordinates = 4 x,y,z vertices), but this didn't fix the problem either.
Update 3 (or, "When Posts Become Too Long"):
Walking through the application step-by-step in gDEBugger, I noticed something that strikes me as odd. In the draw
function, there's the usual cycle of bind the current VAO, call glDrawArrays
, bind VAO 0 so that another thing can be drawn. Watching the GL state settings as this happens, it looks like GL_VERTEX_ARRAY
is TRUE
when my VAO is not bound (viz. VAO 0 is bound) and FALSE
when my VAO is bound. Is this the way things are supposed to be? Does GL_VERTEX_ARRAY
represent state that is superseded by glBindVertexArray
rather than augmented by it? Additionally, changing the mode from GL_TRIANGLE_STRIP
to GL_POINTS
and setting glPointSize(5.0f)
causes a single point to be drawn at 0, 0, so it appears that a point is being created, but it not being properly handled by my vertex shader.
Upvotes: 1
Views: 3714
Reputation: 473407
tetra_vertices = {
0.7f, 0.7f, 0.7f,
-0.7f, -0.7f, 0.7f,
-0.7f, -0.7f, -0.7f,
0.7f, -0.7f, 0.7f
};
You're using an othographic projection (since your matrix is identity). So basically, we can ignore the Z values; they don't matter.
You draw this as a triangle strip, so it comes up with two triangles.
Your first triangle is {(0.7f, 0.7f), (-0.7f, -0.7f), (-0.7f, -0.7f)}
. This triangle has no visible surface area, because two of the points are the same. A triangle with no visible surface area is invisible.
Your second triangle is {(-0.7f, -0.7f), (-0.7f, -0.7f), (0.7f, -0.7f)}
. Just as before, two of the points are the same, so the triangle has no visible area.
You probably meant something like this:
tetra_vertices = {
0.7f, 0.7f, 0.0f,
-0.7f, 0.7f, 0.0f,
-0.7f, -0.7f, 0.0f,
0.7f, -0.7f, 0.0f
};
That's more likely to get you something useful. If you still don't see anything, turn off face culling.
Upvotes: 4