Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

opengl flickering while rendering multiple objects

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

like image 305
user2755996 Avatar asked Sep 07 '13 00:09

user2755996


1 Answers

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.

like image 124
Steve Howard Avatar answered Sep 20 '22 16:09

Steve Howard