6
votes

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

1
Side note: the shaders you're using are called "pass-through" shaders, which means that if you weren't using shaders at all you'd get the same output. Most of that matrix code could go in the shaders, though of course you fix one thing at a time. :)Steve Howard
could this be a problem caused by the matrix calculations? I thought it must be a buffer problem which is why I didn't include the matrix code but I really have no idea.user2755996
The matrix code will determine where your object "is." If you're seeing an object but it's flickering or leaving a trail, that's not likely a matrix problem.Steve Howard

1 Answers

5
votes

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.