6

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

user2755996
  • 115
  • 2
  • 8
  • 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 Sep 07 '13 at 01:03
  • 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 Sep 07 '13 at 02:31
  • 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 Sep 07 '13 at 02:36

1 Answers1

6

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.

GraphicsMuncher
  • 4,583
  • 4
  • 35
  • 50
Steve Howard
  • 6,737
  • 1
  • 26
  • 37
  • Thanks for the reply, I commented out the clear and swap buffers and now the second object leaves a trail of frames and the background flickers as well :s – user2755996 Sep 07 '13 at 02:30
  • Did you comment out all of them, or just the ones between objects? You still need one glClear() at the beginning and one glutSwapBuffers() at the end. It looks a bit like you got the code working for one object and copied all of it for the second, but some of these calls are once-per-frame and others are once-per-object. – Steve Howard Sep 07 '13 at 02:34
  • That did it :), I had previously had a swap buffers at the end of each object instead of the end of the draw section for both. Thanks a lot Steve – user2755996 Sep 07 '13 at 02:43