glc_wiredata.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_wiredata.h"
00026 #include "../glc_ext.h"
00027 #include "../glc_state.h"
00028 
00029 // Class chunk id
00030 quint32 GLC_WireData::m_ChunkId= 0xA706;
00031 
00032 
00033 GLC_WireData::GLC_WireData()
00034 : m_VboId(0)
00035 , m_NextPrimitiveLocalId(1)
00036 , m_Positions()
00037 , m_PositionSize(0)
00038 , m_pBoundingBox(NULL)
00039 , m_VerticeGrouprSizes()
00040 , m_VerticeGroupOffset()
00041 , m_VerticeGroupId()
00042 , m_VerticeGroupCount(0)
00043 {
00044 
00045 }
00046 
00047 
00048 GLC_WireData::GLC_WireData(const GLC_WireData& data)
00049 : m_VboId(0)
00050 , m_NextPrimitiveLocalId(data.m_NextPrimitiveLocalId)
00051 , m_Positions(data.positionVector())
00052 , m_PositionSize(data.m_PositionSize)
00053 , m_pBoundingBox(NULL)
00054 , m_VerticeGrouprSizes(data.m_VerticeGrouprSizes)
00055 , m_VerticeGroupOffset(data.m_VerticeGroupOffset)
00056 , m_VerticeGroupId(data.m_VerticeGroupId)
00057 , m_VerticeGroupCount(data.m_VerticeGroupCount)
00058 {
00059         if (NULL != data.m_pBoundingBox)
00060         {
00061                 m_pBoundingBox= new GLC_BoundingBox(*(data.m_pBoundingBox));
00062         }
00063 }
00064 
00065 
00066 GLC_WireData& GLC_WireData::operator=(const GLC_WireData& data)
00067 {
00068         if (this != &data)
00069         {
00070                 clear();
00071                 m_NextPrimitiveLocalId= data.m_NextPrimitiveLocalId;
00072                 m_Positions= data.positionVector();
00073                 m_PositionSize= data.m_PositionSize;
00074                 if (NULL != data.m_pBoundingBox)
00075                 {
00076                         m_pBoundingBox= new GLC_BoundingBox(*(data.m_pBoundingBox));
00077                 }
00078                 m_VerticeGrouprSizes= data.m_VerticeGrouprSizes;
00079                 m_VerticeGroupOffset= data.m_VerticeGroupOffset;
00080                 m_VerticeGroupId= data.m_VerticeGroupId;
00081                 m_VerticeGroupCount= data.m_VerticeGroupCount;
00082         }
00083         return *this;
00084 }
00085 
00086 GLC_WireData::~GLC_WireData()
00087 {
00088         clear();
00089 
00090         // Delete Main Vbo ID
00091         if (0 != m_VboId)
00092         {
00093                 glDeleteBuffers(1, &m_VboId);
00094                 m_VboId= 0;
00095         }
00096 }
00098 // Get Functions
00100 
00101 
00102 quint32 GLC_WireData::chunckID()
00103 {
00104         return m_ChunkId;
00105 }
00106 
00107 
00108 GLfloatVector GLC_WireData::positionVector() const
00109 {
00110         if (0 != m_VboId)
00111         {
00112                 // VBO created get data from VBO
00113                 const int sizeOfVbo= m_PositionSize;
00114                 const GLsizeiptr dataSize= sizeOfVbo * sizeof(float);
00115                 GLfloatVector positionVector(sizeOfVbo);
00116 
00117                 glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
00118                 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00119                 memcpy(positionVector.data(), pVbo, dataSize);
00120                 glUnmapBuffer(GL_ARRAY_BUFFER);
00121                 glBindBuffer(GL_ARRAY_BUFFER, 0);
00122                 return positionVector;
00123         }
00124         else
00125         {
00126                 return m_Positions;
00127         }
00128 }
00129 
00130 
00131 GLC_BoundingBox& GLC_WireData::boundingBox()
00132 {
00133         if (NULL == m_pBoundingBox)
00134         {
00135                 m_pBoundingBox= new GLC_BoundingBox();
00136 
00137                 if (m_Positions.isEmpty())
00138                 {
00139                         //qDebug() << "GLC_WireData::getBoundingBox empty m_Positions";
00140                 }
00141                 else
00142                 {
00143                         const int max= m_Positions.size();
00144                         for (int i= 0; i < max; i= i + 3)
00145                         {
00146                                 GLC_Point3d point(m_Positions[i], m_Positions[i + 1], m_Positions[i + 2]);
00147                                 m_pBoundingBox->combine(point);
00148                         }
00149                 }
00150 
00151         }
00152         return *m_pBoundingBox;
00153 }
00154 
00156 // Set Functions
00158 
00159 
00160 GLC_uint GLC_WireData::addVerticeGroup(const GLfloatVector& floatVector)
00161 {
00162         Q_ASSERT((floatVector.size() % 3) == 0);
00163 
00164         ++m_VerticeGroupCount;
00165         m_Positions+= floatVector;
00166 
00167         m_VerticeGrouprSizes.append(static_cast<GLsizei>(floatVector.size() / 3));
00168 
00169         if (m_VerticeGroupOffset.isEmpty())
00170         {
00171                 m_VerticeGroupOffset.append(0);
00172         }
00173         int offset= m_VerticeGroupOffset.last() + m_VerticeGrouprSizes.last();
00174         m_VerticeGroupOffset.append(offset);
00175 
00176         // The Polyline id
00177         m_VerticeGroupId.append(m_NextPrimitiveLocalId);
00178         return m_NextPrimitiveLocalId++;
00179 }
00180 
00181 void GLC_WireData::clear()
00182 {
00183         m_NextPrimitiveLocalId= 1;
00184         m_Positions.clear();
00185         m_PositionSize= 0;
00186         delete m_pBoundingBox;
00187         m_pBoundingBox= NULL;
00188 
00189         m_VerticeGrouprSizes.clear();
00190         m_VerticeGroupOffset.clear();
00191         m_VerticeGroupId.clear();
00192         m_VerticeGroupCount= 0;
00193 }
00194 
00195 void GLC_WireData::copyVboToClientSide()
00196 {
00197         if ((0 != m_VboId) && m_Positions.isEmpty())
00198         {
00199                 m_Positions= positionVector();
00200         }
00201 }
00202 
00203 void GLC_WireData::releaseVboClientSide(bool update)
00204 {
00205         if ((0 != m_VboId) && !m_Positions.isEmpty())
00206         {
00207                 if (update) finishVbo();
00208         }
00209 }
00210 
00211 
00213 // OpenGL Functions
00215 
00216 void GLC_WireData::finishVbo()
00217 {
00218         createVBOs();
00219         useVBO(true);
00220         fillVBOs();
00221         useVBO(false);
00222 
00223         m_PositionSize= m_Positions.size();
00224         m_Positions.clear();
00225 }
00226 
00227 void GLC_WireData::useVBO(bool use)
00228 {
00229         if (use)
00230         {
00231                 glBindBuffer(GL_ARRAY_BUFFER, m_VboId); }
00232         else
00233         {
00234                 // Unbind VBO
00235                 glBindBuffer(GL_ARRAY_BUFFER, 0);
00236         }
00237 }
00238 
00239 void GLC_WireData::glDraw(const GLC_RenderProperties&, GLenum mode)
00240 {
00241         Q_ASSERT(!isEmpty());
00242         const bool vboIsUsed= GLC_State::vboUsed();
00243 
00244         if (vboIsUsed && ((m_PositionSize == 0) || (0 == m_VboId)))
00245         {
00246                 finishVbo();
00247         }
00248         else if (m_PositionSize == 0)
00249         {
00250                 m_PositionSize= m_Positions.size();
00251         }
00252 
00253         // Activate VBO or Vertex Array
00254         if (vboIsUsed)
00255         {
00256                 useVBO(true);
00257                 glVertexPointer(3, GL_FLOAT, 0, 0);
00258         }
00259         else
00260         {
00261                 glVertexPointer(3, GL_FLOAT, 0, m_Positions.data());
00262         }
00263         glEnableClientState(GL_VERTEX_ARRAY);
00264 
00265         // Render polylines
00266         for (int i= 0; i < m_VerticeGroupCount; ++i)
00267         {
00268                 glDrawArrays(mode, m_VerticeGroupOffset.at(i), m_VerticeGrouprSizes.at(i));
00269         }
00270 
00271         // Desactivate VBO or Vertex Array
00272         if (vboIsUsed)
00273         {
00274                 useVBO(false);
00275         }
00276 
00277         glDisableClientState(GL_VERTEX_ARRAY);
00278 }
00279 
00280 void GLC_WireData::createVBOs()
00281 {
00282         // Create position VBO
00283         if (0 == m_VboId)
00284         {
00285                 glGenBuffers(1, &m_VboId);
00286         }
00287 }
00288 
00289 void GLC_WireData::fillVBOs()
00290 {
00291         const GLsizei dataNbr= static_cast<GLsizei>(m_Positions.size());
00292         const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00293         glBufferData(GL_ARRAY_BUFFER, dataSize, m_Positions.data(), GL_STATIC_DRAW);
00294 }
00295 
00296 QDataStream &operator<<(QDataStream &stream, const GLC_WireData &wireData)
00297 {
00298         quint32 chunckId= GLC_WireData::m_ChunkId;
00299         stream << chunckId;
00300 
00301         stream << wireData.m_NextPrimitiveLocalId;
00302         stream << wireData.positionVector();
00303         stream << wireData.m_PositionSize;
00304 
00305         stream << wireData.m_VerticeGrouprSizes;
00306         stream << wireData.m_VerticeGroupOffset;
00307         stream << wireData.m_VerticeGroupId;
00308         stream << wireData.m_VerticeGroupCount;
00309 
00310         return stream;
00311 }
00312 
00313 QDataStream &operator>>(QDataStream &stream, GLC_WireData &wireData)
00314 {
00315         quint32 chunckId;
00316         stream >> chunckId;
00317         Q_ASSERT(chunckId == GLC_WireData::m_ChunkId);
00318 
00319         wireData.clear();
00320         stream >> wireData.m_NextPrimitiveLocalId;
00321         stream >> wireData.m_Positions;
00322         stream >> wireData.m_PositionSize;
00323 
00324         stream >> wireData.m_VerticeGrouprSizes;
00325         stream >> wireData.m_VerticeGroupOffset;
00326         stream >> wireData.m_VerticeGroupId;
00327         stream >> wireData.m_VerticeGroupCount;
00328 
00329         return stream;
00330 }

SourceForge.net Logo

©2005-2011 Laurent Ribon