Duplicate geometry appearing on incorrect VBO

Hey folks,

I’m new to openGL and absolutely love it.

Problem:

I have multiple interleaved VBOs. The geometry itself is rendering properly. However, it appears that in some cases that the geometry from one VBO gets combined with the geometry from another VBO.

I’m rendering planets. Each planet contains 4 VBOs based on quality: low, med, high, best. These are selectively rendered based on camera distance from the planet surface.

Most planets render properly. In some situations a planet may render the geometry for itself as well as the geometry of another planet over top of itself.

Image attached.

Details:

Java / LWJGL on Win 7 x64

No shaders

Seems to be vedor specific:
Radeon HD 68xx - problem appears
GeForce 8600GT - no problem

GL_VENDOR: ATI Technologies Inc.
GL_VERSION: 4.2.11318 Compatibility Profile Context
GL_RENDERER: AMD Radeon HD 6800 Series

Does my approach below look correct?



  private void prerender()
  {
    
    if ( !prerendered )
    {
      prerendered = true;
      
      
      validateVerticies();
      
      if ( verticies.length > 0 )
      {
        
        /*
         * Setup Buffers
         */
        
        // Generate buffer ids
        buffers = BufferUtils.createIntBuffer(2);
        GL15.glGenBuffers(buffers);
        
        
        /*
         * Setup VBO
         */
        
        int floatCnt = verticies[0].getOutput().length;
        
        vboBuffer = BufferUtils.createFloatBuffer(verticies.length*floatCnt);
        for ( int i=0; i<verticies.length; ++i)
          vboBuffer.put( verticies[i].getOutput() );
        vboBuffer.flip();
        
        
        // Bind and Upload
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buffers.get(0));
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vboBuffer, GL15.GL_STATIC_DRAW);
        
        
        // Pointer Data
        // note: glVertexPointer should be at the end
        GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, offsetTexture);
        GL11.glNormalPointer(GL11.GL_FLOAT, stride, offsetNormal);
        GL11.glColorPointer(4, GL11.GL_FLOAT, stride, offsetColor);
        GL11.glVertexPointer(3, GL11.GL_FLOAT, stride, offsetVertex);
        
        
        /*
         * Setup IBO
         */
        
        int size = verticies.length*stride;
        
        iboBuffer = BufferUtils.createIntBuffer(size);
        for ( int i=0; i<size; ++i)
          iboBuffer.put(i);
        iboBuffer.flip();
        
        
        // Bind and Upload
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, buffers.get(1));
        GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, iboBuffer, GL15.GL_STATIC_DRAW);
        
        
        checkError();
        
        
        // Log
        log("+ VBO:" + name + ", " + buffers.get(0) + ", " + buffers.get(1) );
        
      }
      
    }
    
  }
  
  
  /*
   * Interleaved Data Format
   * 3 vertex, 3 normal, 4 color, 2 texture, 4 padding
   * 
   * Example Data (floats):
   * {vX, vY, vZ, nX, nY, nZ, cX, cY, cZ, cA, tX, tY, 0f, 0f, 0f, 0f}
   * 
   * floats are 4 bytes each
   * 
   */
  
  private int floatBytes = 4;
  private int stride = (3 + 3 + 4 + 2 + 4) * floatBytes; // should total 64;
  
  private int offsetVertex = 0;
  private int offsetNormal = (3) * floatBytes;
  private int offsetColor = (3+3) * floatBytes;
  private int offsetTexture = (3+3+4) * floatBytes;
  
  
  /*
   * Render VBO data
   * 
   */
  
  public void render()
  {
    
    if ( verticies.length > 0 )
    {
      
      prerender();
      
      
      // Bind the vertex buffer and the index buffer
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, buffers.get(0));
      GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, buffers.get(1));
      
      
      // Enable State
      GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
      GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
      GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
      GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);      
      
      
      // Pointer Data
      GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, offsetTexture);
      GL11.glNormalPointer(GL11.GL_FLOAT, stride, offsetNormal);
      GL11.glColorPointer(4, GL11.GL_FLOAT, stride, offsetColor);
      GL11.glVertexPointer(3, GL11.GL_FLOAT, stride, offsetVertex);
      
      
      
      /*
       * Debug: Check the current binding
       */
      
      IntBuffer response = BufferUtils.createIntBuffer(16);
      GL11.glGetInteger(GL15.GL_ARRAY_BUFFER_BINDING, response);
      int arrayBinding = response.get(0);
      
      GL11.glGetInteger(GL15.GL_COLOR_ARRAY_BUFFER_BINDING, response);
      int colorBinding = response.get(0);
      
      GL11.glGetInteger(GL15.GL_VERTEX_ARRAY_BUFFER_BINDING, response);
      int vertexBinding = response.get(0);
      
      if ( arrayBinding != buffers.get(0) || colorBinding != buffers.get(0) || vertexBinding != buffers.get(0) )
      {
        log("BINDING ERROR!");
      }
      
      
      
      // Draw
      GL11.glDrawElements(type, verticies.length*stride, GL11.GL_UNSIGNED_INT, 0);
      
      // Log
      log("> VBO:" + name + ", " + buffers.get(0) + ", " + buffers.get(1) + ", verts: " + verticies.length);
      
            
      // Disable State
      GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
      GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
      GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
      GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
      

      // Unbind
      GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
      GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
      
      
      
    }
    
    
    
  }



Any suggestions would be appreciated.


int size = verticies.length*stride;

Why do you put #vertices * stride many indices in your IBO? Shouldn’t it be just one index per vertex? Since the i-th index is i you could just use non-indexed drawing (glDrawArrays()) and do away with the IBO completely.

It looks like you are uploading data to the buffers each frame, that wastes performance - of course until it works correctly that is a secondary concern :wink:

I dropped the IBO and used non-indexed drawing like you suggested. This resolved the duplicate geometry issues and provided a nice increase in fps.

This is awesome. Many thanks.

One remaining question:

It looks like you are uploading data to the buffers each frame …

My messy code might not make it clear that prerender is only called on the first render pass.

Is this what you are referring to or am I overlooking something?

No, I just overlooked the test at the beginning of the function, sorry about the false alarm.

Awesome, thanks again.