GLC_lib  2.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
glc_wiredata.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_wiredata.h"
26 #include "glc_bsrep.h"
27 #include "../glc_ext.h"
28 #include "../glc_state.h"
29 #include "../glc_exception.h"
30 
31 // Class chunk id
32 // Old chunkId = 0xA706
33 quint32 GLC_WireData::m_ChunkId= 0xA711;
34 
35 
37 : m_VerticeBuffer()
38 , m_NextPrimitiveLocalId(1)
39 , m_Positions()
40 , m_ColorBuffer()
41 , m_Colors()
42 , m_IndexBuffer(QGLBuffer::IndexBuffer)
43 , m_IndexVector()
44 , m_PositionSize(0)
45 , m_ColorSize(0)
46 , m_pBoundingBox(NULL)
47 , m_VerticeGrouprSizes()
48 , m_VerticeGroupOffseti()
49 , m_VerticeGroupOffset()
50 , m_VerticeGroupId()
51 , m_VerticeGroupCount(0)
52 , m_UseVbo(false)
53 {
54 
55 }
56 
57 
59 : m_VerticeBuffer()
60 , m_NextPrimitiveLocalId(data.m_NextPrimitiveLocalId)
61 , m_Positions(data.positionVector())
62 , m_ColorBuffer()
63 , m_Colors(data.colorVector())
64 , m_IndexBuffer(QGLBuffer::IndexBuffer)
65 , m_IndexVector(data.indexVector())
66 , m_PositionSize(data.m_PositionSize)
67 , m_ColorSize(data.m_ColorSize)
68 , m_pBoundingBox(NULL)
69 , m_VerticeGrouprSizes(data.m_VerticeGrouprSizes)
70 , m_VerticeGroupOffseti(data.m_VerticeGroupOffseti)
71 , m_VerticeGroupOffset(data.m_VerticeGroupOffset)
72 , m_VerticeGroupId(data.m_VerticeGroupId)
73 , m_VerticeGroupCount(data.m_VerticeGroupCount)
74 , m_UseVbo(data.m_UseVbo)
75 {
76  if (NULL != data.m_pBoundingBox)
77  {
79  }
80 }
81 
82 
84 {
85  if (this != &data)
86  {
87  clear();
90  m_Colors= data.colorVector();
91  m_IndexVector= data.indexVector();
94  if (NULL != data.m_pBoundingBox)
95  {
97  }
103  m_UseVbo= data.m_UseVbo;
104  }
105  return *this;
106 }
107 
109 {
110  clear();
111 }
113 // Get Functions
115 
116 
118 {
119  return m_ChunkId;
120 }
121 
122 
124 {
125  if (m_VerticeBuffer.isCreated())
126  {
127  Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid());
128  // VBO created get data from VBO
129  const int sizeOfVbo= m_PositionSize;
130  const GLsizeiptr dataSize= sizeOfVbo * sizeof(float);
131  GLfloatVector positionVector(sizeOfVbo);
132 
133  const_cast<QGLBuffer&>(m_VerticeBuffer).bind();
134  GLvoid* pVbo = const_cast<QGLBuffer&>(m_VerticeBuffer).map(QGLBuffer::ReadOnly);
135  memcpy(positionVector.data(), pVbo, dataSize);
136  const_cast<QGLBuffer&>(m_VerticeBuffer).unmap();
137  const_cast<QGLBuffer&>(m_VerticeBuffer).release();
138  return positionVector;
139  }
140  else
141  {
142  return m_Positions;
143  }
144 }
145 
146 // Return the color Vector
148 {
149  if (m_ColorBuffer.isCreated())
150  {
151  // VBO created get data from VBO
152  const int sizeOfVbo= m_ColorSize;
153  const GLsizeiptr dataSize= sizeOfVbo * sizeof(GLfloat);
154  GLfloatVector normalVector(sizeOfVbo);
155 
156  const_cast<QGLBuffer&>(m_ColorBuffer).bind();
157  GLvoid* pVbo = const_cast<QGLBuffer&>(m_ColorBuffer).map(QGLBuffer::ReadOnly);
158  memcpy(normalVector.data(), pVbo, dataSize);
159  const_cast<QGLBuffer&>(m_ColorBuffer).unmap();
160  const_cast<QGLBuffer&>(m_ColorBuffer).release();
161  return normalVector;
162  }
163  else
164  {
165  return m_Colors;
166  }
167 }
168 
169 QVector<GLuint> GLC_WireData::indexVector() const
170 {
171  if (m_IndexBuffer.isCreated())
172  {
173  // VBO created get data from VBO
174  const int sizeOfIbo= m_PositionSize / 3;
175  const GLsizeiptr dataSize= sizeOfIbo * sizeof(GLuint);
176  QVector<GLuint> indexVector(sizeOfIbo);
177 
178  const_cast<QGLBuffer&>(m_IndexBuffer).bind();
179  GLvoid* pIbo = const_cast<QGLBuffer&>(m_IndexBuffer).map(QGLBuffer::ReadOnly);
180  memcpy(indexVector.data(), pIbo, dataSize);
181  const_cast<QGLBuffer&>(m_IndexBuffer).unmap();
182  const_cast<QGLBuffer&>(m_IndexBuffer).release();
183  return indexVector;
184  }
185  else
186  {
187  return m_IndexVector;
188  }
189 }
190 
191 
193 {
194  if (NULL == m_pBoundingBox)
195  {
197 
198  if (m_Positions.isEmpty())
199  {
200  //qDebug() << "GLC_WireData::getBoundingBox empty m_Positions";
201  }
202  else
203  {
204  const int max= m_Positions.size();
205  if (max == 3) // Only One point
206  {
207  const double delta= 1e-2;
208  GLC_Point3d lower(m_Positions[0] - delta,
209  m_Positions[1] - delta,
210  m_Positions[2] - delta);
211  GLC_Point3d upper(m_Positions[0] + delta,
212  m_Positions[1] + delta,
213  m_Positions[2] + delta);
214  m_pBoundingBox->combine(lower);
215  m_pBoundingBox->combine(upper);
216 
217  }
218  else
219  {
220  for (int i= 0; i < max; i= i + 3)
221  {
222  GLC_Point3d point(m_Positions[i], m_Positions[i + 1], m_Positions[i + 2]);
223  m_pBoundingBox->combine(point);
224  }
225  }
226  }
227 
228  }
229  return *m_pBoundingBox;
230 }
231 
233 // Set Functions
235 
236 
238 {
239  Q_ASSERT((floatVector.size() % 3) == 0);
240 
242  m_Positions+= floatVector;
243 
244  m_VerticeGrouprSizes.append(static_cast<GLsizei>(floatVector.size() / 3));
245 
246  if (m_VerticeGroupOffseti.isEmpty())
247  {
248  m_VerticeGroupOffseti.append(0);
249  }
250  int offset= m_VerticeGroupOffseti.last() + m_VerticeGrouprSizes.last();
251  m_VerticeGroupOffseti.append(offset);
252 
253  // The Polyline id
255  return m_NextPrimitiveLocalId++;
256 }
257 
259 {
260  m_VerticeBuffer.destroy();
262  m_Positions.clear();
263  m_PositionSize= 0;
264  delete m_pBoundingBox;
265  m_pBoundingBox= NULL;
266 
267  m_VerticeGrouprSizes.clear();
268  m_VerticeGroupOffseti.clear();
269  m_VerticeGroupId.clear();
271 }
272 
274 {
275  if (m_VerticeBuffer.isCreated() && m_Positions.isEmpty())
276  {
278 
279  if (m_ColorBuffer.isCreated() && m_Colors.isEmpty())
280  {
282  }
284  }
285 
286 }
287 
289 {
290  if (m_VerticeBuffer.isCreated() && !m_Positions.isEmpty())
291  {
292  if (update) finishVbo();
293  }
294 }
295 
297 {
298  m_UseVbo= usage;
299  if (!isEmpty())
300  {
301  if (m_UseVbo && (m_PositionSize != 0) && (!m_Positions.isEmpty())&& (!m_VerticeBuffer.isCreated()))
302  {
303  finishVbo();
304  }
305  else if (!m_UseVbo && m_VerticeBuffer.isCreated())
306  {
308  m_VerticeBuffer.destroy();
310  m_ColorBuffer.destroy();
312  m_IndexBuffer.destroy();
313  }
314  }
315 }
316 
318 // OpenGL Functions
320 
322 {
323  Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid());
324  if (!m_VerticeBuffer.isCreated())
325  {
326  m_VerticeBuffer.create();
327  }
328  if ((m_Colors.size() > 0) && !m_ColorBuffer.isCreated())
329  {
330  m_ColorBuffer.create();
331  }
332  if (!m_IndexBuffer.isCreated())
333  {
334  m_IndexBuffer.create();
335  }
336  fillVBOs();
337 
338  m_PositionSize= m_Positions.size();
339  m_Positions.clear();
340 
341  m_IndexVector.clear();
342 
343  if (m_ColorBuffer.isCreated())
344  {
345  m_ColorSize= m_Colors.size();
346  m_Colors.clear();
347  }
348 }
349 
351 {
352  if (use)
353  {
354 
355  // Chose the right VBO
356  if (type == GLC_WireData::GLC_Vertex)
357  {
358  if (!m_VerticeBuffer.bind())
359  {
360  GLC_Exception exception("GLC_WireData::useVBO Failed to bind vertex buffer");
361  throw(exception);
362  }
363  }
364  else if (type == GLC_WireData::GLC_Color)
365  {
366  Q_ASSERT(m_ColorSize > 0);
367  if (!m_ColorBuffer.bind())
368  {
369  GLC_Exception exception("GLC_WireData::useVBO Failed to bind color buffer");
370  throw(exception);
371  }
372  }
373  else if ((type == GLC_WireData::GLC_Index) && m_IndexBuffer.isCreated())
374  {
375  if (!m_IndexBuffer.bind())
376  {
377  GLC_Exception exception("GLC_WireData::useVBO Failed to bind index buffer");
378  throw(exception);
379  }
380  }
381  }
382  else
383  {
384  QGLBuffer::release(QGLBuffer::VertexBuffer);
385  QGLBuffer::release(QGLBuffer::IndexBuffer);
386  }
387 }
388 
390 {
391  Q_ASSERT((NULL != QGLContext::currentContext()) && QGLContext::currentContext()->isValid());
392  Q_ASSERT(!isEmpty());
393 
394  const bool vboIsUsed= m_UseVbo && GLC_State::vboSupported();
395 
396  if (vboIsUsed && ((m_PositionSize == 0) || !m_VerticeBuffer.isCreated()))
397  {
398  finishOffset();
399  buidIndex();
400  finishVbo();
401  }
402  else if (!vboIsUsed && (m_PositionSize == 0))
403  {
404  finishOffset();
405  buidIndex();
406  m_PositionSize= m_Positions.size();
407  m_ColorSize= m_Colors.size();
408  }
409 
410  // Activate VBO or Vertex Array
411  if (vboIsUsed)
412  {
414  glVertexPointer(3, GL_FLOAT, 0, 0);
415  glEnableClientState(GL_VERTEX_ARRAY);
416  if (m_ColorSize > 0)
417  {
418  glColorPointer(4, GL_FLOAT, 0, 0);
419  glEnableClientState(GL_COLOR_ARRAY);
420  }
421 
422  // Render polylines
423  for (int i= 0; i < m_VerticeGroupCount; ++i)
424  {
425  glDrawElements(mode, m_VerticeGrouprSizes.at(i), GL_UNSIGNED_INT, m_VerticeGroupOffset.at(i));
426  }
427 
429  }
430  else
431  {
432  glVertexPointer(3, GL_FLOAT, 0, m_Positions.data());
433  glEnableClientState(GL_VERTEX_ARRAY);
434  if (m_ColorSize > 0)
435  {
436  glColorPointer(4, GL_FLOAT, 0, m_Colors.data());
437  glEnableClientState(GL_COLOR_ARRAY);
438  }
439  // Render polylines
440  for (int i= 0; i < m_VerticeGroupCount; ++i)
441  {
442  glDrawElements(mode, m_VerticeGrouprSizes.at(i), GL_UNSIGNED_INT, &(m_IndexVector.data()[m_VerticeGroupOffseti.at(i)]));
443  }
444 
445  }
446 
447  if (m_ColorSize > 0)
448  {
449  glDisableClientState(GL_COLOR_ARRAY);
450  }
451 
452  glDisableClientState(GL_VERTEX_ARRAY);
453 
454  if (vboIsUsed)
455  {
456  QGLBuffer::release(QGLBuffer::IndexBuffer);
457  QGLBuffer::release(QGLBuffer::VertexBuffer);
458  }
459 }
460 
461 
463 {
464  {
465  Q_ASSERT(m_VerticeBuffer.isCreated());
467  const GLsizei dataNbr= static_cast<GLsizei>(m_Positions.size());
468  const GLsizeiptr dataSize= dataNbr * sizeof(GLfloat);
469  m_VerticeBuffer.allocate(m_Positions.data(), dataSize);
470  }
471 
472  {
473  Q_ASSERT(m_IndexBuffer.isCreated());
475  const GLsizei dataNbr= static_cast<GLsizei>(m_IndexVector.size());
476  const GLsizeiptr dataSize= dataNbr * sizeof(GLuint);
477  m_IndexBuffer.allocate(m_IndexVector.data(), dataSize);
478  }
479 
480  if (m_ColorBuffer.isCreated())
481  {
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 }
488 
490 {
491  const int size= m_Positions.size();
492  m_IndexVector.resize(size);
493  for (int i= 0; i < size; ++i)
494  {
495  m_IndexVector[i]= i;
496  }
497 }
498 
500 {
501  // Activate Vertices VBO
503  glVertexPointer(3, GL_FLOAT, 0, 0);
504  glEnableClientState(GL_VERTEX_ARRAY);
505 
506  // Activate Color VBO if needed
507  if (m_ColorSize > 0)
508  {
510  glEnable(GL_COLOR_MATERIAL);
511  glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
512  glColorPointer(4, GL_FLOAT, 0, 0);
513  glEnableClientState(GL_COLOR_ARRAY);
514  }
515 
516  // Activate index Buffer object
518 }
519 
521 {
522  m_VerticeGroupOffseti.remove(m_VerticeGroupOffseti.size() - 1);
523  m_VerticeGroupOffset.clear();
524  const int offsetSize= m_VerticeGroupOffseti.size();
525  for (int i= 0; i < offsetSize; ++i)
526  {
527  m_VerticeGroupOffset.append(BUFFER_OFFSET(static_cast<GLsizei>(m_VerticeGroupOffseti.at(i)) * sizeof(GLuint)));
528  }
529 }
530 
531 QDataStream &operator<<(QDataStream &stream, const GLC_WireData &wireData)
532 {
533  quint32 chunckId= GLC_WireData::m_ChunkId;
534  stream << chunckId;
535 
536  stream << wireData.m_NextPrimitiveLocalId;
537  stream << wireData.positionVector();
538  stream << wireData.m_PositionSize;
539 
540  stream << wireData.m_VerticeGrouprSizes;
541  stream << wireData.m_VerticeGroupOffseti;
542  stream << wireData.m_VerticeGroupId;
543  stream << wireData.m_VerticeGroupCount;
544 
545  // New version Data
546  stream << wireData.colorVector();
547  stream << wireData.m_ColorSize;
548 
549  return stream;
550 }
551 
552 QDataStream &operator>>(QDataStream &stream, GLC_WireData &wireData)
553 {
554  quint32 chunckId;
555  stream >> chunckId;
556  Q_ASSERT((chunckId == GLC_WireData::m_ChunkId) || chunckId == 0xA706);
557 
558  wireData.clear();
559  stream >> wireData.m_NextPrimitiveLocalId;
560  stream >> wireData.m_Positions;
561  stream >> wireData.m_PositionSize;
562 
563  stream >> wireData.m_VerticeGrouprSizes;
564  stream >> wireData.m_VerticeGroupOffseti;
565  stream >> wireData.m_VerticeGroupId;
566  stream >> wireData.m_VerticeGroupCount;
567 
568  if (chunckId == GLC_WireData::m_ChunkId)
569  {
570  // New version Data
571  stream >> wireData.m_Colors;
572  stream >> wireData.m_ColorSize;
573  }
574 
575  return stream;
576 }

©2005-2013 Laurent Ribon