glc_mesh.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  Version 2.0.0, packaged on July 2010.
00006 
00007  http://glc-lib.sourceforge.net
00008 
00009  GLC-lib is free software; you can redistribute it and/or modify
00010  it under the terms of the GNU Lesser General Public License as published by
00011  the Free Software Foundation; either version 3 of the License, or
00012  (at your option) any later version.
00013 
00014  GLC-lib is distributed in the hope that it will be useful,
00015  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  GNU Lesser General Public License for more details.
00018 
00019  You should have received a copy of the GNU Lesser General Public License
00020  along with GLC-lib; if not, write to the Free Software
00021  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022 
00023 *****************************************************************************/
00024 
00026 
00027 #include "glc_mesh.h"
00028 #include "../glc_renderstatistics.h"
00029 
00030 // Class chunk id
00031 quint32 GLC_Mesh::m_ChunkId= 0xA701;
00032 
00033 GLC_Mesh::GLC_Mesh()
00034 :GLC_Geometry("Mesh", false)
00035 , m_NextPrimitiveLocalId(1)
00036 , m_PrimitiveGroups()
00037 , m_DefaultMaterialId(0)
00038 , m_NumberOfVertice(0)
00039 , m_NumberOfNormals(0)
00040 , m_ColorPearVertex(false)
00041 , m_MeshData()
00042 , m_CurrentLod(0)
00043 {
00044 
00045 }
00046 
00047 GLC_Mesh::GLC_Mesh(const GLC_Mesh& mesh)
00048 :GLC_Geometry(mesh)
00049 , m_NextPrimitiveLocalId(mesh.m_NextPrimitiveLocalId)
00050 , m_PrimitiveGroups(mesh.m_PrimitiveGroups)
00051 , m_DefaultMaterialId(mesh.m_DefaultMaterialId)
00052 , m_NumberOfVertice(mesh.m_NumberOfVertice)
00053 , m_NumberOfNormals(mesh.m_NumberOfNormals)
00054 , m_ColorPearVertex(mesh.m_ColorPearVertex)
00055 , m_MeshData(mesh.m_MeshData)
00056 , m_CurrentLod(0)
00057 {
00058         // Make a copy of m_PrimitiveGroups with new material id
00059         PrimitiveGroupsHash::const_iterator iPrimitiveGroups= mesh.m_PrimitiveGroups.constBegin();
00060         while (mesh.m_PrimitiveGroups.constEnd() != iPrimitiveGroups)
00061         {
00062                 LodPrimitiveGroups* pPrimitiveGroups= new LodPrimitiveGroups();
00063                 m_PrimitiveGroups.insert(iPrimitiveGroups.key(), pPrimitiveGroups);
00064 
00065                 LodPrimitiveGroups::const_iterator iPrimitiveGroup= iPrimitiveGroups.value()->constBegin();
00066                 while (iPrimitiveGroups.value()->constEnd() != iPrimitiveGroup)
00067                 {
00068                         GLC_PrimitiveGroup* pPrimitiveGroup= new GLC_PrimitiveGroup(*(iPrimitiveGroup.value()), iPrimitiveGroup.key());
00069                         pPrimitiveGroups->insert(iPrimitiveGroup.key(), pPrimitiveGroup);
00070 
00071                         ++iPrimitiveGroup;
00072                 }
00073 
00074                 ++iPrimitiveGroups;
00075         }
00076 
00077 }
00078 
00079 // Overload "=" operator
00080 GLC_Mesh& GLC_Mesh::operator=(const GLC_Mesh& mesh)
00081 {
00082         if (this != &mesh)
00083         {
00084                 // Call the operator of the super class
00085                 GLC_Geometry::operator=(mesh);
00086 
00087                 // Clear the mesh
00088                 clearMeshWireAndBoundingBox();
00089 
00090                 // Copy members
00091                 m_NextPrimitiveLocalId= mesh.m_NextPrimitiveLocalId;
00092                 m_PrimitiveGroups= mesh.m_PrimitiveGroups;
00093                 m_DefaultMaterialId= mesh.m_DefaultMaterialId;
00094                 m_NumberOfVertice= mesh.m_NumberOfVertice;
00095                 m_NumberOfNormals= mesh.m_NumberOfNormals;
00096                 m_ColorPearVertex= mesh.m_ColorPearVertex;
00097                 m_MeshData= mesh.m_MeshData;
00098                 m_CurrentLod= 0;
00099 
00100                 // Make a copy of m_PrimitiveGroups with new material id
00101                 PrimitiveGroupsHash::const_iterator iPrimitiveGroups= mesh.m_PrimitiveGroups.constBegin();
00102                 while (mesh.m_PrimitiveGroups.constEnd() != iPrimitiveGroups)
00103                 {
00104                         LodPrimitiveGroups* pPrimitiveGroups= new LodPrimitiveGroups();
00105                         m_PrimitiveGroups.insert(iPrimitiveGroups.key(), pPrimitiveGroups);
00106 
00107                         LodPrimitiveGroups::const_iterator iPrimitiveGroup= iPrimitiveGroups.value()->constBegin();
00108                         while (iPrimitiveGroups.value()->constEnd() != iPrimitiveGroup)
00109                         {
00110                                 GLC_PrimitiveGroup* pPrimitiveGroup= new GLC_PrimitiveGroup(*(iPrimitiveGroup.value()), iPrimitiveGroup.key());
00111                                 pPrimitiveGroups->insert(iPrimitiveGroup.key(), pPrimitiveGroup);
00112 
00113                                 ++iPrimitiveGroup;
00114                         }
00115 
00116                         ++iPrimitiveGroups;
00117                 }
00118         }
00119 
00120         return *this;
00121 }
00122 
00123 // Destructor
00124 GLC_Mesh::~GLC_Mesh()
00125 {
00126         PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
00127         while (iGroups != m_PrimitiveGroups.constEnd())
00128         {
00129                 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
00130                 while (iGroup != iGroups.value()->constEnd())
00131                 {
00132                         delete iGroup.value();
00133 
00134                         ++iGroup;
00135                 }
00136                 delete iGroups.value();
00137                 ++iGroups;
00138         }
00139 }
00140 
00142 // Get Functions
00144 // Return the class Chunk ID
00145 quint32 GLC_Mesh::chunckID()
00146 {
00147         return m_ChunkId;
00148 }
00149 
00150 // Get number of faces
00151 unsigned int GLC_Mesh::faceCount(int lod) const
00152 {
00153         return m_MeshData.trianglesCount(lod);
00154 }
00155 
00156 // Get number of vertex
00157 unsigned int GLC_Mesh::VertexCount() const
00158 {
00159         return m_NumberOfVertice;
00160 }
00161 
00162 // return the mesh bounding box
00163 const GLC_BoundingBox& GLC_Mesh::boundingBox()
00164 {
00165         if (NULL == m_pBoundingBox)
00166         {
00167                 //qDebug() << "GLC_Mesh2::boundingBox create boundingBox";
00168                 m_pBoundingBox= new GLC_BoundingBox();
00169 
00170                 if (m_MeshData.positionVectorHandle()->isEmpty())
00171                 {
00172                         qDebug() << "GLC_ExtendedMesh::getBoundingBox empty m_Positions";
00173                 }
00174                 else
00175                 {
00176                         GLfloatVector* pVertexVector= m_MeshData.positionVectorHandle();
00177                         const int max= pVertexVector->size();
00178                         for (int i= 0; i < max; i= i + 3)
00179                         {
00180                                 GLC_Vector3d vector((*pVertexVector)[i], (*pVertexVector)[i + 1], (*pVertexVector)[i + 2]);
00181                                 m_pBoundingBox->combine(vector);
00182                         }
00183                 }
00184                 // Combine with the wiredata bounding box
00185                 m_pBoundingBox->combine(m_WireData.boundingBox());
00186         }
00187         return *m_pBoundingBox;
00188 
00189 }
00190 
00191 // Return a copy of the Mesh as GLC_Geometry pointer
00192 GLC_Geometry* GLC_Mesh::clone() const
00193 {
00194         return new GLC_Mesh(*this);
00195 }
00196 
00197 // Return true if the mesh contains triangles
00198 bool GLC_Mesh::containsTriangles(int lod, GLC_uint materialId) const
00199 {
00200         // Check if the lod exist and material exists
00201         Q_ASSERT(m_PrimitiveGroups.contains(lod));
00202         if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false;
00203         else return m_PrimitiveGroups.value(lod)->value(materialId)->containsTriangles();
00204 }
00205 
00206 // Return the specified index
00207 QVector<GLuint> GLC_Mesh::getTrianglesIndex(int lod, GLC_uint materialId) const
00208 {
00209         // Check if the mesh contains triangles
00210         Q_ASSERT(containsTriangles(lod, materialId));
00211 
00212         GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId);
00213 
00214         int offset= 0;
00215         if (GLC_State::vboUsed())
00216         {
00217                 offset= static_cast<int>(reinterpret_cast<GLsizeiptr>(pPrimitiveGroup->trianglesIndexOffset()) / sizeof(GLuint));
00218         }
00219         else
00220         {
00221                 offset= pPrimitiveGroup->trianglesIndexOffseti();
00222         }
00223         const int size= pPrimitiveGroup->trianglesIndexSize();
00224 
00225         QVector<GLuint> resultIndex(size);
00226 
00227         memcpy((void*)resultIndex.data(), &(m_MeshData.indexVector(lod).data())[offset], size * sizeof(GLuint));
00228 
00229         return resultIndex;
00230 }
00231 
00232 // Return the number of triangles
00233 int GLC_Mesh::numberOfTriangles(int lod, GLC_uint materialId) const
00234 {
00235         // Check if the lod exist and material exists
00236         if (!m_PrimitiveGroups.contains(lod))return 0;
00237         else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0;
00238         else return m_PrimitiveGroups.value(lod)->value(materialId)->trianglesIndexSize();
00239 }
00240 
00241 // Return true if the mesh contains trips
00242 bool GLC_Mesh::containsStrips(int lod, GLC_uint materialId) const
00243 {
00244         // Check if the lod exist and material exists
00245         if (!m_PrimitiveGroups.contains(lod))return false;
00246         else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false;
00247         else return m_PrimitiveGroups.value(lod)->value(materialId)->containsStrip();
00248 
00249 }
00250 
00251 // Return the strips index
00252 QList<QVector<GLuint> > GLC_Mesh::getStripsIndex(int lod, GLC_uint materialId) const
00253 {
00254         // Check if the mesh contains trips
00255         Q_ASSERT(containsStrips(lod, materialId));
00256 
00257         GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId);
00258 
00259         QList<int> offsets;
00260         QList<int> sizes;
00261         int stripsCount;
00262 
00263         if (GLC_State::vboUsed())
00264         {
00265                 stripsCount= pPrimitiveGroup->stripsOffset().size();
00266                 for (int i= 0; i < stripsCount; ++i)
00267                 {
00268                         offsets.append(static_cast<int>(reinterpret_cast<GLsizeiptr>(pPrimitiveGroup->stripsOffset().at(i)) / sizeof(GLuint)));
00269                         sizes.append(static_cast<int>(pPrimitiveGroup->stripsSizes().at(i)));
00270                 }
00271         }
00272         else
00273         {
00274                 stripsCount= pPrimitiveGroup->stripsOffseti().size();
00275                 for (int i= 0; i < stripsCount; ++i)
00276                 {
00277                         offsets.append(static_cast<int>(pPrimitiveGroup->stripsOffseti().at(i)));
00278                         sizes.append(static_cast<int>(pPrimitiveGroup->stripsSizes().at(i)));
00279                 }
00280 
00281         }
00282         // The result list of vector
00283         QList<QVector<GLuint> > result;
00284         // The copy of the mesh Data LOD index vector
00285         QVector<GLuint> SourceIndex(m_MeshData.indexVector(lod));
00286         for (int i= 0; i < stripsCount; ++i)
00287         {
00288                 QVector<GLuint> currentStrip(sizes.at(i));
00289                 memcpy((void*)currentStrip.data(), &(SourceIndex.data())[offsets.at(i)], sizes.at(i) * sizeof(GLuint));
00290                 result.append(currentStrip);
00291         }
00292 
00293         return result;
00294 }
00295 
00296 // Return the number of strips
00297 int GLC_Mesh::numberOfStrips(int lod, GLC_uint materialId) const
00298 {
00299         // Check if the lod exist and material exists
00300         if (!m_PrimitiveGroups.contains(lod))return 0;
00301         else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0;
00302         else return m_PrimitiveGroups.value(lod)->value(materialId)->stripsSizes().size();
00303 }
00304 
00305 // Return true if the mesh contains fans
00306 bool GLC_Mesh::containsFans(int lod, GLC_uint materialId) const
00307 {
00308         // Check if the lod exist and material exists
00309         if (!m_PrimitiveGroups.contains(lod))return false;
00310         else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return false;
00311         else return m_PrimitiveGroups.value(lod)->value(materialId)->containsFan();
00312 
00313 }
00314 
00316 int GLC_Mesh::numberOfFans(int lod, GLC_uint materialId) const
00317 {
00318         // Check if the lod exist and material exists
00319         if(!m_PrimitiveGroups.contains(lod))return 0;
00320         else if (!m_PrimitiveGroups.value(lod)->contains(materialId)) return 0;
00321         else return m_PrimitiveGroups.value(lod)->value(materialId)->fansSizes().size();
00322 }
00323 
00324 // Return the strips index
00325 QList<QVector<GLuint> > GLC_Mesh::getFansIndex(int lod, GLC_uint materialId) const
00326 {
00327         // Check if the mesh contains trips
00328         Q_ASSERT(containsFans(lod, materialId));
00329 
00330         GLC_PrimitiveGroup* pPrimitiveGroup= m_PrimitiveGroups.value(lod)->value(materialId);
00331 
00332         QList<int> offsets;
00333         QList<int> sizes;
00334         int fansCount;
00335 
00336         if (GLC_State::vboUsed())
00337         {
00338                 fansCount= pPrimitiveGroup->fansOffset().size();
00339                 for (int i= 0; i < fansCount; ++i)
00340                 {
00341                         offsets.append(static_cast<int>(reinterpret_cast<GLsizeiptr>(pPrimitiveGroup->fansOffset().at(i)) / sizeof(GLuint)));
00342                         sizes.append(static_cast<int>(pPrimitiveGroup->fansSizes().at(i)));
00343                 }
00344         }
00345         else
00346         {
00347                 fansCount= pPrimitiveGroup->fansOffseti().size();
00348                 for (int i= 0; i < fansCount; ++i)
00349                 {
00350                         offsets.append(static_cast<int>(pPrimitiveGroup->fansOffseti().at(i)));
00351                         sizes.append(static_cast<int>(pPrimitiveGroup->fansSizes().at(i)));
00352                 }
00353 
00354         }
00355         // The result list of vector
00356         QList<QVector<GLuint> > result;
00357         // The copy of the mesh Data LOD index vector
00358         QVector<GLuint> SourceIndex(m_MeshData.indexVector(lod));
00359         for (int i= 0; i < fansCount; ++i)
00360         {
00361                 QVector<GLuint> currentFan(sizes.at(i));
00362                 memcpy((void*)currentFan.data(), &(SourceIndex.data())[offsets.at(i)], sizes.at(i) * sizeof(GLuint));
00363                 result.append(currentFan);
00364         }
00365 
00366         return result;
00367 }
00368 
00370 // Set Functions
00372 
00373 // Clear the content of the mesh and super class GLC_Geometry
00374 void GLC_Mesh::clear()
00375 {
00376         // Clear the mesh content
00377         clearMeshWireAndBoundingBox();
00378 
00379         // Clear the super class GLC_Geometry
00380         GLC_Geometry::clear();
00381 }
00382 
00383 
00384 // Clear the content off the mesh and makes it empty
00385 void GLC_Mesh::clearMeshWireAndBoundingBox()
00386 {
00387         // Reset primitive local id
00388         m_NextPrimitiveLocalId= 1;
00389 
00390         // Remove all primitive groups
00391         PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
00392         while (iGroups != m_PrimitiveGroups.constEnd())
00393         {
00394                 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
00395                 while (iGroup != iGroups.value()->constEnd())
00396                 {
00397                         delete iGroup.value();
00398 
00399                         ++iGroup;
00400                 }
00401                 delete iGroups.value();
00402                 ++iGroups;
00403         }
00404         m_PrimitiveGroups.clear();
00405 
00406         m_DefaultMaterialId= 0;
00407         m_NumberOfVertice= 0;
00408         m_NumberOfNormals= 0;
00409         m_IsSelected= false;
00410         m_ColorPearVertex= false;
00411         // Clear data of the mesh
00412         m_MeshData.clear();
00413         m_CurrentLod= 0;
00414 
00415         GLC_Geometry::clearWireAndBoundingBox();
00416 }
00417 
00418 // Add triangles
00419 GLC_uint GLC_Mesh::addTriangles(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy)
00420 {
00421         GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy);
00422         Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId));
00423         Q_ASSERT(!indexList.isEmpty());
00424 
00425         GLC_uint id= 0;
00426         if (0 == lod)
00427         {
00428                 id= m_NextPrimitiveLocalId++;
00429         }
00430         m_MeshData.trianglesAdded(lod, indexList.size() / 3);
00431 
00432         m_PrimitiveGroups.value(lod)->value(groupId)->addTriangles(indexList, id);
00433 
00434         // Invalid the geometry
00435         m_GeometryIsValid = false;
00436 
00437         return id;
00438 }
00439 
00440 // Add triangles Strip ans return his id
00441 GLC_uint GLC_Mesh::addTrianglesStrip(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy)
00442 {
00443         GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy);
00444         Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId));
00445         Q_ASSERT(!indexList.isEmpty());
00446 
00447         GLC_uint id= 0;
00448         if (0 == lod)
00449         {
00450                 id= m_NextPrimitiveLocalId++;
00451         }
00452         m_MeshData.trianglesAdded(lod, indexList.size() - 2);
00453 
00454         m_PrimitiveGroups.value(lod)->value(groupId)->addTrianglesStrip(indexList, id);
00455 
00456         // Invalid the geometry
00457         m_GeometryIsValid = false;
00458 
00459         return id;
00460 }
00461 // Add triangles Fan
00462 GLC_uint GLC_Mesh::addTrianglesFan(GLC_Material* pMaterial, const IndexList& indexList, const int lod, double accuracy)
00463 {
00464         GLC_uint groupId= setCurrentMaterial(pMaterial, lod, accuracy);
00465         Q_ASSERT(m_PrimitiveGroups.value(lod)->contains(groupId));
00466         Q_ASSERT(!indexList.isEmpty());
00467 
00468         GLC_uint id= 0;
00469         if (0 == lod)
00470         {
00471                 id= m_NextPrimitiveLocalId++;
00472         }
00473         m_MeshData.trianglesAdded(lod, indexList.size() - 2);
00474         m_PrimitiveGroups.value(lod)->value(groupId)->addTrianglesFan(indexList, id);
00475 
00476         // Invalid the geometry
00477         m_GeometryIsValid = false;
00478 
00479         return id;
00480 }
00481 
00482 // Reverse mesh normal
00483 void GLC_Mesh::reverseNormals()
00484 {
00485         GLfloatVector* pNormalVector= m_MeshData.normalVectorHandle();
00486         if (pNormalVector->isEmpty())
00487         {
00488                 (*m_MeshData.normalVectorHandle())= m_MeshData.normalVector();
00489         }
00490         const int size= pNormalVector->size();
00491         for (int i= 0; i < size; ++i)
00492         {
00493                 (*pNormalVector)[i]= - pNormalVector->at(i);
00494         }
00495         // Invalid the geometry
00496         m_GeometryIsValid = false;
00497 }
00498 
00499 // Copy index list in a vector for Vertex Array Use
00500 void GLC_Mesh::finish()
00501 {
00502         boundingBox();
00503 
00504         m_MeshData.finishLod();
00505 
00506         if (GLC_State::vboUsed())
00507         {
00508                 finishVbo();
00509         }
00510         else
00511         {
00512                 finishNonVbo();
00513         }
00514 
00515         //qDebug() << "Mesh mem size= " << memmorySize();
00516 }
00517 
00518 
00519 // Set the lod Index
00520 void GLC_Mesh::setCurrentLod(const int value)
00521 {
00522         if (value)
00523         {
00524                 const int numberOfLod= m_MeshData.lodCount() - 1;
00525                 // Clamp value to number of load
00526                 m_CurrentLod= qRound(static_cast<int>((static_cast<double>(value) / 100.0) * numberOfLod));
00527         }
00528         else
00529         {
00530                 m_CurrentLod= 0;
00531         }
00532 }
00533 // Replace the Master material
00534 void GLC_Mesh::replaceMasterMaterial(GLC_Material* pMat)
00535 {
00536         if (hasMaterial())
00537         {
00538                 GLC_uint oldId= firstMaterial()->id();
00539                 replaceMaterial(oldId, pMat);
00540         }
00541         else
00542         {
00543                 addMaterial(pMat);
00544         }
00545 }
00546 
00547 // Replace the material specified by id with another one
00548 void GLC_Mesh::replaceMaterial(const GLC_uint oldId, GLC_Material* pMat)
00549 {
00550         Q_ASSERT(containsMaterial(oldId));
00551         Q_ASSERT(!containsMaterial(pMat->id()) || (pMat->id() == oldId));
00552 
00553         if (pMat->id() != oldId)
00554         {
00555                 // Iterate over Level of detail
00556                 PrimitiveGroupsHash::const_iterator iGroups= m_PrimitiveGroups.constBegin();
00557                 while (m_PrimitiveGroups.constEnd() != iGroups)
00558                 {
00559                         LodPrimitiveGroups* pPrimitiveGroups= iGroups.value();
00560                         // Iterate over material group
00561                         LodPrimitiveGroups::iterator iGroup= pPrimitiveGroups->begin();
00562                         while (pPrimitiveGroups->constEnd() != iGroup)
00563                         {
00564                                 if (iGroup.key() == oldId)
00565                                 {
00566                                         GLC_PrimitiveGroup* pGroup= iGroup.value();
00567                                         // Erase old group pointer
00568                                         pPrimitiveGroups->erase(iGroup);
00569                                         // Change the group ID
00570                                         pGroup->setId(pMat->id());
00571                                         // Add the group with  new ID
00572                                         pPrimitiveGroups->insert(pMat->id(), pGroup);
00573                                         iGroup= pPrimitiveGroups->end();
00574                                 }
00575                                 else
00576                                 {
00577                                         ++iGroup;
00578                                 }
00579                         }
00580                         ++iGroups;
00581                 }
00582         }
00583 
00584         if (pMat != m_MaterialHash.value(oldId))
00585         {
00586                 // Remove old material
00587                 removeMaterial(oldId);
00588 
00589                 addMaterial(pMat);
00590         }
00591 
00592 }
00593 
00594 void GLC_Mesh::copyVboToClientSide()
00595 {
00596         m_MeshData.copyVboToClientSide();
00597         GLC_Geometry::copyVboToClientSide();
00598 }
00599 
00600 void GLC_Mesh::releaseVboClientSide(bool update)
00601 {
00602         m_MeshData.releaseVboClientSide(update);
00603         GLC_Geometry::releaseVboClientSide(update);
00604 }
00605 
00606 // Load the mesh from binary data stream
00607 void GLC_Mesh::loadFromDataStream(QDataStream& stream, const MaterialHash& materialHash, const QHash<GLC_uint, GLC_uint>& materialIdMap)
00608 {
00609         quint32 chunckId;
00610         stream >> chunckId;
00611         Q_ASSERT(chunckId == m_ChunkId);
00612 
00613         // The mesh name
00614         QString meshName;
00615         stream >> meshName;
00616         setName(meshName);
00617 
00618         // The wire data
00619         stream >> GLC_Geometry::m_WireData;
00620 
00621         // The mesh next primitive local id
00622         GLC_uint localId;
00623         stream >> localId;
00624         setNextPrimitiveLocalId(localId);
00625 
00626         // Retrieve geom mesh data
00627         stream >> m_MeshData;
00628 
00629         // Retrieve primitiveGroupLodList
00630         QList<int> primitiveGroupLodList;
00631         stream >> primitiveGroupLodList;
00632 
00633         // Retrieve primitiveGroup list
00634         QList<QList<GLC_PrimitiveGroup> > primitiveListOfGroupList;
00635         stream >> primitiveListOfGroupList;
00636 
00637         // Construct mesh primitiveGroupHash
00638         const int lodCount= primitiveGroupLodList.size();
00639         for (int i= 0; i < lodCount; ++i)
00640         {
00641                 GLC_Mesh::LodPrimitiveGroups* pCurrentPrimitiveGroup= new GLC_Mesh::LodPrimitiveGroups();
00642                 m_PrimitiveGroups.insert(primitiveGroupLodList.at(i), pCurrentPrimitiveGroup);
00643                 const int groupCount= primitiveListOfGroupList.at(i).size();
00644                 for (int iGroup= 0; iGroup < groupCount; ++iGroup)
00645                 {
00646                         Q_ASSERT(materialIdMap.contains(primitiveListOfGroupList.at(i).at(iGroup).id()));
00647                         const GLC_uint newId= materialIdMap.value(primitiveListOfGroupList.at(i).at(iGroup).id());
00648                         // Test if the mesh contains the material
00649                         if (!containsMaterial(newId))
00650                         {
00651                                 addMaterial(materialHash.value(newId));
00652                         }
00653                         GLC_PrimitiveGroup* pGroup= new GLC_PrimitiveGroup(primitiveListOfGroupList.at(i).at(iGroup), newId);
00654 
00655                         Q_ASSERT(! m_PrimitiveGroups.value(primitiveGroupLodList.at(i))->contains(newId));
00656                         m_PrimitiveGroups.value(primitiveGroupLodList.at(i))->insert(newId, pGroup);
00657                 }
00658         }
00659         stream >> m_NumberOfVertice;
00660         stream >> m_NumberOfNormals;
00661 
00662         finishSerialized();
00663         //qDebug() << "Mesh mem size= " << memmorySize();
00664 }
00665 
00666 // Save the mesh to binary data stream
00667 void GLC_Mesh::saveToDataStream(QDataStream& stream) const
00668 {
00669         quint32 chunckId= m_ChunkId;
00670         stream << chunckId;
00671 
00672         // The mesh name
00673         stream << name();
00674 
00675         // The wire data
00676         stream << m_WireData;
00677 
00678         // The mesh next primitive local id
00679         stream << nextPrimitiveLocalId();
00680 
00681         // Mesh data serialisation
00682         stream << m_MeshData;
00683 
00684         // Primitive groups serialisation
00685         QList<int> primitiveGroupLodList;
00686         QList<QList<GLC_PrimitiveGroup> > primitiveListOfGroupList;
00687 
00688         GLC_Mesh::PrimitiveGroupsHash::const_iterator iGroupsHash= m_PrimitiveGroups.constBegin();
00689         while (m_PrimitiveGroups.constEnd() != iGroupsHash)
00690         {
00691                 primitiveGroupLodList.append(iGroupsHash.key());
00692                 QList<GLC_PrimitiveGroup> primitiveGroupList;
00693                 GLC_Mesh::LodPrimitiveGroups::const_iterator iGroups= iGroupsHash.value()->constBegin();
00694                 while (iGroupsHash.value()->constEnd() != iGroups)
00695                 {
00696                         primitiveGroupList.append(*(iGroups.value()));
00697                         ++iGroups;
00698                 }
00699                 primitiveListOfGroupList.append(primitiveGroupList);
00700                 ++iGroupsHash;
00701         }
00702         stream << primitiveGroupLodList;
00703         stream << primitiveListOfGroupList;
00704 
00705         stream << m_NumberOfVertice;
00706         stream << m_NumberOfNormals;
00707 }
00708 
00710 // OpenGL Functions
00712 
00713 // Virtual interface for OpenGL Geometry set up.
00714 void GLC_Mesh::glDraw(const GLC_RenderProperties& renderProperties)
00715 {
00716         Q_ASSERT(m_GeometryIsValid || !m_MeshData.normalVectorHandle()->isEmpty());
00717 
00718         const bool vboIsUsed= GLC_State::vboUsed();
00719 
00720         if (m_IsSelected && (renderProperties.renderingMode() == glc::PrimitiveSelected) && !GLC_State::isInSelectionMode()
00721         && !renderProperties.setOfSelectedPrimitiveIdIsEmpty())
00722         {
00723                 m_CurrentLod= 0;
00724         }
00725 
00726         if (vboIsUsed)
00727         {
00728                 m_MeshData.createVBOs();
00729 
00730                 // Create VBO and IBO
00731                 if (!m_GeometryIsValid && !m_MeshData.positionVectorHandle()->isEmpty())
00732                 {
00733                         fillVbosAndIbos();
00734                 }
00735                 else if (!m_GeometryIsValid && !m_MeshData.normalVectorHandle()->isEmpty())
00736                 {
00737                         // Normals has been inversed update normal vbo
00738                         m_MeshData.useVBO(true, GLC_MeshData::GLC_Normal);
00739 
00740                         GLfloatVector* pNormalVector= m_MeshData.normalVectorHandle();
00741                         const GLsizei dataNbr= static_cast<GLsizei>(pNormalVector->size());
00742                         const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00743                         glBufferData(GL_ARRAY_BUFFER, dataSize, pNormalVector->data(), GL_STATIC_DRAW);
00744                         m_MeshData.normalVectorHandle()->clear();
00745                 }
00746 
00747                 // Activate mesh VBOs and IBO of the current LOD
00748                 activateVboAndIbo();
00749         }
00750         else
00751         {
00752                 activateVertexArray();
00753         }
00754 
00755         if (GLC_State::isInSelectionMode())
00756         {
00757                 if (renderProperties.renderingMode() == glc::PrimitiveSelection)
00758                 {
00759                         primitiveSelectionRenderLoop(vboIsUsed);
00760                 }
00761                 else if (renderProperties.renderingMode() == glc::BodySelection)
00762                 {
00763                         bodySelectionRenderLoop(vboIsUsed);
00764                 }
00765                 else
00766                 {
00767                         normalRenderLoop(renderProperties, vboIsUsed);
00768                 }
00769         }
00770         else if (m_IsSelected)
00771         {
00772                 if (renderProperties.renderingMode() == glc::PrimitiveSelected)
00773                 {
00774                         if (!renderProperties.setOfSelectedPrimitiveIdIsEmpty())
00775                         {
00776                                 primitiveSelectedRenderLoop(renderProperties, vboIsUsed);
00777                         }
00778                         else
00779                         {
00780                                 m_IsSelected= false;
00781                                 if ((m_CurrentLod == 0) && (renderProperties.savedRenderingMode() == glc::OverwritePrimitiveMaterial) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty())
00782                                         primitiveRenderLoop(renderProperties, vboIsUsed);
00783                                 else
00784                                         normalRenderLoop(renderProperties, vboIsUsed);
00785                                 m_IsSelected= true;
00786                         }
00787                 }
00788                 else
00789                 {
00790                         normalRenderLoop(renderProperties, vboIsUsed);
00791                 }
00792         }
00793         else
00794         {
00795                 // Choose the accurate render loop
00796                 switch (renderProperties.renderingMode())
00797                 {
00798                 case glc::NormalRenderMode:
00799                         normalRenderLoop(renderProperties, vboIsUsed);
00800                         break;
00801                 case glc::OverwriteMaterial:
00802                         OverwriteMaterialRenderLoop(renderProperties, vboIsUsed);
00803                         break;
00804                 case glc::OverwriteTransparency:
00805                         OverwriteTransparencyRenderLoop(renderProperties, vboIsUsed);
00806                         break;
00807                 case glc::OverwritePrimitiveMaterial:
00808                         if ((m_CurrentLod == 0) && !renderProperties.hashOfOverwritePrimitiveMaterialsIsEmpty())
00809                                 primitiveRenderLoop(renderProperties, vboIsUsed);
00810                         else
00811                                 normalRenderLoop(renderProperties, vboIsUsed);
00812                         break;
00813                 default:
00814                         Q_ASSERT(false);
00815                         break;
00816                 }
00817         }
00818 
00819 
00820         // Restore client state
00821         if (vboIsUsed)
00822         {
00823                 m_MeshData.useIBO(false);
00824                 m_MeshData.useVBO(false, GLC_MeshData::GLC_Normal);
00825         }
00826 
00827         if (m_ColorPearVertex && !m_IsSelected && !GLC_State::isInSelectionMode())
00828         {
00829                 glDisableClientState(GL_COLOR_ARRAY);
00830                 glDisable(GL_COLOR_MATERIAL);
00831         }
00832 
00833         glDisableClientState(GL_VERTEX_ARRAY);
00834         glDisableClientState(GL_NORMAL_ARRAY);
00835         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
00836 
00837         // Draw mesh's wire if necessary
00838         if ((renderProperties.renderingFlag() == glc::WireRenderFlag) && !m_WireData.isEmpty() && !GLC_Geometry::typeIsWire())
00839         {
00840                 if (!GLC_State::isInSelectionMode())
00841                 {
00842                         glDisable(GL_LIGHTING);
00843                         // Set polyline colors
00844                         GLfloat color[4]= {static_cast<float>(m_WireColor.redF()),
00845                                                                         static_cast<float>(m_WireColor.greenF()),
00846                                                                         static_cast<float>(m_WireColor.blueF()),
00847                                                                         static_cast<float>(m_WireColor.alphaF())};
00848 
00849                         glColor4fv(color);
00850                         m_WireData.glDraw(renderProperties);
00851                         glEnable(GL_LIGHTING);
00852                 }
00853                 else
00854                 {
00855                         m_WireData.glDraw(renderProperties);
00856                 }
00857         }
00858 
00859         // Update statistics
00860         GLC_RenderStatistics::addBodies(1);
00861         GLC_RenderStatistics::addTriangles(m_MeshData.trianglesCount(m_CurrentLod));
00862 }
00863 
00865 // Private services Functions
00867 
00868 // Set the current material
00869 GLC_uint GLC_Mesh::setCurrentMaterial(GLC_Material* pMaterial, int lod, double accuracy)
00870 {
00871 
00872         // Test if a primitive group hash exists for the specified lod
00873         if (!m_PrimitiveGroups.contains(lod))
00874         {
00875                 m_PrimitiveGroups.insert(lod, new LodPrimitiveGroups());
00876 
00877                 m_MeshData.appendLod(accuracy);
00878         }
00879 
00880         GLC_uint returnId;
00881         if (NULL == pMaterial)
00882         {
00883                 returnId= m_DefaultMaterialId; // Default material id
00884 
00885                 // Test if the material has been already load
00886                 if (m_DefaultMaterialId == 0)
00887                 {
00888                         pMaterial= new GLC_Material();
00889                         // Add the material to the mesh
00890                         addMaterial(pMaterial);
00891                         m_DefaultMaterialId= pMaterial->id();
00892                         returnId= m_DefaultMaterialId;
00893 
00894                 }
00895                 // Test if a primitive group for this material exist
00896                 if (!m_PrimitiveGroups.value(lod)->contains(returnId))
00897                 {
00898                         m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId));
00899                 }
00900         }
00901         else
00902         {
00903                 returnId= pMaterial->id();
00904                 // Test if the material has been already load
00905                 if (!containsMaterial(returnId))
00906                 {
00907                         // Add the material to the mesh
00908                         addMaterial(pMaterial);
00909                         m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId));
00910 
00911                 }
00912                 else if (!m_PrimitiveGroups.value(lod)->contains(returnId))
00913                 {
00914                         // Add the material to the group
00915                         m_PrimitiveGroups.value(lod)->insert(returnId, new GLC_PrimitiveGroup(returnId));
00916                 }
00917         }
00918 
00919         return returnId;
00920 }
00921 
00922 // Fill VBOs and IBOs
00923 void GLC_Mesh::fillVbosAndIbos()
00924 {
00925         // Create VBO of vertices
00926         m_MeshData.fillVbo(GLC_MeshData::GLC_Vertex);
00927 
00928         // Create VBO of normals
00929         m_MeshData.fillVbo(GLC_MeshData::GLC_Normal);
00930 
00931         // Create VBO of texel if needed
00932         m_MeshData.fillVbo(GLC_MeshData::GLC_Texel);
00933 
00934         // Create VBO of color if needed
00935         m_MeshData.fillVbo(GLC_MeshData::GLC_Color);
00936 
00937         const int lodNumber= m_MeshData.lodCount();
00938         for (int i= 0; i < lodNumber; ++i)
00939         {
00940                 //Create LOD IBO
00941                 if (!m_MeshData.indexVectorHandle(i)->isEmpty())
00942                 {
00943                         QVector<GLuint>* pIndexVector= m_MeshData.indexVectorHandle(i);
00944                         m_MeshData.useIBO(true, i);
00945                         const GLsizei indexNbr= static_cast<GLsizei>(pIndexVector->size());
00946                         const GLsizeiptr indexSize = indexNbr * sizeof(GLuint);
00947                         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexSize, pIndexVector->data(), GL_STATIC_DRAW);
00948                 }
00949         }
00950         // Remove client side data
00951         m_MeshData.finishVbo();
00952 
00953 }
00954 // set primitive group offset
00955 void GLC_Mesh::finishSerialized()
00956 {
00957         if (GLC_State::vboUsed())
00958         {
00959                 PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
00960                 while (iGroups != m_PrimitiveGroups.constEnd())
00961                 {
00962                         LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
00963                         while (iGroup != iGroups.value()->constEnd())
00964                         {
00965                                 iGroup.value()->changeToVboMode();
00966                                 ++iGroup;
00967                         }
00968                         ++iGroups;
00969                 }
00970         }
00971 }
00972 
00973 // Move Indexs from the primitive groups to the mesh Data LOD and Set IBOs offsets
00974 void GLC_Mesh::finishVbo()
00975 {
00976         PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
00977         while (iGroups != m_PrimitiveGroups.constEnd())
00978         {
00979                 int currentLod= iGroups.key();
00980                 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
00981                 while (iGroup != iGroups.value()->constEnd())
00982                 {
00983                         // Add group triangles index to mesh Data LOD triangles index vector
00984                         if (iGroup.value()->containsTriangles())
00985                         {
00986                                 iGroup.value()->setTrianglesOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint)));
00987                                 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->trianglesIndex().toVector();
00988                         }
00989 
00990                         // Add group strip index to mesh Data LOD strip index vector
00991                         if (iGroup.value()->containsStrip())
00992                         {
00993                                 iGroup.value()->setBaseTrianglesStripOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint)));
00994                                 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->stripsIndex().toVector();
00995                         }
00996 
00997                         // Add group fan index to mesh Data LOD fan index vector
00998                         if (iGroup.value()->containsFan())
00999                         {
01000                                 iGroup.value()->setBaseTrianglesFanOffset(BUFFER_OFFSET(m_MeshData.indexVectorSize(currentLod) * sizeof(GLuint)));
01001                                 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->fansIndex().toVector();
01002                         }
01003 
01004                         iGroup.value()->finish();
01005                         ++iGroup;
01006                 }
01007                 ++iGroups;
01008 
01009         }
01010 }
01011 
01012 // Move Indexs from the primitive groups to the mesh Data LOD and Set Index offsets
01013 void GLC_Mesh::finishNonVbo()
01014 {
01015         //qDebug() << "GLC_Mesh::finishNonVbo()";
01016         PrimitiveGroupsHash::iterator iGroups= m_PrimitiveGroups.begin();
01017         while (iGroups != m_PrimitiveGroups.constEnd())
01018         {
01019                 int currentLod= iGroups.key();
01020                 LodPrimitiveGroups::iterator iGroup= iGroups.value()->begin();
01021                 while (iGroup != iGroups.value()->constEnd())
01022                 {
01023                         // Add group triangles index to mesh Data LOD triangles index vector
01024                         if (iGroup.value()->containsTriangles())
01025                         {
01026                                 iGroup.value()->setTrianglesOffseti(m_MeshData.indexVectorSize(currentLod));
01027                                 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->trianglesIndex().toVector();
01028                         }
01029 
01030                         // Add group strip index to mesh Data LOD strip index vector
01031                         if (iGroup.value()->containsStrip())
01032                         {
01033                                 iGroup.value()->setBaseTrianglesStripOffseti(m_MeshData.indexVectorSize(currentLod));
01034                                 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->stripsIndex().toVector();
01035                         }
01036 
01037                         // Add group fan index to mesh Data LOD fan index vector
01038                         if (iGroup.value()->containsFan())
01039                         {
01040                                 iGroup.value()->setBaseTrianglesFanOffseti(m_MeshData.indexVectorSize(currentLod));
01041                                 (*m_MeshData.indexVectorHandle(currentLod))+= iGroup.value()->fansIndex().toVector();
01042                         }
01043 
01044                         iGroup.value()->finish();
01045                         ++iGroup;
01046                 }
01047                 ++iGroups;
01048         }
01049 }
01050 
01051 // The normal display loop
01052 void GLC_Mesh::normalRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01053 {
01054         const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
01055         if ((!m_IsSelected || !isTransparent) || GLC_State::isInSelectionMode())
01056         {
01057                 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01058                 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01059                 {
01060                         GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01061                         GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id());
01062 
01063                         // Test if the current material is renderable
01064                         bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent);
01065 
01066                         // Choose the material to render
01067                         if ((materialIsrenderable || m_IsSelected) && !GLC_State::isInSelectionMode())
01068                 {
01069                                 // Execute current material
01070                                 pCurrentMaterial->glExecute();
01071 
01072                                 if (m_IsSelected) GLC_SelectionMaterial::glExecute();
01073                         }
01074 
01075                         // Choose the primitives to render
01076                         if (m_IsSelected || GLC_State::isInSelectionMode() || materialIsrenderable)
01077                         {
01078 
01079                                 if (vboIsUsed)
01080                                         vboDrawPrimitivesOf(pCurrentGroup);
01081                                 else
01082                                         vertexArrayDrawPrimitivesOf(pCurrentGroup);
01083                         }
01084 
01085                         ++iGroup;
01086                 }
01087         }
01088 }
01089 
01090 //  The overwrite material render loop
01091 void GLC_Mesh::OverwriteMaterialRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01092 {
01093         // Get the overwrite material
01094         GLC_Material* pOverwriteMaterial= renderProperties.overwriteMaterial();
01095         Q_ASSERT(NULL != pOverwriteMaterial);
01096         pOverwriteMaterial->glExecute();
01097         if (m_IsSelected) GLC_SelectionMaterial::glExecute();
01098 
01099         LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01100         while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01101         {
01102                 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01103 
01104                 // Test if the current material is renderable
01105                 bool materialIsrenderable = (pOverwriteMaterial->isTransparent() == (renderProperties.renderingFlag() == glc::TransparentRenderFlag));
01106 
01107                 // Choose the primitives to render
01108                 if (m_IsSelected || materialIsrenderable)
01109                 {
01110 
01111                         if (vboIsUsed)
01112                                 vboDrawPrimitivesOf(pCurrentGroup);
01113                         else
01114                                 vertexArrayDrawPrimitivesOf(pCurrentGroup);
01115                 }
01116 
01117                 ++iGroup;
01118         }
01119 }
01120 // The overwrite transparency render loop
01121 void GLC_Mesh::OverwriteTransparencyRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01122 {
01123         // Get transparency value
01124         const float alpha= renderProperties.overwriteTransparency();
01125         Q_ASSERT(-1.0f != alpha);
01126 
01127         // Test if the current material is renderable
01128         bool materialIsrenderable = (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
01129 
01130         if (materialIsrenderable || m_IsSelected)
01131         {
01132                 LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01133                 while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01134                 {
01135                         GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01136                         GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id());
01137 
01138                         // Execute current material
01139                         pCurrentMaterial->glExecute(alpha);
01140 
01141                         if (m_IsSelected) GLC_SelectionMaterial::glExecute();
01142 
01143                         // Choose the primitives to render
01144                         if (m_IsSelected || materialIsrenderable)
01145                         {
01146 
01147                                 if (vboIsUsed)
01148                                         vboDrawPrimitivesOf(pCurrentGroup);
01149                                 else
01150                                         vertexArrayDrawPrimitivesOf(pCurrentGroup);
01151                         }
01152                         ++iGroup;
01153                 }
01154         }
01155 }
01156 
01157 // The body selection render loop
01158 void GLC_Mesh::bodySelectionRenderLoop(bool vboIsUsed)
01159 {
01160         Q_ASSERT(GLC_State::isInSelectionMode());
01161 
01162         LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01163         while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01164         {
01165                 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01166 
01167                 if (vboIsUsed)
01168                         vboDrawPrimitivesOf(pCurrentGroup);
01169                 else
01170                         vertexArrayDrawPrimitivesOf(pCurrentGroup);
01171 
01172                 ++iGroup;
01173         }
01174 }
01175 
01176 // The primitive selection render loop
01177 void GLC_Mesh::primitiveSelectionRenderLoop(bool vboIsUsed)
01178 {
01179         Q_ASSERT(GLC_State::isInSelectionMode());
01180 
01181         LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01182 
01183         while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01184         {
01185                 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01186 
01187                 if (vboIsUsed)
01188                         vboDrawInSelectionModePrimitivesOf(pCurrentGroup);
01189                 else
01190                         vertexArrayDrawInSelectionModePrimitivesOf(pCurrentGroup);
01191 
01192                 ++iGroup;
01193         }
01194 }
01195 
01196 // The primitive rendeder loop
01197 void GLC_Mesh::primitiveRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01198 {
01199         const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
01200         LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01201         while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01202         {
01203                 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01204                 GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id());
01205 
01206                 // Test if the current material is renderable
01207                 const bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent);
01208 
01209                 if (materialIsrenderable)
01210                 {
01211                         pCurrentMaterial->glExecute();
01212                 }
01213                 if (vboIsUsed)
01214                         vboDrawPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties.hashOfOverwritePrimitiveMaterials());
01215                 else
01216                         vertexArrayDrawPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties.hashOfOverwritePrimitiveMaterials());
01217 
01218                 ++iGroup;
01219         }
01220 }
01221 
01222 // The primitive Selected render loop
01223 void GLC_Mesh::primitiveSelectedRenderLoop(const GLC_RenderProperties& renderProperties, bool vboIsUsed)
01224 {
01225         const bool isTransparent= (renderProperties.renderingFlag() == glc::TransparentRenderFlag);
01226         LodPrimitiveGroups::iterator iGroup= m_PrimitiveGroups.value(m_CurrentLod)->begin();
01227         while (iGroup != m_PrimitiveGroups.value(m_CurrentLod)->constEnd())
01228         {
01229                 GLC_PrimitiveGroup* pCurrentGroup= iGroup.value();
01230                 GLC_Material* pCurrentMaterial= m_MaterialHash.value(pCurrentGroup->id());
01231 
01232                 // Test if the current material is renderable
01233                 const bool materialIsrenderable = (pCurrentMaterial->isTransparent() == isTransparent);
01234 
01235                 if (materialIsrenderable)
01236                 {
01237                         pCurrentMaterial->glExecute();
01238                 }
01239 
01240                 if (vboIsUsed)
01241                         vboDrawSelectedPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties);
01242                 else
01243                         vertexArrayDrawSelectedPrimitivesGroupOf(pCurrentGroup, pCurrentMaterial, materialIsrenderable, isTransparent, renderProperties);
01244 
01245                 ++iGroup;
01246         }
01247 }
01248 

SourceForge.net Logo

©2005-2010 Laurent Ribon