/*! Render the model; the time parameter is ignored right now * since this class doesn't currently support animation. */ void ModelGeometry::render(RenderContext& rc, double /* t */) { // The first time the mesh is rendered, we will try and place the // vertex data in a vertex buffer object and potentially get a huge // rendering performance boost. This can consume a great deal of // memory, since we're duplicating the vertex data. TODO: investigate // the possibility of deleting the original data. We can always map // read-only later on for things like picking, but this could be a low // performance path. if (!m_vbInitialized && isVBOSupported()) { m_vbInitialized = true; for (unsigned int i = 0; i < m_model->getMeshCount(); ++i) { Mesh* mesh = m_model->getMesh(i); const Mesh::VertexDescription& vertexDesc = mesh->getVertexDescription(); GLuint vboId = 0; if (mesh->getVertexCount() * vertexDesc.stride > MinVBOSize) { glGenBuffersARB(1, &vboId); if (vboId != 0) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId); glBufferDataARB(GL_ARRAY_BUFFER_ARB, mesh->getVertexCount() * vertexDesc.stride, mesh->getVertexData(), GL_STATIC_DRAW_ARB); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } } m_glData->vbos.push_back(vboId); } } unsigned int lastMaterial = ~0u; unsigned int materialCount = m_model->getMaterialCount(); // Iterate over all meshes in the model for (unsigned int meshIndex = 0; meshIndex < m_model->getMeshCount(); ++meshIndex) { Mesh* mesh = m_model->getMesh(meshIndex); GLuint vboId = 0; if (m_glData && meshIndex < m_glData->vbos.size()) { vboId = m_glData->vbos[meshIndex]; } if (vboId != 0) { // Bind the vertex buffer object. glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboId); rc.setVertexArrays(mesh->getVertexDescription(), NULL); } else { // No vertex buffer object; just use normal vertex arrays rc.setVertexArrays(mesh->getVertexDescription(), mesh->getVertexData()); } // Iterate over all primitive groups in the mesh for (unsigned int groupIndex = 0; groupIndex < mesh->getGroupCount(); ++groupIndex) { const Mesh::PrimitiveGroup* group = mesh->getGroup(groupIndex); // Set up the material const Material* material = NULL; unsigned int materialIndex = group->materialIndex; if (materialIndex != lastMaterial && materialIndex < materialCount) { material = m_model->getMaterial(materialIndex); } rc.setMaterial(material); rc.drawGroup(*group); } // If we set a VBO, unbind it. if (vboId != 0) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); } } }