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 | /*! |
43 | \class QGLPixelBuffer |
44 | \brief The QGLPixelBuffer class encapsulates an OpenGL pbuffer. |
45 | \since 4.1 |
46 | |
47 | \ingroup painting-3D |
48 | |
49 | Rendering into a pbuffer is normally done using full hardware |
50 | acceleration. This can be significantly faster than rendering |
51 | into a QPixmap. |
52 | |
53 | There are three approaches to using this class: |
54 | |
55 | \list 1 |
56 | \o \bold{We can draw into the pbuffer and convert it to a QImage |
57 | using toImage().} This is normally much faster than calling |
58 | QGLWidget::renderPixmap(). |
59 | |
60 | \o \bold{We can draw into the pbuffer and copy the contents into |
61 | an OpenGL texture using updateDynamicTexture().} This allows |
62 | us to create dynamic textures and works on all systems |
63 | with pbuffer support. |
64 | |
65 | \o \bold{On systems that support it, we can bind the pbuffer to |
66 | an OpenGL texture.} The texture is then updated automatically |
67 | when the pbuffer contents change, eliminating the need for |
68 | additional copy operations. This is supported only on Windows |
69 | and Mac OS X systems that provide the \c render_texture |
70 | extension. Note that under Windows, a multi-sampled pbuffer |
71 | can't be used in conjunction with the \c render_texture |
72 | extension. If a multi-sampled pbuffer is requested under |
73 | Windows, the \c render_texture extension is turned off for that |
74 | pbuffer. |
75 | |
76 | |
77 | \endlist |
78 | |
79 | |
80 | \section1 Threading |
81 | |
82 | As of Qt 4.8, it's possible to render into a QGLPixelBuffer using |
83 | a QPainter in a separate thread. Note that OpenGL 2.0 or OpenGL ES |
84 | 2.0 is required for this to work. Also, under X11, it's necessary |
85 | to set the Qt::AA_X11InitThreads application attribute. |
86 | |
87 | Pbuffers are provided by the OpenGL \c pbuffer extension; call |
88 | hasOpenGLPbuffer() to find out if the system provides pbuffers. |
89 | |
90 | \sa {opengl/pbuffers}{Pbuffers Example} |
91 | */ |
92 | |
93 | #include <QtCore/qglobal.h> |
94 | |
95 | #if !defined(QT_OPENGL_ES_1) |
96 | #include <private/qpaintengineex_opengl2_p.h> |
97 | #endif |
98 | |
99 | #include <qglpixelbuffer.h> |
100 | #include <private/qglpixelbuffer_p.h> |
101 | #include <private/qfont_p.h> |
102 | #include <qimage.h> |
103 | |
104 | #ifndef QT_OPENGL_ES_2 |
105 | #include <private/qpaintengine_opengl_p.h> |
106 | #endif |
107 | |
108 | QT_BEGIN_NAMESPACE |
109 | |
110 | #if !defined(QT_OPENGL_ES_2) |
111 | extern void qgl_cleanup_glyph_cache(QGLContext *); |
112 | #else |
113 | void qgl_cleanup_glyph_cache(QGLContext *) {} |
114 | #endif |
115 | |
116 | extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool); |
117 | |
118 | |
119 | QGLContext* QGLPBufferGLPaintDevice::context() const |
120 | { |
121 | return pbuf->d_func()->qctx; |
122 | } |
123 | |
124 | void QGLPBufferGLPaintDevice::endPaint() { |
125 | glFlush(); |
126 | QGLPaintDevice::endPaint(); |
127 | } |
128 | |
129 | void QGLPBufferGLPaintDevice::setPBuffer(QGLPixelBuffer* pb) |
130 | { |
131 | pbuf = pb; |
132 | } |
133 | |
134 | void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget) |
135 | { |
136 | Q_Q(QGLPixelBuffer); |
137 | if(init(size, format, shareWidget)) { |
138 | req_size = size; |
139 | req_format = format; |
140 | req_shareWidget = shareWidget; |
141 | invalid = false; |
142 | qctx = new QGLContext(format); |
143 | qctx->d_func()->sharing = (shareWidget != 0); |
144 | if (shareWidget != 0 && shareWidget->d_func()->glcx) { |
145 | QGLContextGroup::addShare(qctx, shareWidget->d_func()->glcx); |
146 | shareWidget->d_func()->glcx->d_func()->sharing = true; |
147 | } |
148 | |
149 | glDevice.setPBuffer(q); |
150 | qctx->d_func()->paintDevice = q; |
151 | qctx->d_func()->valid = true; |
152 | #if defined(Q_WS_WIN) && !defined(QT_OPENGL_ES) |
153 | qctx->d_func()->dc = dc; |
154 | qctx->d_func()->rc = ctx; |
155 | #elif (defined(Q_WS_X11) && defined(QT_NO_EGL)) |
156 | qctx->d_func()->cx = ctx; |
157 | qctx->d_func()->pbuf = (void *) pbuf; |
158 | qctx->d_func()->vi = 0; |
159 | #elif defined(Q_WS_MAC) |
160 | qctx->d_func()->cx = ctx; |
161 | qctx->d_func()->vi = 0; |
162 | #elif !defined(QT_NO_EGL) |
163 | qctx->d_func()->eglContext = ctx; |
164 | qctx->d_func()->eglSurface = pbuf; |
165 | #endif |
166 | } |
167 | } |
168 | |
169 | /*! |
170 | Constructs an OpenGL pbuffer of the given \a size. If no \a |
171 | format is specified, the \l{QGLFormat::defaultFormat()}{default |
172 | format} is used. If the \a shareWidget parameter points to a |
173 | valid QGLWidget, the pbuffer will share its context with \a |
174 | shareWidget. |
175 | |
176 | If you intend to bind this pbuffer as a dynamic texture, the width |
177 | and height components of \c size must be powers of two (e.g., 512 |
178 | x 128). |
179 | |
180 | \sa size(), format() |
181 | */ |
182 | QGLPixelBuffer::QGLPixelBuffer(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget) |
183 | : d_ptr(new QGLPixelBufferPrivate(this)) |
184 | { |
185 | Q_D(QGLPixelBuffer); |
186 | d->common_init(size, format, shareWidget); |
187 | } |
188 | |
189 | |
190 | /*! \overload |
191 | |
192 | Constructs an OpenGL pbuffer with the \a width and \a height. If |
193 | no \a format is specified, the |
194 | \l{QGLFormat::defaultFormat()}{default format} is used. If the \a |
195 | shareWidget parameter points to a valid QGLWidget, the pbuffer |
196 | will share its context with \a shareWidget. |
197 | |
198 | If you intend to bind this pbuffer as a dynamic texture, the width |
199 | and height components of \c size must be powers of two (e.g., 512 |
200 | x 128). |
201 | |
202 | \sa size(), format() |
203 | */ |
204 | QGLPixelBuffer::QGLPixelBuffer(int width, int height, const QGLFormat &format, QGLWidget *shareWidget) |
205 | : d_ptr(new QGLPixelBufferPrivate(this)) |
206 | { |
207 | Q_D(QGLPixelBuffer); |
208 | d->common_init(QSize(width, height), format, shareWidget); |
209 | } |
210 | |
211 | |
212 | /*! \fn QGLPixelBuffer::~QGLPixelBuffer() |
213 | |
214 | Destroys the pbuffer and frees any allocated resources. |
215 | */ |
216 | QGLPixelBuffer::~QGLPixelBuffer() |
217 | { |
218 | Q_D(QGLPixelBuffer); |
219 | |
220 | // defined in qpaintengine_opengl.cpp |
221 | QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext()); |
222 | if (current != d->qctx) |
223 | makeCurrent(); |
224 | qgl_cleanup_glyph_cache(d->qctx); |
225 | d->cleanup(); |
226 | delete d->qctx; |
227 | if (current && current != d->qctx) |
228 | current->makeCurrent(); |
229 | } |
230 | |
231 | /*! \fn bool QGLPixelBuffer::makeCurrent() |
232 | |
233 | Makes this pbuffer the current OpenGL rendering context. Returns |
234 | true on success; otherwise returns false. |
235 | |
236 | \sa QGLContext::makeCurrent(), doneCurrent() |
237 | */ |
238 | |
239 | bool QGLPixelBuffer::makeCurrent() |
240 | { |
241 | Q_D(QGLPixelBuffer); |
242 | if (d->invalid) |
243 | return false; |
244 | d->qctx->makeCurrent(); |
245 | return true; |
246 | } |
247 | |
248 | /*! \fn bool QGLPixelBuffer::doneCurrent() |
249 | |
250 | Makes no context the current OpenGL context. Returns true on |
251 | success; otherwise returns false. |
252 | */ |
253 | |
254 | bool QGLPixelBuffer::doneCurrent() |
255 | { |
256 | Q_D(QGLPixelBuffer); |
257 | if (d->invalid) |
258 | return false; |
259 | d->qctx->doneCurrent(); |
260 | return true; |
261 | } |
262 | |
263 | /*! |
264 | Generates and binds a 2D GL texture that is the same size as the |
265 | pbuffer, and returns the texture's ID. This can be used in |
266 | conjunction with bindToDynamicTexture() and |
267 | updateDynamicTexture(). |
268 | |
269 | \sa size() |
270 | */ |
271 | |
272 | #if (defined(Q_WS_X11) || defined(Q_WS_WIN)) && defined(QT_NO_EGL) |
273 | GLuint QGLPixelBuffer::generateDynamicTexture() const |
274 | { |
275 | Q_D(const QGLPixelBuffer); |
276 | GLuint texture; |
277 | glGenTextures(1, &texture); |
278 | glBindTexture(GL_TEXTURE_2D, texture); |
279 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, d->req_size.width(), d->req_size.height(), 0, GL_RGBA, GL_FLOAT, 0); |
280 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
281 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
282 | return texture; |
283 | } |
284 | #endif |
285 | |
286 | /*! \fn bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id) |
287 | |
288 | Binds the texture specified by \a texture_id to this pbuffer. |
289 | Returns true on success; otherwise returns false. |
290 | |
291 | The texture must be of the same size and format as the pbuffer. |
292 | |
293 | To unbind the texture, call releaseFromDynamicTexture(). While |
294 | the texture is bound, it is updated automatically when the |
295 | pbuffer contents change, eliminating the need for additional copy |
296 | operations. |
297 | |
298 | Example: |
299 | |
300 | \snippet doc/src/snippets/code/src_opengl_qglpixelbuffer.cpp 0 |
301 | |
302 | \warning This function uses the \c {render_texture} extension, |
303 | which is currently not supported under X11. An alternative that |
304 | works on all systems (including X11) is to manually copy the |
305 | pbuffer contents to a texture using updateDynamicTexture(). |
306 | |
307 | \warning For the bindToDynamicTexture() call to succeed on the |
308 | Mac OS X, the pbuffer needs a shared context, i.e. the |
309 | QGLPixelBuffer must be created with a share widget. |
310 | |
311 | \sa generateDynamicTexture(), releaseFromDynamicTexture() |
312 | */ |
313 | |
314 | /*! \fn void QGLPixelBuffer::releaseFromDynamicTexture() |
315 | |
316 | Releases the pbuffer from any previously bound texture. |
317 | |
318 | \sa bindToDynamicTexture() |
319 | */ |
320 | |
321 | /*! \fn bool QGLPixelBuffer::hasOpenGLPbuffers() |
322 | |
323 | Returns true if the OpenGL \c pbuffer extension is present on |
324 | this system; otherwise returns false. |
325 | */ |
326 | |
327 | /*! |
328 | Copies the pbuffer contents into the texture specified with \a |
329 | texture_id. |
330 | |
331 | The texture must be of the same size and format as the pbuffer. |
332 | |
333 | Example: |
334 | |
335 | \snippet doc/src/snippets/code/src_opengl_qglpixelbuffer.cpp 1 |
336 | |
337 | An alternative on Windows and Mac OS X systems that support the |
338 | \c render_texture extension is to use bindToDynamicTexture() to |
339 | get dynamic updates of the texture. |
340 | |
341 | \sa generateDynamicTexture(), bindToDynamicTexture() |
342 | */ |
343 | void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const |
344 | { |
345 | Q_D(const QGLPixelBuffer); |
346 | if (d->invalid) |
347 | return; |
348 | glBindTexture(GL_TEXTURE_2D, texture_id); |
349 | #ifndef QT_OPENGL_ES |
350 | glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, d->req_size.width(), d->req_size.height(), 0); |
351 | #else |
352 | glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0); |
353 | #endif |
354 | } |
355 | |
356 | #ifdef Q_MAC_COMPAT_GL_FUNCTIONS |
357 | void QGLPixelBuffer::updateDynamicTexture(QMacCompatGLuint texture_id) const |
358 | { |
359 | updateDynamicTexture(GLuint(texture_id)); |
360 | } |
361 | #endif |
362 | |
363 | /*! |
364 | Returns the size of the pbuffer. |
365 | */ |
366 | QSize QGLPixelBuffer::size() const |
367 | { |
368 | Q_D(const QGLPixelBuffer); |
369 | return d->req_size; |
370 | } |
371 | |
372 | /*! |
373 | Returns the contents of the pbuffer as a QImage. |
374 | */ |
375 | QImage QGLPixelBuffer::toImage() const |
376 | { |
377 | Q_D(const QGLPixelBuffer); |
378 | if (d->invalid) |
379 | return QImage(); |
380 | |
381 | const_cast<QGLPixelBuffer *>(this)->makeCurrent(); |
382 | return qt_gl_read_framebuffer(d->req_size, d->format.alpha(), true); |
383 | } |
384 | |
385 | /*! |
386 | Returns the native pbuffer handle. |
387 | */ |
388 | Qt::HANDLE QGLPixelBuffer::handle() const |
389 | { |
390 | Q_D(const QGLPixelBuffer); |
391 | if (d->invalid) |
392 | return 0; |
393 | return (Qt::HANDLE) d->pbuf; |
394 | } |
395 | |
396 | /*! |
397 | Returns true if this pbuffer is valid; otherwise returns false. |
398 | */ |
399 | bool QGLPixelBuffer::isValid() const |
400 | { |
401 | Q_D(const QGLPixelBuffer); |
402 | return !d->invalid; |
403 | } |
404 | |
405 | #if !defined(QT_OPENGL_ES_1) |
406 | Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine) |
407 | #endif |
408 | |
409 | #ifndef QT_OPENGL_ES_2 |
410 | Q_GLOBAL_STATIC(QGLEngineThreadStorage<QOpenGLPaintEngine>, qt_buffer_engine) |
411 | #endif |
412 | |
413 | /*! \reimp */ |
414 | QPaintEngine *QGLPixelBuffer::paintEngine() const |
415 | { |
416 | #if defined(QT_OPENGL_ES_1) |
417 | return qt_buffer_engine()->engine(); |
418 | #elif defined(QT_OPENGL_ES_2) |
419 | return qt_buffer_2_engine()->engine(); |
420 | #else |
421 | if (qt_gl_preferGL2Engine()) |
422 | return qt_buffer_2_engine()->engine(); |
423 | else |
424 | return qt_buffer_engine()->engine(); |
425 | #endif |
426 | } |
427 | |
428 | /*! \reimp */ |
429 | int QGLPixelBuffer::metric(PaintDeviceMetric metric) const |
430 | { |
431 | Q_D(const QGLPixelBuffer); |
432 | |
433 | float dpmx = qt_defaultDpiX()*100./2.54; |
434 | float dpmy = qt_defaultDpiY()*100./2.54; |
435 | int w = d->req_size.width(); |
436 | int h = d->req_size.height(); |
437 | switch (metric) { |
438 | case PdmWidth: |
439 | return w; |
440 | |
441 | case PdmHeight: |
442 | return h; |
443 | |
444 | case PdmWidthMM: |
445 | return qRound(w * 1000 / dpmx); |
446 | |
447 | case PdmHeightMM: |
448 | return qRound(h * 1000 / dpmy); |
449 | |
450 | case PdmNumColors: |
451 | return 0; |
452 | |
453 | case PdmDepth: |
454 | return 32;//d->depth; |
455 | |
456 | case PdmDpiX: |
457 | return qRound(dpmx * 0.0254); |
458 | |
459 | case PdmDpiY: |
460 | return qRound(dpmy * 0.0254); |
461 | |
462 | case PdmPhysicalDpiX: |
463 | return qRound(dpmx * 0.0254); |
464 | |
465 | case PdmPhysicalDpiY: |
466 | return qRound(dpmy * 0.0254); |
467 | |
468 | default: |
469 | qWarning("QGLPixelBuffer::metric(), Unhandled metric type: %d\n" , metric); |
470 | break; |
471 | } |
472 | return 0; |
473 | } |
474 | |
475 | /*! |
476 | Generates and binds a 2D GL texture to the current context, based |
477 | on \a image. The generated texture id is returned and can be used |
478 | in later glBindTexture() calls. |
479 | |
480 | The \a target parameter specifies the texture target. |
481 | |
482 | Equivalent to calling QGLContext::bindTexture(). |
483 | |
484 | \sa deleteTexture() |
485 | */ |
486 | GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target) |
487 | { |
488 | Q_D(QGLPixelBuffer); |
489 | #ifndef QT_OPENGL_ES |
490 | return d->qctx->bindTexture(image, target, GLint(GL_RGBA8)); |
491 | #else |
492 | return d->qctx->bindTexture(image, target, GL_RGBA); |
493 | #endif |
494 | } |
495 | |
496 | #ifdef Q_MAC_COMPAT_GL_FUNCTIONS |
497 | /*! \internal */ |
498 | GLuint QGLPixelBuffer::bindTexture(const QImage &image, QMacCompatGLenum target) |
499 | { |
500 | Q_D(QGLPixelBuffer); |
501 | return d->qctx->bindTexture(image, target, QMacCompatGLint(GL_RGBA8)); |
502 | } |
503 | #endif |
504 | |
505 | /*! \overload |
506 | |
507 | Generates and binds a 2D GL texture based on \a pixmap. |
508 | |
509 | Equivalent to calling QGLContext::bindTexture(). |
510 | |
511 | \sa deleteTexture() |
512 | */ |
513 | GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target) |
514 | { |
515 | Q_D(QGLPixelBuffer); |
516 | #ifndef QT_OPENGL_ES |
517 | return d->qctx->bindTexture(pixmap, target, GLint(GL_RGBA8)); |
518 | #else |
519 | return d->qctx->bindTexture(pixmap, target, GL_RGBA); |
520 | #endif |
521 | } |
522 | |
523 | #ifdef Q_MAC_COMPAT_GL_FUNCTIONS |
524 | /*! \internal */ |
525 | GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target) |
526 | { |
527 | Q_D(QGLPixelBuffer); |
528 | return d->qctx->bindTexture(pixmap, target, QMacCompatGLint(GL_RGBA8)); |
529 | } |
530 | #endif |
531 | |
532 | /*! \overload |
533 | |
534 | Reads the DirectDrawSurface (DDS) compressed file \a fileName and |
535 | generates a 2D GL texture from it. |
536 | |
537 | Equivalent to calling QGLContext::bindTexture(). |
538 | |
539 | \sa deleteTexture() |
540 | */ |
541 | GLuint QGLPixelBuffer::bindTexture(const QString &fileName) |
542 | { |
543 | Q_D(QGLPixelBuffer); |
544 | return d->qctx->bindTexture(fileName); |
545 | } |
546 | |
547 | /*! |
548 | Removes the texture identified by \a texture_id from the texture cache. |
549 | |
550 | Equivalent to calling QGLContext::deleteTexture(). |
551 | */ |
552 | void QGLPixelBuffer::deleteTexture(GLuint texture_id) |
553 | { |
554 | Q_D(QGLPixelBuffer); |
555 | d->qctx->deleteTexture(texture_id); |
556 | } |
557 | |
558 | #ifdef Q_MAC_COMPAT_GL_FUNCTIONS |
559 | /*! \internal */ |
560 | void QGLPixelBuffer::deleteTexture(QMacCompatGLuint texture_id) |
561 | { |
562 | Q_D(QGLPixelBuffer); |
563 | d->qctx->deleteTexture(texture_id); |
564 | } |
565 | #endif |
566 | |
567 | /*! |
568 | \since 4.4 |
569 | |
570 | Draws the given texture, \a textureId, to the given target rectangle, |
571 | \a target, in OpenGL model space. The \a textureTarget should be a 2D |
572 | texture target. |
573 | |
574 | Equivalent to the corresponding QGLContext::drawTexture(). |
575 | */ |
576 | void QGLPixelBuffer::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) |
577 | { |
578 | Q_D(QGLPixelBuffer); |
579 | d->qctx->drawTexture(target, textureId, textureTarget); |
580 | } |
581 | |
582 | #ifdef Q_MAC_COMPAT_GL_FUNCTIONS |
583 | /*! \internal */ |
584 | void QGLPixelBuffer::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget) |
585 | { |
586 | Q_D(QGLPixelBuffer); |
587 | d->qctx->drawTexture(target, textureId, textureTarget); |
588 | } |
589 | #endif |
590 | |
591 | /*! |
592 | \since 4.4 |
593 | |
594 | Draws the given texture, \a textureId, at the given \a point in OpenGL model |
595 | space. The textureTarget parameter should be a 2D texture target. |
596 | |
597 | Equivalent to the corresponding QGLContext::drawTexture(). |
598 | */ |
599 | void QGLPixelBuffer::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) |
600 | { |
601 | Q_D(QGLPixelBuffer); |
602 | d->qctx->drawTexture(point, textureId, textureTarget); |
603 | } |
604 | |
605 | #ifdef Q_MAC_COMPAT_GL_FUNCTIONS |
606 | /*! \internal */ |
607 | void QGLPixelBuffer::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget) |
608 | { |
609 | Q_D(QGLPixelBuffer); |
610 | d->qctx->drawTexture(point, textureId, textureTarget); |
611 | } |
612 | #endif |
613 | |
614 | /*! |
615 | Returns the format of the pbuffer. The format may be different |
616 | from the one that was requested. |
617 | */ |
618 | QGLFormat QGLPixelBuffer::format() const |
619 | { |
620 | Q_D(const QGLPixelBuffer); |
621 | return d->format; |
622 | } |
623 | |
624 | /*! \fn int QGLPixelBuffer::devType() const |
625 | \internal |
626 | */ |
627 | |
628 | QT_END_NAMESPACE |
629 | |