[VBO] One big buffer for everything

Started by
1 comment, last by AzraelilMeraz 15 years, 6 months ago
Hello GameDev I've got a simple but working 3D-Renderer based on VBOs. I've had a single Buffer for each vertex attribute before. Here's the code: rendering:
void ALSAGE_OGL::drawMesh(int Id,AL_Vector pos,AL_Vector scale, int TexId)
{
    glScalef(scale.x,scale.y,scale.z);
    glDisable(GL_LIGHTING);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    if(TexId != -1) glBindTexture(GL_TEXTURE_2D, textures[TexId].Name);

    if(lastMesh != Id)
    {

        glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[2]);
        glColorPointer(4, GL_UNSIGNED_BYTE, 0,0);

        glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[3]);
        glTexCoordPointer(2, GL_FLOAT, 0,0);

        glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[4]);
        glNormalPointer(GL_FLOAT, 0,0);


        glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[0]);
        glVertexPointer(3, GL_FLOAT, 0,0);

        lastMesh = Id;
    }
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,meshes[Id].VBO[1]);
    glDrawRangeElements(GL_TRIANGLES, 0,meshes[Id].numTris*3-1,meshes[Id].numTris*3,
                        GL_UNSIGNED_INT,NULL);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindBuffer(GL_ARRAY_BUFFER,0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
}
loading:
int ALSAGE_OGL::loadMesh(AL_Char* filename)
{
    AL_Mesh* mesh = new AL_Mesh;
    AL_byte nBufs = 5;
    mesh->loadFromFile(filename);
    meshes[numMeshes].numVert = mesh->vertCount();
    meshes[numMeshes].numTris = mesh->TrisCount();


    glGenBuffers(nBufs, meshes[numMeshes].VBO);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, meshes[numMeshes].VBO[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, meshes[numMeshes].numTris*sizeof(AL_Triangle),
                 mesh->getTrianglePointer(), GL_STREAM_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[2]);
    glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertCol),
                 mesh->getColorPointer(), GL_STREAM_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[3]);
    glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertTex),
                 mesh->getUVCoordPointer(), GL_STREAM_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[4]);
    glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertNor),
                 mesh->getNormalPointer(), GL_STREAM_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[0]);
    glBufferData(GL_ARRAY_BUFFER, meshes[numMeshes].numVert*sizeof(AL_VertCrd),
                 mesh->getCoordPointer(), GL_STREAM_DRAW);
    numMeshes++;
    delete mesh;

    return numMeshes-1;
}
Now I want to pack those Buffers into one single Buffer for better performance. I dont want to use interleaved arrays, but packed arrays. first I did this:
glBufferData(GL_ARRAY_BUFFER, 
                 meshes[numMeshes].numVert*sizeof(AL_VertTex),
                 0, 
                 GL_STREAM_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER,
                    0,
                    meshes[numMeshes].numVert*sizeof(AL_VertTex),
                    mesh->getUVCoordPointer());
Everything is ok, it renders fine. Then I tried this: (lines 17-22 in loading):
glBufferData(GL_ARRAY_BUFFER, 
                 meshes[numMeshes].numVert*(sizeof(AL_VertCol)+sizeof(AL_VertTex)),
                 0, 
                 GL_STREAM_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER,
                    0,
                    meshes[numMeshes].numVert*sizeof(AL_VertCol),
                    mesh->getColorPointer());

    /*glBindBuffer(GL_ARRAY_BUFFER, meshes[numMeshes].VBO[3]);
    glBufferData(GL_ARRAY_BUFFER, 
                 meshes[numMeshes].numVert*sizeof(AL_VertTex),
                 0, 
                 GL_STREAM_DRAW);*/
    glBufferSubData(GL_ARRAY_BUFFER,
                    meshes[numMeshes].numVert*sizeof(AL_VertCol),
                    meshes[numMeshes].numVert*sizeof(AL_VertTex),
                    mesh->getUVCoordPointer());
changing the lines 13-17 in rendering to this:
glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[2]);
        glColorPointer(4, GL_UNSIGNED_BYTE, 0,0);

        //glBindBuffer(GL_ARRAY_BUFFER,meshes[Id].VBO[3]);
        glTexCoordPointer(2, GL_FLOAT, 0,
            BUFFER_OFFSET(meshes[numMeshes].numVert*sizeof(AL_VertCol)));
the result: http://b.imagehost.org/view/0899/bug.png the Textur Coordinates are completely off. So, what did I do wrong?
Advertisement
Personally I put the offset in to parameter 2 of glDrawArrays(), there was a reason but I forget what it was!
??
I don't even use glDrawArrays :(

edit: I hate those stupid mistakes :(:

glTexCoordPointer(2, GL_FLOAT, 0,            BUFFER_OFFSET(meshes[numMeshes].numVert*sizeof(AL_VertCol)));

->
glTexCoordPointer(2, GL_FLOAT, 0,            BUFFER_OFFSET(meshes[Id].numVert*sizeof(AL_VertCol)));


[Edited by - AzraelilMeraz on October 6, 2008 2:40:37 PM]

This topic is closed to new replies.

Advertisement