glc_meshdata.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 "glc_meshdata.h"
00026 #include "../glc_state.h"
00027 
00028 // Class chunk id
00029 quint32 GLC_MeshData::m_ChunkId= 0xA704;
00030 
00031 // Default constructor
00032 GLC_MeshData::GLC_MeshData()
00033 : m_VboId(0)
00034 , m_Positions()
00035 , m_Normals()
00036 , m_Texels()
00037 , m_Colors()
00038 , m_NormalVboId(0)
00039 , m_TexelVboId(0)
00040 , m_ColorVboId(0)
00041 , m_LodList()
00042 , m_PositionSize(0)
00043 , m_TexelsSize(0)
00044 , m_ColorSize(0)
00045 {
00046 
00047 }
00048 
00049 // Copy constructor
00050 GLC_MeshData::GLC_MeshData(const GLC_MeshData& meshData)
00051 : m_VboId(0)
00052 , m_Positions(meshData.positionVector())
00053 , m_Normals(meshData.normalVector())
00054 , m_Texels(meshData.texelVector())
00055 , m_Colors(meshData.colorVector())
00056 , m_NormalVboId(0)
00057 , m_TexelVboId(0)
00058 , m_ColorVboId(0)
00059 , m_LodList()
00060 , m_PositionSize(meshData.m_PositionSize)
00061 , m_TexelsSize(meshData.m_TexelsSize)
00062 , m_ColorSize(meshData.m_ColorSize)
00063 {
00064         // Copy meshData LOD list
00065         const int size= meshData.m_LodList.size();
00066         for (int i= 0; i < size; ++i)
00067         {
00068                 m_LodList.append(new GLC_Lod(*meshData.m_LodList.at(i)));
00069         }
00070 }
00071 
00072 // Overload "=" operator
00073 GLC_MeshData& GLC_MeshData::operator=(const GLC_MeshData& meshData)
00074 {
00075         if (this != &meshData)
00076         {
00077                 // Clear the content of the mesh Data
00078                 clear();
00079 
00080                 // Copy mesh Data members
00081                 m_Positions= meshData.positionVector();
00082                 m_Normals= meshData.normalVector();
00083                 m_Texels= meshData.texelVector();
00084                 m_Colors= meshData.colorVector();
00085                 m_PositionSize= meshData.m_PositionSize;
00086                 m_TexelsSize= meshData.m_TexelsSize;
00087                 m_ColorSize= meshData.m_ColorSize;
00088 
00089                 // Copy meshData LOD list
00090                 const int size= meshData.m_LodList.size();
00091                 for (int i= 0; i < size; ++i)
00092                 {
00093                         m_LodList.append(new GLC_Lod(*meshData.m_LodList.at(i)));
00094                 }
00095         }
00096         return *this;
00097 }
00098 
00099 GLC_MeshData::~GLC_MeshData()
00100 {
00101         clear();
00102 }
00104 // Get Functions
00106 // Return the class Chunk ID
00107 quint32 GLC_MeshData::chunckID()
00108 {
00109         return m_ChunkId;
00110 }
00111 
00112 // Return the Position Vector
00113 GLfloatVector GLC_MeshData::positionVector() const
00114 {
00115         if (0 != m_VboId)
00116         {
00117                 // VBO created get data from VBO
00118                 const int sizeOfVbo= m_PositionSize;
00119                 const GLsizeiptr dataSize= sizeOfVbo * sizeof(float);
00120                 GLfloatVector positionVector(sizeOfVbo);
00121 
00122                 glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
00123                 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00124                 memcpy(positionVector.data(), pVbo, dataSize);
00125                 glUnmapBuffer(GL_ARRAY_BUFFER);
00126                 glBindBuffer(GL_ARRAY_BUFFER, 0);
00127                 return positionVector;
00128         }
00129         else
00130         {
00131                 return m_Positions;
00132         }
00133 }
00134 
00135 // Return the normal Vector
00136 GLfloatVector GLC_MeshData::normalVector() const
00137 {
00138         if (0 != m_NormalVboId)
00139         {
00140                 // VBO created get data from VBO
00141                 const int sizeOfVbo= m_PositionSize;
00142                 const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
00143                 GLfloatVector normalVector(sizeOfVbo);
00144 
00145                 glBindBuffer(GL_ARRAY_BUFFER, m_NormalVboId);
00146                 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00147                 memcpy(normalVector.data(), pVbo, dataSize);
00148                 glUnmapBuffer(GL_ARRAY_BUFFER);
00149                 glBindBuffer(GL_ARRAY_BUFFER, 0);
00150                 return normalVector;
00151         }
00152         else
00153         {
00154                 return m_Normals;
00155         }
00156 }
00157 
00158 // Return the texel Vector
00159 GLfloatVector GLC_MeshData::texelVector() const
00160 {
00161         if (0 != m_TexelVboId)
00162         {
00163                 // VBO created get data from VBO
00164                 const int sizeOfVbo= m_TexelsSize;
00165                 const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
00166                 GLfloatVector texelVector(sizeOfVbo);
00167 
00168                 glBindBuffer(GL_ARRAY_BUFFER, m_TexelVboId);
00169                 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00170                 memcpy(texelVector.data(), pVbo, dataSize);
00171                 glUnmapBuffer(GL_ARRAY_BUFFER);
00172                 glBindBuffer(GL_ARRAY_BUFFER, 0);
00173                 return texelVector;
00174         }
00175         else
00176         {
00177                 return m_Texels;
00178         }
00179 }
00180 
00181 // Return the color Vector
00182 GLfloatVector GLC_MeshData::colorVector() const
00183 {
00184         if (0 != m_ColorVboId)
00185         {
00186                 // VBO created get data from VBO
00187                 const int sizeOfVbo= m_ColorSize;
00188                 const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
00189                 GLfloatVector normalVector(sizeOfVbo);
00190 
00191                 glBindBuffer(GL_ARRAY_BUFFER, m_ColorVboId);
00192                 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00193                 memcpy(normalVector.data(), pVbo, dataSize);
00194                 glUnmapBuffer(GL_ARRAY_BUFFER);
00195                 glBindBuffer(GL_ARRAY_BUFFER, 0);
00196                 return normalVector;
00197         }
00198         else
00199         {
00200                 return m_Colors;
00201         }
00202 }
00203 
00205 // Set Functions
00207 
00208 // The mesh wich use the data is finished
00209 void GLC_MeshData::finishVbo()
00210 {
00211         m_PositionSize= m_Positions.size();
00212         m_Positions.clear();
00213         m_Normals.clear();
00214         m_TexelsSize= m_Texels.size();
00215         m_Texels.clear();
00216         m_ColorSize= m_Colors.size();
00217         m_Colors.clear();
00218 
00219         // Finish the LOD
00220         const int size= m_LodList.size();
00221         for (int i= 0; i < size; ++i)
00222         {
00223                 m_LodList[i]->finishVbo();
00224         }
00225 }
00226 
00227 // If the there is more than 2 LOD Swap the first and last
00228 void GLC_MeshData::finishLod()
00229 {
00230         // PLace the master LOD at the beginning of the list
00231         const int size= m_LodList.size();
00232         if (size > 1)
00233         {
00234                 GLC_Lod* PMasterLod= m_LodList.at(size - 1);
00235                 m_LodList.removeAt(size - 1);
00236                 m_LodList.prepend(PMasterLod);
00237         }
00238 }
00239 
00240 // Clear the content of the meshData and makes it empty
00241 void GLC_MeshData::clear()
00242 {
00243         m_Positions.clear();
00244         m_Normals.clear();
00245         m_Texels.clear();
00246         m_Colors.clear();
00247         m_PositionSize= 0;
00248         m_TexelsSize= 0;
00249         m_ColorSize= 0;
00250 
00251         // Delete Main Vbo ID
00252         if (0 != m_VboId)
00253         {
00254                 glDeleteBuffers(1, &m_VboId);
00255                 m_VboId= 0;
00256         }
00257 
00258         // Delete Normal VBO
00259         if (0 != m_NormalVboId)
00260         {
00261                 glDeleteBuffers(1, &m_NormalVboId);
00262                 m_NormalVboId= 0;
00263         }
00264 
00265         // Delete Texel VBO
00266         if (0 != m_TexelVboId)
00267         {
00268                 glDeleteBuffers(1, &m_TexelVboId);
00269                 m_TexelVboId= 0;
00270         }
00271         // Delete color index
00272         if (0 != m_ColorVboId)
00273         {
00274                 glDeleteBuffers(1, &m_ColorVboId);
00275                 m_ColorVboId= 0;
00276         }
00277 
00278         const int size= m_LodList.size();
00279         for (int i= 0; i < size; ++i)
00280         {
00281                 delete m_LodList.at(i);
00282         }
00283         m_LodList.clear();
00284 }
00285 
00286 void GLC_MeshData::copyVboToClientSide()
00287 {
00288 
00289         if ((0 != m_VboId) && m_Positions.isEmpty())
00290         {
00291                 Q_ASSERT(0 != m_NormalVboId);
00292                 m_Positions= positionVector();
00293                 m_Normals= normalVector();
00294                 if (0 != m_TexelVboId)
00295                 {
00296                         m_Texels= texelVector();
00297                 }
00298                 if (0 != m_ColorVboId)
00299                 {
00300                         m_Colors= colorVector();
00301                 }
00302         }
00303 }
00304 
00305 void GLC_MeshData::releaseVboClientSide(bool update)
00306 {
00307         if ((0 != m_VboId) && !m_Positions.isEmpty())
00308         {
00309                 if (update)
00310                 {
00311                         fillVbo(GLC_MeshData::GLC_Vertex);
00312                         fillVbo(GLC_MeshData::GLC_Normal);
00313                         fillVbo(GLC_MeshData::GLC_Texel);
00314                         fillVbo(GLC_MeshData::GLC_Color);
00315                         useVBO(false, GLC_MeshData::GLC_Color);
00316                 }
00317                 m_PositionSize= m_Positions.size();
00318                 m_Positions.clear();
00319                 m_Normals.clear();
00320                 m_TexelsSize= m_Texels.size();
00321                 m_Texels.clear();
00322                 m_ColorSize= m_Colors.size();
00323                 m_Colors.clear();
00324         }
00325 }
00326 
00328 // OpenGL Functions
00330 // Vbo creation
00331 void GLC_MeshData::createVBOs()
00332 {
00333         // Create position VBO
00334         if (0 == m_VboId)
00335         {
00336                 glGenBuffers(1, &m_VboId);
00337                 glGenBuffers(1, &m_NormalVboId);
00338 
00339                 // Create Texel VBO
00340                 if (0 == m_TexelVboId && !m_Texels.isEmpty())
00341                 {
00342                         glGenBuffers(1, &m_TexelVboId);
00343                 }
00344 
00345                 // Create Color VBO
00346                 if (0 == m_ColorVboId && !m_Colors.isEmpty())
00347                 {
00348                         glGenBuffers(1, &m_ColorVboId);
00349                 }
00350 
00351                 const int size= m_LodList.size();
00352                 for (int i= 0; i < size; ++i)
00353                 {
00354                         m_LodList.at(i)->createIBO();
00355                 }
00356         }
00357 }
00358 
00359 // Ibo Usage
00360 bool GLC_MeshData::useVBO(bool use, GLC_MeshData::VboType type) const
00361 {
00362         bool result= true;
00363         if (use)
00364         {
00365                 // Chose the right VBO
00366                 if (type == GLC_MeshData::GLC_Vertex)
00367                 {
00368                         glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
00369                 }
00370                 else if (type == GLC_MeshData::GLC_Normal)
00371                 {
00372                         glBindBuffer(GL_ARRAY_BUFFER, m_NormalVboId);
00373                 }
00374                 else if ((type == GLC_MeshData::GLC_Texel) && (0 != m_TexelVboId))
00375                 {
00376                         glBindBuffer(GL_ARRAY_BUFFER, m_TexelVboId);
00377                 }
00378                 else if ((type == GLC_MeshData::GLC_Color) && (0 != m_ColorVboId))
00379                 {
00380                         glBindBuffer(GL_ARRAY_BUFFER, m_ColorVboId);
00381                 }
00382 
00383                 else result= false;
00384         }
00385         else
00386         {
00387                 // Unbind VBO
00388                 glBindBuffer(GL_ARRAY_BUFFER, 0);
00389         }
00390         return result;
00391 }
00392 
00393 void GLC_MeshData::fillVbo(GLC_MeshData::VboType type)
00394 {
00395         // Chose the right VBO
00396         if (type == GLC_MeshData::GLC_Vertex)
00397         {
00398                 useVBO(true, type);
00399                 const GLsizei dataNbr= static_cast<GLsizei>(m_Positions.size());
00400                 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00401                 glBufferData(GL_ARRAY_BUFFER, dataSize, m_Positions.data(), GL_STATIC_DRAW);
00402         }
00403         else if (type == GLC_MeshData::GLC_Normal)
00404         {
00405                 useVBO(true, type);
00406                 const GLsizei dataNbr= static_cast<GLsizei>(m_Normals.size());
00407                 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00408                 glBufferData(GL_ARRAY_BUFFER, dataSize, m_Normals.data(), GL_STATIC_DRAW);
00409         }
00410         else if ((type == GLC_MeshData::GLC_Texel) && (0 != m_TexelVboId))
00411         {
00412                 useVBO(true, type);
00413                 const GLsizei dataNbr= static_cast<GLsizei>(m_Texels.size());
00414                 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00415                 glBufferData(GL_ARRAY_BUFFER, dataSize, m_Texels.data(), GL_STATIC_DRAW);
00416         }
00417         else if ((type == GLC_MeshData::GLC_Color) && (0 != m_ColorVboId))
00418         {
00419                 useVBO(true, type);
00420                 const GLsizei dataNbr= static_cast<GLsizei>(m_Colors.size());
00421                 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00422                 glBufferData(GL_ARRAY_BUFFER, dataSize, m_Colors.data(), GL_STATIC_DRAW);
00423         }
00424 }
00425 // Non Member methods
00426 // Non-member stream operator
00427 QDataStream &operator<<(QDataStream &stream, const GLC_MeshData &meshData)
00428 {
00429         quint32 chunckId= GLC_MeshData::m_ChunkId;
00430         stream << chunckId;
00431 
00432         stream << meshData.positionVector();
00433         stream << meshData.normalVector();
00434         stream << meshData.texelVector();
00435         stream << meshData.colorVector();
00436 
00437         // List of lod serialisation
00438         const int lodCount= meshData.m_LodList.size();
00439         QList<GLC_Lod> lodsList;
00440         for (int i= 0; i < lodCount; ++i)
00441         {
00442                 lodsList.append(*(meshData.m_LodList[i]));
00443         }
00444         stream << lodsList;
00445 
00446         return stream;
00447 }
00448 
00449 QDataStream &operator>>(QDataStream &stream, GLC_MeshData &meshData)
00450 {
00451         quint32 chunckId;
00452         stream >> chunckId;
00453         Q_ASSERT(chunckId == GLC_MeshData::m_ChunkId);
00454 
00455         meshData.clear();
00456 
00457         GLfloatVector position, normal, texel, color;
00458 
00459         stream >> meshData.m_Positions;
00460         stream >> meshData.m_Normals;
00461         stream >> meshData.m_Texels;
00462         stream >> meshData.m_Colors;
00463 
00464         // List of lod serialisation
00465         QList<GLC_Lod> lodsList;
00466         stream >> lodsList;
00467         const int lodCount= lodsList.size();
00468         for (int i= 0; i < lodCount; ++i)
00469         {
00470                 meshData.m_LodList.append(new GLC_Lod(lodsList.at(i)));
00471         }
00472 
00473         return stream;
00474 }
00475 

SourceForge.net Logo

©2005-2011 Laurent Ribon