Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Only last set of vertices render

  1. #1

    Only last set of vertices render

    Alright here goes, I am in the middle of porting our rendering from fixed-function to fully programmable with a 3.2 core context and glsl 1.5. Whenever we wish to render to the screen (image, text, shapes) we call a function that fills an array with our vertices and writes that to the VBO (Only have 1 VAO and 1 VBO). After that I bind the shaders and the VAO and then glDrawArrays.

    This results in only the last set of vertices being rendered on screen. In the particular test I have, there is a box near the lower left corner that renders and when you click the mouse another box appears at the cursor (like a gunshot). When the shot comes on screen for a second the lower left box disappears and reappears.

    I can't seem for the life of me to render multiple 2d objects onto the screen at once. I have gone so far as changed the fillArray function to create a new VAO and VBO each time it is called to no avail.

    Does this problem standout to anyone? I can provide code samples if needed.

    Here is a screencast of the behavior I have: http://www.youtube.com/watch?v=z97xn...e_gdata_player

    Any and all ideas/thoughts/comments/flames are welcome.
    Last edited by allenmoatallen; 02-05-2013 at 11:49 PM. Reason: Added video of behavior

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,097
    You will need to post some code

  3. #3
    Code :
    void OGL_Renderer_3_2::drawVertexArray(GLuint textureId, bool defaultTextureCoords){
        clearScreen(0, 0, 0);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     
        glUseProgram(mShaderManager->getShaderProgram());
        getError();
     
        mModelViewMatrix = glGetUniformLocation(mShaderManager->getShaderProgram(), "mvp");
        getError();
     
        glUniformMatrix4fv(mModelViewMatrix, 1, GL_FALSE, glm::value_ptr(ModelViewMatrix));
        getError();
     
        glBindVertexArray(mVertexArray);
        getError();
     
     
        glDrawArrays(GL_TRIANGLES, 0, 6);
        getError();
     
     
        glBindVertexArray(0);
        getError();
        glUseProgram(0);
        getError();
        glDisable(GL_BLEND);
    }
     
     
    /**
     * Used internally to fill the vertex array with quad vertex information.
     */
    void OGL_Renderer_3_2::fillVertexArray(GLfloat x, GLfloat y, GLfloat w, GLfloat h)
    {
     
     
        float *mVertexArrayData = new float[18];
     
        mVertexArrayData[0] = static_cast<GLfloat>(x); mVertexArrayData[1] = static_cast<GLfloat>(y + h); mVertexArrayData[2] = 0;
        mVertexArrayData[3] = static_cast<GLfloat>(x); mVertexArrayData[4] = static_cast<GLfloat>(y); mVertexArrayData[5] = 0;
        mVertexArrayData[6] = static_cast<GLfloat>(x + w); mVertexArrayData[7] = static_cast<GLfloat>(y); mVertexArrayData[8] = 0;
        mVertexArrayData[9] = static_cast<GLfloat>(x + w); mVertexArrayData[10] = static_cast<GLfloat>(y); mVertexArrayData[11] = 0;
        mVertexArrayData[12] = static_cast<GLfloat>(x + w);    mVertexArrayData[13] = static_cast<GLfloat>(y + h); mVertexArrayData[14] = 0;
        mVertexArrayData[15] = static_cast<GLfloat>(x);    mVertexArrayData[16] = static_cast<GLfloat>(y + h); mVertexArrayData[17] = 0;
     
        glGenVertexArrays(1, &mVertexArray); // Create our Vertex Array Object
        glBindVertexArray(mVertexArray); // Bind our Vertex Array Object so we can use it
     
        glGenBuffers(1, &mVertexBufferObject); // Generate our Vertex Buffer Object
        glBindBuffer(GL_ARRAY_BUFFER, mVertexBufferObject); // Bind our Vertex Buffer Object
        glBufferData(GL_ARRAY_BUFFER, 18 * sizeof(GLfloat), mVertexArrayData, GL_STATIC_DRAW); // Set the size and data of our VBO and set it to STATIC_DRAW
     
        glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0); // Set up our vertex attributes pointer
     
        glEnableVertexAttribArray(0); // Disable our Vertex Array Object
        glBindVertexArray(0); // Disable our Vertex Buffer Object
     
        delete [] mVertexArrayData;
     
    }


    First fillVertexArray() is called passing in an x and y coordinate where we want the object to draw and usually pass in an image width and height (or box width and height).

    drawVertexArray() is called right after.

    The shaders that are used are basic, just getting vertices and assigning a color to the whole thing.

  4. #4
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    433
    If your clear the screen in drawVertexArray, then each call you make to it will clear the screen of previous contents.

  5. #5
    Quote Originally Posted by Dan Bartlett View Post
    If your clear the screen in drawVertexArray, then each call you make to it will clear the screen of previous contents.
    Thanks Dan I completely overlooked that! Without clearing the screen though the graphics stay on the screen when moving the mouse around and such and I have intense flashing right now. Should there be a clearScreen call somewhere?

    Second issue revealed is my matrix doesn't seem to be correct... It should be a ortho projection against a viewport size of 800x600. Here is the code:
    Code :
    	int w, h;	SDL_GetWindowSize(mWindow, &w, &h);
    	projection = glm::mat4(1.0f);
    	projection = glm::ortho(0.0f, static_cast<float>(w), static_cast<float>(h), 0.0f);
    	view = glm::lookAt(
    				glm::vec3(0,0,0), // Camera is at (0,0,5), in World Space
    				glm::vec3(0,0,1), // and looks at the origin
    				glm::vec3(0,-1,0)  // Head is up (set to 0,-1,0 to look upside-down)
    	);
    	model = glm::mat4(1.0f);
    	ModelViewMatrix = projection * view * model;

  6. #6
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    433
    You typically clear the screen at the start of the frame, render all the objects that need rendering, then swap the back and front buffers using SwapBuffers() / SDL_GL_SwapBuffers() or equivalent. Some common reasons for flashing/flickering are:
    1) When using single buffering you can sometimes see each new object being drawn which causes flashing as objects appear + are drawn over quickly
    2) Using double-buffering without clearing the screen (or without drawing to every pixel) each frame, which can result in contents of previous frames re-appearing when you swap buffers
    3) Drawing objects with very similar depth values can give z-fighting that causes flickering as the camera moves (when depth testing is enabled)

    I can't see anything immediately wrong with the matrix code, although it's a little unusual to have up=(0,-1,0). What do you mean by "doesn't seem to be correct"? If you have resized the window after the context was created, you will probably want to call glViewport afterwards.

  7. #7
    Well this is all 2D rendering so we don't make use of depth values, but I will double check that I have that turned off. Also I thought glViewport was gone in 3.2 Core?

  8. #8
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    433
    glViewport is still part of core OpenGL, as the transformation into window coordinates is still needed.

  9. #9
    Quote Originally Posted by Dan Bartlett View Post
    glViewport is still part of core OpenGL, as the transformation into window coordinates is still needed.
    Wow, then I was sorely wrong... The reason I had the view as (0, -1, 0) is because if I don't, the mouse y orientation is upside down (move mouse up it goes down or at least renders that way).

    glViewport should be called when setting up opengl and if the window is resized correct?

  10. #10
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    433
    The initial size of the viewport is set to the size of the window used for rendering so not strictly needed then (but won't hurt), but when resizing you'll want to adjust it.

    You may also want to adjust the viewport for drawing things like mini-maps, multiple views etc. but remember to set the scissor rectangle too if you do this since it's possible to draw on pixels outside the viewport. A simple example of when this can happen is when drawing large points near the edge of the viewport; it will produce pixels drawn outside the viewport. Once the centre of the point leaves the viewport the entire point will be clipped by the clip volume, in which case you might want a viewport larger than the window (extended by half the max point size in each direction) so that it gradually disappears off screen rather than suddenly vanishing when half visible.

    In the most recent versions of OpenGL there are also multiple viewports/scissor rects available, so if for example you wanted to view something from multiple angles (eg. for stereo or design work) could set multiple different viewports/scissor rects and in the geometry shader emit a copy of the primitives to each viewport resulting in multiple copies in a single pass.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •