glc_wiredata.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00026
00027 #include "glc_wiredata.h"
00028 #include "../glc_ext.h"
00029 #include "../glc_state.h"
00030
00031
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
00093 if (0 != m_VboId)
00094 {
00095 glDeleteBuffers(1, &m_VboId);
00096 m_VboId= 0;
00097 }
00098 }
00100
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
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
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
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
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
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
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
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
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
00258 if (vboIsUsed)
00259 {
00260 useVBO(false);
00261 }
00262
00263 glDisableClientState(GL_VERTEX_ARRAY);
00264 }
00265
00266 void GLC_WireData::createVBOs()
00267 {
00268
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 }