void GLC_Mesh::OverwriteTransparencyAndMaterialRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) { // Get transparency value const float alpha= renderProperties.overwriteTransparency(); Q_ASSERT(-1.0f != alpha); // Get the overwrite material GLC_Material* pOverwriteMaterial= renderProperties.overwriteMaterial(); Q_ASSERT(NULL != pOverwriteMaterial); pOverwriteMaterial->glExecute(alpha); if (m_IsSelected) GLC_SelectionMaterial::glExecute(); LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) { GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); // Test if the current material is renderable bool materialIsrenderable = (renderProperties.renderingFlag() == glc::TransparentRenderFlag); // Choose the primitives to render if (m_IsSelected || materialIsrenderable) { if (vboIsUsed) vboDrawPrimitivesOf(pCurrentGroup); else vertexArrayDrawPrimitivesOf(pCurrentGroup); } ++iGroup; } }
// The primitive Selected render loop void GLC_Mesh::primitiveSelectedRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) { const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag); LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) { GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id()); // Test if the current material is renderable const bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent); if (materialIsrenderable) { pCurrentMaterial->glExecute(); } if (vboIsUsed) vboDrawSelectedPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties); else vertexArrayDrawSelectedPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties); ++iGroup; } }
// Virtual interface for OpenGL Geometry properties. void GLC_Geometry::glPropGeom(const GLC_RenderProperties& renderProperties) { glLineWidth(lineWidth()); if(m_IsWire) { glLineWidth(m_LineWidth); glDisable(GL_LIGHTING); if (!renderProperties.isSelected()) { // Set polyline colors GLfloat color[4]= {static_cast<float>(m_WireColor.redF()), static_cast<float>(m_WireColor.greenF()), static_cast<float>(m_WireColor.blueF()), static_cast<float>(m_WireColor.alphaF())}; glColor4fv(color); } else { GLC_SelectionMaterial::glExecute(); } } else if (m_MaterialHash.size() == 1) { GLC_Material* pCurrentMaterial= m_MaterialHash.begin().value(); if (pCurrentMaterial->hasTexture()) { glEnable(GL_LIGHTING); pCurrentMaterial->glExecute(); if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute(); } else { glEnable(GL_LIGHTING); if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute(); else pCurrentMaterial->glExecute(); } } }
// Geometry display void GLC_Geometry::render(const GLC_RenderProperties& renderProperties) { Q_ASSERT(!m_IsWire || (m_IsWire && m_MaterialHash.isEmpty())); bool renderWire= (renderProperties.renderingFlag() == glc::TransparentRenderFlag) && isTransparent(); renderWire= renderWire || ((renderProperties.renderingFlag() != glc::TransparentRenderFlag) && !isTransparent()); if (!m_IsWire || renderWire) { if (m_MaterialHash.isEmpty() && !m_IsWire) { GLC_Material* pMaterial= new GLC_Material(); pMaterial->setName(name()); addMaterial(pMaterial); } m_IsSelected= renderProperties.isSelected(); // Define Geometry's property if(!GLC_State::isInSelectionMode()) { glPropGeom(renderProperties); } glDraw(renderProperties); m_IsSelected= false; m_GeometryIsValid= true; // OpenGL error handler GLenum error= glGetError(); if (error != GL_NO_ERROR) { GLC_OpenGlException OpenGlException("GLC_Geometry::glExecute " + name(), error); throw(OpenGlException); } } }
// The normal display loop void GLC_Mesh::normalRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed) { const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag); if ((!m_IsSelected || !isTransparent) || GLC_State::isInSelectionMode()) { LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin(); while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd()) { GLC_PrimitiveGroup* pCurrentGroup= iGroup.value(); GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id()); // Test if the current material is renderable bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent); // Choose the material to render if ((materialIsrenderable || m_IsSelected) && !GLC_State::isInSelectionMode()) { // Execute current material pCurrentMaterial->glExecute(); if (m_IsSelected) GLC_SelectionMaterial::glExecute(); } // Choose the primitives to render if (m_IsSelected || GLC_State::isInSelectionMode() || materialIsrenderable) { if (vboIsUsed) { vboDrawPrimitivesOf(pCurrentGroup); } else { vertexArrayDrawPrimitivesOf(pCurrentGroup); } } ++iGroup; } } }
// Virtual interface for OpenGL Geometry set up. void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties) { Q_ASSERT(m_GeometryIsValid || !m_MeshData.positionSizeIsSet()); const bool vboIsUsed= GLC_Geometry::vboIsUsed() && GLC_State::vboSupported(); if (m_IsSelected && (renderProperties.renderingMode() == glc::PrimitiveSelected) && !GLC_State::isInSelectionMode() && !renderProperties.setOfSelectedPrimitiveIdIsEmpty()) { m_CurrentLod= 0; } if (vboIsUsed) { m_MeshData.createVBOs(); // Create VBO and IBO if (!m_GeometryIsValid && !m_MeshData.positionSizeIsSet()) { fillVbosAndIbos(); } // Activate mesh VBOs and IBO of the current LOD activateVboAndIbo(); } else { if (!m_GeometryIsValid) { m_MeshData.initPositionSize(); } activateVertexArray(); } if (GLC_State::isInSelectionMode()) { if (renderProperties.renderingMode() == glc::PrimitiveSelection) { primitiveSelectionRenderLoop(vboIsUsed); } else if (renderProperties.renderingMode() == glc::BodySelection) { bodySelectionRenderLoop(vboIsUsed); } else { normalRenderLoop(renderProperties, vboIsUsed); } } else if (m_IsSelected) { if (renderProperties.renderingMode() == glc::PrimitiveSelected) { if (!renderProperties.setOfSelectedPrimitiveIdIsEmpty()) { primitiveSelectedRenderLoop(renderProperties, vboIsUsed); } else { m_IsSelected= false; if ((m_CurrentLod == 0) && (renderProperties.savedRenderingMode() == glc::OverwritePrimitiveMaterial) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty()) primitiveRenderLoop(renderProperties, vboIsUsed); else normalRenderLoop(renderProperties, vboIsUsed); m_IsSelected= true; } } else { normalRenderLoop(renderProperties, vboIsUsed); } } else { // Choose the accurate render loop switch (renderProperties.renderingMode()) { case glc::NormalRenderMode: normalRenderLoop(renderProperties, vboIsUsed); break; case glc::OverwriteMaterial: OverwriteMaterialRenderLoop(renderProperties, vboIsUsed); break; case glc::OverwriteTransparency: OverwriteTransparencyRenderLoop(renderProperties, vboIsUsed); break; case glc::OverwriteTransparencyAndMaterial: OverwriteTransparencyAndMaterialRenderLoop(renderProperties, vboIsUsed); break; case glc::OverwritePrimitiveMaterial: if ((m_CurrentLod == 0) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty()) primitiveRenderLoop(renderProperties, vboIsUsed); else normalRenderLoop(renderProperties, vboIsUsed); break; default: Q_ASSERT(false); break; } } // Restore client state if (m_ColorPearVertex && !m_IsSelected && !GLC_State::isInSelectionMode()) { glDisableClientState(GL_COLOR_ARRAY); glDisable(GL_COLOR_MATERIAL); } glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); if (vboIsUsed) { QGLBuffer::release(QGLBuffer::IndexBuffer); QGLBuffer::release(QGLBuffer::VertexBuffer); } // Draw mesh's wire if necessary if ((renderProperties.renderingFlag() == glc::WireRenderFlag) && !m_WireData.isEmpty() && !GLC_Geometry::typeIsWire()) { if (!GLC_State::isInSelectionMode()) { GLC_Context::current()->glcEnableLighting(false); // Set polyline colors GLfloat color[4]= {static_cast<float>(m_WireColor.redF()), static_cast<float>(m_WireColor.greenF()), static_cast<float>(m_WireColor.blueF()), static_cast<float>(m_WireColor.alphaF())}; glColor4fv(color); m_WireData.glDraw(renderProperties, GL_LINE_STRIP); GLC_Context::current()->glcEnableLighting(true); } else { m_WireData.glDraw(renderProperties, GL_LINE_STRIP); } } // Update statistics GLC_RenderStatistics::addBodies(1); GLC_RenderStatistics::addTriangles(m_MeshData.trianglesCount(m_CurrentLod)); }