Reputation: 11557
I'm attempting to draw a single large triangle in a window in OpenGL. My program compiles and runs, but I get just a black screen in my window.
I've checked and double-checked multiple tutorials and it seems like my steps are correct... Am I missing something obvious?
Here is the program in its entirety:
#include <stdlib.h>
#include <stdio.h>
#include <GL/glew.h>
#include <GLUT/glut.h>
GLuint VBO;
struct vector {
float _x;
float _y;
float _z;
vector() { }
vector(float x, float y, float z) { _x = x; _y = y; _z = z; }
};
void render()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
void create_vbo()
{
vector verts[3];
verts[0] = vector(-1.0f, -1.0f, 0.0f);
verts[1] = vector(1.0f, -1.0f, 0.0f);
verts[2] = vector(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow("Triangle Test");
glutDisplayFunc(render);
glewInit();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
create_vbo();
glutMainLoop();
return 0;
}
Update: It turns out that drawing this way without a "program" (that is, compiled shader files) produces undefined behavior (the newer your graphics card, the more likely it is to work, however).
Because my card is right on the edge and only supports OpenGL 2.1, it was a little difficult to find an appropriate shader example that would work -- seems like there are many different tutorials out there written at different stages in the evolution of OpenGL.
My vertex shader (entire file):
void main()
{
gl_Position = ftransform();
}
My fragment shader (entire file):
void main()
{
gl_FragColor = vec4(0.4,0.4,0.8,1.0);
}
I used the example LoadShaders
function from this OpenGL Tutorial Site to create the program, and now, I, too, can see the triangle!
(Thanks to @chbaker0 for pointing me in the right direction.)
Upvotes: 4
Views: 3213
Reputation: 11557
The issue I ran into was using pipeline features without defining a shader program. The spec says this should work, but on my graphics card it did not did. (See my update in the question for more specifics).
Thanks to all the commenters for nudging me in the right direction.
Upvotes: 0
Reputation: 7895
I do not know if this will help you or not but in your create_vbo() function where you have:
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
try this instead:
glBufferData( GL_ARRAY_BUFFER, sizeof( verts[0] * 3 ), &verts[0], GL_STATIC_DRAW );
And after this function call add in this function call to the end of your create_vbo() function
// This MUST BE LAST! Used to Stop The Buffer!
glBindBuffer( GL_ARRAY_BUFFER, 0 );
It is hard for me to see your error. In my projects I do have some vbos, but I am also using vaos as well. My code is able to working in OpenGL 2.0 - 4.5 but for the older versions there is a split in logic because of the deprecated functions within the API. I also do not use glut. I hope this helps.
The other thing I noticed too is did you pay attention to your vertex winding order? Meaning are they being used by OpenGL in a CCW order or CW order? Is back face culling turned on or off? There are a lot of elements to consider when setting up and configuring an OpenGL context. It has been a while since I worked with older versions of OpenGL but I do know that once you start working with a specific version or newer you will have to supply your own model view projection matrix, just something to consider.
Upvotes: 2