Reputation: 115
I'm pretty new to opengl and I don't really understand what's going on here. I'm trying to use two VAOs to create multiple objects and am using a custom matrix to rotate/translate them. The image is fine when I load up one, but when I load up two they both flicker. My init is this, where I have a different array for each buffer, vertex position, vertex indices and vertex colours.
void init()
{
readFile();
//glEnable(GL_DEPTH);
glEnable( GL_DEPTH_TEST );
//make background yerpul in colour
glClearColor( 0.235, 0.194, 0.314, 1.0 );
// Load shaders and use the resulting shader program
program = InitShader( "aVertexShader61.glsl", "aFragShader61.glsl" );
glUseProgram( program );
// Create a vertex array object
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
// Create and initialize two buffer objects
glGenBuffers( 2, buffers);
//one buffer for the vertexPositions and colours
glBindBuffer( GL_ARRAY_BUFFER, buffers[0]);
glBufferData( GL_ARRAY_BUFFER, numVertexPositionBytes + numVertexColourBytes,NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions );
glBufferSubData( GL_ARRAY_BUFFER, numVertexPositionBytes, numVertexColourBytes, vertexColours);
//one buffer for the indices
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glBufferData( GL_ELEMENT_ARRAY_BUFFER, numVertexIndexBytes,vertexIndicies, GL_STATIC_DRAW );
// set up vertex arrays
GLuint vPosition = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
GLuint vColor = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor );
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertexPositionBytes) );
// Second object
glGenVertexArrays( 1, &vao2 );
glBindVertexArray( vao2 );
glGenBuffers( 2, buffers2);
//one buffer for the vertexPositions and colours
glBindBuffer( GL_ARRAY_BUFFER, buffers2[0]);
glBufferData( GL_ARRAY_BUFFER, numVertexPositionBytes + numVertexColourBytes,NULL, GL_STATIC_DRAW );
glBufferSubData( GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions2 );
glBufferSubData( GL_ARRAY_BUFFER, numVertexPositionBytes, numVertexColourBytes, vertexColours2);
//one buffer for the indices
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffers2[1]);
glBufferData( GL_ELEMENT_ARRAY_BUFFER, numVertexIndexBytes,vertexIndicies2, GL_STATIC_DRAW );
// set up vertex arrays
GLuint vPosition2 = glGetAttribLocation( program, "vPosition" );
glEnableVertexAttribArray( vPosition2 );
glVertexAttribPointer( vPosition2, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
GLuint vColor2 = glGetAttribLocation( program, "vColor" );
glEnableVertexAttribArray( vColor2 );
glVertexAttribPointer( vColor2, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertexPositionBytes) );
glBindVertexArray(0);
}
This is my display that gets called with glutPostRedisplay(); in my idle function, no other calls to anything are made from the idle. mStack is a matrix stack object created from an external file
void
display( void )
{
//clear for first object, generate matrix and apply to object
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
mStack.loadIdentity();
mStack.translatef(0,yDisplace,0);
mStack.rotatef(Theta[Yaxis], 0.0,1.0,0.0);
for (unsigned char i=0; i<NumVertices; i++){
mStack.transformf(&vertexPositionsInit[i*4],&vertexPositions[i*4]);
}
//Apply to second object
for (unsigned char i=0; i<NumVertices; i++){
mStack.transformf(&vertexPositionsInit2[i*4],&vertexPositions2[i*4]);
}
//Draw first object
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
//Indexing into vertices we need to use glDrawElements
glDrawElements(GL_TRIANGLES, NumIndicies, GL_UNSIGNED_BYTE, 0);
glutSwapBuffers();
//Clear and draw second object
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glutSwapBuffers();
glBindVertexArray(vao2);
glBindBuffer(GL_ARRAY_BUFFER, buffers2[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions2 );
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers2[1]);
//Indexing into vertices we need to use glDrawElements
glDrawElements(GL_TRIANGLES, NumIndicies, GL_UNSIGNED_BYTE, 0);
glutSwapBuffers();
}
I'm using simple vertex and fragment shaders. The vertex shader,
in vec4 vPosition;
in vec4 vColor;
out vec4 color;
void main()
{
gl_Position = vPosition;
color = vColor;
}
And fragment shader,
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
Any help would be appreciated, and I can post the Matrix file if need be. Thanks
Upvotes: 6
Views: 6957
Reputation: 6957
Don't call glutSwapBuffers()
or glClear()
in between objects. Swapping buffers is a way to tell GLUT "Okay, I'm done with this frame, let's start with the next one."
Usually you'll want to split out the code that sets up and completes each frame (like the calls to glClear()
and glutSwapBuffers()
) from the code that renders each object, because OpenGL is basically a gigantic box of global variables and it's hard to write good OpenGL code without breaking your methods up into small pieces.
Upvotes: 6