user1276209
user1276209

Reputation:

Why is my OpenGL 3.3 Application not drawing anything?

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

Answers (1)

Nicol Bolas
Nicol Bolas

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

Related Questions