Hello,
I've spent the last week attempting to leverage vertex buffer objects within my resource management framework. I am not able to get anything to render with the vertex buffer objects I've created.
My suspicion is that I am doing something wrong with glBufferSubDataARB when I create my vbo's because when I use glGetBufferSubDataARB I get something back that looks like a single element instead of an array of data when I step through my code with msvc's debugger. Still glGetError doesn't detect anything is wrong and my application is stable so it doesn't crash and give me any clues what I'm doing wrong.
I can see anything I render in immediate mode but my vbo's simply won't cooperate with me :(
Below I've provided the code for when I create and use my vbos. The code isn't in final state since I just wanted to see something get to screen before I get too far along.
Any ideas as to where I am messing up would be much appreciated.
void OglVbo_Resource::Create()
{
/************************************************************************/
/* If the resource is already initialized then avoid doing costly work */
/* for no purpose. */
/************************************************************************/
if ( this->_initialized )
{
return;
}//end if
/************************************************************************/
/* Initialize function pointers to Opengl extensions */
/************************************************************************/
GLenum glewStatus = glewInit();
if ( glewStatus != GLEW_OK )
{
assert( glewStatus != GLEW_OK && "Problem: glewInit failed, something is seriously wrong." );
return;
}//end if
/************************************************************************/
/* Convert MetaData to usable form */
/************************************************************************/
/************************************************************************/
/* calculate how many bytes the primary buffer in the VBO will store. */
/************************************************************************/
GLsizeiptr totalBytes( 0 );
unsigned int NumSubBuffers( this->_metadata->_subBufferCount );
std::vector<GLsizeiptr> bytesPerBuffer( NumSubBuffers );
//run through the subBuffer data
for ( unsigned int i = 0; i < NumSubBuffers; ++i )
{
/************************************************************************/
/* Calculate the number of bytes in the SubbBuffer. */
/************************************************************************/
if ( this->_metadata->_subBufferInfo[0] == "float" || this->_metadata->_subBufferInfo[0] == "GLfloat" )
{
bytesPerBuffer = sizeof( GLfloat ) *
stringToNumeric<unsigned int>( this->_metadata->_subBufferInfo[1] );
}
else if ( this->_metadata->_subBufferInfo[0] == "double" || this->_metadata->_subBufferInfo[0] == "GLdouble" )
{
bytesPerBuffer = sizeof( GLdouble ) *
stringToNumeric<unsigned int>( this->_metadata->_subBufferInfo[1] );
}
else if ( this->_metadata->_subBufferInfo[0] == "int" || this->_metadata->_subBufferInfo[0] == "GLint" )
{
bytesPerBuffer = sizeof( GLint ) *
stringToNumeric<unsigned int>( this->_metadata->_subBufferInfo[1] );
}
else if ( this->_metadata->_subBufferInfo[0] == "unsigned int" || this->_metadata->_subBufferInfo[0] == "GLuint" )
{
bytesPerBuffer = sizeof( GLuint ) *
stringToNumeric<unsigned int>( this->_metadata->_subBufferInfo[1] );
}
else if ( this->_metadata->_subBufferInfo[0] == "char" || this->_metadata->_subBufferInfo[0] == "GLbyte" )
{
bytesPerBuffer = sizeof( GLbyte ) *
stringToNumeric<unsigned int>( this->_metadata->_subBufferInfo[1] );
}
else
{
bytesPerBuffer = sizeof( GLubyte ) *
stringToNumeric<unsigned int>( this->_metadata->_subBufferInfo[1] );
}//end if
/************************************************************************/
/* Update the number of bytes in the primary buffer as a whole. */
/************************************************************************/
totalBytes += bytesPerBuffer;
}//end for
/************************************************************************/
/* Select proper data transfer mode. */
/************************************************************************/
GLenum transferMode;
if ( this->_metadata->_transferMode == "GL_STATIC_DRAW" )
{
transferMode = GL_STATIC_DRAW_ARB;
}
else if ( this->_metadata->_transferMode == "GL_STREAM_DRAW" )
{
transferMode = GL_STREAM_DRAW_ARB;
}
else
{
transferMode = GL_DYNAMIC_DRAW_ARB;
}//end if
/************************************************************************/
/* Instantiate vertex buffer object. */
/************************************************************************/
GLuint vboID( 0 );
glGenBuffersARB( 1,&vboID );
glBindBufferARB( GL_ARRAY_BUFFER_ARB,vboID );
glBufferDataARB(
GL_ARRAY_BUFFER_ARB,
totalBytes,
NULL,
transferMode
);
/************************************************************************/
/* Initialize vertex buffer object */
/************************************************************************/
//run through the SubBuffers
GLintptr offset( 0 );
for ( unsigned int i = 0; i < this->_metadata->_subBufferCount ; ++i )
{
glBufferSubDataARB(
GL_ARRAY_BUFFER_ARB,
offset,
bytesPerBuffer,
static_cast<void *>( this->_metadata->_subBufferData.get() )
);
offset += bytesPerBuffer;
}//end for
boost::shared_array<GLfloat> dataPtr( new GLfloat[offset/sizeof(GLfloat)] );
glGetBufferSubDataARB( GL_ARRAY_BUFFER_ARB,0,offset/sizeof(GLfloat),(void*)dataPtr.get() );
assert( glGetError() == 0 );
/************************************************************************/
/* Instantiate and initialize index buffer object */
/************************************************************************/
GLuint indexID( 0 );
if ( this->_metadata->_indexBufferData.size() )
{
glGenBuffersARB( 1,&indexID );
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,indexID );
glBufferDataARB(
GL_ELEMENT_ARRAY_BUFFER_ARB,
sizeof( unsigned int ) * this->_metadata->_indexBufferData.size(),
static_cast<void *>( &this->_metadata->_indexBufferData[0] ),
transferMode
);
}//end if
/************************************************************************/
/* Reset client state */
/************************************************************************/
glBindBufferARB( GL_ARRAY_BUFFER_ARB,0 );
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,0 );
/************************************************************************/
/* Create the resource handle. */
/************************************************************************/
this->_realResourceInstance =
Resource<std::pair<GLuint,GLuint> >::ResInstance( new std::pair<GLuint,GLuint>( vboID,indexID ) );
/************************************************************************/
/* Set the signal flag stating the Resource is initialized. */
/************************************************************************/
this->_initialized = true;
}
void OglDisplayWindow::draw()
{
if ( !GlWindow::valid() )
{
/************************************************************************/
/* Just tell the global manager to create any "gl" resources here :) */
/* The needed contexts will be active here etc. */
/* Here's another tip! :) */
/* You can use the member Create of Resource to Create VBOs OR to act */
/* as an Opengl init routine! Just like I do :) */
/* */
/* Checkout the OglInitializer_Resource class too see how to virtualize */
/* init methods. */
/************************************************************************/
GlobalResourceManager::GetSingleton()->CreateResources( ResourceInfo::Ogl );
}
/************************************************************************/
/* Have the Render Manager instruct all Renderers to draw their portion */
/* of the scene. */
/************************************************************************/
//temp code to see something
// clear buffer
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
static GLfloat zAngle( 0 );
static GLfloat xAngle( 0 );
static cml::vector3f zAxis( 0,0,1 );
static cml::vector3f xAxis( 1,0,0 );
static cml::vector3f position( 0,5,0 );
glPushMatrix();
GlRotateTraits<GLfloat>::rotate( ( zAngle < 360 ) ? zAngle +=1.5f : zAngle = 0,zAxis );
//GlRotateTraits<GLfloat>::rotate( ( xAngle < 360 ) ? xAngle +=.5f : xAngle = 0,xAxis );
//GlTranslateTraits<GLfloat>::translate( position );
glBegin( GL_TRIANGLES );
glColor3f( 1,0,0 );
glVertex3f( 1,-1,0 );
glColor3f( 0,1,0 );
glVertex3f( 0,1,0 );
glColor3f( 0,0,1 );
glVertex3f( -1,-1,0 );
glEnd();
glBegin( GL_TRIANGLES );
glColor3f( 0,0,1 );
glVertex3f( -1,-1,0 );
glColor3f( 0,1,0 );
glVertex3f( 0,1,0 );
glColor3f( 1,0,0 );
glVertex3f( 1,-1,0 );
glEnd();
glPopMatrix();
glPushMatrix();
GlRotateTraits<GLfloat>::rotate( ( xAngle < 360 ) ? xAngle +=.5f : xAngle = 0,xAxis );
//GlTranslateTraits<GLfloat>::translate( position );
boost::shared_ptr<ResourceManager_Impl_MapBased<OglVbo_Resource> > VBOManager = VBOManager->GetSingleton();
boost::shared_ptr<OglVbo_Resource> TriangleVBO = VBOManager->GetResourceWrapper<OglVbo_Resource>( "Triangle" );
OglVbo_Resource::MetaData * VBO_MetaData =
static_cast<OglVbo_Resource::MetaData *>( TriangleVBO->GetMetaData().get() );
/************************************************************************/
/* Extract the data transfer mode */
/************************************************************************/
static GLenum transferMode;
if ( VBO_MetaData->_transferMode == "GL_STATIC_DRAW" )
{
transferMode = GL_STATIC_DRAW_ARB;
}
else if ( VBO_MetaData->_transferMode == "GL_STREAM_DRAW" )
{
transferMode = GL_STREAM_DRAW_ARB;
}
else
{
transferMode = GL_DYNAMIC_DRAW_ARB;
}//end if
/************************************************************************/
/* Bind to the vertex buffer object */
/************************************************************************/
std::pair<GLuint,GLuint> VBO_IDS = *static_cast<std::pair<GLuint,GLuint> *>( TriangleVBO->GetResInstance().get() );
assert( glIsBufferARB( VBO_IDS.first ) );
glBindBufferARB( GL_ARRAY_BUFFER_ARB,VBO_IDS.first );
//run through the SubBuffers
static unsigned int stride;
static unsigned int byteCount;
byteCount = 0;
static std::stringstream converter;
converter.clear();
converter.str( "" );
static unsigned int NumElements;
static GLenum DataType;
static unsigned int componentsPerElem;
componentsPerElem = 0;
static unsigned int i;
for ( i = 0; i < VBO_MetaData->_subBufferCount ; ++i )
{
/************************************************************************/
/* Select the DataType and proper stride */
/************************************************************************/
if ( VBO_MetaData->_subBufferInfo[0] == "float" || VBO_MetaData->_subBufferInfo[0] == "GLfloat" )
{
DataType = GL_FLOAT;
stride = sizeof( GLfloat );
}
else if ( VBO_MetaData->_subBufferInfo[0] == "double" || VBO_MetaData->_subBufferInfo[0] == "GLdouble" )
{
DataType = GL_DOUBLE;
stride = sizeof( GLdouble );
}
else if ( VBO_MetaData->_subBufferInfo[0] == "int" || VBO_MetaData->_subBufferInfo[0] == "GLint" )
{
DataType = GL_INT;
stride = sizeof( GLint );
}
else if ( VBO_MetaData->_subBufferInfo[0] == "unsigned int" || VBO_MetaData->_subBufferInfo[0] == "GLuint" )
{
DataType = GL_UNSIGNED_INT;
stride = sizeof( GLuint );
}
else if ( VBO_MetaData->_subBufferInfo[0] == "char" || VBO_MetaData->_subBufferInfo[0] == "GLbyte" )
{
DataType = GL_BYTE;
stride = sizeof( GLbyte );
}
else
{
DataType = GL_UNSIGNED_BYTE;
stride = sizeof( GLubyte );
}//end if
/************************************************************************/
/* Extract the number of elements in the SubBuffer */
/************************************************************************/
converter<<VBO_MetaData->_subBufferInfo[1];
converter>>NumElements;
converter.clear();
converter.str( "" );
/************************************************************************/
/* Create the correct gl*Pointers and set the proper client state */
/************************************************************************/
converter<<VBO_MetaData->_subBufferInfo[2];
converter>>componentsPerElem;
converter.clear();
converter.str( "" );
componentsPerElem = NumElements / componentsPerElem;
if ( VBO_MetaData->_subBufferInfo[3] == "vertex" )
{
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(
componentsPerElem,
DataType,
stride,
static_cast<void *>( &byteCount )
);
}
else if ( VBO_MetaData->_subBufferInfo[3] == "normal" )
{
glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer(
componentsPerElem,
stride,
static_cast<void *>( &byteCount )
);
}
else if ( VBO_MetaData->_subBufferInfo[3] == "color" )
{
glEnableClientState( GL_COLOR_ARRAY );
glColorPointer(
componentsPerElem,
DataType,
stride,
static_cast<void *>( &byteCount )
);
}
else if ( VBO_MetaData->_subBufferInfo[3] == "texture" )
{
//need a texture manager and a texture resource.
//glEnableClientState( GL_TEXTURE_COORD_ARRAY );
continue;
}
/************************************************************************/
/* update the byte count */
/************************************************************************/
byteCount += NumElements * stride;
}//end for
/************************************************************************/
/* Draw what's in the vertex buffer object */
/************************************************************************/
if ( !VBO_MetaData->_indexBufferData.size() )
{
glDrawArrays(
GL_TRIANGLES,
0,
6
);
}
else
{
assert( glIsBufferARB( VBO_IDS.second ) );
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,VBO_IDS.second );
glDrawElements(
GL_TRIANGLES,
VBO_MetaData->_indexBufferData.size(),
GL_UNSIGNED_INT,
NULL
);
}//end if
/************************************************************************/
/* Reset the client state */
/************************************************************************/
for ( i = 0; i < VBO_MetaData->_subBufferCount ; ++i )
{
if ( VBO_MetaData->_subBufferInfo[3] == "vertex" )
{
glDisableClientState( GL_VERTEX_ARRAY );
}
else if ( VBO_MetaData->_subBufferInfo[3] == "normal" )
{
glDisableClientState( GL_NORMAL_ARRAY );
}
else if ( VBO_MetaData->_subBufferInfo[3] == "color" )
{
glDisableClientState( GL_COLOR_ARRAY );
}
else if ( VBO_MetaData->_subBufferInfo[3] == "texture" )
{
//need a texture manager and a texture resource.
//glDisableClientState( GL_TEXTURE_COORD_ARRAY );
}
}//end for
glBindBufferARB( GL_ARRAY_BUFFER_ARB,0 );
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB,0 );
glPopMatrix();
}
[Edited by - Simulacrum on October 30, 2008 11:14:23 AM]
The difference between a dream and reality is only what you choose to do about either of them.