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

SourceForge.net Logo

©2005 Laurent Ribon