GLboolean MaterialGroup::UploadData()
{
/* Copy all data into one array. */
data.clear();
data.insert(data.end(), Vertices.begin(), Vertices.end());
data.insert(data.end(), TexCoords.begin(), TexCoords.end());
data.insert(data.end(), Normals.begin(), Normals.end());
/* Calculate some statistics. */
faces = (Vertices.size() / 3) / 3;
vertexCount = Vertices.size() / 3;
texCoordCount = TexCoords.size() / 2;
normalCount = Normals.size() / 3;
hasTexture = Mat.Texture.IsAllocated && texCoordCount > 0;
hasNormals = normalCount > 0;
/* Only bother uploading if we have geometric data. */
if(Vertices.size() > 0)
{
/* Delete any existing buffer. */
if(glIsBuffer(VBO))
glDeleteBuffers(1, &VBO);
/* Generate and bind the vertex array. */
if(!glIsVertexArray(VAO))
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
/* Generate a new buffer. */
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(GLfloat), &data.at(0), GL_STATIC_DRAW);
glVertexAttribPointer(Attribute_Position, 3, GL_FLOAT, GL_FALSE, 0, &data.at(0));
/* If we have texcoords, set the pointer to them. */
if(texCoordCount)
glVertexAttribPointer(Attribute_Texture0, 2, GL_FLOAT, GL_FALSE, 0, &data.at(Vertices.size()));
/* if we have normals, set the pointer to them. */
if(normalCount)
glVertexAttribPointer(Attribute_Normal, 3, GL_FLOAT, GL_FALSE, 0, &data.at(Vertices.size() + TexCoords.size()));
}
else
{
/* We don't have any geometric data. Let's leave. */
data.clear();
return GL_FALSE;
}
/* Temp data is no longer needed. */
TempVertices.clear();
TempTexCoords.clear();
TempNormals.clear();
/* Success! */
return GL_TRUE;
}
GLvoid MaterialGroup::Draw()
{
/* Bind any textures and set any colors. */
Mat.Bind();
/* Only draw if we've uploaded. */
if(data.size() > 0)
{
/* Bind the vertex array before anything. */
glBindVertexArray(VAO);
/* Bind our VBO and setup vertex drawing. */
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glEnableVertexAttribArray(Attribute_Position);
/* If we have texture coords, set them up. */
if(hasTexture)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, (GLvoid*)(texCoordCount * 2));
glEnableVertexAttribArray(Attribute_Texture0);
}
/* If we have normals, set them up. */
if(hasNormals)
{
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(3, GL_FLOAT, (GLvoid*)((texCoordCount * 2) + (normalCount * 3)));
glEnableVertexAttribArray(Attribute_Normal);
}
/* Draw a point outline of out model. */
glDrawArrays(GL_POINTS, 0, vertexCount);
/* Disable states and attributes. */
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableVertexAttribArray(Attribute_Position);
glDisableVertexAttribArray(Attribute_Texture0);
glDisableVertexAttribArray(Attribute_Normal);
}
/* Unbind our texture. */
Mat.UnBind();
}