Dynamic GL switch on Windows
The patch introduces a new build configuration on Windows which can be requested by passing -opengl dynamic to configure. Platforms other than Windows (including WinRT) are not affected. The existing Angle and desktop configurations are not affected. These continue to function as before and Angle remains the default. In the future, when all modules have added support for the dynamic path, as described below, the default configuration could be changed to be the dynamic one. This would allow providing a single set of binaries in the official builds instead of the current two. When requesting dynamic GL, Angle is built but QT_OPENGL_ES[_2] are never defined. Instead, the code path that has traditionally been desktop GL only becomes the dynamic path that has to do runtime checks. Qt modules and applications are not linked to opengl32.dll or libegl/glesv2.dll in this case. Instead, QtGui exports all necessary egl/egl/gl functions which will, under the hood, forward all requests to a dynamically loaded EGL/WGL/GL implementation. Porting guide (better said, changes needed to prepare your code to work with dynamic GL builds when the fallback to Angle is utilized): 1. In !QT_OPENGL_ES[_2] code branches use QOpenGLFunctions::isES() to differentiate between desktop and ES where needed. Keep in mind that it is the desktop GL header (plus qopenglext.h) that is included, not the GLES one. QtGui's proxy will handle some differences, for example calling glClearDepth will route to glClearDepthf when needed. The built-in eglGetProcAddress is able to retrieve pointers for standard GLES2 functions too so code resolving OpenGL 2 functions will function in any case. 2. QT_CONFIG will contain "opengl" and "dynamicgl" in dynamic builds, but never "angle" or "opengles2". 3. The preprocessor define QT_OPENGL_DYNAMIC is also available in dynamic builds. The usage of this is strongly discouraged and should not be needed anywhere except for QtGui and the platform plugin. 4. Code in need of the library handle can use QOpenGLFunctions::platformGLHandle(). The decision on which library to load is currently based on a simple test that creates a dummy window/context and tries to resolve an OpenGL 2 function. If this fails, it goes for Angle. This seems to work well on Win7 PCs for example that do not have proper graphics drivers providing OpenGL installed but are D3D9 capable using the default drivers. Setting QT_OPENGL to desktop or angle skips the test and forces usage of the given GL. There are also two new application attributes that could be used for the same purpose. If Angle is requested but the libraries are not present, desktop is tried. If desktop is requested, or if angle is requested but nothing works, the EGL/WGL functions will still be callable but will return 0. This conveniently means that eglInitialize() and such will report a failure. Debug messages can be enabled by setting QT_OPENGLPROXY_DEBUG. This will tell which implementation is chosen. The textures example application is ported to OpenGL 2, the GL 1 code path is removed. [ChangeLog][QtGui] Qt builds on Windows can now be configured for dynamic loading of the OpenGL implementation. This can be requested by passing -opengl dynamic to configure. In this mode no modules will link to opengl32.dll or Angle's libegl/libglesv2. Instead, QtGui will dynamically choose between desktop and Angle during the first GL/EGL/WGL call. This allows deploying applications with a single set of Qt libraries with the ability of transparently falling back to Angle in case the opengl32.dll is not suitable, due to missing graphics drivers for example. Task-number: QTBUG-36483 Change-Id: I716fdebbf60b355b7d9ef57d1e069eef366b4ab9 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
parent
f25aca5c65
commit
97c187da3c
@ -50,9 +50,7 @@ GLWidget::GLWidget(QWidget *parent, QGLWidget *shareWidget)
|
||||
xRot = 0;
|
||||
yRot = 0;
|
||||
zRot = 0;
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
program = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
GLWidget::~GLWidget()
|
||||
@ -89,12 +87,10 @@ void GLWidget::initializeGL()
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
#ifdef GL_TEXTURE_2D
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
|
||||
#define PROGRAM_VERTEX_ATTRIBUTE 0
|
||||
#define PROGRAM_TEXCOORD_ATTRIBUTE 1
|
||||
|
||||
@ -130,8 +126,6 @@ void GLWidget::initializeGL()
|
||||
|
||||
program->bind();
|
||||
program->setUniformValue("texture", 0);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLWidget::paintGL()
|
||||
@ -139,21 +133,6 @@ void GLWidget::paintGL()
|
||||
qglClearColor(clearColor);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0f, 0.0f, -10.0f);
|
||||
glRotatef(xRot / 16.0f, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(yRot / 16.0f, 0.0f, 1.0f, 0.0f);
|
||||
glRotatef(zRot / 16.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
|
||||
glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData());
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
#else
|
||||
|
||||
QMatrix4x4 m;
|
||||
m.ortho(-0.5f, +0.5f, +0.5f, -0.5f, 4.0f, 15.0f);
|
||||
m.translate(0.0f, 0.0f, -10.0f);
|
||||
@ -169,8 +148,6 @@ void GLWidget::paintGL()
|
||||
program->setAttributeArray
|
||||
(PROGRAM_TEXCOORD_ATTRIBUTE, texCoords.constData());
|
||||
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i]);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, i * 4, 4);
|
||||
@ -181,17 +158,6 @@ void GLWidget::resizeGL(int width, int height)
|
||||
{
|
||||
int side = qMin(width, height);
|
||||
glViewport((width - side) / 2, (height - side) / 2, side, side);
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
#ifndef QT_OPENGL_ES
|
||||
glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
|
||||
#else
|
||||
glOrthof(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0);
|
||||
#endif
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
#endif
|
||||
}
|
||||
|
||||
void GLWidget::mousePressEvent(QMouseEvent *event)
|
||||
|
@ -81,9 +81,7 @@ private:
|
||||
GLuint textures[6];
|
||||
QVector<QVector3D> vertices;
|
||||
QVector<QVector2D> texCoords;
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
QGLShaderProgram *program;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
#
|
||||
|
||||
load(device_config)
|
||||
load(qt_config)
|
||||
|
||||
MAKEFILE_GENERATOR = MINGW
|
||||
QMAKE_PLATFORM = win32 mingw
|
||||
@ -84,7 +85,7 @@ QMAKE_LIBS =
|
||||
QMAKE_LIBS_CORE = -lole32 -luuid -lws2_32 -ladvapi32 -lshell32 -luser32 -lkernel32
|
||||
QMAKE_LIBS_GUI = -lgdi32 -lcomdlg32 -loleaut32 -limm32 -lwinmm -lws2_32 -lole32 -luuid -luser32 -ladvapi32
|
||||
QMAKE_LIBS_NETWORK = -lws2_32
|
||||
QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
|
||||
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = -lglu32 -lopengl32 -lgdi32 -luser32
|
||||
QMAKE_LIBS_OPENGL_ES2 = -llibEGL -llibGLESv2 -lgdi32 -luser32
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = -llibEGLd -llibGLESv2d -lgdi32 -luser32
|
||||
QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32
|
||||
@ -110,4 +111,3 @@ QMAKE_STRIP = $${CROSS_COMPILE}strip
|
||||
QMAKE_STRIPFLAGS_LIB += --strip-unneeded
|
||||
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
|
||||
QMAKE_NM = $${CROSS_COMPILE}nm -P
|
||||
load(qt_config)
|
||||
|
@ -4,6 +4,8 @@
|
||||
# Written for Intel C++
|
||||
#
|
||||
|
||||
load(qt_config)
|
||||
|
||||
MAKEFILE_GENERATOR = MSVC.NET
|
||||
QMAKE_PLATFORM = win32
|
||||
CONFIG += incremental flat debug_and_release debug_and_release_target
|
||||
@ -61,7 +63,7 @@ QMAKE_LIBS =
|
||||
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
|
||||
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
|
||||
QMAKE_LIBS_NETWORK = ws2_32.lib
|
||||
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib delayimp.lib
|
||||
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib delayimp.lib
|
||||
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
|
||||
QMAKE_LIBS_QT_ENTRY = -lqtmain
|
||||
|
||||
@ -72,4 +74,3 @@ QMAKE_RC = rc
|
||||
include(../common/shell-win32.conf)
|
||||
|
||||
DSP_EXTENSION = .dsp
|
||||
load(qt_config)
|
||||
|
@ -4,6 +4,8 @@
|
||||
# Written for Microsoft Visual C++ 2005
|
||||
#
|
||||
|
||||
load(qt_config)
|
||||
|
||||
MAKEFILE_GENERATOR = MSVC.NET
|
||||
QMAKE_PLATFORM = win32
|
||||
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
|
||||
@ -75,7 +77,7 @@ QMAKE_EXTENSION_STATICLIB = lib
|
||||
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
|
||||
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
|
||||
QMAKE_LIBS_NETWORK = ws2_32.lib
|
||||
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
|
||||
@ -91,4 +93,3 @@ include(../common/shell-win32.conf)
|
||||
VCPROJ_EXTENSION = .vcproj
|
||||
VCSOLUTION_EXTENSION = .sln
|
||||
VCPROJ_KEYWORD = Qt4VSv1.0
|
||||
load(qt_config)
|
||||
|
@ -4,6 +4,8 @@
|
||||
# Written for Microsoft Visual C++ 2008
|
||||
#
|
||||
|
||||
load(qt_config)
|
||||
|
||||
MAKEFILE_GENERATOR = MSVC.NET
|
||||
QMAKE_PLATFORM = win32
|
||||
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
|
||||
@ -77,7 +79,7 @@ QMAKE_EXTENSION_STATICLIB = lib
|
||||
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
|
||||
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
|
||||
QMAKE_LIBS_NETWORK = ws2_32.lib
|
||||
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
|
||||
@ -93,4 +95,3 @@ include(../common/shell-win32.conf)
|
||||
VCPROJ_EXTENSION = .vcproj
|
||||
VCSOLUTION_EXTENSION = .sln
|
||||
VCPROJ_KEYWORD = Qt4VSv1.0
|
||||
load(qt_config)
|
||||
|
@ -4,6 +4,8 @@
|
||||
# Written for Microsoft Visual C++ 2010
|
||||
#
|
||||
|
||||
load(qt_config)
|
||||
|
||||
MAKEFILE_GENERATOR = MSBUILD
|
||||
QMAKE_PLATFORM = win32
|
||||
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
|
||||
@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
|
||||
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
|
||||
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
|
||||
QMAKE_LIBS_NETWORK = ws2_32.lib
|
||||
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
|
||||
@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
|
||||
VCPROJ_EXTENSION = .vcxproj
|
||||
VCSOLUTION_EXTENSION = .sln
|
||||
VCPROJ_KEYWORD = Qt4VSv1.0
|
||||
load(qt_config)
|
||||
|
@ -4,6 +4,8 @@
|
||||
# Written for Microsoft Visual C++ 2012
|
||||
#
|
||||
|
||||
load(qt_config)
|
||||
|
||||
MAKEFILE_GENERATOR = MSBUILD
|
||||
QMAKE_PLATFORM = win32
|
||||
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
|
||||
@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
|
||||
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
|
||||
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
|
||||
QMAKE_LIBS_NETWORK = ws2_32.lib
|
||||
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
|
||||
@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
|
||||
VCPROJ_EXTENSION = .vcxproj
|
||||
VCSOLUTION_EXTENSION = .sln
|
||||
VCPROJ_KEYWORD = Qt4VSv1.0
|
||||
load(qt_config)
|
||||
|
@ -4,6 +4,8 @@
|
||||
# Written for Microsoft Visual C++ 2013
|
||||
#
|
||||
|
||||
load(qt_config)
|
||||
|
||||
MAKEFILE_GENERATOR = MSBUILD
|
||||
QMAKE_PLATFORM = win32
|
||||
CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target embed_manifest_dll embed_manifest_exe
|
||||
@ -79,7 +81,7 @@ QMAKE_EXTENSION_STATICLIB = lib
|
||||
QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib advapi32.lib ws2_32.lib
|
||||
QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib ws2_32.lib ole32.lib user32.lib advapi32.lib
|
||||
QMAKE_LIBS_NETWORK = ws2_32.lib
|
||||
QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
!contains(QT_CONFIG, dynamicgl): QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_OPENGL_ES2_DEBUG = libEGLd.lib libGLESv2d.lib gdi32.lib user32.lib
|
||||
QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib
|
||||
@ -95,4 +97,3 @@ include(../common/shell-win32.conf)
|
||||
VCPROJ_EXTENSION = .vcxproj
|
||||
VCSOLUTION_EXTENSION = .sln
|
||||
VCPROJ_KEYWORD = Qt4VSv1.0
|
||||
load(qt_config)
|
||||
|
@ -517,6 +517,8 @@ public:
|
||||
AA_SynthesizeMouseForUnhandledTouchEvents = 12,
|
||||
AA_UseHighDpiPixmaps = 13,
|
||||
AA_ForceRasterWidgets = 14,
|
||||
AA_UseDesktopOpenGL = 15,
|
||||
AA_UseOpenGLES = 16,
|
||||
|
||||
// Add new attributes before this line
|
||||
AA_AttributeCount
|
||||
|
@ -168,6 +168,14 @@
|
||||
\value AA_ForceRasterWidgets Make top-level widgets use pure raster surfaces,
|
||||
and do not support non-native GL-based child widgets.
|
||||
|
||||
\value AA_UseDesktopOpenGL Forces the usage of the desktop OpenGL on
|
||||
platforms that use dynamic loading of the OpenGL implementation.
|
||||
This value has been added in Qt 5.3.
|
||||
|
||||
\value AA_UseOpenGLES Forces the usage of OpenGL ES 2.0 on platforms that
|
||||
use dynamic loading of the OpenGL implementation.
|
||||
This value has been added in Qt 5.3.
|
||||
|
||||
The following values are obsolete:
|
||||
|
||||
\value AA_ImmediateWidgetCreation This attribute is no longer fully
|
||||
|
@ -13,11 +13,13 @@ MODULE_PLUGIN_TYPES = \
|
||||
imageformats
|
||||
|
||||
# This is here only because the platform plugin is no module, obviously.
|
||||
win32:contains(QT_CONFIG, angle) {
|
||||
win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
|
||||
MODULE_AUX_INCLUDES = \
|
||||
\$\$QT_MODULE_INCLUDE_BASE/QtANGLE
|
||||
}
|
||||
|
||||
contains(QT_CONFIG, dynamicgl): DEFINES += QT_OPENGL_DYNAMIC_IN_GUI
|
||||
|
||||
load(qt_module)
|
||||
|
||||
# Code coverage with TestCocoon
|
||||
|
@ -337,31 +337,32 @@ int QOpenGLContextPrivate::maxTextureSize()
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
|
||||
#if defined(QT_OPENGL_ES)
|
||||
return max_texture_size;
|
||||
#else
|
||||
GLenum proxy = GL_PROXY_TEXTURE_2D;
|
||||
#ifndef QT_OPENGL_ES
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
GLenum proxy = GL_PROXY_TEXTURE_2D;
|
||||
|
||||
GLint size;
|
||||
GLint next = 64;
|
||||
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
|
||||
if (size == 0) {
|
||||
return max_texture_size;
|
||||
}
|
||||
do {
|
||||
size = next;
|
||||
next = size * 2;
|
||||
|
||||
if (next > max_texture_size)
|
||||
break;
|
||||
GLint size;
|
||||
GLint next = 64;
|
||||
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
|
||||
} while (next > size);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
|
||||
if (size == 0) {
|
||||
return max_texture_size;
|
||||
}
|
||||
do {
|
||||
size = next;
|
||||
next = size * 2;
|
||||
|
||||
if (next > max_texture_size)
|
||||
break;
|
||||
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
|
||||
} while (next > size);
|
||||
|
||||
max_texture_size = size;
|
||||
}
|
||||
#endif // QT_OPENGL_ES
|
||||
|
||||
max_texture_size = size;
|
||||
return max_texture_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -641,6 +642,13 @@ QOpenGLFunctions *QOpenGLContext::functions() const
|
||||
*/
|
||||
QAbstractOpenGLFunctions *QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile) const
|
||||
{
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
qWarning("versionFunctions: Not supported on dynamic GL ES");
|
||||
return 0;
|
||||
}
|
||||
#endif // QT_OPENGL_ES_2
|
||||
|
||||
Q_D(const QOpenGLContext);
|
||||
const QSurfaceFormat f = format();
|
||||
|
||||
|
@ -122,4 +122,8 @@ contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
|
||||
|
||||
SOURCES += opengl/qopenglfunctions_es2.cpp
|
||||
}
|
||||
|
||||
contains(QT_CONFIG, dynamicgl) {
|
||||
win32: SOURCES += opengl/qopenglproxy_win.cpp
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +107,17 @@ typedef GLfloat GLdouble;
|
||||
# include <OpenGL/glext.h>
|
||||
# else
|
||||
# define GL_GLEXT_LEGACY // Prevents GL/gl.h from #including system glext.h
|
||||
// In dynamic GL builds qopenglproxy will export the GL functions that are
|
||||
// called also in QtGui itself. To prevent linker warnings (msvc) or errors (mingw)
|
||||
// we need to make sure the prototypes do not have dllimport.
|
||||
# ifdef QT_OPENGL_DYNAMIC_IN_GUI
|
||||
# undef WINGDIAPI
|
||||
# define WINGDIAPI
|
||||
# endif // QT_OPENGL_DYNAMIC_IN_GUI
|
||||
# include <GL/gl.h>
|
||||
# ifdef QT_OPENGL_DYNAMIC_IN_GUI
|
||||
# undef WINGDIAPI
|
||||
# endif // QT_OPENGL_DYNAMIC_IN_GUI
|
||||
# include <QtGui/qopenglext.h>
|
||||
# endif // Q_OS_MAC
|
||||
#endif
|
||||
|
@ -333,18 +333,20 @@ void QOpenGLBuffer::destroy()
|
||||
bool QOpenGLBuffer::read(int offset, void *data, int count)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES)
|
||||
Q_D(QOpenGLBuffer);
|
||||
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
|
||||
return false;
|
||||
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
|
||||
d->funcs->glGetBufferSubData(d->type, offset, count, data);
|
||||
return glGetError() == GL_NO_ERROR;
|
||||
if (QOpenGLFunctions::platformGLType() != QOpenGLFunctions::GLES1) {
|
||||
Q_D(QOpenGLBuffer);
|
||||
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
|
||||
return false;
|
||||
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
|
||||
d->funcs->glGetBufferSubData(d->type, offset, count, data);
|
||||
return glGetError() == GL_NO_ERROR;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(offset);
|
||||
Q_UNUSED(data);
|
||||
Q_UNUSED(count);
|
||||
return false;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -164,7 +164,10 @@ QOpenGLEngineSharedShaders::QOpenGLEngineSharedShaders(QOpenGLContext* context)
|
||||
code[NonPremultipliedImageSrcFragmentShader] = qopenglslNonPremultipliedImageSrcFragmentShader;
|
||||
code[CustomImageSrcFragmentShader] = qopenglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
|
||||
code[SolidBrushSrcFragmentShader] = qopenglslSolidBrushSrcFragmentShader;
|
||||
code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader;
|
||||
if (QOpenGLFunctions::isES())
|
||||
code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_ES;
|
||||
else
|
||||
code[TextureBrushSrcFragmentShader] = qopenglslTextureBrushSrcFragmentShader_desktop;
|
||||
code[TextureBrushSrcWithPatternFragmentShader] = qopenglslTextureBrushSrcWithPatternFragmentShader;
|
||||
code[PatternBrushSrcFragmentShader] = qopenglslPatternBrushSrcFragmentShader;
|
||||
code[LinearGradientBrushSrcFragmentShader] = qopenglslLinearGradientBrushSrcFragmentShader;
|
||||
|
@ -305,25 +305,23 @@ static const char* const qopenglslPositionWithTextureBrushVertexShader = "\n\
|
||||
static const char* const qopenglslAffinePositionWithTextureBrushVertexShader
|
||||
= qopenglslPositionWithTextureBrushVertexShader;
|
||||
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
|
||||
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
|
||||
// TODO: Special case POT textures which don't need this emulation
|
||||
static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
|
||||
static const char* const qopenglslTextureBrushSrcFragmentShader_ES = "\n\
|
||||
varying highp vec2 brushTextureCoords; \n\
|
||||
uniform sampler2D brushTexture; \n\
|
||||
lowp vec4 srcPixel() { \n\
|
||||
return texture2D(brushTexture, fract(brushTextureCoords)); \n\
|
||||
}\n";
|
||||
#else
|
||||
static const char* const qopenglslTextureBrushSrcFragmentShader = "\n\
|
||||
|
||||
static const char* const qopenglslTextureBrushSrcFragmentShader_desktop = "\n\
|
||||
varying highp vec2 brushTextureCoords; \n\
|
||||
uniform sampler2D brushTexture; \n\
|
||||
lowp vec4 srcPixel() \n\
|
||||
{ \n\
|
||||
return texture2D(brushTexture, brushTextureCoords); \n\
|
||||
}\n";
|
||||
#endif
|
||||
|
||||
static const char* const qopenglslTextureBrushSrcWithPatternFragmentShader = "\n\
|
||||
varying highp vec2 brushTextureCoords; \n\
|
||||
|
@ -72,8 +72,6 @@ QT_BEGIN_NAMESPACE
|
||||
#define QT_CHECK_GLERROR() {}
|
||||
#endif
|
||||
|
||||
// ####TODO Properly #ifdef this class to use #define symbols actually defined
|
||||
// by OpenGL/ES includes
|
||||
#ifndef GL_MAX_SAMPLES
|
||||
#define GL_MAX_SAMPLES 0x8D57
|
||||
#endif
|
||||
@ -592,30 +590,29 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
|
||||
funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
|
||||
Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
|
||||
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
|
||||
#ifdef QT_OPENGL_ES
|
||||
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT24, size.width(), size.height());
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT24, size.width(), size.height());
|
||||
else
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT16, size.width(), size.height());
|
||||
} else {
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT16, size.width(), size.height());
|
||||
GL_DEPTH_COMPONENT, size.width(), size.height());
|
||||
}
|
||||
#else
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT, size.width(), size.height());
|
||||
#endif
|
||||
} else {
|
||||
#ifdef QT_OPENGL_ES
|
||||
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
|
||||
size.width(), size.height());
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
|
||||
size.width(), size.height());
|
||||
} else {
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
|
||||
size.width(), size.height());
|
||||
}
|
||||
} else {
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
|
||||
size.width(), size.height());
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
|
||||
}
|
||||
#else
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
|
||||
#endif
|
||||
}
|
||||
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, depth_buffer);
|
||||
@ -630,23 +627,18 @@ void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpen
|
||||
funcs.glGenRenderbuffers(1, &stencil_buffer);
|
||||
funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
|
||||
Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
|
||||
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
|
||||
|
||||
#ifdef QT_OPENGL_ES
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_STENCIL_INDEX8, size.width(), size.height());
|
||||
GLenum storage = GL_STENCIL_INDEX8;
|
||||
#else
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_STENCIL_INDEX, size.width(), size.height());
|
||||
GLenum storage = QOpenGLFunctions::isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
|
||||
#endif
|
||||
} else {
|
||||
#ifdef QT_OPENGL_ES
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
|
||||
size.width(), size.height());
|
||||
#else
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
|
||||
size.width(), size.height());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
|
||||
else
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());
|
||||
|
||||
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, stencil_buffer);
|
||||
valid = checkFramebufferStatus(ctx);
|
||||
@ -779,7 +771,13 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, GLenum tar
|
||||
: d_ptr(new QOpenGLFramebufferObjectPrivate)
|
||||
{
|
||||
Q_D(QOpenGLFramebufferObject);
|
||||
d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
|
||||
d->init(this, size, NoAttachment, target,
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
|
||||
#else
|
||||
GL_RGBA
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -793,7 +791,13 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, GLenum
|
||||
: d_ptr(new QOpenGLFramebufferObjectPrivate)
|
||||
{
|
||||
Q_D(QOpenGLFramebufferObject);
|
||||
d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
|
||||
d->init(this, QSize(width, height), NoAttachment, target,
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
|
||||
#else
|
||||
GL_RGBA
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -842,6 +846,12 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(int width, int height, Attach
|
||||
: d_ptr(new QOpenGLFramebufferObjectPrivate)
|
||||
{
|
||||
Q_D(QOpenGLFramebufferObject);
|
||||
if (!internal_format)
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
internal_format = GL_RGBA;
|
||||
#else
|
||||
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
#endif
|
||||
d->init(this, QSize(width, height), attachment, target, internal_format);
|
||||
}
|
||||
|
||||
@ -863,6 +873,12 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment
|
||||
: d_ptr(new QOpenGLFramebufferObjectPrivate)
|
||||
{
|
||||
Q_D(QOpenGLFramebufferObject);
|
||||
if (!internal_format)
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
internal_format = GL_RGBA;
|
||||
#else
|
||||
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
#endif
|
||||
d->init(this, size, attachment, target, internal_format);
|
||||
}
|
||||
|
||||
|
@ -69,17 +69,11 @@ public:
|
||||
|
||||
explicit QOpenGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D);
|
||||
QOpenGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
|
||||
#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
|
||||
|
||||
QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
|
||||
QOpenGLFramebufferObject(int width, int height, Attachment attachment,
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
|
||||
#else
|
||||
QOpenGLFramebufferObject(const QSize &size, Attachment attachment,
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
|
||||
QOpenGLFramebufferObject(int width, int height, Attachment attachment,
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
|
||||
#endif
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
|
||||
|
||||
QOpenGLFramebufferObject(const QSize &size, const QOpenGLFramebufferObjectFormat &format);
|
||||
QOpenGLFramebufferObject(int width, int height, const QOpenGLFramebufferObjectFormat &format);
|
||||
|
@ -59,12 +59,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_OPENGL_ES
|
||||
#define DEFAULT_FORMAT GL_RGBA8
|
||||
#else
|
||||
#define DEFAULT_FORMAT GL_RGBA
|
||||
#endif
|
||||
|
||||
class QOpenGLFramebufferObjectFormatPrivate
|
||||
{
|
||||
public:
|
||||
@ -73,9 +67,13 @@ public:
|
||||
samples(0),
|
||||
attachment(QOpenGLFramebufferObject::NoAttachment),
|
||||
target(GL_TEXTURE_2D),
|
||||
internal_format(DEFAULT_FORMAT),
|
||||
mipmap(false)
|
||||
{
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
#else
|
||||
internal_format = GL_RGBA;
|
||||
#endif
|
||||
}
|
||||
QOpenGLFramebufferObjectFormatPrivate
|
||||
(const QOpenGLFramebufferObjectFormatPrivate *other)
|
||||
|
@ -249,98 +249,98 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
|
||||
|
||||
static int qt_gl_resolve_features()
|
||||
{
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
int features = QOpenGLFunctions::Multitexture |
|
||||
QOpenGLFunctions::Shaders |
|
||||
QOpenGLFunctions::Buffers |
|
||||
QOpenGLFunctions::Framebuffers |
|
||||
QOpenGLFunctions::BlendColor |
|
||||
QOpenGLFunctions::BlendEquation |
|
||||
QOpenGLFunctions::BlendEquationSeparate |
|
||||
QOpenGLFunctions::BlendFuncSeparate |
|
||||
QOpenGLFunctions::BlendSubtract |
|
||||
QOpenGLFunctions::CompressedTextures |
|
||||
QOpenGLFunctions::Multisample |
|
||||
QOpenGLFunctions::StencilSeparate;
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (extensions.match("GL_IMG_texture_npot"))
|
||||
features |= QOpenGLFunctions::NPOTTextures;
|
||||
if (extensions.match("GL_OES_texture_npot"))
|
||||
features |= QOpenGLFunctions::NPOTTextures |
|
||||
QOpenGLFunctions::NPOTTextureRepeat;
|
||||
return features;
|
||||
#elif defined(QT_OPENGL_ES)
|
||||
int features = QOpenGLFunctions::Multitexture |
|
||||
QOpenGLFunctions::Buffers |
|
||||
QOpenGLFunctions::CompressedTextures |
|
||||
QOpenGLFunctions::Multisample;
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (extensions.match("GL_OES_framebuffer_object"))
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_OES_blend_equation_separate"))
|
||||
features |= QOpenGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_OES_blend_func_separate"))
|
||||
features |= QOpenGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_OES_blend_subtract"))
|
||||
features |= QOpenGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_OES_texture_npot"))
|
||||
features |= QOpenGLFunctions::NPOTTextures;
|
||||
if (extensions.match("GL_IMG_texture_npot"))
|
||||
features |= QOpenGLFunctions::NPOTTextures;
|
||||
return features;
|
||||
#else
|
||||
int features = 0;
|
||||
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES2) {
|
||||
int features = QOpenGLFunctions::Multitexture |
|
||||
QOpenGLFunctions::Shaders |
|
||||
QOpenGLFunctions::Buffers |
|
||||
QOpenGLFunctions::Framebuffers |
|
||||
QOpenGLFunctions::BlendColor |
|
||||
QOpenGLFunctions::BlendEquation |
|
||||
QOpenGLFunctions::BlendEquationSeparate |
|
||||
QOpenGLFunctions::BlendFuncSeparate |
|
||||
QOpenGLFunctions::BlendSubtract |
|
||||
QOpenGLFunctions::CompressedTextures |
|
||||
QOpenGLFunctions::Multisample |
|
||||
QOpenGLFunctions::StencilSeparate;
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (extensions.match("GL_IMG_texture_npot"))
|
||||
features |= QOpenGLFunctions::NPOTTextures;
|
||||
if (extensions.match("GL_OES_texture_npot"))
|
||||
features |= QOpenGLFunctions::NPOTTextures |
|
||||
QOpenGLFunctions::NPOTTextureRepeat;
|
||||
return features;
|
||||
} else if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES1) {
|
||||
int features = QOpenGLFunctions::Multitexture |
|
||||
QOpenGLFunctions::Buffers |
|
||||
QOpenGLFunctions::CompressedTextures |
|
||||
QOpenGLFunctions::Multisample;
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (extensions.match("GL_OES_framebuffer_object"))
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_OES_blend_equation_separate"))
|
||||
features |= QOpenGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_OES_blend_func_separate"))
|
||||
features |= QOpenGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_OES_blend_subtract"))
|
||||
features |= QOpenGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_OES_texture_npot"))
|
||||
features |= QOpenGLFunctions::NPOTTextures;
|
||||
if (extensions.match("GL_IMG_texture_npot"))
|
||||
features |= QOpenGLFunctions::NPOTTextures;
|
||||
return features;
|
||||
} else {
|
||||
int features = 0;
|
||||
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
|
||||
// Recognize features by extension name.
|
||||
if (extensions.match("GL_ARB_multitexture"))
|
||||
features |= QOpenGLFunctions::Multitexture;
|
||||
if (extensions.match("GL_ARB_shader_objects"))
|
||||
features |= QOpenGLFunctions::Shaders;
|
||||
if (extensions.match("GL_EXT_framebuffer_object") ||
|
||||
// Recognize features by extension name.
|
||||
if (extensions.match("GL_ARB_multitexture"))
|
||||
features |= QOpenGLFunctions::Multitexture;
|
||||
if (extensions.match("GL_ARB_shader_objects"))
|
||||
features |= QOpenGLFunctions::Shaders;
|
||||
if (extensions.match("GL_EXT_framebuffer_object") ||
|
||||
extensions.match("GL_ARB_framebuffer_object"))
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_EXT_blend_color"))
|
||||
features |= QOpenGLFunctions::BlendColor;
|
||||
if (extensions.match("GL_EXT_blend_equation_separate"))
|
||||
features |= QOpenGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_EXT_blend_func_separate"))
|
||||
features |= QOpenGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_EXT_blend_subtract"))
|
||||
features |= QOpenGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_ARB_texture_compression"))
|
||||
features |= QOpenGLFunctions::CompressedTextures;
|
||||
if (extensions.match("GL_ARB_multisample"))
|
||||
features |= QOpenGLFunctions::Multisample;
|
||||
if (extensions.match("GL_ARB_texture_non_power_of_two"))
|
||||
features |= QOpenGLFunctions::NPOTTextures;
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_EXT_blend_color"))
|
||||
features |= QOpenGLFunctions::BlendColor;
|
||||
if (extensions.match("GL_EXT_blend_equation_separate"))
|
||||
features |= QOpenGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_EXT_blend_func_separate"))
|
||||
features |= QOpenGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_EXT_blend_subtract"))
|
||||
features |= QOpenGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_ARB_texture_compression"))
|
||||
features |= QOpenGLFunctions::CompressedTextures;
|
||||
if (extensions.match("GL_ARB_multisample"))
|
||||
features |= QOpenGLFunctions::Multisample;
|
||||
if (extensions.match("GL_ARB_texture_non_power_of_two"))
|
||||
features |= QOpenGLFunctions::NPOTTextures;
|
||||
|
||||
// assume version 2.0 or higher
|
||||
features |= QOpenGLFunctions::BlendColor |
|
||||
QOpenGLFunctions::BlendEquation |
|
||||
QOpenGLFunctions::Multitexture |
|
||||
QOpenGLFunctions::CompressedTextures |
|
||||
QOpenGLFunctions::Multisample |
|
||||
QOpenGLFunctions::BlendFuncSeparate |
|
||||
QOpenGLFunctions::Buffers |
|
||||
QOpenGLFunctions::Shaders |
|
||||
QOpenGLFunctions::StencilSeparate |
|
||||
QOpenGLFunctions::BlendEquationSeparate |
|
||||
QOpenGLFunctions::NPOTTextures;
|
||||
// assume version 2.0 or higher
|
||||
features |= QOpenGLFunctions::BlendColor |
|
||||
QOpenGLFunctions::BlendEquation |
|
||||
QOpenGLFunctions::Multitexture |
|
||||
QOpenGLFunctions::CompressedTextures |
|
||||
QOpenGLFunctions::Multisample |
|
||||
QOpenGLFunctions::BlendFuncSeparate |
|
||||
QOpenGLFunctions::Buffers |
|
||||
QOpenGLFunctions::Shaders |
|
||||
QOpenGLFunctions::StencilSeparate |
|
||||
QOpenGLFunctions::BlendEquationSeparate |
|
||||
QOpenGLFunctions::NPOTTextures;
|
||||
|
||||
if (format.majorVersion() >= 3)
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
if (format.majorVersion() >= 3)
|
||||
features |= QOpenGLFunctions::Framebuffers;
|
||||
|
||||
const QPair<int, int> version = format.version();
|
||||
if (version < qMakePair(3, 0)
|
||||
const QPair<int, int> version = format.version();
|
||||
if (version < qMakePair(3, 0)
|
||||
|| (version == qMakePair(3, 0) && format.testOption(QSurfaceFormat::DeprecatedFunctions))
|
||||
|| (version == qMakePair(3, 1) && extensions.match("GL_ARB_compatibility"))
|
||||
|| (version >= qMakePair(3, 2) && format.profile() == QSurfaceFormat::CompatibilityProfile)) {
|
||||
features |= QOpenGLFunctions::FixedFunctionPipeline;
|
||||
features |= QOpenGLFunctions::FixedFunctionPipeline;
|
||||
}
|
||||
return features;
|
||||
}
|
||||
return features;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int qt_gl_resolve_extensions()
|
||||
@ -350,38 +350,38 @@ static int qt_gl_resolve_extensions()
|
||||
if (extensionMatcher.match("GL_EXT_bgra"))
|
||||
extensions |= QOpenGLExtensions::BGRATextureFormat;
|
||||
|
||||
#if defined(QT_OPENGL_ES)
|
||||
if (extensionMatcher.match("GL_OES_mapbuffer"))
|
||||
extensions |= QOpenGLExtensions::MapBuffer;
|
||||
if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
|
||||
extensions |= QOpenGLExtensions::PackedDepthStencil;
|
||||
if (extensionMatcher.match("GL_OES_element_index_uint"))
|
||||
extensions |= QOpenGLExtensions::ElementIndexUint;
|
||||
if (extensionMatcher.match("GL_OES_depth24"))
|
||||
extensions |= QOpenGLExtensions::Depth24;
|
||||
// TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
|
||||
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
|
||||
extensions |= QOpenGLExtensions::BGRATextureFormat;
|
||||
#else
|
||||
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
|
||||
extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
|
||||
|
||||
// Recognize features by extension name.
|
||||
if (format.majorVersion() >= 3
|
||||
|| extensionMatcher.match("GL_ARB_framebuffer_object"))
|
||||
{
|
||||
extensions |= QOpenGLExtensions::FramebufferMultisample |
|
||||
QOpenGLExtensions::FramebufferBlit |
|
||||
QOpenGLExtensions::PackedDepthStencil;
|
||||
} else {
|
||||
if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
|
||||
extensions |= QOpenGLExtensions::FramebufferMultisample;
|
||||
if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
|
||||
extensions |= QOpenGLExtensions::FramebufferBlit;
|
||||
if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
if (extensionMatcher.match("GL_OES_mapbuffer"))
|
||||
extensions |= QOpenGLExtensions::MapBuffer;
|
||||
if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
|
||||
extensions |= QOpenGLExtensions::PackedDepthStencil;
|
||||
if (extensionMatcher.match("GL_OES_element_index_uint"))
|
||||
extensions |= QOpenGLExtensions::ElementIndexUint;
|
||||
if (extensionMatcher.match("GL_OES_depth24"))
|
||||
extensions |= QOpenGLExtensions::Depth24;
|
||||
// TODO: Consider matching GL_APPLE_texture_format_BGRA8888 as well, but it needs testing.
|
||||
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
|
||||
extensions |= QOpenGLExtensions::BGRATextureFormat;
|
||||
} else {
|
||||
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
|
||||
extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
|
||||
|
||||
// Recognize features by extension name.
|
||||
if (format.majorVersion() >= 3
|
||||
|| extensionMatcher.match("GL_ARB_framebuffer_object"))
|
||||
{
|
||||
extensions |= QOpenGLExtensions::FramebufferMultisample |
|
||||
QOpenGLExtensions::FramebufferBlit |
|
||||
QOpenGLExtensions::PackedDepthStencil;
|
||||
} else {
|
||||
if (extensionMatcher.match("GL_EXT_framebuffer_multisample"))
|
||||
extensions |= QOpenGLExtensions::FramebufferMultisample;
|
||||
if (extensionMatcher.match("GL_EXT_framebuffer_blit"))
|
||||
extensions |= QOpenGLExtensions::FramebufferBlit;
|
||||
if (extensionMatcher.match("GL_EXT_packed_depth_stencil"))
|
||||
extensions |= QOpenGLExtensions::PackedDepthStencil;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return extensions;
|
||||
}
|
||||
|
||||
@ -2509,4 +2509,88 @@ QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx)
|
||||
GetBufferSubData = qopenglfResolveGetBufferSubData;
|
||||
}
|
||||
|
||||
#if defined(QT_OPENGL_DYNAMIC)
|
||||
extern int qgl_proxyLibraryType(void);
|
||||
extern HMODULE qgl_glHandle(void);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\enum QOpenGLFunctions::PlatformGLType
|
||||
This enum defines the type of the underlying GL implementation.
|
||||
|
||||
\value DesktopGL Desktop OpenGL
|
||||
\value GLES2 OpenGL ES 2.0 or higher
|
||||
\value GLES1 OpenGL ES 1.x
|
||||
|
||||
\since 5.3
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QOpenGLFunctions::isES()
|
||||
|
||||
On platforms where the OpenGL implementation is dynamically loaded
|
||||
this function returns true if the underlying GL implementation is
|
||||
Open GL ES.
|
||||
|
||||
On platforms that do not use runtime loading of the GL the return
|
||||
value is based on Qt's compile-time configuration and will never
|
||||
change during runtime.
|
||||
|
||||
\sa platformGLType()
|
||||
|
||||
\since 5.3
|
||||
*/
|
||||
|
||||
/*!
|
||||
Returns the underlying GL implementation type.
|
||||
|
||||
On platforms where the OpenGL implementation is not dynamically
|
||||
loaded, the return value is determined during compile time and never
|
||||
changes.
|
||||
|
||||
Platforms that use dynamic GL loading (e.g. Windows) cannot rely on
|
||||
compile-time defines for differentiating between desktop and ES
|
||||
OpenGL code. Instead, they rely on this function to query, during
|
||||
runtime, the type of the loaded graphics library.
|
||||
|
||||
\since 5.3
|
||||
*/
|
||||
QOpenGLFunctions::PlatformGLType QOpenGLFunctions::platformGLType()
|
||||
{
|
||||
#if defined(QT_OPENGL_DYNAMIC)
|
||||
return PlatformGLType(qgl_proxyLibraryType());
|
||||
#elif defined(QT_OPENGL_ES_2)
|
||||
return GLES2;
|
||||
#elif defined(QT_OPENGL_ES)
|
||||
return GLES1;
|
||||
#else
|
||||
return DesktopGL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the platform-specific handle for the OpenGL implementation that
|
||||
is currently in use. (for example, a HMODULE on Windows)
|
||||
|
||||
On platforms that do not use dynamic GL switch the return value is null.
|
||||
|
||||
The library might be GL-only, meaning that windowing system interface
|
||||
functions (for example EGL) may live in another, separate library.
|
||||
|
||||
Always use platformGLType() before resolving any functions to check if the
|
||||
library implements desktop OpenGL or OpenGL ES.
|
||||
|
||||
\sa platformGLType()
|
||||
|
||||
\since 5.3
|
||||
*/
|
||||
void *QOpenGLFunctions::platformGLHandle()
|
||||
{
|
||||
#if defined(QT_OPENGL_DYNAMIC)
|
||||
return qgl_glHandle();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -311,6 +311,15 @@ public:
|
||||
void glVertexAttrib4fv(GLuint indx, const GLfloat* values);
|
||||
void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
|
||||
|
||||
enum PlatformGLType {
|
||||
DesktopGL = 0,
|
||||
GLES2,
|
||||
GLES1
|
||||
};
|
||||
static PlatformGLType platformGLType();
|
||||
static void *platformGLHandle();
|
||||
static bool isES() { return platformGLType() != DesktopGL; }
|
||||
|
||||
protected:
|
||||
QOpenGLFunctionsPrivate *d_ptr;
|
||||
static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
|
||||
@ -322,7 +331,6 @@ struct QOpenGLFunctionsPrivate
|
||||
{
|
||||
QOpenGLFunctionsPrivate(QOpenGLContext *ctx);
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture);
|
||||
void (QOPENGLF_APIENTRYP AttachShader)(GLuint program, GLuint shader);
|
||||
void (QOPENGLF_APIENTRYP BindAttribLocation)(GLuint program, GLuint index, const char* name);
|
||||
@ -418,7 +426,6 @@ struct QOpenGLFunctionsPrivate
|
||||
void (QOPENGLF_APIENTRYP VertexAttrib4f)(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
||||
void (QOPENGLF_APIENTRYP VertexAttrib4fv)(GLuint indx, const GLfloat* values);
|
||||
void (QOPENGLF_APIENTRYP VertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
|
||||
#endif
|
||||
};
|
||||
|
||||
inline void QOpenGLFunctions::glActiveTexture(GLenum texture)
|
||||
|
@ -220,14 +220,14 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
|
||||
if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size)
|
||||
currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio);
|
||||
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
|
||||
// we emulate GL_REPEAT by only taking the fractional part of the texture coords
|
||||
// in the qopenglslTextureBrushSrcFragmentShader program.
|
||||
GLuint wrapMode = GL_CLAMP_TO_EDGE;
|
||||
#else
|
||||
GLuint wrapMode = GL_REPEAT;
|
||||
#endif
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
|
||||
// we emulate GL_REPEAT by only taking the fractional part of the texture coords
|
||||
// in the qopenglslTextureBrushSrcFragmentShader program.
|
||||
wrapMode = GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
|
||||
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
|
||||
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushPixmap);
|
||||
updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
|
||||
@ -542,36 +542,38 @@ void QOpenGL2PaintEngineEx::beginNativePainting()
|
||||
d->funcs.glDisableVertexAttribArray(i);
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
Q_ASSERT(QOpenGLContext::currentContext());
|
||||
const QOpenGLContext *ctx = d->ctx;
|
||||
const QSurfaceFormat &fmt = d->device->context()->format();
|
||||
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|
||||
|| (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
|
||||
|| fmt.profile() == QSurfaceFormat::CompatibilityProfile)
|
||||
{
|
||||
// be nice to people who mix OpenGL 1.x code with QPainter commands
|
||||
// by setting modelview and projection matrices to mirror the GL 1
|
||||
// paint engine
|
||||
const QTransform& mtx = state()->matrix;
|
||||
|
||||
float mv_matrix[4][4] =
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_ASSERT(QOpenGLContext::currentContext());
|
||||
const QOpenGLContext *ctx = d->ctx;
|
||||
const QSurfaceFormat &fmt = d->device->context()->format();
|
||||
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|
||||
|| (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
|
||||
|| fmt.profile() == QSurfaceFormat::CompatibilityProfile)
|
||||
{
|
||||
{ float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
|
||||
{ float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
|
||||
{ 0, 0, 1, 0 },
|
||||
{ float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
|
||||
};
|
||||
// be nice to people who mix OpenGL 1.x code with QPainter commands
|
||||
// by setting modelview and projection matrices to mirror the GL 1
|
||||
// paint engine
|
||||
const QTransform& mtx = state()->matrix;
|
||||
|
||||
const QSize sz = d->device->size();
|
||||
float mv_matrix[4][4] =
|
||||
{
|
||||
{ float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
|
||||
{ float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
|
||||
{ 0, 0, 1, 0 },
|
||||
{ float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
|
||||
};
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
|
||||
const QSize sz = d->device->size();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(&mv_matrix[0][0]);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(&mv_matrix[0][0]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // QT_OPENGL_ES_2
|
||||
|
||||
d->lastTextureUsed = GLuint(-1);
|
||||
d->dirtyStencilRegion = QRect(0, 0, d->width, d->height);
|
||||
@ -598,11 +600,11 @@ void QOpenGL2PaintEngineExPrivate::resetGLState()
|
||||
setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false);
|
||||
setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
|
||||
setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
// gl_Color, corresponding to vertex attribute 3, may have been changed
|
||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
funcs.glVertexAttrib4fv(3, color);
|
||||
#endif
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
// gl_Color, corresponding to vertex attribute 3, may have been changed
|
||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
funcs.glVertexAttrib4fv(3, color);
|
||||
}
|
||||
}
|
||||
|
||||
void QOpenGL2PaintEngineEx::endNativePainting()
|
||||
@ -1332,13 +1334,15 @@ void QOpenGL2PaintEngineEx::renderHintsChanged()
|
||||
{
|
||||
state()->renderHintsChanged = true;
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if ((state()->renderHints & QPainter::Antialiasing)
|
||||
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
else
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
#endif
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
if ((state()->renderHints & QPainter::Antialiasing)
|
||||
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
else
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
#endif // QT_OPENGL_ES_2
|
||||
|
||||
Q_D(QOpenGL2PaintEngineEx);
|
||||
d->lastTextureUsed = GLuint(-1);
|
||||
@ -2008,24 +2012,21 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev)
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
#endif
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
|
||||
d->multisamplingAlwaysEnabled = false;
|
||||
} else
|
||||
#endif // QT_OPENGL_ES_2
|
||||
{
|
||||
// OpenGL ES can't switch MSAA off, so if the gl paint device is
|
||||
// multisampled, it's always multisampled.
|
||||
d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
|
||||
}
|
||||
|
||||
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
|
||||
#endif
|
||||
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
// OpenGL ES can't switch MSAA off, so if the gl paint device is
|
||||
// multisampled, it's always multisampled.
|
||||
d->multisamplingAlwaysEnabled = d->device->context()->format().samples() > 1;
|
||||
#else
|
||||
d->multisamplingAlwaysEnabled = false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
4601
src/gui/opengl/qopenglproxy_win.cpp
Normal file
4601
src/gui/opengl/qopenglproxy_win.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -175,13 +175,15 @@ public:
|
||||
#endif
|
||||
{
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
QSurfaceFormat f = ctx->format();
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
QSurfaceFormat f = ctx->format();
|
||||
|
||||
// Geometry shaders require OpenGL >= 3.2
|
||||
if (shaderType & QOpenGLShader::Geometry)
|
||||
supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
|
||||
else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
|
||||
supportsTessellationShaders = (f.version() >= qMakePair<int, int>(4, 0));
|
||||
// Geometry shaders require OpenGL >= 3.2
|
||||
if (shaderType & QOpenGLShader::Geometry)
|
||||
supportsGeometryShaders = (f.version() >= qMakePair<int, int>(3, 2));
|
||||
else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
|
||||
supportsTessellationShaders = (f.version() >= qMakePair<int, int>(4, 0));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
~QOpenGLShaderPrivate();
|
||||
@ -441,7 +443,8 @@ bool QOpenGLShader::compileSourceCode(const char *source)
|
||||
}
|
||||
|
||||
#ifdef QOpenGL_REDEFINE_HIGHP
|
||||
if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers) {
|
||||
if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers
|
||||
&& QOpenGLFunctions::isES()) {
|
||||
src.append(redefineHighp);
|
||||
srclen.append(GLint(sizeof(redefineHighp) - 1));
|
||||
}
|
||||
@ -650,7 +653,8 @@ bool QOpenGLShaderProgram::init()
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
// Resolve OpenGL 4 functions for tessellation shader support
|
||||
QSurfaceFormat format = context->format();
|
||||
if (format.version() >= qMakePair<int, int>(4, 0)) {
|
||||
if (!QOpenGLFunctions::isES()
|
||||
&& format.version() >= qMakePair<int, int>(4, 0)) {
|
||||
d->tessellationFuncs = context->versionFunctions<QOpenGLFunctions_4_0_Core>();
|
||||
d->tessellationFuncs->initializeOpenGLFunctions();
|
||||
}
|
||||
@ -3248,14 +3252,16 @@ bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
// Geometry shaders require OpenGL 3.2 or newer
|
||||
QSurfaceFormat format = context->format();
|
||||
return (format.version() >= qMakePair<int, int>(3, 2));
|
||||
return (!QOpenGLFunctions::isES())
|
||||
&& (format.version() >= qMakePair<int, int>(3, 2));
|
||||
#else
|
||||
// No geometry shader support in OpenGL ES2
|
||||
return false;
|
||||
#endif
|
||||
} else if (type == TessellationControl || type == TessellationEvaluation) {
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
return (format.version() >= qMakePair<int, int>(4, 0));
|
||||
return (!QOpenGLFunctions::isES())
|
||||
&& (format.version() >= qMakePair<int, int>(4, 0));
|
||||
#else
|
||||
// No tessellation shader support in OpenGL ES2
|
||||
return false;
|
||||
|
@ -2406,78 +2406,87 @@ bool QOpenGLTexture::hasFeature(Feature feature)
|
||||
QSurfaceFormat f = ctx->format();
|
||||
|
||||
bool supported = false;
|
||||
switch (feature) {
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
case ImmutableMultisampleStorage:
|
||||
case TextureBuffer:
|
||||
case StencilTexturing:
|
||||
supported = f.version() >= qMakePair(4, 3);
|
||||
break;
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
switch (feature) {
|
||||
case ImmutableMultisampleStorage:
|
||||
case TextureBuffer:
|
||||
case StencilTexturing:
|
||||
supported = f.version() >= qMakePair(4, 3);
|
||||
break;
|
||||
|
||||
case ImmutableStorage:
|
||||
supported = f.version() >= qMakePair(4, 2);
|
||||
break;
|
||||
case ImmutableStorage:
|
||||
supported = f.version() >= qMakePair(4, 2);
|
||||
break;
|
||||
|
||||
case TextureCubeMapArrays:
|
||||
supported = f.version() >= qMakePair(4, 0);
|
||||
break;
|
||||
case TextureCubeMapArrays:
|
||||
supported = f.version() >= qMakePair(4, 0);
|
||||
break;
|
||||
|
||||
case Swizzle:
|
||||
supported = f.version() >= qMakePair(3, 3);
|
||||
break;
|
||||
case Swizzle:
|
||||
supported = f.version() >= qMakePair(3, 3);
|
||||
break;
|
||||
|
||||
case TextureMultisample:
|
||||
supported = f.version() >= qMakePair(3, 2);
|
||||
break;
|
||||
case TextureMultisample:
|
||||
supported = f.version() >= qMakePair(3, 2);
|
||||
break;
|
||||
|
||||
case TextureArrays:
|
||||
supported = f.version() >= qMakePair(3, 0);
|
||||
break;
|
||||
case TextureArrays:
|
||||
supported = f.version() >= qMakePair(3, 0);
|
||||
break;
|
||||
|
||||
case TextureRectangle:
|
||||
supported = f.version() >= qMakePair(2, 1);
|
||||
break;
|
||||
case TextureRectangle:
|
||||
supported = f.version() >= qMakePair(2, 1);
|
||||
break;
|
||||
|
||||
case Texture3D:
|
||||
supported = f.version() >= qMakePair(1, 3);
|
||||
break;
|
||||
case Texture3D:
|
||||
supported = f.version() >= qMakePair(1, 3);
|
||||
break;
|
||||
|
||||
case AnisotropicFiltering:
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
|
||||
break;
|
||||
case AnisotropicFiltering:
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
|
||||
break;
|
||||
|
||||
case NPOTTextures:
|
||||
case NPOTTextureRepeat:
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
|
||||
break;
|
||||
case NPOTTextures:
|
||||
case NPOTTextureRepeat:
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
|
||||
break;
|
||||
|
||||
case Texture1D:
|
||||
supported = f.version() >= qMakePair(1, 1);
|
||||
break;
|
||||
case Texture1D:
|
||||
supported = f.version() >= qMakePair(1, 1);
|
||||
break;
|
||||
|
||||
case MaxFeatureFlag:
|
||||
break;
|
||||
}
|
||||
case MaxFeatureFlag:
|
||||
break;
|
||||
|
||||
#else
|
||||
case Texture3D:
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
|
||||
break;
|
||||
case AnisotropicFiltering:
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
|
||||
break;
|
||||
case NPOTTextures:
|
||||
case NPOTTextureRepeat:
|
||||
supported = f.version() >= qMakePair(3,0);
|
||||
if (!supported) {
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
|
||||
if (!supported)
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (QOpenGLFunctions::isES())
|
||||
#endif
|
||||
{
|
||||
switch (feature) {
|
||||
case Texture3D:
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"));
|
||||
break;
|
||||
case AnisotropicFiltering:
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_filter_anisotropic"));
|
||||
break;
|
||||
case NPOTTextures:
|
||||
case NPOTTextureRepeat:
|
||||
supported = f.version() >= qMakePair(3,0);
|
||||
if (!supported) {
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_OES_texture_npot"));
|
||||
if (!supported)
|
||||
supported = ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_non_power_of_two"));
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
@ -2491,17 +2500,20 @@ bool QOpenGLTexture::hasFeature(Feature feature)
|
||||
void QOpenGLTexture::setMipBaseLevel(int baseLevel)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(baseLevel <= d->maxLevel);
|
||||
d->baseLevel = baseLevel;
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(baseLevel <= d->maxLevel);
|
||||
d->baseLevel = baseLevel;
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(baseLevel);
|
||||
qWarning("QOpenGLTexture: Mipmap base level is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Mipmap base level is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2525,17 +2537,20 @@ int QOpenGLTexture::mipBaseLevel() const
|
||||
void QOpenGLTexture::setMipMaxLevel(int maxLevel)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->baseLevel <= maxLevel);
|
||||
d->maxLevel = maxLevel;
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->baseLevel <= maxLevel);
|
||||
d->maxLevel = maxLevel;
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(maxLevel);
|
||||
qWarning("QOpenGLTexture: Mipmap max level is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Mipmap max level is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2559,18 +2574,21 @@ int QOpenGLTexture::mipMaxLevel() const
|
||||
void QOpenGLTexture::setMipLevelRange(int baseLevel, int maxLevel)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(baseLevel <= maxLevel);
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(baseLevel <= maxLevel);
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BASE_LEVEL, baseLevel);
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(baseLevel);
|
||||
Q_UNUSED(maxLevel);
|
||||
qWarning("QOpenGLTexture: Mipmap level range is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Mipmap level range is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2666,21 +2684,24 @@ void QOpenGLTexture::generateMipMaps(int baseLevel, bool resetBaseLevel)
|
||||
void QOpenGLTexture::setSwizzleMask(SwizzleComponent component, SwizzleValue value)
|
||||
{
|
||||
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
if (!d->features.testFlag(Swizzle)) {
|
||||
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
if (!d->features.testFlag(Swizzle)) {
|
||||
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
|
||||
return;
|
||||
}
|
||||
d->swizzleMask[component - SwizzleRed] = value;
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
|
||||
return;
|
||||
}
|
||||
d->swizzleMask[component - SwizzleRed] = value;
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, component, value);
|
||||
#else
|
||||
Q_UNUSED(component);
|
||||
Q_UNUSED(value);
|
||||
qWarning("QOpenGLTexture: Texture swizzling is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Texture swizzling is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2690,27 +2711,30 @@ void QOpenGLTexture::setSwizzleMask(SwizzleValue r, SwizzleValue g,
|
||||
SwizzleValue b, SwizzleValue a)
|
||||
{
|
||||
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
if (!d->features.testFlag(Swizzle)) {
|
||||
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
if (!d->features.testFlag(Swizzle)) {
|
||||
qWarning("QOpenGLTexture::setSwizzleMask() requires OpenGL >= 3.3");
|
||||
return;
|
||||
}
|
||||
GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
|
||||
d->swizzleMask[0] = r;
|
||||
d->swizzleMask[1] = g;
|
||||
d->swizzleMask[2] = b;
|
||||
d->swizzleMask[3] = a;
|
||||
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
return;
|
||||
}
|
||||
GLint swizzleMask[] = {GLint(r), GLint(g), GLint(b), GLint(a)};
|
||||
d->swizzleMask[0] = r;
|
||||
d->swizzleMask[1] = g;
|
||||
d->swizzleMask[2] = b;
|
||||
d->swizzleMask[3] = a;
|
||||
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask);
|
||||
#else
|
||||
Q_UNUSED(r);
|
||||
Q_UNUSED(g);
|
||||
Q_UNUSED(b);
|
||||
Q_UNUSED(a);
|
||||
qWarning("QOpenGLTexture: Texture swizzling is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Texture swizzling is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2736,20 +2760,23 @@ QOpenGLTexture::SwizzleValue QOpenGLTexture::swizzleMask(SwizzleComponent compon
|
||||
void QOpenGLTexture::setDepthStencilMode(QOpenGLTexture::DepthStencilMode mode)
|
||||
{
|
||||
#if !defined(Q_OS_MAC) && !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
if (!d->features.testFlag(StencilTexturing)) {
|
||||
qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
if (!d->features.testFlag(StencilTexturing)) {
|
||||
qWarning("QOpenGLTexture::setDepthStencilMode() requires OpenGL >= 4.3");
|
||||
return;
|
||||
}
|
||||
d->depthStencilMode = mode;
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
|
||||
return;
|
||||
}
|
||||
d->depthStencilMode = mode;
|
||||
d->texFuncs->glTextureParameteri(d->textureId, d->target, d->bindingTarget, GL_DEPTH_STENCIL_TEXTURE_MODE, mode);
|
||||
#else
|
||||
Q_UNUSED(mode);
|
||||
qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: DepthStencil Mode is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2923,23 +2950,26 @@ QOpenGLTexture::WrapMode QOpenGLTexture::wrapMode(QOpenGLTexture::CoordinateDire
|
||||
void QOpenGLTexture::setBorderColor(QColor color)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
float values[4];
|
||||
values[0] = color.redF();
|
||||
values[1] = color.greenF();
|
||||
values[2] = color.blueF();
|
||||
values[3] = color.alphaF();
|
||||
d->borderColor.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
d->borderColor.append(QVariant(values[i]));
|
||||
d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
float values[4];
|
||||
values[0] = color.redF();
|
||||
values[1] = color.greenF();
|
||||
values[2] = color.blueF();
|
||||
values[3] = color.alphaF();
|
||||
d->borderColor.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
d->borderColor.append(QVariant(values[i]));
|
||||
d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(color);
|
||||
qWarning("QOpenGLTexture: Border color is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Border color is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2948,26 +2978,29 @@ void QOpenGLTexture::setBorderColor(QColor color)
|
||||
void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
float values[4];
|
||||
values[0] = r;
|
||||
values[1] = g;
|
||||
values[2] = b;
|
||||
values[3] = a;
|
||||
d->borderColor.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
d->borderColor.append(QVariant(values[i]));
|
||||
d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
float values[4];
|
||||
values[0] = r;
|
||||
values[1] = g;
|
||||
values[2] = b;
|
||||
values[3] = a;
|
||||
d->borderColor.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
d->borderColor.append(QVariant(values[i]));
|
||||
d->texFuncs->glTextureParameterfv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(r);
|
||||
Q_UNUSED(g);
|
||||
Q_UNUSED(b);
|
||||
Q_UNUSED(a);
|
||||
qWarning("QOpenGLTexture: Border color is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Border color is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2976,26 +3009,29 @@ void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
|
||||
void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
int values[4];
|
||||
values[0] = r;
|
||||
values[1] = g;
|
||||
values[2] = b;
|
||||
values[3] = a;
|
||||
d->borderColor.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
d->borderColor.append(QVariant(values[i]));
|
||||
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
int values[4];
|
||||
values[0] = r;
|
||||
values[1] = g;
|
||||
values[2] = b;
|
||||
values[3] = a;
|
||||
d->borderColor.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
d->borderColor.append(QVariant(values[i]));
|
||||
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(r);
|
||||
Q_UNUSED(g);
|
||||
Q_UNUSED(b);
|
||||
Q_UNUSED(a);
|
||||
qWarning("QOpenGLTexture: Border color is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Border color is not supported");
|
||||
|
||||
// TODO Handle case of using glTextureParameterIiv() based on format
|
||||
}
|
||||
@ -3006,26 +3042,29 @@ void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
|
||||
void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
int values[4];
|
||||
values[0] = int(r);
|
||||
values[1] = int(g);
|
||||
values[2] = int(b);
|
||||
values[3] = int(a);
|
||||
d->borderColor.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
d->borderColor.append(QVariant(values[i]));
|
||||
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
int values[4];
|
||||
values[0] = int(r);
|
||||
values[1] = int(g);
|
||||
values[2] = int(b);
|
||||
values[3] = int(a);
|
||||
d->borderColor.clear();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
d->borderColor.append(QVariant(values[i]));
|
||||
d->texFuncs->glTextureParameteriv(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_BORDER_COLOR, values);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(r);
|
||||
Q_UNUSED(g);
|
||||
Q_UNUSED(b);
|
||||
Q_UNUSED(a);
|
||||
qWarning("QOpenGLTexture: Border color is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Border color is not supported");
|
||||
|
||||
// TODO Handle case of using glTextureParameterIuiv() based on format
|
||||
}
|
||||
@ -3109,17 +3148,20 @@ void QOpenGLTexture::borderColor(unsigned int *border) const
|
||||
void QOpenGLTexture::setMinimumLevelOfDetail(float value)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(value < d->maxLevelOfDetail);
|
||||
d->minLevelOfDetail = value;
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(value < d->maxLevelOfDetail);
|
||||
d->minLevelOfDetail = value;
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, value);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(value);
|
||||
qWarning("QOpenGLTexture: Detail level is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Detail level is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3143,17 +3185,20 @@ float QOpenGLTexture::minimumLevelOfDetail() const
|
||||
void QOpenGLTexture::setMaximumLevelOfDetail(float value)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(value > d->minLevelOfDetail);
|
||||
d->maxLevelOfDetail = value;
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(value > d->minLevelOfDetail);
|
||||
d->maxLevelOfDetail = value;
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, value);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(value);
|
||||
qWarning("QOpenGLTexture: Detail level is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Detail level is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3176,20 +3221,23 @@ float QOpenGLTexture::maximumLevelOfDetail() const
|
||||
void QOpenGLTexture::setLevelOfDetailRange(float min, float max)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(min < max);
|
||||
d->minLevelOfDetail = min;
|
||||
d->maxLevelOfDetail = max;
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
Q_ASSERT(min < max);
|
||||
d->minLevelOfDetail = min;
|
||||
d->maxLevelOfDetail = max;
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MIN_LOD, min);
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_MAX_LOD, max);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(min);
|
||||
Q_UNUSED(max);
|
||||
qWarning("QOpenGLTexture: Detail level is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Detail level is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -3212,16 +3260,19 @@ QPair<float, float> QOpenGLTexture::levelOfDetailRange() const
|
||||
void QOpenGLTexture::setLevelofDetailBias(float bias)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
d->levelOfDetailBias = bias;
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QOpenGLTexture);
|
||||
d->create();
|
||||
Q_ASSERT(d->texFuncs);
|
||||
Q_ASSERT(d->textureId);
|
||||
d->levelOfDetailBias = bias;
|
||||
d->texFuncs->glTextureParameterf(d->textureId, d->target, d->bindingTarget, GL_TEXTURE_LOD_BIAS, bias);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(bias);
|
||||
qWarning("QOpenGLTexture: Detail level is not supported");
|
||||
#endif
|
||||
qWarning("QOpenGLTexture: Detail level is not supported");
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -328,8 +328,11 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
|
||||
if (mask.format() == QImage::Format_RGB32
|
||||
// We need to make the alpha component equal to the average of the RGB values.
|
||||
// This is needed when drawing sub-pixel antialiased text on translucent targets.
|
||||
#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
|| mask.format() == QImage::Format_ARGB32_Premultiplied
|
||||
#else
|
||||
|| (mask.format() == QImage::Format_ARGB32_Premultiplied
|
||||
&& QOpenGLFunctions::isES())
|
||||
#endif
|
||||
) {
|
||||
for (int y = 0; y < maskHeight; ++y) {
|
||||
@ -345,10 +348,11 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
|
||||
avg = qAlpha(src[x]);
|
||||
|
||||
src[x] = qRgba(r, g, b, avg);
|
||||
#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
// swizzle the bits to accommodate for the GL_RGBA upload.
|
||||
src[x] = ARGB2RGBA(src[x]);
|
||||
#if Q_BYTE_ORDER != Q_BIG_ENDIAN
|
||||
if (QOpenGLFunctions::isES())
|
||||
#endif
|
||||
src[x] = ARGB2RGBA(src[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -356,11 +360,16 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
if (mask.depth() == 32) {
|
||||
#if defined(QT_OPENGL_ES_2) || Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mask.bits());
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
GLenum fmt = GL_RGBA;
|
||||
#else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
|
||||
GLenum fmt = QOpenGLFunctions::isES() ? GL_RGBA : GL_BGRA;
|
||||
#endif // QT_OPENGL_ES_2
|
||||
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
fmt = GL_RGBA;
|
||||
#endif
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, fmt, GL_UNSIGNED_BYTE, mask.bits());
|
||||
} else {
|
||||
// glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
|
||||
// not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
|
||||
|
@ -42,14 +42,15 @@
|
||||
#include "qopengltexturehelper_p.h"
|
||||
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
|
||||
{
|
||||
// Resolve EXT_direct_state_access entry points if present
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
|
||||
if (!QOpenGLFunctions::isES()
|
||||
&& context->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) {
|
||||
TextureParameteriEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLint )>(context->getProcAddress(QByteArrayLiteral("glTextureParameteriEXT")));
|
||||
TextureParameterivEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , const GLint *)>(context->getProcAddress(QByteArrayLiteral("glTextureParameterivEXT")));
|
||||
TextureParameterfEXT = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLenum , GLfloat )>(context->getProcAddress(QByteArrayLiteral("glTextureParameterfEXT")));
|
||||
@ -97,7 +98,6 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
|
||||
CompressedTextureImage2D = &QOpenGLTextureHelper::dsa_CompressedTextureImage2D;
|
||||
CompressedTextureImage3D = &QOpenGLTextureHelper::dsa_CompressedTextureImage3D;
|
||||
} else {
|
||||
#endif
|
||||
// Use our own DSA emulation
|
||||
TextureParameteri = &QOpenGLTextureHelper::qt_TextureParameteri;
|
||||
TextureParameteriv = &QOpenGLTextureHelper::qt_TextureParameteriv;
|
||||
@ -119,31 +119,28 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
|
||||
CompressedTextureImage1D = &QOpenGLTextureHelper::qt_CompressedTextureImage1D;
|
||||
CompressedTextureImage2D = &QOpenGLTextureHelper::qt_CompressedTextureImage2D;
|
||||
CompressedTextureImage3D = &QOpenGLTextureHelper::qt_CompressedTextureImage3D;
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Some DSA functions are part of NV_texture_multisample instead
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
|
||||
if (!QOpenGLFunctions::isES()
|
||||
&& context->hasExtension(QByteArrayLiteral("GL_NV_texture_multisample"))) {
|
||||
TextureImage3DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(QByteArrayLiteral("glTextureImage3DMultisampleNV")));
|
||||
TextureImage2DMultisampleNV = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLsizei , GLint , GLsizei , GLsizei , GLboolean )>(context->getProcAddress(QByteArrayLiteral("glTextureImage2DMultisampleNV")));
|
||||
|
||||
TextureImage3DMultisample = &QOpenGLTextureHelper::dsa_TextureImage3DMultisample;
|
||||
TextureImage2DMultisample = &QOpenGLTextureHelper::dsa_TextureImage2DMultisample;
|
||||
} else {
|
||||
#endif
|
||||
TextureImage3DMultisample = &QOpenGLTextureHelper::qt_TextureImage3DMultisample;
|
||||
TextureImage2DMultisample = &QOpenGLTextureHelper::qt_TextureImage2DMultisample;
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
}
|
||||
#endif
|
||||
|
||||
// wglGetProcAddress should not be used to (and indeed will not) load OpenGL <= 1.1 functions.
|
||||
// Hence, we resolve them "the hard way"
|
||||
|
||||
#if defined(Q_OS_WIN) && !defined(QT_OPENGL_ES_2)
|
||||
HMODULE handle = GetModuleHandleA("opengl32.dll");
|
||||
HMODULE handle = static_cast<HMODULE>(QOpenGLFunctions::platformGLHandle());
|
||||
if (!handle)
|
||||
handle = GetModuleHandleA("opengl32.dll");
|
||||
|
||||
// OpenGL 1.0
|
||||
GetIntegerv = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint *)>(GetProcAddress(handle, QByteArrayLiteral("glGetIntegerv")));
|
||||
@ -194,15 +191,12 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
|
||||
TexSubImage1D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage1D")));
|
||||
#endif
|
||||
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
if (context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
|
||||
if (QOpenGLFunctions::isES() && context->hasExtension(QByteArrayLiteral("GL_OES_texture_3D"))) {
|
||||
TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexImage3DOES")));
|
||||
TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3DOES")));
|
||||
CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES")));
|
||||
CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES")));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
// OpenGL 1.2
|
||||
TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D")));
|
||||
TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D")));
|
||||
@ -239,8 +233,6 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context)
|
||||
TextureView = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLuint , GLenum , GLuint , GLenum , GLuint , GLuint , GLuint , GLuint )>(context->getProcAddress(QByteArrayLiteral("glTextureView")));
|
||||
}
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
|
||||
void QOpenGLTextureHelper::dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
|
||||
{
|
||||
Q_UNUSED(bindingTarget);
|
||||
@ -385,8 +377,6 @@ void QOpenGLTextureHelper::dsa_CompressedTextureImage3D(GLuint texture, GLenum t
|
||||
CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits);
|
||||
}
|
||||
|
||||
#endif // !defined(QT_OPENGL_ES_2)
|
||||
|
||||
void QOpenGLTextureHelper::qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param)
|
||||
{
|
||||
GLint oldTexture;
|
||||
|
@ -256,7 +256,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
// DSA wrapper (so we can use pointer to member function as switch)
|
||||
void dsa_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
|
||||
|
||||
@ -332,7 +331,6 @@ private:
|
||||
void dsa_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level,
|
||||
GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLsizei imageSize, const GLvoid *bits);
|
||||
#endif
|
||||
|
||||
// DSA emulation API
|
||||
void qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param);
|
||||
@ -749,7 +747,6 @@ private:
|
||||
CompressedTextureImage2DMemberFunc CompressedTextureImage2D;
|
||||
CompressedTextureImage3DMemberFunc CompressedTextureImage3D;
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
// Raw function pointers for core and DSA functions
|
||||
|
||||
// EXT_direct_state_access used when DSA is available
|
||||
@ -780,7 +777,6 @@ private:
|
||||
// Plus some missing ones that are in the NV_texture_multisample extension instead
|
||||
void (QOPENGLF_APIENTRYP TextureImage3DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations);
|
||||
void (QOPENGLF_APIENTRYP TextureImage2DMultisampleNV)(GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
|
||||
#endif
|
||||
|
||||
// OpenGL 1.0
|
||||
void (QOPENGLF_APIENTRYP GetIntegerv)(GLenum pname, GLint *params);
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "qopenglqueryhelper_p.h"
|
||||
#include <QtCore/private/qobject_p.h>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
#include <QtGui/QOpenGLFunctions>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -123,6 +124,11 @@ public:
|
||||
|
||||
bool QOpenGLTimerQueryPrivate::create()
|
||||
{
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
qWarning("QOpenGLTimerQuery: Not supported on dynamic GL ES");
|
||||
return false;
|
||||
}
|
||||
|
||||
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
||||
|
||||
if (timer && context == ctx)
|
||||
|
@ -43,6 +43,7 @@
|
||||
|
||||
#include <QtCore/private/qobject_p.h>
|
||||
#include <QtGui/qopenglcontext.h>
|
||||
#include <QtGui/qopenglfunctions.h>
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
#include <QtGui/qopenglfunctions_3_0.h>
|
||||
@ -156,6 +157,13 @@ bool QOpenGLVertexArrayObjectPrivate::create()
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
qWarning("QOpenGLVertexArrayObject: Not supported on dynamic GL ES");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_Q(QOpenGLVertexArrayObject);
|
||||
if (context)
|
||||
QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
|
||||
|
@ -163,7 +163,10 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context)
|
||||
code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader;
|
||||
code[CustomImageSrcFragmentShader] = qglslCustomSrcFragmentShader; // Calls "customShader", which must be appended
|
||||
code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader;
|
||||
code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader;
|
||||
if (!QOpenGLFunctions::isES())
|
||||
code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_desktop;
|
||||
else
|
||||
code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_ES;
|
||||
code[TextureBrushSrcWithPatternFragmentShader] = qglslTextureBrushSrcWithPatternFragmentShader;
|
||||
code[PatternBrushSrcFragmentShader] = qglslPatternBrushSrcFragmentShader;
|
||||
code[LinearGradientBrushSrcFragmentShader] = qglslLinearGradientBrushSrcFragmentShader;
|
||||
|
@ -305,25 +305,23 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
|
||||
static const char* const qglslAffinePositionWithTextureBrushVertexShader
|
||||
= qglslPositionWithTextureBrushVertexShader;
|
||||
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
// OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead,
|
||||
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
|
||||
// TODO: Special case POT textures which don't need this emulation
|
||||
static const char* const qglslTextureBrushSrcFragmentShader = "\n\
|
||||
static const char* const qglslTextureBrushSrcFragmentShader_ES = "\n\
|
||||
varying highp vec2 brushTextureCoords; \n\
|
||||
uniform sampler2D brushTexture; \n\
|
||||
lowp vec4 srcPixel() { \n\
|
||||
return texture2D(brushTexture, fract(brushTextureCoords)); \n\
|
||||
}\n";
|
||||
#else
|
||||
static const char* const qglslTextureBrushSrcFragmentShader = "\n\
|
||||
|
||||
static const char* const qglslTextureBrushSrcFragmentShader_desktop = "\n\
|
||||
varying highp vec2 brushTextureCoords; \n\
|
||||
uniform sampler2D brushTexture; \n\
|
||||
lowp vec4 srcPixel() \n\
|
||||
{ \n\
|
||||
return texture2D(brushTexture, brushTextureCoords); \n\
|
||||
}\n";
|
||||
#endif
|
||||
|
||||
static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\
|
||||
varying highp vec2 brushTextureCoords; \n\
|
||||
|
@ -539,33 +539,35 @@ void QGL2PaintEngineEx::beginNativePainting()
|
||||
d->funcs.glDisableVertexAttribArray(i);
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
const QGLContext *ctx = d->ctx;
|
||||
const QGLFormat &fmt = d->device->format();
|
||||
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|
||||
|| (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->contextHandle()->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
|
||||
|| fmt.profile() == QGLFormat::CompatibilityProfile)
|
||||
{
|
||||
// be nice to people who mix OpenGL 1.x code with QPainter commands
|
||||
// by setting modelview and projection matrices to mirror the GL 1
|
||||
// paint engine
|
||||
const QTransform& mtx = state()->matrix;
|
||||
|
||||
float mv_matrix[4][4] =
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
const QGLContext *ctx = d->ctx;
|
||||
const QGLFormat &fmt = d->device->format();
|
||||
if (fmt.majorVersion() < 3 || (fmt.majorVersion() == 3 && fmt.minorVersion() < 1)
|
||||
|| (fmt.majorVersion() == 3 && fmt.minorVersion() == 1 && ctx->contextHandle()->hasExtension(QByteArrayLiteral("GL_ARB_compatibility")))
|
||||
|| fmt.profile() == QGLFormat::CompatibilityProfile)
|
||||
{
|
||||
{ float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
|
||||
{ float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
|
||||
{ 0, 0, 1, 0 },
|
||||
{ float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
|
||||
};
|
||||
// be nice to people who mix OpenGL 1.x code with QPainter commands
|
||||
// by setting modelview and projection matrices to mirror the GL 1
|
||||
// paint engine
|
||||
const QTransform& mtx = state()->matrix;
|
||||
|
||||
const QSize sz = d->device->size();
|
||||
float mv_matrix[4][4] =
|
||||
{
|
||||
{ float(mtx.m11()), float(mtx.m12()), 0, float(mtx.m13()) },
|
||||
{ float(mtx.m21()), float(mtx.m22()), 0, float(mtx.m23()) },
|
||||
{ 0, 0, 1, 0 },
|
||||
{ float(mtx.dx()), float(mtx.dy()), 0, float(mtx.m33()) }
|
||||
};
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
|
||||
const QSize sz = d->device->size();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(&mv_matrix[0][0]);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixf(&mv_matrix[0][0]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -595,9 +597,11 @@ void QGL2PaintEngineExPrivate::resetGLState()
|
||||
ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false);
|
||||
ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false);
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
// gl_Color, corresponding to vertex attribute 3, may have been changed
|
||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
funcs.glVertexAttrib4fv(3, color);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
// gl_Color, corresponding to vertex attribute 3, may have been changed
|
||||
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
funcs.glVertexAttrib4fv(3, color);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1352,11 +1356,13 @@ void QGL2PaintEngineEx::renderHintsChanged()
|
||||
state()->renderHintsChanged = true;
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if ((state()->renderHints & QPainter::Antialiasing)
|
||||
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
else
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
if ((state()->renderHints & QPainter::Antialiasing)
|
||||
|| (state()->renderHints & QPainter::HighQualityAntialiasing))
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
else
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
#endif
|
||||
|
||||
Q_D(QGL2PaintEngineEx);
|
||||
@ -2027,21 +2033,23 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
if (!QOpenGLFunctions::isES())
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
#endif
|
||||
|
||||
d->glyphCacheType = QFontEngineGlyphCache::Raster_A8;
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
d->glyphCacheType = QFontEngineGlyphCache::Raster_RGBMask;
|
||||
#endif
|
||||
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
d->multisamplingAlwaysEnabled = false;
|
||||
} else {
|
||||
d->multisamplingAlwaysEnabled = d->device->format().sampleBuffers();
|
||||
}
|
||||
#else
|
||||
// OpenGL ES can't switch MSAA off, so if the gl paint device is
|
||||
// multisampled, it's always multisampled.
|
||||
d->multisamplingAlwaysEnabled = d->device->format().sampleBuffers();
|
||||
#else
|
||||
d->multisamplingAlwaysEnabled = false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -319,23 +319,24 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub
|
||||
uchar g = src[x] >> 8;
|
||||
uchar b = src[x];
|
||||
quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding.
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
// swizzle the bits to accommodate for the GL_RGBA upload.
|
||||
src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16);
|
||||
#else
|
||||
src[x] = (src[x] & 0x00ffffff) | (avg << 24);
|
||||
#endif
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
// swizzle the bits to accommodate for the GL_RGBA upload.
|
||||
src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16);
|
||||
} else {
|
||||
src[x] = (src[x] & 0x00ffffff) | (avg << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture);
|
||||
if (mask.format() == QImage::Format_RGB32) {
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_RGBA, GL_UNSIGNED_BYTE, mask.bits());
|
||||
#else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_BGRA, GL_UNSIGNED_BYTE, mask.bits());
|
||||
GLenum format = GL_RGBA;
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (!QOpenGLFunctions::isES())
|
||||
format = GL_BGRA;
|
||||
#endif
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, format, GL_UNSIGNED_BYTE, mask.bits());
|
||||
} else {
|
||||
// glTexSubImage2D() might cause some garbage to appear in the texture if the mask width is
|
||||
// not a multiple of four bytes. The bug appeared on a computer with 32-bit Windows Vista
|
||||
|
@ -1699,10 +1699,12 @@ QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alp
|
||||
return QImage();
|
||||
int w = size.width();
|
||||
int h = size.height();
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
//### glGetTexImage not in GL ES 2.0, need to do something else here!
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
#endif
|
||||
#ifndef QT_OPENGL_ES
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
//### glGetTexImage not in GL ES 2.0, need to do something else here!
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
|
||||
}
|
||||
#endif // QT_OPENGL_ES
|
||||
convertFromGLImage(img, w, h, alpha_format, include_alpha);
|
||||
return img;
|
||||
}
|
||||
@ -2282,17 +2284,20 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
glBindTexture(target, tx_id);
|
||||
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering);
|
||||
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
bool genMipmap = false;
|
||||
#endif
|
||||
bool genMipmap = !QOpenGLFunctions::isES();
|
||||
if (glFormat.directRendering()
|
||||
&& (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::GenerateMipmap))
|
||||
&& target == GL_TEXTURE_2D
|
||||
&& (options & QGLContext::MipmapBindOption))
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
|
||||
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
if (genMipmap) {
|
||||
glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
|
||||
glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
} else {
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
|
||||
genMipmap = true;
|
||||
}
|
||||
#else
|
||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST);
|
||||
genMipmap = true;
|
||||
@ -2421,11 +2426,11 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
printf(" - did byte swapping (%d ms)\n", time.elapsed());
|
||||
#endif
|
||||
}
|
||||
#ifdef QT_OPENGL_ES
|
||||
// OpenGL/ES requires that the internal and external formats be
|
||||
// identical.
|
||||
internalFormat = externalFormat;
|
||||
#endif
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
// OpenGL/ES requires that the internal and external formats be
|
||||
// identical.
|
||||
internalFormat = externalFormat;
|
||||
}
|
||||
#ifdef QGL_BIND_TEXTURE_DEBUG
|
||||
printf(" - uploading, image.format=%d, externalFormat=0x%x, internalFormat=0x%x, pixel_type=0x%x\n",
|
||||
img.format(), externalFormat, internalFormat, pixel_type);
|
||||
@ -2434,10 +2439,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
|
||||
const QImage &constRef = img; // to avoid detach in bits()...
|
||||
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
|
||||
pixel_type, constRef.bits());
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
if (genMipmap)
|
||||
glGenerateMipmap(target);
|
||||
#endif
|
||||
if (genMipmap && QOpenGLFunctions::isES())
|
||||
functions->glGenerateMipmap(target);
|
||||
#ifndef QT_NO_DEBUG
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR) {
|
||||
@ -2518,31 +2521,32 @@ int QGLContextPrivate::maxTextureSize()
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
|
||||
|
||||
#if defined(QT_OPENGL_ES)
|
||||
return max_texture_size;
|
||||
#else
|
||||
GLenum proxy = GL_PROXY_TEXTURE_2D;
|
||||
#ifndef QT_OPENGL_ES
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
GLenum proxy = GL_PROXY_TEXTURE_2D;
|
||||
|
||||
GLint size;
|
||||
GLint next = 64;
|
||||
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
|
||||
if (size == 0) {
|
||||
return max_texture_size;
|
||||
}
|
||||
do {
|
||||
size = next;
|
||||
next = size * 2;
|
||||
|
||||
if (next > max_texture_size)
|
||||
break;
|
||||
GLint size;
|
||||
GLint next = 64;
|
||||
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
|
||||
} while (next > size);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &size);
|
||||
if (size == 0) {
|
||||
return max_texture_size;
|
||||
}
|
||||
do {
|
||||
size = next;
|
||||
next = size * 2;
|
||||
|
||||
max_texture_size = size;
|
||||
return max_texture_size;
|
||||
if (next > max_texture_size)
|
||||
break;
|
||||
glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next);
|
||||
} while (next > size);
|
||||
|
||||
max_texture_size = size;
|
||||
}
|
||||
#endif
|
||||
|
||||
return max_texture_size;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2696,7 +2700,7 @@ static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint tex
|
||||
Q_UNUSED(textureHeight);
|
||||
Q_UNUSED(textureTarget);
|
||||
#else
|
||||
if (textureTarget != GL_TEXTURE_2D) {
|
||||
if (textureTarget != GL_TEXTURE_2D && !QOpenGLFunctions::isES()) {
|
||||
if (textureWidth == -1 || textureHeight == -1) {
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
|
||||
@ -2763,35 +2767,38 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
|
||||
#endif
|
||||
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
#ifdef QT_OPENGL_ES
|
||||
if (textureTarget != GL_TEXTURE_2D) {
|
||||
qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
|
||||
if (textureTarget != GL_TEXTURE_2D) {
|
||||
qWarning("QGLContext::drawTexture(): texture target must be GL_TEXTURE_2D on OpenGL ES");
|
||||
return;
|
||||
}
|
||||
#else
|
||||
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
|
||||
GLint oldTexture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
|
||||
#endif
|
||||
|
||||
glEnable(textureTarget);
|
||||
glBindTexture(textureTarget, textureId);
|
||||
|
||||
qDrawTextureRect(target, -1, -1, textureTarget);
|
||||
|
||||
#ifdef QT_OPENGL_ES
|
||||
glDisable(textureTarget);
|
||||
#else
|
||||
if (!wasEnabled)
|
||||
glDisable(textureTarget);
|
||||
glBindTexture(textureTarget, oldTexture);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#else
|
||||
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
|
||||
GLint oldTexture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
|
||||
#endif
|
||||
|
||||
glEnable(textureTarget);
|
||||
glBindTexture(textureTarget, textureId);
|
||||
|
||||
qDrawTextureRect(target, -1, -1, textureTarget);
|
||||
|
||||
#ifdef QT_OPENGL_ES
|
||||
glDisable(textureTarget);
|
||||
#else
|
||||
if (!wasEnabled)
|
||||
glDisable(textureTarget);
|
||||
glBindTexture(textureTarget, oldTexture);
|
||||
#endif
|
||||
#else
|
||||
Q_UNUSED(target);
|
||||
Q_UNUSED(textureId);
|
||||
Q_UNUSED(textureTarget);
|
||||
qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine");
|
||||
#endif
|
||||
qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2821,40 +2828,42 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
|
||||
Q_UNUSED(point);
|
||||
Q_UNUSED(textureId);
|
||||
Q_UNUSED(textureTarget);
|
||||
qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead");
|
||||
#else
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
|
||||
GLint oldTexture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
|
||||
|
||||
const bool wasEnabled = glIsEnabled(GL_TEXTURE_2D);
|
||||
GLint oldTexture;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture);
|
||||
glEnable(textureTarget);
|
||||
glBindTexture(textureTarget, textureId);
|
||||
|
||||
glEnable(textureTarget);
|
||||
glBindTexture(textureTarget, textureId);
|
||||
GLint textureWidth;
|
||||
GLint textureHeight;
|
||||
|
||||
GLint textureWidth;
|
||||
GLint textureHeight;
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
|
||||
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth);
|
||||
glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight);
|
||||
|
||||
if (d_ptr->active_engine &&
|
||||
d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
|
||||
QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine);
|
||||
if (!eng->isNativePaintingActive()) {
|
||||
QRectF dest(point, QSizeF(textureWidth, textureHeight));
|
||||
QRectF src(0, 0, textureWidth, textureHeight);
|
||||
QSize size(textureWidth, textureHeight);
|
||||
if (eng->drawTexture(dest, textureId, size, src))
|
||||
return;
|
||||
if (d_ptr->active_engine &&
|
||||
d_ptr->active_engine->type() == QPaintEngine::OpenGL2) {
|
||||
QGL2PaintEngineEx *eng = static_cast<QGL2PaintEngineEx*>(d_ptr->active_engine);
|
||||
if (!eng->isNativePaintingActive()) {
|
||||
QRectF dest(point, QSizeF(textureWidth, textureHeight));
|
||||
QRectF src(0, 0, textureWidth, textureHeight);
|
||||
QSize size(textureWidth, textureHeight);
|
||||
if (eng->drawTexture(dest, textureId, size, src))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget);
|
||||
|
||||
if (!wasEnabled)
|
||||
glDisable(textureTarget);
|
||||
glBindTexture(textureTarget, oldTexture);
|
||||
return;
|
||||
}
|
||||
|
||||
qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget);
|
||||
|
||||
if (!wasEnabled)
|
||||
glDisable(textureTarget);
|
||||
glBindTexture(textureTarget, oldTexture);
|
||||
#endif
|
||||
qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead");
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -4163,7 +4172,7 @@ void QGLWidget::glDraw()
|
||||
return;
|
||||
makeCurrent();
|
||||
#ifndef QT_OPENGL_ES
|
||||
if (d->glcx->deviceIsPixmap())
|
||||
if (d->glcx->deviceIsPixmap() && !QOpenGLFunctions::isES())
|
||||
glDrawBuffer(GL_FRONT);
|
||||
#endif
|
||||
QSize readback_target_size = d->glcx->d_ptr->readback_target_size;
|
||||
@ -4206,18 +4215,20 @@ void QGLWidget::qglColor(const QColor& c) const
|
||||
#ifdef QT_OPENGL_ES
|
||||
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
#else
|
||||
Q_D(const QGLWidget);
|
||||
const QGLContext *ctx = QGLContext::currentContext();
|
||||
if (ctx) {
|
||||
if (ctx->format().rgba())
|
||||
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
|
||||
int i = d->cmap.find(c.rgb());
|
||||
if (i < 0)
|
||||
i = d->cmap.findNearest(c.rgb());
|
||||
glIndexi(i);
|
||||
} else
|
||||
glIndexi(ctx->colorIndex(c));
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(const QGLWidget);
|
||||
const QGLContext *ctx = QGLContext::currentContext();
|
||||
if (ctx) {
|
||||
if (ctx->format().rgba())
|
||||
glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
|
||||
int i = d->cmap.find(c.rgb());
|
||||
if (i < 0)
|
||||
i = d->cmap.findNearest(c.rgb());
|
||||
glIndexi(i);
|
||||
} else
|
||||
glIndexi(ctx->colorIndex(c));
|
||||
}
|
||||
}
|
||||
#endif //QT_OPENGL_ES
|
||||
#else
|
||||
@ -4238,18 +4249,23 @@ void QGLWidget::qglClearColor(const QColor& c) const
|
||||
#ifdef QT_OPENGL_ES
|
||||
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
#else
|
||||
Q_D(const QGLWidget);
|
||||
const QGLContext *ctx = QGLContext::currentContext();
|
||||
if (ctx) {
|
||||
if (ctx->format().rgba())
|
||||
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
|
||||
int i = d->cmap.find(c.rgb());
|
||||
if (i < 0)
|
||||
i = d->cmap.findNearest(c.rgb());
|
||||
glClearIndex(i);
|
||||
} else
|
||||
glClearIndex(ctx->colorIndex(c));
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(const QGLWidget);
|
||||
const QGLContext *ctx = QGLContext::currentContext();
|
||||
if (ctx) {
|
||||
if (ctx->format().rgba())
|
||||
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
else if (!d->cmap.isEmpty()) { // QGLColormap in use?
|
||||
int i = d->cmap.find(c.rgb());
|
||||
if (i < 0)
|
||||
i = d->cmap.findNearest(c.rgb());
|
||||
glClearIndex(i);
|
||||
} else {
|
||||
glClearIndex(ctx->colorIndex(c));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -4411,72 +4427,75 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str,
|
||||
void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
|
||||
{
|
||||
#ifndef QT_OPENGL_ES
|
||||
Q_D(QGLWidget);
|
||||
if (str.isEmpty() || !isValid())
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QGLWidget);
|
||||
if (str.isEmpty() || !isValid())
|
||||
return;
|
||||
|
||||
GLint view[4];
|
||||
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
|
||||
if (!use_scissor_testing)
|
||||
glGetIntegerv(GL_VIEWPORT, &view[0]);
|
||||
int width = d->glcx->device()->width();
|
||||
int height = d->glcx->device()->height();
|
||||
bool auto_swap = autoBufferSwap();
|
||||
|
||||
QPaintEngine *engine = paintEngine();
|
||||
|
||||
qt_save_gl_state();
|
||||
|
||||
QPainter *p;
|
||||
bool reuse_painter = false;
|
||||
if (engine->isActive()) {
|
||||
reuse_painter = true;
|
||||
p = engine->painter();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, width, height, 0, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glLoadIdentity();
|
||||
} else {
|
||||
setAutoBufferSwap(false);
|
||||
// disable glClear() as a result of QPainter::begin()
|
||||
d->disable_clear_on_painter_begin = true;
|
||||
p = new QPainter(this);
|
||||
}
|
||||
|
||||
QRect viewport(view[0], view[1], view[2], view[3]);
|
||||
if (!use_scissor_testing && viewport != rect()) {
|
||||
// if the user hasn't set a scissor box, we set one that
|
||||
// covers the current viewport
|
||||
glScissor(view[0], view[1], view[2], view[3]);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
} else if (use_scissor_testing) {
|
||||
// use the scissor box set by the user
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
qt_gl_draw_text(p, x, y, str, font);
|
||||
|
||||
if (!reuse_painter) {
|
||||
p->end();
|
||||
delete p;
|
||||
setAutoBufferSwap(auto_swap);
|
||||
d->disable_clear_on_painter_begin = false;
|
||||
}
|
||||
|
||||
qt_restore_gl_state();
|
||||
|
||||
return;
|
||||
|
||||
GLint view[4];
|
||||
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
|
||||
if (!use_scissor_testing)
|
||||
glGetIntegerv(GL_VIEWPORT, &view[0]);
|
||||
int width = d->glcx->device()->width();
|
||||
int height = d->glcx->device()->height();
|
||||
bool auto_swap = autoBufferSwap();
|
||||
|
||||
QPaintEngine *engine = paintEngine();
|
||||
|
||||
qt_save_gl_state();
|
||||
|
||||
QPainter *p;
|
||||
bool reuse_painter = false;
|
||||
if (engine->isActive()) {
|
||||
reuse_painter = true;
|
||||
p = engine->painter();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glViewport(0, 0, width, height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, width, height, 0, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
||||
glLoadIdentity();
|
||||
} else {
|
||||
setAutoBufferSwap(false);
|
||||
// disable glClear() as a result of QPainter::begin()
|
||||
d->disable_clear_on_painter_begin = true;
|
||||
p = new QPainter(this);
|
||||
}
|
||||
|
||||
QRect viewport(view[0], view[1], view[2], view[3]);
|
||||
if (!use_scissor_testing && viewport != rect()) {
|
||||
// if the user hasn't set a scissor box, we set one that
|
||||
// covers the current viewport
|
||||
glScissor(view[0], view[1], view[2], view[3]);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
} else if (use_scissor_testing) {
|
||||
// use the scissor box set by the user
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
qt_gl_draw_text(p, x, y, str, font);
|
||||
|
||||
if (!reuse_painter) {
|
||||
p->end();
|
||||
delete p;
|
||||
setAutoBufferSwap(auto_swap);
|
||||
d->disable_clear_on_painter_begin = false;
|
||||
}
|
||||
|
||||
qt_restore_gl_state();
|
||||
|
||||
#else // QT_OPENGL_ES
|
||||
Q_UNUSED(x);
|
||||
Q_UNUSED(y);
|
||||
Q_UNUSED(str);
|
||||
Q_UNUSED(font);
|
||||
qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
|
||||
#endif
|
||||
qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -4503,80 +4522,83 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
|
||||
void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font)
|
||||
{
|
||||
#ifndef QT_OPENGL_ES
|
||||
Q_D(QGLWidget);
|
||||
if (str.isEmpty() || !isValid())
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
Q_D(QGLWidget);
|
||||
if (str.isEmpty() || !isValid())
|
||||
return;
|
||||
|
||||
bool auto_swap = autoBufferSwap();
|
||||
|
||||
int width = d->glcx->device()->width();
|
||||
int height = d->glcx->device()->height();
|
||||
GLdouble model[4 * 4], proj[4 * 4];
|
||||
GLint view[4];
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]);
|
||||
glGetIntegerv(GL_VIEWPORT, &view[0]);
|
||||
GLdouble win_x = 0, win_y = 0, win_z = 0;
|
||||
qgluProject(x, y, z, &model[0], &proj[0], &view[0],
|
||||
&win_x, &win_y, &win_z);
|
||||
win_y = height - win_y; // y is inverted
|
||||
|
||||
QPaintEngine *engine = paintEngine();
|
||||
|
||||
QPainter *p;
|
||||
bool reuse_painter = false;
|
||||
bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
|
||||
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
|
||||
|
||||
qt_save_gl_state();
|
||||
|
||||
if (engine->isActive()) {
|
||||
reuse_painter = true;
|
||||
p = engine->painter();
|
||||
} else {
|
||||
setAutoBufferSwap(false);
|
||||
// disable glClear() as a result of QPainter::begin()
|
||||
d->disable_clear_on_painter_begin = true;
|
||||
p = new QPainter(this);
|
||||
}
|
||||
|
||||
QRect viewport(view[0], view[1], view[2], view[3]);
|
||||
if (!use_scissor_testing && viewport != rect()) {
|
||||
glScissor(view[0], view[1], view[2], view[3]);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
} else if (use_scissor_testing) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glViewport(0, 0, width, height);
|
||||
glOrtho(0, width, height, 0, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glAlphaFunc(GL_GREATER, 0.0);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
if (use_depth_testing)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glTranslated(0, 0, -win_z);
|
||||
qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
|
||||
|
||||
if (!reuse_painter) {
|
||||
p->end();
|
||||
delete p;
|
||||
setAutoBufferSwap(auto_swap);
|
||||
d->disable_clear_on_painter_begin = false;
|
||||
}
|
||||
|
||||
qt_restore_gl_state();
|
||||
|
||||
return;
|
||||
|
||||
bool auto_swap = autoBufferSwap();
|
||||
|
||||
int width = d->glcx->device()->width();
|
||||
int height = d->glcx->device()->height();
|
||||
GLdouble model[4 * 4], proj[4 * 4];
|
||||
GLint view[4];
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]);
|
||||
glGetIntegerv(GL_VIEWPORT, &view[0]);
|
||||
GLdouble win_x = 0, win_y = 0, win_z = 0;
|
||||
qgluProject(x, y, z, &model[0], &proj[0], &view[0],
|
||||
&win_x, &win_y, &win_z);
|
||||
win_y = height - win_y; // y is inverted
|
||||
|
||||
QPaintEngine *engine = paintEngine();
|
||||
|
||||
QPainter *p;
|
||||
bool reuse_painter = false;
|
||||
bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST);
|
||||
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
|
||||
|
||||
qt_save_gl_state();
|
||||
|
||||
if (engine->isActive()) {
|
||||
reuse_painter = true;
|
||||
p = engine->painter();
|
||||
} else {
|
||||
setAutoBufferSwap(false);
|
||||
// disable glClear() as a result of QPainter::begin()
|
||||
d->disable_clear_on_painter_begin = true;
|
||||
p = new QPainter(this);
|
||||
}
|
||||
|
||||
QRect viewport(view[0], view[1], view[2], view[3]);
|
||||
if (!use_scissor_testing && viewport != rect()) {
|
||||
glScissor(view[0], view[1], view[2], view[3]);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
} else if (use_scissor_testing) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glViewport(0, 0, width, height);
|
||||
glOrtho(0, width, height, 0, 0, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glAlphaFunc(GL_GREATER, 0.0);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
if (use_depth_testing)
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glTranslated(0, 0, -win_z);
|
||||
qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
|
||||
|
||||
if (!reuse_painter) {
|
||||
p->end();
|
||||
delete p;
|
||||
setAutoBufferSwap(auto_swap);
|
||||
d->disable_clear_on_painter_begin = false;
|
||||
}
|
||||
|
||||
qt_restore_gl_state();
|
||||
|
||||
#else // QT_OPENGL_ES
|
||||
Q_UNUSED(x);
|
||||
Q_UNUSED(y);
|
||||
Q_UNUSED(z);
|
||||
Q_UNUSED(str);
|
||||
Q_UNUSED(font);
|
||||
qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
|
||||
#endif
|
||||
qWarning("QGLWidget::renderText is not supported under OpenGL/ES");
|
||||
}
|
||||
|
||||
QGLFormat QGLWidget::format() const
|
||||
|
@ -321,21 +321,23 @@ QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
|
||||
|
||||
d->context = new QOpenGLContext;
|
||||
#if !defined(QT_OPENGL_ES)
|
||||
// On desktop, request latest released version
|
||||
QSurfaceFormat format;
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
// On desktop, request latest released version
|
||||
QSurfaceFormat format;
|
||||
#if defined(Q_OS_MAC)
|
||||
// OS X is limited to OpenGL 3.2 Core Profile at present
|
||||
// so set that here. If we use compatibility profile it
|
||||
// only reports 2.x contexts.
|
||||
format.setMajorVersion(3);
|
||||
format.setMinorVersion(2);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
// OS X is limited to OpenGL 3.2 Core Profile at present
|
||||
// so set that here. If we use compatibility profile it
|
||||
// only reports 2.x contexts.
|
||||
format.setMajorVersion(3);
|
||||
format.setMinorVersion(2);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
#else
|
||||
format.setMajorVersion(4);
|
||||
format.setMinorVersion(3);
|
||||
#endif
|
||||
d->context->setFormat(format);
|
||||
format.setMajorVersion(4);
|
||||
format.setMinorVersion(3);
|
||||
#endif
|
||||
d->context->setFormat(format);
|
||||
}
|
||||
#endif // QT_OPENGL_ES
|
||||
d->context->create();
|
||||
d->context->makeCurrent(d->window);
|
||||
}
|
||||
|
@ -344,18 +344,20 @@ void QGLBuffer::destroy()
|
||||
bool QGLBuffer::read(int offset, void *data, int count)
|
||||
{
|
||||
#if !defined(QT_OPENGL_ES)
|
||||
Q_D(QGLBuffer);
|
||||
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
|
||||
return false;
|
||||
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
|
||||
d->funcs->glGetBufferSubData(d->type, offset, count, data);
|
||||
return glGetError() == GL_NO_ERROR;
|
||||
if (QOpenGLFunctions::platformGLType() != QOpenGLFunctions::GLES1) {
|
||||
Q_D(QGLBuffer);
|
||||
if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
|
||||
return false;
|
||||
while (glGetError() != GL_NO_ERROR) ; // Clear error state.
|
||||
d->funcs->glGetBufferSubData(d->type, offset, count, data);
|
||||
return glGetError() == GL_NO_ERROR;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(offset);
|
||||
Q_UNUSED(data);
|
||||
Q_UNUSED(count);
|
||||
return false;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -373,8 +373,11 @@ void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f,
|
||||
|
||||
GLenum format = f->format().internalTextureFormat();
|
||||
reqAlpha = (format != GL_RGB
|
||||
#ifndef QT_OPENGL_ES
|
||||
&& format != GL_RGB5 && format != GL_RGB8
|
||||
#ifdef GL_RGB5
|
||||
&& format != GL_RGB5
|
||||
#endif
|
||||
#ifdef GL_RGB8
|
||||
&& format != GL_RGB8
|
||||
#endif
|
||||
);
|
||||
}
|
||||
@ -592,8 +595,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
|
||||
GL_DEPTH_COMPONENT16, size.width(), size.height());
|
||||
}
|
||||
#else
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT, size.width(), size.height());
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT24, size.width(), size.height());
|
||||
else
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT16, size.width(), size.height());
|
||||
} else {
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_DEPTH_COMPONENT, size.width(), size.height());
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#ifdef QT_OPENGL_ES
|
||||
@ -605,7 +617,17 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
|
||||
size.width(), size.height());
|
||||
}
|
||||
#else
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
|
||||
size.width(), size.height());
|
||||
} else {
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
|
||||
size.width(), size.height());
|
||||
}
|
||||
} else {
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
@ -621,23 +643,18 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
|
||||
funcs.glGenRenderbuffers(1, &stencil_buffer);
|
||||
funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
|
||||
Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));
|
||||
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
|
||||
|
||||
#ifdef QT_OPENGL_ES
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_STENCIL_INDEX8, size.width(), size.height());
|
||||
GLenum storage = GL_STENCIL_INDEX8;
|
||||
#else
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
|
||||
GL_STENCIL_INDEX, size.width(), size.height());
|
||||
GLenum storage = QOpenGLFunctions::isES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
|
||||
#endif
|
||||
} else {
|
||||
#ifdef QT_OPENGL_ES
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
|
||||
size.width(), size.height());
|
||||
#else
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX,
|
||||
size.width(), size.height());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
|
||||
funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
|
||||
else
|
||||
funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());
|
||||
|
||||
funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, stencil_buffer);
|
||||
valid = checkFramebufferStatus();
|
||||
@ -830,7 +847,13 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
|
||||
: d_ptr(new QGLFramebufferObjectPrivate)
|
||||
{
|
||||
Q_D(QGLFramebufferObject);
|
||||
d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
|
||||
d->init(this, size, NoAttachment, target,
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
|
||||
#else
|
||||
GL_RGBA
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -844,7 +867,13 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target)
|
||||
: d_ptr(new QGLFramebufferObjectPrivate)
|
||||
{
|
||||
Q_D(QGLFramebufferObject);
|
||||
d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
|
||||
d->init(this, QSize(width, height), NoAttachment, target,
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
|
||||
#else
|
||||
GL_RGBA
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -893,6 +922,12 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att
|
||||
: d_ptr(new QGLFramebufferObjectPrivate)
|
||||
{
|
||||
Q_D(QGLFramebufferObject);
|
||||
if (!internal_format)
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
internal_format = GL_RGBA;
|
||||
#else
|
||||
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
#endif
|
||||
d->init(this, QSize(width, height), attachment, target, internal_format);
|
||||
}
|
||||
|
||||
@ -914,6 +949,12 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
|
||||
: d_ptr(new QGLFramebufferObjectPrivate)
|
||||
{
|
||||
Q_D(QGLFramebufferObject);
|
||||
if (!internal_format)
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
internal_format = GL_RGBA;
|
||||
#else
|
||||
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
#endif
|
||||
d->init(this, size, attachment, target, internal_format);
|
||||
}
|
||||
|
||||
|
@ -63,17 +63,11 @@ public:
|
||||
|
||||
QGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D);
|
||||
QGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D);
|
||||
#if !defined(QT_OPENGL_ES) || defined(Q_QDOC)
|
||||
|
||||
QGLFramebufferObject(const QSize &size, Attachment attachment,
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
|
||||
QGLFramebufferObject(int width, int height, Attachment attachment,
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA8);
|
||||
#else
|
||||
QGLFramebufferObject(const QSize &size, Attachment attachment,
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
|
||||
QGLFramebufferObject(int width, int height, Attachment attachment,
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = GL_RGBA);
|
||||
#endif
|
||||
GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0);
|
||||
|
||||
QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format);
|
||||
QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format);
|
||||
|
@ -60,12 +60,6 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_OPENGL_ES
|
||||
#define DEFAULT_FORMAT GL_RGBA8
|
||||
#else
|
||||
#define DEFAULT_FORMAT GL_RGBA
|
||||
#endif
|
||||
|
||||
class QGLFramebufferObjectFormatPrivate
|
||||
{
|
||||
public:
|
||||
@ -74,9 +68,13 @@ public:
|
||||
samples(0),
|
||||
attachment(QGLFramebufferObject::NoAttachment),
|
||||
target(GL_TEXTURE_2D),
|
||||
internal_format(DEFAULT_FORMAT),
|
||||
mipmap(false)
|
||||
{
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
internal_format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
#else
|
||||
internal_format = GL_RGBA;
|
||||
#endif
|
||||
}
|
||||
QGLFramebufferObjectFormatPrivate
|
||||
(const QGLFramebufferObjectFormatPrivate *other)
|
||||
|
@ -213,94 +213,94 @@ QGLFunctions::QGLFunctions(const QGLContext *context)
|
||||
|
||||
static int qt_gl_resolve_features()
|
||||
{
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
int features = QGLFunctions::Multitexture |
|
||||
QGLFunctions::Shaders |
|
||||
QGLFunctions::Buffers |
|
||||
QGLFunctions::Framebuffers |
|
||||
QGLFunctions::BlendColor |
|
||||
QGLFunctions::BlendEquation |
|
||||
QGLFunctions::BlendEquationSeparate |
|
||||
QGLFunctions::BlendFuncSeparate |
|
||||
QGLFunctions::BlendSubtract |
|
||||
QGLFunctions::CompressedTextures |
|
||||
QGLFunctions::Multisample |
|
||||
QGLFunctions::StencilSeparate;
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (extensions.match("GL_OES_texture_npot"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
if (extensions.match("GL_IMG_texture_npot"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
return features;
|
||||
#elif defined(QT_OPENGL_ES)
|
||||
int features = QGLFunctions::Multitexture |
|
||||
QGLFunctions::Buffers |
|
||||
QGLFunctions::CompressedTextures |
|
||||
QGLFunctions::Multisample;
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (extensions.match("GL_OES_framebuffer_object"))
|
||||
features |= QGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_OES_blend_equation_separate"))
|
||||
features |= QGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_OES_blend_func_separate"))
|
||||
features |= QGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_OES_blend_subtract"))
|
||||
features |= QGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_OES_texture_npot"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
if (extensions.match("GL_IMG_texture_npot"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
return features;
|
||||
#else
|
||||
int features = 0;
|
||||
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES2) {
|
||||
int features = QGLFunctions::Multitexture |
|
||||
QGLFunctions::Shaders |
|
||||
QGLFunctions::Buffers |
|
||||
QGLFunctions::Framebuffers |
|
||||
QGLFunctions::BlendColor |
|
||||
QGLFunctions::BlendEquation |
|
||||
QGLFunctions::BlendEquationSeparate |
|
||||
QGLFunctions::BlendFuncSeparate |
|
||||
QGLFunctions::BlendSubtract |
|
||||
QGLFunctions::CompressedTextures |
|
||||
QGLFunctions::Multisample |
|
||||
QGLFunctions::StencilSeparate;
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (extensions.match("GL_OES_texture_npot"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
if (extensions.match("GL_IMG_texture_npot"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
return features;
|
||||
} if (QOpenGLFunctions::platformGLType() == QOpenGLFunctions::GLES1) {
|
||||
int features = QGLFunctions::Multitexture |
|
||||
QGLFunctions::Buffers |
|
||||
QGLFunctions::CompressedTextures |
|
||||
QGLFunctions::Multisample;
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
if (extensions.match("GL_OES_framebuffer_object"))
|
||||
features |= QGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_OES_blend_equation_separate"))
|
||||
features |= QGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_OES_blend_func_separate"))
|
||||
features |= QGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_OES_blend_subtract"))
|
||||
features |= QGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_OES_texture_npot"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
if (extensions.match("GL_IMG_texture_npot"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
return features;
|
||||
} else {
|
||||
int features = 0;
|
||||
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
|
||||
QOpenGLExtensionMatcher extensions;
|
||||
|
||||
// Recognize features by extension name.
|
||||
if (extensions.match("GL_ARB_multitexture"))
|
||||
features |= QGLFunctions::Multitexture;
|
||||
if (extensions.match("GL_ARB_shader_objects"))
|
||||
features |= QGLFunctions::Shaders;
|
||||
if (extensions.match("GL_EXT_framebuffer_object") ||
|
||||
// Recognize features by extension name.
|
||||
if (extensions.match("GL_ARB_multitexture"))
|
||||
features |= QGLFunctions::Multitexture;
|
||||
if (extensions.match("GL_ARB_shader_objects"))
|
||||
features |= QGLFunctions::Shaders;
|
||||
if (extensions.match("GL_EXT_framebuffer_object") ||
|
||||
extensions.match("GL_ARB_framebuffer_object"))
|
||||
features |= QGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_EXT_blend_color"))
|
||||
features |= QGLFunctions::BlendColor;
|
||||
if (extensions.match("GL_EXT_blend_equation_separate"))
|
||||
features |= QGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_EXT_blend_func_separate"))
|
||||
features |= QGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_EXT_blend_subtract"))
|
||||
features |= QGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_ARB_texture_compression"))
|
||||
features |= QGLFunctions::CompressedTextures;
|
||||
if (extensions.match("GL_ARB_multisample"))
|
||||
features |= QGLFunctions::Multisample;
|
||||
if (extensions.match("GL_ARB_texture_non_power_of_two"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
features |= QGLFunctions::Framebuffers;
|
||||
if (extensions.match("GL_EXT_blend_color"))
|
||||
features |= QGLFunctions::BlendColor;
|
||||
if (extensions.match("GL_EXT_blend_equation_separate"))
|
||||
features |= QGLFunctions::BlendEquationSeparate;
|
||||
if (extensions.match("GL_EXT_blend_func_separate"))
|
||||
features |= QGLFunctions::BlendFuncSeparate;
|
||||
if (extensions.match("GL_EXT_blend_subtract"))
|
||||
features |= QGLFunctions::BlendSubtract;
|
||||
if (extensions.match("GL_ARB_texture_compression"))
|
||||
features |= QGLFunctions::CompressedTextures;
|
||||
if (extensions.match("GL_ARB_multisample"))
|
||||
features |= QGLFunctions::Multisample;
|
||||
if (extensions.match("GL_ARB_texture_non_power_of_two"))
|
||||
features |= QGLFunctions::NPOTTextures;
|
||||
|
||||
// Recognize features by minimum OpenGL version.
|
||||
if (versions & QGLFormat::OpenGL_Version_1_2) {
|
||||
features |= QGLFunctions::BlendColor |
|
||||
QGLFunctions::BlendEquation;
|
||||
// Recognize features by minimum OpenGL version.
|
||||
if (versions & QGLFormat::OpenGL_Version_1_2) {
|
||||
features |= QGLFunctions::BlendColor |
|
||||
QGLFunctions::BlendEquation;
|
||||
}
|
||||
if (versions & QGLFormat::OpenGL_Version_1_3) {
|
||||
features |= QGLFunctions::Multitexture |
|
||||
QGLFunctions::CompressedTextures |
|
||||
QGLFunctions::Multisample;
|
||||
}
|
||||
if (versions & QGLFormat::OpenGL_Version_1_4)
|
||||
features |= QGLFunctions::BlendFuncSeparate;
|
||||
if (versions & QGLFormat::OpenGL_Version_1_5)
|
||||
features |= QGLFunctions::Buffers;
|
||||
if (versions & QGLFormat::OpenGL_Version_2_0) {
|
||||
features |= QGLFunctions::Shaders |
|
||||
QGLFunctions::StencilSeparate |
|
||||
QGLFunctions::BlendEquationSeparate |
|
||||
QGLFunctions::NPOTTextures;
|
||||
}
|
||||
return features;
|
||||
}
|
||||
if (versions & QGLFormat::OpenGL_Version_1_3) {
|
||||
features |= QGLFunctions::Multitexture |
|
||||
QGLFunctions::CompressedTextures |
|
||||
QGLFunctions::Multisample;
|
||||
}
|
||||
if (versions & QGLFormat::OpenGL_Version_1_4)
|
||||
features |= QGLFunctions::BlendFuncSeparate;
|
||||
if (versions & QGLFormat::OpenGL_Version_1_5)
|
||||
features |= QGLFunctions::Buffers;
|
||||
if (versions & QGLFormat::OpenGL_Version_2_0) {
|
||||
features |= QGLFunctions::Shaders |
|
||||
QGLFunctions::StencilSeparate |
|
||||
QGLFunctions::BlendEquationSeparate |
|
||||
QGLFunctions::NPOTTextures;
|
||||
}
|
||||
return features;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -51,6 +51,7 @@
|
||||
|
||||
#include <QtOpenGL/qgl.h>
|
||||
#include <QtGui/qopenglcontext.h>
|
||||
#include <QtGui/qopenglfunctions.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -361,7 +361,8 @@ void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture_id);
|
||||
#ifndef QT_OPENGL_ES
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||
GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||
#else
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0);
|
||||
#endif
|
||||
@ -487,7 +488,8 @@ GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target)
|
||||
{
|
||||
Q_D(QGLPixelBuffer);
|
||||
#ifndef QT_OPENGL_ES
|
||||
return d->qctx->bindTexture(image, target, GLint(GL_RGBA8));
|
||||
GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
return d->qctx->bindTexture(image, target, GLint(format));
|
||||
#else
|
||||
return d->qctx->bindTexture(image, target, GL_RGBA);
|
||||
#endif
|
||||
@ -505,7 +507,8 @@ GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target)
|
||||
{
|
||||
Q_D(QGLPixelBuffer);
|
||||
#ifndef QT_OPENGL_ES
|
||||
return d->qctx->bindTexture(pixmap, target, GLint(GL_RGBA8));
|
||||
GLenum format = QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
return d->qctx->bindTexture(pixmap, target, GLint(format));
|
||||
#else
|
||||
return d->qctx->bindTexture(pixmap, target, GL_RGBA);
|
||||
#endif
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include <QtCore/qfile.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtCore/qvector.h>
|
||||
#include <QDebug>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -246,7 +247,8 @@ bool QGLShaderPrivate::create()
|
||||
if (shaderType == QGLShader::Vertex)
|
||||
shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
else if (shaderType == QGLShader::Geometry)
|
||||
else if (shaderType == QGLShader::Geometry
|
||||
&& !QOpenGLFunctions::isES())
|
||||
shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT);
|
||||
#endif
|
||||
else
|
||||
@ -428,11 +430,14 @@ bool QGLShader::compileSourceCode(const char *source)
|
||||
srclen.append(GLint(headerLen));
|
||||
}
|
||||
#ifdef QGL_DEFINE_QUALIFIERS
|
||||
src.append(qualifierDefines);
|
||||
srclen.append(GLint(sizeof(qualifierDefines) - 1));
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
src.append(qualifierDefines);
|
||||
srclen.append(GLint(sizeof(qualifierDefines) - 1));
|
||||
}
|
||||
#endif
|
||||
#ifdef QGL_REDEFINE_HIGHP
|
||||
if (d->shaderType == Fragment) {
|
||||
if (d->shaderType == Fragment
|
||||
&& QOpenGLFunctions::isES()) {
|
||||
src.append(redefineHighp);
|
||||
srclen.append(GLint(sizeof(redefineHighp) - 1));
|
||||
}
|
||||
@ -562,13 +567,15 @@ public:
|
||||
|
||||
void initializeGeometryShaderFunctions()
|
||||
{
|
||||
QOpenGLContext *context = QOpenGLContext::currentContext();
|
||||
glProgramParameteri = (type_glProgramParameteri)
|
||||
context->getProcAddress("glProgramParameteri");
|
||||
|
||||
if (!glProgramParameteri) {
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
QOpenGLContext *context = QOpenGLContext::currentContext();
|
||||
glProgramParameteri = (type_glProgramParameteri)
|
||||
context->getProcAddress("glProgramParameteriEXT");
|
||||
context->getProcAddress("glProgramParameteri");
|
||||
|
||||
if (!glProgramParameteri) {
|
||||
glProgramParameteri = (type_glProgramParameteri)
|
||||
context->getProcAddress("glProgramParameteriEXT");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -929,7 +936,8 @@ bool QGLShaderProgram::link()
|
||||
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
// Set up the geometry shader parameters
|
||||
if (d->glfuncs->glProgramParameteri) {
|
||||
if (!QOpenGLFunctions::isES()
|
||||
&& d->glfuncs->glProgramParameteri) {
|
||||
foreach (QGLShader *shader, d->shaders) {
|
||||
if (shader->shaderType() & QGLShader::Geometry) {
|
||||
d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_INPUT_TYPE_EXT,
|
||||
@ -3060,7 +3068,8 @@ int QGLShaderProgram::maxGeometryOutputVertices() const
|
||||
{
|
||||
GLint n = 0;
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
|
||||
if (!QOpenGLFunctions::isES())
|
||||
glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n);
|
||||
#endif
|
||||
return n;
|
||||
}
|
||||
|
@ -37,4 +37,15 @@ contains(QT_CONFIG,egl) {
|
||||
$$PWD/qxlibeglintegration.cpp
|
||||
}
|
||||
CONFIG += egl
|
||||
|
||||
} else: contains(QT_CONFIG,dynamicgl) {
|
||||
HEADERS += \
|
||||
$$PWD/qeglconvenience_p.h \
|
||||
$$PWD/qeglplatformcontext_p.h \
|
||||
$$PWD/qeglpbuffer_p.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/qeglconvenience.cpp \
|
||||
$$PWD/qeglplatformcontext.cpp \
|
||||
$$PWD/qeglpbuffer.cpp
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <sys/ioctl.h>
|
||||
@ -243,12 +244,15 @@ EGLConfig QEglConfigChooser::chooseConfig()
|
||||
configureAttributes.append(EGL_OPENVG_BIT);
|
||||
break;
|
||||
#ifdef EGL_VERSION_1_4
|
||||
# if !defined(QT_OPENGL_ES_2)
|
||||
case QSurfaceFormat::DefaultRenderableType:
|
||||
# endif
|
||||
case QSurfaceFormat::OpenGL:
|
||||
configureAttributes.append(EGL_OPENGL_BIT);
|
||||
if (!QOpenGLFunctions::isES())
|
||||
configureAttributes.append(EGL_OPENGL_BIT);
|
||||
else
|
||||
configureAttributes.append(EGL_OPENGL_ES2_BIT);
|
||||
break;
|
||||
case QSurfaceFormat::OpenGL:
|
||||
configureAttributes.append(EGL_OPENGL_BIT);
|
||||
break;
|
||||
#endif
|
||||
case QSurfaceFormat::OpenGLES:
|
||||
if (m_format.majorVersion() == 1) {
|
||||
@ -353,11 +357,12 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config,
|
||||
if (referenceFormat.renderableType() == QSurfaceFormat::OpenVG && (renderableType & EGL_OPENVG_BIT))
|
||||
format.setRenderableType(QSurfaceFormat::OpenVG);
|
||||
#ifdef EGL_VERSION_1_4
|
||||
else if ((referenceFormat.renderableType() == QSurfaceFormat::OpenGL
|
||||
# if !defined(QT_OPENGL_ES_2)
|
||||
|| referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType
|
||||
# endif
|
||||
) && (renderableType & EGL_OPENGL_BIT))
|
||||
else if (referenceFormat.renderableType() == QSurfaceFormat::OpenGL
|
||||
&& (renderableType & EGL_OPENGL_BIT))
|
||||
format.setRenderableType(QSurfaceFormat::OpenGL);
|
||||
else if (referenceFormat.renderableType() == QSurfaceFormat::DefaultRenderableType
|
||||
&& !QOpenGLFunctions::isES()
|
||||
&& (renderableType & EGL_OPENGL_BIT))
|
||||
format.setRenderableType(QSurfaceFormat::OpenGL);
|
||||
#endif
|
||||
else
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "qeglplatformcontext_p.h"
|
||||
#include "qeglconvenience_p.h"
|
||||
#include <qpa/qplatformwindow.h>
|
||||
#include <QtGui/QOpenGLFunctions>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -69,9 +70,12 @@ static inline void bindApi(const QSurfaceFormat &format)
|
||||
eglBindAPI(EGL_OPENVG_API);
|
||||
break;
|
||||
#ifdef EGL_VERSION_1_4
|
||||
# if !defined(QT_OPENGL_ES_2)
|
||||
case QSurfaceFormat::DefaultRenderableType:
|
||||
# endif
|
||||
if (!QOpenGLFunctions::isES())
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
else
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
break;
|
||||
case QSurfaceFormat::OpenGL:
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
break;
|
||||
|
@ -135,11 +135,7 @@ QWindowsEGLContext::~QWindowsEGLContext()
|
||||
|
||||
bool QWindowsEGLContext::hasThreadedOpenGLCapability()
|
||||
{
|
||||
#ifdef QT_OPENGL_ES_2_ANGLE
|
||||
return false;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
EGLSurface QWindowsEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
|
||||
|
@ -43,12 +43,20 @@
|
||||
#include "qwindowsintegration.h"
|
||||
#include "qwindowswindow.h"
|
||||
#include "qwindowscontext.h"
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
# include "qwindowseglcontext.h"
|
||||
# include <QtGui/QOpenGLContext>
|
||||
#elif !defined(QT_NO_OPENGL)
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
|
||||
# include "qwindowsglcontext.h"
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_OPENGL)
|
||||
# include <QtGui/QOpenGLFunctions>
|
||||
#endif
|
||||
|
||||
#include "qwindowsscreen.h"
|
||||
#include "qwindowstheme.h"
|
||||
#include "qwindowsservices.h"
|
||||
@ -125,9 +133,10 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
struct QWindowsIntegrationPrivate
|
||||
{
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
typedef QSharedPointer<QWindowsEGLStaticContext> QEGLStaticContextPtr;
|
||||
#elif !defined(QT_NO_OPENGL)
|
||||
#endif
|
||||
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
|
||||
typedef QSharedPointer<QOpenGLStaticContext> QOpenGLStaticContextPtr;
|
||||
#endif
|
||||
|
||||
@ -143,9 +152,10 @@ struct QWindowsIntegrationPrivate
|
||||
QWindowsDrag m_drag;
|
||||
# endif
|
||||
#endif
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
QEGLStaticContextPtr m_staticEGLContext;
|
||||
#elif !defined(QT_NO_OPENGL)
|
||||
#endif
|
||||
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
|
||||
QOpenGLStaticContextPtr m_staticOpenGLContext;
|
||||
#endif
|
||||
QWindowsInputContext m_inputContext;
|
||||
@ -216,8 +226,8 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
|
||||
case OpenGL:
|
||||
return true;
|
||||
case ThreadedOpenGL:
|
||||
# ifdef QT_OPENGL_ES_2
|
||||
return QWindowsEGLContext::hasThreadedOpenGLCapability();
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
return QOpenGLFunctions::isES() ? QWindowsEGLContext::hasThreadedOpenGLCapability() : true;
|
||||
# else
|
||||
return true;
|
||||
# endif // QT_OPENGL_ES_2
|
||||
@ -278,23 +288,27 @@ QPlatformOpenGLContext
|
||||
*QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
|
||||
{
|
||||
qCDebug(lcQpaGl) << __FUNCTION__ << context->format();
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
if (d->m_staticEGLContext.isNull()) {
|
||||
QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create();
|
||||
if (!staticContext)
|
||||
return 0;
|
||||
d->m_staticEGLContext = QSharedPointer<QWindowsEGLStaticContext>(staticContext);
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
if (QOpenGLFunctions::isES()){
|
||||
if (d->m_staticEGLContext.isNull()) {
|
||||
QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create();
|
||||
if (!staticContext)
|
||||
return 0;
|
||||
d->m_staticEGLContext = QSharedPointer<QWindowsEGLStaticContext>(staticContext);
|
||||
}
|
||||
return new QWindowsEGLContext(d->m_staticEGLContext, context->format(), context->shareHandle());
|
||||
}
|
||||
#endif
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
if (d->m_staticOpenGLContext.isNull())
|
||||
d->m_staticOpenGLContext =
|
||||
QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
|
||||
QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
|
||||
return result->isValid() ? result.take() : 0;
|
||||
}
|
||||
return new QWindowsEGLContext(d->m_staticEGLContext, context->format(), context->shareHandle());
|
||||
#else // QT_OPENGL_ES_2
|
||||
if (d->m_staticOpenGLContext.isNull())
|
||||
d->m_staticOpenGLContext =
|
||||
QSharedPointer<QOpenGLStaticContext>(QOpenGLStaticContext::create());
|
||||
QScopedPointer<QWindowsGLContext> result(new QWindowsGLContext(d->m_staticOpenGLContext, context));
|
||||
if (result->isValid())
|
||||
return result.take();
|
||||
return 0;
|
||||
#endif // !QT_OPENGL_ES_2
|
||||
return 0;
|
||||
}
|
||||
#endif // !QT_NO_OPENGL
|
||||
|
||||
|
@ -43,13 +43,19 @@
|
||||
#include "qwindowswindow.h"
|
||||
#include "qwindowscontext.h"
|
||||
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
# include "qwindowseglcontext.h"
|
||||
# include <QtGui/QOpenGLContext>
|
||||
#elif !defined(QT_NO_OPENGL)
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
|
||||
# include "qwindowsglcontext.h"
|
||||
#endif
|
||||
|
||||
#if !defined(QT_NO_OPENGL)
|
||||
# include <QtGui/QOpenGLFunctions>
|
||||
#endif
|
||||
|
||||
#include <QtGui/QWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -113,19 +119,24 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour
|
||||
qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData());
|
||||
return 0;
|
||||
}
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
|
||||
if (resource == QByteArrayLiteral("eglDisplay"))
|
||||
return windowsEglContext->eglDisplay();
|
||||
if (resource == QByteArrayLiteral("eglContext"))
|
||||
return windowsEglContext->eglContext();
|
||||
if (resource == QByteArrayLiteral("eglConfig"))
|
||||
return windowsEglContext->eglConfig();
|
||||
#else // QT_OPENGL_ES_2
|
||||
QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
|
||||
if (resource == QByteArrayLiteral("renderingContext"))
|
||||
return windowsContext->renderingContext();
|
||||
#endif // !QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
QWindowsEGLContext *windowsEglContext = static_cast<QWindowsEGLContext *>(context->handle());
|
||||
if (resource == QByteArrayLiteral("eglDisplay"))
|
||||
return windowsEglContext->eglDisplay();
|
||||
if (resource == QByteArrayLiteral("eglContext"))
|
||||
return windowsEglContext->eglContext();
|
||||
if (resource == QByteArrayLiteral("eglConfig"))
|
||||
return windowsEglContext->eglConfig();
|
||||
}
|
||||
#endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC
|
||||
#if !defined(QT_OPENGL_ES_2)
|
||||
if (!QOpenGLFunctions::isES()) {
|
||||
QWindowsGLContext *windowsContext = static_cast<QWindowsGLContext *>(context->handle());
|
||||
if (resource == QByteArrayLiteral("renderingContext"))
|
||||
return windowsContext->renderingContext();
|
||||
}
|
||||
#endif // QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC
|
||||
|
||||
qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
|
||||
return 0;
|
||||
|
@ -48,8 +48,9 @@
|
||||
# include "qwindowscursor.h"
|
||||
#endif
|
||||
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
# include "qwindowseglcontext.h"
|
||||
# include <QtGui/QOpenGLFunctions>
|
||||
#endif
|
||||
|
||||
#include <QtGui/QGuiApplication>
|
||||
@ -861,7 +862,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
|
||||
m_dropTarget(0),
|
||||
m_savedStyle(0),
|
||||
m_format(aWindow->format()),
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
m_eglSurface(0),
|
||||
#endif
|
||||
#ifdef Q_OS_WINCE
|
||||
@ -878,8 +879,9 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
|
||||
return; // No further handling for Qt::Desktop
|
||||
if (aWindow->surfaceType() == QWindow::OpenGLSurface) {
|
||||
setFlag(OpenGLSurface);
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
setFlag(OpenGL_ES2);
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
if (QOpenGLFunctions::isES())
|
||||
setFlag(OpenGL_ES2);
|
||||
#endif
|
||||
}
|
||||
updateDropSite();
|
||||
@ -933,7 +935,7 @@ void QWindowsWindow::destroyWindow()
|
||||
if (hasMouseCapture())
|
||||
setMouseGrabEnabled(false);
|
||||
setDropSiteEnabled(false);
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
if (m_eglSurface) {
|
||||
qCDebug(lcQpaGl) << __FUNCTION__ << "Freeing EGL surface " << m_eglSurface << window();
|
||||
eglDestroySurface(m_staticEglContext->display(), m_eglSurface);
|
||||
@ -2107,7 +2109,7 @@ void QWindowsWindow::setEnabled(bool enabled)
|
||||
setStyle(newStyle);
|
||||
}
|
||||
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
EGLSurface QWindowsWindow::ensureEglSurfaceHandle(const QWindowsWindow::QWindowsEGLStaticContextPtr &staticContext, EGLConfig config)
|
||||
{
|
||||
if (!m_eglSurface) {
|
||||
|
@ -50,7 +50,7 @@
|
||||
|
||||
#include <qpa/qplatformwindow.h>
|
||||
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
# include <QtCore/QSharedPointer>
|
||||
# include <EGL/egl.h>
|
||||
#endif
|
||||
@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
|
||||
class QWindowsOleDropTarget;
|
||||
class QDebug;
|
||||
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
class QWindowsEGLStaticContext;
|
||||
#endif
|
||||
|
||||
@ -130,7 +130,7 @@ struct QWindowsWindowData
|
||||
class QWindowsWindow : public QPlatformWindow
|
||||
{
|
||||
public:
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
typedef QSharedPointer<QWindowsEGLStaticContext> QWindowsEGLStaticContextPtr;
|
||||
#endif
|
||||
|
||||
@ -206,7 +206,7 @@ public:
|
||||
QMargins customMargins() const { return m_data.customMargins; }
|
||||
void setCustomMargins(const QMargins &m);
|
||||
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
EGLSurface eglSurfaceHandle() const { return m_eglSurface;}
|
||||
EGLSurface ensureEglSurfaceHandle(const QWindowsEGLStaticContextPtr &staticContext, EGLConfig config);
|
||||
#endif
|
||||
@ -301,7 +301,7 @@ private:
|
||||
unsigned m_savedStyle;
|
||||
QRect m_savedFrameGeometry;
|
||||
const QSurfaceFormat m_format;
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)
|
||||
EGLSurface m_eglSurface;
|
||||
QSharedPointer<QWindowsEGLStaticContext> m_staticEglContext;
|
||||
#endif
|
||||
|
@ -2,7 +2,7 @@
|
||||
LIBS *= -lole32
|
||||
!wince*:LIBS *= -luser32 -lwinspool -limm32 -lwinmm -loleaut32
|
||||
|
||||
contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):LIBS *= -lopengl32
|
||||
contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):!contains(QT_CONFIG, dynamicgl): LIBS *= -lopengl32
|
||||
|
||||
mingw: LIBS *= -luuid
|
||||
# For the dialog helpers:
|
||||
@ -71,11 +71,15 @@ INCLUDEPATH += $$PWD
|
||||
contains(QT_CONFIG, opengles2) {
|
||||
SOURCES += $$PWD/qwindowseglcontext.cpp
|
||||
HEADERS += $$PWD/qwindowseglcontext.h
|
||||
} else {
|
||||
contains(QT_CONFIG, opengl) {
|
||||
SOURCES += $$PWD/qwindowsglcontext.cpp
|
||||
HEADERS += $$PWD/qwindowsglcontext.h
|
||||
}
|
||||
} else: contains(QT_CONFIG,opengl) {
|
||||
SOURCES += $$PWD/qwindowsglcontext.cpp
|
||||
HEADERS += $$PWD/qwindowsglcontext.h
|
||||
}
|
||||
|
||||
# Dynamic GL needs both WGL and EGL
|
||||
contains(QT_CONFIG,dynamicgl) {
|
||||
SOURCES += $$PWD/qwindowseglcontext.cpp
|
||||
HEADERS += $$PWD/qwindowseglcontext.h
|
||||
}
|
||||
|
||||
!contains( DEFINES, QT_NO_CLIPBOARD ) {
|
||||
|
@ -130,7 +130,7 @@ contains(QT_CONFIG, dbus) {
|
||||
}
|
||||
contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
|
||||
!contains(QT_CONFIG, no-gui) {
|
||||
win32:contains(QT_CONFIG, angle) {
|
||||
win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
|
||||
SUBDIRS += src_angle
|
||||
src_gui.depends += src_angle
|
||||
}
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <qglframebufferobject.h>
|
||||
#include <qglcolormap.h>
|
||||
#include <qpaintengine.h>
|
||||
#include <qopenglfunctions.h>
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsProxyWidget>
|
||||
@ -751,7 +752,10 @@ void tst_QGL::openGLVersionCheck()
|
||||
#elif defined(QT_OPENGL_ES_2)
|
||||
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0);
|
||||
#else
|
||||
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1);
|
||||
if (QOpenGLFunctions::isES())
|
||||
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0);
|
||||
else
|
||||
QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1);
|
||||
#endif //defined(QT_OPENGL_ES_1)
|
||||
}
|
||||
#endif //QT_BUILD_INTERNAL
|
||||
@ -1511,12 +1515,6 @@ void tst_QGL::colormap()
|
||||
QCOMPARE(cmap4.size(), 256);
|
||||
}
|
||||
|
||||
#ifndef QT_OPENGL_ES
|
||||
#define DEFAULT_FORMAT GL_RGBA8
|
||||
#else
|
||||
#define DEFAULT_FORMAT GL_RGBA
|
||||
#endif
|
||||
|
||||
#ifndef GL_TEXTURE_3D
|
||||
#define GL_TEXTURE_3D 0x806F
|
||||
#endif
|
||||
@ -1532,7 +1530,13 @@ void tst_QGL::fboFormat()
|
||||
QCOMPARE(format1.samples(), 0);
|
||||
QVERIFY(format1.attachment() == QGLFramebufferObject::NoAttachment);
|
||||
QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_2D));
|
||||
QCOMPARE(int(format1.internalTextureFormat()), int(DEFAULT_FORMAT));
|
||||
int expectedFormat =
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
GL_RGBA;
|
||||
#else
|
||||
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8;
|
||||
#endif
|
||||
QCOMPARE(int(format1.internalTextureFormat()), expectedFormat);
|
||||
|
||||
// Modify the values and re-check.
|
||||
format1.setSamples(8);
|
||||
@ -1603,14 +1607,26 @@ void tst_QGL::fboFormat()
|
||||
QGLFramebufferObjectFormat format4c;
|
||||
QVERIFY(format1c == format3c);
|
||||
QVERIFY(!(format1c != format3c));
|
||||
format3c.setInternalTextureFormat(DEFAULT_FORMAT);
|
||||
format3c.setInternalTextureFormat(
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
GL_RGBA
|
||||
#else
|
||||
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
|
||||
#endif
|
||||
);
|
||||
QVERIFY(!(format1c == format3c));
|
||||
QVERIFY(format1c != format3c);
|
||||
|
||||
format4c = format1c;
|
||||
QVERIFY(format1c == format4c);
|
||||
QVERIFY(!(format1c != format4c));
|
||||
format4c.setInternalTextureFormat(DEFAULT_FORMAT);
|
||||
format4c.setInternalTextureFormat(
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
GL_RGBA
|
||||
#else
|
||||
QOpenGLFunctions::isES() ? GL_RGBA : GL_RGBA8
|
||||
#endif
|
||||
);
|
||||
QVERIFY(!(format1c == format4c));
|
||||
QVERIFY(format1c != format4c);
|
||||
}
|
||||
|
@ -96,97 +96,99 @@ void tst_QGLFunctions::features()
|
||||
funcs.initializeGLFunctions();
|
||||
|
||||
// Validate the features against what we expect for this platform.
|
||||
#if defined(QT_OPENGL_ES_2)
|
||||
QGLFunctions::OpenGLFeatures allFeatures =
|
||||
(QGLFunctions::Multitexture |
|
||||
QGLFunctions::Shaders |
|
||||
QGLFunctions::Buffers |
|
||||
QGLFunctions::Framebuffers |
|
||||
QGLFunctions::BlendColor |
|
||||
QGLFunctions::BlendEquation |
|
||||
QGLFunctions::BlendEquationSeparate |
|
||||
QGLFunctions::BlendFuncSeparate |
|
||||
QGLFunctions::BlendSubtract |
|
||||
QGLFunctions::CompressedTextures |
|
||||
QGLFunctions::Multisample |
|
||||
QGLFunctions::StencilSeparate |
|
||||
QGLFunctions::NPOTTextures);
|
||||
QVERIFY((funcs.openGLFeatures() & allFeatures) == allFeatures);
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Shaders));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures));
|
||||
#elif defined(QT_OPENGL_ES)
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2)
|
||||
QGLFunctions::OpenGLFeatures allFeatures =
|
||||
(QGLFunctions::Multitexture |
|
||||
QGLFunctions::Shaders |
|
||||
QGLFunctions::Buffers |
|
||||
QGLFunctions::Framebuffers |
|
||||
QGLFunctions::BlendColor |
|
||||
QGLFunctions::BlendEquation |
|
||||
QGLFunctions::BlendEquationSeparate |
|
||||
QGLFunctions::BlendFuncSeparate |
|
||||
QGLFunctions::BlendSubtract |
|
||||
QGLFunctions::CompressedTextures |
|
||||
QGLFunctions::Multisample |
|
||||
QGLFunctions::StencilSeparate |
|
||||
QGLFunctions::NPOTTextures);
|
||||
QVERIFY((funcs.openGLFeatures() & allFeatures) == allFeatures);
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Shaders));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures));
|
||||
#elif defined(QT_OPENGL_ES) && !defined(QT_OPENGL_ES_2)
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multitexture));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Buffers));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures));
|
||||
QVERIFY(funcs.hasOpenGLFeature(QGLFunctions::Multisample));
|
||||
|
||||
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders));
|
||||
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
|
||||
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
|
||||
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::Shaders));
|
||||
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::BlendColor));
|
||||
QVERIFY(!funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate));
|
||||
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
|
||||
hasExtension("GL_OES_framebuffer_object"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
|
||||
hasExtension("GL_OES_blend_equation_separate"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
|
||||
hasExtension("GL_OES_blend_func_separate"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
|
||||
hasExtension("GL_OES_blend_subtract"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
|
||||
hasExtension("GL_OES_texture_npot"));
|
||||
#else
|
||||
// We check for both the extension name and the minimum OpenGL version
|
||||
// for the feature. This will help us catch situations where a platform
|
||||
// doesn't list an extension by name but does have the feature by virtue
|
||||
// of its version number.
|
||||
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multitexture),
|
||||
hasExtension("GL_ARB_multitexture") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Shaders),
|
||||
hasExtension("GL_ARB_shader_objects") ||
|
||||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Buffers),
|
||||
(versions & QGLFormat::OpenGL_Version_1_5) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
|
||||
hasExtension("GL_EXT_framebuffer_object") ||
|
||||
hasExtension("GL_ARB_framebuffer_object"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendColor),
|
||||
hasExtension("GL_EXT_blend_color") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_2) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation),
|
||||
(versions & QGLFormat::OpenGL_Version_1_2) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
|
||||
hasExtension("GL_EXT_blend_equation_separate") ||
|
||||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
|
||||
hasExtension("GL_EXT_blend_func_separate") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_4) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
|
||||
hasExtension("GL_EXT_blend_subtract"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures),
|
||||
hasExtension("GL_ARB_texture_compression") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multisample),
|
||||
hasExtension("GL_ARB_multisample") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate),
|
||||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
|
||||
hasExtension("GL_ARB_texture_non_power_of_two") ||
|
||||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
|
||||
hasExtension("GL_OES_framebuffer_object"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
|
||||
hasExtension("GL_OES_blend_equation_separate"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
|
||||
hasExtension("GL_OES_blend_func_separate"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
|
||||
hasExtension("GL_OES_blend_subtract"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
|
||||
hasExtension("GL_OES_texture_npot"));
|
||||
#endif
|
||||
} else {
|
||||
// We check for both the extension name and the minimum OpenGL version
|
||||
// for the feature. This will help us catch situations where a platform
|
||||
// doesn't list an extension by name but does have the feature by virtue
|
||||
// of its version number.
|
||||
QGLFormat::OpenGLVersionFlags versions = QGLFormat::openGLVersionFlags();
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multitexture),
|
||||
hasExtension("GL_ARB_multitexture") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Shaders),
|
||||
hasExtension("GL_ARB_shader_objects") ||
|
||||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Buffers),
|
||||
(versions & QGLFormat::OpenGL_Version_1_5) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Framebuffers),
|
||||
hasExtension("GL_EXT_framebuffer_object") ||
|
||||
hasExtension("GL_ARB_framebuffer_object"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendColor),
|
||||
hasExtension("GL_EXT_blend_color") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_2) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquation),
|
||||
(versions & QGLFormat::OpenGL_Version_1_2) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendEquationSeparate),
|
||||
hasExtension("GL_EXT_blend_equation_separate") ||
|
||||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendFuncSeparate),
|
||||
hasExtension("GL_EXT_blend_func_separate") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_4) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::BlendSubtract),
|
||||
hasExtension("GL_EXT_blend_subtract"));
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::CompressedTextures),
|
||||
hasExtension("GL_ARB_texture_compression") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::Multisample),
|
||||
hasExtension("GL_ARB_multisample") ||
|
||||
(versions & QGLFormat::OpenGL_Version_1_3) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::StencilSeparate),
|
||||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
|
||||
QCOMPARE(funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures),
|
||||
hasExtension("GL_ARB_texture_non_power_of_two") ||
|
||||
(versions & QGLFormat::OpenGL_Version_2_0) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the multitexture functions appear to resolve and work.
|
||||
|
@ -333,52 +333,55 @@ static inline float qrandom() { return (rand() % 100) / 100.f; }
|
||||
|
||||
void renderAScene(int w, int h)
|
||||
{
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
Q_UNUSED(w)
|
||||
Q_UNUSED(h)
|
||||
QGLShaderProgram program;
|
||||
program.addShaderFromSourceCode(QGLShader::Vertex, "attribute highp vec2 pos; void main() { gl_Position = vec4(pos.xy, 1.0, 1.0); }");
|
||||
program.addShaderFromSourceCode(QGLShader::Fragment, "uniform lowp vec4 color; void main() { gl_FragColor = color; }");
|
||||
program.bindAttributeLocation("pos", 0);
|
||||
program.bind();
|
||||
if (QOpenGLFunctions::isES()) {
|
||||
QGLFunctions funcs(QGLContext::currentContext());
|
||||
Q_UNUSED(w);
|
||||
Q_UNUSED(h);
|
||||
QGLShaderProgram program;
|
||||
program.addShaderFromSourceCode(QGLShader::Vertex, "attribute highp vec2 pos; void main() { gl_Position = vec4(pos.xy, 1.0, 1.0); }");
|
||||
program.addShaderFromSourceCode(QGLShader::Fragment, "uniform lowp vec4 color; void main() { gl_FragColor = color; }");
|
||||
program.bindAttributeLocation("pos", 0);
|
||||
program.bind();
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
funcs.glEnableVertexAttribArray(0);
|
||||
|
||||
for (int i=0; i<1000; ++i) {
|
||||
GLfloat pos[] = {
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f
|
||||
};
|
||||
for (int i=0; i<1000; ++i) {
|
||||
GLfloat pos[] = {
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f,
|
||||
(rand() % 100) / 100.f
|
||||
};
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
|
||||
}
|
||||
#else
|
||||
glViewport(0, 0, w, h);
|
||||
funcs.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
|
||||
}
|
||||
} else {
|
||||
#ifndef QT_OPENGL_ES_2
|
||||
glViewport(0, 0, w, h);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(0, w, h, 0, 1, 100);
|
||||
glTranslated(0, 0, -1);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(0, w, h, 0, 1, 100);
|
||||
glTranslated(0, 0, -1);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
for (int i=0;i<1000; ++i) {
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glEnd();
|
||||
}
|
||||
for (int i=0;i<1000; ++i) {
|
||||
glBegin(GL_TRIANGLES);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glColor3f(qrandom(), qrandom(), qrandom());
|
||||
glVertex2f(qrandom() * w, qrandom() * h);
|
||||
glEnd();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadSafeGLWidget : public QGLWidget
|
||||
|
@ -2596,8 +2596,8 @@ void tst_QMdiArea::nativeSubWindows()
|
||||
const QString platformName = QGuiApplication::platformName();
|
||||
if (platformName != QLatin1String("xcb") && platformName != QLatin1String("windows"))
|
||||
QSKIP(qPrintable(QString::fromLatin1("nativeSubWindows() does not work on this platform (%1).").arg(platformName)));
|
||||
#ifdef QT_OPENGL_ES_2_ANGLE
|
||||
if (platformName == QLatin1String("windows"))
|
||||
#ifdef Q_OS_WIN
|
||||
if (QOpenGLFunctions::isES())
|
||||
QSKIP("nativeSubWindows() does not work with ANGLE on Windows, QTBUG-28545.");
|
||||
#endif
|
||||
{ // Add native widgets after show.
|
||||
|
@ -259,6 +259,7 @@ Configure::Configure(int& argc, char** argv)
|
||||
dictionary[ "ICU" ] = "auto";
|
||||
|
||||
dictionary[ "ANGLE" ] = "auto";
|
||||
dictionary[ "DYNAMICGL" ] = "auto";
|
||||
|
||||
dictionary[ "GIF" ] = "auto";
|
||||
dictionary[ "JPEG" ] = "auto";
|
||||
@ -682,6 +683,8 @@ void Configure::parseCmdLine()
|
||||
dictionary[ "OPENGL_ES_2" ] = "yes";
|
||||
} else if ( configCmdLine.at(i) == "desktop" ) {
|
||||
// OPENGL=yes suffices
|
||||
} else if ( configCmdLine.at(i) == "dynamic" ) {
|
||||
dictionary[ "DYNAMICGL" ] = "yes";
|
||||
} else {
|
||||
cout << "Argument passed to -opengl option is not valid." << endl;
|
||||
dictionary[ "DONE" ] = "error";
|
||||
@ -1623,6 +1626,7 @@ void Configure::applySpecSpecifics()
|
||||
dictionary[ "CE_CRT" ] = "yes";
|
||||
dictionary[ "LARGE_FILE" ] = "no";
|
||||
dictionary[ "ANGLE" ] = "d3d11";
|
||||
dictionary[ "DYNAMICGL" ] = "no";
|
||||
if (dictionary.value("XQMAKESPEC").startsWith("winphone"))
|
||||
dictionary[ "SQL_SQLITE" ] = "no";
|
||||
} else if (dictionary.value("XQMAKESPEC").startsWith("wince")) {
|
||||
@ -1645,6 +1649,7 @@ void Configure::applySpecSpecifics()
|
||||
dictionary[ "CE_CRT" ] = "yes";
|
||||
dictionary[ "LARGE_FILE" ] = "no";
|
||||
dictionary[ "ANGLE" ] = "no";
|
||||
dictionary[ "DYNAMICGL" ] = "no";
|
||||
// We only apply MMX/IWMMXT for mkspecs we know they work
|
||||
if (dictionary[ "XQMAKESPEC" ].startsWith("wincewm")) {
|
||||
dictionary[ "MMX" ] = "yes";
|
||||
@ -1674,6 +1679,7 @@ void Configure::applySpecSpecifics()
|
||||
dictionary["LGMON"] = "auto";
|
||||
dictionary["QT_XKBCOMMON"] = "no";
|
||||
dictionary[ "ANGLE" ] = "no";
|
||||
dictionary[ "DYNAMICGL" ] = "no";
|
||||
dictionary[ "FONT_CONFIG" ] = "auto";
|
||||
} else if (platform() == ANDROID) {
|
||||
dictionary[ "REDUCE_EXPORTS" ] = "yes";
|
||||
@ -1681,6 +1687,7 @@ void Configure::applySpecSpecifics()
|
||||
dictionary[ "BUILDALL" ] = "no";
|
||||
dictionary[ "LARGE_FILE" ] = "no";
|
||||
dictionary[ "ANGLE" ] = "no";
|
||||
dictionary[ "DYNAMICGL" ] = "no";
|
||||
dictionary[ "REDUCE_RELOCATIONS" ] = "yes";
|
||||
dictionary[ "QT_GETIFADDRS" ] = "no";
|
||||
dictionary[ "QT_XKBCOMMON" ] = "no";
|
||||
@ -1792,9 +1799,10 @@ bool Configure::displayHelp()
|
||||
desc("OPENGL", "no","-no-opengl", "Do not support OpenGL.");
|
||||
desc("OPENGL", "no","-opengl <api>", "Enable OpenGL support with specified API version.\n"
|
||||
"Available values for <api>:");
|
||||
desc("", "no", "", " desktop - Enable support for Desktop OpenGL", ' ');
|
||||
desc("", "no", "", " desktop - Enable support for Desktop OpenGL", ' ');
|
||||
desc("", "no", "", " dynamic - Enable support for dynamically loaded OpenGL (either desktop or ES)", ' ');
|
||||
desc("OPENGL_ES_CM", "no", "", " es1 - Enable support for OpenGL ES Common Profile", ' ');
|
||||
desc("OPENGL_ES_2", "yes", "", " es2 - Enable support for OpenGL ES 2.0\n", ' ');
|
||||
desc("OPENGL_ES_2", "yes", "", " es2 - Enable support for OpenGL ES 2.0\n", ' ');
|
||||
|
||||
desc("OPENVG", "no","-no-openvg", "Disables OpenVG functionality.");
|
||||
desc("OPENVG", "yes","-openvg", "Enables OpenVG functionality.\n");
|
||||
@ -2299,6 +2307,10 @@ void Configure::autoDetection()
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic GL. This must be explicitly requested, no autodetection.
|
||||
if (dictionary["DYNAMICGL"] == "auto")
|
||||
dictionary["DYNAMICGL"] = "no";
|
||||
|
||||
// Image format detection
|
||||
if (dictionary["GIF"] == "auto")
|
||||
dictionary["GIF"] = defaultTo("GIF");
|
||||
@ -2503,6 +2515,13 @@ bool Configure::verifyConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
if (dictionary["DYNAMICGL"] == "yes") {
|
||||
if (dictionary["OPENGL_ES_2"] == "yes" || dictionary["ANGLE"] != "no") {
|
||||
cout << "ERROR: Dynamic OpenGL cannot be used together with native Angle (GLES2) builds." << endl;
|
||||
dictionary[ "DONE" ] = "error";
|
||||
}
|
||||
}
|
||||
|
||||
if (prompt)
|
||||
promptKeyPress();
|
||||
|
||||
@ -2580,6 +2599,10 @@ void Configure::generateOutputVars()
|
||||
qmakeConfig += "angle_d3d11";
|
||||
}
|
||||
|
||||
// Dynamic OpenGL loading ---------------------------------------
|
||||
if (dictionary[ "DYNAMICGL" ] != "no")
|
||||
qtConfig += "dynamicgl";
|
||||
|
||||
// Image formates -----------------------------------------------
|
||||
if (dictionary[ "GIF" ] == "no")
|
||||
qtConfig += "no-gif";
|
||||
@ -3460,6 +3483,7 @@ void Configure::generateConfigfiles()
|
||||
|
||||
if (dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1";
|
||||
if (dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2";
|
||||
if (dictionary["DYNAMICGL"] == "yes") qconfigList += "QT_OPENGL_DYNAMIC";
|
||||
if (dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL";
|
||||
if (dictionary["SQL_ODBC"] == "yes") qconfigList += "QT_SQL_ODBC";
|
||||
if (dictionary["SQL_OCI"] == "yes") qconfigList += "QT_SQL_OCI";
|
||||
@ -3641,6 +3665,7 @@ void Configure::displayConfig()
|
||||
sout << " LGMON support..........." << dictionary[ "LGMON" ] << endl;
|
||||
}
|
||||
sout << " ANGLE..................." << dictionary[ "ANGLE" ] << endl;
|
||||
sout << " Dynamic OpenGL.........." << dictionary[ "DYNAMICGL" ] << endl;
|
||||
sout << endl;
|
||||
|
||||
sout << "Styles:" << endl;
|
||||
|
Loading…
x
Reference in New Issue
Block a user