Qt 4.8
qglbuffer.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtOpenGL module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <QtOpenGL/qgl.h>
43 #include <QtOpenGL/private/qgl_p.h>
44 #include <QtOpenGL/private/qglextensions_p.h>
45 #include <QtCore/qatomic.h>
46 #include "qglbuffer.h"
47 
49 
143 {
144 public:
146  : ref(1),
147  type(t),
148  guard(0),
149  usagePattern(QGLBuffer::StaticDraw),
150  actualUsagePattern(QGLBuffer::StaticDraw)
151  {
152  }
153 
159 };
160 
170  : d_ptr(new QGLBufferPrivate(QGLBuffer::VertexBuffer))
171 {
172 }
173 
183  : d_ptr(new QGLBufferPrivate(type))
184 {
185 }
186 
194  : d_ptr(other.d_ptr)
195 {
196  d_ptr->ref.ref();
197 }
198 
199 #define ctx d->guard.context()
200 
206 {
207  if (!d_ptr->ref.deref()) {
208  destroy();
209  delete d_ptr;
210  }
211 }
212 
220 {
221  if (d_ptr != other.d_ptr) {
222  other.d_ptr->ref.ref();
223  if (!d_ptr->ref.deref()) {
224  destroy();
225  delete d_ptr;
226  }
227  d_ptr = other.d_ptr;
228  }
229  return *this;
230 }
231 
236 {
237  Q_D(const QGLBuffer);
238  return d->type;
239 }
240 
248 {
249  Q_D(const QGLBuffer);
250  return d->usagePattern;
251 }
252 
260 {
261  Q_D(QGLBuffer);
262 #if defined(QT_OPENGL_ES_1)
263  // OpenGL/ES 1.1 does not support GL_STREAM_DRAW, so use GL_STATIC_DRAW.
264  // OpenGL/ES 2.0 does support GL_STREAM_DRAW.
265  d->usagePattern = value;
266  if (value == StreamDraw)
267  d->actualUsagePattern = StaticDraw;
268  else
269  d->actualUsagePattern = value;
270 #else
271  d->usagePattern = d->actualUsagePattern = value;
272 #endif
273 }
274 
275 #undef ctx
276 
291 {
292  Q_D(QGLBuffer);
293  if (d->guard.id())
294  return true;
296  if (ctx) {
297  if (!qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx)))
298  return false;
299  GLuint bufferId = 0;
300  glGenBuffers(1, &bufferId);
301  if (bufferId) {
302  d->guard.setContext(ctx);
303  d->guard.setId(bufferId);
304  return true;
305  }
306  }
307  return false;
308 }
309 
310 #define ctx d->guard.context()
311 
318 {
319  Q_D(const QGLBuffer);
320  return d->guard.id() != 0;
321 }
322 
329 {
330  Q_D(QGLBuffer);
331  GLuint bufferId = d->guard.id();
332  if (bufferId) {
333  // Switch to the original creating context to destroy it.
334  QGLShareContextScope scope(d->guard.context());
335  glDeleteBuffers(1, &bufferId);
336  }
337  d->guard.setId(0);
338  d->guard.setContext(0);
339 }
340 
351 bool QGLBuffer::read(int offset, void *data, int count)
352 {
353 #if !defined(QT_OPENGL_ES)
354  Q_D(QGLBuffer);
355  if (!glGetBufferSubData || !d->guard.id())
356  return false;
357  while (glGetError() != GL_NO_ERROR) ; // Clear error state.
358  glGetBufferSubData(d->type, offset, count, data);
359  return glGetError() == GL_NO_ERROR;
360 #else
361  Q_UNUSED(offset);
362  Q_UNUSED(data);
363  Q_UNUSED(count);
364  return false;
365 #endif
366 }
367 
378 void QGLBuffer::write(int offset, const void *data, int count)
379 {
380 #ifndef QT_NO_DEBUG
381  if (!isCreated())
382  qWarning("QGLBuffer::allocate(): buffer not created");
383 #endif
384  Q_D(QGLBuffer);
385  if (d->guard.id())
386  glBufferSubData(d->type, offset, count, data);
387 }
388 
398 void QGLBuffer::allocate(const void *data, int count)
399 {
400 #ifndef QT_NO_DEBUG
401  if (!isCreated())
402  qWarning("QGLBuffer::allocate(): buffer not created");
403 #endif
404  Q_D(QGLBuffer);
405  if (d->guard.id())
406  glBufferData(d->type, count, data, d->actualUsagePattern);
407 }
408 
437 {
438 #ifndef QT_NO_DEBUG
439  if (!isCreated())
440  qWarning("QGLBuffer::bind(): buffer not created");
441 #endif
442  Q_D(const QGLBuffer);
443  GLuint bufferId = d->guard.id();
444  if (bufferId) {
446  d->guard.context())) {
447 #ifndef QT_NO_DEBUG
448  qWarning("QGLBuffer::bind: buffer is not valid in the current context");
449 #endif
450  return false;
451  }
452  glBindBuffer(d->type, bufferId);
453  return true;
454  } else {
455  return false;
456  }
457 }
458 
469 {
470 #ifndef QT_NO_DEBUG
471  if (!isCreated())
472  qWarning("QGLBuffer::release(): buffer not created");
473 #endif
474  Q_D(const QGLBuffer);
475  if (d->guard.id())
476  glBindBuffer(d->type, 0);
477 }
478 
479 #undef ctx
480 
495 {
497  if (ctx && qt_resolve_buffer_extensions(const_cast<QGLContext *>(ctx)))
498  glBindBuffer(GLenum(type), 0);
499 }
500 
501 #define ctx d->guard.context()
502 
509 GLuint QGLBuffer::bufferId() const
510 {
511  Q_D(const QGLBuffer);
512  return d->guard.id();
513 }
514 
515 #ifndef GL_BUFFER_SIZE
516 #define GL_BUFFER_SIZE 0x8764
517 #endif
518 
528 int QGLBuffer::size() const
529 {
530  Q_D(const QGLBuffer);
531  if (!d->guard.id())
532  return -1;
533  GLint value = -1;
534  glGetBufferParameteriv(d->type, GL_BUFFER_SIZE, &value);
535  return value;
536 }
537 
553 {
554  Q_D(QGLBuffer);
555 #ifndef QT_NO_DEBUG
556  if (!isCreated())
557  qWarning("QGLBuffer::map(): buffer not created");
558 #endif
559  if (!d->guard.id())
560  return 0;
561  if (!glMapBufferARB)
562  return 0;
563 #ifdef QT_OPENGL_ES_2
564  if (access != QGLBuffer::WriteOnly)
565  return 0;
566 #endif
567  return glMapBufferARB(d->type, access);
568 }
569 
584 {
585  Q_D(QGLBuffer);
586 #ifndef QT_NO_DEBUG
587  if (!isCreated())
588  qWarning("QGLBuffer::unmap(): buffer not created");
589 #endif
590  if (!d->guard.id())
591  return false;
592  if (!glUnmapBufferARB)
593  return false;
594  return glUnmapBufferARB(d->type) == GL_TRUE;
595 }
596 
double d
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
#define GL_TRUE
#define glBufferSubData
The QAtomicInt class provides platform-independent atomic operations on integers. ...
Definition: qatomic.h:55
Type
This enum defines the type of GL buffer object to create with QGLBuffer.
Definition: qglbuffer.h:59
bool ref()
Atomically increments the value of this QAtomicInt.
bool read(int offset, void *data, int count)
Reads the count bytes in this buffer starting at offset into data.
Definition: qglbuffer.cpp:351
void setUsagePattern(QGLBuffer::UsagePattern value)
Sets the usage pattern for this buffer object to value.
Definition: qglbuffer.cpp:259
void * map(QGLBuffer::Access access)
Maps the contents of this buffer into the application&#39;s memory space and returns a pointer to it...
Definition: qglbuffer.cpp:552
void write(int offset, const void *data, int count)
Replaces the count bytes of this buffer starting at offset with the contents of data.
Definition: qglbuffer.cpp:378
QGLBuffer::Type type() const
Returns the type of buffer represented by this object.
Definition: qglbuffer.cpp:235
#define Q_D(Class)
Definition: qglobal.h:2482
bool create()
Creates the buffer object in the GL server.
Definition: qglbuffer.cpp:290
void destroy()
Destroys this buffer object, including the storage being used in the GL server.
Definition: qglbuffer.cpp:328
GLuint bufferId() const
Returns the GL identifier associated with this buffer; zero if the buffer has not been created...
Definition: qglbuffer.cpp:509
#define glGetBufferParameteriv
static const QGLContext * currentContext()
Returns the current context, i.e.
Definition: qgl.cpp:3545
bool qt_resolve_buffer_extensions(QGLContext *ctx)
#define ctx
Definition: qglbuffer.cpp:501
static bool areSharing(const QGLContext *context1, const QGLContext *context2)
Returns true if context1 and context2 are sharing their GL resources such as textures, shader programs, etc; otherwise returns false.
Definition: qgl.cpp:3319
bool unmap()
Unmaps the buffer after it was mapped into the application&#39;s memory space with a previous call to map...
Definition: qglbuffer.cpp:583
QGLBufferPrivate * d_ptr
Definition: qglbuffer.h:123
#define glGenBuffers
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
~QGLBuffer()
Destroys this buffer object, including the storage being used in the GL server.
Definition: qglbuffer.cpp:205
UsagePattern
This enum defines the usage pattern of a QGLBuffer object.
Definition: qglbuffer.h:74
int access(const char *, int)
The QGLContext class encapsulates an OpenGL rendering context.
Definition: qgl.h:310
#define glMapBufferARB
bool deref()
Atomically decrements the value of this QAtomicInt.
QGLSharedResourceGuard guard
Definition: qglbuffer.cpp:156
Q_CORE_EXPORT void qWarning(const char *,...)
static const char * data(const QByteArray &arr)
#define glGetBufferSubData
QGLBuffer::UsagePattern usagePattern() const
Returns the usage pattern for this buffer object.
Definition: qglbuffer.cpp:247
Access
This enum defines the access mode for QGLBuffer::map().
Definition: qglbuffer.h:87
QGLBuffer()
Constructs a new buffer object of type QGLBuffer::VertexBuffer.
Definition: qglbuffer.cpp:169
#define glDeleteBuffers
QAtomicInt ref
Definition: qglbuffer.cpp:154
QGLBufferPrivate(QGLBuffer::Type t)
Definition: qglbuffer.cpp:145
QGLBuffer::Type type
Definition: qglbuffer.cpp:155
unsigned int GLenum
Definition: main.cpp:50
bool isCreated() const
Returns true if this buffer has been created; false otherwise.
Definition: qglbuffer.cpp:317
bool bind()
Binds the buffer associated with this object to the current GL context.
Definition: qglbuffer.cpp:436
#define GL_BUFFER_SIZE
Definition: qglbuffer.cpp:516
The QGLBuffer class provides functions for creating and managing GL buffer objects.
Definition: qglbuffer.h:56
void release()
Releases the buffer associated with this object from the current GL context.
Definition: qglbuffer.cpp:468
QGLBuffer & operator=(const QGLBuffer &other)
Assigns a shallow copy of other to this object.
Definition: qglbuffer.cpp:219
int size() const
Returns the size of the data in this buffer, for reading operations.
Definition: qglbuffer.cpp:528
void allocate(const void *data, int count)
Allocates count bytes of space to the buffer, initialized to the contents of data.
Definition: qglbuffer.cpp:398
typedef GLint
Definition: glfunctions.h:67
#define glUnmapBufferARB
#define glBindBuffer
QGLBuffer::UsagePattern usagePattern
Definition: qglbuffer.cpp:157
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
#define GL_NO_ERROR
QGLBuffer::UsagePattern actualUsagePattern
Definition: qglbuffer.cpp:158
#define glBufferData