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_meshdata.h"
00026 #include "../glc_state.h"
00027
00028
00029 quint32 GLC_MeshData::m_ChunkId= 0xA704;
00030
00031
00032 GLC_MeshData::GLC_MeshData()
00033 : m_VboId(0)
00034 , m_Positions()
00035 , m_Normals()
00036 , m_Texels()
00037 , m_Colors()
00038 , m_NormalVboId(0)
00039 , m_TexelVboId(0)
00040 , m_ColorVboId(0)
00041 , m_LodList()
00042 , m_PositionSize(0)
00043 , m_TexelsSize(0)
00044 , m_ColorSize(0)
00045 {
00046
00047 }
00048
00049
00050 GLC_MeshData::GLC_MeshData(const GLC_MeshData& meshData)
00051 : m_VboId(0)
00052 , m_Positions(meshData.positionVector())
00053 , m_Normals(meshData.normalVector())
00054 , m_Texels(meshData.texelVector())
00055 , m_Colors(meshData.colorVector())
00056 , m_NormalVboId(0)
00057 , m_TexelVboId(0)
00058 , m_ColorVboId(0)
00059 , m_LodList()
00060 , m_PositionSize(meshData.m_PositionSize)
00061 , m_TexelsSize(meshData.m_TexelsSize)
00062 , m_ColorSize(meshData.m_ColorSize)
00063 {
00064
00065 const int size= meshData.m_LodList.size();
00066 for (int i= 0; i < size; ++i)
00067 {
00068 m_LodList.append(new GLC_Lod(*meshData.m_LodList.at(i)));
00069 }
00070 }
00071
00072
00073 GLC_MeshData& GLC_MeshData::operator=(const GLC_MeshData& meshData)
00074 {
00075 if (this != &meshData)
00076 {
00077
00078 clear();
00079
00080
00081 m_Positions= meshData.positionVector();
00082 m_Normals= meshData.normalVector();
00083 m_Texels= meshData.texelVector();
00084 m_Colors= meshData.colorVector();
00085 m_PositionSize= meshData.m_PositionSize;
00086 m_TexelsSize= meshData.m_TexelsSize;
00087 m_ColorSize= meshData.m_ColorSize;
00088
00089
00090 const int size= meshData.m_LodList.size();
00091 for (int i= 0; i < size; ++i)
00092 {
00093 m_LodList.append(new GLC_Lod(*meshData.m_LodList.at(i)));
00094 }
00095 }
00096 return *this;
00097 }
00098
00099 GLC_MeshData::~GLC_MeshData()
00100 {
00101 clear();
00102 }
00104
00106
00107 quint32 GLC_MeshData::chunckID()
00108 {
00109 return m_ChunkId;
00110 }
00111
00112
00113 GLfloatVector GLC_MeshData::positionVector() const
00114 {
00115 if (0 != m_VboId)
00116 {
00117
00118 const int sizeOfVbo= m_PositionSize;
00119 const GLsizeiptr dataSize= sizeOfVbo * sizeof(float);
00120 GLfloatVector positionVector(sizeOfVbo);
00121
00122 glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
00123 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00124 memcpy(positionVector.data(), pVbo, dataSize);
00125 glUnmapBuffer(GL_ARRAY_BUFFER);
00126 glBindBuffer(GL_ARRAY_BUFFER, 0);
00127 return positionVector;
00128 }
00129 else
00130 {
00131 return m_Positions;
00132 }
00133 }
00134
00135
00136 GLfloatVector GLC_MeshData::normalVector() const
00137 {
00138 if (0 != m_NormalVboId)
00139 {
00140
00141 const int sizeOfVbo= m_PositionSize;
00142 const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
00143 GLfloatVector normalVector(sizeOfVbo);
00144
00145 glBindBuffer(GL_ARRAY_BUFFER, m_NormalVboId);
00146 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00147 memcpy(normalVector.data(), pVbo, dataSize);
00148 glUnmapBuffer(GL_ARRAY_BUFFER);
00149 glBindBuffer(GL_ARRAY_BUFFER, 0);
00150 return normalVector;
00151 }
00152 else
00153 {
00154 return m_Normals;
00155 }
00156 }
00157
00158
00159 GLfloatVector GLC_MeshData::texelVector() const
00160 {
00161 if (0 != m_TexelVboId)
00162 {
00163
00164 const int sizeOfVbo= m_TexelsSize;
00165 const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
00166 GLfloatVector texelVector(sizeOfVbo);
00167
00168 glBindBuffer(GL_ARRAY_BUFFER, m_TexelVboId);
00169 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00170 memcpy(texelVector.data(), pVbo, dataSize);
00171 glUnmapBuffer(GL_ARRAY_BUFFER);
00172 glBindBuffer(GL_ARRAY_BUFFER, 0);
00173 return texelVector;
00174 }
00175 else
00176 {
00177 return m_Texels;
00178 }
00179 }
00180
00181
00182 GLfloatVector GLC_MeshData::colorVector() const
00183 {
00184 if (0 != m_ColorVboId)
00185 {
00186
00187 const int sizeOfVbo= m_ColorSize;
00188 const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
00189 GLfloatVector normalVector(sizeOfVbo);
00190
00191 glBindBuffer(GL_ARRAY_BUFFER, m_ColorVboId);
00192 GLvoid* pVbo = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
00193 memcpy(normalVector.data(), pVbo, dataSize);
00194 glUnmapBuffer(GL_ARRAY_BUFFER);
00195 glBindBuffer(GL_ARRAY_BUFFER, 0);
00196 return normalVector;
00197 }
00198 else
00199 {
00200 return m_Colors;
00201 }
00202 }
00203
00205
00207
00208
00209 void GLC_MeshData::finishVbo()
00210 {
00211 m_PositionSize= m_Positions.size();
00212 m_Positions.clear();
00213 m_Normals.clear();
00214 m_TexelsSize= m_Texels.size();
00215 m_Texels.clear();
00216 m_ColorSize= m_Colors.size();
00217 m_Colors.clear();
00218
00219
00220 const int size= m_LodList.size();
00221 for (int i= 0; i < size; ++i)
00222 {
00223 m_LodList[i]->finishVbo();
00224 }
00225 }
00226
00227
00228 void GLC_MeshData::finishLod()
00229 {
00230
00231 const int size= m_LodList.size();
00232 if (size > 1)
00233 {
00234 GLC_Lod* PMasterLod= m_LodList.at(size - 1);
00235 m_LodList.removeAt(size - 1);
00236 m_LodList.prepend(PMasterLod);
00237 }
00238 }
00239
00240
00241 void GLC_MeshData::clear()
00242 {
00243 m_Positions.clear();
00244 m_Normals.clear();
00245 m_Texels.clear();
00246 m_Colors.clear();
00247 m_PositionSize= 0;
00248 m_TexelsSize= 0;
00249 m_ColorSize= 0;
00250
00251
00252 if (0 != m_VboId)
00253 {
00254 glDeleteBuffers(1, &m_VboId);
00255 m_VboId= 0;
00256 }
00257
00258
00259 if (0 != m_NormalVboId)
00260 {
00261 glDeleteBuffers(1, &m_NormalVboId);
00262 m_NormalVboId= 0;
00263 }
00264
00265
00266 if (0 != m_TexelVboId)
00267 {
00268 glDeleteBuffers(1, &m_TexelVboId);
00269 m_TexelVboId= 0;
00270 }
00271
00272 if (0 != m_ColorVboId)
00273 {
00274 glDeleteBuffers(1, &m_ColorVboId);
00275 m_ColorVboId= 0;
00276 }
00277
00278 const int size= m_LodList.size();
00279 for (int i= 0; i < size; ++i)
00280 {
00281 delete m_LodList.at(i);
00282 }
00283 m_LodList.clear();
00284 }
00285
00286 void GLC_MeshData::copyVboToClientSide()
00287 {
00288
00289 if ((0 != m_VboId) && m_Positions.isEmpty())
00290 {
00291 Q_ASSERT(0 != m_NormalVboId);
00292 m_Positions= positionVector();
00293 m_Normals= normalVector();
00294 if (0 != m_TexelVboId)
00295 {
00296 m_Texels= texelVector();
00297 }
00298 if (0 != m_ColorVboId)
00299 {
00300 m_Colors= colorVector();
00301 }
00302 }
00303 }
00304
00305 void GLC_MeshData::releaseVboClientSide(bool update)
00306 {
00307 if ((0 != m_VboId) && !m_Positions.isEmpty())
00308 {
00309 if (update)
00310 {
00311 fillVbo(GLC_MeshData::GLC_Vertex);
00312 fillVbo(GLC_MeshData::GLC_Normal);
00313 fillVbo(GLC_MeshData::GLC_Texel);
00314 fillVbo(GLC_MeshData::GLC_Color);
00315 useVBO(false, GLC_MeshData::GLC_Color);
00316 }
00317 m_PositionSize= m_Positions.size();
00318 m_Positions.clear();
00319 m_Normals.clear();
00320 m_TexelsSize= m_Texels.size();
00321 m_Texels.clear();
00322 m_ColorSize= m_Colors.size();
00323 m_Colors.clear();
00324 }
00325 }
00326
00328
00330
00331 void GLC_MeshData::createVBOs()
00332 {
00333
00334 if (0 == m_VboId)
00335 {
00336 glGenBuffers(1, &m_VboId);
00337 glGenBuffers(1, &m_NormalVboId);
00338
00339
00340 if (0 == m_TexelVboId && !m_Texels.isEmpty())
00341 {
00342 glGenBuffers(1, &m_TexelVboId);
00343 }
00344
00345
00346 if (0 == m_ColorVboId && !m_Colors.isEmpty())
00347 {
00348 glGenBuffers(1, &m_ColorVboId);
00349 }
00350
00351 const int size= m_LodList.size();
00352 for (int i= 0; i < size; ++i)
00353 {
00354 m_LodList.at(i)->createIBO();
00355 }
00356 }
00357 }
00358
00359
00360 bool GLC_MeshData::useVBO(bool use, GLC_MeshData::VboType type) const
00361 {
00362 bool result= true;
00363 if (use)
00364 {
00365
00366 if (type == GLC_MeshData::GLC_Vertex)
00367 {
00368 glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
00369 }
00370 else if (type == GLC_MeshData::GLC_Normal)
00371 {
00372 glBindBuffer(GL_ARRAY_BUFFER, m_NormalVboId);
00373 }
00374 else if ((type == GLC_MeshData::GLC_Texel) && (0 != m_TexelVboId))
00375 {
00376 glBindBuffer(GL_ARRAY_BUFFER, m_TexelVboId);
00377 }
00378 else if ((type == GLC_MeshData::GLC_Color) && (0 != m_ColorVboId))
00379 {
00380 glBindBuffer(GL_ARRAY_BUFFER, m_ColorVboId);
00381 }
00382
00383 else result= false;
00384 }
00385 else
00386 {
00387
00388 glBindBuffer(GL_ARRAY_BUFFER, 0);
00389 }
00390 return result;
00391 }
00392
00393 void GLC_MeshData::fillVbo(GLC_MeshData::VboType type)
00394 {
00395
00396 if (type == GLC_MeshData::GLC_Vertex)
00397 {
00398 useVBO(true, type);
00399 const GLsizei dataNbr= static_cast<GLsizei>(m_Positions.size());
00400 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00401 glBufferData(GL_ARRAY_BUFFER, dataSize, m_Positions.data(), GL_STATIC_DRAW);
00402 }
00403 else if (type == GLC_MeshData::GLC_Normal)
00404 {
00405 useVBO(true, type);
00406 const GLsizei dataNbr= static_cast<GLsizei>(m_Normals.size());
00407 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00408 glBufferData(GL_ARRAY_BUFFER, dataSize, m_Normals.data(), GL_STATIC_DRAW);
00409 }
00410 else if ((type == GLC_MeshData::GLC_Texel) && (0 != m_TexelVboId))
00411 {
00412 useVBO(true, type);
00413 const GLsizei dataNbr= static_cast<GLsizei>(m_Texels.size());
00414 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00415 glBufferData(GL_ARRAY_BUFFER, dataSize, m_Texels.data(), GL_STATIC_DRAW);
00416 }
00417 else if ((type == GLC_MeshData::GLC_Color) && (0 != m_ColorVboId))
00418 {
00419 useVBO(true, type);
00420 const GLsizei dataNbr= static_cast<GLsizei>(m_Colors.size());
00421 const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
00422 glBufferData(GL_ARRAY_BUFFER, dataSize, m_Colors.data(), GL_STATIC_DRAW);
00423 }
00424 }
00425
00426
00427 QDataStream &operator<<(QDataStream &stream, const GLC_MeshData &meshData)
00428 {
00429 quint32 chunckId= GLC_MeshData::m_ChunkId;
00430 stream << chunckId;
00431
00432 stream << meshData.positionVector();
00433 stream << meshData.normalVector();
00434 stream << meshData.texelVector();
00435 stream << meshData.colorVector();
00436
00437
00438 const int lodCount= meshData.m_LodList.size();
00439 QList<GLC_Lod> lodsList;
00440 for (int i= 0; i < lodCount; ++i)
00441 {
00442 lodsList.append(*(meshData.m_LodList[i]));
00443 }
00444 stream << lodsList;
00445
00446 return stream;
00447 }
00448
00449 QDataStream &operator>>(QDataStream &stream, GLC_MeshData &meshData)
00450 {
00451 quint32 chunckId;
00452 stream >> chunckId;
00453 Q_ASSERT(chunckId == GLC_MeshData::m_ChunkId);
00454
00455 meshData.clear();
00456
00457 GLfloatVector position, normal, texel, color;
00458
00459 stream >> meshData.m_Positions;
00460 stream >> meshData.m_Normals;
00461 stream >> meshData.m_Texels;
00462 stream >> meshData.m_Colors;
00463
00464
00465 QList<GLC_Lod> lodsList;
00466 stream >> lodsList;
00467 const int lodCount= lodsList.size();
00468 for (int i= 0; i < lodCount; ++i)
00469 {
00470 meshData.m_LodList.append(new GLC_Lod(lodsList.at(i)));
00471 }
00472
00473 return stream;
00474 }
00475