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 *n*^{th} opinion

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 ); }