VBO newbie

Moderator
Posts: 704
Joined: 2002.04
Post: #1
Greetings, I've hit performance problems rendering an environment in an app I'm developing, performance problems that I'm trying to ameliorate by implementing the environment as a VBO; unfortunately, I've been unable to develop even a prototype using a VBO - the best I've managed is a prototype which renders an off-white quad (which I'm assuming is my texture smeared across the quad Annoyed )

I'd appreciate it if anybody here could help point out where I'm going wrong...

Initialisation of the VBO is as follows:

Code:
glGenBuffers( 1, &m_VBO ); // m_VBO is a GLuint
glBindBuffer( GL_ARRAY_BUFFER, m_VBO );
const GLsizeiptr coordinatesSize = ( 4 * 2 * sizeof( GLfloat )); // 4 vertices * x and y coordinates per vertex
const GLsizeiptr textureCoordinatesSize = ( 4 * 2 * sizeof( GLfloat )); // Ditto
glBufferData( GL_ARRAY_BUFFER, ( coordinatesSize + textureCoordinatesSize ), 0, GL_STATIC_DRAW );
void *buffer = glMapBufferOES( GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES );
m_texture = new sealTexture( "texture" ); // Wrapper for (in this prototype) a texture atlas containing two textures, both 128x128
sealCoordinates c( 0, 0, 128, 128 ); // Wrapper for a quad built out of a GL_TRIANGLE_STRIP stored as GLfloat[ 8 ]; parameters are bottom-left x, bottom-left y, width, and height
memcpy( buffer, c.m_coordinates, ( sizeof( GLfloat ) * 4 * 2 ));
( size_t* )buffer += coordinatesSize;
memcpy( buffer, c.m_coordinates, ( sizeof( GLfloat ) * 4 * 2 ));
glUnmapBufferOES( GL_ARRAY_BUFFER );
glBindBuffer( GL_ARRAY_BUFFER, 0 );

Immediately following the above, initialisation of the VBO indices is as follows:

Code:
glGenBuffers( 1, &m_VBOIndices );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_VBOIndices );
const GLubyte indices[] = { 0, 1, 2, 3 }; // 4 vertices
glBufferData( GL_ELEMENT_ARRAY_BUFFER, ( 4 * sizeof(GLubyte)), 0, GL_STATIC_DRAW );
buffer = glMapBufferOES( GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY_OES );
memcpy( buffer, indices, 4 );
glUnmapBufferOES( GL_ELEMENT_ARRAY_BUFFER );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );

Rendering of the VBO is as follows:

Code:
glBindBuffer( GL_ARRAY_BUFFER, m_VBO );
m_texture->Bind(); // Binds the texture atlas and sets the texture matrix to the (pixel) dimensions of the texture atlas
glVertexPointer( 2, GL_FLOAT, 0, 0 );
glTexCoordPointer( 2, GL_FLOAT, 0, ( GLvoid* )( 4 * 2 * sizeof( GLfloat )));
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_VBOIndices );
glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );

