📄 qgl.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtOpenGL module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qapplication.h"#include "qplatformdefs.h"#include "qgl.h"#include <qdebug.h>#include "qpixmap.h"#include "qimage.h"#include "qgl_p.h"#include <private/qpaintengine_opengl_p.h>#include "qcolormap.h"#include "qcache.h"#include "qfile.h"#include "qlibrary.h"#if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs;#endifQThreadStorage<QGLThreadContext *> qgl_context_storage;Q_GLOBAL_STATIC(QGLFormat, qgl_default_format)class QGLDefaultOverlayFormat: public QGLFormat{public: inline QGLDefaultOverlayFormat() { setOption(QGL::FormatOption(0xffff << 16)); // turn off all options setOption(QGL::DirectRendering); setPlane(1); }};Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance)QGLExtensions::Extensions QGLExtensions::glExtensions = 0;bool QGLExtensions::nvidiaFboNeedsFinish = false;#ifndef APIENTRY# define APIENTRY#endiftypedef void (APIENTRY *pfn_glCompressedTexImage2DARB) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);static pfn_glCompressedTexImage2DARB qt_glCompressedTexImage2DARB = 0;#if defined(Q_WS_X11)#include "private/qt_x11_p.h"#define INT32 dummy_INT32#define INT8 dummy_INT8#include <GL/glx.h>#undef INT32#undef INT8#include "qx11info_x11.h"#elif defined(Q_WS_MAC)# include <private/qt_mac_p.h>#endif#include <stdlib.h> // malloc#ifndef APIENTRY#define APIENTRY#endif/*! \namespace QGL \brief The QGL namespace specifies miscellaneous identifiers used in the Qt OpenGL module. \ingroup multimedia*//*! \enum QGL::FormatOption This enum specifies the format options. \value DoubleBuffer \value DepthBuffer \value Rgba \value AlphaChannel \value AccumBuffer \value StencilBuffer \value StereoBuffers \value DirectRendering \value HasOverlay \value SampleBuffers \value SingleBuffer \value NoDepthBuffer \value ColorIndex \value NoAlphaChannel \value NoAccumBuffer \value NoStencilBuffer \value NoStereoBuffers \value IndirectRendering \value NoOverlay \value NoSampleBuffers \sa {Sample Buffers Example}*//***************************************************************************** QGLFormat implementation *****************************************************************************//*! \class QGLFormat \brief The QGLFormat class specifies the display format of an OpenGL rendering context. \ingroup multimedia A display format has several characteristics: \list \i \link setDoubleBuffer() Double or single buffering.\endlink \i \link setDepth() Depth buffer.\endlink \i \link setRgba() RGBA or color index mode.\endlink \i \link setAlpha() Alpha channel.\endlink \i \link setAccum() Accumulation buffer.\endlink \i \link setStencil() Stencil buffer.\endlink \i \link setStereo() Stereo buffers.\endlink \i \link setDirectRendering() Direct rendering.\endlink \i \link setOverlay() Presence of an overlay.\endlink \i \link setPlane() The plane of an overlay format.\endlink \i \link setSampleBuffers() Multisample buffers.\endlink \endlist You can also specify preferred bit depths for the depth buffer, alpha buffer, accumulation buffer and the stencil buffer with the functions: setDepthBufferSize(), setAlphaBufferSize(), setAccumBufferSize() and setStencilBufferSize(). Note that even if you specify that you prefer a 32 bit depth buffer (e.g. with setDepthBufferSize(32)), the format that is chosen may not have a 32 bit depth buffer, even if there is a format available with a 32 bit depth buffer. The main reason for this is how the system dependant picking algorithms work on the different platforms, and some format options may have higher precedence than others. You create and tell a QGLFormat object what rendering options you want from an OpenGL rendering context. OpenGL drivers or accelerated hardware may or may not support advanced features such as alpha channel or stereographic viewing. If you request some features that the driver/hardware does not provide when you create a QGLWidget, you will get a rendering context with the nearest subset of features. There are different ways to define the display characteristics of a rendering context. One is to create a QGLFormat and make it the default for the entire application: \code QGLFormat fmt; fmt.setAlpha(true); fmt.setStereo(true); QGLFormat::setDefaultFormat(fmt); \endcode Or you can specify the desired format when creating an object of your QGLWidget subclass: \code QGLFormat fmt; fmt.setDoubleBuffer(false); // single buffer fmt.setDirectRendering(false); // software rendering MyGLWidget* myWidget = new MyGLWidget(fmt, ...); \endcode After the widget has been created, you can find out which of the requested features the system was able to provide: \code QGLFormat fmt; fmt.setOverlay(true); fmt.setStereo(true); MyGLWidget* myWidget = new MyGLWidget(fmt, ...); if (!myWidget->format().stereo()) { // ok, goggles off if (!myWidget->format().hasOverlay()) { qFatal("Cool hardware required"); } } \endcode \legalese OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other countries. \endlegalese \sa QGLContext, QGLWidget*/static inline void transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4]){#define M(row,col) m[col*4+row] out[0] = M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3]; out[1] = M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3]; out[2] = M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3]; out[3] = M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];#undef M}static inline GLint qgluProject(GLdouble objx, GLdouble objy, GLdouble objz, const GLdouble model[16], const GLdouble proj[16], const GLint viewport[4], GLdouble * winx, GLdouble * winy, GLdouble * winz){ GLdouble in[4], out[4]; in[0] = objx; in[1] = objy; in[2] = objz; in[3] = 1.0; transform_point(out, model, in); transform_point(in, proj, out); if (in[3] == 0.0) return GL_FALSE; in[0] /= in[3]; in[1] /= in[3]; in[2] /= in[3]; *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2; *winy = viewport[1] + (1 + in[1]) * viewport[3] / 2; *winz = (1 + in[2]) / 2; return GL_TRUE;}/*! Constructs a QGLFormat object with the factory default settings: \list \i \link setDoubleBuffer() Double buffer:\endlink Enabled. \i \link setDepth() Depth buffer:\endlink Enabled. \i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled). \i \link setAlpha() Alpha channel:\endlink Disabled. \i \link setAccum() Accumulator buffer:\endlink Disabled. \i \link setStencil() Stencil buffer:\endlink Disabled. \i \link setStereo() Stereo:\endlink Disabled. \i \link setDirectRendering() Direct rendering:\endlink Enabled. \i \link setOverlay() Overlay:\endlink Disabled. \i \link setPlane() Plane:\endlink 0 (i.e., normal plane). \i \link setSampleBuffers() Multisample buffers:\endlink Disabled. \endlist*/QGLFormat::QGLFormat(){ d = new QGLFormatPrivate;}/*! Creates a QGLFormat object that is a copy of the current \link defaultFormat() application default format\endlink. If \a options is not 0, this copy is modified by these format options. The \a options parameter should be \c FormatOption values OR'ed together. This constructor makes it easy to specify a certain desired format in classes derived from QGLWidget, for example: \code // The rendering in MyGLWidget depends on using // stencil buffer and alpha channel MyGLWidget::MyGLWidget(QWidget* parent) : QGLWidget(QGLFormat(QGL::StencilBuffer | QGL::AlphaChannel), parent) { if (!format().stencil()) qWarning("Could not get stencil buffer; results will be suboptimal"); if (!format().alpha()) qWarning("Could not get alpha channel; results will be suboptimal"); ... } \endcode Note that there are \c FormatOption values to turn format settings both on and off, e.g. \c DepthBuffer and \c NoDepthBuffer, \c DirectRendering and \c IndirectRendering, etc. The \a plane parameter defaults to 0 and is the plane which this format should be associated with. Not all OpenGL implementations supports overlay/underlay rendering planes. \sa defaultFormat(), setOption()*/QGLFormat::QGLFormat(QGL::FormatOptions options, int plane){ d = new QGLFormatPrivate; QGL::FormatOptions newOpts = options; d->opts = defaultFormat().d->opts; d->opts |= (newOpts & 0xffff); d->opts &= ~(newOpts >> 16); d->pln = plane;}/*! Constructs a copy of \a other.*/QGLFormat::QGLFormat(const QGLFormat &other){ d = new QGLFormatPrivate; *d = *other.d;}/*! Assigns \a other to this object.*/QGLFormat &QGLFormat::operator=(const QGLFormat &other){ *d = *other.d; return *this;}/*! Destroys the QGLFormat.*/QGLFormat::~QGLFormat(){ delete d;}/*! \fn bool QGLFormat::doubleBuffer() const Returns true if double buffering is enabled; otherwise returns false. Double buffering is enabled by default. \sa setDoubleBuffer()*//*! If \a enable is true sets double buffering; otherwise sets single buffering. Double buffering is enabled by default. Double buffering is a technique where graphics are rendered on an off-screen buffer and not directly to the screen. When the drawing has been completed, the program calls a swapBuffers() function to exchange the screen contents with the buffer. The result is flicker-free drawing and often better performance. \sa doubleBuffer(), QGLContext::swapBuffers(), QGLWidget::swapBuffers()*/void QGLFormat::setDoubleBuffer(bool enable){ setOption(enable ? QGL::DoubleBuffer : QGL::SingleBuffer);}/*! \fn bool QGLFormat::depth() const Returns true if the depth buffer is enabled; otherwise returns false. The depth buffer is enabled by default. \sa setDepth(), setDepthBufferSize()*//*! If \a enable is true enables the depth buffer; otherwise disables the depth buffer. The depth buffer is enabled by default. The purpose of a depth buffer (or Z-buffering) is to remove hidden surfaces. Pixels are assigned Z values based on the distance to the viewer. A pixel with a high Z value is closer to the viewer than a pixel with a low Z value. This information is used to decide whether to draw a pixel or not. \sa depth(), setDepthBufferSize()*/void QGLFormat::setDepth(bool enable){ setOption(enable ? QGL::DepthBuffer : QGL::NoDepthBuffer);}/*! \fn bool QGLFormat::rgba() const Returns true if RGBA color mode is set. Returns false if color index mode is set. The default color mode is RGBA. \sa setRgba()*//*! If \a enable is true sets RGBA mode. If \a enable is false sets color index mode. The default color mode is RGBA. RGBA is the preferred mode for most OpenGL applications. In RGBA color mode you specify colors as red + green + blue + alpha quadruplets. In color index mode you specify an index into a color lookup table. \sa rgba()*/void QGLFormat::setRgba(bool enable){ setOption(enable ? QGL::Rgba : QGL::ColorIndex);}/*! \fn bool QGLFormat::alpha() const Returns true if the alpha buffer in the framebuffer is enabled; otherwise returns false. The alpha buffer is disabled by default.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -