Since you do not have a shader, OpenGL does not know how to interpret your vertex attribute 0, as it only knows about position, color, etc. but knows nothing about generic attributes. If you want to keep the code shader-free, you need to use the named attributes:
static void RenderSceneCB()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY); // or GL_NORMAL_ARRAY, etc.
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexPointer(3, GL_FLOAT, GL_FALSE, 0, 0); // or glNormalPointer(), etc.
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
}
Note that your code may actually work on some GPUs as they will map the generic attributes to the same "slots" as the named attributes, and zero would then be interpreted as position (typically NVidia is (errorneously) less strict with these issues and on my GTX 680 the provided code indeed displays a white triangle).
You can use MiniShader, just put the following code after CreateVertexBuffer();
:
minish::InitializeGLExts(); // initialize shading extensions
const char *vs =
"layout(location = 0) in vec3 pos;\n"
// the layout specifier binds this variable to vertex attribute 0
"void main()\n"
"{\n"
" gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0);\n"
"}\n";
const char *fs = "void main() { gl_FragColor=vec4(.0, 1.0, .0, 1.0); }"; // green
minish::CompileShader(vs, fs);
Note that writing the vertex shader just like that will likely lead to problems, as no version is specified. The layout
qualifier is only available in GLSL 330, but gl_ModelViewProjectionMatrix
is deprecated after GLSL 120. So we need to add something like this to the beginning of the vertex shader:
"#version 140\n" // need at least 140 for GL_ARB_explicit_attrib_location
"#extension GL_ARB_explicit_attrib_location : require\n"
// required for layout(location)
"#extension GL_ARB_compatibility : require\n"
// still need gl_ModelViewProjectionMatrix
// (which is otherwise deprecated after version 120)
// also, GL_ARB_compatibility is not supported in version 330 (and above)
Alternately, we can just use GLSL 330 (or greater) but then the modelview-projection matrix needs to be passed through an uniform (which also needs to be properly set in the CPU code):
"#version 330\n"
"uniform mat4 MVP;\n"
"layout(location = 0) in vec3 pos;\n"
"void main()\n"
"{\n"
" gl_Position = MVP * vec4(pos, 1.0);\n"
"}\n";
Note that this answer is an extended duplicate of my answer to Triangle doesn't render.