I'm having trouble rendering a pretty large VBO of quads. This code appears to work fine on small meshes, yet when I try to render pretty large ones(58997 quads) from a single VBO it crashes specifically in
glDrawArrays( it->second.mType, 0, it->second.mNumPrimitives * it->second.mNumVertsPerPrimitive );
No call stack, just a single random address in the callstack window and the output windows shows
First-chance exception at 0x003ff829 in ET.exe: 0xC0000005: Access violation reading location 0x01e27000.
Unhandled exception at 0x003ff829 in ET.exe: 0xC0000005: Access violation reading location 0x01e27000.
If I remove for example the * it->second.mNumVertsPerPrimitive from the glDrawArrays I don't see the whole mesh.
Here's my construction and rendering code. Since I always get confused about whether various parameters means number of geometric primtives(quad, triangle, etc), or number of floats, I'm trying to wrap the VBO creation and rendering in some helper functions to hide it.
bool RenderBuffer::StaticBufferCreate( obuint32 & bufferId, const QuadList & primitives )
{
static int nextBufferId = 0;
StaticBufferDelete( bufferId );
if ( bufferId == 0 )
bufferId = ++nextBufferId;
glPushClientAttrib( GL_CLIENT_ALL_ATTRIB_BITS );
VBO v;
v.mType = GL_QUADS;
v.mNumPrimitives = primitives.size();
v.mNumVertsPerPrimitive = 4;
glGenBuffersARB( 1, &v.mBufferVertId );
glGenBuffersARB( 1, &v.mBufferColorId );
std::vector<float> coords( v.mNumPrimitives * v.mNumVertsPerPrimitive * 3 /* floats per vert */ );
std::vector<float> colors( v.mNumPrimitives * v.mNumVertsPerPrimitive * 4 /* floats per color */ );
coords.resize( 0 );
colors.resize( 0 );
for ( size_t i = 0; i < primitives.size(); ++i )
{
const Quad & q = primitives[ i ];
for ( size_t v = 0; v < 4; ++v )
{
coords.push_back( q.v[v].x );
coords.push_back( q.v[v].y );
coords.push_back( q.v[v].z );
colors.push_back( q.c.rF() );
colors.push_back( q.c.gF() );
colors.push_back( q.c.bF() );
colors.push_back( q.c.aF() );
}
}
GLsizeiptr vertexBytes = sizeof(float) * coords.size();
GLsizeiptr colorBytes = sizeof(float) * colors.size();
glBindBufferARB( GL_ARRAY_BUFFER_ARB, v.mBufferVertId );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, vertexBytes, &coords[ 0 ], GL_STATIC_DRAW_ARB );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, v.mBufferColorId );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, colorBytes, &colors[ 0 ], GL_STATIC_DRAW_ARB );
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
vbos.insert( std::make_pair( bufferId, v ) );
glPopClientAttrib();
return true;
}
And the drawing code
for ( size_t i = 0; i < mVBOList.size(); ++i )
{
VBOMap::const_iterator it = vbos.find( mVBOList[ i ] );
if ( it != vbos.end() )
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, it->second.mBufferVertId );
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, NULL /*start of buffer, no offset*/ );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, it->second.mBufferColorId );
glEnableClientState( GL_COLOR_ARRAY );
glColorPointer( 4, GL_FLOAT, 0, NULL /*start of buffer, no offset*/ );
glDrawArrays( it->second.mType, 0, it->second.mNumPrimitives * it->second.mNumVertsPerPrimitive );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
}
}