Jump to content
  • Advertisement
Sign in to follow this  
cty41

OpenGL [question]how to optimize vbo

This topic is 2761 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, guys. I am newbies for opengl (and es), first sorry for posting this thread from powervr forums(...cause no one responsed..) Anyway,now I am developing a ipad game, we have finish most of the game, now we plan to optimize it(for quick develop and save money~, we just use most functions and classes which powervr sdk support).

now our fps is pretty (the best scene is 34~36 when polys num is about 16k, the worse is about 10 when polys num is about 40k),I know the performance is depend on many factors, so I thought and searched for a while. and I wonder whether we use vbo correctly, because we found very strange that some place we use vbo can boost the fps but some another place it did negative effort(slow donw the fps!?):
we just followed and powerVR's trainning course(07_IntroducingPOD) and create single vbo and index vbo for each submesh in a model, but these days I read the <POWERVR SGX.OpenGL ES 2.0 Application Development Recommendations.1.8f.External> , it suggest just not to do that ,it said group meshes to create a big vbo will be better, and I searched the forums did not find a very good answer(sorry for my poor search skill) .And I wrote the code by myself, and problem came..

here is my setup vbo code for <07_IntroducingPOD>(did not change other parts):

bool OGLES2IntroducingPOD::LoadVbos(CPVRTString* pErrorStr)
{
if(!m_Scene.pMesh[0].pInterleaved)
{
*pErrorStr = "ERROR: IntroducingPOD requires the pod data to be interleaved. Please re-export with the interleaved option enabled.";
return false;
}

//pool test
glGenBuffers(1, &m_VboPools);
glGenBuffers(1, &m_IndexVboPools);

unsigned int wholeMeshSize = 0, wholeIndexSize = 0;
for (unsigned int i = 0; i < m_Scene.nNumMesh; ++i)
{
SPODMesh& Mesh = m_Scene.pMesh;
unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride;
wholeMeshSize += uiSize;
if (Mesh.sFaces.pData)
{
unsigned int uiIndexSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort);
wholeIndexSize += uiIndexSize;
}
}

//vbo
glBindBuffer(GL_ARRAY_BUFFER, m_VboPools);
glBufferData(GL_ARRAY_BUFFER, wholeMeshSize, 0, GL_STATIC_DRAW);

//index vbo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexVboPools);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, wholeIndexSize, 0, GL_STATIC_DRAW);

unsigned int meshOffset = 0, indexOffset = 0;
for (unsigned int i = 0; i < m_Scene.nNumMesh; ++i)
{
// Load vertex data into buffer object
SPODMesh& Mesh = m_Scene.pMesh;
unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride;
glBufferSubData(GL_ARRAY_BUFFER, meshOffset, uiSize, Mesh.pInterleaved);
meshOffset += uiSize;
if (Mesh.sFaces.pData)
{
uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, indexOffset, uiSize, Mesh.sFaces.pData);
}
indexOffset += uiSize;

}
}
....
void OGLES2IntroducingPOD::DrawMesh(int i32NodeIndex)
{
..
// test
glBindBuffer(GL_ARRAY_BUFFER, m_VboPools);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IndexVboPools);
...
glVertexAttribPointer...
...
// Indexed Triangle list
glDrawElements(GL_TRIANGLES, pMesh->nNumFaces*3, GL_UNSIGNED_SHORT, 0);
...
}



but I got some wrong result, here is pics:
wrong result

right:
correct result



I thought there is some steps I forgot to set( I only create a big vbo and copy the mesh data to it), but I did not find any sources to tell me how to do, so is there anyone who can give a advice or any informations? I will be very appericated!

Best regards,
Franky

Share this post


Link to post
Share on other sites
Advertisement
first, the recommended fastest way to draw VBOs is as you already to to interleave the vertex attributes another thing which is recommended that the data for one vertex should be a multiple of 32bit.

so often u have only position, normal and texcoord which sums up to 32 luckily((3+3+2)*4 = 32). But if u you less, more or different vertex attributes be sure to pad always up to the next multiple (32,64,...)

after that u can try to optimize your meshes to reduce overdraw and optimise for the Transformation Cache(there are many different algorithms out there, but AMD's Tootle was the only free tool which does this that i could find).

Another optimization step would be to look at your scene you are rendering. Only dynamic stuff should be in it's one vbo. When you for example have a little forest, combine all the different trees into one single vbo.


ps: the approach you are trying just saves u all the buffer bindings and attribute pointer setting. I think there is no big performance issue with that, especially when u use VAOs.

pps:
I think your problem is that u don't offset into the index list when drawing.

Share this post


Link to post
Share on other sites
Check out this link for all apples recommendations for vertex data practises. You will need to sign on with your apple dev id, but it'll still work if you have the free account.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!