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
00024
00025 #include "glc_wiredata.h"
00026 #include "../glc_ext.h"
00027 #include "../glc_state.h"
00028
00029
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
00091 if (0 != m_VboId)
00092 {
00093 glDeleteBuffers(1, &m_VboId);
00094 m_VboId= 0;
00095 }
00096 }
00098
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
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
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
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
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
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
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
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
00266 for (int i= 0; i < m_VerticeGroupCount; ++i)
00267 {
00268 glDrawArrays(mode, m_VerticeGroupOffset.at(i), m_VerticeGrouprSizes.at(i));
00269 }
00270
00271
00272 if (vboIsUsed)
00273 {
00274 useVBO(false);
00275 }
00276
00277 glDisableClientState(GL_VERTEX_ARRAY);
00278 }
00279
00280 void GLC_WireData::createVBOs()
00281 {
00282
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 }