GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_meshdata.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 
3  This file is part of the GLC-lib library.
4  Copyright (C) 2005-2008 Laurent Ribon (laumaya@users.sourceforge.net)
5  http://glc-lib.sourceforge.net
6 
7  GLC-lib is free software; you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  GLC-lib is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with GLC-lib; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21 *****************************************************************************/
22 
24 
25 #include "../glc_exception.h"
26 #include "glc_meshdata.h"
27 #include "../glc_state.h"
28 
29 // Class chunk id
30 quint32 GLC_MeshData::m_ChunkId= 0xA704;
31 
32 // Default constructor
34 : m_VertexBuffer()
35 , m_Positions()
36 , m_Normals()
37 , m_Texels()
38 , m_Colors()
39 , m_NormalBuffer()
40 , m_TexelBuffer()
41 , m_ColorBuffer()
42 , m_LodList()
43 , m_PositionSize(-1)
44 , m_TexelsSize(-1)
45 , m_ColorSize(-1)
46 , m_UseVbo(false)
47 {
48 
49 }
50 
51 // Copy constructor
53 : m_VertexBuffer()
54 , m_Positions(meshData.positionVector())
55 , m_Normals(meshData.normalVector())
56 , m_Texels(meshData.texelVector())
57 , m_Colors(meshData.colorVector())
58 , m_NormalBuffer()
59 , m_TexelBuffer()
60 , m_ColorBuffer()
61 , m_LodList()
62 , m_PositionSize(meshData.m_PositionSize)
63 , m_TexelsSize(meshData.m_TexelsSize)
64 , m_ColorSize(meshData.m_ColorSize)
65 , m_UseVbo(meshData.m_UseVbo)
66 {
67  // Copy meshData LOD list
68  const int size= meshData.m_LodList.size();
69  for (int i= 0; i < size; ++i)
70  {
71  m_LodList.append(new GLC_Lod(*meshData.m_LodList.at(i)));
72  }
73 }
74 
75 // Overload "=" operator
77 {
78  if (this != &meshData)
79  {
80  // Clear the content of the mesh Data
81  clear();
82 
83  // Copy mesh Data members
84  m_Positions= meshData.positionVector();
85  m_Normals= meshData.normalVector();
86  m_Texels= meshData.texelVector();
87  m_Colors= meshData.colorVector();
89  m_TexelsSize= meshData.m_TexelsSize;
90  m_ColorSize= meshData.m_ColorSize;
91  m_UseVbo= meshData.m_UseVbo;
92 
93  // Copy meshData LOD list
94  const int size= meshData.m_LodList.size();
95  for (int i= 0; i < size; ++i)
96  {
97  m_LodList.append(new GLC_Lod(*meshData.m_LodList.at(i)));
98  }
99  }
100  return *this;
101 }
102 
104 {
105  clear();
106 }
108 // Get Functions
110 // Return the class Chunk ID
112 {
113  return m_ChunkId;
114 }
115 
116 // Return the Position Vector
118 {
119  if (m_VertexBuffer.isCreated())
120  {
121  // VBO created get data from VBO
122  const int sizeOfVbo= m_PositionSize;
123  const GLsizeiptr dataSize= sizeOfVbo * sizeof(float);
124  GLfloatVector positionVector(sizeOfVbo);
125 
126  if (!const_cast<QGLBuffer&>(m_VertexBuffer).bind())
127  {
128  GLC_Exception exception("GLC_MeshData::positionVector() Failed to bind vertex buffer");
129  throw(exception);
130  }
131  GLvoid* pVbo = const_cast<QGLBuffer&>(m_VertexBuffer).map(QGLBuffer::ReadOnly);
132  memcpy(positionVector.data(), pVbo, dataSize);
133  const_cast<QGLBuffer&>(m_VertexBuffer).unmap();
134  const_cast<QGLBuffer&>(m_VertexBuffer).release();
135  return positionVector;
136  }
137  else
138  {
139  return m_Positions;
140  }
141 }
142 
143 // Return the normal Vector
145 {
146  if (m_NormalBuffer.isCreated())
147  {
148  // VBO created get data from VBO
149  const int sizeOfVbo= m_PositionSize;
150  const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
151  GLfloatVector normalVector(sizeOfVbo);
152 
153  const_cast<QGLBuffer&>(m_NormalBuffer).bind();
154  GLvoid* pVbo = const_cast<QGLBuffer&>(m_NormalBuffer).map(QGLBuffer::ReadOnly);
155  memcpy(normalVector.data(), pVbo, dataSize);
156  const_cast<QGLBuffer&>(m_NormalBuffer).unmap();
157  const_cast<QGLBuffer&>(m_NormalBuffer).release();
158  return normalVector;
159  }
160  else
161  {
162  return m_Normals;
163  }
164 }
165 
166 // Return the texel Vector
168 {
169  if (m_TexelBuffer.isCreated())
170  {
171  // VBO created get data from VBO
172  const int sizeOfVbo= m_TexelsSize;
173  const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
174  GLfloatVector texelVector(sizeOfVbo);
175 
176  const_cast<QGLBuffer&>(m_TexelBuffer).bind();
177  GLvoid* pVbo = const_cast<QGLBuffer&>(m_TexelBuffer).map(QGLBuffer::ReadOnly);
178  memcpy(texelVector.data(), pVbo, dataSize);
179  const_cast<QGLBuffer&>(m_TexelBuffer).unmap();
180  const_cast<QGLBuffer&>(m_TexelBuffer).release();
181  return texelVector;
182  }
183  else
184  {
185  return m_Texels;
186  }
187 }
188 
189 // Return the color Vector
191 {
192  if (m_ColorBuffer.isCreated())
193  {
194  // VBO created get data from VBO
195  const int sizeOfVbo= m_ColorSize;
196  const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
197  GLfloatVector normalVector(sizeOfVbo);
198 
199  const_cast<QGLBuffer&>(m_ColorBuffer).bind();
200  GLvoid* pVbo = const_cast<QGLBuffer&>(m_ColorBuffer).map(QGLBuffer::ReadOnly);
201  memcpy(normalVector.data(), pVbo, dataSize);
202  const_cast<QGLBuffer&>(m_ColorBuffer).unmap();
203  const_cast<QGLBuffer&>(m_ColorBuffer).release();
204  return normalVector;
205  }
206  else
207  {
208  return m_Colors;
209  }
210 }
211 
213 // Set Functions
215 
216 // If the there is more than 2 LOD Swap the first and last
218 {
219  // PLace the master LOD at the beginning of the list
220  const int size= m_LodList.size();
221  if (size > 1)
222  {
223  GLC_Lod* PMasterLod= m_LodList.at(size - 1);
224  m_LodList.removeAt(size - 1);
225  m_LodList.prepend(PMasterLod);
226  }
227 }
228 
229 // Clear the content of the meshData and makes it empty
231 {
232  m_Positions.clear();
233  m_Normals.clear();
234  m_Texels.clear();
235  m_Colors.clear();
236  m_PositionSize= -1;
237  m_TexelsSize= -1;
238  m_ColorSize= -1;
239 
240  // Delete Main Vbo ID
241  if (m_VertexBuffer.isCreated())
242  {
243  m_VertexBuffer.destroy();
244  }
245 
246  // Delete Normal VBO
247  if (m_NormalBuffer.isCreated())
248  {
249  m_NormalBuffer.destroy();
250  }
251 
252  // Delete Texel VBO
253  if (m_TexelBuffer.isCreated())
254  {
255  m_TexelBuffer.destroy();
256  }
257  // Delete color index
258  if (m_ColorBuffer.isCreated())
259  {
260  m_ColorBuffer.destroy();
261  }
262 
263  const int size= m_LodList.size();
264  for (int i= 0; i < size; ++i)
265  {
266  delete m_LodList.at(i);
267  }
268  m_LodList.clear();
269 }
270 
272 {
273 
274  if (m_VertexBuffer.isCreated() && m_Positions.isEmpty())
275  {
276  Q_ASSERT(m_NormalBuffer.isCreated());
279  if (m_TexelBuffer.isCreated())
280  {
282  }
283  if (m_ColorBuffer.isCreated())
284  {
286  }
287  }
288 }
289 
291 {
292  if (m_VertexBuffer.isCreated() && !m_Positions.isEmpty())
293  {
294  if (update)
295  {
301  }
302  m_PositionSize= m_Positions.size();
303  m_Positions.clear();
304  m_Normals.clear();
305  m_TexelsSize= m_Texels.size();
306  m_Texels.clear();
307  m_ColorSize= m_Colors.size();
308  m_Colors.clear();
309  }
310 }
311 
313 {
314  if (usage && (m_PositionSize != -1) && (!m_Positions.isEmpty()) && (!m_VertexBuffer.isCreated()))
315  {
316  createVBOs();
317 
323 
324  const int lodCount= m_LodList.count();
325  for (int i= 0; i < lodCount; ++i)
326  {
327  m_LodList.at(i)->setIboUsage(usage);
328  }
329 
330  }
331  else if (!usage && m_VertexBuffer.isCreated())
332  {
334  m_PositionSize= m_Positions.size();
335  m_VertexBuffer.destroy();
336 
338  m_NormalBuffer.destroy();
339 
340  if (m_TexelBuffer.isCreated())
341  {
343  m_TexelsSize= m_Texels.size();
344  m_TexelBuffer.destroy();
345  }
346  if (m_ColorBuffer.isCreated())
347  {
349  m_ColorSize= m_Colors.size();
350  m_ColorBuffer.destroy();
351  }
352 
353  const int lodCount= m_LodList.count();
354  for (int i= 0; i < lodCount; ++i)
355  {
356  m_LodList.at(i)->setIboUsage(usage);
357  }
358  }
359  m_UseVbo= usage;
360 
361 }
362 
364 // OpenGL Functions
366 // Vbo creation
368 {
369 
370  // Create position VBO
371  if (!m_VertexBuffer.isCreated())
372  {
373  Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid());
374 
375  m_VertexBuffer.create();
376  m_NormalBuffer.create();
377 
378  // Create Texel VBO
379  if (!m_TexelBuffer.isCreated() && !m_Texels.isEmpty())
380  {
381  m_TexelBuffer.create();
382  }
383 
384  // Create Color VBO
385  if (!m_ColorBuffer.isCreated() && !m_Colors.isEmpty())
386  {
387  m_ColorBuffer.create();
388  }
389 
390  const int size= m_LodList.size();
391  for (int i= 0; i < size; ++i)
392  {
393  m_LodList.at(i)->createIBO();
394  }
395  }
396 }
397 
398 // Ibo Usage
400 {
401  bool result= true;
402  if (use)
403  {
404  // Chose the right VBO
405  if (type == GLC_MeshData::GLC_Vertex)
406  {
407  if (!m_VertexBuffer.bind())
408  {
409  GLC_Exception exception("GLC_MeshData::useVBO Failed to bind vertex buffer");
410  throw(exception);
411  }
412  }
413  else if (type == GLC_MeshData::GLC_Normal)
414  {
415  if (!m_NormalBuffer.bind())
416  {
417  GLC_Exception exception("GLC_MeshData::useVBO Failed to bind normal buffer");
418  throw(exception);
419  }
420  }
421  else if ((type == GLC_MeshData::GLC_Texel) && m_TexelBuffer.isCreated())
422  {
423  if (!m_TexelBuffer.bind())
424  {
425  GLC_Exception exception("GLC_MeshData::useVBO Failed to bind texel buffer");
426  throw(exception);
427  }
428  }
429  else if ((type == GLC_MeshData::GLC_Color) && m_ColorBuffer.isCreated())
430  {
431  if (!m_ColorBuffer.bind())
432  {
433  GLC_Exception exception("GLC_MeshData::useVBO Failed to bind color buffer");
434  throw(exception);
435  }
436  }
437 
438  else result= false;
439  }
440  else
441  {
442  // Unbind VBO
443  QGLBuffer::release(QGLBuffer::VertexBuffer);
444  }
445  return result;
446 }
447 
449 {
450  // Chose the right VBO
451  if (type == GLC_MeshData::GLC_Vertex)
452  {
453  useVBO(true, type);
454  const GLsizei dataNbr= static_cast<GLsizei>(m_Positions.size());
455  const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
456  m_VertexBuffer.allocate(m_Positions.data(), dataSize);
457 
458  m_PositionSize= m_Positions.size();
459  m_Positions.clear();
460  }
461  else if (type == GLC_MeshData::GLC_Normal)
462  {
463  useVBO(true, type);
464  const GLsizei dataNbr= static_cast<GLsizei>(m_Normals.size());
465  const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
466  m_NormalBuffer.allocate(m_Normals.data(), dataSize);
467 
468  m_Normals.clear();
469  }
470  else if ((type == GLC_MeshData::GLC_Texel) && m_TexelBuffer.isCreated())
471  {
472  useVBO(true, type);
473  const GLsizei dataNbr= static_cast<GLsizei>(m_Texels.size());
474  const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
475  m_TexelBuffer.allocate(m_Texels.data(), dataSize);
476 
477  m_TexelsSize= m_Texels.size();
478  m_Texels.clear();
479  }
480  else if ((type == GLC_MeshData::GLC_Color) && m_ColorBuffer.isCreated())
481  {
482  useVBO(true, type);
483  const GLsizei dataNbr= static_cast<GLsizei>(m_Colors.size());
484  const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
485  m_ColorBuffer.allocate(m_Colors.data(), dataSize);
486 
487  m_ColorSize= m_Colors.size();
488  m_Colors.clear();
489  }
490 }
491 
493 {
494  const int lodCount= m_LodList.count();
495  for (int i= 0; i < lodCount; ++i)
496  {
497  m_LodList.at(i)->fillIbo();
498  }
499 }
500 // Non Member methods
501 // Non-member stream operator
502 QDataStream &operator<<(QDataStream &stream, const GLC_MeshData &meshData)
503 {
504  quint32 chunckId= GLC_MeshData::m_ChunkId;
505  stream << chunckId;
506 
507  stream << meshData.positionVector();
508  stream << meshData.normalVector();
509  stream << meshData.texelVector();
510  stream << meshData.colorVector();
511 
512  // List of lod serialisation
513  const int lodCount= meshData.m_LodList.size();
514  QList<GLC_Lod> lodsList;
515  for (int i= 0; i < lodCount; ++i)
516  {
517  lodsList.append(*(meshData.m_LodList[i]));
518  }
519  stream << lodsList;
520 
521  return stream;
522 }
523 
524 QDataStream &operator>>(QDataStream &stream, GLC_MeshData &meshData)
525 {
526  quint32 chunckId;
527  stream >> chunckId;
528  Q_ASSERT(chunckId == GLC_MeshData::m_ChunkId);
529 
530  meshData.clear();
531 
532  GLfloatVector position, normal, texel, color;
533 
534  stream >> meshData.m_Positions;
535  stream >> meshData.m_Normals;
536  stream >> meshData.m_Texels;
537  stream >> meshData.m_Colors;
538 
539  // List of lod serialisation
540  QList<GLC_Lod> lodsList;
541  stream >> lodsList;
542  const int lodCount= lodsList.size();
543  for (int i= 0; i < lodCount; ++i)
544  {
545  meshData.m_LodList.append(new GLC_Lod(lodsList.at(i)));
546  }
547 
548  return stream;
549 }
550 

©2005-2013 Laurent Ribon