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

SourceForge.net Logo

©2005-2011 Laurent Ribon