Page 1 of 3 123 LastLast
Results 1 to 10 of 22

Thread: Problem with VBOs

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2006
    Posts
    14

    Problem with VBOs

    Hello all,

    I'm learning how to use VBOs but I have a problem. I have a model that is about 10k triangles and I can render it using vertex arrays or VBOs. With vertex arrays I get about 75fps but if I switch to VBOs I get about 0.003fps... so I must be doing something wrong.

    My code looks like this
    Code :
     
    void InitializeVBOs()
    {
        int 
            totalVerticesSize = 0,
            totalNormalsSize = 0,
            totalTxCoordsSize = 0,
            numTextures = 0,
            numVertices = 0,
            totalVBOSize = 0;
     
        if( 
            ( m_VBOsSupported ) && 
            ( m_pGeometry[ 0 ] != NULL ) &&
            ( m_pGeometry[ 0 ]->Get_NumVertices() > 0 )
            )
        {
            numVertices = m_pGeometry[ 0 ]->Get_NumVertices();
            numTextures = m_pGeometry[ 0 ]->GetNumTextures();
     
            totalVerticesSize = ( sizeof(float) * 3 ) * numVertices; // for vertices
            totalNormalsSize = ( sizeof(float) * 3 ) * numVertices; // for normals
            totalTxCoordsSize = 
                ( sizeof(float) * 3 ) * numVertices * numTextures; // for tx coords
            totalVBOSize = totalVerticesSize + totalNormalsSize + totalTxCoordsSize;
     
            glGenBuffersARB( 1, &m_GPUVertexBufferID );
            glGenBuffersARB( 1, &m_GPUIndexBufferID );
     
            // Bind the vertex data vbo.
            glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_GPUVertexBufferID );
     
            // Create a data store big enough for vertices, normals, and texture coords.
            glBufferDataARB( GL_ARRAY_BUFFER_ARB, totalVBOSize, NULL, GL_STATIC_DRAW_ARB );
     
            // Load vertices
            glBufferSubDataARB( 
                GL_ARRAY_BUFFER_ARB,// target
                0,                  // start from
                totalVerticesSize,  // total bytes of data
                m_pGeometry[0]->m_vertices // data
                );
     
            // Load normals
            glBufferSubDataARB(
                GL_ARRAY_BUFFER_ARB,// target
                totalVerticesSize,  // start from
                totalNormalsSize,   // total bytes of data
                m_pGeometry[0]->m_vertexNormals // data
                );
     
            // Load texture coordinates
            glBufferSubDataARB(
                GL_ARRAY_BUFFER_ARB,// target
                totalVerticesSize + totalNormalsSize, // start from
                totalTxCoordsSize,  // total bytes of data
                m_pGeometry[0]->m_txCoords // data
                );
     
            // Load the indices
            glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_GPUIndexBufferID );
     
            glBufferDataARB(
                GL_ELEMENT_ARRAY_BUFFER, // target
                m_numIndices * sizeof(unsigned short), // total size
                m_pGeometry[0]->m_indices, // data
                GL_STATIC_DRAW_ARB 
                );
        }
    }
     
    // ---
     
    void Render()
    {	
        int 
            totalVerticesSize = 0,
            totalNormalsSize = 0,
            numvertices = 0,
            numtextures = 0;
     
    	//...
    	//...	
     
    	if( m_pGeometry[0] != NULL ) 
    	{
                numvertices = m_pGeometry[0]->Get_NumVertices(); 
                numtextures = m_pGeometry[0]->GetNumTextures(); 
                totalVerticesSize = ( sizeof(float) * 3 ) * numvertices; 
                totalNormalsSize = ( sizeof(float) * 3 ) * numvertices; 
     
                // If VBOs are supported and we have valid buffers
                if( 
                    m_VBOsSupported && 
                    ( m_GPUVertexBufferID > 0 ) &&
                    ( m_GPUIndexBufferID > 0 )
                    )
                { 
                    // Bind the data buffer
                    glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_GPUVertexBufferID );
     
                    // Bind the element buffer
                    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_GPUIndexBufferID );
     
                    // Setup pointers
     
                    glVertexPointer( 
                        3, // coords
                        GL_FLOAT, // floats
                        0, // stride is 0, vertices are contiguous
                        0  // offset is 0, vertices are at the start of the buffer
                        ); 
     
                    glNormalPointer( 
                        GL_FLOAT, // floats
                        0, // stride is 0, normals are contiguous
                        BUFFER_OFFSET( totalVerticesSize ) // offset is (total size of vertices)
                        );
     
                    /*
                    glTexCoordPointer(
                        2, // 2 coordinates
                        GL_FLOAT, // floats 
                        sizeof(float), // stride is one float
                        BUFFER_OFFSET( totalVerticesSize + totalNormalsSize ) // offset into the buffer
                    );
                    */
                } 
                else 
                { 
                    // SET VERTEX AND NORMAL POINTER 		    		
     
                    glVertexPointer(3, GL_FLOAT, 0, m_pGeometry[0]->m_vertices); 
                    glNormalPointer(GL_FLOAT, 0, m_pGeometry[0]->m_vertexNormals); 
                    /*glTexCoordPointer( 3, GL_FLOAT, sizeof(float), m_pGeometry[0]->m_txCoords ); */
     
                } 
     
    	    groupIndices = m_pGeometry[0]->Get_NumIndices();
     
                if( m_VBOsSupported )
                {           
                    start_time = timeGetTime() / 1000.0f;
     
                    glDrawElements( 
                        GL_TRIANGLES, 
                        groupIndices,
                        GL_UNSIGNED_SHORT, 
                        0
                        );  
     
                    end_time = timeGetTime() / 1000.0f;
                    sprintf(tmpStr, "VBO CALL = %f", end_time - start_time);
                    MessageBox(NULL, tmpStr, "VBO CALL", MB_OK );
     
                    glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
                    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
                }
                else 
                { 
                    start_time = timeGetTime() / 1000.0f;
     
      	        glDrawElements(	
                        GL_TRIANGLES, 
    		    groupIndices, 
    	  	    GL_UNSIGNED_SHORT, 
    		    m_pGeometry[0]->m_indices 
                        );
     
                    end_time = timeGetTime() / 1000.0f;
                    sprintf(tmpStr, "VA CALL = %f", end_time - start_time);
                    MessageBox(NULL, tmpStr, "VA CALL", MB_OK );
                } 
     
    	} 
    }
    With the message box calls I could see the problem seems to be with glDrawElements. For VBOs, the call takes about 1.3 seconds.

    Any ideas what could be wrong ??

    Also, I downloaded a demo from Delphi3D that renders a terrain using VBOs. The demo renders about 2 million triangles and I get about 9fps. The only difference is that the demo uses an interleaved array for vertices/colors.
    Is there anything wrong with the way I setup the data in the VBOs?

    Thanks for any help!

  2. #2
    Senior Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    913

    Re: Problem with VBOs

    EDIT: Because the slowdown is so big it is possible that the driver is falling to sw fallback because of the limitations of the hardware (initially I assumed that this might be caused by bad interaction with the GPU caches however the numer triangles is low). Imho the most likely reason is the size of the offset (it is too big or there is too big difference between individual inputs) inside the VBO for normal and texture coordinate pointers. Try to use separate VBO for each part of the vertex or interleave them in single VBO.

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2006
    Posts
    14

    Re: Problem with VBOs

    Thanks for your reply Komat, I tried using a different VBO for normals and another for TexCoords but the result is still the same. If I interleave them in a single VBO how can I use multitexturing ? would I need a separate interleaved VBO for each texture ?

  4. #4
    Senior Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    913

    Re: Problem with VBOs

    Originally posted by Count Duckula:
    Thanks for your reply Komat, I tried using a different VBO for normals and another for TexCoords but the result is still the same.
    That is strange. What happens if you use only the position array without normals or texture coordinates?.


    If I interleave them in a single VBO how can I use multitexturing ? would I need a separate interleaved VBO for each texture ?
    No. I did not meant to use the InterleavedArrays api which is old and limited, you can interleave manually. The VBO will contain array of structures similiar to the following:
    Code :
    struct VertexStruct {
    float x, y, z ;
    float nx, ny, nz ;
    float u0, v0 ;
    float u1, v1 ;
    float u2, v2 ;
    }
    And then you will set the array pointers in such way that the stride is sizeof( VertexStruct ) and the offset corresponds to offset of corresponding fields within this structure (e.g. offset of u2 for the third texture coordinates array)

  5. #5
    Junior Member Newbie
    Join Date
    Sep 2006
    Posts
    14

    Re: Problem with VBOs

    Originally posted by Komat:
    That is strange. What happens if you use only the position array without normals or texture coordinates?.
    I've tried it and it shows the model but with flat color since normals are missing but the speed is the same.

    No. I did not meant to use the InterleavedArrays api which is old and limited, you can interleave manually. The VBO will contain array of structures similiar to the following:
    Code :
    struct VertexStruct {
    float x, y, z ;
    float nx, ny, nz ;
    float u0, v0 ;
    float u1, v1 ;
    float u2, v2 ;
    }
    And then you will set the array pointers in such way that the stride is sizeof( VertexStruct ) and the offset corresponds to offset of corresponding fields within this structure (e.g. offset of u2 for the third texture coordinates array)
    Ahh, ok , I hadn't understood that part. I'll try it as well.

  6. #6
    Senior Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    913

    Re: Problem with VBOs

    Originally posted by Count Duckula:
    I've tried it and it shows the model but with flat color since normals are missing but the speed is the same.
    With the same speed you meant that even with only the position it is slow with VBO and fast without VBO?

  7. #7
    Junior Member Newbie
    Join Date
    Sep 2006
    Posts
    14

    Re: Problem with VBOs

    Originally posted by Komat:
    With the same speed you meant that even with only the position it is slow with VBO and fast without VBO?
    Yep

  8. #8
    Senior Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    913

    Re: Problem with VBOs

    Which graphics card do you have?

  9. #9
    Senior Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    913

    Re: Problem with VBOs

    It is also possible that something different, unrelated to VBO, is causing sw vertex processing. Because the VBOs are likely to be stored in video memory, this might cause additional performance hit for the sw emulation.

  10. #10
    Junior Member Newbie
    Join Date
    Sep 2006
    Posts
    14

    Re: Problem with VBOs

    I have an ATI Mobility Radeon 7500 and I've just tried it on a GeForceFx 5500 and it's very different. On the 5500 I get almost the same speed with VA (160fps windowed, 190fps fs) and VBOs (180fps windowed, 200fps fs). I had thought it would run faster on one of those cards but maybe it's fillrate limited or it's just the pc that's not a high end one hehe..

    However, on the 7500, it seems like the driver doesn't like glDrawElements. I had a look at other VBO code on NeHe, basically what it does is duplicate the vertices so it doesn't use indices. I did the same for testing, so I use glDrawArrays instead of glDrawElements and it's better, it's about 8fps, but the VA is still about 70fps.

    One thing though... the NeHe code runs at about 60fps, and my duplicated vertices code runs at 8fps, so I might still be doing something stupid hehe.

Page 1 of 3 123 LastLast

Similar Threads

  1. Problem using VBOs
    By myk45 in forum OpenGL: Basic Coding
    Replies: 4
    Last Post: 11-08-2012, 11:13 PM
  2. Beginner problem with VBOs
    By jonny2011 in forum OpenGL: Basic Coding
    Replies: 1
    Last Post: 05-09-2011, 12:12 AM
  3. Problem with diffrent sizes of VBOs
    By christianmüller in forum OpenGL: Advanced Coding
    Replies: 0
    Last Post: 05-31-2010, 06:14 AM
  4. Problem with glDrawElements() via VBOs
    By Kip Warner in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 12-15-2009, 10:35 PM
  5. Problem with VBOs :)
    By OnTheRun in forum OpenGL: Basic Coding
    Replies: 6
    Last Post: 10-15-2004, 01:44 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean