glc_geometry.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 
00003  This file is part of the GLC-lib library.
00004  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
00005  http://glc-lib.sourceforge.net
00006 
00007  GLC-lib is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU Lesser General Public License as published by
00009  the Free Software Foundation; either version 3 of the License, or
00010  (at your option) any later version.
00011 
00012  GLC-lib is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU Lesser General Public License for more details.
00016 
00017  You should have received a copy of the GNU Lesser General Public License
00018  along with GLC-lib; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 *****************************************************************************/
00022 
00024 
00025 #include "../shading/glc_selectionmaterial.h"
00026 #include "../glc_openglexception.h"
00027 #include "../glc_state.h"
00028 #include "../glc_context.h"
00029 #include "glc_geometry.h"
00030 
00032 // Constructor destructor
00034 // Default constructor
00035 GLC_Geometry::GLC_Geometry(const QString& name, const bool typeIsWire)
00036 : m_GeometryIsValid(false)      // By default geometry is invalid
00037 , m_pBoundingBox(NULL)
00038 , m_MaterialHash()
00039 , m_UseColorPerVertex(false)
00040 , m_IsSelected(false)
00041 , m_WireData()
00042 , m_WireColor(Qt::black)
00043 , m_LineWidth(1.0f)
00044 , m_IsWire(typeIsWire)          // the geometry type
00045 , m_TransparentMaterialNumber(0)
00046 , m_Id(glc::GLC_GenGeomID())
00047 , m_Name(name)
00048 , m_UseVbo(false)
00049 {
00050 
00051 }
00052 // Copy constructor
00053 GLC_Geometry::GLC_Geometry(const GLC_Geometry& sourceGeom)
00054 : m_GeometryIsValid(false)      // By default geometry is invalid
00055 , m_pBoundingBox(NULL)
00056 , m_MaterialHash(sourceGeom.m_MaterialHash)
00057 , m_UseColorPerVertex(sourceGeom.m_UseColorPerVertex)
00058 , m_IsSelected(false)
00059 , m_WireData(sourceGeom.m_WireData)
00060 , m_WireColor(sourceGeom.m_WireColor)
00061 , m_LineWidth(sourceGeom.m_LineWidth)
00062 , m_IsWire(sourceGeom.m_IsWire)
00063 , m_TransparentMaterialNumber(sourceGeom.m_TransparentMaterialNumber)
00064 , m_Id(glc::GLC_GenGeomID())
00065 , m_Name(sourceGeom.m_Name)
00066 , m_UseVbo(sourceGeom.m_UseVbo)
00067 {
00068         // Add this mesh to inner material
00069         MaterialHash::const_iterator i= sourceGeom.m_MaterialHash.constBegin();
00070     while (i != sourceGeom.m_MaterialHash.constEnd())
00071     {
00072         // update inner material use table
00073         i.value()->addGLC_Geom(this);
00074         ++i;
00075     }
00076 
00077         if (NULL != sourceGeom.m_pBoundingBox)
00078         {
00079                 m_pBoundingBox= new GLC_BoundingBox(*sourceGeom.m_pBoundingBox);
00080         }
00081 }
00082 
00083 // Overload "=" operator
00084 GLC_Geometry& GLC_Geometry::operator=(const GLC_Geometry& sourceGeom)
00085 {
00086         if (this != &sourceGeom)
00087         {
00088                 clear();
00089                 m_GeometryIsValid= false;
00090                 m_pBoundingBox= NULL;
00091                 m_MaterialHash= sourceGeom.m_MaterialHash;
00092                 m_UseColorPerVertex= sourceGeom.m_UseColorPerVertex;
00093                 m_IsSelected= false;
00094                 m_WireData= sourceGeom.m_WireData;
00095                 m_WireColor= sourceGeom.m_WireColor;
00096                 m_LineWidth= sourceGeom.m_LineWidth;
00097                 m_IsWire= sourceGeom.m_IsWire;
00098                 m_TransparentMaterialNumber= sourceGeom.m_TransparentMaterialNumber;
00099                 m_Id= glc::GLC_GenGeomID();
00100                 m_Name= sourceGeom.m_Name;
00101                 m_UseVbo= sourceGeom.m_UseVbo;
00102         }
00103         return *this;
00104 }
00105 
00106 GLC_Geometry::~GLC_Geometry()
00107 {
00108         // delete mesh inner material
00109         {
00110                 MaterialHash::const_iterator i= m_MaterialHash.begin();
00111             while (i != m_MaterialHash.constEnd())
00112             {
00113                 // delete the material if necessary
00114                 i.value()->delGLC_Geom(id());
00115                 if (i.value()->isUnused()) delete i.value();
00116                 ++i;
00117             }
00118         }
00119         m_MaterialHash.clear();
00120 
00121         delete m_pBoundingBox;
00122 
00123 }
00124 
00126 // Get Functions
00128 
00129 // Get number of faces
00130 unsigned int GLC_Geometry::faceCount(int) const
00131 {
00132         return 0;
00133 }
00134 
00135 // Get number of vertex
00136 unsigned int GLC_Geometry::VertexCount() const
00137 {
00138         return 0;
00139 }
00140 
00141 double GLC_Geometry::volume()
00142 {
00143         return 0.0;
00144 }
00145 
00147 // Set Functions
00149 // Clear the content of the geometry and makes it empty
00150 void GLC_Geometry::clear()
00151 {
00152         clearGeometry();
00153 }
00154 
00155 // Replace the Master material
00156 void GLC_Geometry::replaceMasterMaterial(GLC_Material* pMaterial)
00157 {
00158         Q_ASSERT(!m_IsWire);
00159         if (!m_MaterialHash.isEmpty())
00160         {
00161                 if (pMaterial != firstMaterial())
00162                 {
00163                         // Remove the first material
00164                         MaterialHash::iterator iMaterial= m_MaterialHash.begin();
00165                         removeMaterial(iMaterial.value()->id());
00166 
00167                         // Add the new material
00168                         addMaterial(pMaterial);
00169                 }
00170         }
00171         else
00172         {
00173                 addMaterial(pMaterial);
00174         }
00175 }
00177 void GLC_Geometry::updateTransparentMaterialNumber()
00178 {
00179         m_TransparentMaterialNumber= 0;
00180         MaterialHash::const_iterator iMat= m_MaterialHash.constBegin();
00181         while (iMat != m_MaterialHash.constEnd())
00182         {
00183                 if (iMat.value()->isTransparent())
00184                 {
00185                         ++m_TransparentMaterialNumber;
00186                 }
00187                 ++iMat;
00188         }
00189         if (m_WireColor.alpha() != 255)
00190         {
00191                 ++m_TransparentMaterialNumber;
00192         }
00193 }
00194 
00195 // Add material to mesh
00196 void GLC_Geometry::addMaterial(GLC_Material* pMaterial)
00197 {
00198         if (pMaterial != NULL)
00199         {
00200                 const GLC_uint materialID= pMaterial->id();
00201                 MaterialHash::const_iterator iMaterial= m_MaterialHash.find(materialID);
00202                 // Check if there is a material at specified index
00203                 Q_ASSERT(iMaterial == m_MaterialHash.end());
00204 
00205                 // Add this geometry in the material use table
00206                 pMaterial->addGLC_Geom(this);
00207                 // Add the Material to Material hash table
00208                 m_MaterialHash.insert(materialID, pMaterial);
00209 
00210                 // Test if the material is transparent
00211                 if (pMaterial->isTransparent())
00212                 {
00213                         //qDebug() << "Add transparent material";
00214                         ++m_TransparentMaterialNumber;
00215                 }
00216         }
00217 }
00218 
00219 void GLC_Geometry::setWireColor(const QColor& color)
00220 {
00221         bool previousColorIsTransparent= (m_WireColor.alpha() != 255);
00222         bool newColorIsTransparent= (color.alpha() != 255);
00223 
00224         if (previousColorIsTransparent != newColorIsTransparent)
00225         {
00226                 if (newColorIsTransparent) ++m_TransparentMaterialNumber;
00227                 else if (previousColorIsTransparent) --m_TransparentMaterialNumber;
00228         }
00229 
00230         m_WireColor= color;
00231 }
00232 
00233 void GLC_Geometry::copyVboToClientSide()
00234 {
00235         m_WireData.copyVboToClientSide();
00236 }
00237 
00238 void GLC_Geometry::releaseVboClientSide(bool update)
00239 {
00240         m_WireData.releaseVboClientSide(update);
00241 }
00242 
00243 void GLC_Geometry::setVboUsage(bool usage)
00244 {
00245         m_UseVbo= usage;
00246         if (!usage || (usage && GLC_State::vboSupported()))
00247         {
00248                 m_WireData.setVboUsage(m_UseVbo);
00249         }
00250 }
00251 
00253 // OpenGL Functions
00255 
00256 // if the geometry have a texture, load it
00257 void GLC_Geometry::glLoadTexture(void)
00258 {
00259         MaterialHash::iterator iMaterial= m_MaterialHash.begin();
00260 
00261     while (iMaterial != m_MaterialHash.constEnd())
00262     {
00263         // Load texture of mesh materials
00264         iMaterial.value()->glLoadTexture();
00265         ++iMaterial;
00266     }
00267 }
00268 
00269 // Geometry display
00270 void GLC_Geometry::render(const GLC_RenderProperties& renderProperties)
00271 {
00272         Q_ASSERT(!m_IsWire || (m_IsWire && m_MaterialHash.isEmpty()));
00273         bool renderWire= (renderProperties.renderingFlag() == glc::TransparentRenderFlag) && isTransparent();
00274         renderWire= renderWire || ((renderProperties.renderingFlag() != glc::TransparentRenderFlag) && !isTransparent());
00275         if (!m_IsWire || renderWire)
00276         {
00277                 if (m_MaterialHash.isEmpty() && !m_IsWire)
00278                 {
00279                         GLC_Material* pMaterial= new GLC_Material();
00280                         pMaterial->setName(name());
00281                         addMaterial(pMaterial);
00282                 }
00283 
00284                 m_IsSelected= renderProperties.isSelected();
00285 
00286                 // Define Geometry's property
00287                 if(!GLC_State::isInSelectionMode())
00288                 {
00289                         glPropGeom(renderProperties);
00290                 }
00291 
00292                 glDraw(renderProperties);
00293 
00294                 m_IsSelected= false;
00295                 m_GeometryIsValid= true;
00296 
00297                 // OpenGL error handler
00298                 GLenum error= glGetError();
00299                 if (error != GL_NO_ERROR)
00300                 {
00301                         GLC_OpenGlException OpenGlException("GLC_Geometry::render " + name(), error);
00302                         throw(OpenGlException);
00303                 }
00304         }
00305 }
00306 
00307 // Virtual interface for OpenGL Geometry properties.
00308 void GLC_Geometry::glPropGeom(const GLC_RenderProperties& renderProperties)
00309 {
00310         glLineWidth(lineWidth());
00311 
00312         if(m_IsWire)
00313         {
00314                 glLineWidth(m_LineWidth);
00315                 GLC_Context::current()->glcEnableLighting(false);;
00316                 if (!renderProperties.isSelected())
00317                 {
00318                         // Set polyline colors
00319                         GLfloat color[4]= {static_cast<float>(m_WireColor.redF()),
00320                                                                         static_cast<float>(m_WireColor.greenF()),
00321                                                                         static_cast<float>(m_WireColor.blueF()),
00322                                                                         static_cast<float>(m_WireColor.alphaF())};
00323 
00324                         glColor4fv(color);
00325                 }
00326                 else
00327                 {
00328                         GLC_SelectionMaterial::glExecute();
00329                 }
00330         }
00331         else if (m_MaterialHash.size() == 1)
00332         {
00333                 GLC_Material* pCurrentMaterial= m_MaterialHash.begin().value();
00334                 if (pCurrentMaterial->hasTexture())
00335                 {
00336                         GLC_Context::current()->glcEnableLighting(true);
00337                         pCurrentMaterial->glExecute();
00338                         if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
00339                 }
00340                 else
00341                 {
00342                         GLC_Context::current()->glcEnableLighting(true);
00343                         if (renderProperties.isSelected()) GLC_SelectionMaterial::glExecute();
00344                         else pCurrentMaterial->glExecute();
00345                 }
00346         }
00347 }
00348 
00349 // Remove the specified material from the geometry
00350 void GLC_Geometry::removeMaterial(GLC_uint id)
00351 {
00352         Q_ASSERT(containsMaterial(id));
00353         // Remove the first material
00354         GLC_Material* pMaterial= m_MaterialHash.value(id);
00355     // delete the material if necessary
00356         pMaterial->delGLC_Geom(this->id());
00357         if (pMaterial->isTransparent())
00358         {
00359                 --m_TransparentMaterialNumber;
00360         }
00361     if (pMaterial->isUnused()) delete pMaterial;
00362         m_MaterialHash.remove(id);
00363 
00364 }
00365 
00366 // Clear the content of this object and makes it empty
00367 void  GLC_Geometry::clearGeometry()
00368 {
00369         m_GeometryIsValid= false;
00370 
00371         delete m_pBoundingBox;
00372         m_pBoundingBox= NULL;
00373 
00374         // delete mesh inner material
00375         {
00376                 MaterialHash::const_iterator i= m_MaterialHash.begin();
00377             while (i != m_MaterialHash.constEnd())
00378             {
00379                 // delete the material if necessary
00380                 i.value()->delGLC_Geom(id());
00381                 if (i.value()->isUnused()) delete i.value();
00382                 ++i;
00383             }
00384         }
00385         m_MaterialHash.clear();
00386 
00387         m_UseColorPerVertex= false;
00388         m_IsSelected= false;
00389         m_WireData.clear();
00390         m_IsWire= false;
00391         m_TransparentMaterialNumber= 0;
00392         m_Name.clear();
00393 
00394 }

SourceForge.net Logo

©2005-2011 Laurent Ribon