Hi there, I've got some OpenGL 3.3+ rendering code that's not quite where it should be at in terms of behaviour, so I thought I'd get an nth opinion :P
All my vertex data is in separate buffers - no interleaved stuff happening here - however, I do have vertex position, normal, and UV data that I'd like to get into the shaders.
The problem seems to be my understanding and usage of glEnableVertexAttribArray and glVertexAttribPointer.. et la:
Any obvious errors/bus/issues?
Thanks in advance
// elsewhere:
#define POSITION_ATTRIBS 0
#define NORMAL_ATTRIBS 1
//etc
bool GL_VAO::OnCard(GeometryData* geometry)
{
if( onCard == true )
return true;
topology = geometry->GetTopology();
if( _VAO == -1 )
{
glGenVertexArrays( 1, &_VAO ); //Allocate an OpenGL VAO
glBindVertexArray( _VAO ); //Bind the VAO to store all the buffers and attributes we create here
if( _VxBuffer == -1 && geometry->numVerts != 0 )
{ //position data
numVertices = geometry->numVerts;
glGenBuffers(1, &_VxBuffer); //Generate an ID for the Vertex Buffer
glBindBuffer(GL_ARRAY_BUFFER, _VxBuffer); //Bind the Vertex Buffer and load the vertices into the Vertex Buffer
glBufferData(GL_ARRAY_BUFFER, geometry->Vertices()->BufferSizeBytes(), geometry->Vertices()->Data(), GL_STATIC_DRAW);
glVertexAttribPointer( POSITION_ATTRIBS, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid * ) 0 );
glEnableVertexAttribArray( POSITION_ATTRIBS );
}
if( _NxBuffer == -1 && geometry->numNorms != 0 )
{ // normal data
glGenBuffers(1, &_NxBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _NxBuffer);
glBufferData(GL_ARRAY_BUFFER, geometry->Normals()->BufferSizeBytes(), geometry->Normals()->Data(), GL_STATIC_DRAW);
glVertexAttribPointer( NORMAL_ATTRIBS, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid * ) 0 ); //attribute 1 gets normal data
glEnableVertexAttribArray( NORMAL_ATTRIBS );
}
if( _TxBuffer == -1 && geometry->numUVs != 0 )
{ // texcoord data
glGenBuffers(1, &_TxBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _TxBuffer);
glBufferData(GL_ARRAY_BUFFER, geometry->Textures()->BufferSizeBytes(), geometry->Textures()->Data(), GL_STATIC_DRAW);
glVertexAttribPointer( UV0_ATTRIBS, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid * ) 0 ); //attribute 3, UV data, is paits of two unnormalised flots with no offsets
glEnableVertexAttribArray( UV0_ATTRIBS );
}
if( _IxBuffer == -1 && geometry->GetIndicesCount() != 0 )
{ // Faces / Indices
numIndices = unsigned int(geometry->GetIndicesCount());
glGenBuffers(1, &_IxBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _IxBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, geometry->Indices()->BufferSizeBytes() , geometry->Indices()->Data(), GL_STATIC_DRAW);
}
}
if( _VAO != -1 )
{
glBindVertexArray(0); //done binding to meshVAO
onCard = true;
}
return onCard;
}
void GL_VAO::Render()
{
glBindVertexArray( _VAO );
glVertexAttribPointer( POSITION_ATTRIBS, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid * ) 0 );
glEnableVertexAttribArray( POSITION_ATTRIBS );
glVertexAttribPointer( NORMAL_ATTRIBS, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0 );
glEnableVertexAttribArray( NORMAL_ATTRIBS );
glPolygonMode( GL_FRONT_AND_BACK, fillmode );
if(numIndices > 0)
glDrawElements( topology, numIndices, GL_UNSIGNED_INT, (const GLvoid*)0 );
else
glDrawArrays( topology, 0, numVertices );
glDisableVertexAttribArray(POSITION_ATTRIBS);
glDisableVertexAttribArray(NORMAL_ATTRIBS);
glBindVertexArray( 0 );
}