(Also, I've read reports that VBOs bring no performance benefits...?)

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
( size_t* )buffer += coordinatesSize; looks suspect. Why are you offsetting the pointer by 4 * coordinatesSize (iOS) or 8 * coordinatesSize (Mac)?

If you're trying to solve performance problems, you should first profile to discover where your performance problems lie. If your problems are due to fill-rate limitations, using VBOs is unlikely to help a great deal. If they're due to CPU overhead of draw calls, they may help a lot.

There are now a lot of good tools for profiling OpenGL ES apps included with the developer tools, including the OpenGL ES Performance Detective and OpenGL ES Instrument (names from memory).
Quote this message in a reply
Member
Posts: 312
Joined: 2006.10
Post: #3
(Dec 27, 2011 06:04 PM)OneSadCookie Wrote:  ( size_t* )buffer += coordinatesSize; looks suspect. Why are you offsetting the pointer by 4 * coordinatesSize (iOS) or 8 * coordinatesSize (Mac)?

In addition to what OneSadCookie pointed out, do you mean for the same data to be used for both the vertices and texture coordinates (third line below)?

Code:
memcpy( buffer, c.m_coordinates, ( sizeof( GLfloat ) * 4 * 2 ));
( size_t* )buffer += coordinatesSize;
memcpy( buffer, c.m_coordinates, ( sizeof( GLfloat ) * 4 * 2 ));
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #4
(Dec 27, 2011 06:04 PM)OneSadCookie Wrote:  ( size_t* )buffer += coordinatesSize; looks suspect. Why are you offsetting the pointer by 4 * coordinatesSize (iOS) or 8 * coordinatesSize (Mac)?

Maybe I'm being an idiot, but because I'm trying to append the texture vertices to the end of the vertices? (ie. 1. copy the vertex array into the array beginning at the address of buffer; 2. the address of buffer += the size of the vertex array just copied; 3. copy the texture vertex array into the array beginning at the (updated) address of buffer) (and yes, I've read that the vertices and texture vertices should be interleaved for best performance Wink)

Anyway, it seems you are correct to be suspicious of that line; if I replace
Code:
memcpy( buffer, c.m_coordinates, ( sizeof( GLfloat ) * 4 * 2 ));
( size_t* )buffer += coordinatesSize;
memcpy( buffer, c.m_coordinates, ( sizeof( GLfloat ) * 4 * 2 ));
with
Code:
size_t loop = 0;
for( ; loop < 8; loop ++ )
{
    (( GLfloat* )buffer )[ loop ] = c.m_coordinates[ loop ];
    (( GLfloat* )buffer )[ ( loop + 8 ) ] = c.m_coordinates[ loop ];
}
the quad is rendered and textured; but I'm still not sure what I was doing wrong in the code I replaced...

(Dec 27, 2011 06:04 PM)OneSadCookie Wrote:  If you're trying to solve performance problems, you should first profile to discover where your performance problems lie.

No worries, I know to profile before trying to solve performance problems; anyway, even if VBOs are not of any help in solving this particular performance problem, it is good to expand my knowledge Wink
(Dec 27, 2011 06:52 PM)bronxbomber92 Wrote:  In addition to what OneSadCookie pointed out, do you mean for the same data to be used for both the vertices and texture coordinates [...] ?

In this instance yes, but thank you for the suggestion Wink

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Member
Posts: 312
Joined: 2006.10
Post: #5
(Dec 28, 2011 10:32 AM)sealfin Wrote:  [...] the quad is rendered and textured; but I'm still not sure what I was doing wrong in the code I replaced... [...]

Your vbo was allocated to hold coordinatesSize + textureCoordinatesSize bytes. Your thought process (2. the address of buffer += the size of the vertex array just copied;) was correct and your first memcpy was correct - copying coordinatesSize number of bytes into the beginning of the buffer. However, when you casted buffer to size_t* and then incremented by coordinatesSize, you weren't advancing by coordinatesSize number of bytes. Pointer arithmetic is relative to the size of the type of the pointer, so you were instead advancing by sizeof(size_t) * coordinatesSize number of bytes, which put you way past the end of your buffer.
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #6
(Dec 28, 2011 11:53 AM)bronxbomber92 Wrote:  Pointer arithmetic is relative to the size of the type of the pointer, so you were instead advancing by sizeof(size_t) * coordinatesSize number of bytes, which put you way past the end of your buffer.

...I tend to avoid pointer arithmetic and so had missed that. Totally. Blush

Thank you OneSadCookie, bronxbomber92 Smile

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Moderator
Posts: 704
Joined: 2002.04
Post: #7
(Dec 27, 2011 04:05 PM)sealfin Wrote:  (Also, I've read reports that VBOs bring no performance benefits...?)

I've just finished implementing the environment as a(n interleaved) VBO, and I thought I'd mention that – contrary to what I'd read – I've seen a significant performance improvement; previously, the app managed maybe 2fps when rendering the maximum size environment – now when rendering that size environment the app is managing ≥30fps Grin

Mark Bishop
--
Student and freelance OS X & iOS developer
Quote this message in a reply
Member
Posts: 227
Joined: 2008.08
Post: #8
I believe that VBOs offered no speed up before the 3GS, so that article is probably way outdated. Check your dates Wink Particularly the part where it says "Daniel Pasco wrote this on July 21, 2009."
Quote this message in a reply
Member
Posts: 312
Joined: 2006.10
Post: #9
Glad to see you found the speed up you were looking for!
Quote this message in a reply
Post Reply