How to generate data efficiently for a VBO.
I've set up a VBO in my program that displays an ammount of triangles.
But the class system that I use to transform my objects into a vertices, colors and normals vectors is way too inefficient.
I only get 9 fps while I generate the positions for 300 cubes containing 36 vertices, colors and normals each.
I've set my classes up in such a way.
A figure class has multiple vertices/colors/normals and a matrix.
An object class has multiple figure classes and another matrix.
each 1/50th of a second I update each cube's matrix and recalculate the vertices for it.
Now my question is if someone might point out to me what might be more efficient for my code. I would also be interested in how other people have set up their data line to their vbo's.
Why would you need to generate 300 cubes? 1 cube is enough.
Then use glScale to give it the size you want and render 300 times.
Then use glScale to give it the size you want and render 300 times.
300 cubes are just for the stress test.
It comes around to 10800 triangles.
And scale/movement and rotation are already done trough the matrixes.
Edit:
The point is that I can dynamicly make graphics with this engine.
[Edited by - Empty_Null on May 2, 2009 6:34:21 PM]
It comes around to 10800 triangles.
And scale/movement and rotation are already done trough the matrixes.
Edit:
The point is that I can dynamicly make graphics with this engine.
[Edited by - Empty_Null on May 2, 2009 6:34:21 PM]
I see.
Well, you have to pay attention to the format. I don't know what you are doing. You don't show any code but here are examples.
http://www.opengl.org/wiki/VBO#Sample_Code
and also
http://www.opengl.org/wiki/VBO_-_more#Dynamic_VBO
Well, you have to pay attention to the format. I don't know what you are doing. You don't show any code but here are examples.
http://www.opengl.org/wiki/VBO#Sample_Code
and also
http://www.opengl.org/wiki/VBO_-_more#Dynamic_VBO
This is how I set up the vbo
This is what I call every frame to either display vbo1 or vbo2 depending on which one is being updated
This is what I use to update the vbo.
[Edited by - Empty_Null on May 3, 2009 9:06:15 AM]
glGenBuffersARB(1, &vboId1); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId1); glBufferDataARB(GL_ARRAY_BUFFER_ARB, ((testVertices.size() + testNormals.size())*sizeof(float) + testColors.size()*sizeof(GLubyte)), NULL, GL_DYNAMIC_DRAW_ARB); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, testVertices.size()*sizeof(float), &testVertices[0]); // copy vertices starting from 0 offest glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, testVertices.size()*sizeof(float), testNormals.size()*sizeof(float), &testNormals[0]); // copy normals after vertices glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, (testVertices.size() + testNormals.size())*sizeof(float), testColors.size()*sizeof(unsigned char), &testColors[0]); // copy colours after normals glGenBuffersARB(1, &vboId2); glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId2); glBufferDataARB(GL_ARRAY_BUFFER_ARB, ((testVertices.size() + testNormals.size())*sizeof(float) + testColors.size()*sizeof(unsigned char)), NULL, GL_DYNAMIC_DRAW_ARB); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, testVertices.size()*sizeof(float), &testVertices[0]); // copy vertices starting from 0 offest glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, testVertices.size()*sizeof(float), testNormals.size()*sizeof(float), &testNormals[0]); // copy normals after vertices glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, (testVertices.size() + testNormals.size())*sizeof(float), testColors.size()*sizeof(unsigned char), &testColors[0]); // copy colours after normals
This is what I call every frame to either display vbo1 or vbo2 depending on which one is being updated
if(vboId){glBindBufferARB(GL_ARRAY_BUFFER, vboId1);} else{glBindBufferARB(GL_ARRAY_BUFFER, vboId2);} glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glNormalPointer(GL_FLOAT, 0, (GLvoid*)(testVertices.size()*sizeof(float))); glColorPointer(4, GL_UNSIGNED_BYTE, 0, (GLvoid*)((testVertices.size() + testNormals.size())*sizeof(float))); glVertexPointer(3, GL_FLOAT, 0, 0); //glDrawElements(GL_TRIANGLES, vertAmmount, GL_UNSIGNED_BYTE, 0); glDrawArrays(GL_TRIANGLES, 0, vertAmmount); glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
This is what I use to update the vbo.
if(vboId){glBindBufferARB(GL_ARRAY_BUFFER, vboId1);vboId = false;} else{glBindBufferARB(GL_ARRAY_BUFFER, vboId2);vboId = true;} glBufferDataARB(GL_ARRAY_BUFFER_ARB, ((testVertices.size() + testNormals.size())*sizeof(float) + testColors.size()*sizeof(unsigned char)), NULL, GL_DYNAMIC_DRAW_ARB); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, testVertices.size()*sizeof(float), &testVertices[0]); // copy vertices starting from 0 offest glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, testVertices.size()*sizeof(float), testNormals.size()*sizeof(float), &testNormals[0]); // copy normals after vertices glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, (testVertices.size() + testNormals.size())*sizeof(float), testColors.size()*sizeof(unsigned char), &testColors[0]); // copy colours after normals
[Edited by - Empty_Null on May 3, 2009 9:06:15 AM]
Try to not use color to see if it improves the speed.
Try another format, like 4 component RGBA GL_FLOAT color.
Try 4 component RGBA UNSIGNED_BYTE color.
Try another format, like 4 component RGBA GL_FLOAT color.
Try 4 component RGBA UNSIGNED_BYTE color.
I've now implemented an unsigned char rgba color scheme.
I've also updated my code in my previous post to reflect that.
I've tested my program a bit longer then usual and have noticed that it always starts out at 10fps.
But that it shoots to between 30 and 50fps after around 20 seconds.
Perhaps I've made an error in my fps control code.
I'll post it as well.
This code happens before drawing the vbo.
struct vertex{ float x, y, z; float normx, normy, normz; unsigned char red, green, blue, alpha; unsigned char buffer1;};
I've also updated my code in my previous post to reflect that.
I've tested my program a bit longer then usual and have noticed that it always starts out at 10fps.
But that it shoots to between 30 and 50fps after around 20 seconds.
Perhaps I've made an error in my fps control code.
I'll post it as well.
loops = 0; while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) { for ( Iter2 = testParticle.begin( ) ; Iter2 != testParticle.end( ) ; Iter2++ ){ Iter2->update();//these are the boxes and update changes the matrix for them } updateVBO();//vbo that isn't drawn is updated next_game_tick += SKIP_TICKS; loops++; } interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick ) / float( SKIP_TICKS ); dwFrames++; dwCurrentTime = GetTickCount(); // Even better to use timeGetTime() dwElapsedTime = dwCurrentTime - dwLastUpdateTime; if(dwElapsedTime >= 1000){ //to update the fps in the program header wsprintf(szFPS, "FPS = %u", (UINT)(dwFrames * 1000.0 / dwElapsedTime)); SetWindowText(hWnd,szFPS); dwFrames = 0; dwLastUpdateTime = dwCurrentTime; }
This code happens before drawing the vbo.
It seems my limiting the boxes to only update each 1/50th of a second was killing my fps.
I removed the while loop in my fps limiting code and update the boxes each frame.
Now I can handle 2200 boxes at a fps of 14.
Which comes down to 79200 vertices/colors/normals or 26400 triangles.
They might be some other things I might improve.
Because when I compare this to some of the games I play on my comp there's a big difference.
[Edited by - Empty_Null on May 3, 2009 3:09:49 PM]
I removed the while loop in my fps limiting code and update the boxes each frame.
Now I can handle 2200 boxes at a fps of 14.
Which comes down to 79200 vertices/colors/normals or 26400 triangles.
They might be some other things I might improve.
Because when I compare this to some of the games I play on my comp there's a big difference.
[Edited by - Empty_Null on May 3, 2009 3:09:49 PM]
Drawing boxes like that and trying to compare it against any real game is meaningless.
1) Your doing alot of really small draw calls(each draw call is relatively expensive).
2) Your updating the buffer each frame, why in the world are you doing that? Just pass the modified matrix into OGL, don't manually modify your vertices each frame.
1) Your doing alot of really small draw calls(each draw call is relatively expensive).
2) Your updating the buffer each frame, why in the world are you doing that? Just pass the modified matrix into OGL, don't manually modify your vertices each frame.
as other say doing what youre doing is pointless (try a real scene)
though in saying that it perhaps still seems slow (though depending on cpu)
just tried a simple slut app
(verts only)
10,000 boxs @ ~70fps a single draw call per box drawelements
drawbox()
{
glVertexPointer( 3, GL_FLOAT, 0, corners );
glEnableClientState( GL_VERTEX_ARRAY );
glDrawElements( GL_QUADS, 24, GL_UNSIGNED_SHORT, indices );
}
btw same speed in immediate
though in saying that it perhaps still seems slow (though depending on cpu)
just tried a simple slut app
(verts only)
10,000 boxs @ ~70fps a single draw call per box drawelements
drawbox()
{
glVertexPointer( 3, GL_FLOAT, 0, corners );
glEnableClientState( GL_VERTEX_ARRAY );
glDrawElements( GL_QUADS, 24, GL_UNSIGNED_SHORT, indices );
}
btw same speed in immediate
drawbox(){glBegin( GL_QUADS );for ( int i=0; i<24; i++ ) glVertex3fv( corners[ indices ] );glEnd();}srand(1234);for ( int i=0; i<10000; i++ ){ glPushMatrix(); glTranslatef( (rand()%100-50)*0.1, (rand()%100-50)*0.1, (rand()%100-50)*0.1 ); drawbox(); glPopMatrix();}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement