I am writing some openGL wrappers and am trying to run the following code:
void some_func1() {
float vertices[] = {50.0, 50.0, 0.0, 20.0, 50.0, 0.0, 20.0, 60.0, 0.0};
glColor3f(1.0, 0.0, 0.0);
glInterleavedArrays(GL_V3F, 0, vertices);
}
void some_func2() {
int indices[] = {0,1,2};
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
}
void parent_func() {
some_func1();
some_func2();
}
But it would seem that openGL is not picking up the call to glDrawElements in the second function. My routine opens a window, clears it to black, and draws nothing. What’s weird is that running this code
void some_func1() {
float vertices[] = {50.0, 50.0, 0.0, 20.0, 50.0, 0.0, 20.0, 60.0, 0.0};
int indices[] = {0,1,2};
glColor3f(1.0, 0.0, 0.0);
glInterleavedArrays(GL_V3F, 0, vertices);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices);
}
void parent_func() {
some_func1();
}
works exactly as expected: a red triangle is drawn. I’ve looked through the documentation and searched around, but I can’t find any reason that glDrawElements wouldn’t work, or would miss data somehow if called in another function. Any ideas?
FYI: I am running this on an Ubuntu 12.04 VM through VirtualBox, 32-bit processor on the host, and freeglut is doing my window handling. I have also set LIBGL_ALWAYS_INDIRECT=1 to work around an issue with the VM’s 3D rendering. (not sure if any of that matters but… :))
The reason is, that at the point of drawing with
glDrawElements, there is no valid vertex data to draw. When callingglInterleavedArrays(which just does a bunch ofgl...Pointercalls under the hood) you are merely telling OpenGL where to find the vertex data, without copying anything. The actual data is not accessed before the drawing operation (glDrawElements). So insome_func1you are setting a pointer to the local variablevertices, which doesn’t exist anymore after the function returns. This doesn’t happen in your modified code (where the pointer is set and drawn in the same function).So either make this array survive until the
glDrawElementscall or, even better, make OpenGL to actually store the vertex data itself, by employing a vertex buffer object and performing an actual data copy. In this case you might also want to refrain from the awfully deprecatedglInterleavedArraysfunction (which isn’t much more than a mere software wrapper around propergl...PointerandglEnableClientStatecalls, anyway).