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?