diff options
107 files changed, 16 insertions, 33376 deletions
diff --git a/examples/widgets/animation/sub-attaq/mainwindow.cpp b/examples/widgets/animation/sub-attaq/mainwindow.cpp index f9617a22eb..0c152c9180 100644 --- a/examples/widgets/animation/sub-attaq/mainwindow.cpp +++ b/examples/widgets/animation/sub-attaq/mainwindow.cpp @@ -59,10 +59,6 @@ #include <QMenuBar> #include <QLayout> -#ifndef QT_NO_OPENGL -# include <QtOpenGL> -#endif - MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { @@ -84,14 +80,5 @@ MainWindow::MainWindow(QWidget *parent) view = new QGraphicsView(scene, this); view->setAlignment(Qt::AlignLeft | Qt::AlignTop); scene->setupScene(newAction, quitAction); -#ifndef QT_NO_OPENGL - QGLWidget *glWidget = new QGLWidget(QGLFormat(QGL::SampleBuffers)); - if (glWidget->context()->isValid()) { - view->setViewport(glWidget); - } else { - qWarning("Unable to create an Open GL context with sample buffers, not using Open GL."); - delete glWidget; - } -#endif setCentralWidget(view); } diff --git a/examples/widgets/animation/sub-attaq/sub-attaq.pro b/examples/widgets/animation/sub-attaq/sub-attaq.pro index ac79fd4249..ea44253fa1 100644 --- a/examples/widgets/animation/sub-attaq/sub-attaq.pro +++ b/examples/widgets/animation/sub-attaq/sub-attaq.pro @@ -1,5 +1,4 @@ QT += widgets -qtHaveModule(opengl): QT += opengl HEADERS += boat.h \ bomb.h \ mainwindow.h \ diff --git a/examples/widgets/graphicsview/boxes/3rdparty/fbm.c b/examples/widgets/graphicsview/boxes/3rdparty/fbm.c deleted file mode 100644 index 3eebaabfba..0000000000 --- a/examples/widgets/graphicsview/boxes/3rdparty/fbm.c +++ /dev/null @@ -1,207 +0,0 @@ -/***************************************************************** - - Implementation of the fractional Brownian motion algorithm. These - functions were originally the work of F. Kenton Musgrave. - For documentation of the different functions please refer to the - book: - "Texturing and modeling: a procedural approach" - by David S. Ebert et. al. - -******************************************************************/ - -#if defined (_MSC_VER) -#include <qglobal.h> -#endif - -#include <time.h> -#include <stdlib.h> -#include "fbm.h" - -#if defined(Q_CC_MSVC) -#pragma warning(disable:4244) -#endif - -/* Definitions used by the noise2() functions */ - -//#define B 0x100 -//#define BM 0xff -#define B 0x20 -#define BM 0x1f - -#define N 0x1000 -#define NP 12 /* 2^N */ -#define NM 0xfff - -static int p[B + B + 2]; -static float g3[B + B + 2][3]; -static float g2[B + B + 2][2]; -static float g1[B + B + 2]; -static int start = 1; - -static void init(void); - -#define s_curve(t) ( t * t * (3. - 2. * t) ) - -#define lerp(t, a, b) ( a + t * (b - a) ) - -#define setup(i,b0,b1,r0,r1)\ - t = vec[i] + N;\ - b0 = ((int)t) & BM;\ - b1 = (b0+1) & BM;\ - r0 = t - (int)t;\ - r1 = r0 - 1.; -#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] ) - -/* Fractional Brownian Motion function */ - -double fBm( Vector point, double H, double lacunarity, double octaves, - int init ) -{ - - double value, frequency, remainder; - int i; - static double exponent_array[10]; - float vec[3]; - - /* precompute and store spectral weights */ - if ( init ) { - start = 1; - srand( time(0) ); - /* seize required memory for exponent_array */ - frequency = 1.0; - for (i=0; i<=octaves; i++) { - /* compute weight for each frequency */ - exponent_array[i] = pow( frequency, -H ); - frequency *= lacunarity; - } - } - - value = 0.0; /* initialize vars to proper values */ - frequency = 1.0; - vec[0]=point.x; - vec[1]=point.y; - vec[2]=point.z; - - - /* inner loop of spectral construction */ - for (i=0; i<octaves; i++) { - /* value += noise3( vec ) * exponent_array[i];*/ - value += noise3( vec ) * exponent_array[i]; - vec[0] *= lacunarity; - vec[1] *= lacunarity; - vec[2] *= lacunarity; - } /* for */ - - remainder = octaves - (int)octaves; - if ( remainder ) /* add in ``octaves'' remainder */ - /* ``i'' and spatial freq. are preset in loop above */ - value += remainder * noise3( vec ) * exponent_array[i]; - - return( value ); - -} /* fBm() */ - - -float noise3(float vec[3]) -{ - int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; - float rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v; - int i, j; - - if (start) { - start = 0; - init(); - } - - setup(0, bx0,bx1, rx0,rx1); - setup(1, by0,by1, ry0,ry1); - setup(2, bz0,bz1, rz0,rz1); - - i = p[ bx0 ]; - j = p[ bx1 ]; - - b00 = p[ i + by0 ]; - b10 = p[ j + by0 ]; - b01 = p[ i + by1 ]; - b11 = p[ j + by1 ]; - - t = s_curve(rx0); - sy = s_curve(ry0); - sz = s_curve(rz0); - - - q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0); - q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0); - a = lerp(t, u, v); - - q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0); - q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0); - b = lerp(t, u, v); - - c = lerp(sy, a, b); - - q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1); - q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1); - a = lerp(t, u, v); - - q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1); - q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1); - b = lerp(t, u, v); - - d = lerp(sy, a, b); - - return lerp(sz, c, d); -} - -static void normalize2(float v[2]) -{ - float s; - - s = sqrt(v[0] * v[0] + v[1] * v[1]); - v[0] = v[0] / s; - v[1] = v[1] / s; -} - -static void normalize3(float v[3]) -{ - float s; - - s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - v[0] = v[0] / s; - v[1] = v[1] / s; - v[2] = v[2] / s; -} - -static void init(void) -{ - int i, j, k; - - for (i = 0 ; i < B ; i++) { - p[i] = i; - - g1[i] = (float)((rand() % (B + B)) - B) / B; - - for (j = 0 ; j < 2 ; j++) - g2[i][j] = (float)((rand() % (B + B)) - B) / B; - normalize2(g2[i]); - - for (j = 0 ; j < 3 ; j++) - g3[i][j] = (float)((rand() % (B + B)) - B) / B; - normalize3(g3[i]); - } - - while (--i) { - k = p[i]; - p[i] = p[j = rand() % B]; - p[j] = k; - } - - for (i = 0 ; i < B + 2 ; i++) { - p[B + i] = p[i]; - g1[B + i] = g1[i]; - for (j = 0 ; j < 2 ; j++) - g2[B + i][j] = g2[i][j]; - for (j = 0 ; j < 3 ; j++) - g3[B + i][j] = g3[i][j]; - } -} diff --git a/examples/widgets/graphicsview/boxes/3rdparty/fbm.h b/examples/widgets/graphicsview/boxes/3rdparty/fbm.h deleted file mode 100644 index b8a4a99ae4..0000000000 --- a/examples/widgets/graphicsview/boxes/3rdparty/fbm.h +++ /dev/null @@ -1,40 +0,0 @@ -/***************************************************************** - - Prototypes for the fractional Brownian motion algorithm. These - functions were originally the work of F. Kenton Musgrave. For - documentation of the different functions please refer to the book: - "Texturing and modeling: a procedural approach" - by David S. Ebert et. al. - -******************************************************************/ - -#ifndef _fbm_h -#define _fbm_h - -#include <math.h> - -#ifdef __cplusplus -extern "C" { -#endif - -//#define TRUE 1 -//#define FALSE 0 - -typedef struct { - double x; - double y; - double z; -} Vector; - -float noise3(float vec[]); -double fBm( Vector point, double H, double lacunarity, double octaves, - int init ); -#endif - -#ifdef __cplusplus -} -#endif - - - - diff --git a/examples/widgets/graphicsview/boxes/basic.fsh b/examples/widgets/graphicsview/boxes/basic.fsh deleted file mode 100644 index 327daeef54..0000000000 --- a/examples/widgets/graphicsview/boxes/basic.fsh +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; -uniform vec4 basicColor; - -void main() -{ - vec3 N = normalize(normal); - // assume directional light - - gl_MaterialParameters M = gl_FrontMaterial; - - float NdotL = dot(N, lightDirection.xyz); - float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz); - - vec3 absN = abs(gl_TexCoord[1].xyz); - vec3 texCoord; - if (absN.x > absN.y && absN.x > absN.z) - texCoord = gl_TexCoord[1].yzx; - else if (absN.y > absN.z) - texCoord = gl_TexCoord[1].zxy; - else - texCoord = gl_TexCoord[1].xyz; - texCoord.y *= -sign(texCoord.z); - texCoord += 0.5; - - vec4 texColor = texture2D(tex, texCoord.xy); - vec4 unlitColor = gl_Color * mix(basicColor, vec4(texColor.xyz, 1.0), texColor.w); - gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor + - M.specular * specular * pow(max(RdotL, 0.0), M.shininess); -} diff --git a/examples/widgets/graphicsview/boxes/basic.vsh b/examples/widgets/graphicsview/boxes/basic.vsh deleted file mode 100644 index 454e0bd903..0000000000 --- a/examples/widgets/graphicsview/boxes/basic.vsh +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform mat4 view; - -void main() -{ - gl_TexCoord[0] = gl_MultiTexCoord0; - gl_TexCoord[1] = gl_Vertex; - specular = gl_LightSource[0].specular; - ambient = gl_LightSource[0].ambient; - diffuse = gl_LightSource[0].diffuse; - lightDirection = view * gl_LightSource[0].position; - - normal = gl_NormalMatrix * gl_Normal; - position = (gl_ModelViewMatrix * gl_Vertex).xyz; - - gl_FrontColor = gl_Color; - gl_Position = ftransform(); -} diff --git a/examples/widgets/graphicsview/boxes/boxes.pro b/examples/widgets/graphicsview/boxes/boxes.pro deleted file mode 100644 index 601edd6883..0000000000 --- a/examples/widgets/graphicsview/boxes/boxes.pro +++ /dev/null @@ -1,27 +0,0 @@ -QT += opengl widgets -requires(qtConfig(combobox)) - -qtConfig(opengles.|angle|dynamicgl): error("This example requires Qt to be configured with -opengl desktop") - -HEADERS += 3rdparty/fbm.h \ - glbuffers.h \ - glextensions.h \ - gltrianglemesh.h \ - qtbox.h \ - roundedbox.h \ - scene.h \ - trackball.h -SOURCES += 3rdparty/fbm.c \ - glbuffers.cpp \ - glextensions.cpp \ - main.cpp \ - qtbox.cpp \ - roundedbox.cpp \ - scene.cpp \ - trackball.cpp - -RESOURCES += boxes.qrc - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/widgets/graphicsview/boxes -INSTALLS += target diff --git a/examples/widgets/graphicsview/boxes/boxes.qrc b/examples/widgets/graphicsview/boxes/boxes.qrc deleted file mode 100644 index d27506dc5a..0000000000 --- a/examples/widgets/graphicsview/boxes/boxes.qrc +++ /dev/null @@ -1,25 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource prefix="/res/boxes"> - <file>cubemap_negx.jpg</file> - <file>cubemap_negy.jpg</file> - <file>cubemap_negz.jpg</file> - <file>cubemap_posx.jpg</file> - <file>cubemap_posy.jpg</file> - <file>cubemap_posz.jpg</file> - <file>square.jpg</file> - <file>basic.vsh</file> - <file>basic.fsh</file> - <file>dotted.fsh</file> - <file>fresnel.fsh</file> - <file>glass.fsh</file> - <file>granite.fsh</file> - <file>marble.fsh</file> - <file>reflection.fsh</file> - <file>refraction.fsh</file> - <file>wood.fsh</file> - <file>parameters.par</file> - <file>qt-logo.png</file> - <file>smiley.png</file> - <file>qt-logo.jpg</file> -</qresource> -</RCC> diff --git a/examples/widgets/graphicsview/boxes/cubemap_negx.jpg b/examples/widgets/graphicsview/boxes/cubemap_negx.jpg Binary files differdeleted file mode 100644 index 07c282eab9..0000000000 --- a/examples/widgets/graphicsview/boxes/cubemap_negx.jpg +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/cubemap_negy.jpg b/examples/widgets/graphicsview/boxes/cubemap_negy.jpg Binary files differdeleted file mode 100644 index 46cd2f9cf3..0000000000 --- a/examples/widgets/graphicsview/boxes/cubemap_negy.jpg +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/cubemap_negz.jpg b/examples/widgets/graphicsview/boxes/cubemap_negz.jpg Binary files differdeleted file mode 100644 index 40c01ddff3..0000000000 --- a/examples/widgets/graphicsview/boxes/cubemap_negz.jpg +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/cubemap_posx.jpg b/examples/widgets/graphicsview/boxes/cubemap_posx.jpg Binary files differdeleted file mode 100644 index 0b42e8a1b1..0000000000 --- a/examples/widgets/graphicsview/boxes/cubemap_posx.jpg +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/cubemap_posy.jpg b/examples/widgets/graphicsview/boxes/cubemap_posy.jpg Binary files differdeleted file mode 100644 index 2aca9b1e98..0000000000 --- a/examples/widgets/graphicsview/boxes/cubemap_posy.jpg +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/cubemap_posz.jpg b/examples/widgets/graphicsview/boxes/cubemap_posz.jpg Binary files differdeleted file mode 100644 index 2e49173848..0000000000 --- a/examples/widgets/graphicsview/boxes/cubemap_posz.jpg +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/dotted.fsh b/examples/widgets/graphicsview/boxes/dotted.fsh deleted file mode 100644 index 5cbf590e21..0000000000 --- a/examples/widgets/graphicsview/boxes/dotted.fsh +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; - -void main() -{ - vec3 N = normalize(normal); - - gl_MaterialParameters M = gl_FrontMaterial; - - // assume directional light - float NdotL = dot(N, lightDirection.xyz); - float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz); - - float r1 = length(fract(7.0 * gl_TexCoord[1].xyz) - 0.5); - float r2 = length(fract(5.0 * gl_TexCoord[1].xyz + 0.2) - 0.5); - float r3 = length(fract(11.0 * gl_TexCoord[1].xyz + 0.7) - 0.5); - vec4 rs = vec4(r1, r2, r3, 0.0); - - vec4 unlitColor = gl_Color * (0.8 - clamp(10.0 * (0.4 - rs), 0.0, 0.2)); - unlitColor.w = 1.0; - gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor + - M.specular * specular * pow(max(RdotL, 0.0), M.shininess); -} diff --git a/examples/widgets/graphicsview/boxes/fresnel.fsh b/examples/widgets/graphicsview/boxes/fresnel.fsh deleted file mode 100644 index 6758ad5770..0000000000 --- a/examples/widgets/graphicsview/boxes/fresnel.fsh +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; -uniform samplerCube env; -uniform mat4 view; -uniform vec4 basicColor; - -void main() -{ - vec3 N = normalize(normal); - // assume directional light - - gl_MaterialParameters M = gl_FrontMaterial; - - float NdotL = dot(N, lightDirection.xyz); - float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz); - - vec3 absN = abs(gl_TexCoord[1].xyz); - vec3 texCoord; - if (absN.x > absN.y && absN.x > absN.z) - texCoord = gl_TexCoord[1].yzx; - else if (absN.y > absN.z) - texCoord = gl_TexCoord[1].zxy; - else - texCoord = gl_TexCoord[1].xyz; - texCoord.y *= -sign(texCoord.z); - texCoord += 0.5; - - vec4 texColor = texture2D(tex, texCoord.xy); - vec4 unlitColor = gl_Color * mix(basicColor, vec4(texColor.xyz, 1.0), texColor.w); - vec4 litColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor + - M.specular * specular * pow(max(RdotL, 0.0), M.shininess); - - vec3 R = 2.0 * dot(-position, N) * N + position; - vec4 reflectedColor = textureCube(env, R * mat3(view[0].xyz, view[1].xyz, view[2].xyz)); - gl_FragColor = mix(litColor, reflectedColor, 0.2 + 0.8 * pow(1.0 + dot(N, normalize(position)), 2.0)); -} diff --git a/examples/widgets/graphicsview/boxes/glass.fsh b/examples/widgets/graphicsview/boxes/glass.fsh deleted file mode 100644 index 528d04e4d3..0000000000 --- a/examples/widgets/graphicsview/boxes/glass.fsh +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; -uniform samplerCube env; -uniform mat4 view; - -// Some arbitrary values -// Arrays don't work here on glsl < 120, apparently. -//const float coeffs[6] = float[6](1.0/4.0, 1.0/4.1, 1.0/4.2, 1.0/4.3, 1.0/4.4, 1.0/4.5); -float coeffs(int i) -{ - return 1.0 / (3.0 + 0.1 * float(i)); -} - -void main() -{ - vec3 N = normalize(normal); - vec3 I = -normalize(position); - mat3 V = mat3(view[0].xyz, view[1].xyz, view[2].xyz); - float IdotN = dot(I, N); - float scales[6]; - vec3 C[6]; - for (int i = 0; i < 6; ++i) { - scales[i] = (IdotN - sqrt(1.0 - coeffs(i) + coeffs(i) * (IdotN * IdotN))); - C[i] = textureCube(env, (-I + coeffs(i) * N) * V).xyz; - } - vec4 refractedColor = 0.25 * vec4(C[5].x + 2.0*C[0].x + C[1].x, C[1].y + 2.0*C[2].y + C[3].y, - C[3].z + 2.0*C[4].z + C[5].z, 4.0); - - vec3 R = 2.0 * dot(-position, N) * N + position; - vec4 reflectedColor = textureCube(env, R * V); - - gl_FragColor = mix(refractedColor, reflectedColor, 0.4 + 0.6 * pow(1.0 - IdotN, 2.0)); -} diff --git a/examples/widgets/graphicsview/boxes/glbuffers.cpp b/examples/widgets/graphicsview/boxes/glbuffers.cpp deleted file mode 100644 index 91de336af3..0000000000 --- a/examples/widgets/graphicsview/boxes/glbuffers.cpp +++ /dev/null @@ -1,406 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "glbuffers.h" - -void qgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) -{ - const GLdouble ymax = zNear * tan(qDegreesToRadians(fovy) / 2.0); - const GLdouble ymin = -ymax; - const GLdouble xmin = ymin * aspect; - const GLdouble xmax = ymax * aspect; - glFrustum(xmin, xmax, ymin, ymax, zNear, zFar); -} - -//============================================================================// -// GLTexture // -//============================================================================// - -GLTexture::GLTexture() -{ - glGenTextures(1, &m_texture); -} - -GLTexture::~GLTexture() -{ - glDeleteTextures(1, &m_texture); -} - -//============================================================================// -// GLTexture2D // -//============================================================================// - -GLTexture2D::GLTexture2D(int width, int height) -{ - glBindTexture(GL_TEXTURE_2D, m_texture); - glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, - GL_BGRA, GL_UNSIGNED_BYTE, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - glBindTexture(GL_TEXTURE_2D, 0); -} - - -GLTexture2D::GLTexture2D(const QString &fileName, int width, int height) -{ - // TODO: Add error handling. - QImage image(fileName); - - if (image.isNull()) { - m_failed = true; - return; - } - - image = image.convertToFormat(QImage::Format_ARGB32); - - //qDebug() << "Image size:" << image.width() << "x" << image.height(); - if (width <= 0) - width = image.width(); - if (height <= 0) - height = image.height(); - if (width != image.width() || height != image.height()) - image = image.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - - glBindTexture(GL_TEXTURE_2D, m_texture); - - // Works on x86, so probably works on all little-endian systems. - // Does it work on big-endian systems? - glTexImage2D(GL_TEXTURE_2D, 0, 4, image.width(), image.height(), 0, - GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - glBindTexture(GL_TEXTURE_2D, 0); -} - -void GLTexture2D::load(int width, int height, QRgb *data) -{ - glBindTexture(GL_TEXTURE_2D, m_texture); - glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, - GL_BGRA, GL_UNSIGNED_BYTE, data); - glBindTexture(GL_TEXTURE_2D, 0); -} - -void GLTexture2D::bind() -{ - glBindTexture(GL_TEXTURE_2D, m_texture); - glEnable(GL_TEXTURE_2D); -} - -void GLTexture2D::unbind() -{ - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); -} - - -//============================================================================// -// GLTexture3D // -//============================================================================// - -GLTexture3D::GLTexture3D(int width, int height, int depth) -{ - GLBUFFERS_ASSERT_OPENGL("GLTexture3D::GLTexture3D", glTexImage3D, return) - - glBindTexture(GL_TEXTURE_3D, m_texture); - glTexImage3D(GL_TEXTURE_3D, 0, 4, width, height, depth, 0, - GL_BGRA, GL_UNSIGNED_BYTE, nullptr); - - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - //glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP, GL_TRUE); - glBindTexture(GL_TEXTURE_3D, 0); -} - -void GLTexture3D::load(int width, int height, int depth, QRgb *data) -{ - GLBUFFERS_ASSERT_OPENGL("GLTexture3D::load", glTexImage3D, return) - - glBindTexture(GL_TEXTURE_3D, m_texture); - glTexImage3D(GL_TEXTURE_3D, 0, 4, width, height, depth, 0, - GL_BGRA, GL_UNSIGNED_BYTE, data); - glBindTexture(GL_TEXTURE_3D, 0); -} - -void GLTexture3D::bind() -{ - glBindTexture(GL_TEXTURE_3D, m_texture); - glEnable(GL_TEXTURE_3D); -} - -void GLTexture3D::unbind() -{ - glBindTexture(GL_TEXTURE_3D, 0); - glDisable(GL_TEXTURE_3D); -} - -//============================================================================// -// GLTextureCube // -//============================================================================// - -GLTextureCube::GLTextureCube(int size) -{ - glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture); - - for (int i = 0; i < 6; ++i) - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 4, size, size, 0, - GL_BGRA, GL_UNSIGNED_BYTE, nullptr); - - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE); - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); -} - -GLTextureCube::GLTextureCube(const QStringList &fileNames, int size) -{ - // TODO: Add error handling. - - glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture); - - int index = 0; - for (const QString &file : fileNames) { - QImage image(file); - if (image.isNull()) { - m_failed = true; - break; - } - - image = image.convertToFormat(QImage::Format_ARGB32); - - //qDebug() << "Image size:" << image.width() << "x" << image.height(); - if (size <= 0) - size = image.width(); - if (size != image.width() || size != image.height()) - image = image.scaled(size, size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - - // Works on x86, so probably works on all little-endian systems. - // Does it work on big-endian systems? - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index, 0, 4, image.width(), image.height(), 0, - GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); - - if (++index == 6) - break; - } - - // Clear remaining faces. - while (index < 6) { - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index, 0, 4, size, size, 0, - GL_BGRA, GL_UNSIGNED_BYTE, nullptr); - ++index; - } - - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - //glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE); - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); -} - -void GLTextureCube::load(int size, int face, QRgb *data) -{ - glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture); - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, 4, size, size, 0, - GL_BGRA, GL_UNSIGNED_BYTE, data); - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); -} - -void GLTextureCube::bind() -{ - glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture); - glEnable(GL_TEXTURE_CUBE_MAP); -} - -void GLTextureCube::unbind() -{ - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); - glDisable(GL_TEXTURE_CUBE_MAP); -} - -//============================================================================// -// GLFrameBufferObject // -//============================================================================// - -GLFrameBufferObject::GLFrameBufferObject(int width, int height) - : m_width(width) - , m_height(height) -{ - GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::GLFrameBufferObject", - glGenFramebuffersEXT && glGenRenderbuffersEXT && glBindRenderbufferEXT && glRenderbufferStorageEXT, return) - - // TODO: share depth buffers of same size - glGenFramebuffersEXT(1, &m_fbo); - //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - glGenRenderbuffersEXT(1, &m_depthBuffer); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height); - //glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); - //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -} - -GLFrameBufferObject::~GLFrameBufferObject() -{ - GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::~GLFrameBufferObject", - glDeleteFramebuffersEXT && glDeleteRenderbuffersEXT, return) - - glDeleteFramebuffersEXT(1, &m_fbo); - glDeleteRenderbuffersEXT(1, &m_depthBuffer); -} - -void GLFrameBufferObject::setAsRenderTarget(bool state) -{ - GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::setAsRenderTarget", glBindFramebufferEXT, return) - - if (state) { - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - glPushAttrib(GL_VIEWPORT_BIT); - glViewport(0, 0, m_width, m_height); - } else { - glPopAttrib(); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - } -} - -bool GLFrameBufferObject::isComplete() -{ - GLBUFFERS_ASSERT_OPENGL("GLFrameBufferObject::isComplete", glCheckFramebufferStatusEXT, return false) - - return GL_FRAMEBUFFER_COMPLETE_EXT == glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); -} - -//============================================================================// -// GLRenderTargetCube // -//============================================================================// - -GLRenderTargetCube::GLRenderTargetCube(int size) - : GLTextureCube(size) - , m_fbo(size, size) -{ -} - -void GLRenderTargetCube::begin(int face) -{ - GLBUFFERS_ASSERT_OPENGL("GLRenderTargetCube::begin", - glFramebufferTexture2DEXT && glFramebufferRenderbufferEXT, return) - - m_fbo.setAsRenderTarget(true); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, m_texture, 0); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_fbo.m_depthBuffer); -} - -void GLRenderTargetCube::end() -{ - m_fbo.setAsRenderTarget(false); -} - -void GLRenderTargetCube::getViewMatrix(QMatrix4x4& mat, int face) -{ - if (face < 0 || face >= 6) { - qWarning("GLRenderTargetCube::getViewMatrix: 'face' must be in the range [0, 6). (face == %d)", face); - return; - } - - static constexpr int perm[6][3] = { - {2, 1, 0}, - {2, 1, 0}, - {0, 2, 1}, - {0, 2, 1}, - {0, 1, 2}, - {0, 1, 2}, - }; - - static constexpr float signs[6][3] = { - {-1.0f, -1.0f, -1.0f}, - {+1.0f, -1.0f, +1.0f}, - {+1.0f, +1.0f, -1.0f}, - {+1.0f, -1.0f, +1.0f}, - {+1.0f, -1.0f, -1.0f}, - {-1.0f, -1.0f, +1.0f}, - }; - - mat.fill(0.0f); - for (int i = 0; i < 3; ++i) - mat(i, perm[face][i]) = signs[face][i]; - mat(3, 3) = 1.0f; -} - -void GLRenderTargetCube::getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ) -{ - static const QMatrix4x4 reference( - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, -1.0f, 0.0f); - - mat = reference; - mat(2, 2) = (nearZ+farZ)/(nearZ-farZ); - mat(2, 3) = 2.0f*nearZ*farZ/(nearZ-farZ); -} diff --git a/examples/widgets/graphicsview/boxes/glbuffers.h b/examples/widgets/graphicsview/boxes/glbuffers.h deleted file mode 100644 index 4318e8ac24..0000000000 --- a/examples/widgets/graphicsview/boxes/glbuffers.h +++ /dev/null @@ -1,372 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GLBUFFERS_H -#define GLBUFFERS_H - -//#include <GL/glew.h> -#include "glextensions.h" - -#include <QtWidgets> -#include <QtOpenGL> - -#define BUFFER_OFFSET(i) ((char*)0 + (i)) -#define SIZE_OF_MEMBER(cls, member) sizeof(static_cast<cls *>(nullptr)->member) - -#define GLBUFFERS_ASSERT_OPENGL(prefix, assertion, returnStatement) \ -if (m_failed || !(assertion)) { \ - if (!m_failed) qCritical(prefix ": The necessary OpenGL functions are not available."); \ - m_failed = true; \ - returnStatement; \ -} - -void qgluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); - -QT_BEGIN_NAMESPACE -class QMatrix4x4; -QT_END_NAMESPACE - -class GLTexture -{ -public: - GLTexture(); - virtual ~GLTexture(); - virtual void bind() = 0; - virtual void unbind() = 0; - virtual bool failed() const {return m_failed;} -protected: - GLuint m_texture = 0; - bool m_failed = false; -}; - -class GLFrameBufferObject -{ -public: - friend class GLRenderTargetCube; - // friend class GLRenderTarget2D; - - GLFrameBufferObject(int width, int height); - virtual ~GLFrameBufferObject(); - bool isComplete(); - virtual bool failed() const {return m_failed;} -protected: - void setAsRenderTarget(bool state = true); - GLuint m_fbo = 0; - GLuint m_depthBuffer = 0; - int m_width, m_height; - bool m_failed = false; -}; - -class GLTexture2D : public GLTexture -{ -public: - GLTexture2D(int width, int height); - explicit GLTexture2D(const QString &fileName, int width = 0, int height = 0); - void load(int width, int height, QRgb *data); - void bind() override; - void unbind() override; -}; - -class GLTexture3D : public GLTexture -{ -public: - GLTexture3D(int width, int height, int depth); - // TODO: Implement function below - //GLTexture3D(const QString& fileName, int width = 0, int height = 0); - void load(int width, int height, int depth, QRgb *data); - void bind() override; - void unbind() override; -}; - -class GLTextureCube : public GLTexture -{ -public: - GLTextureCube(int size); - explicit GLTextureCube(const QStringList &fileNames, int size = 0); - void load(int size, int face, QRgb *data); - void bind() override; - void unbind() override; -}; - -// TODO: Define and implement class below -//class GLRenderTarget2D : public GLTexture2D - -class GLRenderTargetCube : public GLTextureCube -{ -public: - GLRenderTargetCube(int size); - // begin rendering to one of the cube's faces. 0 <= face < 6 - void begin(int face); - // end rendering - void end(); - bool failed() const override { return m_failed || m_fbo.failed(); } - - static void getViewMatrix(QMatrix4x4& mat, int face); - static void getProjectionMatrix(QMatrix4x4& mat, float nearZ, float farZ); -private: - GLFrameBufferObject m_fbo; -}; - -struct VertexDescription -{ - enum - { - Null = 0, // Terminates a VertexDescription array - Position, - TexCoord, - Normal, - Color, - }; - int field; // Position, TexCoord, Normal, Color - int type; // GL_FLOAT, GL_UNSIGNED_BYTE - int count; // number of elements - int offset; // field's offset into vertex struct - int index; // 0 (unused at the moment) -}; - -// Implementation of interleaved buffers. -// 'T' is a struct which must include a null-terminated static array -// 'VertexDescription* description'. -// Example: -/* -struct Vertex -{ - GLfloat position[3]; - GLfloat texCoord[2]; - GLfloat normal[3]; - GLbyte color[4]; - static VertexDescription description[]; -}; - -VertexDescription Vertex::description[] = { - {VertexDescription::Position, GL_FLOAT, SIZE_OF_MEMBER(Vertex, position) / sizeof(GLfloat), offsetof(Vertex, position), 0}, - {VertexDescription::TexCoord, GL_FLOAT, SIZE_OF_MEMBER(Vertex, texCoord) / sizeof(GLfloat), offsetof(Vertex, texCoord), 0}, - {VertexDescription::Normal, GL_FLOAT, SIZE_OF_MEMBER(Vertex, normal) / sizeof(GLfloat), offsetof(Vertex, normal), 0}, - {VertexDescription::Color, GL_BYTE, SIZE_OF_MEMBER(Vertex, color) / sizeof(GLbyte), offsetof(Vertex, color), 0}, - {VertexDescription::Null, 0, 0, 0, 0}, -}; -*/ -template<class T> -class GLVertexBuffer -{ -public: - GLVertexBuffer(int length, const T *data = nullptr, int mode = GL_STATIC_DRAW) - { - GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::GLVertexBuffer", glGenBuffers && glBindBuffer && glBufferData, return) - - glGenBuffers(1, &m_buffer); - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode); - } - - ~GLVertexBuffer() - { - GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::~GLVertexBuffer", glDeleteBuffers, return) - - glDeleteBuffers(1, &m_buffer); - } - - void bind() - { - GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::bind", glBindBuffer, return) - - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - for (VertexDescription *desc = T::description; desc->field != VertexDescription::Null; ++desc) { - switch (desc->field) { - case VertexDescription::Position: - glVertexPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset)); - glEnableClientState(GL_VERTEX_ARRAY); - break; - case VertexDescription::TexCoord: - glTexCoordPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset)); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - break; - case VertexDescription::Normal: - glNormalPointer(desc->type, sizeof(T), BUFFER_OFFSET(desc->offset)); - glEnableClientState(GL_NORMAL_ARRAY); - break; - case VertexDescription::Color: - glColorPointer(desc->count, desc->type, sizeof(T), BUFFER_OFFSET(desc->offset)); - glEnableClientState(GL_COLOR_ARRAY); - break; - default: - break; - } - } - } - - void unbind() - { - GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unbind", glBindBuffer, return) - - glBindBuffer(GL_ARRAY_BUFFER, 0); - for (VertexDescription *desc = T::description; desc->field != VertexDescription::Null; ++desc) { - switch (desc->field) { - case VertexDescription::Position: - glDisableClientState(GL_VERTEX_ARRAY); - break; - case VertexDescription::TexCoord: - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - break; - case VertexDescription::Normal: - glDisableClientState(GL_NORMAL_ARRAY); - break; - case VertexDescription::Color: - glDisableClientState(GL_COLOR_ARRAY); - break; - default: - break; - } - } - } - - int length() const {return m_length;} - - T *lock() - { - GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::lock", glBindBuffer && glMapBuffer, return nullptr) - - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - //glBufferData(GL_ARRAY_BUFFER, m_length, NULL, m_mode); - GLvoid* buffer = glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); - m_failed = (buffer == nullptr); - return reinterpret_cast<T *>(buffer); - } - - void unlock() - { - GLBUFFERS_ASSERT_OPENGL("GLVertexBuffer::unlock", glBindBuffer && glUnmapBuffer, return) - - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - glUnmapBuffer(GL_ARRAY_BUFFER); - } - - bool failed() - { - return m_failed; - } - -private: - int m_length = 0; - int m_mode = 0; - GLuint m_buffer = 0; - bool m_failed = false; -}; - -template<class T> -class GLIndexBuffer -{ -public: - GLIndexBuffer(int length, const T *data = nullptr, int mode = GL_STATIC_DRAW) - : m_length(0) - , m_mode(mode) - , m_buffer(0) - , m_failed(false) - { - GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::GLIndexBuffer", glGenBuffers && glBindBuffer && glBufferData, return) - - glGenBuffers(1, &m_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, (m_length = length) * sizeof(T), data, mode); - } - - ~GLIndexBuffer() - { - GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::~GLIndexBuffer", glDeleteBuffers, return) - - glDeleteBuffers(1, &m_buffer); - } - - void bind() - { - GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::bind", glBindBuffer, return) - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - } - - void unbind() - { - GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unbind", glBindBuffer, return) - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } - - int length() const {return m_length;} - - T *lock() - { - GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::lock", glBindBuffer && glMapBuffer, return nullptr) - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - GLvoid* buffer = glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_READ_WRITE); - m_failed = (buffer == nullptr); - return reinterpret_cast<T *>(buffer); - } - - void unlock() - { - GLBUFFERS_ASSERT_OPENGL("GLIndexBuffer::unlock", glBindBuffer && glUnmapBuffer, return) - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - } - - bool failed() - { - return m_failed; - } - -private: - int m_length, m_mode; - GLuint m_buffer; - bool m_failed; -}; - -#endif diff --git a/examples/widgets/graphicsview/boxes/glextensions.cpp b/examples/widgets/graphicsview/boxes/glextensions.cpp deleted file mode 100644 index ac89911046..0000000000 --- a/examples/widgets/graphicsview/boxes/glextensions.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "glextensions.h" - -#define RESOLVE_GL_FUNC(f) ok &= bool((f = (_gl##f) context->getProcAddress(QLatin1String("gl" #f)))); - -bool GLExtensionFunctions::resolve(const QGLContext *context) -{ - bool ok = true; - - RESOLVE_GL_FUNC(GenFramebuffersEXT) - RESOLVE_GL_FUNC(GenRenderbuffersEXT) - RESOLVE_GL_FUNC(BindRenderbufferEXT) - RESOLVE_GL_FUNC(RenderbufferStorageEXT) - RESOLVE_GL_FUNC(DeleteFramebuffersEXT) - RESOLVE_GL_FUNC(DeleteRenderbuffersEXT) - RESOLVE_GL_FUNC(BindFramebufferEXT) - RESOLVE_GL_FUNC(FramebufferTexture2DEXT) - RESOLVE_GL_FUNC(FramebufferRenderbufferEXT) - RESOLVE_GL_FUNC(CheckFramebufferStatusEXT) - - RESOLVE_GL_FUNC(ActiveTexture) - RESOLVE_GL_FUNC(TexImage3D) - - RESOLVE_GL_FUNC(GenBuffers) - RESOLVE_GL_FUNC(BindBuffer) - RESOLVE_GL_FUNC(BufferData) - RESOLVE_GL_FUNC(DeleteBuffers) - RESOLVE_GL_FUNC(MapBuffer) - RESOLVE_GL_FUNC(UnmapBuffer) - - return ok; -} - -bool GLExtensionFunctions::fboSupported() { - return GenFramebuffersEXT - && GenRenderbuffersEXT - && BindRenderbufferEXT - && RenderbufferStorageEXT - && DeleteFramebuffersEXT - && DeleteRenderbuffersEXT - && BindFramebufferEXT - && FramebufferTexture2DEXT - && FramebufferRenderbufferEXT - && CheckFramebufferStatusEXT; -} - -bool GLExtensionFunctions::openGL15Supported() { - return ActiveTexture - && TexImage3D - && GenBuffers - && BindBuffer - && BufferData - && DeleteBuffers - && MapBuffer - && UnmapBuffer; -} - -#undef RESOLVE_GL_FUNC diff --git a/examples/widgets/graphicsview/boxes/glextensions.h b/examples/widgets/graphicsview/boxes/glextensions.h deleted file mode 100644 index 685700d866..0000000000 --- a/examples/widgets/graphicsview/boxes/glextensions.h +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GLEXTENSIONS_H -#define GLEXTENSIONS_H - -#include <QtOpenGL> - -/* -Functions resolved: - -glGenFramebuffersEXT -glGenRenderbuffersEXT -glBindRenderbufferEXT -glRenderbufferStorageEXT -glDeleteFramebuffersEXT -glDeleteRenderbuffersEXT -glBindFramebufferEXT -glFramebufferTexture2DEXT -glFramebufferRenderbufferEXT -glCheckFramebufferStatusEXT - -glActiveTexture -glTexImage3D - -glGenBuffers -glBindBuffer -glBufferData -glDeleteBuffers -glMapBuffer -glUnmapBuffer -*/ - -#ifndef APIENTRY -# define APIENTRY -#endif -#ifndef APIENTRYP -# define APIENTRYP APIENTRY * -#endif - -#ifndef GL_VERSION_1_2 -#define GL_TEXTURE_3D 0x806F -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_BGRA 0x80E1 -#endif - -#ifndef GL_VERSION_1_3 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -//#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -//#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -//#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#endif - -#ifndef GL_ARB_vertex_buffer_object -typedef ptrdiff_t GLsizeiptrARB; -#endif - -#ifndef GL_VERSION_1_5 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_READ_WRITE 0x88BA -#define GL_STATIC_DRAW 0x88E4 -#endif - -#ifndef GL_EXT_framebuffer_object -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#endif - -typedef void (APIENTRY *_glGenFramebuffersEXT) (GLsizei, GLuint *); -typedef void (APIENTRY *_glGenRenderbuffersEXT) (GLsizei, GLuint *); -typedef void (APIENTRY *_glBindRenderbufferEXT) (GLenum, GLuint); -typedef void (APIENTRY *_glRenderbufferStorageEXT) (GLenum, GLenum, GLsizei, GLsizei); -typedef void (APIENTRY *_glDeleteFramebuffersEXT) (GLsizei, const GLuint*); -typedef void (APIENTRY *_glDeleteRenderbuffersEXT) (GLsizei, const GLuint*); -typedef void (APIENTRY *_glBindFramebufferEXT) (GLenum, GLuint); -typedef void (APIENTRY *_glFramebufferTexture2DEXT) (GLenum, GLenum, GLenum, GLuint, GLint); -typedef void (APIENTRY *_glFramebufferRenderbufferEXT) (GLenum, GLenum, GLenum, GLuint); -typedef GLenum (APIENTRY *_glCheckFramebufferStatusEXT) (GLenum); - -typedef void (APIENTRY *_glActiveTexture) (GLenum); -typedef void (APIENTRY *_glTexImage3D) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); - -typedef void (APIENTRY *_glGenBuffers) (GLsizei, GLuint *); -typedef void (APIENTRY *_glBindBuffer) (GLenum, GLuint); -typedef void (APIENTRY *_glBufferData) (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); -typedef void (APIENTRY *_glDeleteBuffers) (GLsizei, const GLuint *); -typedef void *(APIENTRY *_glMapBuffer) (GLenum, GLenum); -typedef GLboolean (APIENTRY *_glUnmapBuffer) (GLenum); - -struct GLExtensionFunctions -{ - bool resolve(const QGLContext *context); - - bool fboSupported(); - bool openGL15Supported(); // the rest: multi-texture, 3D-texture, vertex buffer objects - - _glGenFramebuffersEXT GenFramebuffersEXT; - _glGenRenderbuffersEXT GenRenderbuffersEXT; - _glBindRenderbufferEXT BindRenderbufferEXT; - _glRenderbufferStorageEXT RenderbufferStorageEXT; - _glDeleteFramebuffersEXT DeleteFramebuffersEXT; - _glDeleteRenderbuffersEXT DeleteRenderbuffersEXT; - _glBindFramebufferEXT BindFramebufferEXT; - _glFramebufferTexture2DEXT FramebufferTexture2DEXT; - _glFramebufferRenderbufferEXT FramebufferRenderbufferEXT; - _glCheckFramebufferStatusEXT CheckFramebufferStatusEXT; - - _glActiveTexture ActiveTexture; - _glTexImage3D TexImage3D; - - _glGenBuffers GenBuffers; - _glBindBuffer BindBuffer; - _glBufferData BufferData; - _glDeleteBuffers DeleteBuffers; - _glMapBuffer MapBuffer; - _glUnmapBuffer UnmapBuffer; -}; - -inline GLExtensionFunctions &getGLExtensionFunctions() -{ - static GLExtensionFunctions funcs; - return funcs; -} - -#define glGenFramebuffersEXT getGLExtensionFunctions().GenFramebuffersEXT -#define glGenRenderbuffersEXT getGLExtensionFunctions().GenRenderbuffersEXT -#define glBindRenderbufferEXT getGLExtensionFunctions().BindRenderbufferEXT -#define glRenderbufferStorageEXT getGLExtensionFunctions().RenderbufferStorageEXT -#define glDeleteFramebuffersEXT getGLExtensionFunctions().DeleteFramebuffersEXT -#define glDeleteRenderbuffersEXT getGLExtensionFunctions().DeleteRenderbuffersEXT -#define glBindFramebufferEXT getGLExtensionFunctions().BindFramebufferEXT -#define glFramebufferTexture2DEXT getGLExtensionFunctions().FramebufferTexture2DEXT -#define glFramebufferRenderbufferEXT getGLExtensionFunctions().FramebufferRenderbufferEXT -#define glCheckFramebufferStatusEXT getGLExtensionFunctions().CheckFramebufferStatusEXT - -#define glActiveTexture getGLExtensionFunctions().ActiveTexture -#define glTexImage3D getGLExtensionFunctions().TexImage3D - -#define glGenBuffers getGLExtensionFunctions().GenBuffers -#define glBindBuffer getGLExtensionFunctions().BindBuffer -#define glBufferData getGLExtensionFunctions().BufferData -#define glDeleteBuffers getGLExtensionFunctions().DeleteBuffers -#define glMapBuffer getGLExtensionFunctions().MapBuffer -#define glUnmapBuffer getGLExtensionFunctions().UnmapBuffer - -#endif diff --git a/examples/widgets/graphicsview/boxes/gltrianglemesh.h b/examples/widgets/graphicsview/boxes/gltrianglemesh.h deleted file mode 100644 index e5c4f51514..0000000000 --- a/examples/widgets/graphicsview/boxes/gltrianglemesh.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GLTRIANGLEMESH_H -#define GLTRIANGLEMESH_H - -#include "glbuffers.h" -#include "glextensions.h" - -#include <QtWidgets> -#include <QtOpenGL> - - -template<class TVertex, class TIndex> -class GLTriangleMesh -{ -public: - GLTriangleMesh(int vertexCount, int indexCount) : m_vb(vertexCount), m_ib(indexCount) - { - } - - virtual ~GLTriangleMesh() - { - } - - virtual void draw() - { - if (failed()) - return; - - int type = GL_UNSIGNED_INT; - if (sizeof(TIndex) == sizeof(char)) type = GL_UNSIGNED_BYTE; - if (sizeof(TIndex) == sizeof(short)) type = GL_UNSIGNED_SHORT; - - m_vb.bind(); - m_ib.bind(); - glDrawElements(GL_TRIANGLES, m_ib.length(), type, BUFFER_OFFSET(0)); - m_vb.unbind(); - m_ib.unbind(); - } - - bool failed() - { - return m_vb.failed() || m_ib.failed(); - } -protected: - GLVertexBuffer<TVertex> m_vb; - GLIndexBuffer<TIndex> m_ib; -}; - - -#endif diff --git a/examples/widgets/graphicsview/boxes/granite.fsh b/examples/widgets/graphicsview/boxes/granite.fsh deleted file mode 100644 index 5dcde5d2b1..0000000000 --- a/examples/widgets/graphicsview/boxes/granite.fsh +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; -uniform sampler3D noise; - -//const vec4 graniteColors[3] = {vec4(0.0, 0.0, 0.0, 1), vec4(0.30, 0.15, 0.10, 1), vec4(0.80, 0.70, 0.75, 1)}; -uniform vec4 graniteColors[3]; - -float steep(float x) -{ - return clamp(5.0 * x - 2.0, 0.0, 1.0); -} - -void main() -{ - vec2 turbulence = vec2(0, 0); - float scale = 1.0; - for (int i = 0; i < 4; ++i) { - turbulence += scale * (texture3D(noise, gl_TexCoord[1].xyz / scale).xy - 0.5); - scale *= 0.5; - } - - vec3 N = normalize(normal); - // assume directional light - - gl_MaterialParameters M = gl_FrontMaterial; - - float NdotL = dot(N, lightDirection.xyz); - float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz); - - vec4 unlitColor = mix(graniteColors[1], mix(graniteColors[0], graniteColors[2], steep(0.5 + turbulence.y)), 4.0 * abs(turbulence.x)); - gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor + - M.specular * specular * pow(max(RdotL, 0.0), M.shininess); -} diff --git a/examples/widgets/graphicsview/boxes/main.cpp b/examples/widgets/graphicsview/boxes/main.cpp deleted file mode 100644 index 2b3e6d3389..0000000000 --- a/examples/widgets/graphicsview/boxes/main.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "glextensions.h" -#include "scene.h" - -#include <QGLWidget> -#include <QtWidgets> - -class GraphicsView : public QGraphicsView -{ -public: - GraphicsView() - { - setWindowTitle(tr("Boxes")); - setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - //setRenderHints(QPainter::SmoothPixmapTransform); - } - -protected: - void resizeEvent(QResizeEvent *event) override { - if (scene()) - scene()->setSceneRect(QRect(QPoint(0, 0), event->size())); - QGraphicsView::resizeEvent(event); - } -}; - -inline bool matchString(const char *extensionString, const char *subString) -{ - int subStringLength = strlen(subString); - return (strncmp(extensionString, subString, subStringLength) == 0) - && ((extensionString[subStringLength] == ' ') || (extensionString[subStringLength] == '\0')); -} - -bool necessaryExtensionsSupported() -{ - const char *extensionString = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)); - const char *p = extensionString; - - const int GL_EXT_FBO = 1; - const int GL_ARB_VS = 2; - const int GL_ARB_FS = 4; - const int GL_ARB_SO = 8; - int extensions = 0; - - while (*p) { - if (matchString(p, "GL_EXT_framebuffer_object")) - extensions |= GL_EXT_FBO; - else if (matchString(p, "GL_ARB_vertex_shader")) - extensions |= GL_ARB_VS; - else if (matchString(p, "GL_ARB_fragment_shader")) - extensions |= GL_ARB_FS; - else if (matchString(p, "GL_ARB_shader_objects")) - extensions |= GL_ARB_SO; - while ((*p != ' ') && (*p != '\0')) - ++p; - if (*p == ' ') - ++p; - } - return (extensions == 15); -} - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - - if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_5) == 0) { - QMessageBox::critical(nullptr, "OpenGL features missing", - "OpenGL version 1.5 or higher is required to run this demo.\n" - "The program will now exit."); - return -1; - } - - int maxTextureSize = 1024; - QGLWidget *widget = new QGLWidget(QGLFormat(QGL::SampleBuffers)); - widget->makeCurrent(); - - if (!necessaryExtensionsSupported()) { - QMessageBox::critical(nullptr, "OpenGL features missing", - "The OpenGL extensions required to run this demo are missing.\n" - "The program will now exit."); - delete widget; - return -2; - } - - // Check if all the necessary functions are resolved. - if (!getGLExtensionFunctions().resolve(widget->context())) { - QMessageBox::critical(nullptr, "OpenGL features missing", - "Failed to resolve OpenGL functions required to run this demo.\n" - "The program will now exit."); - delete widget; - return -3; - } - - // TODO: Make conditional for final release - QMessageBox::information(nullptr, "For your information", - "This demo can be GPU and CPU intensive and may\n" - "work poorly or not at all on your system."); - - widget->makeCurrent(); // The current context must be set before calling Scene's constructor - Scene scene(1024, 768, maxTextureSize); - GraphicsView view; - view.setViewport(widget); - view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate); - view.setScene(&scene); - view.show(); - - return app.exec(); -} - diff --git a/examples/widgets/graphicsview/boxes/marble.fsh b/examples/widgets/graphicsview/boxes/marble.fsh deleted file mode 100644 index c0b1980a67..0000000000 --- a/examples/widgets/graphicsview/boxes/marble.fsh +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; -uniform sampler3D noise; - -//const vec4 marbleColors[2] = {vec4(0.9, 0.9, 0.9, 1), vec4(0.6, 0.5, 0.5, 1)}; -uniform vec4 marbleColors[2]; - -void main() -{ - float turbulence = 0.0; - float scale = 1.0; - for (int i = 0; i < 4; ++i) { - turbulence += scale * (texture3D(noise, 0.125 * gl_TexCoord[1].xyz / scale).x - 0.5); - scale *= 0.5; - } - - vec3 N = normalize(normal); - // assume directional light - - gl_MaterialParameters M = gl_FrontMaterial; - - float NdotL = dot(N, lightDirection.xyz); - float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz); - - vec4 unlitColor = mix(marbleColors[0], marbleColors[1], exp(-4.0 * abs(turbulence))); - gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor + - M.specular * specular * pow(max(RdotL, 0.0), M.shininess); -} diff --git a/examples/widgets/graphicsview/boxes/parameters.par b/examples/widgets/graphicsview/boxes/parameters.par deleted file mode 100644 index 50e20739b9..0000000000 --- a/examples/widgets/graphicsview/boxes/parameters.par +++ /dev/null @@ -1,5 +0,0 @@ -color basicColor ff0e3d0e -color woodColors ff5e3d33 ffcc9966 -float woodTubulence 0.1 -color graniteColors ff000000 ff4d261a ffccb3bf -color marbleColors ffe6e6e6 ff998080 diff --git a/examples/widgets/graphicsview/boxes/qt-logo.jpg b/examples/widgets/graphicsview/boxes/qt-logo.jpg Binary files differdeleted file mode 100644 index 8d7fab052a..0000000000 --- a/examples/widgets/graphicsview/boxes/qt-logo.jpg +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/qt-logo.png b/examples/widgets/graphicsview/boxes/qt-logo.png Binary files differdeleted file mode 100644 index 0b0b15480c..0000000000 --- a/examples/widgets/graphicsview/boxes/qt-logo.png +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/qtbox.cpp b/examples/widgets/graphicsview/boxes/qtbox.cpp deleted file mode 100644 index 8713aac05d..0000000000 --- a/examples/widgets/graphicsview/boxes/qtbox.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtbox.h" - -constexpr qreal ROTATE_SPEED_X = 30.0 / 1000.0; -constexpr qreal ROTATE_SPEED_Y = 20.0 / 1000.0; -constexpr qreal ROTATE_SPEED_Z = 40.0 / 1000.0; -constexpr int MAX_ITEM_SIZE = 512; -constexpr int MIN_ITEM_SIZE = 16; - -//============================================================================// -// ItemBase // -//============================================================================// - -ItemBase::ItemBase(int size, int x, int y) : m_size(size), m_startTime(QTime::currentTime()) -{ - setFlag(QGraphicsItem::ItemIsMovable, true); - setFlag(QGraphicsItem::ItemIsSelectable, true); - setFlag(QGraphicsItem::ItemIsFocusable, true); - setAcceptHoverEvents(true); - setPos(x, y); -} - -QRectF ItemBase::boundingRect() const -{ - return QRectF(-m_size / 2, -m_size / 2, m_size, m_size); -} - -void ItemBase::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) -{ - if (option->state & QStyle::State_Selected) { - painter->setRenderHint(QPainter::Antialiasing, true); - if (option->state & QStyle::State_HasFocus) - painter->setPen(Qt::yellow); - else - painter->setPen(Qt::white); - painter->drawRect(boundingRect()); - - painter->drawLine(m_size / 2 - 9, m_size / 2, m_size / 2, m_size / 2 - 9); - painter->drawLine(m_size / 2 - 6, m_size / 2, m_size / 2, m_size / 2 - 6); - painter->drawLine(m_size / 2 - 3, m_size / 2, m_size / 2, m_size / 2 - 3); - - painter->setRenderHint(QPainter::Antialiasing, false); - } -} - -void ItemBase::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) -{ - if (!isSelected() && scene()) { - scene()->clearSelection(); - setSelected(true); - } - - QMenu menu; - QAction *delAction = menu.addAction("Delete"); - QAction *newAction = menu.addAction("New"); - QAction *growAction = menu.addAction("Grow"); - QAction *shrinkAction = menu.addAction("Shrink"); - - QAction *selectedAction = menu.exec(event->screenPos()); - - if (selectedAction == delAction) - deleteSelectedItems(scene()); - else if (selectedAction == newAction) - duplicateSelectedItems(scene()); - else if (selectedAction == growAction) - growSelectedItems(scene()); - else if (selectedAction == shrinkAction) - shrinkSelectedItems(scene()); -} - -void ItemBase::duplicateSelectedItems(QGraphicsScene *scene) -{ - if (!scene) - return; - - const QList<QGraphicsItem *> selected = scene->selectedItems(); - for (QGraphicsItem *item : selected) { - ItemBase *itemBase = qgraphicsitem_cast<ItemBase *>(item); - if (itemBase) - scene->addItem(itemBase->createNew(itemBase->m_size, itemBase->pos().x() + itemBase->m_size, itemBase->pos().y())); - } -} - -void ItemBase::deleteSelectedItems(QGraphicsScene *scene) -{ - if (!scene) - return; - - const QList<QGraphicsItem *> selected = scene->selectedItems(); - for (QGraphicsItem *item : selected) { - ItemBase *itemBase = qgraphicsitem_cast<ItemBase *>(item); - if (itemBase) - delete itemBase; - } -} - -void ItemBase::growSelectedItems(QGraphicsScene *scene) -{ - if (!scene) - return; - - const QList<QGraphicsItem *> selected = scene->selectedItems(); - for (QGraphicsItem *item : selected) { - ItemBase *itemBase = qgraphicsitem_cast<ItemBase *>(item); - if (itemBase) { - itemBase->prepareGeometryChange(); - itemBase->m_size *= 2; - if (itemBase->m_size > MAX_ITEM_SIZE) - itemBase->m_size = MAX_ITEM_SIZE; - } - } -} - -void ItemBase::shrinkSelectedItems(QGraphicsScene *scene) -{ - if (!scene) - return; - - const QList<QGraphicsItem *> selected = scene->selectedItems(); - for (QGraphicsItem *item : selected) { - ItemBase *itemBase = qgraphicsitem_cast<ItemBase *>(item); - if (itemBase) { - itemBase->prepareGeometryChange(); - itemBase->m_size /= 2; - if (itemBase->m_size < MIN_ITEM_SIZE) - itemBase->m_size = MIN_ITEM_SIZE; - } - } -} - -void ItemBase::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - if (m_isResizing) { - int dx = int(2.0 * event->pos().x()); - int dy = int(2.0 * event->pos().y()); - prepareGeometryChange(); - m_size = (dx > dy ? dx : dy); - if (m_size < MIN_ITEM_SIZE) - m_size = MIN_ITEM_SIZE; - else if (m_size > MAX_ITEM_SIZE) - m_size = MAX_ITEM_SIZE; - } else { - QGraphicsItem::mouseMoveEvent(event); - } -} - -void ItemBase::hoverMoveEvent(QGraphicsSceneHoverEvent *event) -{ - if (m_isResizing || (isInResizeArea(event->pos()) && isSelected())) - setCursor(Qt::SizeFDiagCursor); - else - setCursor(Qt::ArrowCursor); - QGraphicsItem::hoverMoveEvent(event); -} - -void ItemBase::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - static qreal z = 0.0; - setZValue(z += 1.0); - if (event->button() == Qt::LeftButton && isInResizeArea(event->pos())) { - m_isResizing = true; - } else { - QGraphicsItem::mousePressEvent(event); - } -} - -void ItemBase::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - if (event->button() == Qt::LeftButton && m_isResizing) { - m_isResizing = false; - } else { - QGraphicsItem::mouseReleaseEvent(event); - } -} - -void ItemBase::keyPressEvent(QKeyEvent *event) -{ - switch (event->key()) { - case Qt::Key_Delete: - deleteSelectedItems(scene()); - break; - case Qt::Key_Insert: - duplicateSelectedItems(scene()); - break; - case Qt::Key_Plus: - growSelectedItems(scene()); - break; - case Qt::Key_Minus: - shrinkSelectedItems(scene()); - break; - default: - QGraphicsItem::keyPressEvent(event); - break; - } -} - -void ItemBase::wheelEvent(QGraphicsSceneWheelEvent *event) -{ - prepareGeometryChange(); - m_size = int(m_size * qExp(-event->delta() / 600.0)); - m_size = qBound(MIN_ITEM_SIZE, m_size, MAX_ITEM_SIZE); -} - -int ItemBase::type() const -{ - return Type; -} - - -bool ItemBase::isInResizeArea(const QPointF &pos) -{ - return (-pos.y() < pos.x() - m_size + 9); -} - -//============================================================================// -// QtBox // -//============================================================================// - -QtBox::QtBox(int size, int x, int y) : ItemBase(size, x, y) -{ - for (int i = 0; i < 8; ++i) { - m_vertices[i].setX(i & 1 ? 0.5f : -0.5f); - m_vertices[i].setY(i & 2 ? 0.5f : -0.5f); - m_vertices[i].setZ(i & 4 ? 0.5f : -0.5f); - } - for (int i = 0; i < 4; ++i) { - m_texCoords[i].setX(i & 1 ? 1.0f : 0.0f); - m_texCoords[i].setY(i & 2 ? 1.0f : 0.0f); - } - m_normals[0] = QVector3D(-1.0f, 0.0f, 0.0f); - m_normals[1] = QVector3D(1.0f, 0.0f, 0.0f); - m_normals[2] = QVector3D(0.0f, -1.0f, 0.0f); - m_normals[3] = QVector3D(0.0f, 1.0f, 0.0f); - m_normals[4] = QVector3D(0.0f, 0.0f, -1.0f); - m_normals[5] = QVector3D(0.0f, 0.0f, 1.0f); -} - -QtBox::~QtBox() -{ - delete m_texture; -} - -ItemBase *QtBox::createNew(int size, int x, int y) -{ - return new QtBox(size, x, y); -} - -void QtBox::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - QRectF rect = boundingRect().translated(pos()); - float width = float(painter->device()->width()); - float height = float(painter->device()->height()); - - float left = 2.0f * float(rect.left()) / width - 1.0f; - float right = 2.0f * float(rect.right()) / width - 1.0f; - float top = 1.0f - 2.0f * float(rect.top()) / height; - float bottom = 1.0f - 2.0f * float(rect.bottom()) / height; - float moveToRectMatrix[] = { - 0.5f * (right - left), 0.0f, 0.0f, 0.0f, - 0.0f, 0.5f * (bottom - top), 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.5f * (right + left), 0.5f * (bottom + top), 0.0f, 1.0f - }; - - painter->beginNativePainting(); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(moveToRectMatrix); - qgluPerspective(60.0, 1.0, 0.01, 10.0); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - //glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); - glEnable(GL_COLOR_MATERIAL); - glEnable(GL_NORMALIZE); - - if (m_texture == nullptr) - m_texture = new GLTexture2D(":/res/boxes/qt-logo.jpg", 64, 64); - m_texture->bind(); - glEnable(GL_TEXTURE_2D); - - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - float lightColour[] = {1.0f, 1.0f, 1.0f, 1.0f}; - float lightDir[] = {0.0f, 0.0f, 1.0f, 0.0f}; - glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColour); - glLightfv(GL_LIGHT0, GL_POSITION, lightDir); - glEnable(GL_LIGHT0); - - glTranslatef(0.0f, 0.0f, -1.5f); - glRotatef(ROTATE_SPEED_X * m_startTime.msecsTo(QTime::currentTime()), 1.0f, 0.0f, 0.0f); - glRotatef(ROTATE_SPEED_Y * m_startTime.msecsTo(QTime::currentTime()), 0.0f, 1.0f, 0.0f); - glRotatef(ROTATE_SPEED_Z * m_startTime.msecsTo(QTime::currentTime()), 0.0f, 0.0f, 1.0f); - int dt = m_startTime.msecsTo(QTime::currentTime()); - if (dt < 500) - glScalef(dt / 500.0f, dt / 500.0f, dt / 500.0f); - - for (int dir = 0; dir < 3; ++dir) { - glColor4f(1.0f, 1.0f, 1.0f, 1.0); - - glBegin(GL_TRIANGLE_STRIP); - glNormal3fv(reinterpret_cast<float *>(&m_normals[2 * dir + 0])); - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < 2; ++j) { - glTexCoord2fv(reinterpret_cast<float *>(&m_texCoords[(j << 1) | i])); - glVertex3fv(reinterpret_cast<float *>(&m_vertices[(i << ((dir + 2) % 3)) | (j << ((dir + 1) % 3))])); - } - } - glEnd(); - - glBegin(GL_TRIANGLE_STRIP); - glNormal3fv(reinterpret_cast<float *>(&m_normals[2 * dir + 1])); - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < 2; ++j) { - glTexCoord2fv(reinterpret_cast<float *>(&m_texCoords[(j << 1) | i])); - glVertex3fv(reinterpret_cast<float *>(&m_vertices[(1 << dir) | (i << ((dir + 1) % 3)) | (j << ((dir + 2) % 3))])); - } - } - glEnd(); - } - m_texture->unbind(); - - //glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHT0); - glDisable(GL_NORMALIZE); - - glPopMatrix(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - painter->endNativePainting(); - - ItemBase::paint(painter, option, widget); -} - -//============================================================================// -// CircleItem // -//============================================================================// - -CircleItem::CircleItem(int size, int x, int y) : ItemBase(size, x, y) - , m_color(QColor::fromHsv(QRandomGenerator::global()->bounded(360), 255, 255)) -{} - -void CircleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - int dt = m_startTime.msecsTo(QTime::currentTime()); - - qreal r0 = 0.5 * m_size * (1.0 - qExp(-0.001 * ((dt + 3800) % 4000))); - qreal r1 = 0.5 * m_size * (1.0 - qExp(-0.001 * ((dt + 0) % 4000))); - qreal r2 = 0.5 * m_size * (1.0 - qExp(-0.001 * ((dt + 1800) % 4000))); - qreal r3 = 0.5 * m_size * (1.0 - qExp(-0.001 * ((dt + 2000) % 4000))); - - if (r0 > r1) - r0 = 0.0; - if (r2 > r3) - r2 = 0.0; - - QPainterPath path; - path.moveTo(r1, 0.0); - path.arcTo(-r1, -r1, 2 * r1, 2 * r1, 0.0, 360.0); - path.lineTo(r0, 0.0); - path.arcTo(-r0, -r0, 2 * r0, 2 * r0, 0.0, -360.0); - path.closeSubpath(); - path.moveTo(r3, 0.0); - path.arcTo(-r3, -r3, 2 * r3, 2 * r3, 0.0, 360.0); - path.lineTo(r0, 0.0); - path.arcTo(-r2, -r2, 2 * r2, 2 * r2, 0.0, -360.0); - path.closeSubpath(); - painter->setRenderHint(QPainter::Antialiasing, true); - painter->setBrush(QBrush(m_color)); - painter->setPen(Qt::NoPen); - painter->drawPath(path); - painter->setBrush(Qt::NoBrush); - painter->setPen(Qt::SolidLine); - painter->setRenderHint(QPainter::Antialiasing, false); - - ItemBase::paint(painter, option, widget); -} - -ItemBase *CircleItem::createNew(int size, int x, int y) -{ - return new CircleItem(size, x, y); -} - -//============================================================================// -// SquareItem // -//============================================================================// - -SquareItem::SquareItem(int size, int x, int y) : ItemBase(size, x, y) - , m_image(QPixmap(":/res/boxes/square.jpg")) -{} - -void SquareItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - int dt = m_startTime.msecsTo(QTime::currentTime()); - QTransform oldTransform = painter->worldTransform(); - int dtMod = dt % 2000; - qreal amp = 0.002 * (dtMod < 1000 ? dtMod : 2000 - dtMod) - 1.0; - - qreal scale = 0.6 + 0.2 * amp * amp; - painter->setWorldTransform(QTransform().rotate(15.0 * amp).scale(scale, scale), true); - - painter->drawPixmap(-m_size / 2, -m_size / 2, m_size, m_size, m_image); - - painter->setWorldTransform(oldTransform, false); - ItemBase::paint(painter, option, widget); -} - -ItemBase *SquareItem::createNew(int size, int x, int y) -{ - return new SquareItem(size, x, y); -} diff --git a/examples/widgets/graphicsview/boxes/qtbox.h b/examples/widgets/graphicsview/boxes/qtbox.h deleted file mode 100644 index 84c8cb1d93..0000000000 --- a/examples/widgets/graphicsview/boxes/qtbox.h +++ /dev/null @@ -1,126 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTBOX_H -#define QTBOX_H - -#include "glbuffers.h" - -#include <QtWidgets> -#include <QVector3D> - -class ItemBase : public QGraphicsItem -{ -public: - enum { Type = UserType + 1 }; - - ItemBase(int size, int x, int y); - QRectF boundingRect() const override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; -protected: - virtual ItemBase *createNew(int size, int x, int y) = 0; - void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override; - void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; - void hoverMoveEvent(QGraphicsSceneHoverEvent *event) override; - void mousePressEvent(QGraphicsSceneMouseEvent *event) override; - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; - void keyPressEvent(QKeyEvent *event) override; - void wheelEvent(QGraphicsSceneWheelEvent *event) override; - int type() const override; - bool isInResizeArea(const QPointF &pos); - - static void duplicateSelectedItems(QGraphicsScene *scene); - static void deleteSelectedItems(QGraphicsScene *scene); - static void growSelectedItems(QGraphicsScene *scene); - static void shrinkSelectedItems(QGraphicsScene *scene); - - int m_size; - QTime m_startTime; - bool m_isResizing = false; -}; - -class QtBox : public ItemBase -{ -public: - QtBox(int size, int x, int y); - virtual ~QtBox(); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; -protected: - ItemBase *createNew(int size, int x, int y) override; -private: - QVector3D m_vertices[8]; - QVector3D m_texCoords[4]; - QVector3D m_normals[6]; - GLTexture *m_texture = nullptr; -}; - -class CircleItem : public ItemBase -{ -public: - CircleItem(int size, int x, int y); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; -protected: - ItemBase *createNew(int size, int x, int y) override; - - QColor m_color; -}; - -class SquareItem : public ItemBase -{ -public: - SquareItem(int size, int x, int y); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; -protected: - ItemBase *createNew(int size, int x, int y) override; - - QPixmap m_image; -}; - -#endif diff --git a/examples/widgets/graphicsview/boxes/reflection.fsh b/examples/widgets/graphicsview/boxes/reflection.fsh deleted file mode 100644 index 0f0a26476f..0000000000 --- a/examples/widgets/graphicsview/boxes/reflection.fsh +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; -uniform samplerCube env; -uniform mat4 view; - -void main() -{ - vec3 N = normalize(normal); - vec3 R = 2.0 * dot(-position, N) * N + position; - gl_FragColor = textureCube(env, R * mat3(view[0].xyz, view[1].xyz, view[2].xyz)); -} diff --git a/examples/widgets/graphicsview/boxes/refraction.fsh b/examples/widgets/graphicsview/boxes/refraction.fsh deleted file mode 100644 index 8ba2d36329..0000000000 --- a/examples/widgets/graphicsview/boxes/refraction.fsh +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; -uniform samplerCube env; -uniform mat4 view; - -// Arrays don't work here on glsl < 120, apparently. -//const float coeffs[6] = float[6](1.0/2.0, 1.0/2.1, 1.0/2.2, 1.0/2.3, 1.0/2.4, 1.0/2.5); -float coeffs(int i) -{ - return 1.0 / (2.0 + 0.1 * float(i)); -} - -void main() -{ - vec3 N = normalize(normal); - vec3 I = -normalize(position); - float IdotN = dot(I, N); - float scales[6]; - vec3 C[6]; - for (int i = 0; i < 6; ++i) { - scales[i] = (IdotN - sqrt(1.0 - coeffs(i) + coeffs(i) * (IdotN * IdotN))); - C[i] = textureCube(env, (-I + coeffs(i) * N) * mat3(view[0].xyz, view[1].xyz, view[2].xyz)).xyz; - } - - gl_FragColor = 0.25 * vec4(C[5].x + 2.0*C[0].x + C[1].x, C[1].y + 2.0*C[2].y + C[3].y, - C[3].z + 2.0*C[4].z + C[5].z, 4.0); -} diff --git a/examples/widgets/graphicsview/boxes/roundedbox.cpp b/examples/widgets/graphicsview/boxes/roundedbox.cpp deleted file mode 100644 index be96223b9f..0000000000 --- a/examples/widgets/graphicsview/boxes/roundedbox.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "roundedbox.h" - -//============================================================================// -// P3T2N3Vertex // -//============================================================================// - -VertexDescription P3T2N3Vertex::description[] = { - {VertexDescription::Position, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, position) / sizeof(float), 0, 0}, - {VertexDescription::TexCoord, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, texCoord) / sizeof(float), sizeof(QVector3D), 0}, - {VertexDescription::Normal, GL_FLOAT, SIZE_OF_MEMBER(P3T2N3Vertex, normal) / sizeof(float), sizeof(QVector3D) + sizeof(QVector2D), 0}, - - {VertexDescription::Null, 0, 0, 0, 0}, -}; - -//============================================================================// -// GLRoundedBox // -//============================================================================// - -float lerp(float a, float b, float t) -{ - return a * (1.0f - t) + b * t; -} - -GLRoundedBox::GLRoundedBox(float r, float scale, int n) - : GLTriangleMesh<P3T2N3Vertex, unsigned short>((n+2)*(n+3)*4, (n+1)*(n+1)*24+36+72*(n+1)) -{ - int vidx = 0, iidx = 0; - int vertexCountPerCorner = (n + 2) * (n + 3) / 2; - - P3T2N3Vertex *vp = m_vb.lock(); - unsigned short *ip = m_ib.lock(); - - if (!vp || !ip) { - qWarning("GLRoundedBox::GLRoundedBox: Failed to lock vertex buffer and/or index buffer."); - m_ib.unlock(); - m_vb.unlock(); - return; - } - - for (int corner = 0; corner < 8; ++corner) { - QVector3D centre(corner & 1 ? 1.0f : -1.0f, - corner & 2 ? 1.0f : -1.0f, - corner & 4 ? 1.0f : -1.0f); - int winding = (corner & 1) ^ ((corner >> 1) & 1) ^ (corner >> 2); - int offsX = ((corner ^ 1) - corner) * vertexCountPerCorner; - int offsY = ((corner ^ 2) - corner) * vertexCountPerCorner; - int offsZ = ((corner ^ 4) - corner) * vertexCountPerCorner; - - // Face polygons - if (winding) { - ip[iidx++] = vidx; - ip[iidx++] = vidx + offsX; - ip[iidx++] = vidx + offsY; - - ip[iidx++] = vidx + vertexCountPerCorner - n - 2; - ip[iidx++] = vidx + vertexCountPerCorner - n - 2 + offsY; - ip[iidx++] = vidx + vertexCountPerCorner - n - 2 + offsZ; - - ip[iidx++] = vidx + vertexCountPerCorner - 1; - ip[iidx++] = vidx + vertexCountPerCorner - 1 + offsZ; - ip[iidx++] = vidx + vertexCountPerCorner - 1 + offsX; - } - - for (int i = 0; i < n + 2; ++i) { - - // Edge polygons - if (winding && i < n + 1) { - ip[iidx++] = vidx + i + 1; - ip[iidx++] = vidx; - ip[iidx++] = vidx + offsY + i + 1; - ip[iidx++] = vidx + offsY; - ip[iidx++] = vidx + offsY + i + 1; - ip[iidx++] = vidx; - - ip[iidx++] = vidx + i; - ip[iidx++] = vidx + 2 * i + 2; - ip[iidx++] = vidx + i + offsX; - ip[iidx++] = vidx + 2 * i + offsX + 2; - ip[iidx++] = vidx + i + offsX; - ip[iidx++] = vidx + 2 * i + 2; - - ip[iidx++] = (corner + 1) * vertexCountPerCorner - 1 - i; - ip[iidx++] = (corner + 1) * vertexCountPerCorner - 2 - i; - ip[iidx++] = (corner + 1) * vertexCountPerCorner - 1 - i + offsZ; - ip[iidx++] = (corner + 1) * vertexCountPerCorner - 2 - i + offsZ; - ip[iidx++] = (corner + 1) * vertexCountPerCorner - 1 - i + offsZ; - ip[iidx++] = (corner + 1) * vertexCountPerCorner - 2 - i; - } - - for (int j = 0; j <= i; ++j) { - QVector3D normal = QVector3D(i - j, j, n + 1 - i).normalized(); - QVector3D offset(0.5f - r, 0.5f - r, 0.5f - r); - QVector3D pos = centre * (offset + r * normal); - - vp[vidx].position = scale * pos; - vp[vidx].normal = centre * normal; - vp[vidx].texCoord = QVector2D(pos.x() + 0.5f, pos.y() + 0.5f); - - // Corner polygons - if (i < n + 1) { - ip[iidx++] = vidx; - ip[iidx++] = vidx + i + 2 - winding; - ip[iidx++] = vidx + i + 1 + winding; - } - if (i < n) { - ip[iidx++] = vidx + i + 1 + winding; - ip[iidx++] = vidx + i + 2 - winding; - ip[iidx++] = vidx + 2 * i + 4; - } - - ++vidx; - } - } - - } - - m_ib.unlock(); - m_vb.unlock(); -} - diff --git a/examples/widgets/graphicsview/boxes/roundedbox.h b/examples/widgets/graphicsview/boxes/roundedbox.h deleted file mode 100644 index a1f15cd631..0000000000 --- a/examples/widgets/graphicsview/boxes/roundedbox.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ROUNDEDBOX_H -#define ROUNDEDBOX_H - -#include "glbuffers.h" -#include "glextensions.h" -#include "gltrianglemesh.h" - -#include <QVector2D> -#include <QVector3D> - -struct P3T2N3Vertex -{ - QVector3D position; - QVector2D texCoord; - QVector3D normal; - static VertexDescription description[]; -}; - -class GLRoundedBox : public GLTriangleMesh<P3T2N3Vertex, unsigned short> -{ -public: - // 0 < r < 0.5, 0 <= n <= 125 - explicit GLRoundedBox(float r = 0.25f, float scale = 1.0f, int n = 10); -}; - - -#endif diff --git a/examples/widgets/graphicsview/boxes/scene.cpp b/examples/widgets/graphicsview/boxes/scene.cpp deleted file mode 100644 index b344f65561..0000000000 --- a/examples/widgets/graphicsview/boxes/scene.cpp +++ /dev/null @@ -1,1028 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "scene.h" - -#include <QMatrix4x4> -#include <QRandomGenerator> -#include <QVector3D> -#include <qmath.h> - -#include "3rdparty/fbm.h" - -//============================================================================// -// ColorEdit // -//============================================================================// - -ColorEdit::ColorEdit(QRgb initialColor, int id) - : m_color(initialColor), m_id(id) -{ - QHBoxLayout *layout = new QHBoxLayout; - setLayout(layout); - layout->setContentsMargins(0, 0, 0, 0); - - m_lineEdit = new QLineEdit(QString::number(m_color, 16)); - layout->addWidget(m_lineEdit); - - m_button = new QFrame; - QPalette palette = m_button->palette(); - palette.setColor(QPalette::Window, QColor(m_color)); - m_button->setPalette(palette); - m_button->setAutoFillBackground(true); - m_button->setMinimumSize(32, 0); - m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); - m_button->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); - layout->addWidget(m_button); - - connect(m_lineEdit, &QLineEdit::editingFinished, this, &ColorEdit::editDone); -} - -void ColorEdit::editDone() -{ - bool ok; - QRgb newColor = m_lineEdit->text().toUInt(&ok, 16); - if (ok) - setColor(newColor); -} - -void ColorEdit::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) { - QColor color(m_color); - QColorDialog dialog(color, nullptr); - dialog.setOption(QColorDialog::ShowAlphaChannel, true); - dialog.move(280, 120); - if (dialog.exec() == QDialog::Rejected) - return; - QRgb newColor = dialog.selectedColor().rgba(); - if (newColor == m_color) - return; - setColor(newColor); - } -} - -void ColorEdit::setColor(QRgb color) -{ - m_color = color; - m_lineEdit->setText(QString::number(m_color, 16)); // "Clean up" text - QPalette palette = m_button->palette(); - palette.setColor(QPalette::Window, QColor(m_color)); - m_button->setPalette(palette); - emit colorChanged(m_color, m_id); -} - -//============================================================================// -// FloatEdit // -//============================================================================// - -FloatEdit::FloatEdit(float initialValue, int id) - : m_value(initialValue), m_id(id) -{ - QHBoxLayout *layout = new QHBoxLayout; - setLayout(layout); - layout->setContentsMargins(0, 0, 0, 0); - - m_lineEdit = new QLineEdit(QString::number(m_value)); - layout->addWidget(m_lineEdit); - - connect(m_lineEdit, &QLineEdit::editingFinished, this, &FloatEdit::editDone); -} - -void FloatEdit::editDone() -{ - bool ok; - float newValue = m_lineEdit->text().toFloat(&ok); - if (ok) { - m_value = newValue; - m_lineEdit->setText(QString::number(m_value)); // "Clean up" text - emit valueChanged(m_value, m_id); - } -} - -//============================================================================// -// TwoSidedGraphicsWidget // -//============================================================================// -void TwoSidedGraphicsWidget::setWidget(int index, QWidget *widget) -{ - if (index < 0 || index >= 2) - { - qWarning("TwoSidedGraphicsWidget::setWidget: Index out of bounds, index == %d", index); - return; - } - - GraphicsWidget *proxy = new GraphicsWidget; - proxy->setWidget(widget); - - delete m_proxyWidgets[index]; - m_proxyWidgets[index] = proxy; - - proxy->setCacheMode(QGraphicsItem::ItemCoordinateCache); - proxy->setZValue(1e30); // Make sure the dialog is drawn on top of all other (OpenGL) items - - if (index != m_current) - proxy->setVisible(false); - - qobject_cast<QGraphicsScene *>(parent())->addItem(proxy); -} - -QWidget *TwoSidedGraphicsWidget::widget(int index) -{ - if (index < 0 || index >= 2) - { - qWarning("TwoSidedGraphicsWidget::widget: Index out of bounds, index == %d", index); - return nullptr; - } - return m_proxyWidgets[index]->widget(); -} - -void TwoSidedGraphicsWidget::flip() -{ - m_delta = (m_current == 0 ? 9 : -9); - animateFlip(); -} - -void TwoSidedGraphicsWidget::animateFlip() -{ - m_angle += m_delta; - if (m_angle == 90) { - int old = m_current; - m_current ^= 1; - m_proxyWidgets[old]->setVisible(false); - m_proxyWidgets[m_current]->setVisible(true); - m_proxyWidgets[m_current]->setGeometry(m_proxyWidgets[old]->geometry()); - } - - QRectF r = m_proxyWidgets[m_current]->boundingRect(); - m_proxyWidgets[m_current]->setTransform(QTransform() - .translate(r.width() / 2, r.height() / 2) - .rotate(m_angle - 180 * m_current, Qt::YAxis) - .translate(-r.width() / 2, -r.height() / 2)); - - if ((m_current == 0 && m_angle > 0) || (m_current == 1 && m_angle < 180)) - QTimer::singleShot(25, this, &TwoSidedGraphicsWidget::animateFlip); -} - -QVariant GraphicsWidget::itemChange(GraphicsItemChange change, const QVariant &value) -{ - if (change == ItemPositionChange && scene()) { - QRectF rect = boundingRect(); - QPointF pos = value.toPointF(); - QRectF sceneRect = scene()->sceneRect(); - if (pos.x() + rect.left() < sceneRect.left()) - pos.setX(sceneRect.left() - rect.left()); - else if (pos.x() + rect.right() >= sceneRect.right()) - pos.setX(sceneRect.right() - rect.right()); - if (pos.y() + rect.top() < sceneRect.top()) - pos.setY(sceneRect.top() - rect.top()); - else if (pos.y() + rect.bottom() >= sceneRect.bottom()) - pos.setY(sceneRect.bottom() - rect.bottom()); - return pos; - } - return QGraphicsProxyWidget::itemChange(change, value); -} - -void GraphicsWidget::resizeEvent(QGraphicsSceneResizeEvent *event) -{ - setCacheMode(QGraphicsItem::NoCache); - setCacheMode(QGraphicsItem::ItemCoordinateCache); - QGraphicsProxyWidget::resizeEvent(event); -} - -void GraphicsWidget::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - painter->setRenderHint(QPainter::Antialiasing, false); - QGraphicsProxyWidget::paint(painter, option, widget); - //painter->setRenderHint(QPainter::Antialiasing, true); -} - -//============================================================================// -// RenderOptionsDialog // -//============================================================================// - -RenderOptionsDialog::RenderOptionsDialog() - : QDialog(nullptr, Qt::CustomizeWindowHint | Qt::WindowTitleHint) -{ - setWindowOpacity(0.75); - setWindowTitle(tr("Options (double click to flip)")); - QGridLayout *layout = new QGridLayout; - setLayout(layout); - layout->setColumnStretch(1, 1); - - int row = 0; - - QCheckBox *check = new QCheckBox(tr("Dynamic cube map")); - check->setCheckState(Qt::Unchecked); - // Dynamic cube maps are only enabled when multi-texturing and render to texture are available. - check->setEnabled(glActiveTexture && glGenFramebuffersEXT); - connect(check, &QCheckBox::stateChanged, this, &RenderOptionsDialog::dynamicCubemapToggled); - layout->addWidget(check, 0, 0, 1, 2); - ++row; - - // Load all .par files - // .par files have a simple syntax for specifying user adjustable uniform variables. - const QList<QFileInfo> files = QDir(QStringLiteral(":/res/boxes/")) - .entryInfoList({ QStringLiteral("*.par") }, - QDir::Files | QDir::Readable); - - for (const QFileInfo &fileInfo : files) { - QFile file(fileInfo.absoluteFilePath()); - if (file.open(QIODevice::ReadOnly)) { - while (!file.atEnd()) { - QList<QByteArray> tokens = file.readLine().simplified().split(' '); - QList<QByteArray>::const_iterator it = tokens.begin(); - if (it == tokens.end()) - continue; - QByteArray type = *it; - if (++it == tokens.end()) - continue; - QByteArray name = *it; - bool singleElement = (tokens.size() == 3); // type, name and one value - char counter[10] = "000000000"; - int counterPos = 8; // position of last digit - while (++it != tokens.end()) { - m_parameterNames << name; - if (!singleElement) { - m_parameterNames.back() += '['; - m_parameterNames.back() += counter + counterPos; - m_parameterNames.back() += ']'; - int j = 8; // position of last digit - ++counter[j]; - while (j > 0 && counter[j] > '9') { - counter[j] = '0'; - ++counter[--j]; - } - if (j < counterPos) - counterPos = j; - } - - if (type == "color") { - layout->addWidget(new QLabel(m_parameterNames.back())); - bool ok; - ColorEdit *colorEdit = new ColorEdit(it->toUInt(&ok, 16), m_parameterNames.size() - 1); - m_parameterEdits << colorEdit; - layout->addWidget(colorEdit); - connect(colorEdit, &ColorEdit::colorChanged, this, &RenderOptionsDialog::setColorParameter); - ++row; - } else if (type == "float") { - layout->addWidget(new QLabel(m_parameterNames.back())); - bool ok; - FloatEdit *floatEdit = new FloatEdit(it->toFloat(&ok), m_parameterNames.size() - 1); - m_parameterEdits << floatEdit; - layout->addWidget(floatEdit); - connect(floatEdit, &FloatEdit::valueChanged, this, &RenderOptionsDialog::setFloatParameter); - ++row; - } - } - } - file.close(); - } - } - - layout->addWidget(new QLabel(tr("Texture:"))); - m_textureCombo = new QComboBox; - connect(m_textureCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), - this, &RenderOptionsDialog::textureChanged); - layout->addWidget(m_textureCombo); - ++row; - - layout->addWidget(new QLabel(tr("Shader:"))); - m_shaderCombo = new QComboBox; - connect(m_shaderCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), - this, &RenderOptionsDialog::shaderChanged); - layout->addWidget(m_shaderCombo); - ++row; - - layout->setRowStretch(row, 1); -} - -int RenderOptionsDialog::addTexture(const QString &name) -{ - m_textureCombo->addItem(name); - return m_textureCombo->count() - 1; -} - -int RenderOptionsDialog::addShader(const QString &name) -{ - m_shaderCombo->addItem(name); - return m_shaderCombo->count() - 1; -} - -void RenderOptionsDialog::emitParameterChanged() -{ - for (ParameterEdit *edit : qAsConst(m_parameterEdits)) - edit->emitChange(); -} - -void RenderOptionsDialog::setColorParameter(QRgb color, int id) -{ - emit colorParameterChanged(m_parameterNames[id], color); -} - -void RenderOptionsDialog::setFloatParameter(float value, int id) -{ - emit floatParameterChanged(m_parameterNames[id], value); -} - -void RenderOptionsDialog::mouseDoubleClickEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - emit doubleClicked(); -} - -//============================================================================// -// ItemDialog // -//============================================================================// - -ItemDialog::ItemDialog() - : QDialog(nullptr, Qt::CustomizeWindowHint | Qt::WindowTitleHint) -{ - setWindowTitle(tr("Items (double click to flip)")); - setWindowOpacity(0.75); - resize(160, 100); - - QVBoxLayout *layout = new QVBoxLayout; - setLayout(layout); - QPushButton *button; - - button = new QPushButton(tr("Add Qt box")); - layout->addWidget(button); - connect(button, &QAbstractButton::clicked, this, &ItemDialog::triggerNewQtBox); - - button = new QPushButton(tr("Add circle")); - layout->addWidget(button); - connect(button, &QAbstractButton::clicked, this, &ItemDialog::triggerNewCircleItem); - - button = new QPushButton(tr("Add square")); - layout->addWidget(button); - connect(button, &QAbstractButton::clicked, this, &ItemDialog::triggerNewSquareItem); - - layout->addStretch(1); -} - -void ItemDialog::triggerNewQtBox() -{ - emit newItemTriggered(QtBoxItem); -} - -void ItemDialog::triggerNewCircleItem() -{ - emit newItemTriggered(CircleItem); -} - -void ItemDialog::triggerNewSquareItem() -{ - emit newItemTriggered(SquareItem); -} - -void ItemDialog::mouseDoubleClickEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - emit doubleClicked(); -} - -//============================================================================// -// Scene // -//============================================================================// - -const static char environmentShaderText[] = - "uniform samplerCube env;" - "void main() {" - "gl_FragColor = textureCube(env, gl_TexCoord[1].xyz);" - "}"; - -Scene::Scene(int width, int height, int maxTextureSize) - : m_distExp(600) - , m_frame(0) - , m_maxTextureSize(maxTextureSize) - , m_currentShader(0) - , m_currentTexture(0) - , m_dynamicCubemap(false) - , m_updateAllCubemaps(true) - , m_box(nullptr) - , m_vertexShader(nullptr) - , m_environmentShader(nullptr) - , m_environmentProgram(nullptr) -{ - setSceneRect(0, 0, width, height); - - m_trackBalls[0] = TrackBall(0.05f, QVector3D(0, 1, 0), TrackBall::Sphere); - m_trackBalls[1] = TrackBall(0.005f, QVector3D(0, 0, 1), TrackBall::Sphere); - m_trackBalls[2] = TrackBall(0.0f, QVector3D(0, 1, 0), TrackBall::Plane); - - m_renderOptions = new RenderOptionsDialog; - m_renderOptions->move(20, 120); - m_renderOptions->resize(m_renderOptions->sizeHint()); - - connect(m_renderOptions, &RenderOptionsDialog::dynamicCubemapToggled, this, &Scene::toggleDynamicCubemap); - connect(m_renderOptions, &RenderOptionsDialog::colorParameterChanged, this, &Scene::setColorParameter); - connect(m_renderOptions, &RenderOptionsDialog::floatParameterChanged, this, &Scene::setFloatParameter); - connect(m_renderOptions, &RenderOptionsDialog::textureChanged, this, &Scene::setTexture); - connect(m_renderOptions, &RenderOptionsDialog::shaderChanged, this, &Scene::setShader); - - m_itemDialog = new ItemDialog; - connect(m_itemDialog, &ItemDialog::newItemTriggered, this, &Scene::newItem); - - TwoSidedGraphicsWidget *twoSided = new TwoSidedGraphicsWidget(this); - twoSided->setWidget(0, m_renderOptions); - twoSided->setWidget(1, m_itemDialog); - - connect(m_renderOptions, &RenderOptionsDialog::doubleClicked, twoSided, &TwoSidedGraphicsWidget::flip); - connect(m_itemDialog, &ItemDialog::doubleClicked, twoSided, &TwoSidedGraphicsWidget::flip); - - addItem(new QtBox(64, width - 64, height - 64)); - addItem(new QtBox(64, width - 64, 64)); - addItem(new QtBox(64, 64, height - 64)); - addItem(new QtBox(64, 64, 64)); - - initGL(); - - m_timer = new QTimer(this); - m_timer->setInterval(20); - connect(m_timer, &QTimer::timeout, this, [this](){ update(); }); - m_timer->start(); -} - -Scene::~Scene() -{ - delete m_box; - qDeleteAll(m_textures); - delete m_mainCubemap; - qDeleteAll(m_programs); - delete m_vertexShader; - qDeleteAll(m_fragmentShaders); - qDeleteAll(m_cubemaps); - delete m_environmentShader; - delete m_environmentProgram; -} - -void Scene::initGL() -{ - m_box = new GLRoundedBox(0.25f, 1.0f, 10); - - m_vertexShader = new QGLShader(QGLShader::Vertex); - m_vertexShader->compileSourceFile(QLatin1String(":/res/boxes/basic.vsh")); - - QStringList list; - list << ":/res/boxes/cubemap_posx.jpg" << ":/res/boxes/cubemap_negx.jpg" << ":/res/boxes/cubemap_posy.jpg" - << ":/res/boxes/cubemap_negy.jpg" << ":/res/boxes/cubemap_posz.jpg" << ":/res/boxes/cubemap_negz.jpg"; - m_environment = new GLTextureCube(list, qMin(1024, m_maxTextureSize)); - m_environmentShader = new QGLShader(QGLShader::Fragment); - m_environmentShader->compileSourceCode(environmentShaderText); - m_environmentProgram = new QGLShaderProgram; - m_environmentProgram->addShader(m_vertexShader); - m_environmentProgram->addShader(m_environmentShader); - m_environmentProgram->link(); - - const int NOISE_SIZE = 128; // for a different size, B and BM in fbm.c must also be changed - m_noise = new GLTexture3D(NOISE_SIZE, NOISE_SIZE, NOISE_SIZE); - QVector<QRgb> data(NOISE_SIZE * NOISE_SIZE * NOISE_SIZE, QRgb(0)); - QRgb *p = data.data(); - float pos[3]; - for (int k = 0; k < NOISE_SIZE; ++k) { - pos[2] = k * (0x20 / (float)NOISE_SIZE); - for (int j = 0; j < NOISE_SIZE; ++j) { - for (int i = 0; i < NOISE_SIZE; ++i) { - for (int byte = 0; byte < 4; ++byte) { - pos[0] = (i + (byte & 1) * 16) * (0x20 / (float)NOISE_SIZE); - pos[1] = (j + (byte & 2) * 8) * (0x20 / (float)NOISE_SIZE); - *p |= (int)(128.0f * (noise3(pos) + 1.0f)) << (byte * 8); - } - ++p; - } - } - } - m_noise->load(NOISE_SIZE, NOISE_SIZE, NOISE_SIZE, data.data()); - - m_mainCubemap = new GLRenderTargetCube(512); - - QList<QFileInfo> files; - - // Load all .png files as textures - m_currentTexture = 0; - files = QDir(":/res/boxes/").entryInfoList({ QStringLiteral("*.png") }, QDir::Files | QDir::Readable); - - for (const QFileInfo &file : qAsConst(files)) { - GLTexture *texture = new GLTexture2D(file.absoluteFilePath(), qMin(256, m_maxTextureSize), qMin(256, m_maxTextureSize)); - if (texture->failed()) { - delete texture; - continue; - } - m_textures << texture; - m_renderOptions->addTexture(file.baseName()); - } - - if (m_textures.size() == 0) - m_textures << new GLTexture2D(qMin(64, m_maxTextureSize), qMin(64, m_maxTextureSize)); - - // Load all .fsh files as fragment shaders - m_currentShader = 0; - files = QDir(":/res/boxes/").entryInfoList({ QStringLiteral("*.fsh") }, QDir::Files | QDir::Readable); - for (const QFileInfo &file : qAsConst(files)) { - QGLShaderProgram *program = new QGLShaderProgram; - QGLShader* shader = new QGLShader(QGLShader::Fragment); - shader->compileSourceFile(file.absoluteFilePath()); - // The program does not take ownership over the shaders, so store them in a vector so they can be deleted afterwards. - program->addShader(m_vertexShader); - program->addShader(shader); - if (!program->link()) { - qWarning("Failed to compile and link shader program"); - qWarning("Vertex shader log:"); - qWarning() << m_vertexShader->log(); - qWarning() << "Fragment shader log ( file =" << file.absoluteFilePath() << "):"; - qWarning() << shader->log(); - qWarning("Shader program log:"); - qWarning() << program->log(); - - delete shader; - delete program; - continue; - } - - m_fragmentShaders << shader; - m_programs << program; - m_renderOptions->addShader(file.baseName()); - - program->bind(); - m_cubemaps << ((program->uniformLocation("env") != -1) ? new GLRenderTargetCube(qMin(256, m_maxTextureSize)) : nullptr); - program->release(); - } - - if (m_programs.size() == 0) - m_programs << new QGLShaderProgram; - - m_renderOptions->emitParameterChanged(); -} - -static void loadMatrix(const QMatrix4x4 &m) -{ - // static to prevent glLoadMatrixf to fail on certain drivers - static GLfloat mat[16]; - const float *data = m.constData(); - for (int index = 0; index < 16; ++index) - mat[index] = data[index]; - glLoadMatrixf(mat); -} - -// If one of the boxes should not be rendered, set excludeBox to its index. -// If the main box should not be rendered, set excludeBox to -1. -void Scene::renderBoxes(const QMatrix4x4 &view, int excludeBox) -{ - QMatrix4x4 invView = view.inverted(); - - // If multi-texturing is supported, use three saplers. - if (glActiveTexture) { - glActiveTexture(GL_TEXTURE0); - m_textures[m_currentTexture]->bind(); - glActiveTexture(GL_TEXTURE2); - m_noise->bind(); - glActiveTexture(GL_TEXTURE1); - } else { - m_textures[m_currentTexture]->bind(); - } - - glDisable(GL_LIGHTING); - glDisable(GL_CULL_FACE); - - QMatrix4x4 viewRotation(view); - viewRotation(3, 0) = viewRotation(3, 1) = viewRotation(3, 2) = 0.0f; - viewRotation(0, 3) = viewRotation(1, 3) = viewRotation(2, 3) = 0.0f; - viewRotation(3, 3) = 1.0f; - loadMatrix(viewRotation); - glScalef(20.0f, 20.0f, 20.0f); - - // Don't render the environment if the environment texture can't be set for the correct sampler. - if (glActiveTexture) { - m_environment->bind(); - m_environmentProgram->bind(); - m_environmentProgram->setUniformValue("tex", GLint(0)); - m_environmentProgram->setUniformValue("env", GLint(1)); - m_environmentProgram->setUniformValue("noise", GLint(2)); - m_box->draw(); - m_environmentProgram->release(); - m_environment->unbind(); - } - - loadMatrix(view); - - glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); - - for (int i = 0; i < m_programs.size(); ++i) { - if (i == excludeBox) - continue; - - glPushMatrix(); - QMatrix4x4 m; - m.rotate(m_trackBalls[1].rotation()); - glMultMatrixf(m.constData()); - - glRotatef(360.0f * i / m_programs.size(), 0.0f, 0.0f, 1.0f); - glTranslatef(2.0f, 0.0f, 0.0f); - glScalef(0.3f, 0.6f, 0.6f); - - if (glActiveTexture) { - if (m_dynamicCubemap && m_cubemaps[i]) - m_cubemaps[i]->bind(); - else - m_environment->bind(); - } - m_programs[i]->bind(); - m_programs[i]->setUniformValue("tex", GLint(0)); - m_programs[i]->setUniformValue("env", GLint(1)); - m_programs[i]->setUniformValue("noise", GLint(2)); - m_programs[i]->setUniformValue("view", view); - m_programs[i]->setUniformValue("invView", invView); - m_box->draw(); - m_programs[i]->release(); - - if (glActiveTexture) { - if (m_dynamicCubemap && m_cubemaps[i]) - m_cubemaps[i]->unbind(); - else - m_environment->unbind(); - } - glPopMatrix(); - } - - if (-1 != excludeBox) { - QMatrix4x4 m; - m.rotate(m_trackBalls[0].rotation()); - glMultMatrixf(m.constData()); - - if (glActiveTexture) { - if (m_dynamicCubemap) - m_mainCubemap->bind(); - else - m_environment->bind(); - } - - m_programs[m_currentShader]->bind(); - m_programs[m_currentShader]->setUniformValue("tex", GLint(0)); - m_programs[m_currentShader]->setUniformValue("env", GLint(1)); - m_programs[m_currentShader]->setUniformValue("noise", GLint(2)); - m_programs[m_currentShader]->setUniformValue("view", view); - m_programs[m_currentShader]->setUniformValue("invView", invView); - m_box->draw(); - m_programs[m_currentShader]->release(); - - if (glActiveTexture) { - if (m_dynamicCubemap) - m_mainCubemap->unbind(); - else - m_environment->unbind(); - } - } - - if (glActiveTexture) { - glActiveTexture(GL_TEXTURE2); - m_noise->unbind(); - glActiveTexture(GL_TEXTURE0); - } - m_textures[m_currentTexture]->unbind(); -} - -void Scene::setStates() -{ - //glClearColor(0.25f, 0.25f, 0.5f, 1.0f); - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - glEnable(GL_LIGHTING); - //glEnable(GL_COLOR_MATERIAL); - glEnable(GL_TEXTURE_2D); - glEnable(GL_NORMALIZE); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - setLights(); - - float materialSpecular[] = {0.5f, 0.5f, 0.5f, 1.0f}; - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materialSpecular); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 32.0f); -} - -void Scene::setLights() -{ - glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); - //float lightColour[] = {1.0f, 1.0f, 1.0f, 1.0f}; - float lightDir[] = {0.0f, 0.0f, 1.0f, 0.0f}; - //glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColour); - //glLightfv(GL_LIGHT0, GL_SPECULAR, lightColour); - glLightfv(GL_LIGHT0, GL_POSITION, lightDir); - glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0f); - glEnable(GL_LIGHT0); -} - -void Scene::defaultStates() -{ - //glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_LIGHTING); - //glDisable(GL_COLOR_MATERIAL); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHT0); - glDisable(GL_NORMALIZE); - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 0.0f); - float defaultMaterialSpecular[] = {0.0f, 0.0f, 0.0f, 1.0f}; - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, defaultMaterialSpecular); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f); -} - -void Scene::renderCubemaps() -{ - // To speed things up, only update the cubemaps for the small cubes every N frames. - const int N = (m_updateAllCubemaps ? 1 : 3); - - QMatrix4x4 mat; - GLRenderTargetCube::getProjectionMatrix(mat, 0.1f, 100.0f); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - loadMatrix(mat); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - - QVector3D center; - - const float eachAngle = 2 * M_PI / m_cubemaps.size(); - for (int i = m_frame % N; i < m_cubemaps.size(); i += N) { - if (0 == m_cubemaps[i]) - continue; - - float angle = i * eachAngle; - - center = m_trackBalls[1].rotation().rotatedVector(QVector3D(std::cos(angle), std::sin(angle), 0.0f)); - - for (int face = 0; face < 6; ++face) { - m_cubemaps[i]->begin(face); - - GLRenderTargetCube::getViewMatrix(mat, face); - QVector4D v = QVector4D(-center.x(), -center.y(), -center.z(), 1.0); - mat.setColumn(3, mat * v); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - renderBoxes(mat, i); - - m_cubemaps[i]->end(); - } - } - - for (int face = 0; face < 6; ++face) { - m_mainCubemap->begin(face); - GLRenderTargetCube::getViewMatrix(mat, face); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - renderBoxes(mat, -1); - - m_mainCubemap->end(); - } - - glPopMatrix(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - m_updateAllCubemaps = false; -} - -void Scene::drawBackground(QPainter *painter, const QRectF &) -{ - float width = float(painter->device()->width()); - float height = float(painter->device()->height()); - - painter->beginNativePainting(); - setStates(); - - if (m_dynamicCubemap) - renderCubemaps(); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - qgluPerspective(60.0, width / height, 0.01, 15.0); - - glMatrixMode(GL_MODELVIEW); - - QMatrix4x4 view; - view.rotate(m_trackBalls[2].rotation()); - view(2, 3) -= 2.0f * std::exp(m_distExp / 1200.0f); - renderBoxes(view); - - defaultStates(); - ++m_frame; - - painter->endNativePainting(); -} - -QPointF Scene::pixelPosToViewPos(const QPointF& p) -{ - return QPointF(2.0 * float(p.x()) / width() - 1.0, - 1.0 - 2.0 * float(p.y()) / height()); -} - -void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) -{ - QGraphicsScene::mouseMoveEvent(event); - if (event->isAccepted()) - return; - - if (event->buttons() & Qt::LeftButton) { - m_trackBalls[0].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated()); - event->accept(); - } else { - m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated()); - } - - if (event->buttons() & Qt::RightButton) { - m_trackBalls[1].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated()); - event->accept(); - } else { - m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated()); - } - - if (event->buttons() & Qt::MidButton) { - m_trackBalls[2].move(pixelPosToViewPos(event->scenePos()), QQuaternion()); - event->accept(); - } else { - m_trackBalls[2].release(pixelPosToViewPos(event->scenePos()), QQuaternion()); - } -} - -void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - QGraphicsScene::mousePressEvent(event); - if (event->isAccepted()) - return; - - if (event->buttons() & Qt::LeftButton) { - m_trackBalls[0].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated()); - event->accept(); - } - - if (event->buttons() & Qt::RightButton) { - m_trackBalls[1].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated()); - event->accept(); - } - - if (event->buttons() & Qt::MidButton) { - m_trackBalls[2].push(pixelPosToViewPos(event->scenePos()), QQuaternion()); - event->accept(); - } -} - -void Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - QGraphicsScene::mouseReleaseEvent(event); - if (event->isAccepted()) - return; - - if (event->button() == Qt::LeftButton) { - m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated()); - event->accept(); - } - - if (event->button() == Qt::RightButton) { - m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated()); - event->accept(); - } - - if (event->button() == Qt::MidButton) { - m_trackBalls[2].release(pixelPosToViewPos(event->scenePos()), QQuaternion()); - event->accept(); - } -} - -void Scene::wheelEvent(QGraphicsSceneWheelEvent * event) -{ - QGraphicsScene::wheelEvent(event); - if (!event->isAccepted()) { - m_distExp += event->delta(); - if (m_distExp < -8 * 120) - m_distExp = -8 * 120; - if (m_distExp > 10 * 120) - m_distExp = 10 * 120; - event->accept(); - } -} - -void Scene::setShader(int index) -{ - if (index >= 0 && index < m_fragmentShaders.size()) - m_currentShader = index; -} - -void Scene::setTexture(int index) -{ - if (index >= 0 && index < m_textures.size()) - m_currentTexture = index; -} - -void Scene::toggleDynamicCubemap(int state) -{ - if ((m_dynamicCubemap = (state == Qt::Checked))) - m_updateAllCubemaps = true; -} - -void Scene::setColorParameter(const QString &name, QRgb color) -{ - // set the color in all programs - for (QGLShaderProgram *program : qAsConst(m_programs)) { - program->bind(); - program->setUniformValue(program->uniformLocation(name), QColor(color)); - program->release(); - } -} - -void Scene::setFloatParameter(const QString &name, float value) -{ - // set the color in all programs - for (QGLShaderProgram *program : qAsConst(m_programs)) { - program->bind(); - program->setUniformValue(program->uniformLocation(name), value); - program->release(); - } -} - -void Scene::newItem(ItemDialog::ItemType type) -{ - QSize size = sceneRect().size().toSize(); - switch (type) { - case ItemDialog::QtBoxItem: - addItem(new QtBox(64, QRandomGenerator::global()->bounded(size.width() - 64) + 32, - QRandomGenerator::global()->bounded(size.height() - 64) + 32)); - break; - case ItemDialog::CircleItem: - addItem(new CircleItem(64, QRandomGenerator::global()->bounded(size.width() - 64) + 32, - QRandomGenerator::global()->bounded(size.height() - 64) + 32)); - break; - case ItemDialog::SquareItem: - addItem(new SquareItem(64, QRandomGenerator::global()->bounded(size.width() - 64) + 32, - QRandomGenerator::global()->bounded(size.height() - 64) + 32)); - break; - default: - break; - } -} diff --git a/examples/widgets/graphicsview/boxes/scene.h b/examples/widgets/graphicsview/boxes/scene.h deleted file mode 100644 index 5d65dc71e2..0000000000 --- a/examples/widgets/graphicsview/boxes/scene.h +++ /dev/null @@ -1,247 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SCENE_H -#define SCENE_H - -#include "glbuffers.h" -#include "glextensions.h" -#include "gltrianglemesh.h" -#include "qtbox.h" -#include "roundedbox.h" -#include "trackball.h" - -QT_BEGIN_NAMESPACE -class QMatrix4x4; -QT_END_NAMESPACE - -class ParameterEdit : public QWidget -{ -public: - virtual void emitChange() = 0; -}; - -class ColorEdit : public ParameterEdit -{ - Q_OBJECT -public: - ColorEdit(QRgb initialColor, int id); - QRgb color() const {return m_color;} - void emitChange() override { emit colorChanged(m_color, m_id); } -public slots: - void editDone(); -signals: - void colorChanged(QRgb color, int id); -protected: - void mousePressEvent(QMouseEvent *event) override; - void setColor(QRgb color); // also emits colorChanged() -private: - QGraphicsScene *m_dialogParentScene; - QLineEdit *m_lineEdit; - QFrame *m_button; - QRgb m_color; - int m_id; -}; - -class FloatEdit : public ParameterEdit -{ - Q_OBJECT -public: - FloatEdit(float initialValue, int id); - float value() const {return m_value;} - void emitChange() override { emit valueChanged(m_value, m_id); } -public slots: - void editDone(); -signals: - void valueChanged(float value, int id); -private: - QGraphicsScene *m_dialogParentScene; - QLineEdit *m_lineEdit; - float m_value; - int m_id; -}; - -class GraphicsWidget : public QGraphicsProxyWidget -{ -public: - GraphicsWidget() : QGraphicsProxyWidget(nullptr, Qt::Window) {} -protected: - QVariant itemChange(GraphicsItemChange change, const QVariant &value) override; - void resizeEvent(QGraphicsSceneResizeEvent *event) override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; -}; - -class TwoSidedGraphicsWidget : public QObject -{ - Q_OBJECT -public: - using QObject::QObject; - void setWidget(int index, QWidget *widget); - QWidget *widget(int index); -public slots: - void flip(); -protected slots: - void animateFlip(); -private: - GraphicsWidget *m_proxyWidgets[2] = {nullptr, nullptr}; - int m_current = 0; - int m_angle = 0; // angle in degrees - int m_delta = 0; -}; - -class RenderOptionsDialog : public QDialog -{ - Q_OBJECT -public: - RenderOptionsDialog(); - int addTexture(const QString &name); - int addShader(const QString &name); - void emitParameterChanged(); -protected slots: - void setColorParameter(QRgb color, int id); - void setFloatParameter(float value, int id); -signals: - void dynamicCubemapToggled(int); - void colorParameterChanged(const QString &, QRgb); - void floatParameterChanged(const QString &, float); - void textureChanged(int); - void shaderChanged(int); - void doubleClicked(); -protected: - void mouseDoubleClickEvent(QMouseEvent *event) override; - - QVector<QByteArray> m_parameterNames; - QComboBox *m_textureCombo; - QComboBox *m_shaderCombo; - QVector<ParameterEdit *> m_parameterEdits; -}; - -class ItemDialog : public QDialog -{ - Q_OBJECT -public: - enum ItemType { - QtBoxItem, - CircleItem, - SquareItem, - }; - - ItemDialog(); -public slots: - void triggerNewQtBox(); - void triggerNewCircleItem(); - void triggerNewSquareItem(); -signals: - void doubleClicked(); - void newItemTriggered(ItemDialog::ItemType type); -protected: - void mouseDoubleClickEvent(QMouseEvent *event) override; -}; - -class Scene : public QGraphicsScene -{ - Q_OBJECT -public: - Scene(int width, int height, int maxTextureSize); - ~Scene(); - void drawBackground(QPainter *painter, const QRectF &rect) override; - -public slots: - void setShader(int index); - void setTexture(int index); - void toggleDynamicCubemap(int state); - void setColorParameter(const QString &name, QRgb color); - void setFloatParameter(const QString &name, float value); - void newItem(ItemDialog::ItemType type); -protected: - void renderBoxes(const QMatrix4x4 &view, int excludeBox = -2); - void setStates(); - void setLights(); - void defaultStates(); - void renderCubemaps(); - - void mousePressEvent(QGraphicsSceneMouseEvent *event) override; - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; - void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; - void wheelEvent(QGraphicsSceneWheelEvent * event) override; -private: - void initGL(); - QPointF pixelPosToViewPos(const QPointF& p); - - QTime m_time; // ### Qt 6: remove (unused) - int m_lastTime; - int m_mouseEventTime; - int m_distExp; - int m_frame; - int m_maxTextureSize; - - int m_currentShader; - int m_currentTexture; - bool m_dynamicCubemap; - bool m_updateAllCubemaps; - - RenderOptionsDialog *m_renderOptions; - ItemDialog *m_itemDialog; - QTimer *m_timer; - GLRoundedBox *m_box; - TrackBall m_trackBalls[3]; - QVector<GLTexture *> m_textures; - GLTextureCube *m_environment; - GLTexture3D *m_noise; - GLRenderTargetCube *m_mainCubemap; - QVector<GLRenderTargetCube *> m_cubemaps; - QVector<QGLShaderProgram *> m_programs; - QGLShader *m_vertexShader; - QVector<QGLShader *> m_fragmentShaders; - QGLShader *m_environmentShader; - QGLShaderProgram *m_environmentProgram; -}; - -#endif diff --git a/examples/widgets/graphicsview/boxes/smiley.png b/examples/widgets/graphicsview/boxes/smiley.png Binary files differdeleted file mode 100644 index 41cfda6b23..0000000000 --- a/examples/widgets/graphicsview/boxes/smiley.png +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/square.jpg b/examples/widgets/graphicsview/boxes/square.jpg Binary files differdeleted file mode 100644 index 03f53bd530..0000000000 --- a/examples/widgets/graphicsview/boxes/square.jpg +++ /dev/null diff --git a/examples/widgets/graphicsview/boxes/trackball.cpp b/examples/widgets/graphicsview/boxes/trackball.cpp deleted file mode 100644 index b9dfc1fc7f..0000000000 --- a/examples/widgets/graphicsview/boxes/trackball.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "trackball.h" -#include "scene.h" - -//============================================================================// -// TrackBall // -//============================================================================// - -TrackBall::TrackBall(TrackMode mode) - : TrackBall(0, QVector3D(0, 1, 0), mode) -{ -} - -TrackBall::TrackBall(float angularVelocity, const QVector3D& axis, TrackMode mode) - : m_axis(axis) - , m_angularVelocity(angularVelocity) - , m_mode(mode) -{} - -void TrackBall::push(const QPointF& p, const QQuaternion &) -{ - m_rotation = rotation(); - m_pressed = true; - m_lastTime = QTime::currentTime(); - m_lastPos = p; - m_angularVelocity = 0.0f; -} - -void TrackBall::move(const QPointF& p, const QQuaternion &transformation) -{ - if (!m_pressed) - return; - - QTime currentTime = QTime::currentTime(); - int msecs = m_lastTime.msecsTo(currentTime); - if (msecs <= 20) - return; - - switch (m_mode) { - case Plane: - { - QLineF delta(m_lastPos, p); - const float angleDelta = qRadiansToDegrees(float(delta.length())); - m_angularVelocity = angleDelta / msecs; - m_axis = QVector3D(-delta.dy(), delta.dx(), 0.0f).normalized(); - m_axis = transformation.rotatedVector(m_axis); - m_rotation = QQuaternion::fromAxisAndAngle(m_axis, angleDelta) * m_rotation; - } - break; - case Sphere: - { - QVector3D lastPos3D = QVector3D(m_lastPos.x(), m_lastPos.y(), 0.0f); - float sqrZ = 1 - QVector3D::dotProduct(lastPos3D, lastPos3D); - if (sqrZ > 0) - lastPos3D.setZ(std::sqrt(sqrZ)); - else - lastPos3D.normalize(); - - QVector3D currentPos3D = QVector3D(p.x(), p.y(), 0.0f); - sqrZ = 1 - QVector3D::dotProduct(currentPos3D, currentPos3D); - if (sqrZ > 0) - currentPos3D.setZ(std::sqrt(sqrZ)); - else - currentPos3D.normalize(); - - m_axis = QVector3D::crossProduct(lastPos3D, currentPos3D); - float angle = qRadiansToDegrees(std::asin(m_axis.length())); - - m_angularVelocity = angle / msecs; - m_axis.normalize(); - m_axis = transformation.rotatedVector(m_axis); - m_rotation = QQuaternion::fromAxisAndAngle(m_axis, angle) * m_rotation; - } - break; - } - - - m_lastPos = p; - m_lastTime = currentTime; -} - -void TrackBall::release(const QPointF& p, const QQuaternion &transformation) -{ - // Calling move() caused the rotation to stop if the framerate was too low. - move(p, transformation); - m_pressed = false; -} - -void TrackBall::start() -{ - m_lastTime = QTime::currentTime(); - m_paused = false; -} - -void TrackBall::stop() -{ - m_rotation = rotation(); - m_paused = true; -} - -QQuaternion TrackBall::rotation() const -{ - if (m_paused || m_pressed) - return m_rotation; - - QTime currentTime = QTime::currentTime(); - float angle = m_angularVelocity * m_lastTime.msecsTo(currentTime); - return QQuaternion::fromAxisAndAngle(m_axis, angle) * m_rotation; -} - diff --git a/examples/widgets/graphicsview/boxes/trackball.h b/examples/widgets/graphicsview/boxes/trackball.h deleted file mode 100644 index af90e4d842..0000000000 --- a/examples/widgets/graphicsview/boxes/trackball.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TRACKBALL_H -#define TRACKBALL_H - -#include <QQuaternion> -#include <QTime> -#include <QVector3D> - -class TrackBall -{ -public: - enum TrackMode - { - Plane, - Sphere, - }; - TrackBall(TrackMode mode = Sphere); - TrackBall(float angularVelocity, const QVector3D &axis, TrackMode mode = Sphere); - // coordinates in [-1,1]x[-1,1] - void push(const QPointF &p, const QQuaternion &transformation); - void move(const QPointF &p, const QQuaternion &transformation); - void release(const QPointF &p, const QQuaternion &transformation); - void start(); // starts clock - void stop(); // stops clock - QQuaternion rotation() const; -private: - QQuaternion m_rotation; - QVector3D m_axis = QVector3D(0, 1, 0); - float m_angularVelocity = 0; - - QPointF m_lastPos; - QTime m_lastTime = QTime::currentTime(); - TrackMode m_mode; - bool m_paused = false; - bool m_pressed = false; -}; - -#endif diff --git a/examples/widgets/graphicsview/boxes/wood.fsh b/examples/widgets/graphicsview/boxes/wood.fsh deleted file mode 100644 index fbb5195f3a..0000000000 --- a/examples/widgets/graphicsview/boxes/wood.fsh +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -varying vec3 position, normal; -varying vec4 specular, ambient, diffuse, lightDirection; - -uniform sampler2D tex; -uniform sampler3D noise; - -//const vec4 woodColors[2] = {vec4(0.37,0.24,0.20,1), vec4(0.8,0.6,0.4,1)}; -uniform vec4 woodColors[2]; -//const float woodTubulence = 0.1; -uniform float woodTubulence; - -void main() -{ - float r = length(gl_TexCoord[1].yz); - r += woodTubulence * texture3D(noise, 0.25 * gl_TexCoord[1].xyz).x; - - vec3 N = normalize(normal); - // assume directional light - - gl_MaterialParameters M = gl_FrontMaterial; - - float NdotL = dot(N, lightDirection.xyz); - float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz); - - float f = fract(16.0 * r); - vec4 unlitColor = mix(woodColors[0], woodColors[1], min(1.25 * f, 5.0 - 5.0 * f)); - gl_FragColor = (ambient + diffuse * max(NdotL, 0.0)) * unlitColor + - M.specular * specular * pow(max(RdotL, 0.0), M.shininess); -} diff --git a/examples/widgets/graphicsview/chip/chip.pro b/examples/widgets/graphicsview/chip/chip.pro index a46f07ce35..508928d026 100644 --- a/examples/widgets/graphicsview/chip/chip.pro +++ b/examples/widgets/graphicsview/chip/chip.pro @@ -6,7 +6,6 @@ SOURCES += mainwindow.cpp view.cpp chip.cpp QT += widgets qtHaveModule(printsupport): QT += printsupport -qtHaveModule(opengl): QT += opengl build_all:!build_pass { CONFIG -= build_all diff --git a/examples/widgets/graphicsview/chip/view.cpp b/examples/widgets/graphicsview/chip/view.cpp index 21998dc2df..77a6310778 100644 --- a/examples/widgets/graphicsview/chip/view.cpp +++ b/examples/widgets/graphicsview/chip/view.cpp @@ -57,11 +57,7 @@ #include <QPrintDialog> #endif #endif -#ifndef QT_NO_OPENGL -#include <QtOpenGL> -#else #include <QtWidgets> -#endif #include <QtMath> #if QT_CONFIG(wheelevent) @@ -156,14 +152,6 @@ View::View(const QString &name, QWidget *parent) antialiasButton->setText(tr("Antialiasing")); antialiasButton->setCheckable(true); antialiasButton->setChecked(false); - openGlButton = new QToolButton; - openGlButton->setText(tr("OpenGL")); - openGlButton->setCheckable(true); -#ifndef QT_NO_OPENGL - openGlButton->setEnabled(QGLFormat::hasOpenGL()); -#else - openGlButton->setEnabled(false); -#endif printButton = new QToolButton; printButton->setIcon(QIcon(QPixmap(":/fileprint.png"))); @@ -179,7 +167,6 @@ View::View(const QString &name, QWidget *parent) labelLayout->addWidget(dragModeButton); labelLayout->addStretch(); labelLayout->addWidget(antialiasButton); - labelLayout->addWidget(openGlButton); labelLayout->addWidget(printButton); QGridLayout *topLayout = new QGridLayout; @@ -200,7 +187,6 @@ View::View(const QString &name, QWidget *parent) connect(selectModeButton, &QAbstractButton::toggled, this, &View::togglePointerMode); connect(dragModeButton, &QAbstractButton::toggled, this, &View::togglePointerMode); connect(antialiasButton, &QAbstractButton::toggled, this, &View::toggleAntialiasing); - connect(openGlButton, &QAbstractButton::toggled, this, &View::toggleOpenGL); connect(rotateLeftIcon, &QAbstractButton::clicked, this, &View::rotateLeft); connect(rotateRightIcon, &QAbstractButton::clicked, this, &View::rotateRight); connect(zoomInIcon, &QAbstractButton::clicked, this, &View::zoomIn); @@ -250,13 +236,6 @@ void View::togglePointerMode() graphicsView->setInteractive(selectModeButton->isChecked()); } -void View::toggleOpenGL() -{ -#ifndef QT_NO_OPENGL - graphicsView->setViewport(openGlButton->isChecked() ? new QGLWidget(QGLFormat(QGL::SampleBuffers)) : new QWidget); -#endif -} - void View::toggleAntialiasing() { graphicsView->setRenderHint(QPainter::Antialiasing, antialiasButton->isChecked()); diff --git a/examples/widgets/graphicsview/chip/view.h b/examples/widgets/graphicsview/chip/view.h index ea7bd414f5..b780702c34 100644 --- a/examples/widgets/graphicsview/chip/view.h +++ b/examples/widgets/graphicsview/chip/view.h @@ -94,7 +94,6 @@ private slots: void setResetButtonEnabled(); void setupMatrix(); void togglePointerMode(); - void toggleOpenGL(); void toggleAntialiasing(); void print(); void rotateLeft(); @@ -106,7 +105,6 @@ private: QLabel *label2; QToolButton *selectModeButton; QToolButton *dragModeButton; - QToolButton *openGlButton; QToolButton *antialiasButton; QToolButton *printButton; QToolButton *resetButton; diff --git a/examples/widgets/graphicsview/graphicsview.pro b/examples/widgets/graphicsview/graphicsview.pro index b9bef70a0e..d591450559 100644 --- a/examples/widgets/graphicsview/graphicsview.pro +++ b/examples/widgets/graphicsview/graphicsview.pro @@ -14,7 +14,3 @@ SUBDIRS = \ weatheranchorlayout contains(DEFINES, QT_NO_CURSOR)|!qtConfig(draganddrop): SUBDIRS -= dragdroprobot - -qtHaveModule(opengl):!qtConfig(opengles.):!qtConfig(dynamicgl) { - SUBDIRS += boxes -} diff --git a/src/opengl/doc/snippets/code/src_opengl_qgl.cpp b/src/opengl/doc/snippets/code/src_opengl_qgl.cpp deleted file mode 100644 index a73ee2cdc5..0000000000 --- a/src/opengl/doc/snippets/code/src_opengl_qgl.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] -QGLFormat fmt; -fmt.setAlpha(true); -fmt.setStereo(true); -QGLFormat::setDefaultFormat(fmt); -//! [0] - - -//! [1] -QGLFormat fmt; -fmt.setDoubleBuffer(false); // single buffer -fmt.setDirectRendering(false); // software rendering -MyGLWidget* myWidget = new MyGLWidget(fmt, ...); -//! [1] - - -//! [2] -QGLFormat fmt; -fmt.setOverlay(true); -fmt.setStereo(true); -MyGLWidget* myWidget = new MyGLWidget(fmt, ...); -if (!myWidget->format().stereo()) { - // ok, goggles off - if (!myWidget->format().hasOverlay()) { - qFatal("Cool hardware required"); - } -} -//! [2] - - -//! [3] -// The rendering in MyGLWidget depends on using -// stencil buffer and alpha channel -MyGLWidget::MyGLWidget(QWidget* parent) - : QGLWidget(QGLFormat(QGL::StencilBuffer | QGL::AlphaChannel), parent) -{ - if (!format().stencil()) - qWarning("Could not get stencil buffer; results will be suboptimal"); - if (!format().alpha()) - qWarning("Could not get alpha channel; results will be suboptimal"); - ... -} -//! [3] - - -//! [4] -QApplication a(argc, argv); -QGLFormat f; -f.setDoubleBuffer(false); -QGLFormat::setDefaultFormat(f); -//! [4] - - -//! [5] -QGLFormat f = QGLFormat::defaultOverlayFormat(); -f.setDoubleBuffer(true); -QGLFormat::setDefaultOverlayFormat(f); -//! [5] - - -//! [6] -// ...continued from above -MyGLWidget* myWidget = new MyGLWidget(QGLFormat(QGL::HasOverlay), ...); -if (myWidget->format().hasOverlay()) { - // Yes, we got an overlay, let's check _its_ format: - QGLContext* olContext = myWidget->overlayContext(); - if (olContext->format().doubleBuffer()) - ; // yes, we got a double buffered overlay - else - ; // no, only single buffered overlays are available -} -//! [6] - - -//! [7] -QGLContext *cx; -// ... -QGLFormat f; -f.setStereo(true); -cx->setFormat(f); -if (!cx->create()) - exit(); // no OpenGL support, or cannot render on the specified paintdevice -if (!cx->format().stereo()) - exit(); // could not create stereo context -//! [7] - - -//! [8] -class MyGLDrawer : public QGLWidget -{ - Q_OBJECT // must include this if you use Qt signals/slots - -public: - MyGLDrawer(QWidget *parent) - : QGLWidget(parent) {} - -protected: - - void initializeGL() override - { - // Set up the rendering context, define display lists etc.: - ... - glClearColor(0.0, 0.0, 0.0, 0.0); - glEnable(GL_DEPTH_TEST); - ... - } - - void resizeGL(int w, int h) override - { - // setup viewport, projection etc.: - glViewport(0, 0, (GLint)w, (GLint)h); - ... - glFrustum(...); - ... - } - - void paintGL() override - { - // draw the scene: - ... - glRotatef(...); - glMaterialfv(...); - glBegin(GL_QUADS); - glVertex3f(...); - glVertex3f(...); - ... - glEnd(); - ... - } - -}; -//! [8] diff --git a/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp b/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp deleted file mode 100644 index 11ef88ab37..0000000000 --- a/src/opengl/doc/snippets/code/src_opengl_qglbuffer.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] - QGLBuffer buffer1(QGLBuffer::IndexBuffer); - buffer1.create(); - - QGLBuffer buffer2 = buffer1; -//! [0] - -//! [1] - QGLBuffer::release(QGLBuffer::VertexBuffer); -//! [1] diff --git a/src/opengl/doc/snippets/code/src_opengl_qglcolormap.cpp b/src/opengl/doc/snippets/code/src_opengl_qglcolormap.cpp deleted file mode 100644 index 12a089944f..0000000000 --- a/src/opengl/doc/snippets/code/src_opengl_qglcolormap.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] -#include <QApplication> -#include <QGLColormap> - -int main() -{ - QApplication app(argc, argv); - - MySuperGLWidget widget; // a QGLWidget in color-index mode - QGLColormap colormap; - - // This will fill the colormap with colors ranging from - // black to white. - for (int i = 0; i < colormap.size(); i++) - colormap.setEntry(i, qRgb(i, i, i)); - - widget.setColormap(colormap); - widget.show(); - return app.exec(); -} -//! [0] diff --git a/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp b/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp deleted file mode 100644 index c848ae7ede..0000000000 --- a/src/opengl/doc/snippets/code/src_opengl_qglfunctions.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] - class MyGLWidget : public QGLWidget, protected QGLFunctions - { - Q_OBJECT - public: - MyGLWidget(QWidget *parent = 0) : QGLWidget(parent) {} - - protected: - void initializeGL(); - void paintGL(); - }; - - void MyGLWidget::initializeGL() - { - initializeGLFunctions(); - } -//! [0] - -//! [1] - void MyGLWidget::paintGL() - { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, textureId); - ... - } -//! [1] - -//! [2] - QGLFunctions glFuncs(QGLContext::currentContext()); - glFuncs.glActiveTexture(GL_TEXTURE1); -//! [2] - -//! [3] - QGLFunctions funcs(QGLContext::currentContext()); - bool npot = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures); -//! [3] diff --git a/src/opengl/doc/snippets/code/src_opengl_qglpixelbuffer.cpp b/src/opengl/doc/snippets/code/src_opengl_qglpixelbuffer.cpp deleted file mode 100644 index f6fbe6ddb4..0000000000 --- a/src/opengl/doc/snippets/code/src_opengl_qglpixelbuffer.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] -QGLPixelBuffer pbuffer(...); -... -pbuffer.makeCurrent(); -GLuint dynamicTexture = pbuffer.generateDynamicTexture(); -pbuffer.bindToDynamicTexture(dynamicTexture); -... -pbuffer.releaseFromDynamicTexture(); -//! [0] - - -//! [1] -QGLPixelBuffer pbuffer(...); -... -pbuffer.makeCurrent(); -GLuint dynamicTexture = pbuffer.generateDynamicTexture(); -... -pbuffer.updateDynamicTexture(dynamicTexture); -//! [1] diff --git a/src/opengl/doc/snippets/code/src_opengl_qglshaderprogram.cpp b/src/opengl/doc/snippets/code/src_opengl_qglshaderprogram.cpp deleted file mode 100644 index 04492499e8..0000000000 --- a/src/opengl/doc/snippets/code/src_opengl_qglshaderprogram.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] -QGLShader shader(QGLShader::Vertex); -shader.compileSourceCode(code); - -QGLShaderProgram program(context); -program.addShader(shader); -program.link(); - -program.bind(); -//! [0] - -//! [1] -program.addShaderFromSourceCode(QGLShader::Vertex, - "attribute highp vec4 vertex;\n" - "uniform highp mat4 matrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = matrix * vertex;\n" - "}"); -program.addShaderFromSourceCode(QGLShader::Fragment, - "uniform mediump vec4 color;\n" - "void main(void)\n" - "{\n" - " gl_FragColor = color;\n" - "}"); -program.link(); -program.bind(); - -int vertexLocation = program.attributeLocation("vertex"); -int matrixLocation = program.uniformLocation("matrix"); -int colorLocation = program.uniformLocation("color"); -//! [1] - -//! [2] -static GLfloat const triangleVertices[] = { - 60.0f, 10.0f, 0.0f, - 110.0f, 110.0f, 0.0f, - 10.0f, 110.0f, 0.0f -}; - -QColor color(0, 255, 0, 255); - -QMatrix4x4 pmvMatrix; -pmvMatrix.ortho(rect()); - -program.enableAttributeArray(vertexLocation); -program.setAttributeArray(vertexLocation, triangleVertices, 3); -program.setUniformValue(matrixLocation, pmvMatrix); -program.setUniformValue(colorLocation, color); - -glDrawArrays(GL_TRIANGLES, 0, 3); - -program.disableAttributeArray(vertexLocation); -//! [2] diff --git a/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp b/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp deleted file mode 100644 index 461e96e094..0000000000 --- a/src/opengl/doc/snippets/code/src_opengl_qgraphicsshadereffect.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//! [0] - static char const colorizeShaderCode[] = - "uniform lowp vec4 effectColor;\n" - "lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) {\n" - " vec4 src = texture2D(imageTexture, textureCoords);\n" - " float gray = dot(src.rgb, vec3(0.212671, 0.715160, 0.072169));\n" - " vec4 colorize = 1.0-((1.0-gray)*(1.0-effectColor));\n" - " return vec4(colorize.rgb, src.a);\n" - "}"; -//! [0] - -//! [1] - class ColorizeEffect : public QGraphicsShaderEffect - { - Q_OBJECT - public: - ColorizeEffect(QObject *parent = 0) - : QGraphicsShaderEffect(parent), color(Qt::black) - { - setPixelShaderFragment(colorizeShaderCode); - } - - QColor effectColor() const { return color; } - void setEffectColor(const QColor& c) - { - color = c; - setUniformsDirty(); - } - - protected: - void setUniforms(QGLShaderProgram *program) - { - program->setUniformValue("effectColor", color); - } - - private: - QColor color; - }; -//! [1] - -//! [2] - lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) { - return texture2D(imageTexture, textureCoords); - } -//! [2] diff --git a/src/opengl/doc/src/qtopengl-examples.qdoc b/src/opengl/doc/src/qtopengl-examples.qdoc index de80c92883..8770d6247e 100644 --- a/src/opengl/doc/src/qtopengl-examples.qdoc +++ b/src/opengl/doc/src/qtopengl-examples.qdoc @@ -33,12 +33,11 @@ \image opengl-examples.png - These examples describe how to use the \l {Qt OpenGL} module. For new code, - please use the OpenGL classes in the \l {Qt GUI} module. + These examples describe how to use the \l {Qt OpenGL} module. - Qt provides support for integration with OpenGL implementations on all - platforms, giving developers the opportunity to display hardware accelerated - 3D graphics alongside a more conventional user interface. + Qt provides support for integration with OpenGL implementations, giving + developers the opportunity to display hardware accelerated 3D graphics + alongside a more conventional user interface. These examples demonstrate the basic techniques used to take advantage of OpenGL in Qt applications. diff --git a/src/opengl/doc/src/qtopengl-module.qdoc b/src/opengl/doc/src/qtopengl-module.qdoc index 336d37c73f..24df4aec76 100644 --- a/src/opengl/doc/src/qtopengl-module.qdoc +++ b/src/opengl/doc/src/qtopengl-module.qdoc @@ -34,8 +34,7 @@ \brief The Qt OpenGL module offers classes that make it easy to use OpenGL in Qt applications. - \warning This module should not be used anymore for new code. Please - use the corresponding OpenGL classes in \l{Qt GUI}. + \warning This module should not be used anymore for new code. OpenGL is a standard API for rendering 3D graphics. OpenGL only deals with 3D rendering and provides little or no support for GUI @@ -48,9 +47,6 @@ the United States and other countries. The Qt OpenGL module makes it easy to use OpenGL in Qt applications. - It provides an OpenGL widget class that can be used just like any - other Qt widget, except that it opens an OpenGL display buffer where - you can use the OpenGL API to render the contents. To include the definitions of the module's classes, use the following directive: @@ -63,11 +59,4 @@ \snippet code/doc_src_qtopengl.pro 1 \endif - - The Qt OpenGL module is implemented as a platform-independent Qt/C++ - wrapper around the platform-dependent GLX (version 1.3 or later), - WGL, or AGL C APIs. Although the basic functionality provided is very - similar to Mark Kilgard's GLUT library, applications using the Qt - OpenGL module can take advantage of the whole Qt API for - non-OpenGL-specific GUI functionality. */ diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp deleted file mode 100644 index 979ea19fee..0000000000 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgl2pexvertexarray_p.h" - -#include <private/qbezier_p.h> - -QT_BEGIN_NAMESPACE - -void QGL2PEXVertexArray::clear() -{ - vertexArray.reset(); - vertexArrayStops.reset(); - boundingRectDirty = true; -} - - -QGLRect QGL2PEXVertexArray::boundingRect() const -{ - if (boundingRectDirty) - return QGLRect(0.0, 0.0, 0.0, 0.0); - else - return QGLRect(minX, minY, maxX, maxY); -} - -void QGL2PEXVertexArray::addClosingLine(int index) -{ - QPointF point(vertexArray.at(index)); - if (point != QPointF(vertexArray.last())) - vertexArray.add(point); -} - -void QGL2PEXVertexArray::addCentroid(const QVectorPath &path, int subPathIndex) -{ - const QPointF *const points = reinterpret_cast<const QPointF *>(path.points()); - const QPainterPath::ElementType *const elements = path.elements(); - - QPointF sum = points[subPathIndex]; - int count = 1; - - for (int i = subPathIndex + 1; i < path.elementCount() && (!elements || elements[i] != QPainterPath::MoveToElement); ++i) { - sum += points[i]; - ++count; - } - - const QPointF centroid = sum / qreal(count); - vertexArray.add(centroid); -} - -void QGL2PEXVertexArray::addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline) -{ - const QPointF* const points = reinterpret_cast<const QPointF*>(path.points()); - const QPainterPath::ElementType* const elements = path.elements(); - - if (boundingRectDirty) { - minX = maxX = points[0].x(); - minY = maxY = points[0].y(); - boundingRectDirty = false; - } - - if (!outline && !path.isConvex()) - addCentroid(path, 0); - - int lastMoveTo = vertexArray.size(); - vertexArray.add(points[0]); // The first element is always a moveTo - - do { - if (!elements) { -// qDebug("QVectorPath has no elements"); - // If the path has a null elements pointer, the elements implicitly - // start with a moveTo (already added) and continue with lineTos: - for (int i=1; i<path.elementCount(); ++i) - lineToArray(points[i].x(), points[i].y()); - - break; - } -// qDebug("QVectorPath has element types"); - - for (int i=1; i<path.elementCount(); ++i) { - switch (elements[i]) { - case QPainterPath::MoveToElement: - if (!outline) - addClosingLine(lastMoveTo); -// qDebug("element[%d] is a MoveToElement", i); - vertexArrayStops.add(vertexArray.size()); - if (!outline) { - if (!path.isConvex()) addCentroid(path, i); - lastMoveTo = vertexArray.size(); - } - lineToArray(points[i].x(), points[i].y()); // Add the moveTo as a new vertex - break; - case QPainterPath::LineToElement: -// qDebug("element[%d] is a LineToElement", i); - lineToArray(points[i].x(), points[i].y()); - break; - case QPainterPath::CurveToElement: { - QBezier b = QBezier::fromPoints(*(((const QPointF *) points) + i - 1), - points[i], - points[i+1], - points[i+2]); - QRectF bounds = b.bounds(); - // threshold based on same algorithm as in qtriangulatingstroker.cpp - int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * 3.14f / (curveInverseScale * 6)); - if (threshold < 3) threshold = 3; - qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1); - for (int t=0; t<threshold; ++t) { - QPointF pt = b.pointAt(t * one_over_threshold_minus_1); - lineToArray(pt.x(), pt.y()); - } - i += 2; - break; } - default: - break; - } - } - } while (0); - - if (!outline) - addClosingLine(lastMoveTo); - vertexArrayStops.add(vertexArray.size()); -} - -void QGL2PEXVertexArray::lineToArray(const GLfloat x, const GLfloat y) -{ - vertexArray.add(QGLPoint(x, y)); - - if (x > maxX) - maxX = x; - else if (x < minX) - minX = x; - if (y > maxY) - maxY = y; - else if (y < minY) - minY = y; -} - -QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h deleted file mode 100644 index 5c95268790..0000000000 --- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h +++ /dev/null @@ -1,167 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QGL2PEXVERTEXARRAY_P_H -#define QGL2PEXVERTEXARRAY_P_H - -#include <QRectF> - -#include <private/qdatabuffer_p.h> -#include <private/qvectorpath_p.h> -#include <private/qgl_p.h> - -QT_BEGIN_NAMESPACE - -class QGLPoint -{ -public: - QGLPoint(GLfloat new_x, GLfloat new_y) : - x(new_x), y(new_y) {}; - - QGLPoint(const QPointF &p) : - x(p.x()), y(p.y()) {}; - - QGLPoint(const QPointF* p) : - x(p->x()), y(p->y()) {}; - - GLfloat x; - GLfloat y; - - operator QPointF() {return QPointF(x,y);} - operator QPointF() const {return QPointF(x,y);} -}; - -struct QGLRect -{ - QGLRect(const QRectF &r) - : left(r.left()), top(r.top()), right(r.right()), bottom(r.bottom()) {} - - QGLRect(GLfloat l, GLfloat t, GLfloat r, GLfloat b) - : left(l), top(t), right(r), bottom(b) {} - - GLfloat left; - GLfloat top; - GLfloat right; - GLfloat bottom; - - operator QRectF() const {return QRectF(left, top, right-left, bottom-top);} -}; - -class QGL2PEXVertexArray -{ -public: - QGL2PEXVertexArray() : - vertexArray(0), vertexArrayStops(0), - maxX(-2e10), maxY(-2e10), minX(2e10), minY(2e10), - boundingRectDirty(true) - { } - - inline void addRect(const QRectF &rect) - { - qreal top = rect.top(); - qreal left = rect.left(); - qreal bottom = rect.bottom(); - qreal right = rect.right(); - - vertexArray << QGLPoint(left, top) - << QGLPoint(right, top) - << QGLPoint(right, bottom) - << QGLPoint(right, bottom) - << QGLPoint(left, bottom) - << QGLPoint(left, top); - } - - inline void addQuad(const QRectF &rect) - { - qreal top = rect.top(); - qreal left = rect.left(); - qreal bottom = rect.bottom(); - qreal right = rect.right(); - - vertexArray << QGLPoint(left, top) - << QGLPoint(right, top) - << QGLPoint(left, bottom) - << QGLPoint(right, bottom); - - } - - inline void addVertex(const GLfloat x, const GLfloat y) - { - vertexArray.add(QGLPoint(x, y)); - } - - void addPath(const QVectorPath &path, GLfloat curveInverseScale, bool outline = true); - void clear(); - - QGLPoint* data() {return vertexArray.data();} - int *stops() const { return vertexArrayStops.data(); } - int stopCount() const { return vertexArrayStops.size(); } - QGLRect boundingRect() const; - - int vertexCount() const { return vertexArray.size(); } - - void lineToArray(const GLfloat x, const GLfloat y); - -private: - QDataBuffer<QGLPoint> vertexArray; - QDataBuffer<int> vertexArrayStops; - - GLfloat maxX; - GLfloat maxY; - GLfloat minX; - GLfloat minY; - bool boundingRectDirty; - void addClosingLine(int index); - void addCentroid(const QVectorPath &path, int subPathIndex); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp deleted file mode 100644 index 7d6d4595ba..0000000000 --- a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglcustomshaderstage_p.h" -#include "qglengineshadermanager_p.h" -#include "qpaintengineex_opengl2_p.h" -#include <private/qpainter_p.h> - -QT_BEGIN_NAMESPACE - -class QGLCustomShaderStagePrivate -{ -public: - QGLCustomShaderStagePrivate() : - m_manager(0) {} - - QPointer<QGLEngineShaderManager> m_manager; - QByteArray m_source; -}; - - - - -QGLCustomShaderStage::QGLCustomShaderStage() - : d_ptr(new QGLCustomShaderStagePrivate) -{ -} - -QGLCustomShaderStage::~QGLCustomShaderStage() -{ - Q_D(QGLCustomShaderStage); - if (d->m_manager) { - d->m_manager->removeCustomStage(); - d->m_manager->sharedShaders->cleanupCustomStage(this); - } - delete d_ptr; -} - -void QGLCustomShaderStage::setUniformsDirty() -{ - Q_D(QGLCustomShaderStage); - if (d->m_manager) - d->m_manager->setDirty(); // ### Probably a bit overkill! -} - -bool QGLCustomShaderStage::setOnPainter(QPainter* p) -{ - Q_D(QGLCustomShaderStage); - if (p->paintEngine()->type() != QPaintEngine::OpenGL2) { - qWarning("QGLCustomShaderStage::setOnPainter() - paint engine not OpenGL2"); - return false; - } - if (d->m_manager) - qWarning("Custom shader is already set on a painter"); - - QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx*>(p->paintEngine()); - d->m_manager = QGL2PaintEngineExPrivate::shaderManagerForEngine(engine); - Q_ASSERT(d->m_manager); - - d->m_manager->setCustomStage(this); - return true; -} - -void QGLCustomShaderStage::removeFromPainter(QPainter* p) -{ - Q_D(QGLCustomShaderStage); - if (p->paintEngine()->type() != QPaintEngine::OpenGL2) - return; - - QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx*>(p->paintEngine()); - d->m_manager = QGL2PaintEngineExPrivate::shaderManagerForEngine(engine); - Q_ASSERT(d->m_manager); - - // Just set the stage to null, don't call removeCustomStage(). - // This should leave the program in a compiled/linked state - // if the next custom shader stage is this one again. - d->m_manager->setCustomStage(0); - d->m_manager = 0; -} - -QByteArray QGLCustomShaderStage::source() const -{ - Q_D(const QGLCustomShaderStage); - return d->m_source; -} - -// Called by the shader manager if another custom shader is attached or -// the manager is deleted -void QGLCustomShaderStage::setInactive() -{ - Q_D(QGLCustomShaderStage); - d->m_manager = 0; -} - -void QGLCustomShaderStage::setSource(const QByteArray& s) -{ - Q_D(QGLCustomShaderStage); - d->m_source = s; -} - -QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h deleted file mode 100644 index 77421ebdd3..0000000000 --- a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGL_CUSTOM_SHADER_STAGE_H -#define QGL_CUSTOM_SHADER_STAGE_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QGLShaderProgram> - -QT_BEGIN_NAMESPACE - - -class QGLCustomShaderStagePrivate; -class Q_OPENGL_EXPORT QGLCustomShaderStage -{ - Q_DECLARE_PRIVATE(QGLCustomShaderStage) -public: - QGLCustomShaderStage(); - virtual ~QGLCustomShaderStage(); - virtual void setUniforms(QGLShaderProgram*) {} - - void setUniformsDirty(); - - bool setOnPainter(QPainter*); - void removeFromPainter(QPainter*); - QByteArray source() const; - - void setInactive(); -protected: - void setSource(const QByteArray&); - -private: - QGLCustomShaderStagePrivate* d_ptr; -}; - - -QT_END_NAMESPACE - - -#endif diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp deleted file mode 100644 index 47e8531959..0000000000 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ /dev/null @@ -1,875 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglengineshadermanager_p.h" -#include "qglengineshadersource_p.h" -#include "qpaintengineex_opengl2_p.h" -#include "qglshadercache_p.h" - -#include <QtGui/private/qopenglcontext_p.h> - -#if defined(QT_DEBUG) -#include <QMetaEnum> -#endif - -#include <algorithm> - -// #define QT_GL_SHARED_SHADER_DEBUG - -QT_BEGIN_NAMESPACE - -class QGLEngineSharedShadersResource : public QOpenGLSharedResource -{ -public: - QGLEngineSharedShadersResource(QOpenGLContext *ctx) - : QOpenGLSharedResource(ctx->shareGroup()) - , m_shaders(new QGLEngineSharedShaders(QGLContext::fromOpenGLContext(ctx))) - { - } - - ~QGLEngineSharedShadersResource() - { - delete m_shaders; - } - - void invalidateResource() override - { - delete m_shaders; - m_shaders = 0; - } - - void freeResource(QOpenGLContext *) override - { - } - - QGLEngineSharedShaders *shaders() const { return m_shaders; } - -private: - QGLEngineSharedShaders *m_shaders; -}; - -class QGLShaderStorage -{ -public: - QGLEngineSharedShaders *shadersForThread(const QGLContext *context) { - QOpenGLMultiGroupSharedResource *&shaders = m_storage.localData(); - if (!shaders) - shaders = new QOpenGLMultiGroupSharedResource; - QGLEngineSharedShadersResource *resource = - shaders->value<QGLEngineSharedShadersResource>(context->contextHandle()); - return resource ? resource->shaders() : 0; - } - -private: - QThreadStorage<QOpenGLMultiGroupSharedResource *> m_storage; -}; - -Q_GLOBAL_STATIC(QGLShaderStorage, qt_shader_storage); - -QGLEngineSharedShaders *QGLEngineSharedShaders::shadersForContext(const QGLContext *context) -{ - return qt_shader_storage()->shadersForThread(context); -} - -const char* QGLEngineSharedShaders::qShaderSnippets[] = { - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0 -}; - -QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) - : blitShaderProg(0) - , simpleShaderProg(0) -{ - -/* - Rather than having the shader source array statically initialised, it is initialised - here instead. This is to allow new shader names to be inserted or existing names moved - around without having to change the order of the glsl strings. It is hoped this will - make future hard-to-find runtime bugs more obvious and generally give more solid code. -*/ - static bool snippetsPopulated = false; - if (!snippetsPopulated) { - - const char** code = qShaderSnippets; // shortcut - - code[MainVertexShader] = qglslMainVertexShader; - code[MainWithTexCoordsVertexShader] = qglslMainWithTexCoordsVertexShader; - code[MainWithTexCoordsAndOpacityVertexShader] = qglslMainWithTexCoordsAndOpacityVertexShader; - - code[UntransformedPositionVertexShader] = qglslUntransformedPositionVertexShader; - code[PositionOnlyVertexShader] = qglslPositionOnlyVertexShader; - code[ComplexGeometryPositionOnlyVertexShader] = qglslComplexGeometryPositionOnlyVertexShader; - code[PositionWithPatternBrushVertexShader] = qglslPositionWithPatternBrushVertexShader; - code[PositionWithLinearGradientBrushVertexShader] = qglslPositionWithLinearGradientBrushVertexShader; - code[PositionWithConicalGradientBrushVertexShader] = qglslPositionWithConicalGradientBrushVertexShader; - code[PositionWithRadialGradientBrushVertexShader] = qglslPositionWithRadialGradientBrushVertexShader; - code[PositionWithTextureBrushVertexShader] = qglslPositionWithTextureBrushVertexShader; - code[AffinePositionWithPatternBrushVertexShader] = qglslAffinePositionWithPatternBrushVertexShader; - code[AffinePositionWithLinearGradientBrushVertexShader] = qglslAffinePositionWithLinearGradientBrushVertexShader; - code[AffinePositionWithConicalGradientBrushVertexShader] = qglslAffinePositionWithConicalGradientBrushVertexShader; - code[AffinePositionWithRadialGradientBrushVertexShader] = qglslAffinePositionWithRadialGradientBrushVertexShader; - code[AffinePositionWithTextureBrushVertexShader] = qglslAffinePositionWithTextureBrushVertexShader; - - code[MainFragmentShader_CMO] = qglslMainFragmentShader_CMO; - code[MainFragmentShader_CM] = qglslMainFragmentShader_CM; - code[MainFragmentShader_MO] = qglslMainFragmentShader_MO; - code[MainFragmentShader_M] = qglslMainFragmentShader_M; - code[MainFragmentShader_CO] = qglslMainFragmentShader_CO; - code[MainFragmentShader_C] = qglslMainFragmentShader_C; - code[MainFragmentShader_O] = qglslMainFragmentShader_O; - code[MainFragmentShader] = qglslMainFragmentShader; - code[MainFragmentShader_ImageArrays] = qglslMainFragmentShader_ImageArrays; - - code[ImageSrcFragmentShader] = qglslImageSrcFragmentShader; - code[ImageSrcWithPatternFragmentShader] = qglslImageSrcWithPatternFragmentShader; - code[NonPremultipliedImageSrcFragmentShader] = qglslNonPremultipliedImageSrcFragmentShader; - code[CustomImageSrcFragmentShader] = qglslCustomSrcFragmentShader; // Calls "customShader", which must be appended - code[SolidBrushSrcFragmentShader] = qglslSolidBrushSrcFragmentShader; - if (!context->contextHandle()->isOpenGLES()) - code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_desktop; - else - code[TextureBrushSrcFragmentShader] = qglslTextureBrushSrcFragmentShader_ES; - code[TextureBrushSrcWithPatternFragmentShader] = qglslTextureBrushSrcWithPatternFragmentShader; - code[PatternBrushSrcFragmentShader] = qglslPatternBrushSrcFragmentShader; - code[LinearGradientBrushSrcFragmentShader] = qglslLinearGradientBrushSrcFragmentShader; - code[RadialGradientBrushSrcFragmentShader] = qglslRadialGradientBrushSrcFragmentShader; - code[ConicalGradientBrushSrcFragmentShader] = qglslConicalGradientBrushSrcFragmentShader; - code[ShockingPinkSrcFragmentShader] = qglslShockingPinkSrcFragmentShader; - - code[NoMaskFragmentShader] = ""; - code[MaskFragmentShader] = qglslMaskFragmentShader; - code[RgbMaskFragmentShaderPass1] = qglslRgbMaskFragmentShaderPass1; - code[RgbMaskFragmentShaderPass2] = qglslRgbMaskFragmentShaderPass2; - code[RgbMaskWithGammaFragmentShader] = ""; //### - - code[NoCompositionModeFragmentShader] = ""; - code[MultiplyCompositionModeFragmentShader] = ""; //### - code[ScreenCompositionModeFragmentShader] = ""; //### - code[OverlayCompositionModeFragmentShader] = ""; //### - code[DarkenCompositionModeFragmentShader] = ""; //### - code[LightenCompositionModeFragmentShader] = ""; //### - code[ColorDodgeCompositionModeFragmentShader] = ""; //### - code[ColorBurnCompositionModeFragmentShader] = ""; //### - code[HardLightCompositionModeFragmentShader] = ""; //### - code[SoftLightCompositionModeFragmentShader] = ""; //### - code[DifferenceCompositionModeFragmentShader] = ""; //### - code[ExclusionCompositionModeFragmentShader] = ""; //### - -#if defined(QT_DEBUG) - // Check that all the elements have been filled: - for (int i = 0; i < TotalSnippetCount; ++i) { - if (Q_UNLIKELY(!qShaderSnippets[i])) { - qFatal("Shader snippet for %s (#%d) is missing!", - snippetNameStr(SnippetName(i)).constData(), i); - } - } -#endif - snippetsPopulated = true; - } - - QGLShader* fragShader; - QGLShader* vertexShader; - QByteArray vertexSource; - QByteArray fragSource; - - // Compile up the simple shader: - vertexSource.append(qShaderSnippets[MainVertexShader]); - vertexSource.append(qShaderSnippets[PositionOnlyVertexShader]); - - fragSource.append(qShaderSnippets[MainFragmentShader]); - fragSource.append(qShaderSnippets[ShockingPinkSrcFragmentShader]); - - simpleShaderProg = new QGLShaderProgram(context, 0); - - CachedShader simpleShaderCache(fragSource, vertexSource); - - bool inCache = simpleShaderCache.load(simpleShaderProg, context); - - if (!inCache) { - vertexShader = new QGLShader(QGLShader::Vertex, context, 0); - shaders.append(vertexShader); - if (!vertexShader->compileSourceCode(vertexSource)) - qWarning("Vertex shader for simpleShaderProg (MainVertexShader & PositionOnlyVertexShader) failed to compile"); - - fragShader = new QGLShader(QGLShader::Fragment, context, 0); - shaders.append(fragShader); - if (!fragShader->compileSourceCode(fragSource)) - qWarning("Fragment shader for simpleShaderProg (MainFragmentShader & ShockingPinkSrcFragmentShader) failed to compile"); - - simpleShaderProg->addShader(vertexShader); - simpleShaderProg->addShader(fragShader); - - simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); - simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); - simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); - } - - simpleShaderProg->link(); - - if (Q_UNLIKELY(!simpleShaderProg->isLinked())) { - qCritical("Errors linking simple shader: %s", qPrintable(simpleShaderProg->log())); - } else { - if (!inCache) - simpleShaderCache.store(simpleShaderProg, context); - } - - // Compile the blit shader: - vertexSource.clear(); - vertexSource.append(qShaderSnippets[MainWithTexCoordsVertexShader]); - vertexSource.append(qShaderSnippets[UntransformedPositionVertexShader]); - - fragSource.clear(); - fragSource.append(qShaderSnippets[MainFragmentShader]); - fragSource.append(qShaderSnippets[ImageSrcFragmentShader]); - - blitShaderProg = new QGLShaderProgram(context, 0); - - CachedShader blitShaderCache(fragSource, vertexSource); - - inCache = blitShaderCache.load(blitShaderProg, context); - - if (!inCache) { - vertexShader = new QGLShader(QGLShader::Vertex, context, 0); - shaders.append(vertexShader); - if (!vertexShader->compileSourceCode(vertexSource)) - qWarning("Vertex shader for blitShaderProg (MainWithTexCoordsVertexShader & UntransformedPositionVertexShader) failed to compile"); - - fragShader = new QGLShader(QGLShader::Fragment, context, 0); - shaders.append(fragShader); - if (!fragShader->compileSourceCode(fragSource)) - qWarning("Fragment shader for blitShaderProg (MainFragmentShader & ImageSrcFragmentShader) failed to compile"); - - blitShaderProg->addShader(vertexShader); - blitShaderProg->addShader(fragShader); - - blitShaderProg->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - blitShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - } - - blitShaderProg->link(); - if (Q_UNLIKELY(!blitShaderProg->isLinked())) { - qCritical("Errors linking blit shader: %s", qPrintable(blitShaderProg->log())); - } else { - if (!inCache) - blitShaderCache.store(blitShaderProg, context); - } - -#ifdef QT_GL_SHARED_SHADER_DEBUG - qDebug(" -> QGLEngineSharedShaders() %p for thread %p.", this, QThread::currentThread()); -#endif -} - -QGLEngineSharedShaders::~QGLEngineSharedShaders() -{ -#ifdef QT_GL_SHARED_SHADER_DEBUG - qDebug(" -> ~QGLEngineSharedShaders() %p for thread %p.", this, QThread::currentThread()); -#endif - qDeleteAll(shaders); - shaders.clear(); - - qDeleteAll(cachedPrograms); - cachedPrograms.clear(); - - if (blitShaderProg) { - delete blitShaderProg; - blitShaderProg = 0; - } - - if (simpleShaderProg) { - delete simpleShaderProg; - simpleShaderProg = 0; - } -} - -#if defined (QT_DEBUG) -QByteArray QGLEngineSharedShaders::snippetNameStr(SnippetName name) -{ - QMetaEnum m = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("SnippetName")); - return QByteArray(m.valueToKey(name)); -} -#endif - -// The address returned here will only be valid until next time this function is called. -// The program is return bound. -QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineShaderProg &prog) -{ - for (int i = 0; i < cachedPrograms.size(); ++i) { - QGLEngineShaderProg *cachedProg = cachedPrograms.at(i); - if (*cachedProg == prog) { - // Move the program to the top of the list as a poor-man's cache algo - cachedPrograms.move(i, 0); - cachedProg->program->bind(); - return cachedProg; - } - } - - QScopedPointer<QGLEngineShaderProg> newProg; - - do { - QByteArray fragSource; - // Insert the custom stage before the srcPixel shader to work around an ATI driver bug - // where you cannot forward declare a function that takes a sampler as argument. - if (prog.srcPixelFragShader == CustomImageSrcFragmentShader) - fragSource.append(prog.customStageSource); - fragSource.append(qShaderSnippets[prog.mainFragShader]); - fragSource.append(qShaderSnippets[prog.srcPixelFragShader]); - if (prog.compositionFragShader) - fragSource.append(qShaderSnippets[prog.compositionFragShader]); - if (prog.maskFragShader) - fragSource.append(qShaderSnippets[prog.maskFragShader]); - - QByteArray vertexSource; - vertexSource.append(qShaderSnippets[prog.mainVertexShader]); - vertexSource.append(qShaderSnippets[prog.positionVertexShader]); - - QScopedPointer<QGLShaderProgram> shaderProgram(new QGLShaderProgram); - - CachedShader shaderCache(fragSource, vertexSource); - bool inCache = shaderCache.load(shaderProgram.data(), QGLContext::currentContext()); - - if (!inCache) { - - QScopedPointer<QGLShader> fragShader(new QGLShader(QGLShader::Fragment)); - QByteArray description; -#if defined(QT_DEBUG) - // Name the shader for easier debugging - description.append("Fragment shader: main="); - description.append(snippetNameStr(prog.mainFragShader)); - description.append(", srcPixel="); - description.append(snippetNameStr(prog.srcPixelFragShader)); - if (prog.compositionFragShader) { - description.append(", composition="); - description.append(snippetNameStr(prog.compositionFragShader)); - } - if (prog.maskFragShader) { - description.append(", mask="); - description.append(snippetNameStr(prog.maskFragShader)); - } - fragShader->setObjectName(QString::fromLatin1(description)); -#endif - if (!fragShader->compileSourceCode(fragSource)) { - qWarning() << "Warning:" << description << "failed to compile!"; - break; - } - - QScopedPointer<QGLShader> vertexShader(new QGLShader(QGLShader::Vertex)); -#if defined(QT_DEBUG) - // Name the shader for easier debugging - description.clear(); - description.append("Vertex shader: main="); - description.append(snippetNameStr(prog.mainVertexShader)); - description.append(", position="); - description.append(snippetNameStr(prog.positionVertexShader)); - vertexShader->setObjectName(QString::fromLatin1(description)); -#endif - if (!vertexShader->compileSourceCode(vertexSource)) { - qWarning() << "Warning:" << description << "failed to compile!"; - break; - } - - shaders.append(vertexShader.data()); - shaders.append(fragShader.data()); - shaderProgram->addShader(vertexShader.take()); - shaderProgram->addShader(fragShader.take()); - - // We have to bind the vertex attribute names before the program is linked: - shaderProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - if (prog.useTextureCoords) - shaderProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - if (prog.useOpacityAttribute) - shaderProgram->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); - if (prog.usePmvMatrixAttribute) { - shaderProgram->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); - shaderProgram->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); - shaderProgram->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); - } - } - - newProg.reset(new QGLEngineShaderProg(prog)); - newProg->program = shaderProgram.take(); - - newProg->program->link(); - if (newProg->program->isLinked()) { - if (!inCache) - shaderCache.store(newProg->program, QGLContext::currentContext()); - } else { - QString error; - error = QLatin1String("Shader program failed to link,"); -#if defined(QT_DEBUG) - QLatin1String br("\n"); - error += QLatin1String("\n Shaders Used:\n"); - for (int i = 0; i < newProg->program->shaders().count(); ++i) { - QGLShader *shader = newProg->program->shaders().at(i); - error += QLatin1String(" ") + shader->objectName() + QLatin1String(": \n") - + QLatin1String(shader->sourceCode()) + br; - } -#endif - error += QLatin1String(" Error Log:\n") - + QLatin1String(" ") + newProg->program->log(); - qWarning() << error; - break; - } - - newProg->program->bind(); - - if (newProg->maskFragShader != QGLEngineSharedShaders::NoMaskFragmentShader) { - GLuint location = newProg->program->uniformLocation("maskTexture"); - newProg->program->setUniformValue(location, QT_MASK_TEXTURE_UNIT); - } - - if (cachedPrograms.count() > 30) { - // The cache is full, so delete the last 5 programs in the list. - // These programs will be least used, as a program us bumped to - // the top of the list when it's used. - for (int i = 0; i < 5; ++i) { - delete cachedPrograms.last(); - cachedPrograms.removeLast(); - } - } - - cachedPrograms.insert(0, newProg.data()); - } while (false); - - return newProg.take(); -} - -void QGLEngineSharedShaders::cleanupCustomStage(QGLCustomShaderStage* stage) -{ - auto hasStageAsCustomShaderSouce = [stage](QGLEngineShaderProg *cachedProg) -> bool { - if (cachedProg->customStageSource == stage->source()) { - delete cachedProg; - return true; - } - return false; - }; - cachedPrograms.erase(std::remove_if(cachedPrograms.begin(), cachedPrograms.end(), - hasStageAsCustomShaderSouce), - cachedPrograms.end()); -} - - -QGLEngineShaderManager::QGLEngineShaderManager(QGLContext* context) - : ctx(context), - shaderProgNeedsChanging(true), - complexGeometry(false), - srcPixelType(Qt::NoBrush), - opacityMode(NoOpacity), - maskType(NoMask), - compositionMode(QPainter::CompositionMode_SourceOver), - customSrcStage(0), - currentShaderProg(0) -{ - sharedShaders = QGLEngineSharedShaders::shadersForContext(context); -} - -QGLEngineShaderManager::~QGLEngineShaderManager() -{ - //### - removeCustomStage(); -} - -GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) -{ - if (!currentShaderProg) - return 0; - - QVector<uint> &uniformLocations = currentShaderProg->uniformLocations; - if (uniformLocations.isEmpty()) - uniformLocations.fill(GLuint(-1), NumUniforms); - - static const char *const uniformNames[] = { - "imageTexture", - "patternColor", - "globalOpacity", - "depth", - "maskTexture", - "fragmentColor", - "linearData", - "angle", - "halfViewportSize", - "fmp", - "fmp2_m_radius2", - "inverse_2_fmp2_m_radius2", - "sqrfr", - "bradius", - "invertedTextureSize", - "brushTransform", - "brushTexture", - "matrix", - "translateZ" - }; - - if (uniformLocations.at(id) == GLuint(-1)) - uniformLocations[id] = currentShaderProg->program->uniformLocation(uniformNames[id]); - - return uniformLocations.at(id); -} - - -void QGLEngineShaderManager::optimiseForBrushTransform(QTransform::TransformationType transformType) -{ - Q_UNUSED(transformType); // Currently ignored -} - -void QGLEngineShaderManager::setDirty() -{ - shaderProgNeedsChanging = true; -} - -void QGLEngineShaderManager::setSrcPixelType(Qt::BrushStyle style) -{ - Q_ASSERT(style != Qt::NoBrush); - if (srcPixelType == PixelSrcType(style)) - return; - - srcPixelType = style; - shaderProgNeedsChanging = true; //### -} - -void QGLEngineShaderManager::setSrcPixelType(PixelSrcType type) -{ - if (srcPixelType == type) - return; - - srcPixelType = type; - shaderProgNeedsChanging = true; //### -} - -void QGLEngineShaderManager::setOpacityMode(OpacityMode mode) -{ - if (opacityMode == mode) - return; - - opacityMode = mode; - shaderProgNeedsChanging = true; //### -} - -void QGLEngineShaderManager::setMaskType(MaskType type) -{ - if (maskType == type) - return; - - maskType = type; - shaderProgNeedsChanging = true; //### -} - -void QGLEngineShaderManager::setCompositionMode(QPainter::CompositionMode mode) -{ - if (compositionMode == mode) - return; - - compositionMode = mode; - shaderProgNeedsChanging = true; //### -} - -void QGLEngineShaderManager::setCustomStage(QGLCustomShaderStage* stage) -{ - if (customSrcStage) - removeCustomStage(); - customSrcStage = stage; - shaderProgNeedsChanging = true; -} - -void QGLEngineShaderManager::removeCustomStage() -{ - if (customSrcStage) - customSrcStage->setInactive(); - customSrcStage = 0; - shaderProgNeedsChanging = true; -} - -QGLShaderProgram* QGLEngineShaderManager::currentProgram() -{ - if (currentShaderProg) - return currentShaderProg->program; - else - return sharedShaders->simpleProgram(); -} - -void QGLEngineShaderManager::useSimpleProgram() -{ - sharedShaders->simpleProgram()->bind(); - QGLContextPrivate* ctx_d = ctx->d_func(); - ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); - ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false); - ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); - shaderProgNeedsChanging = true; -} - -void QGLEngineShaderManager::useBlitProgram() -{ - sharedShaders->blitProgram()->bind(); - QGLContextPrivate* ctx_d = ctx->d_func(); - ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); - ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, true); - ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); - shaderProgNeedsChanging = true; -} - -QGLShaderProgram* QGLEngineShaderManager::simpleProgram() -{ - return sharedShaders->simpleProgram(); -} - -QGLShaderProgram* QGLEngineShaderManager::blitProgram() -{ - return sharedShaders->blitProgram(); -} - - - -// Select & use the correct shader program using the current state. -// Returns \c true if program needed changing. -bool QGLEngineShaderManager::useCorrectShaderProg() -{ - if (!shaderProgNeedsChanging) - return false; - - bool useCustomSrc = customSrcStage != 0; - if (useCustomSrc && srcPixelType != QGLEngineShaderManager::ImageSrc && srcPixelType != Qt::TexturePattern) { - useCustomSrc = false; - qWarning("QGLEngineShaderManager - Ignoring custom shader stage for non image src"); - } - - QGLEngineShaderProg requiredProgram; - - bool texCoords = false; - - // Choose vertex shader shader position function (which typically also sets - // varyings) and the source pixel (srcPixel) fragment shader function: - requiredProgram.positionVertexShader = QGLEngineSharedShaders::InvalidSnippetName; - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::InvalidSnippetName; - bool isAffine = brushTransform.isAffine(); - if ( (srcPixelType >= Qt::Dense1Pattern) && (srcPixelType <= Qt::DiagCrossPattern) ) { - if (isAffine) - requiredProgram.positionVertexShader = QGLEngineSharedShaders::AffinePositionWithPatternBrushVertexShader; - else - requiredProgram.positionVertexShader = QGLEngineSharedShaders::PositionWithPatternBrushVertexShader; - - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::PatternBrushSrcFragmentShader; - } - else switch (srcPixelType) { - default: - case Qt::NoBrush: - qFatal("QGLEngineShaderManager::useCorrectShaderProg() - Qt::NoBrush style is set"); - break; - case QGLEngineShaderManager::ImageSrc: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::ImageSrcFragmentShader; - requiredProgram.positionVertexShader = QGLEngineSharedShaders::PositionOnlyVertexShader; - texCoords = true; - break; - case QGLEngineShaderManager::NonPremultipliedImageSrc: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::NonPremultipliedImageSrcFragmentShader; - requiredProgram.positionVertexShader = QGLEngineSharedShaders::PositionOnlyVertexShader; - texCoords = true; - break; - case QGLEngineShaderManager::PatternSrc: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::ImageSrcWithPatternFragmentShader; - requiredProgram.positionVertexShader = QGLEngineSharedShaders::PositionOnlyVertexShader; - texCoords = true; - break; - case QGLEngineShaderManager::TextureSrcWithPattern: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::TextureBrushSrcWithPatternFragmentShader; - requiredProgram.positionVertexShader = isAffine ? QGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader - : QGLEngineSharedShaders::PositionWithTextureBrushVertexShader; - break; - case Qt::SolidPattern: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::SolidBrushSrcFragmentShader; - requiredProgram.positionVertexShader = QGLEngineSharedShaders::PositionOnlyVertexShader; - break; - case Qt::LinearGradientPattern: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::LinearGradientBrushSrcFragmentShader; - requiredProgram.positionVertexShader = isAffine ? QGLEngineSharedShaders::AffinePositionWithLinearGradientBrushVertexShader - : QGLEngineSharedShaders::PositionWithLinearGradientBrushVertexShader; - break; - case Qt::ConicalGradientPattern: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::ConicalGradientBrushSrcFragmentShader; - requiredProgram.positionVertexShader = isAffine ? QGLEngineSharedShaders::AffinePositionWithConicalGradientBrushVertexShader - : QGLEngineSharedShaders::PositionWithConicalGradientBrushVertexShader; - break; - case Qt::RadialGradientPattern: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::RadialGradientBrushSrcFragmentShader; - requiredProgram.positionVertexShader = isAffine ? QGLEngineSharedShaders::AffinePositionWithRadialGradientBrushVertexShader - : QGLEngineSharedShaders::PositionWithRadialGradientBrushVertexShader; - break; - case Qt::TexturePattern: - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::TextureBrushSrcFragmentShader; - requiredProgram.positionVertexShader = isAffine ? QGLEngineSharedShaders::AffinePositionWithTextureBrushVertexShader - : QGLEngineSharedShaders::PositionWithTextureBrushVertexShader; - break; - }; - - if (useCustomSrc) { - requiredProgram.srcPixelFragShader = QGLEngineSharedShaders::CustomImageSrcFragmentShader; - requiredProgram.customStageSource = customSrcStage->source(); - } - - const bool hasCompose = compositionMode > QPainter::CompositionMode_Plus; - const bool hasMask = maskType != QGLEngineShaderManager::NoMask; - - // Choose fragment shader main function: - if (opacityMode == AttributeOpacity) { - Q_ASSERT(!hasCompose && !hasMask); - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader_ImageArrays; - } else { - bool useGlobalOpacity = (opacityMode == UniformOpacity); - if (hasCompose && hasMask && useGlobalOpacity) - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader_CMO; - if (hasCompose && hasMask && !useGlobalOpacity) - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader_CM; - if (!hasCompose && hasMask && useGlobalOpacity) - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader_MO; - if (!hasCompose && hasMask && !useGlobalOpacity) - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader_M; - if (hasCompose && !hasMask && useGlobalOpacity) - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader_CO; - if (hasCompose && !hasMask && !useGlobalOpacity) - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader_C; - if (!hasCompose && !hasMask && useGlobalOpacity) - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader_O; - if (!hasCompose && !hasMask && !useGlobalOpacity) - requiredProgram.mainFragShader = QGLEngineSharedShaders::MainFragmentShader; - } - - if (hasMask) { - if (maskType == PixelMask) { - requiredProgram.maskFragShader = QGLEngineSharedShaders::MaskFragmentShader; - texCoords = true; - } else if (maskType == SubPixelMaskPass1) { - requiredProgram.maskFragShader = QGLEngineSharedShaders::RgbMaskFragmentShaderPass1; - texCoords = true; - } else if (maskType == SubPixelMaskPass2) { - requiredProgram.maskFragShader = QGLEngineSharedShaders::RgbMaskFragmentShaderPass2; - texCoords = true; - } else if (maskType == SubPixelWithGammaMask) { - requiredProgram.maskFragShader = QGLEngineSharedShaders::RgbMaskWithGammaFragmentShader; - texCoords = true; - } else { - qCritical("QGLEngineShaderManager::useCorrectShaderProg() - Unknown mask type"); - } - } else { - requiredProgram.maskFragShader = QGLEngineSharedShaders::NoMaskFragmentShader; - } - - if (hasCompose) { - switch (compositionMode) { - case QPainter::CompositionMode_Multiply: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::MultiplyCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_Screen: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::ScreenCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_Overlay: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::OverlayCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_Darken: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::DarkenCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_Lighten: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::LightenCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_ColorDodge: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::ColorDodgeCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_ColorBurn: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::ColorBurnCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_HardLight: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::HardLightCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_SoftLight: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::SoftLightCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_Difference: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::DifferenceCompositionModeFragmentShader; - break; - case QPainter::CompositionMode_Exclusion: - requiredProgram.compositionFragShader = QGLEngineSharedShaders::ExclusionCompositionModeFragmentShader; - break; - default: - qWarning("QGLEngineShaderManager::useCorrectShaderProg() - Unsupported composition mode"); - } - } else { - requiredProgram.compositionFragShader = QGLEngineSharedShaders::NoCompositionModeFragmentShader; - } - - // Choose vertex shader main function - if (opacityMode == AttributeOpacity) { - Q_ASSERT(texCoords); - requiredProgram.mainVertexShader = QGLEngineSharedShaders::MainWithTexCoordsAndOpacityVertexShader; - } else if (texCoords) { - requiredProgram.mainVertexShader = QGLEngineSharedShaders::MainWithTexCoordsVertexShader; - } else { - requiredProgram.mainVertexShader = QGLEngineSharedShaders::MainVertexShader; - } - requiredProgram.useTextureCoords = texCoords; - requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity); - if (complexGeometry && srcPixelType == Qt::SolidPattern) { - requiredProgram.positionVertexShader = QGLEngineSharedShaders::ComplexGeometryPositionOnlyVertexShader; - requiredProgram.usePmvMatrixAttribute = false; - } else { - requiredProgram.usePmvMatrixAttribute = true; - - // Force complexGeometry off, since we currently don't support that mode for - // non-solid brushes - complexGeometry = false; - } - - // At this point, requiredProgram is fully populated so try to find the program in the cache - currentShaderProg = sharedShaders->findProgramInCache(requiredProgram); - - if (currentShaderProg && useCustomSrc) { - customSrcStage->setUniforms(currentShaderProg->program); - } - - // Make sure all the vertex attribute arrays the program uses are enabled (and the ones it - // doesn't use are disabled) - QGLContextPrivate* ctx_d = ctx->d_func(); - ctx_d->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, true); - ctx_d->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, currentShaderProg && currentShaderProg->useTextureCoords); - ctx_d->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, currentShaderProg && currentShaderProg->useOpacityAttribute); - - shaderProgNeedsChanging = false; - return true; -} - -QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h deleted file mode 100644 index d23b3ad550..0000000000 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ /dev/null @@ -1,508 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -/* - VERTEX SHADERS - ============== - - Vertex shaders are specified as multiple (partial) shaders. On desktop, - this works fine. On ES, QGLShader & QGLShaderProgram will make partial - shaders work by concatenating the source in each QGLShader and compiling - it as a single shader. This is abstracted nicely by QGLShaderProgram and - the GL2 engine doesn't need to worry about it. - - Generally, there's two vertex shader objects. The position shaders are - the ones which set gl_Position. There's also two "main" vertex shaders, - one which just calls the position shader and another which also passes - through some texture coordinates from a vertex attribute array to a - varying. These texture coordinates are used for mask position in text - rendering and for the source coordinates in drawImage/drawPixmap. There's - also a "Simple" vertex shader for rendering a solid colour (used to render - into the stencil buffer where the actual colour value is discarded). - - The position shaders for brushes look scary. This is because many of the - calculations which logically belong in the fragment shader have been moved - into the vertex shader to improve performance. This is why the position - calculation is in a separate shader. Not only does it calculate the - position, but it also calculates some data to be passed to the fragment - shader as a varying. It is optimal to move as much of the calculation as - possible into the vertex shader as this is executed less often. - - The varyings passed to the fragment shaders are interpolated (which is - cheap). Unfortunately, GL will apply perspective correction to the - interpolation calusing errors. To get around this, the vertex shader must - apply perspective correction itself and set the w-value of gl_Position to - zero. That way, GL will be tricked into thinking it doesn't need to apply a - perspective correction and use linear interpolation instead (which is what - we want). Of course, if the brush transform is affeine, no perspective - correction is needed and a simpler vertex shader can be used instead. - - So there are the following "main" vertex shaders: - qglslMainVertexShader - qglslMainWithTexCoordsVertexShader - - And the following position vertex shaders: - qglslPositionOnlyVertexShader - qglslPositionWithTextureBrushVertexShader - qglslPositionWithPatternBrushVertexShader - qglslPositionWithLinearGradientBrushVertexShader - qglslPositionWithRadialGradientBrushVertexShader - qglslPositionWithConicalGradientBrushVertexShader - qglslAffinePositionWithTextureBrushVertexShader - qglslAffinePositionWithPatternBrushVertexShader - qglslAffinePositionWithLinearGradientBrushVertexShader - qglslAffinePositionWithRadialGradientBrushVertexShader - qglslAffinePositionWithConicalGradientBrushVertexShader - - Leading to 23 possible vertex shaders - - - FRAGMENT SHADERS - ================ - - Fragment shaders are also specified as multiple (partial) shaders. The - different fragment shaders represent the different stages in Qt's fragment - pipeline. There are 1-3 stages in this pipeline: First stage is to get the - fragment's colour value. The next stage is to get the fragment's mask value - (coverage value for anti-aliasing) and the final stage is to blend the - incoming fragment with the background (for composition modes not supported - by GL). - - Of these, the first stage will always be present. If Qt doesn't need to - apply anti-aliasing (because it's off or handled by multisampling) then - the coverage value doesn't need to be applied. (Note: There are two types - of mask, one for regular anti-aliasing and one for sub-pixel anti- - aliasing.) If the composition mode is one which GL supports natively then - the blending stage doesn't need to be applied. - - As eash stage can have multiple implementations, they are abstracted as - GLSL function calls with the following signatures: - - Brushes & image drawing are implementations of "qcolorp vec4 srcPixel()": - qglslImageSrcFragShader - qglslImageSrcWithPatternFragShader - qglslNonPremultipliedImageSrcFragShader - qglslSolidBrushSrcFragShader - qglslTextureBrushSrcFragShader - qglslTextureBrushWithPatternFragShader - qglslPatternBrushSrcFragShader - qglslLinearGradientBrushSrcFragShader - qglslRadialGradientBrushSrcFragShader - qglslConicalGradientBrushSrcFragShader - NOTE: It is assumed the colour returned by srcPixel() is pre-multiplied - - Masks are implementations of "qcolorp vec4 applyMask(qcolorp vec4 src)": - qglslMaskFragmentShader - qglslRgbMaskFragmentShaderPass1 - qglslRgbMaskFragmentShaderPass2 - qglslRgbMaskWithGammaFragmentShader - - Composition modes are "qcolorp vec4 compose(qcolorp vec4 src)": - qglslColorBurnCompositionModeFragmentShader - qglslColorDodgeCompositionModeFragmentShader - qglslDarkenCompositionModeFragmentShader - qglslDifferenceCompositionModeFragmentShader - qglslExclusionCompositionModeFragmentShader - qglslHardLightCompositionModeFragmentShader - qglslLightenCompositionModeFragmentShader - qglslMultiplyCompositionModeFragmentShader - qglslOverlayCompositionModeFragmentShader - qglslScreenCompositionModeFragmentShader - qglslSoftLightCompositionModeFragmentShader - - - Note: In the future, some GLSL compilers will support an extension allowing - a new 'color' precision specifier. To support this, qcolorp is used for - all color components so it can be defined to colorp or lowp depending upon - the implementation. - - So there are differnt frament shader main functions, depending on the - number & type of pipelines the fragment needs to go through. - - The choice of which main() fragment shader string to use depends on: - - Use of global opacity - - Brush style (some brushes apply opacity themselves) - - Use & type of mask (TODO: Need to support high quality anti-aliasing & text) - - Use of non-GL Composition mode - - Leading to the following fragment shader main functions: - gl_FragColor = compose(applyMask(srcPixel()*globalOpacity)); - gl_FragColor = compose(applyMask(srcPixel())); - gl_FragColor = applyMask(srcPixel()*globalOpacity); - gl_FragColor = applyMask(srcPixel()); - gl_FragColor = compose(srcPixel()*globalOpacity); - gl_FragColor = compose(srcPixel()); - gl_FragColor = srcPixel()*globalOpacity; - gl_FragColor = srcPixel(); - - Called: - qglslMainFragmentShader_CMO - qglslMainFragmentShader_CM - qglslMainFragmentShader_MO - qglslMainFragmentShader_M - qglslMainFragmentShader_CO - qglslMainFragmentShader_C - qglslMainFragmentShader_O - qglslMainFragmentShader - - Where: - M = Mask - C = Composition - O = Global Opacity - - - CUSTOM SHADER CODE - ================== - - The use of custom shader code is supported by the engine for drawImage and - drawPixmap calls. This is implemented via hooks in the fragment pipeline. - - The custom shader is passed to the engine as a partial fragment shader - (QGLCustomShaderStage). The shader will implement a pre-defined method name - which Qt's fragment pipeline will call: - - lowp vec4 customShader(lowp sampler2d imageTexture, highp vec2 textureCoords) - - The provided src and srcCoords parameters can be used to sample from the - source image. - - Transformations, clipping, opacity, and composition modes set using QPainter - will be respected when using the custom shader hook. -*/ - -#ifndef QGLENGINE_SHADER_MANAGER_H -#define QGLENGINE_SHADER_MANAGER_H - -#include <QGLShader> -#include <QGLShaderProgram> -#include <QPainter> -#include <private/qgl_p.h> -#include <private/qglcustomshaderstage_p.h> - -QT_BEGIN_NAMESPACE - - - -/* -struct QGLEngineCachedShaderProg -{ - QGLEngineCachedShaderProg(QGLEngineShaderManager::ShaderName vertexMain, - QGLEngineShaderManager::ShaderName vertexPosition, - QGLEngineShaderManager::ShaderName fragMain, - QGLEngineShaderManager::ShaderName pixelSrc, - QGLEngineShaderManager::ShaderName mask, - QGLEngineShaderManager::ShaderName composition); - - int cacheKey; - QGLShaderProgram* program; -} -*/ - -static const GLuint QT_VERTEX_COORDS_ATTR = 0; -static const GLuint QT_TEXTURE_COORDS_ATTR = 1; -static const GLuint QT_OPACITY_ATTR = 2; -static const GLuint QT_PMV_MATRIX_1_ATTR = 3; -static const GLuint QT_PMV_MATRIX_2_ATTR = 4; -static const GLuint QT_PMV_MATRIX_3_ATTR = 5; - -class QGLEngineShaderProg; - -class Q_OPENGL_EXPORT QGLEngineSharedShaders -{ - Q_GADGET -public: - - enum SnippetName { - MainVertexShader, - MainWithTexCoordsVertexShader, - MainWithTexCoordsAndOpacityVertexShader, - - // UntransformedPositionVertexShader must be first in the list: - UntransformedPositionVertexShader, - PositionOnlyVertexShader, - ComplexGeometryPositionOnlyVertexShader, - PositionWithPatternBrushVertexShader, - PositionWithLinearGradientBrushVertexShader, - PositionWithConicalGradientBrushVertexShader, - PositionWithRadialGradientBrushVertexShader, - PositionWithTextureBrushVertexShader, - AffinePositionWithPatternBrushVertexShader, - AffinePositionWithLinearGradientBrushVertexShader, - AffinePositionWithConicalGradientBrushVertexShader, - AffinePositionWithRadialGradientBrushVertexShader, - AffinePositionWithTextureBrushVertexShader, - - // MainFragmentShader_CMO must be first in the list: - MainFragmentShader_CMO, - MainFragmentShader_CM, - MainFragmentShader_MO, - MainFragmentShader_M, - MainFragmentShader_CO, - MainFragmentShader_C, - MainFragmentShader_O, - MainFragmentShader, - MainFragmentShader_ImageArrays, - - // ImageSrcFragmentShader must be first in the list:: - ImageSrcFragmentShader, - ImageSrcWithPatternFragmentShader, - NonPremultipliedImageSrcFragmentShader, - CustomImageSrcFragmentShader, - SolidBrushSrcFragmentShader, - TextureBrushSrcFragmentShader, - TextureBrushSrcWithPatternFragmentShader, - PatternBrushSrcFragmentShader, - LinearGradientBrushSrcFragmentShader, - RadialGradientBrushSrcFragmentShader, - ConicalGradientBrushSrcFragmentShader, - ShockingPinkSrcFragmentShader, - - // NoMaskFragmentShader must be first in the list: - NoMaskFragmentShader, - MaskFragmentShader, - RgbMaskFragmentShaderPass1, - RgbMaskFragmentShaderPass2, - RgbMaskWithGammaFragmentShader, - - // NoCompositionModeFragmentShader must be first in the list: - NoCompositionModeFragmentShader, - MultiplyCompositionModeFragmentShader, - ScreenCompositionModeFragmentShader, - OverlayCompositionModeFragmentShader, - DarkenCompositionModeFragmentShader, - LightenCompositionModeFragmentShader, - ColorDodgeCompositionModeFragmentShader, - ColorBurnCompositionModeFragmentShader, - HardLightCompositionModeFragmentShader, - SoftLightCompositionModeFragmentShader, - DifferenceCompositionModeFragmentShader, - ExclusionCompositionModeFragmentShader, - - TotalSnippetCount, InvalidSnippetName - }; -#if defined (QT_DEBUG) - Q_ENUMS(SnippetName) - static QByteArray snippetNameStr(SnippetName snippetName); -#endif - -/* - // These allow the ShaderName enum to be used as a cache key - const int mainVertexOffset = 0; - const int positionVertexOffset = (1<<2) - PositionOnlyVertexShader; - const int mainFragOffset = (1<<6) - MainFragmentShader_CMO; - const int srcPixelOffset = (1<<10) - ImageSrcFragmentShader; - const int maskOffset = (1<<14) - NoMaskShader; - const int compositionOffset = (1 << 16) - MultiplyCompositionModeFragmentShader; -*/ - - QGLEngineSharedShaders(const QGLContext *context); - ~QGLEngineSharedShaders(); - - QGLShaderProgram *simpleProgram() { return simpleShaderProg; } - QGLShaderProgram *blitProgram() { return blitShaderProg; } - // Compile the program if it's not already in the cache, return the item in the cache. - QGLEngineShaderProg *findProgramInCache(const QGLEngineShaderProg &prog); - // Compile the custom shader if it's not already in the cache, return the item in the cache. - - static QGLEngineSharedShaders *shadersForContext(const QGLContext *context); - - // Ideally, this would be static and cleanup all programs in all contexts which - // contain the custom code. Currently it is just a hint and we rely on deleted - // custom shaders being cleaned up by being kicked out of the cache when it's - // full. - void cleanupCustomStage(QGLCustomShaderStage* stage); - -private: - QGLShaderProgram *blitShaderProg; - QGLShaderProgram *simpleShaderProg; - QList<QGLEngineShaderProg*> cachedPrograms; - QList<QGLShader *> shaders; - - static const char* qShaderSnippets[TotalSnippetCount]; -}; - - -class QGLEngineShaderProg -{ -public: - QGLEngineShaderProg() : program(nullptr) {} - - ~QGLEngineShaderProg() { - if (program) - delete program; - } - - QGLEngineSharedShaders::SnippetName mainVertexShader; - QGLEngineSharedShaders::SnippetName positionVertexShader; - QGLEngineSharedShaders::SnippetName mainFragShader; - QGLEngineSharedShaders::SnippetName srcPixelFragShader; - QGLEngineSharedShaders::SnippetName maskFragShader; - QGLEngineSharedShaders::SnippetName compositionFragShader; - - QByteArray customStageSource; //TODO: Decent cache key for custom stages - QGLShaderProgram* program; - - QVector<uint> uniformLocations; - - bool useTextureCoords; - bool useOpacityAttribute; - bool usePmvMatrixAttribute; - - bool operator==(const QGLEngineShaderProg& other) const { - // We don't care about the program - return ( mainVertexShader == other.mainVertexShader && - positionVertexShader == other.positionVertexShader && - mainFragShader == other.mainFragShader && - srcPixelFragShader == other.srcPixelFragShader && - maskFragShader == other.maskFragShader && - compositionFragShader == other.compositionFragShader && - customStageSource == other.customStageSource - ); - } -}; - -class Q_OPENGL_EXPORT QGLEngineShaderManager : public QObject -{ - Q_OBJECT -public: - QGLEngineShaderManager(QGLContext* context); - ~QGLEngineShaderManager(); - - enum MaskType {NoMask, PixelMask, SubPixelMaskPass1, SubPixelMaskPass2, SubPixelWithGammaMask}; - enum PixelSrcType { - ImageSrc = Qt::TexturePattern+1, - NonPremultipliedImageSrc = Qt::TexturePattern+2, - PatternSrc = Qt::TexturePattern+3, - TextureSrcWithPattern = Qt::TexturePattern+4 - }; - - enum Uniform { - ImageTexture, - PatternColor, - GlobalOpacity, - Depth, - MaskTexture, - FragmentColor, - LinearData, - Angle, - HalfViewportSize, - Fmp, - Fmp2MRadius2, - Inverse2Fmp2MRadius2, - SqrFr, - BRadius, - InvertedTextureSize, - BrushTransform, - BrushTexture, - Matrix, - TranslateZ, - NumUniforms - }; - - enum OpacityMode { - NoOpacity, - UniformOpacity, - AttributeOpacity - }; - - // There are optimizations we can do, depending on the brush transform: - // 1) May not have to apply perspective-correction - // 2) Can use lower precision for matrix - void optimiseForBrushTransform(QTransform::TransformationType transformType); - void setSrcPixelType(Qt::BrushStyle); - void setSrcPixelType(PixelSrcType); // For non-brush sources, like pixmaps & images - void setOpacityMode(OpacityMode); - void setMaskType(MaskType); - void setCompositionMode(QPainter::CompositionMode); - void setCustomStage(QGLCustomShaderStage* stage); - void removeCustomStage(); - - GLuint getUniformLocation(Uniform id); - - void setDirty(); // someone has manually changed the current shader program - bool useCorrectShaderProg(); // returns true if the shader program needed to be changed - - void useSimpleProgram(); - void useBlitProgram(); - void setHasComplexGeometry(bool hasComplexGeometry) - { - complexGeometry = hasComplexGeometry; - shaderProgNeedsChanging = true; - } - bool hasComplexGeometry() const - { - return complexGeometry; - } - - QGLShaderProgram* currentProgram(); // Returns pointer to the shader the manager has chosen - QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers - QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer - - QGLEngineSharedShaders* sharedShaders; - -private: - QGLContext* ctx; - bool shaderProgNeedsChanging; - bool complexGeometry; - - // Current state variables which influence the choice of shader: - QTransform brushTransform; - int srcPixelType; - OpacityMode opacityMode; - MaskType maskType; - QPainter::CompositionMode compositionMode; - QGLCustomShaderStage* customSrcStage; - - QGLEngineShaderProg* currentShaderProg; -}; - -QT_END_NAMESPACE - -#endif //QGLENGINE_SHADER_MANAGER_H diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h deleted file mode 100644 index a667af9b96..0000000000 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ /dev/null @@ -1,523 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - - -#ifndef QGL_ENGINE_SHADER_SOURCE_H -#define QGL_ENGINE_SHADER_SOURCE_H - -#include "qglengineshadermanager_p.h" - -QT_BEGIN_NAMESPACE - - - -static const char* const qglslMainVertexShader = "\n\ - void setPosition(); \n\ - void main(void) \n\ - { \n\ - setPosition(); \n\ - }\n"; - -static const char* const qglslMainWithTexCoordsVertexShader = "\n\ - attribute highp vec2 textureCoordArray; \n\ - varying highp vec2 textureCoords; \n\ - void setPosition(); \n\ - void main(void) \n\ - { \n\ - setPosition(); \n\ - textureCoords = textureCoordArray; \n\ - }\n"; - -static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\n\ - attribute highp vec2 textureCoordArray; \n\ - attribute lowp float opacityArray; \n\ - varying highp vec2 textureCoords; \n\ - varying lowp float opacity; \n\ - void setPosition(); \n\ - void main(void) \n\ - { \n\ - setPosition(); \n\ - textureCoords = textureCoordArray; \n\ - opacity = opacityArray; \n\ - }\n"; - -// NOTE: We let GL do the perspective correction so texture lookups in the fragment -// shader are also perspective corrected. -static const char* const qglslPositionOnlyVertexShader = "\n\ - attribute highp vec2 vertexCoordsArray; \n\ - attribute highp vec3 pmvMatrix1; \n\ - attribute highp vec3 pmvMatrix2; \n\ - attribute highp vec3 pmvMatrix3; \n\ - void setPosition(void) \n\ - { \n\ - highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ - gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\ - }\n"; - -static const char* const qglslComplexGeometryPositionOnlyVertexShader = "\n\ - uniform highp mat3 matrix; \n\ - uniform highp float translateZ; \n\ - attribute highp vec2 vertexCoordsArray; \n\ - void setPosition(void) \n\ - { \n\ - vec3 v = matrix * vec3(vertexCoordsArray, 1.0); \n\ - vec4 vz = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, translateZ, 1) * vec4(v, 1.0); \n\ - gl_Position = vec4(vz.xyz, 1.0);\n\ - } \n"; - -static const char* const qglslUntransformedPositionVertexShader = "\n\ - attribute highp vec4 vertexCoordsArray; \n\ - void setPosition(void) \n\ - { \n\ - gl_Position = vertexCoordsArray; \n\ - }\n"; - -// Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125 -static const char* const qglslPositionWithPatternBrushVertexShader = "\n\ - attribute highp vec2 vertexCoordsArray; \n\ - attribute highp vec3 pmvMatrix1; \n\ - attribute highp vec3 pmvMatrix2; \n\ - attribute highp vec3 pmvMatrix3; \n\ - uniform mediump vec2 halfViewportSize; \n\ - uniform highp vec2 invertedTextureSize; \n\ - uniform highp mat3 brushTransform; \n\ - varying highp vec2 patternTexCoords; \n\ - void setPosition(void) \n\ - { \n\ - highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ - gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ - patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\ - }\n"; - -static const char* const qglslAffinePositionWithPatternBrushVertexShader - = qglslPositionWithPatternBrushVertexShader; - -static const char* const qglslPatternBrushSrcFragmentShader = "\n\ - uniform sampler2D brushTexture; \n\ - uniform lowp vec4 patternColor; \n\ - varying highp vec2 patternTexCoords;\n\ - lowp vec4 srcPixel() \n\ - { \n\ - return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \n\ - }\n"; - - -// Linear Gradient Brush -static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\n\ - attribute highp vec2 vertexCoordsArray; \n\ - attribute highp vec3 pmvMatrix1; \n\ - attribute highp vec3 pmvMatrix2; \n\ - attribute highp vec3 pmvMatrix3; \n\ - uniform mediump vec2 halfViewportSize; \n\ - uniform highp vec3 linearData; \n\ - uniform highp mat3 brushTransform; \n\ - varying mediump float index; \n\ - void setPosition() \n\ - { \n\ - highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ - gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ - index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\ - }\n"; - -static const char* const qglslAffinePositionWithLinearGradientBrushVertexShader - = qglslPositionWithLinearGradientBrushVertexShader; - -static const char* const qglslLinearGradientBrushSrcFragmentShader = "\n\ - uniform sampler2D brushTexture; \n\ - varying mediump float index; \n\ - lowp vec4 srcPixel() \n\ - { \n\ - mediump vec2 val = vec2(index, 0.5); \n\ - return texture2D(brushTexture, val); \n\ - }\n"; - - -// Conical Gradient Brush -static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\n\ - attribute highp vec2 vertexCoordsArray; \n\ - attribute highp vec3 pmvMatrix1; \n\ - attribute highp vec3 pmvMatrix2; \n\ - attribute highp vec3 pmvMatrix3; \n\ - uniform mediump vec2 halfViewportSize; \n\ - uniform highp mat3 brushTransform; \n\ - varying highp vec2 A; \n\ - void setPosition(void) \n\ - { \n\ - highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ - gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ - A = hTexCoords.xy * invertedHTexCoordsZ; \n\ - }\n"; - -static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader - = qglslPositionWithConicalGradientBrushVertexShader; - -static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\ - #define INVERSE_2PI 0.1591549430918953358 \n\ - uniform sampler2D brushTexture; \n\ - uniform mediump float angle; \n\ - varying highp vec2 A; \n\ - lowp vec4 srcPixel() \n\ - { \n\ - highp float t; \n\ - if (abs(A.y) == abs(A.x)) \n\ - t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\ - else \n\ - t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\ - return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \n\ - }\n"; - - -// Radial Gradient Brush -static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\ - attribute highp vec2 vertexCoordsArray;\n\ - attribute highp vec3 pmvMatrix1; \n\ - attribute highp vec3 pmvMatrix2; \n\ - attribute highp vec3 pmvMatrix3; \n\ - uniform mediump vec2 halfViewportSize; \n\ - uniform highp mat3 brushTransform; \n\ - uniform highp vec2 fmp; \n\ - uniform mediump vec3 bradius; \n\ - varying highp float b; \n\ - varying highp vec2 A; \n\ - void setPosition(void) \n\ - {\n\ - highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ - gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ - A = hTexCoords.xy * invertedHTexCoordsZ; \n\ - b = bradius.x + 2.0 * dot(A, fmp); \n\ - }\n"; - -static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader - = qglslPositionWithRadialGradientBrushVertexShader; - -static const char* const qglslRadialGradientBrushSrcFragmentShader = "\n\ - uniform sampler2D brushTexture; \n\ - uniform highp float fmp2_m_radius2; \n\ - uniform highp float inverse_2_fmp2_m_radius2; \n\ - uniform highp float sqrfr; \n\ - varying highp float b; \n\ - varying highp vec2 A; \n\ - uniform mediump vec3 bradius; \n\ - lowp vec4 srcPixel() \n\ - { \n\ - highp float c = sqrfr-dot(A, A); \n\ - highp float det = b*b - 4.0*fmp2_m_radius2*c; \n\ - lowp vec4 result = vec4(0.0); \n\ - if (det >= 0.0) { \n\ - highp float detSqrt = sqrt(det); \n\ - highp float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2); \n\ - if (bradius.y + w * bradius.z >= 0.0) \n\ - result = texture2D(brushTexture, vec2(w, 0.5)); \n\ - } \n\ - return result; \n\ - }\n"; - - -// Texture Brush -static const char* const qglslPositionWithTextureBrushVertexShader = "\n\ - attribute highp vec2 vertexCoordsArray; \n\ - attribute highp vec3 pmvMatrix1; \n\ - attribute highp vec3 pmvMatrix2; \n\ - attribute highp vec3 pmvMatrix3; \n\ - uniform mediump vec2 halfViewportSize; \n\ - uniform highp vec2 invertedTextureSize; \n\ - uniform highp mat3 brushTransform; \n\ - varying highp vec2 brushTextureCoords; \n\ - void setPosition(void) \n\ - { \n\ - highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ - gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ - brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\ - }\n"; - -static const char* const qglslAffinePositionWithTextureBrushVertexShader - = qglslPositionWithTextureBrushVertexShader; - -// 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_ES = "\n\ - varying highp vec2 brushTextureCoords; \n\ - uniform sampler2D brushTexture; \n\ - lowp vec4 srcPixel() { \n\ - return texture2D(brushTexture, fract(brushTextureCoords)); \n\ - }\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"; - -static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\ - varying highp vec2 brushTextureCoords; \n\ - uniform lowp vec4 patternColor; \n\ - uniform sampler2D brushTexture; \n\ - lowp vec4 srcPixel() \n\ - { \n\ - return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \n\ - }\n"; - -// Solid Fill Brush -static const char* const qglslSolidBrushSrcFragmentShader = "\n\ - uniform lowp vec4 fragmentColor; \n\ - lowp vec4 srcPixel() \n\ - { \n\ - return fragmentColor; \n\ - }\n"; - -static const char* const qglslImageSrcFragmentShader = "\n\ - varying highp vec2 textureCoords; \n\ - uniform sampler2D imageTexture; \n\ - lowp vec4 srcPixel() \n\ - { \n" - "return texture2D(imageTexture, textureCoords); \n" - "}\n"; - -static const char* const qglslCustomSrcFragmentShader = "\n\ - varying highp vec2 textureCoords; \n\ - uniform sampler2D imageTexture; \n\ - lowp vec4 srcPixel() \n\ - { \n\ - return customShader(imageTexture, textureCoords); \n\ - }\n"; - -static const char* const qglslImageSrcWithPatternFragmentShader = "\n\ - varying highp vec2 textureCoords; \n\ - uniform lowp vec4 patternColor; \n\ - uniform sampler2D imageTexture; \n\ - lowp vec4 srcPixel() \n\ - { \n\ - return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \n\ - }\n"; - -static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\n\ - varying highp vec2 textureCoords; \n\ - uniform sampler2D imageTexture; \n\ - lowp vec4 srcPixel() \n\ - { \n\ - lowp vec4 sample = texture2D(imageTexture, textureCoords); \n\ - sample.rgb = sample.rgb * sample.a; \n\ - return sample; \n\ - }\n"; - -static const char* const qglslShockingPinkSrcFragmentShader = "\n\ - lowp vec4 srcPixel() \n\ - { \n\ - return vec4(0.98, 0.06, 0.75, 1.0); \n\ - }\n"; - -static const char* const qglslMainFragmentShader_ImageArrays = "\n\ - varying lowp float opacity; \n\ - lowp vec4 srcPixel(); \n\ - void main() \n\ - { \n\ - gl_FragColor = srcPixel() * opacity; \n\ - }\n"; - -static const char* const qglslMainFragmentShader_CMO = "\n\ - uniform lowp float globalOpacity; \n\ - lowp vec4 srcPixel(); \n\ - lowp vec4 applyMask(lowp vec4); \n\ - lowp vec4 compose(lowp vec4); \n\ - void main() \n\ - { \n\ - gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\ - }\n"; - -static const char* const qglslMainFragmentShader_CM = "\n\ - lowp vec4 srcPixel(); \n\ - lowp vec4 applyMask(lowp vec4); \n\ - lowp vec4 compose(lowp vec4); \n\ - void main() \n\ - { \n\ - gl_FragColor = applyMask(compose(srcPixel())); \n\ - }\n"; - -static const char* const qglslMainFragmentShader_MO = "\n\ - uniform lowp float globalOpacity; \n\ - lowp vec4 srcPixel(); \n\ - lowp vec4 applyMask(lowp vec4); \n\ - void main() \n\ - { \n\ - gl_FragColor = applyMask(srcPixel()*globalOpacity); \n\ - }\n"; - -static const char* const qglslMainFragmentShader_M = "\n\ - lowp vec4 srcPixel(); \n\ - lowp vec4 applyMask(lowp vec4); \n\ - void main() \n\ - { \n\ - gl_FragColor = applyMask(srcPixel()); \n\ - }\n"; - -static const char* const qglslMainFragmentShader_CO = "\n\ - uniform lowp float globalOpacity; \n\ - lowp vec4 srcPixel(); \n\ - lowp vec4 compose(lowp vec4); \n\ - void main() \n\ - { \n\ - gl_FragColor = compose(srcPixel()*globalOpacity); \n\ - }\n"; - -static const char* const qglslMainFragmentShader_C = "\n\ - lowp vec4 srcPixel(); \n\ - lowp vec4 compose(lowp vec4); \n\ - void main() \n\ - { \n\ - gl_FragColor = compose(srcPixel()); \n\ - }\n"; - -static const char* const qglslMainFragmentShader_O = "\n\ - uniform lowp float globalOpacity; \n\ - lowp vec4 srcPixel(); \n\ - void main() \n\ - { \n\ - gl_FragColor = srcPixel()*globalOpacity; \n\ - }\n"; - -static const char* const qglslMainFragmentShader = "\n\ - lowp vec4 srcPixel(); \n\ - void main() \n\ - { \n\ - gl_FragColor = srcPixel(); \n\ - }\n"; - -static const char* const qglslMaskFragmentShader = "\n\ - varying highp vec2 textureCoords;\n\ - uniform sampler2D maskTexture;\n\ - lowp vec4 applyMask(lowp vec4 src) \n\ - {\n\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ - return src * mask.a; \n\ - }\n"; - -// For source over with subpixel antialiasing, the final color is calculated per component as follows -// (.a is alpha component, .c is red, green or blue component): -// alpha = src.a * mask.c * opacity -// dest.c = dest.c * (1 - alpha) + src.c * alpha -// -// In the first pass, calculate: dest.c = dest.c * (1 - alpha) with blend funcs: zero, 1 - source color -// In the second pass, calculate: dest.c = dest.c + src.c * alpha with blend funcs: one, one -// -// If source is a solid color (src is constant), only the first pass is needed, with blend funcs: constant, 1 - source color - -// For source composition with subpixel antialiasing, the final color is calculated per component as follows: -// alpha = src.a * mask.c * opacity -// dest.c = dest.c * (1 - mask.c) + src.c * alpha -// - -static const char* const qglslRgbMaskFragmentShaderPass1 = "\n\ - varying highp vec2 textureCoords;\n\ - uniform sampler2D maskTexture;\n\ - lowp vec4 applyMask(lowp vec4 src) \n\ - { \n\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ - return src.a * mask; \n\ - }\n"; - -static const char* const qglslRgbMaskFragmentShaderPass2 = "\n\ - varying highp vec2 textureCoords;\n\ - uniform sampler2D maskTexture;\n\ - lowp vec4 applyMask(lowp vec4 src) \n\ - { \n\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ - return src * mask; \n\ - }\n"; - -/* - Left to implement: - RgbMaskFragmentShader, - RgbMaskWithGammaFragmentShader, - - MultiplyCompositionModeFragmentShader, - ScreenCompositionModeFragmentShader, - OverlayCompositionModeFragmentShader, - DarkenCompositionModeFragmentShader, - LightenCompositionModeFragmentShader, - ColorDodgeCompositionModeFragmentShader, - ColorBurnCompositionModeFragmentShader, - HardLightCompositionModeFragmentShader, - SoftLightCompositionModeFragmentShader, - DifferenceCompositionModeFragmentShader, - ExclusionCompositionModeFragmentShader, -*/ - -QT_END_NAMESPACE - -#endif // GLGC_SHADER_SOURCE_H diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp deleted file mode 100644 index fc5e236ca6..0000000000 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglgradientcache_p.h" -#include <private/qdrawhelper_p.h> -#include <private/qgl_p.h> -#include <QtCore/qmutex.h> -#include <QtCore/qrandom.h> - -QT_BEGIN_NAMESPACE - -class QGL2GradientCacheWrapper -{ -public: - QGL2GradientCache *cacheForContext(const QGLContext *context) { - QMutexLocker lock(&m_mutex); - return m_resource.value<QGL2GradientCache>(context->contextHandle()); - } - -private: - QOpenGLMultiGroupSharedResource m_resource; - QMutex m_mutex; -}; - -Q_GLOBAL_STATIC(QGL2GradientCacheWrapper, qt_gradient_caches) - -QGL2GradientCache::QGL2GradientCache(QOpenGLContext *ctx) - : QOpenGLSharedResource(ctx->shareGroup()) -{ -} - -QGL2GradientCache::~QGL2GradientCache() -{ - cache.clear(); -} - -QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context) -{ - return qt_gradient_caches()->cacheForContext(context); -} - -void QGL2GradientCache::invalidateResource() -{ - QMutexLocker lock(&m_mutex); - cache.clear(); -} - -void QGL2GradientCache::freeResource(QOpenGLContext *) -{ - cleanCache(); -} - -void QGL2GradientCache::cleanCache() -{ - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - QMutexLocker lock(&m_mutex); - QGLGradientColorTableHash::const_iterator it = cache.constBegin(); - for (; it != cache.constEnd(); ++it) { - const CacheInfo &cache_info = it.value(); - funcs->glDeleteTextures(1, &cache_info.texId); - } - cache.clear(); -} - -GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity) -{ - QMutexLocker lock(&m_mutex); - quint64 hash_val = 0; - - const QGradientStops stops = gradient.stops(); - for (int i = 0; i < stops.size() && i <= 2; i++) - hash_val += stops[i].second.rgba(); - - QGLGradientColorTableHash::const_iterator it = cache.constFind(hash_val); - - if (it == cache.constEnd()) - return addCacheElement(hash_val, gradient, opacity); - else { - do { - const CacheInfo &cache_info = it.value(); - if (cache_info.stops == stops && cache_info.opacity == opacity - && cache_info.interpolationMode == gradient.interpolationMode()) - { - return cache_info.texId; - } - ++it; - } while (it != cache.constEnd() && it.key() == hash_val); - // an exact match for these stops and opacity was not found, create new cache - return addCacheElement(hash_val, gradient, opacity); - } -} - - -GLuint QGL2GradientCache::addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity) -{ - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - if (cache.size() == maxCacheSize()) { - int elem_to_remove = QRandomGenerator::global()->bounded(maxCacheSize()); - quint64 key = cache.keys()[elem_to_remove]; - - // need to call glDeleteTextures on each removed cache entry: - QGLGradientColorTableHash::const_iterator it = cache.constFind(key); - do { - funcs->glDeleteTextures(1, &it.value().texId); - } while (++it != cache.constEnd() && it.key() == key); - cache.remove(key); // may remove more than 1, but OK - } - - CacheInfo cache_entry(gradient.stops(), opacity, gradient.interpolationMode()); - uint buffer[1024]; - generateGradientColorTable(gradient, buffer, paletteSize(), opacity); - funcs->glGenTextures(1, &cache_entry.texId); - funcs->glBindTexture(GL_TEXTURE_2D, cache_entry.texId); - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, paletteSize(), 1, - 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); - return cache.insert(hash_val, cache_entry).value().texId; -} - - -// GL's expects pixels in RGBA (when using GL_RGBA), bin-endian (ABGR on x86). -// Qt always stores in ARGB reguardless of the byte-order the mancine uses. -static inline uint qtToGlColor(uint c) -{ - uint o; -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN - o = (c & 0xff00ff00) // alpha & green already in the right place - | ((c >> 16) & 0x000000ff) // red - | ((c << 16) & 0x00ff0000); // blue -#else //Q_BIG_ENDIAN - o = (c << 8) - | ((c >> 24) & 0x000000ff); -#endif // Q_BYTE_ORDER - return o; -} - -//TODO: Let GL generate the texture using an FBO -void QGL2GradientCache::generateGradientColorTable(const QGradient& gradient, uint *colorTable, int size, qreal opacity) const -{ - int pos = 0; - const QGradientStops s = gradient.stops(); - bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); - - uint alpha = qRound(opacity * 256); - // Qt LIES! It returns ARGB (on little-endian AND on big-endian) - uint current_color = ARGB_COMBINE_ALPHA(s[0].second.rgba(), alpha); - qreal incr = 1.0 / qreal(size); - qreal fpos = 1.5 * incr; - colorTable[pos++] = qtToGlColor(qPremultiply(current_color)); - - while (fpos <= s.first().first) { - colorTable[pos] = colorTable[pos - 1]; - pos++; - fpos += incr; - } - - if (colorInterpolation) - current_color = qPremultiply(current_color); - - const int sLast = s.size() - 1; - for (int i = 0; i < sLast; ++i) { - qreal delta = 1/(s[i+1].first - s[i].first); - uint next_color = ARGB_COMBINE_ALPHA(s[i + 1].second.rgba(), alpha); - if (colorInterpolation) - next_color = qPremultiply(next_color); - - while (fpos < s[i+1].first && pos < size) { - int dist = int(256 * ((fpos - s[i].first) * delta)); - int idist = 256 - dist; - if (colorInterpolation) - colorTable[pos] = qtToGlColor(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)); - else - colorTable[pos] = qtToGlColor(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist))); - ++pos; - fpos += incr; - } - current_color = next_color; - } - - Q_ASSERT(s.size() > 0); - - uint last_color = qtToGlColor(qPremultiply(ARGB_COMBINE_ALPHA(s[sLast].second.rgba(), alpha))); - for (;pos < size; ++pos) - colorTable[pos] = last_color; - - // Make sure the last color stop is represented at the end of the table - colorTable[size-1] = last_color; -} - -QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qglgradientcache_p.h b/src/opengl/gl2paintengineex/qglgradientcache_p.h deleted file mode 100644 index 3c9da982e9..0000000000 --- a/src/opengl/gl2paintengineex/qglgradientcache_p.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLGRADIENTCACHE_P_H -#define QGLGRADIENTCACHE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QMultiHash> -#include <QObject> -#include <QtOpenGL/QtOpenGL> -#include <private/qgl_p.h> -#include <QtCore/qmutex.h> - -QT_BEGIN_NAMESPACE - -class QGL2GradientCache : public QOpenGLSharedResource -{ - struct CacheInfo - { - inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) : - stops(s), opacity(op), interpolationMode(mode) {} - - GLuint texId; - QGradientStops stops; - qreal opacity; - QGradient::InterpolationMode interpolationMode; - }; - - typedef QMultiHash<quint64, CacheInfo> QGLGradientColorTableHash; - -public: - static QGL2GradientCache *cacheForContext(const QGLContext *context); - - QGL2GradientCache(QOpenGLContext *); - ~QGL2GradientCache(); - - GLuint getBuffer(const QGradient &gradient, qreal opacity); - inline int paletteSize() const { return 1024; } - - void invalidateResource() override; - void freeResource(QOpenGLContext *ctx) override; - -private: - inline int maxCacheSize() const { return 60; } - inline void generateGradientColorTable(const QGradient& gradient, - uint *colorTable, - int size, qreal opacity) const; - GLuint addCacheElement(quint64 hash_val, const QGradient &gradient, qreal opacity); - void cleanCache(); - - QGLGradientColorTableHash cache; - QMutex m_mutex; -}; - -QT_END_NAMESPACE - -#endif // QGLGRADIENTCACHE_P_H diff --git a/src/opengl/gl2paintengineex/qglshadercache_p.h b/src/opengl/gl2paintengineex/qglshadercache_p.h deleted file mode 100644 index 4204e3e256..0000000000 --- a/src/opengl/gl2paintengineex/qglshadercache_p.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#ifndef QGLSHADERCACHE_P_H -#define QGLSHADERCACHE_P_H - -#include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE - - -class QGLShaderProgram; -class QGLContext; - -class CachedShader -{ -public: - inline CachedShader(const QByteArray &, const QByteArray &) - {} - - inline bool isCached() - { - return false; - } - - inline bool load(QGLShaderProgram *, const QGLContext *) - { - return false; - } - - inline bool store(QGLShaderProgram *, const QGLContext *) - { - return false; - } -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp deleted file mode 100644 index 2546f6dc13..0000000000 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ /dev/null @@ -1,2515 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - When the active program changes, we need to update it's uniforms. - We could track state for each program and only update stale uniforms - - Could lead to lots of overhead if there's a lot of programs - We could update all the uniforms when the program changes - - Could end up updating lots of uniforms which don't need updating - - Updating uniforms should be cheap, so the overhead of updating up-to-date - uniforms should be minimal. It's also less complex. - - Things which _may_ cause a different program to be used: - - Change in brush/pen style - - Change in painter opacity - - Change in composition mode - - Whenever we set a mode on the shader manager - it needs to tell us if it had - to switch to a different program. - - The shader manager should only switch when we tell it to. E.g. if we set a new - brush style and then switch to transparent painter, we only want it to compile - and use the correct program when we really need it. -*/ - -// #define QT_OPENGL_CACHE_AS_VBOS - -#include "qglgradientcache_p.h" -#include "qpaintengineex_opengl2_p.h" - -#include <string.h> //for memcpy -#include <qmath.h> - -#include <private/qgl_p.h> -#include <private/qpaintengineex_p.h> -#include <QPaintEngine> -#include <private/qpainter_p.h> -#include <private/qfontengine_p.h> -#include <private/qdatabuffer_p.h> -#include <private/qstatictext_p.h> -#include <QtGui/private/qtriangulator_p.h> - -#include "qglengineshadermanager_p.h" -#include "qgl2pexvertexarray_p.h" -#include "qtextureglyphcache_gl_p.h" - -#include <QDebug> - -#ifndef QT_OPENGL_ES_2 -# include <qopenglfunctions_1_1.h> -#endif - -QT_BEGIN_NAMESPACE - - - -Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert); - -////////////////////////////////// Private Methods ////////////////////////////////////////// - -QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() -{ - delete shaderManager; - - while (pathCaches.size()) { - QVectorPath::CacheEntry *e = *(pathCaches.constBegin()); - e->cleanup(e->engine, e->data); - e->data = 0; - e->engine = 0; - } - - if (elementIndicesVBOId != 0) { - glDeleteBuffers(1, &elementIndicesVBOId); - elementIndicesVBOId = 0; - } -} - -void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) -{ -// glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit? - if (id != GLuint(-1) && id == lastTextureUsed) - return; - - lastTextureUsed = id; - - if (smoothPixmapTransform) { - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode); - glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode); -} - - -inline QColor qt_premultiplyColor(QColor c, GLfloat opacity) -{ - qreal alpha = c.alphaF() * opacity; - c.setAlphaF(alpha); - c.setRedF(c.redF() * alpha); - c.setGreenF(c.greenF() * alpha); - c.setBlueF(c.blueF() * alpha); - return c; -} - - -void QGL2PaintEngineExPrivate::setBrush(const QBrush& brush) -{ - if (qbrush_fast_equals(currentBrush, brush)) - return; - - const Qt::BrushStyle newStyle = qbrush_style(brush); - Q_ASSERT(newStyle != Qt::NoBrush); - - currentBrush = brush; - if (!currentBrushPixmap.isNull()) - currentBrushPixmap = QPixmap(); - brushUniformsDirty = true; // All brushes have at least one uniform - - if (newStyle > Qt::SolidPattern) - brushTextureDirty = true; - - if (currentBrush.style() == Qt::TexturePattern - && qHasPixmapTexture(brush) && brush.texture().isQBitmap()) - { - shaderManager->setSrcPixelType(QGLEngineShaderManager::TextureSrcWithPattern); - } else { - shaderManager->setSrcPixelType(newStyle); - } - shaderManager->optimiseForBrushTransform(currentBrush.transform().type()); -} - - -void QGL2PaintEngineExPrivate::useSimpleShader() -{ - shaderManager->useSimpleProgram(); - - if (matrixDirty) - updateMatrix(); -} - -// ####TODO Properly #ifdef this class to use #define symbols actually defined -// by OpenGL/ES includes -#ifndef GL_MIRRORED_REPEAT_IBM -#define GL_MIRRORED_REPEAT_IBM 0x8370 -#endif - -void QGL2PaintEngineExPrivate::updateBrushTexture() -{ - Q_Q(QGL2PaintEngineEx); -// qDebug("QGL2PaintEngineExPrivate::updateBrushTexture()"); - Qt::BrushStyle style = currentBrush.style(); - - if ( (style >= Qt::Dense1Pattern) && (style <= Qt::DiagCrossPattern) ) { - // Get the image data for the pattern - QImage texImage = qt_imageForBrush(style, false); - - glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption); - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); - } - else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) { - // Gradiant brush: All the gradiants use the same texture - - const QGradient* g = currentBrush.gradient(); - - // We apply global opacity in the fragment shaders, so we always pass 1.0 - // for opacity to the cache. - GLuint texId = QGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); - - glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, texId); - - if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform); - else if (g->spread() == QGradient::ReflectSpread) - updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT_IBM, q->state()->renderHints & QPainter::SmoothPixmapTransform); - else - updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform); - } - else if (style == Qt::TexturePattern) { - currentBrushPixmap = currentBrush.texture(); - - int max_texture_size = ctx->d_func()->maxTextureSize(); - if (currentBrushPixmap.width() > max_texture_size || currentBrushPixmap.height() > max_texture_size) - currentBrushPixmap = currentBrushPixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); - - GLuint wrapMode = GL_REPEAT; - if (ctx->contextHandle()->isOpenGLES()) { - // 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; - } - - glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA, - QGLContext::InternalBindOption | - QGLContext::CanFlipNativePixmapBindOption); - updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform); - textureInvertedY = tex->options & QGLContext::InvertedYBindOption ? -1 : 1; - } - brushTextureDirty = false; -} - - -void QGL2PaintEngineExPrivate::updateBrushUniforms() -{ -// qDebug("QGL2PaintEngineExPrivate::updateBrushUniforms()"); - Qt::BrushStyle style = currentBrush.style(); - - if (style == Qt::NoBrush) - return; - - QTransform brushQTransform = currentBrush.transform(); - - if (style == Qt::SolidPattern) { - QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::FragmentColor), col); - } - else { - // All other brushes have a transform and thus need the translation point: - QPointF translationPoint; - - if (style <= Qt::DiagCrossPattern) { - QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity); - - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); - - QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); - } - else if (style == Qt::LinearGradientPattern) { - const QLinearGradient *g = static_cast<const QLinearGradient *>(currentBrush.gradient()); - - QPointF realStart = g->start(); - QPointF realFinal = g->finalStop(); - translationPoint = realStart; - - QPointF l = realFinal - realStart; - - QVector3D linearData( - l.x(), - l.y(), - 1.0f / (l.x() * l.x() + l.y() * l.y()) - ); - - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::LinearData), linearData); - - QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); - } - else if (style == Qt::ConicalGradientPattern) { - const QConicalGradient *g = static_cast<const QConicalGradient *>(currentBrush.gradient()); - translationPoint = g->center(); - - GLfloat angle = -qDegreesToRadians(g->angle()); - - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Angle), angle); - - QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); - } - else if (style == Qt::RadialGradientPattern) { - const QRadialGradient *g = static_cast<const QRadialGradient *>(currentBrush.gradient()); - QPointF realCenter = g->center(); - QPointF realFocal = g->focalPoint(); - qreal realRadius = g->centerRadius() - g->focalRadius(); - translationPoint = realFocal; - - QPointF fmp = realCenter - realFocal; - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Fmp), fmp); - - GLfloat fmp2_m_radius2 = -fmp.x() * fmp.x() - fmp.y() * fmp.y() + realRadius*realRadius; - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Fmp2MRadius2), fmp2_m_radius2); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Inverse2Fmp2MRadius2), - GLfloat(1.0 / (2.0*fmp2_m_radius2))); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::SqrFr), - GLfloat(g->focalRadius() * g->focalRadius())); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BRadius), - GLfloat(2 * (g->centerRadius() - g->focalRadius()) * g->focalRadius()), - g->focalRadius(), - g->centerRadius() - g->focalRadius()); - - QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); - } - else if (style == Qt::TexturePattern) { - const QPixmap& texPixmap = currentBrush.texture(); - - if (qHasPixmapTexture(currentBrush) && currentBrush.texture().isQBitmap()) { - QColor col = qt_premultiplyColor(currentBrush.color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); - } - - QSizeF invertedTextureSize(1.0 / texPixmap.width(), 1.0 / texPixmap.height()); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::InvertedTextureSize), invertedTextureSize); - - QVector2D halfViewportSize(width*0.5, height*0.5); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); - } - else - qWarning("QGL2PaintEngineEx: Unimplemented fill style"); - - const QPointF &brushOrigin = q->state()->brushOrigin; - QTransform matrix = q->state()->matrix; - matrix.translate(brushOrigin.x(), brushOrigin.y()); - - QTransform translate(1, 0, 0, 1, -translationPoint.x(), -translationPoint.y()); - qreal m22 = -1; - qreal dy = height; - if (device->isFlipped()) { - m22 = 1; - dy = 0; - } - QTransform gl_to_qt(1, 0, 0, m22, 0, dy); - QTransform inv_matrix; - if (style == Qt::TexturePattern && textureInvertedY == -1) - inv_matrix = gl_to_qt * (QTransform(1, 0, 0, -1, 0, currentBrush.texture().height()) * brushQTransform * matrix).inverted() * translate; - else - inv_matrix = gl_to_qt * (brushQTransform * matrix).inverted() * translate; - - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BrushTransform), inv_matrix); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BrushTexture), QT_BRUSH_TEXTURE_UNIT); - } - brushUniformsDirty = false; -} - - -// This assumes the shader manager has already setup the correct shader program -void QGL2PaintEngineExPrivate::updateMatrix() -{ -// qDebug("QGL2PaintEngineExPrivate::updateMatrix()"); - - const QTransform& transform = q->state()->matrix; - - // The projection matrix converts from Qt's coordinate system to GL's coordinate system - // * GL's viewport is 2x2, Qt's is width x height - // * GL has +y -> -y going from bottom -> top, Qt is the other way round - // * GL has [0,0] in the center, Qt has it in the top-left - // - // This results in the Projection matrix below, which is multiplied by the painter's - // transformation matrix, as shown below: - // - // Projection Matrix Painter Transform - // ------------------------------------------------ ------------------------ - // | 2.0 / width | 0.0 | -1.0 | | m11 | m21 | dx | - // | 0.0 | -2.0 / height | 1.0 | * | m12 | m22 | dy | - // | 0.0 | 0.0 | 1.0 | | m13 | m23 | m33 | - // ------------------------------------------------ ------------------------ - // - // NOTE: The resultant matrix is also transposed, as GL expects column-major matracies - - const GLfloat wfactor = 2.0f / width; - GLfloat hfactor = -2.0f / height; - - GLfloat dx = transform.dx(); - GLfloat dy = transform.dy(); - - if (device->isFlipped()) { - hfactor *= -1; - dy -= height; - } - - // Non-integer translates can have strange effects for some rendering operations such as - // anti-aliased text rendering. In such cases, we snap the translate to the pixel grid. - if (snapToPixelGrid && transform.type() == QTransform::TxTranslate) { - // 0.50 needs to rounded down to 0.0 for consistency with raster engine: - dx = std::ceil(dx - 0.5f); - dy = std::ceil(dy - 0.5f); - } - pmvMatrix[0][0] = (wfactor * transform.m11()) - transform.m13(); - pmvMatrix[1][0] = (wfactor * transform.m21()) - transform.m23(); - pmvMatrix[2][0] = (wfactor * dx) - transform.m33(); - pmvMatrix[0][1] = (hfactor * transform.m12()) + transform.m13(); - pmvMatrix[1][1] = (hfactor * transform.m22()) + transform.m23(); - pmvMatrix[2][1] = (hfactor * dy) + transform.m33(); - pmvMatrix[0][2] = transform.m13(); - pmvMatrix[1][2] = transform.m23(); - pmvMatrix[2][2] = transform.m33(); - - // 1/10000 == 0.0001, so we have good enough res to cover curves - // that span the entire widget... - inverseScale = qMax(1 / qMax( qMax(qAbs(transform.m11()), qAbs(transform.m22())), - qMax(qAbs(transform.m12()), qAbs(transform.m21())) ), - qreal(0.0001)); - - matrixDirty = false; - matrixUniformDirty = true; - - // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only - // need to do this once for every matrix change and persists across all shader programs. - glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]); - glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]); - glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]); - - dasher.setInvScale(inverseScale); - stroker.setInvScale(inverseScale); -} - - -void QGL2PaintEngineExPrivate::updateCompositionMode() -{ - // NOTE: The entire paint engine works on pre-multiplied data - which is why some of these - // composition modes look odd. -// qDebug() << "QGL2PaintEngineExPrivate::updateCompositionMode() - Setting GL composition mode for " << q->state()->composition_mode; - switch(q->state()->composition_mode) { - case QPainter::CompositionMode_SourceOver: - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - break; - case QPainter::CompositionMode_DestinationOver: - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE); - break; - case QPainter::CompositionMode_Clear: - glBlendFunc(GL_ZERO, GL_ZERO); - break; - case QPainter::CompositionMode_Source: - glBlendFunc(GL_ONE, GL_ZERO); - break; - case QPainter::CompositionMode_Destination: - glBlendFunc(GL_ZERO, GL_ONE); - break; - case QPainter::CompositionMode_SourceIn: - glBlendFunc(GL_DST_ALPHA, GL_ZERO); - break; - case QPainter::CompositionMode_DestinationIn: - glBlendFunc(GL_ZERO, GL_SRC_ALPHA); - break; - case QPainter::CompositionMode_SourceOut: - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ZERO); - break; - case QPainter::CompositionMode_DestinationOut: - glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA); - break; - case QPainter::CompositionMode_SourceAtop: - glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - break; - case QPainter::CompositionMode_DestinationAtop: - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA); - break; - case QPainter::CompositionMode_Xor: - glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - break; - case QPainter::CompositionMode_Plus: - glBlendFunc(GL_ONE, GL_ONE); - break; - default: - qWarning("Unsupported composition mode"); - break; - } - - compositionModeDirty = false; -} - -static inline void setCoords(GLfloat *coords, const QGLRect &rect) -{ - coords[0] = rect.left; - coords[1] = rect.top; - coords[2] = rect.right; - coords[3] = rect.top; - coords[4] = rect.right; - coords[5] = rect.bottom; - coords[6] = rect.left; - coords[7] = rect.bottom; -} - -void QGL2PaintEngineExPrivate::drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern) -{ - // Setup for texture drawing - currentBrush = noBrush; - shaderManager->setSrcPixelType(pattern ? QGLEngineShaderManager::PatternSrc : QGLEngineShaderManager::ImageSrc); - - if (snapToPixelGrid) { - snapToPixelGrid = false; - matrixDirty = true; - } - - if (prepareForDraw(opaque)) - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); - - if (pattern) { - QColor col = qt_premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); - } - - GLfloat dx = 1.0 / textureSize.width(); - GLfloat dy = 1.0 / textureSize.height(); - - QGLRect srcTextureRect(src.left*dx, src.top*dy, src.right*dx, src.bottom*dy); - - setCoords(staticVertexCoordinateArray, dest); - setCoords(staticTextureCoordinateArray, srcTextureRect); - - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -} - -void QGL2PaintEngineEx::beginNativePainting() -{ - Q_D(QGL2PaintEngineEx); - ensureActive(); - d->transferMode(BrushDrawingMode); - - d->nativePaintingActive = true; - - d->glUseProgram(0); - - // Disable all the vertex attribute arrays: - for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) - d->glDisableVertexAttribArray(i); - -#ifndef QT_OPENGL_ES_2 - if (!d->ctx->contextHandle()->isOpenGLES()) { - 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] = - { - { 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()) } - }; - - const QSize sz = d->device->size(); - - QOpenGLFunctions_1_1 *gl1funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_1_1>(); - gl1funcs->initializeOpenGLFunctions(); - - gl1funcs->glMatrixMode(GL_PROJECTION); - gl1funcs->glLoadIdentity(); - gl1funcs->glOrtho(0, sz.width(), sz.height(), 0, -999999, 999999); - - gl1funcs->glMatrixMode(GL_MODELVIEW); - gl1funcs->glLoadMatrixf(&mv_matrix[0][0]); - } - } -#endif - - d->lastTextureUsed = GLuint(-1); - d->dirtyStencilRegion = QRect(0, 0, d->width, d->height); - d->resetGLState(); - - d->shaderManager->setDirty(); - - d->needsSync = true; -} - -void QGL2PaintEngineExPrivate::resetGLState() -{ - glDisable(GL_BLEND); - glActiveTexture(GL_TEXTURE0); - glDisable(GL_STENCIL_TEST); - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDepthMask(true); - glDepthFunc(GL_LESS); - glClearDepthf(1); - glStencilMask(0xff); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_ALWAYS, 0, 0xff); - ctx->d_func()->setVertexAttribArrayEnabled(QT_TEXTURE_COORDS_ATTR, false); - ctx->d_func()->setVertexAttribArrayEnabled(QT_VERTEX_COORDS_ATTR, false); - ctx->d_func()->setVertexAttribArrayEnabled(QT_OPACITY_ATTR, false); -#ifndef QT_OPENGL_ES_2 - if (!ctx->contextHandle()->isOpenGLES()) { - // gl_Color, corresponding to vertex attribute 3, may have been changed - float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; - glVertexAttrib4fv(3, color); - } -#endif -} - -bool QGL2PaintEngineExPrivate::resetOpenGLContextActiveEngine() -{ - QOpenGLContext *guiGlContext = ctx->contextHandle(); - QOpenGLContextPrivate *guiGlContextPrivate = - guiGlContext ? QOpenGLContextPrivate::get(guiGlContext) : 0; - - if (guiGlContextPrivate && guiGlContextPrivate->active_engine) { - ctx->d_func()->refreshCurrentFbo(); - guiGlContextPrivate->active_engine = 0; - return true; - } - - return false; -} - -void QGL2PaintEngineEx::endNativePainting() -{ - Q_D(QGL2PaintEngineEx); - d->needsSync = true; - d->nativePaintingActive = false; -} - -void QGL2PaintEngineEx::invalidateState() -{ - Q_D(QGL2PaintEngineEx); - d->needsSync = true; -} - -bool QGL2PaintEngineEx::isNativePaintingActive() const { - Q_D(const QGL2PaintEngineEx); - return d->nativePaintingActive; -} - -bool QGL2PaintEngineEx::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &t) const -{ - // The paint engine does not support projected cached glyph drawing - if (t.type() == QTransform::TxProject) - return false; - - // The font engine might not support filling the glyph cache - // with the given transform applied, in which case we need to - // fall back to the QPainterPath code-path. - if (!fontEngine->supportsTransformation(t)) { - // Except that drawing paths is slow, so for scales between - // 0.5 and 2.0 we leave the glyph cache untransformed and deal - // with the transform ourselves when painting, resulting in - // drawing 1x cached glyphs with a smooth-scale. - float det = t.determinant(); - if (det >= 0.25f && det <= 4.f) { - // Assuming the baseclass still agrees - return QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, t); - } - - return false; // Fall back to path-drawing - } - - return QPaintEngineEx::shouldDrawCachedGlyphs(fontEngine, t); -} - -void QGL2PaintEngineExPrivate::transferMode(EngineMode newMode) -{ - if (newMode == mode) - return; - - if (mode == TextDrawingMode || mode == ImageDrawingMode || mode == ImageArrayDrawingMode) { - lastTextureUsed = GLuint(-1); - } - - if (newMode == TextDrawingMode) { - shaderManager->setHasComplexGeometry(true); - } else { - shaderManager->setHasComplexGeometry(false); - } - - if (newMode == ImageDrawingMode) { - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray); - setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, staticTextureCoordinateArray); - } - - if (newMode == ImageArrayDrawingMode) { - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data()); - setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data()); - setVertexAttributePointer(QT_OPACITY_ATTR, (GLfloat*)opacityArray.data()); - } - - // This needs to change when we implement high-quality anti-aliasing... - if (newMode != TextDrawingMode) - shaderManager->setMaskType(QGLEngineShaderManager::NoMask); - - mode = newMode; -} - -struct QGL2PEVectorPathCache -{ -#ifdef QT_OPENGL_CACHE_AS_VBOS - GLuint vbo; - GLuint ibo; -#else - float *vertices; - void *indices; -#endif - int vertexCount; - int indexCount; - GLenum primitiveType; - qreal iscale; - QVertexIndexVector::Type indexType; -}; - -void QGL2PaintEngineExPrivate::cleanupVectorPath(QPaintEngineEx *engine, void *data) -{ - QGL2PEVectorPathCache *c = (QGL2PEVectorPathCache *) data; -#ifdef QT_OPENGL_CACHE_AS_VBOS - Q_ASSERT(engine->type() == QPaintEngine::OpenGL2); - static_cast<QGL2PaintEngineEx *>(engine)->d_func()->unusedVBOSToClean << c->vbo; - if (c->ibo) - d->unusedIBOSToClean << c->ibo; -#else - Q_UNUSED(engine); - free(c->vertices); - free(c->indices); -#endif - delete c; -} - -// Assumes everything is configured for the brush you want to use -void QGL2PaintEngineExPrivate::fill(const QVectorPath& path) -{ - transferMode(BrushDrawingMode); - - if (snapToPixelGrid) { - snapToPixelGrid = false; - matrixDirty = true; - } - - // Might need to call updateMatrix to re-calculate inverseScale - if (matrixDirty) - updateMatrix(); - - const QPointF* const points = reinterpret_cast<const QPointF*>(path.points()); - - // Check to see if there's any hints - if (path.shape() == QVectorPath::RectangleHint) { - QGLRect rect(points[0].x(), points[0].y(), points[2].x(), points[2].y()); - prepareForDraw(currentBrush.isOpaque()); - composite(rect); - } else if (path.isConvex()) { - - if (path.isCacheable()) { - QVectorPath::CacheEntry *data = path.lookupCacheData(q); - QGL2PEVectorPathCache *cache; - - bool updateCache = false; - - if (data) { - cache = (QGL2PEVectorPathCache *) data->data; - // Check if scale factor is exceeded for curved paths and generate curves if so... - if (path.isCurved()) { - qreal scaleFactor = cache->iscale / inverseScale; - if (scaleFactor < 0.5 || scaleFactor > 2.0) { -#ifdef QT_OPENGL_CACHE_AS_VBOS - glDeleteBuffers(1, &cache->vbo); - cache->vbo = 0; - Q_ASSERT(cache->ibo == 0); -#else - free(cache->vertices); - Q_ASSERT(cache->indices == 0); -#endif - updateCache = true; - } - } - } else { - cache = new QGL2PEVectorPathCache; - data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath); - updateCache = true; - } - - // Flatten the path at the current scale factor and fill it into the cache struct. - if (updateCache) { - vertexCoordinateArray.clear(); - vertexCoordinateArray.addPath(path, inverseScale, false); - int vertexCount = vertexCoordinateArray.vertexCount(); - int floatSizeInBytes = vertexCount * 2 * sizeof(float); - cache->vertexCount = vertexCount; - cache->indexCount = 0; - cache->primitiveType = GL_TRIANGLE_FAN; - cache->iscale = inverseScale; -#ifdef QT_OPENGL_CACHE_AS_VBOS - glGenBuffers(1, &cache->vbo); - glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); - glBufferData(GL_ARRAY_BUFFER, floatSizeInBytes, vertexCoordinateArray.data(), GL_STATIC_DRAW); - cache->ibo = 0; -#else - cache->vertices = (float *) malloc(floatSizeInBytes); - memcpy(cache->vertices, vertexCoordinateArray.data(), floatSizeInBytes); - cache->indices = 0; -#endif - } - - prepareForDraw(currentBrush.isOpaque()); -#ifdef QT_OPENGL_CACHE_AS_VBOS - glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0); -#else - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices); -#endif - glDrawArrays(cache->primitiveType, 0, cache->vertexCount); - - } else { - // printf(" - Marking path as cachable...\n"); - // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable - path.makeCacheable(); - vertexCoordinateArray.clear(); - vertexCoordinateArray.addPath(path, inverseScale, false); - prepareForDraw(currentBrush.isOpaque()); - drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); - } - - } else { - bool useCache = path.isCacheable(); - if (useCache) { - QRectF bbox = path.controlPointRect(); - // If the path doesn't fit within these limits, it is possible that the triangulation will fail. - useCache &= (bbox.left() > -0x8000 * inverseScale) - && (bbox.right() < 0x8000 * inverseScale) - && (bbox.top() > -0x8000 * inverseScale) - && (bbox.bottom() < 0x8000 * inverseScale); - } - - if (useCache) { - QVectorPath::CacheEntry *data = path.lookupCacheData(q); - QGL2PEVectorPathCache *cache; - - bool updateCache = false; - - if (data) { - cache = (QGL2PEVectorPathCache *) data->data; - // Check if scale factor is exceeded for curved paths and generate curves if so... - if (path.isCurved()) { - qreal scaleFactor = cache->iscale / inverseScale; - if (scaleFactor < 0.5 || scaleFactor > 2.0) { -#ifdef QT_OPENGL_CACHE_AS_VBOS - glDeleteBuffers(1, &cache->vbo); - glDeleteBuffers(1, &cache->ibo); -#else - free(cache->vertices); - free(cache->indices); -#endif - updateCache = true; - } - } - } else { - cache = new QGL2PEVectorPathCache; - data = const_cast<QVectorPath &>(path).addCacheData(q, cache, cleanupVectorPath); - updateCache = true; - } - - // Flatten the path at the current scale factor and fill it into the cache struct. - if (updateCache) { - QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale)); - cache->vertexCount = polys.vertices.size() / 2; - cache->indexCount = polys.indices.size(); - cache->primitiveType = GL_TRIANGLES; - cache->iscale = inverseScale; - cache->indexType = polys.indices.type(); -#ifdef QT_OPENGL_CACHE_AS_VBOS - glGenBuffers(1, &cache->vbo); - glGenBuffers(1, &cache->ibo); - glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo); - - if (polys.indices.type() == QVertexIndexVector::UnsignedInt) - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint32) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW); - else - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(quint16) * polys.indices.size(), polys.indices.data(), GL_STATIC_DRAW); - - QVarLengthArray<float> vertices(polys.vertices.size()); - for (int i = 0; i < polys.vertices.size(); ++i) - vertices[i] = float(inverseScale * polys.vertices.at(i)); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertices.size(), vertices.data(), GL_STATIC_DRAW); -#else - cache->vertices = (float *) malloc(sizeof(float) * polys.vertices.size()); - if (polys.indices.type() == QVertexIndexVector::UnsignedInt) { - cache->indices = (quint32 *) malloc(sizeof(quint32) * polys.indices.size()); - memcpy(cache->indices, polys.indices.data(), sizeof(quint32) * polys.indices.size()); - } else { - cache->indices = (quint16 *) malloc(sizeof(quint16) * polys.indices.size()); - memcpy(cache->indices, polys.indices.data(), sizeof(quint16) * polys.indices.size()); - } - for (int i = 0; i < polys.vertices.size(); ++i) - cache->vertices[i] = float(inverseScale * polys.vertices.at(i)); -#endif - } - - prepareForDraw(currentBrush.isOpaque()); -#ifdef QT_OPENGL_CACHE_AS_VBOS - glBindBuffer(GL_ARRAY_BUFFER, cache->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cache->ibo); - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, 0); - if (cache->indexType == QVertexIndexVector::UnsignedInt) - glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, 0); - else - glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); -#else - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, cache->vertices); - if (cache->indexType == QVertexIndexVector::UnsignedInt) - glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_INT, (qint32 *)cache->indices); - else - glDrawElements(cache->primitiveType, cache->indexCount, GL_UNSIGNED_SHORT, (qint16 *)cache->indices); -#endif - - } else { - // printf(" - Marking path as cachable...\n"); - // Tag it for later so that if the same path is drawn twice, it is assumed to be static and thus cachable - path.makeCacheable(); - - if (!device->format().stencil()) { - // If there is no stencil buffer, triangulate the path instead. - - QRectF bbox = path.controlPointRect(); - // If the path doesn't fit within these limits, it is possible that the triangulation will fail. - bool withinLimits = (bbox.left() > -0x8000 * inverseScale) - && (bbox.right() < 0x8000 * inverseScale) - && (bbox.top() > -0x8000 * inverseScale) - && (bbox.bottom() < 0x8000 * inverseScale); - if (withinLimits) { - QTriangleSet polys = qTriangulate(path, QTransform().scale(1 / inverseScale, 1 / inverseScale)); - - QVarLengthArray<float> vertices(polys.vertices.size()); - for (int i = 0; i < polys.vertices.size(); ++i) - vertices[i] = float(inverseScale * polys.vertices.at(i)); - - prepareForDraw(currentBrush.isOpaque()); - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, vertices.constData()); - if (polys.indices.type() == QVertexIndexVector::UnsignedInt) - glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_INT, polys.indices.data()); - else - glDrawElements(GL_TRIANGLES, polys.indices.size(), GL_UNSIGNED_SHORT, polys.indices.data()); - } else { - // We can't handle big, concave painter paths with OpenGL without stencil buffer. - qWarning("Painter path exceeds +/-32767 pixels."); - } - return; - } - - // The path is too complicated & needs the stencil technique - vertexCoordinateArray.clear(); - vertexCoordinateArray.addPath(path, inverseScale, false); - - fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill()); - - glStencilMask(0xff); - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); - - if (q->state()->clipTestEnabled) { - // Pass when high bit is set, replace stencil value with current clip - glStencilFunc(GL_NOTEQUAL, q->state()->currentClip, GL_STENCIL_HIGH_BIT); - } else if (path.hasWindingFill()) { - // Pass when any bit is set, replace stencil value with 0 - glStencilFunc(GL_NOTEQUAL, 0, 0xff); - } else { - // Pass when high bit is set, replace stencil value with 0 - glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); - } - prepareForDraw(currentBrush.isOpaque()); - - // Stencil the brush onto the dest buffer - composite(vertexCoordinateArray.boundingRect()); - glStencilMask(0); - updateClipScissorTest(); - } - } -} - - -void QGL2PaintEngineExPrivate::fillStencilWithVertexArray(const float *data, - int count, - int *stops, - int stopCount, - const QGLRect &bounds, - StencilFillMode mode) -{ - Q_ASSERT(count || stops); - -// qDebug("QGL2PaintEngineExPrivate::fillStencilWithVertexArray()"); - glStencilMask(0xff); // Enable stencil writes - - if (dirtyStencilRegion.intersects(currentScissorBounds)) { - const QRegion clearRegion = dirtyStencilRegion.intersected(currentScissorBounds); - glClearStencil(0); // Clear to zero - for (const QRect &rect : clearRegion) { -#ifndef QT_GL_NO_SCISSOR_TEST - setScissor(rect); -#endif - glClear(GL_STENCIL_BUFFER_BIT); - } - - dirtyStencilRegion -= currentScissorBounds; - -#ifndef QT_GL_NO_SCISSOR_TEST - updateClipScissorTest(); -#endif - } - - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Disable color writes - useSimpleShader(); - glEnable(GL_STENCIL_TEST); // For some reason, this has to happen _after_ the simple shader is use()'d - - if (mode == WindingFillMode) { - Q_ASSERT(stops && !count); - if (q->state()->clipTestEnabled) { - // Flatten clip values higher than current clip, and set high bit to match current clip - glStencilFunc(GL_LEQUAL, GL_STENCIL_HIGH_BIT | q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); - composite(bounds); - - glStencilFunc(GL_EQUAL, GL_STENCIL_HIGH_BIT, GL_STENCIL_HIGH_BIT); - } else if (!stencilClean) { - // Clear stencil buffer within bounding rect - glStencilFunc(GL_ALWAYS, 0, 0xff); - glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO); - composite(bounds); - } - - // Inc. for front-facing triangle - glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_INCR_WRAP); - // Dec. for back-facing "holes" - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_DECR_WRAP); - glStencilMask(~GL_STENCIL_HIGH_BIT); - drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); - - if (q->state()->clipTestEnabled) { - // Clear high bit of stencil outside of path - glStencilFunc(GL_EQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); - glStencilMask(GL_STENCIL_HIGH_BIT); - composite(bounds); - } - } else if (mode == OddEvenFillMode) { - glStencilMask(GL_STENCIL_HIGH_BIT); - glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit - drawVertexArrays(data, stops, stopCount, GL_TRIANGLE_FAN); - - } else { // TriStripStrokeFillMode - Q_ASSERT(count && !stops); // tristrips generated directly, so no vertexArray or stops - glStencilMask(GL_STENCIL_HIGH_BIT); -#if 0 - glStencilOp(GL_KEEP, GL_KEEP, GL_INVERT); // Simply invert the stencil bit - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data); - glDrawArrays(GL_TRIANGLE_STRIP, 0, count); -#else - - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - if (q->state()->clipTestEnabled) { - glStencilFunc(GL_LEQUAL, q->state()->currentClip | GL_STENCIL_HIGH_BIT, - ~GL_STENCIL_HIGH_BIT); - } else { - glStencilFunc(GL_ALWAYS, GL_STENCIL_HIGH_BIT, 0xff); - } - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data); - glDrawArrays(GL_TRIANGLE_STRIP, 0, count); -#endif - } - - // Enable color writes & disable stencil writes - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); -} - -/* - If the maximum value in the stencil buffer is GL_STENCIL_HIGH_BIT - 1, - restore the stencil buffer to a pristine state. The current clip region - is set to 1, and the rest to 0. -*/ -void QGL2PaintEngineExPrivate::resetClipIfNeeded() -{ - if (maxClip != (GL_STENCIL_HIGH_BIT - 1)) - return; - - Q_Q(QGL2PaintEngineEx); - - useSimpleShader(); - glEnable(GL_STENCIL_TEST); - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - - QRectF bounds = q->state()->matrix.inverted().mapRect(QRectF(0, 0, width, height)); - QGLRect rect(bounds.left(), bounds.top(), bounds.right(), bounds.bottom()); - - // Set high bit on clip region - glStencilFunc(GL_LEQUAL, q->state()->currentClip, 0xff); - glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT); - glStencilMask(GL_STENCIL_HIGH_BIT); - composite(rect); - - // Reset clipping to 1 and everything else to zero - glStencilFunc(GL_NOTEQUAL, 0x01, GL_STENCIL_HIGH_BIT); - glStencilOp(GL_ZERO, GL_REPLACE, GL_REPLACE); - glStencilMask(0xff); - composite(rect); - - q->state()->currentClip = 1; - q->state()->canRestoreClip = false; - - maxClip = 1; - - glStencilMask(0x0); - glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); -} - -bool QGL2PaintEngineExPrivate::prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache) -{ - Q_Q(QGL2PaintEngineEx); - - Q_ASSERT(cache.transform().type() <= QTransform::TxScale); - - QTransform &transform = q->state()->matrix; - transform.scale(1.0 / cache.transform().m11(), 1.0 / cache.transform().m22()); - bool ret = prepareForDraw(false); - transform.scale(cache.transform().m11(), cache.transform().m22()); - - return ret; -} - -bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) -{ - if (brushTextureDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) - updateBrushTexture(); - - if (compositionModeDirty) - updateCompositionMode(); - - if (matrixDirty) - updateMatrix(); - - const bool stateHasOpacity = q->state()->opacity < 0.99f; - if (q->state()->composition_mode == QPainter::CompositionMode_Source - || (q->state()->composition_mode == QPainter::CompositionMode_SourceOver - && srcPixelsAreOpaque && !stateHasOpacity)) - { - glDisable(GL_BLEND); - } else { - glEnable(GL_BLEND); - } - - QGLEngineShaderManager::OpacityMode opacityMode; - if (mode == ImageArrayDrawingMode) { - opacityMode = QGLEngineShaderManager::AttributeOpacity; - } else { - opacityMode = stateHasOpacity ? QGLEngineShaderManager::UniformOpacity - : QGLEngineShaderManager::NoOpacity; - if (stateHasOpacity && (mode != ImageDrawingMode)) { - // Using a brush - bool brushIsPattern = (currentBrush.style() >= Qt::Dense1Pattern) && - (currentBrush.style() <= Qt::DiagCrossPattern); - - if ((currentBrush.style() == Qt::SolidPattern) || brushIsPattern) - opacityMode = QGLEngineShaderManager::NoOpacity; // Global opacity handled by srcPixel shader - } - } - shaderManager->setOpacityMode(opacityMode); - - bool changed = shaderManager->useCorrectShaderProg(); - // If the shader program needs changing, we change it and mark all uniforms as dirty - if (changed) { - // The shader program has changed so mark all uniforms as dirty: - brushUniformsDirty = true; - opacityUniformDirty = true; - matrixUniformDirty = true; - translateZUniformDirty = true; - } - - if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) - updateBrushUniforms(); - - if (opacityMode == QGLEngineShaderManager::UniformOpacity && opacityUniformDirty) { - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity); - opacityUniformDirty = false; - } - - if (matrixUniformDirty && shaderManager->hasComplexGeometry()) { - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Matrix), - pmvMatrix); - matrixUniformDirty = false; - } - - if (translateZUniformDirty && shaderManager->hasComplexGeometry()) { - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::TranslateZ), - translateZ); - translateZUniformDirty = false; - } - - return changed; -} - -void QGL2PaintEngineExPrivate::composite(const QGLRect& boundingRect) -{ - setCoords(staticVertexCoordinateArray, boundingRect); - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, staticVertexCoordinateArray); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -} - -// Draws the vertex array as a set of <vertexArrayStops.size()> triangle fans. -void QGL2PaintEngineExPrivate::drawVertexArrays(const float *data, int *stops, int stopCount, - GLenum primitive) -{ - // Now setup the pointer to the vertex array: - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, data); - - int previousStop = 0; - for (int i=0; i<stopCount; ++i) { - int stop = stops[i]; -/* - qDebug("Drawing triangle fan for vertecies %d -> %d:", previousStop, stop-1); - for (int i=previousStop; i<stop; ++i) - qDebug(" %02d: [%.2f, %.2f]", i, vertexArray.data()[i].x, vertexArray.data()[i].y); -*/ - glDrawArrays(primitive, previousStop, stop - previousStop); - previousStop = stop; - } -} - -/////////////////////////////////// Public Methods ////////////////////////////////////////// - -QGL2PaintEngineEx::QGL2PaintEngineEx() - : QPaintEngineEx(*(new QGL2PaintEngineExPrivate(this))) -{ -} - -QGL2PaintEngineEx::~QGL2PaintEngineEx() -{ -} - -void QGL2PaintEngineEx::fill(const QVectorPath &path, const QBrush &brush) -{ - Q_D(QGL2PaintEngineEx); - - if (qbrush_style(brush) == Qt::NoBrush) - return; - ensureActive(); - d->setBrush(brush); - d->fill(path); -} - -Q_GUI_EXPORT bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp - - -void QGL2PaintEngineEx::stroke(const QVectorPath &path, const QPen &pen) -{ - Q_D(QGL2PaintEngineEx); - - const QBrush &penBrush = qpen_brush(pen); - if (qpen_style(pen) == Qt::NoPen || qbrush_style(penBrush) == Qt::NoBrush) - return; - - QGL2PaintEngineState *s = state(); - if (qt_pen_is_cosmetic(pen, s->renderHints) && !qt_scaleForTransform(s->transform(), 0)) { - // QTriangulatingStroker class is not meant to support cosmetically sheared strokes. - QPaintEngineEx::stroke(path, pen); - return; - } - - ensureActive(); - d->setBrush(penBrush); - d->stroke(path, pen); -} - -void QGL2PaintEngineExPrivate::stroke(const QVectorPath &path, const QPen &pen) -{ - const QGL2PaintEngineState *s = q->state(); - if (snapToPixelGrid) { - snapToPixelGrid = false; - matrixDirty = true; - } - - const Qt::PenStyle penStyle = qpen_style(pen); - const QBrush &penBrush = qpen_brush(pen); - const bool opaque = penBrush.isOpaque() && s->opacity > 0.99; - - transferMode(BrushDrawingMode); - - // updateMatrix() is responsible for setting the inverse scale on - // the strokers, so we need to call it here and not wait for - // prepareForDraw() down below. - updateMatrix(); - - QRectF clip = q->state()->matrix.inverted().mapRect(q->state()->clipEnabled - ? q->state()->rectangleClip - : QRectF(0, 0, width, height)); - - if (penStyle == Qt::SolidLine) { - stroker.process(path, pen, clip, s->renderHints); - - } else { // Some sort of dash - dasher.process(path, pen, clip, s->renderHints); - - QVectorPath dashStroke(dasher.points(), - dasher.elementCount(), - dasher.elementTypes()); - stroker.process(dashStroke, pen, clip, s->renderHints); - } - - if (!stroker.vertexCount()) - return; - - if (opaque) { - prepareForDraw(opaque); - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, stroker.vertices()); - glDrawArrays(GL_TRIANGLE_STRIP, 0, stroker.vertexCount() / 2); - -// QBrush b(Qt::green); -// d->setBrush(&b); -// d->prepareForDraw(true); -// glDrawArrays(GL_LINE_STRIP, 0, d->stroker.vertexCount() / 2); - - } else { - qreal width = qpen_widthf(pen) / 2; - if (width == 0) - width = 0.5; - qreal extra = pen.joinStyle() == Qt::MiterJoin - ? qMax(pen.miterLimit() * width, width) - : width; - - if (qt_pen_is_cosmetic(pen, s->renderHints)) - extra = extra * inverseScale; - - QRectF bounds = path.controlPointRect().adjusted(-extra, -extra, extra, extra); - - fillStencilWithVertexArray(stroker.vertices(), stroker.vertexCount() / 2, - 0, 0, bounds, QGL2PaintEngineExPrivate::TriStripStrokeFillMode); - - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); - - // Pass when any bit is set, replace stencil value with 0 - glStencilFunc(GL_NOTEQUAL, 0, GL_STENCIL_HIGH_BIT); - prepareForDraw(false); - - // Stencil the brush onto the dest buffer - composite(bounds); - - glStencilMask(0); - - updateClipScissorTest(); - } -} - -void QGL2PaintEngineEx::penChanged() { } -void QGL2PaintEngineEx::brushChanged() { } -void QGL2PaintEngineEx::brushOriginChanged() { } - -void QGL2PaintEngineEx::opacityChanged() -{ -// qDebug("QGL2PaintEngineEx::opacityChanged()"); - Q_D(QGL2PaintEngineEx); - state()->opacityChanged = true; - - Q_ASSERT(d->shaderManager); - d->brushUniformsDirty = true; - d->opacityUniformDirty = true; -} - -void QGL2PaintEngineEx::compositionModeChanged() -{ -// qDebug("QGL2PaintEngineEx::compositionModeChanged()"); - Q_D(QGL2PaintEngineEx); - state()->compositionModeChanged = true; - d->compositionModeDirty = true; -} - -void QGL2PaintEngineEx::renderHintsChanged() -{ - Q_D(QGL2PaintEngineEx); - state()->renderHintsChanged = true; - -#if !defined(QT_OPENGL_ES_2) -QT_WARNING_PUSH -QT_WARNING_DISABLE_DEPRECATED - if (!d->ctx->contextHandle()->isOpenGLES()) { - if ((state()->renderHints & QPainter::Antialiasing) -#if QT_DEPRECATED_SINCE(5, 14) - || (state()->renderHints & QPainter::HighQualityAntialiasing) -#endif - ) - d->glEnable(GL_MULTISAMPLE); - else - d->glDisable(GL_MULTISAMPLE); - } -QT_WARNING_POP -#endif - - d->lastTextureUsed = GLuint(-1); - d->brushTextureDirty = true; -// qDebug("QGL2PaintEngineEx::renderHintsChanged() not implemented!"); -} - -void QGL2PaintEngineEx::transformChanged() -{ - Q_D(QGL2PaintEngineEx); - d->matrixDirty = true; - state()->matrixChanged = true; -} - - -static const QRectF scaleRect(const QRectF &r, qreal sx, qreal sy) -{ - return QRectF(r.x() * sx, r.y() * sy, r.width() * sx, r.height() * sy); -} - -void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, const QRectF & src) -{ - Q_D(QGL2PaintEngineEx); - QGLContext *ctx = d->ctx; - - int max_texture_size = ctx->d_func()->maxTextureSize(); - if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) { - QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); - - const qreal sx = scaled.width() / qreal(pixmap.width()); - const qreal sy = scaled.height() / qreal(pixmap.height()); - - drawPixmap(dest, scaled, scaleRect(src, sx, sy)); - return; - } - - ensureActive(); - d->transferMode(ImageDrawingMode); - - QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption|QGLContext::CanFlipNativePixmapBindOption; -#ifdef QGL_USE_TEXTURE_POOL - bindOptions |= QGLContext::TemporarilyCachedBindOption; -#endif - - d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - QGLTexture *texture = - ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, bindOptions); - - GLfloat top = texture->options & QGLContext::InvertedYBindOption ? (pixmap.height() - src.top()) : src.top(); - GLfloat bottom = texture->options & QGLContext::InvertedYBindOption ? (pixmap.height() - src.bottom()) : src.bottom(); - QGLRect srcRect(src.left(), top, src.right(), bottom); - - bool isBitmap = pixmap.isQBitmap(); - bool isOpaque = !isBitmap && !pixmap.hasAlpha(); - - d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, - state()->renderHints & QPainter::SmoothPixmapTransform, texture->id); - d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap); - - if (texture->options&QGLContext::TemporarilyCachedBindOption) { - // pixmap was temporarily cached as a QImage texture by pooling system - // and should be destroyed immediately - QGLTextureCache::instance()->remove(ctx, texture->id); - } -} - -void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src, - Qt::ImageConversionFlags) -{ - Q_D(QGL2PaintEngineEx); - QGLContext *ctx = d->ctx; - - int max_texture_size = ctx->d_func()->maxTextureSize(); - if (image.width() > max_texture_size || image.height() > max_texture_size) { - QImage scaled = image.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); - - const qreal sx = scaled.width() / qreal(image.width()); - const qreal sy = scaled.height() / qreal(image.height()); - - drawImage(dest, scaled, scaleRect(src, sx, sy)); - return; - } - - ensureActive(); - d->transferMode(ImageDrawingMode); - - d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - - QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption; -#ifdef QGL_USE_TEXTURE_POOL - bindOptions |= QGLContext::TemporarilyCachedBindOption; -#endif - - QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, bindOptions); - GLuint id = texture->id; - - d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, - state()->renderHints & QPainter::SmoothPixmapTransform, id); - d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel()); - - if (texture->options&QGLContext::TemporarilyCachedBindOption) { - // image was temporarily cached by texture pooling system - // and should be destroyed immediately - QGLTextureCache::instance()->remove(ctx, texture->id); - } -} - -void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem) -{ - Q_D(QGL2PaintEngineEx); - - ensureActive(); - - QPainterState *s = state(); - - // don't try to cache huge fonts or vastly transformed fonts - QFontEngine *fontEngine = textItem->fontEngine(); - if (shouldDrawCachedGlyphs(fontEngine, s->matrix)) { - - QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat != QFontEngine::Format_None - ? fontEngine->glyphFormat : d->glyphCacheFormat; - - if (glyphFormat == QFontEngine::Format_A32) { - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects() - || d->device->alphaRequested() || s->matrix.type() > QTransform::TxTranslate - || (s->composition_mode != QPainter::CompositionMode_Source - && s->composition_mode != QPainter::CompositionMode_SourceOver)) - { - glyphFormat = QFontEngine::Format_A8; - } - } - - d->drawCachedGlyphs(glyphFormat, textItem); - } else { - QPaintEngineEx::drawStaticTextItem(textItem); - } -} - -bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src) -{ - Q_D(QGL2PaintEngineEx); - if (!d->shaderManager) - return false; - - ensureActive(); - d->transferMode(ImageDrawingMode); - - d->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - d->glBindTexture(GL_TEXTURE_2D, textureId); - - QGLRect srcRect(src.left(), src.bottom(), src.right(), src.top()); - - d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, - state()->renderHints & QPainter::SmoothPixmapTransform, textureId); - d->drawTexture(dest, srcRect, size, false); - return true; -} - -void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem) -{ - Q_D(QGL2PaintEngineEx); - - ensureActive(); - QGL2PaintEngineState *s = state(); - - const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem); - - QTransform::TransformationType txtype = s->matrix.type(); - - QFontEngine::GlyphFormat glyphFormat = ti.fontEngine->glyphFormat != QFontEngine::Format_None - ? ti.fontEngine->glyphFormat : d->glyphCacheFormat; - - if (glyphFormat == QFontEngine::Format_A32) { - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects() - || d->device->alphaRequested() || txtype > QTransform::TxTranslate - || (state()->composition_mode != QPainter::CompositionMode_Source - && state()->composition_mode != QPainter::CompositionMode_SourceOver)) - { - glyphFormat = QFontEngine::Format_A8; - } - } - - if (shouldDrawCachedGlyphs(ti.fontEngine, s->matrix)) { - QVarLengthArray<QFixedPoint> positions; - QVarLengthArray<glyph_t> glyphs; - QTransform matrix = QTransform::fromTranslate(p.x(), p.y()); - ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); - - { - QStaticTextItem staticTextItem; - staticTextItem.setFontEngine(ti.fontEngine); - staticTextItem.glyphs = glyphs.data(); - staticTextItem.numGlyphs = glyphs.size(); - staticTextItem.glyphPositions = positions.data(); - - d->drawCachedGlyphs(glyphFormat, &staticTextItem); - } - return; - } - - QPaintEngineEx::drawTextItem(p, ti); -} - -namespace { - - class QOpenGLStaticTextUserData: public QStaticTextUserData - { - public: - QOpenGLStaticTextUserData() - : QStaticTextUserData(OpenGLUserData), cacheSize(0, 0), cacheSerialNumber(0) - { - } - - ~QOpenGLStaticTextUserData() - { - } - - QSize cacheSize; - QGL2PEXVertexArray vertexCoordinateArray; - QGL2PEXVertexArray textureCoordinateArray; - QFontEngine::GlyphFormat glyphFormat; - int cacheSerialNumber; - }; - -} - - -// #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO - -void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat glyphFormat, - QStaticTextItem *staticTextItem) -{ - Q_Q(QGL2PaintEngineEx); - - QGL2PaintEngineState *s = q->state(); - - void *cacheKey = const_cast<QGLContext *>(QGLContextPrivate::contextGroup(ctx)->context()); - bool recreateVertexArrays = false; - - QTransform glyphCacheTransform; - QFontEngine *fe = staticTextItem->fontEngine(); - if (fe->supportsTransformation(s->matrix)) { - // The font-engine supports rendering glyphs with the current transform, so we - // build a glyph-cache with the scale pre-applied, so that the cache contains - // glyphs with the appropriate resolution in the case of retina displays. - glyphCacheTransform = s->matrix.type() < QTransform::TxRotate ? - QTransform::fromScale(qAbs(s->matrix.m11()), qAbs(s->matrix.m22())) : - QTransform::fromScale( - QVector2D(s->matrix.m11(), s->matrix.m12()).length(), - QVector2D(s->matrix.m21(), s->matrix.m22()).length()); - } - - QGLTextureGlyphCache *cache = - (QGLTextureGlyphCache *) fe->glyphCache(cacheKey, glyphFormat, glyphCacheTransform); - if (!cache || cache->glyphFormat() != glyphFormat || cache->contextGroup() == 0) { - cache = new QGLTextureGlyphCache(glyphFormat, glyphCacheTransform); - fe->setGlyphCache(cacheKey, cache); - recreateVertexArrays = true; - } - - if (staticTextItem->userDataNeedsUpdate) { - recreateVertexArrays = true; - } else if (staticTextItem->userData() == 0) { - recreateVertexArrays = true; - } else if (staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) { - recreateVertexArrays = true; - } else { - QOpenGLStaticTextUserData *userData = static_cast<QOpenGLStaticTextUserData *>(staticTextItem->userData()); - if (userData->glyphFormat != glyphFormat) { - recreateVertexArrays = true; - } else if (userData->cacheSerialNumber != cache->serialNumber()) { - recreateVertexArrays = true; - } - } - - // We only need to update the cache with new glyphs if we are actually going to recreate the vertex arrays. - // If the cache size has changed, we do need to regenerate the vertices, but we don't need to repopulate the - // cache so this text is performed before we test if the cache size has changed. - if (recreateVertexArrays) { - cache->setPaintEnginePrivate(this); - if (!cache->populate(fe, staticTextItem->numGlyphs, - staticTextItem->glyphs, staticTextItem->glyphPositions)) { - // No space for glyphs in cache. We need to reset it and try again. - cache->clear(); - cache->populate(fe, staticTextItem->numGlyphs, - staticTextItem->glyphs, staticTextItem->glyphPositions); - } - cache->fillInPendingGlyphs(); - } - - if (cache->width() == 0 || cache->height() == 0) - return; - - transferMode(TextDrawingMode); - - int margin = fe->glyphMargin(glyphFormat); - - GLfloat dx = 1.0 / cache->width(); - GLfloat dy = 1.0 / cache->height(); - - // Use global arrays by default - QGL2PEXVertexArray *vertexCoordinates = &vertexCoordinateArray; - QGL2PEXVertexArray *textureCoordinates = &textureCoordinateArray; - - if (staticTextItem->useBackendOptimizations) { - QOpenGLStaticTextUserData *userData = 0; - - if (staticTextItem->userData() == 0 - || staticTextItem->userData()->type != QStaticTextUserData::OpenGLUserData) { - - userData = new QOpenGLStaticTextUserData(); - staticTextItem->setUserData(userData); - - } else { - userData = static_cast<QOpenGLStaticTextUserData*>(staticTextItem->userData()); - } - - userData->glyphFormat = glyphFormat; - userData->cacheSerialNumber = cache->serialNumber(); - - // Use cache if backend optimizations is turned on - vertexCoordinates = &userData->vertexCoordinateArray; - textureCoordinates = &userData->textureCoordinateArray; - - QSize size(cache->width(), cache->height()); - if (userData->cacheSize != size) { - recreateVertexArrays = true; - userData->cacheSize = size; - } - } - - if (recreateVertexArrays) { - vertexCoordinates->clear(); - textureCoordinates->clear(); - - bool supportsSubPixelPositions = fe->supportsSubPixelPositions(); - for (int i=0; i<staticTextItem->numGlyphs; ++i) { - QFixed subPixelPosition; - if (supportsSubPixelPositions) - subPixelPosition = fe->subPixelPositionForX(staticTextItem->glyphPositions[i].x); - - QTextureGlyphCache::GlyphAndSubPixelPosition glyph(staticTextItem->glyphs[i], subPixelPosition); - - const QTextureGlyphCache::Coord &c = cache->coords[glyph]; - if (c.isNull()) - continue; - - int x = qFloor(staticTextItem->glyphPositions[i].x.toReal() * cache->transform().m11()) + c.baseLineX - margin; - int y = qRound(staticTextItem->glyphPositions[i].y.toReal() * cache->transform().m22()) - c.baseLineY - margin; - - vertexCoordinates->addQuad(QRectF(x, y, c.w, c.h)); - textureCoordinates->addQuad(QRectF(c.x*dx, c.y*dy, c.w * dx, c.h * dy)); - } - - staticTextItem->userDataNeedsUpdate = false; - } - - int numGlyphs = vertexCoordinates->vertexCount() / 4; - if (numGlyphs == 0) - return; - - if (elementIndices.size() < numGlyphs*6) { - Q_ASSERT(elementIndices.size() % 6 == 0); - int j = elementIndices.size() / 6 * 4; - while (j < numGlyphs*4) { - elementIndices.append(j + 0); - elementIndices.append(j + 0); - elementIndices.append(j + 1); - elementIndices.append(j + 2); - elementIndices.append(j + 3); - elementIndices.append(j + 3); - - j += 4; - } - -#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - if (elementIndicesVBOId == 0) - glGenBuffers(1, &elementIndicesVBOId); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementIndices.size() * sizeof(GLushort), - elementIndices.constData(), GL_STATIC_DRAW); -#endif - } else { -#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementIndicesVBOId); -#endif - } - - setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinates->data()); - setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinates->data()); - - if (!snapToPixelGrid) { - snapToPixelGrid = true; - matrixDirty = true; - } - - QBrush pensBrush = q->state()->pen.brush(); - setBrush(pensBrush); - - if (glyphFormat == QFontEngine::Format_A32) { - - // Subpixel antialiasing without gamma correction - - QPainter::CompositionMode compMode = q->state()->composition_mode; - Q_ASSERT(compMode == QPainter::CompositionMode_Source - || compMode == QPainter::CompositionMode_SourceOver); - - shaderManager->setMaskType(QGLEngineShaderManager::SubPixelMaskPass1); - - if (pensBrush.style() == Qt::SolidPattern) { - // Solid patterns can get away with only one pass. - QColor c = pensBrush.color(); - qreal oldOpacity = q->state()->opacity; - if (compMode == QPainter::CompositionMode_Source) { - c = qt_premultiplyColor(c, q->state()->opacity); - q->state()->opacity = 1; - opacityUniformDirty = true; - } - - compositionModeDirty = false; // I can handle this myself, thank you very much - prepareForCachedGlyphDraw(*cache); - - // prepareForCachedGlyphDraw() have set the opacity on the current shader, so the opacity state can now be reset. - if (compMode == QPainter::CompositionMode_Source) { - q->state()->opacity = oldOpacity; - opacityUniformDirty = true; - } - - glEnable(GL_BLEND); - glBlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); - glBlendColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); - } else { - // Other brush styles need two passes. - - qreal oldOpacity = q->state()->opacity; - if (compMode == QPainter::CompositionMode_Source) { - q->state()->opacity = 1; - opacityUniformDirty = true; - pensBrush = Qt::white; - setBrush(pensBrush); - } - - compositionModeDirty = false; // I can handle this myself, thank you very much - prepareForCachedGlyphDraw(*cache); - glEnable(GL_BLEND); - glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - - glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, cache->texture()); - updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false); - -#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); -#else - glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); -#endif - - shaderManager->setMaskType(QGLEngineShaderManager::SubPixelMaskPass2); - - if (compMode == QPainter::CompositionMode_Source) { - q->state()->opacity = oldOpacity; - opacityUniformDirty = true; - pensBrush = q->state()->pen.brush(); - setBrush(pensBrush); - } - - compositionModeDirty = false; - prepareForCachedGlyphDraw(*cache); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - } - compositionModeDirty = true; - } else { - // Grayscale/mono glyphs - - shaderManager->setMaskType(QGLEngineShaderManager::PixelMask); - prepareForCachedGlyphDraw(*cache); - } - - QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest; - if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) { - - glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT); - if (lastMaskTextureUsed != cache->texture()) { - glBindTexture(GL_TEXTURE_2D, cache->texture()); - lastMaskTextureUsed = cache->texture(); - } - - if (cache->filterMode() != filterMode) { - if (filterMode == QGLTextureGlyphCache::Linear) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - cache->setFilterMode(filterMode); - } - } - -#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) - glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -#else - glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); -#endif -} - -void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, - QPainter::PixmapFragmentHints hints) -{ - Q_D(QGL2PaintEngineEx); - // Use fallback for extended composition modes. - if (state()->composition_mode > QPainter::CompositionMode_Plus) { - QPaintEngineEx::drawPixmapFragments(fragments, fragmentCount, pixmap, hints); - return; - } - - ensureActive(); - int max_texture_size = d->ctx->d_func()->maxTextureSize(); - if (pixmap.width() > max_texture_size || pixmap.height() > max_texture_size) { - QPixmap scaled = pixmap.scaled(max_texture_size, max_texture_size, Qt::KeepAspectRatio); - d->drawPixmapFragments(fragments, fragmentCount, scaled, hints); - } else { - d->drawPixmapFragments(fragments, fragmentCount, pixmap, hints); - } -} - - -void QGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFragment *fragments, - int fragmentCount, const QPixmap &pixmap, - QPainter::PixmapFragmentHints hints) -{ - GLfloat dx = 1.0f / pixmap.size().width(); - GLfloat dy = 1.0f / pixmap.size().height(); - - vertexCoordinateArray.clear(); - textureCoordinateArray.clear(); - opacityArray.reset(); - - if (snapToPixelGrid) { - snapToPixelGrid = false; - matrixDirty = true; - } - - bool allOpaque = true; - - for (int i = 0; i < fragmentCount; ++i) { - qreal s = 0; - qreal c = 1; - if (fragments[i].rotation != 0) { - s = qFastSin(qDegreesToRadians(fragments[i].rotation)); - c = qFastCos(qDegreesToRadians(fragments[i].rotation)); - } - - qreal right = 0.5 * fragments[i].scaleX * fragments[i].width; - qreal bottom = 0.5 * fragments[i].scaleY * fragments[i].height; - QGLPoint bottomRight(right * c - bottom * s, right * s + bottom * c); - QGLPoint bottomLeft(-right * c - bottom * s, -right * s + bottom * c); - - vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); - vertexCoordinateArray.addVertex(-bottomLeft.x + fragments[i].x, -bottomLeft.y + fragments[i].y); - vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); - vertexCoordinateArray.addVertex(-bottomRight.x + fragments[i].x, -bottomRight.y + fragments[i].y); - vertexCoordinateArray.addVertex(bottomLeft.x + fragments[i].x, bottomLeft.y + fragments[i].y); - vertexCoordinateArray.addVertex(bottomRight.x + fragments[i].x, bottomRight.y + fragments[i].y); - - QGLRect src(fragments[i].sourceLeft * dx, fragments[i].sourceTop * dy, - (fragments[i].sourceLeft + fragments[i].width) * dx, - (fragments[i].sourceTop + fragments[i].height) * dy); - - textureCoordinateArray.addVertex(src.right, src.bottom); - textureCoordinateArray.addVertex(src.right, src.top); - textureCoordinateArray.addVertex(src.left, src.top); - textureCoordinateArray.addVertex(src.left, src.top); - textureCoordinateArray.addVertex(src.left, src.bottom); - textureCoordinateArray.addVertex(src.right, src.bottom); - - qreal opacity = fragments[i].opacity * q->state()->opacity; - opacityArray << opacity << opacity << opacity << opacity << opacity << opacity; - allOpaque &= (opacity >= 0.99f); - } - - glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, - QGLContext::InternalBindOption - | QGLContext::CanFlipNativePixmapBindOption); - - if (texture->options & QGLContext::InvertedYBindOption) { - // Flip texture y-coordinate. - QGLPoint *data = textureCoordinateArray.data(); - for (int i = 0; i < 6 * fragmentCount; ++i) - data[i].y = 1 - data[i].y; - } - - transferMode(ImageArrayDrawingMode); - - bool isBitmap = pixmap.isQBitmap(); - bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque; - - updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, - q->state()->renderHints & QPainter::SmoothPixmapTransform, texture->id); - - // Setup for texture drawing - currentBrush = noBrush; - shaderManager->setSrcPixelType(isBitmap ? QGLEngineShaderManager::PatternSrc - : QGLEngineShaderManager::ImageSrc); - if (prepareForDraw(isOpaque)) - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::ImageTexture), QT_IMAGE_TEXTURE_UNIT); - - if (isBitmap) { - QColor col = qt_premultiplyColor(q->state()->pen.color(), (GLfloat)q->state()->opacity); - shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::PatternColor), col); - } - - glDrawArrays(GL_TRIANGLES, 0, 6 * fragmentCount); -} - -bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) -{ - Q_D(QGL2PaintEngineEx); - -// qDebug("QGL2PaintEngineEx::begin()"); - if (pdev->devType() == QInternal::OpenGL) - d->device = static_cast<QGLPaintDevice*>(pdev); - else - d->device = QGLPaintDevice::getDevice(pdev); - - if (!d->device) - return false; - - d->ctx = d->device->context(); - d->ctx->d_ptr->active_engine = this; - - d->resetOpenGLContextActiveEngine(); - - const QSize sz = d->device->size(); - d->width = sz.width(); - d->height = sz.height(); - d->mode = BrushDrawingMode; - d->brushTextureDirty = true; - d->brushUniformsDirty = true; - d->matrixUniformDirty = true; - d->matrixDirty = true; - d->compositionModeDirty = true; - d->opacityUniformDirty = true; - d->translateZUniformDirty = true; - d->needsSync = true; - d->useSystemClip = !systemClip().isEmpty(); - d->currentBrush = QBrush(); - - d->dirtyStencilRegion = QRect(0, 0, d->width, d->height); - d->stencilClean = true; - - // Calling begin paint should make the correct context current. So, any - // code which calls into GL or otherwise needs a current context *must* - // go after beginPaint: - d->device->beginPaint(); - - d->initializeOpenGLFunctions(); - - d->shaderManager = new QGLEngineShaderManager(d->ctx); - - d->glDisable(GL_STENCIL_TEST); - d->glDisable(GL_DEPTH_TEST); - d->glDisable(GL_SCISSOR_TEST); - -#if !defined(QT_OPENGL_ES_2) - if (!d->ctx->contextHandle()->isOpenGLES()) - d->glDisable(GL_MULTISAMPLE); -#endif - - d->glyphCacheFormat = QFontEngine::Format_A8; - -#if !defined(QT_OPENGL_ES_2) - if (!d->ctx->contextHandle()->isOpenGLES()) { - d->glyphCacheFormat = QFontEngine::Format_A32; - 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(); -#endif - - return true; -} - -bool QGL2PaintEngineEx::end() -{ - Q_D(QGL2PaintEngineEx); - - QGLContext *ctx = d->ctx; - d->glUseProgram(0); - d->transferMode(BrushDrawingMode); - d->device->endPaint(); - - ctx->d_ptr->active_engine = 0; - ctx->makeCurrent(); - d->resetOpenGLContextActiveEngine(); - d->resetGLState(); - - delete d->shaderManager; - d->shaderManager = 0; - d->currentBrush = QBrush(); - -#ifdef QT_OPENGL_CACHE_AS_VBOS - if (!d->unusedVBOSToClean.isEmpty()) { - d->glDeleteBuffers(d->unusedVBOSToClean.size(), d->unusedVBOSToClean.constData()); - d->unusedVBOSToClean.clear(); - } - if (!d->unusedIBOSToClean.isEmpty()) { - d->glDeleteBuffers(d->unusedIBOSToClean.size(), d->unusedIBOSToClean.constData()); - d->unusedIBOSToClean.clear(); - } -#endif - - return false; -} - -void QGL2PaintEngineEx::ensureActive() -{ - Q_D(QGL2PaintEngineEx); - QGLContext *ctx = d->ctx; - - if (isActive() && (ctx->d_ptr->active_engine != this || d->resetOpenGLContextActiveEngine())) { - ctx->d_ptr->active_engine = this; - d->needsSync = true; - } - - d->device->ensureActiveTarget(); - - if (d->needsSync) { - d->transferMode(BrushDrawingMode); - d->glViewport(0, 0, d->width, d->height); - d->needsSync = false; - d->lastMaskTextureUsed = 0; - d->shaderManager->setDirty(); - d->ctx->d_func()->syncGlState(); - for (int i = 0; i < 3; ++i) - d->vertexAttribPointers[i] = (GLfloat*)-1; // Assume the pointers are clobbered - setState(state()); - } -} - -void QGL2PaintEngineExPrivate::updateClipScissorTest() -{ - Q_Q(QGL2PaintEngineEx); - if (q->state()->clipTestEnabled) { - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); - } else { - glDisable(GL_STENCIL_TEST); - glStencilFunc(GL_ALWAYS, 0, 0xff); - } - -#ifdef QT_GL_NO_SCISSOR_TEST - currentScissorBounds = QRect(0, 0, width, height); -#else - QRect bounds = q->state()->rectangleClip; - if (!q->state()->clipEnabled) { - if (useSystemClip) - bounds = systemClip.boundingRect(); - else - bounds = QRect(0, 0, width, height); - } else { - if (useSystemClip) - bounds = bounds.intersected(systemClip.boundingRect()); - else - bounds = bounds.intersected(QRect(0, 0, width, height)); - } - - currentScissorBounds = bounds; - - if (bounds == QRect(0, 0, width, height)) { - glDisable(GL_SCISSOR_TEST); - } else { - glEnable(GL_SCISSOR_TEST); - setScissor(bounds); - } -#endif -} - -void QGL2PaintEngineExPrivate::setScissor(const QRect &rect) -{ - const int left = rect.left(); - const int width = rect.width(); - int bottom = height - (rect.top() + rect.height()); - if (device->isFlipped()) { - bottom = rect.top(); - } - const int height = rect.height(); - - glScissor(left, bottom, width, height); -} - -void QGL2PaintEngineEx::clipEnabledChanged() -{ - Q_D(QGL2PaintEngineEx); - - state()->clipChanged = true; - - if (painter()->hasClipping()) - d->regenerateClip(); - else - d->systemStateChanged(); -} - -void QGL2PaintEngineExPrivate::clearClip(uint value) -{ - dirtyStencilRegion -= currentScissorBounds; - - glStencilMask(0xff); - glClearStencil(value); - glClear(GL_STENCIL_BUFFER_BIT); - glStencilMask(0x0); - - q->state()->needsClipBufferClear = false; -} - -void QGL2PaintEngineExPrivate::writeClip(const QVectorPath &path, uint value) -{ - transferMode(BrushDrawingMode); - - if (snapToPixelGrid) { - snapToPixelGrid = false; - matrixDirty = true; - } - - if (matrixDirty) - updateMatrix(); - - stencilClean = false; - - const bool singlePass = !path.hasWindingFill() - && (((q->state()->currentClip == maxClip - 1) && q->state()->clipTestEnabled) - || q->state()->needsClipBufferClear); - const uint referenceClipValue = q->state()->needsClipBufferClear ? 1 : q->state()->currentClip; - - if (q->state()->needsClipBufferClear) - clearClip(1); - - if (path.isEmpty()) { - glEnable(GL_STENCIL_TEST); - glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT); - return; - } - - if (q->state()->clipTestEnabled) - glStencilFunc(GL_LEQUAL, q->state()->currentClip, ~GL_STENCIL_HIGH_BIT); - else - glStencilFunc(GL_ALWAYS, 0, 0xff); - - vertexCoordinateArray.clear(); - vertexCoordinateArray.addPath(path, inverseScale, false); - - if (!singlePass) - fillStencilWithVertexArray(vertexCoordinateArray, path.hasWindingFill()); - - glColorMask(false, false, false, false); - glEnable(GL_STENCIL_TEST); - useSimpleShader(); - - if (singlePass) { - // Under these conditions we can set the new stencil value in a single - // pass, by using the current value and the "new value" as the toggles - - glStencilFunc(GL_LEQUAL, referenceClipValue, ~GL_STENCIL_HIGH_BIT); - glStencilOp(GL_KEEP, GL_INVERT, GL_INVERT); - glStencilMask(value ^ referenceClipValue); - - drawVertexArrays(vertexCoordinateArray, GL_TRIANGLE_FAN); - } else { - glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE); - glStencilMask(0xff); - - if (!q->state()->clipTestEnabled && path.hasWindingFill()) { - // Pass when any clip bit is set, set high bit - glStencilFunc(GL_NOTEQUAL, GL_STENCIL_HIGH_BIT, ~GL_STENCIL_HIGH_BIT); - composite(vertexCoordinateArray.boundingRect()); - } - - // Pass when high bit is set, replace stencil value with new clip value - glStencilFunc(GL_NOTEQUAL, value, GL_STENCIL_HIGH_BIT); - - composite(vertexCoordinateArray.boundingRect()); - } - - glStencilFunc(GL_LEQUAL, value, ~GL_STENCIL_HIGH_BIT); - glStencilMask(0); - - glColorMask(true, true, true, true); -} - -void QGL2PaintEngineEx::clip(const QVectorPath &path, Qt::ClipOperation op) -{ -// qDebug("QGL2PaintEngineEx::clip()"); - Q_D(QGL2PaintEngineEx); - - state()->clipChanged = true; - - ensureActive(); - - if (op == Qt::ReplaceClip) { - op = Qt::IntersectClip; - if (d->hasClipOperations()) { - d->systemStateChanged(); - state()->canRestoreClip = false; - } - } - -#ifndef QT_GL_NO_SCISSOR_TEST - if (!path.isEmpty() && op == Qt::IntersectClip && (path.shape() == QVectorPath::RectangleHint)) { - const QPointF* const points = reinterpret_cast<const QPointF*>(path.points()); - QRectF rect(points[0], points[2]); - - if (state()->matrix.type() <= QTransform::TxScale - || (state()->matrix.type() == QTransform::TxRotate - && qFuzzyIsNull(state()->matrix.m11()) - && qFuzzyIsNull(state()->matrix.m22()))) - { - state()->rectangleClip = state()->rectangleClip.intersected(state()->matrix.mapRect(rect).toRect()); - d->updateClipScissorTest(); - return; - } - } -#endif - - const QRect pathRect = state()->matrix.mapRect(path.controlPointRect()).toAlignedRect(); - - switch (op) { - case Qt::NoClip: - if (d->useSystemClip) { - state()->clipTestEnabled = true; - state()->currentClip = 1; - } else { - state()->clipTestEnabled = false; - } - state()->rectangleClip = QRect(0, 0, d->width, d->height); - state()->canRestoreClip = false; - d->updateClipScissorTest(); - break; - case Qt::IntersectClip: - state()->rectangleClip = state()->rectangleClip.intersected(pathRect); - d->updateClipScissorTest(); - d->resetClipIfNeeded(); - ++d->maxClip; - d->writeClip(path, d->maxClip); - state()->currentClip = d->maxClip; - state()->clipTestEnabled = true; - break; - default: - break; - } -} - -void QGL2PaintEngineExPrivate::regenerateClip() -{ - systemStateChanged(); - replayClipOperations(); -} - -void QGL2PaintEngineExPrivate::systemStateChanged() -{ - Q_Q(QGL2PaintEngineEx); - - q->state()->clipChanged = true; - - if (systemClip.isEmpty()) { - useSystemClip = false; - } else { - if (q->paintDevice()->devType() == QInternal::Widget && currentClipDevice) { - QWidgetPrivate *widgetPrivate = qt_widget_private(static_cast<QWidget *>(currentClipDevice)->window()); - useSystemClip = widgetPrivate->extra && widgetPrivate->extra->inRenderWithPainter; - } else { - useSystemClip = true; - } - } - - q->state()->clipTestEnabled = false; - q->state()->needsClipBufferClear = true; - - q->state()->currentClip = 1; - maxClip = 1; - - q->state()->rectangleClip = useSystemClip ? systemClip.boundingRect() : QRect(0, 0, width, height); - updateClipScissorTest(); - - if (systemClip.rectCount() == 1) { - if (systemClip.boundingRect() == QRect(0, 0, width, height)) - useSystemClip = false; -#ifndef QT_GL_NO_SCISSOR_TEST - // scissoring takes care of the system clip - return; -#endif - } - - if (useSystemClip) { - clearClip(0); - - QPainterPath path; - path.addRegion(systemClip); - - q->state()->currentClip = 0; - writeClip(qtVectorPathForPath(q->state()->matrix.inverted().map(path)), 1); - q->state()->currentClip = 1; - q->state()->clipTestEnabled = true; - } -} - -void QGL2PaintEngineEx::setTranslateZ(GLfloat z) -{ - Q_D(QGL2PaintEngineEx); - if (d->translateZ != z) { - d->translateZ = z; - d->translateZUniformDirty = true; - } -} - -void QGL2PaintEngineEx::setState(QPainterState *new_state) -{ - // qDebug("QGL2PaintEngineEx::setState()"); - - Q_D(QGL2PaintEngineEx); - - QGL2PaintEngineState *s = static_cast<QGL2PaintEngineState *>(new_state); - QGL2PaintEngineState *old_state = state(); - - QPaintEngineEx::setState(s); - - if (s->isNew) { - // Newly created state object. The call to setState() - // will either be followed by a call to begin(), or we are - // setting the state as part of a save(). - s->isNew = false; - return; - } - - // Setting the state as part of a restore(). - - if (old_state == s || old_state->renderHintsChanged) - renderHintsChanged(); - - if (old_state == s || old_state->matrixChanged) - d->matrixDirty = true; - - if (old_state == s || old_state->compositionModeChanged) - d->compositionModeDirty = true; - - if (old_state == s || old_state->opacityChanged) - d->opacityUniformDirty = true; - - if (old_state == s || old_state->clipChanged) { - if (old_state && old_state != s && old_state->canRestoreClip) { - d->updateClipScissorTest(); - d->glDepthFunc(GL_LEQUAL); - } else { - d->regenerateClip(); - } - } -} - -QPainterState *QGL2PaintEngineEx::createState(QPainterState *orig) const -{ - if (orig) - const_cast<QGL2PaintEngineEx *>(this)->ensureActive(); - - QGL2PaintEngineState *s; - if (!orig) - s = new QGL2PaintEngineState(); - else - s = new QGL2PaintEngineState(*static_cast<QGL2PaintEngineState *>(orig)); - - s->matrixChanged = false; - s->compositionModeChanged = false; - s->opacityChanged = false; - s->renderHintsChanged = false; - s->clipChanged = false; - - return s; -} - -QGL2PaintEngineState::QGL2PaintEngineState(QGL2PaintEngineState &other) - : QPainterState(other) -{ - isNew = true; - needsClipBufferClear = other.needsClipBufferClear; - clipTestEnabled = other.clipTestEnabled; - currentClip = other.currentClip; - canRestoreClip = other.canRestoreClip; - rectangleClip = other.rectangleClip; -} - -QGL2PaintEngineState::QGL2PaintEngineState() -{ - isNew = true; - needsClipBufferClear = true; - clipTestEnabled = false; - canRestoreClip = true; -} - -QGL2PaintEngineState::~QGL2PaintEngineState() -{ -} - -QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h deleted file mode 100644 index 762aac2f65..0000000000 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ /dev/null @@ -1,334 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPAINTENGINEEX_OPENGL2_P_H -#define QPAINTENGINEEX_OPENGL2_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QDebug> - -#include <private/qpaintengineex_p.h> -#include <private/qglengineshadermanager_p.h> -#include <private/qgl2pexvertexarray_p.h> -#include <private/qglpaintdevice_p.h> -#include <private/qfontengine_p.h> -#include <private/qdatabuffer_p.h> -#include <private/qtriangulatingstroker_p.h> -#include <private/qopenglextensions_p.h> - -enum EngineMode { - ImageDrawingMode, - TextDrawingMode, - BrushDrawingMode, - ImageArrayDrawingMode -}; - -QT_BEGIN_NAMESPACE - -#define GL_STENCIL_HIGH_BIT GLuint(0x80) -#define QT_BRUSH_TEXTURE_UNIT GLuint(0) -#define QT_IMAGE_TEXTURE_UNIT GLuint(0) //Can be the same as brush texture unit -#define QT_MASK_TEXTURE_UNIT GLuint(1) -#define QT_BACKGROUND_TEXTURE_UNIT GLuint(2) - -class QGL2PaintEngineExPrivate; - - -class QGL2PaintEngineState : public QPainterState -{ -public: - QGL2PaintEngineState(QGL2PaintEngineState &other); - QGL2PaintEngineState(); - ~QGL2PaintEngineState(); - - uint isNew : 1; - uint needsClipBufferClear : 1; - uint clipTestEnabled : 1; - uint canRestoreClip : 1; - uint matrixChanged : 1; - uint compositionModeChanged : 1; - uint opacityChanged : 1; - uint renderHintsChanged : 1; - uint clipChanged : 1; - uint currentClip : 8; - - QRect rectangleClip; -}; - -class Q_OPENGL_EXPORT QGL2PaintEngineEx : public QPaintEngineEx -{ - Q_DECLARE_PRIVATE(QGL2PaintEngineEx) -public: - QGL2PaintEngineEx(); - ~QGL2PaintEngineEx(); - - bool begin(QPaintDevice *device) override; - void ensureActive(); - bool end() override; - - virtual void clipEnabledChanged() override; - virtual void penChanged() override; - virtual void brushChanged() override; - virtual void brushOriginChanged() override; - virtual void opacityChanged() override; - virtual void compositionModeChanged() override; - virtual void renderHintsChanged() override; - virtual void transformChanged() override; - - virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override; - virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, - QPainter::PixmapFragmentHints hints) override; - virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, - Qt::ImageConversionFlags flags = Qt::AutoColor) override; - virtual void drawTextItem(const QPointF &p, const QTextItem &textItem) override; - virtual void fill(const QVectorPath &path, const QBrush &brush) override; - virtual void stroke(const QVectorPath &path, const QPen &pen) override; - virtual void clip(const QVectorPath &path, Qt::ClipOperation op) override; - - virtual void drawStaticTextItem(QStaticTextItem *textItem) override; - - bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr); - - Type type() const override { return OpenGL2; } - - virtual void setState(QPainterState *s) override; - virtual QPainterState *createState(QPainterState *orig) const override; - inline QGL2PaintEngineState *state() { - return static_cast<QGL2PaintEngineState *>(QPaintEngineEx::state()); - } - inline const QGL2PaintEngineState *state() const { - return static_cast<const QGL2PaintEngineState *>(QPaintEngineEx::state()); - } - - void beginNativePainting() override; - void endNativePainting() override; - - void invalidateState(); - - void setRenderTextActive(bool); - - bool isNativePaintingActive() const; - bool requiresPretransformedGlyphPositions(QFontEngine *, const QTransform &) const override { return false; } - bool shouldDrawCachedGlyphs(QFontEngine *, const QTransform &) const override; - - void setTranslateZ(GLfloat z); - -private: - Q_DISABLE_COPY_MOVE(QGL2PaintEngineEx) -}; - -class QGL2PaintEngineExPrivate : public QPaintEngineExPrivate, protected QOpenGLExtensions -{ - Q_DECLARE_PUBLIC(QGL2PaintEngineEx) -public: - enum StencilFillMode { - OddEvenFillMode, - WindingFillMode, - TriStripStrokeFillMode - }; - - QGL2PaintEngineExPrivate(QGL2PaintEngineEx *q_ptr) : - q(q_ptr), - shaderManager(nullptr), - width(0), height(0), - ctx(nullptr), - useSystemClip(true), - elementIndicesVBOId(0), - opacityArray(0), - snapToPixelGrid(false), - nativePaintingActive(false), - inverseScale(1), - lastMaskTextureUsed(0), - translateZ(0) - { } - - ~QGL2PaintEngineExPrivate(); - - void updateBrushTexture(); - void updateBrushUniforms(); - void updateMatrix(); - void updateCompositionMode(); - void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1)); - - void resetGLState(); - bool resetOpenGLContextActiveEngine(); - - // fill, stroke, drawTexture, drawPixmaps & drawCachedGlyphs are the main rendering entry-points, - // however writeClip can also be thought of as en entry point as it does similar things. - void fill(const QVectorPath &path); - void stroke(const QVectorPath &path, const QPen &pen); - void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); - void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, - QPainter::PixmapFragmentHints hints); - void drawCachedGlyphs(QFontEngine::GlyphFormat glyphFormat, QStaticTextItem *staticTextItem); - - // Calls glVertexAttributePointer if the pointer has changed - inline void setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer); - - // draws whatever is in the vertex array: - void drawVertexArrays(const float *data, int *stops, int stopCount, GLenum primitive); - void drawVertexArrays(QGL2PEXVertexArray &vertexArray, GLenum primitive) { - drawVertexArrays((const float *) vertexArray.data(), vertexArray.stops(), vertexArray.stopCount(), primitive); - } - - // Composites the bounding rect onto dest buffer: - void composite(const QGLRect& boundingRect); - - // Calls drawVertexArrays to render into stencil buffer: - void fillStencilWithVertexArray(const float *data, int count, int *stops, int stopCount, const QGLRect &bounds, StencilFillMode mode); - void fillStencilWithVertexArray(QGL2PEXVertexArray& vertexArray, bool useWindingFill) { - fillStencilWithVertexArray((const float *) vertexArray.data(), 0, vertexArray.stops(), vertexArray.stopCount(), - vertexArray.boundingRect(), - useWindingFill ? WindingFillMode : OddEvenFillMode); - } - - void setBrush(const QBrush& brush); - void transferMode(EngineMode newMode); - bool prepareForDraw(bool srcPixelsAreOpaque); // returns true if the program has changed - bool prepareForCachedGlyphDraw(const QFontEngineGlyphCache &cache); - inline void useSimpleShader(); - inline GLuint location(const QGLEngineShaderManager::Uniform uniform) { - return shaderManager->getUniformLocation(uniform); - } - - void clearClip(uint value); - void writeClip(const QVectorPath &path, uint value); - void resetClipIfNeeded(); - - void updateClipScissorTest(); - void setScissor(const QRect &rect); - void regenerateClip(); - void systemStateChanged() override; - - - static QGLEngineShaderManager* shaderManagerForEngine(QGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; } - static QGL2PaintEngineExPrivate *getData(QGL2PaintEngineEx *engine) { return engine->d_func(); } - static void cleanupVectorPath(QPaintEngineEx *engine, void *data); - - - QGL2PaintEngineEx* q; - QGLEngineShaderManager* shaderManager; - QGLPaintDevice* device; - int width, height; - QGLContext *ctx; - EngineMode mode; - QFontEngine::GlyphFormat glyphCacheFormat; - - // Dirty flags - bool matrixDirty; // Implies matrix uniforms are also dirty - bool compositionModeDirty; - bool brushTextureDirty; - bool brushUniformsDirty; - bool opacityUniformDirty; - bool matrixUniformDirty; - bool translateZUniformDirty; - - bool stencilClean; // Has the stencil not been used for clipping so far? - bool useSystemClip; - QRegion dirtyStencilRegion; - QRect currentScissorBounds; - uint maxClip; - - QBrush currentBrush; // May not be the state's brush! - const QBrush noBrush; - - QPixmap currentBrushPixmap; - - QGL2PEXVertexArray vertexCoordinateArray; - QGL2PEXVertexArray textureCoordinateArray; - QVector<GLushort> elementIndices; - GLuint elementIndicesVBOId; - QDataBuffer<GLfloat> opacityArray; - GLfloat staticVertexCoordinateArray[8]; - GLfloat staticTextureCoordinateArray[8]; - - bool snapToPixelGrid; - bool nativePaintingActive; - GLfloat pmvMatrix[3][3]; - GLfloat inverseScale; - - GLuint lastTextureUsed; - GLuint lastMaskTextureUsed; - - bool needsSync; - bool multisamplingAlwaysEnabled; - - GLfloat depthRange[2]; - - float textureInvertedY; - - QTriangulatingStroker stroker; - QDashedStrokeProcessor dasher; - - QSet<QVectorPath::CacheEntry *> pathCaches; - QVector<GLuint> unusedVBOSToClean; - QVector<GLuint> unusedIBOSToClean; - - const GLfloat *vertexAttribPointers[3]; - - GLfloat translateZ; -}; - - -void QGL2PaintEngineExPrivate::setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer) -{ - Q_ASSERT(arrayIndex < 3); - if (pointer == vertexAttribPointers[arrayIndex]) - return; - - vertexAttribPointers[arrayIndex] = pointer; - if (arrayIndex == QT_OPACITY_ATTR) - glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, pointer); - else - glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, pointer); -} - -QT_END_NAMESPACE - -#endif // QPAINTENGINEEX_OPENGL2_P_H diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp deleted file mode 100644 index d5ce4efd1a..0000000000 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ /dev/null @@ -1,414 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtextureglyphcache_gl_p.h" -#include "qpaintengineex_opengl2_p.h" -#include "qglfunctions.h" -#include "private/qglengineshadersource_p.h" - -QT_BEGIN_NAMESPACE - - -static int next_qgltextureglyphcache_serial_number() -{ - static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); - return 1 + serial.fetchAndAddRelaxed(1); -} - -QGLTextureGlyphCache::QGLTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix) - : QImageTextureGlyphCache(format, matrix) - , m_textureResource(0) - , pex(0) - , m_blitProgram(0) - , m_filterMode(Nearest) - , m_serialNumber(next_qgltextureglyphcache_serial_number()) -{ -#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG - qDebug(" -> QGLTextureGlyphCache() %p for context %p.", this, QOpenGLContext::currentContext()); -#endif - m_vertexCoordinateArray[0] = -1.0f; - m_vertexCoordinateArray[1] = -1.0f; - m_vertexCoordinateArray[2] = 1.0f; - m_vertexCoordinateArray[3] = -1.0f; - m_vertexCoordinateArray[4] = 1.0f; - m_vertexCoordinateArray[5] = 1.0f; - m_vertexCoordinateArray[6] = -1.0f; - m_vertexCoordinateArray[7] = 1.0f; - - m_textureCoordinateArray[0] = 0.0f; - m_textureCoordinateArray[1] = 0.0f; - m_textureCoordinateArray[2] = 1.0f; - m_textureCoordinateArray[3] = 0.0f; - m_textureCoordinateArray[4] = 1.0f; - m_textureCoordinateArray[5] = 1.0f; - m_textureCoordinateArray[6] = 0.0f; - m_textureCoordinateArray[7] = 1.0f; -} - -QGLTextureGlyphCache::~QGLTextureGlyphCache() -{ -#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG - qDebug(" -> ~QGLTextureGlyphCache() %p.", this); -#endif - delete m_blitProgram; - if (m_textureResource) - m_textureResource->free(); -} - -void QGLTextureGlyphCache::createTextureData(int width, int height) -{ - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); - if (ctx == 0) { - qWarning("QGLTextureGlyphCache::createTextureData: Called with no context"); - return; - } - QOpenGLFunctions *funcs = ctx->contextHandle()->functions(); - - // create in QImageTextureGlyphCache baseclass is meant to be called - // only to create the initial image and does not preserve the content, - // so we don't call when this function is called from resize. - if ((!QGLFramebufferObject::hasOpenGLFramebufferObjects() || ctx->d_ptr->workaround_brokenFBOReadBack) && image().isNull()) - QImageTextureGlyphCache::createTextureData(width, height); - - // Make the lower glyph texture size 16 x 16. - if (width < 16) - width = 16; - if (height < 16) - height = 16; - - if (m_textureResource && !m_textureResource->m_texture) { - delete m_textureResource; - m_textureResource = 0; - } - - if (!m_textureResource) - m_textureResource = new QGLGlyphTexture(ctx); - - funcs->glGenTextures(1, &m_textureResource->m_texture); - funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - - m_textureResource->m_width = width; - m_textureResource->m_height = height; - - if (m_format == QFontEngine::Format_A32) { - QVarLengthArray<uchar> data(width * height * 4); - for (int i = 0; i < data.size(); ++i) - data[i] = 0; - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); - } else { - QVarLengthArray<uchar> data(width * height); - for (int i = 0; i < data.size(); ++i) - data[i] = 0; - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, &data[0]); - } - - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - m_filterMode = Nearest; -} - -void QGLTextureGlyphCache::resizeTextureData(int width, int height) -{ - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); - if (ctx == 0) { - qWarning("QGLTextureGlyphCache::resizeTextureData: Called with no context"); - return; - } - QOpenGLFunctions *funcs = ctx->contextHandle()->functions(); - - int oldWidth = m_textureResource->m_width; - int oldHeight = m_textureResource->m_height; - - // Make the lower glyph texture size 16 x 16. - if (width < 16) - width = 16; - if (height < 16) - height = 16; - - GLuint oldTexture = m_textureResource->m_texture; - createTextureData(width, height); - - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects() || ctx->d_ptr->workaround_brokenFBOReadBack) { - QImageTextureGlyphCache::resizeTextureData(width, height); - Q_ASSERT(image().depth() == 8); - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); - funcs->glDeleteTextures(1, &oldTexture); - return; - } - - // ### the QTextureGlyphCache API needs to be reworked to allow - // ### resizeTextureData to fail - - ctx->d_ptr->refreshCurrentFbo(); - - funcs->glBindFramebuffer(GL_FRAMEBUFFER, m_textureResource->m_fbo); - - GLuint tmp_texture; - funcs->glGenTextures(1, &tmp_texture); - funcs->glBindTexture(GL_TEXTURE_2D, tmp_texture); - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, oldWidth, oldHeight, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - m_filterMode = Nearest; - funcs->glBindTexture(GL_TEXTURE_2D, 0); - funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, tmp_texture, 0); - - funcs->glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - funcs->glBindTexture(GL_TEXTURE_2D, oldTexture); - - if (pex != 0) - pex->transferMode(BrushDrawingMode); - - funcs->glDisable(GL_STENCIL_TEST); - funcs->glDisable(GL_DEPTH_TEST); - funcs->glDisable(GL_SCISSOR_TEST); - funcs->glDisable(GL_BLEND); - - funcs->glViewport(0, 0, oldWidth, oldHeight); - - QGLShaderProgram *blitProgram = 0; - if (pex == 0) { - if (m_blitProgram == 0) { - m_blitProgram = new QGLShaderProgram(ctx); - - { - QString source; - source.append(QLatin1String(qglslMainWithTexCoordsVertexShader)); - source.append(QLatin1String(qglslUntransformedPositionVertexShader)); - - QGLShader *vertexShader = new QGLShader(QGLShader::Vertex, m_blitProgram); - vertexShader->compileSourceCode(source); - - m_blitProgram->addShader(vertexShader); - } - - { - QString source; - source.append(QLatin1String(qglslMainFragmentShader)); - source.append(QLatin1String(qglslImageSrcFragmentShader)); - - QGLShader *fragmentShader = new QGLShader(QGLShader::Fragment, m_blitProgram); - fragmentShader->compileSourceCode(source); - - m_blitProgram->addShader(fragmentShader); - } - - m_blitProgram->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); - m_blitProgram->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); - - m_blitProgram->link(); - } - - funcs->glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_vertexCoordinateArray); - funcs->glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, m_textureCoordinateArray); - - m_blitProgram->bind(); - m_blitProgram->enableAttributeArray(int(QT_VERTEX_COORDS_ATTR)); - m_blitProgram->enableAttributeArray(int(QT_TEXTURE_COORDS_ATTR)); - m_blitProgram->disableAttributeArray(int(QT_OPACITY_ATTR)); - - blitProgram = m_blitProgram; - - } else { - pex->setVertexAttributePointer(QT_VERTEX_COORDS_ATTR, m_vertexCoordinateArray); - pex->setVertexAttributePointer(QT_TEXTURE_COORDS_ATTR, m_textureCoordinateArray); - - pex->shaderManager->useBlitProgram(); - blitProgram = pex->shaderManager->blitProgram(); - } - - blitProgram->setUniformValue("imageTexture", QT_IMAGE_TEXTURE_UNIT); - - funcs->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - - funcs->glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, oldWidth, oldHeight); - - funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, 0); - funcs->glDeleteTextures(1, &tmp_texture); - funcs->glDeleteTextures(1, &oldTexture); - - funcs->glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo); - - if (pex != 0) { - funcs->glViewport(0, 0, pex->width, pex->height); - pex->updateClipScissorTest(); - } -} - -void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) -{ - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); - if (ctx == 0) { - qWarning("QGLTextureGlyphCache::fillTexture: Called with no context"); - return; - } - QOpenGLFunctions *funcs = ctx->contextHandle()->functions(); - - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects() || ctx->d_ptr->workaround_brokenFBOReadBack) { - QImageTextureGlyphCache::fillTexture(c, glyph, subPixelPosition); - - funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - const QImage &texture = image(); - const uchar *bits = texture.constBits(); - bits += c.y * texture.bytesPerLine() + c.x; - for (int i=0; i<c.h; ++i) { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, c.w, 1, GL_ALPHA, GL_UNSIGNED_BYTE, bits); - bits += texture.bytesPerLine(); - } - return; - } - - QImage mask = textureMapForGlyph(glyph, subPixelPosition); - const int maskWidth = mask.width(); - const int maskHeight = mask.height(); - - if (mask.format() == QImage::Format_Mono) { - mask = mask.convertToFormat(QImage::Format_Indexed8); - for (int y = 0; y < maskHeight; ++y) { - uchar *src = (uchar *) mask.scanLine(y); - for (int x = 0; x < maskWidth; ++x) - src[x] = -src[x]; // convert 0 and 1 into 0 and 255 - } - } else if (mask.depth() == 32) { - // Make the alpha component equal to the average of the RGB values. - // This is needed when drawing sub-pixel antialiased text on translucent targets. - for (int y = 0; y < maskHeight; ++y) { - quint32 *src = (quint32 *) mask.scanLine(y); - for (int x = 0; x < maskWidth; ++x) { - int r = qRed(src[x]); - int g = qGreen(src[x]); - int b = qBlue(src[x]); - int avg; - if (mask.format() == QImage::Format_RGB32) - avg = (r + g + b + 1) / 3; // "+1" for rounding. - else // Format_ARGB_Premultiplied - avg = qAlpha(src[x]); - if (ctx->contextHandle()->isOpenGLES()) { - // swizzle the bits to accommodate for the GL_RGBA upload. - src[x] = (avg << 24) | (r << 0) | (g << 8) | (b << 16); - } else { - src[x] = (src[x] & 0x00ffffff) | (avg << 24); - } - } - } - } - - funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - if (mask.depth() == 32) { - GLenum format = GL_RGBA; -#if !defined(QT_OPENGL_ES_2) - if (!ctx->contextHandle()->isOpenGLES()) - format = GL_BGRA; -#endif - funcs->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 - // and nVidia GeForce 8500GT. GL_UNPACK_ALIGNMENT is set to four bytes, 'mask' has a - // multiple of four bytes per line, and most of the glyph shows up correctly in the - // texture, which makes me think that this is a driver bug. - // One workaround is to make sure the mask width is a multiple of four bytes, for instance - // by converting it to a format with four bytes per pixel. Another is to copy one line at a - // time. - - if (!ctx->d_ptr->workaround_brokenAlphaTexSubImage_init) { - // don't know which driver versions exhibit this bug, so be conservative for now - const QByteArray vendorString(reinterpret_cast<const char*>(funcs->glGetString(GL_VENDOR))); - ctx->d_ptr->workaround_brokenAlphaTexSubImage = vendorString.indexOf("NVIDIA") >= 0; - ctx->d_ptr->workaround_brokenAlphaTexSubImage_init = true; - } - - if (ctx->d_ptr->workaround_brokenAlphaTexSubImage) { - for (int i = 0; i < maskHeight; ++i) - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y + i, maskWidth, 1, GL_ALPHA, GL_UNSIGNED_BYTE, mask.scanLine(i)); - } else { - funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, c.x, c.y, maskWidth, maskHeight, GL_ALPHA, GL_UNSIGNED_BYTE, mask.bits()); - } - } -} - -int QGLTextureGlyphCache::glyphPadding() const -{ - return 1; -} - -int QGLTextureGlyphCache::maxTextureWidth() const -{ - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); - if (ctx == 0) - return QImageTextureGlyphCache::maxTextureWidth(); - else - return ctx->d_ptr->maxTextureSize(); -} - -int QGLTextureGlyphCache::maxTextureHeight() const -{ - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); - if (ctx == 0) - return QImageTextureGlyphCache::maxTextureHeight(); - - if (ctx->d_ptr->workaround_brokenTexSubImage) - return qMin(1024, ctx->d_ptr->maxTextureSize()); - else - return ctx->d_ptr->maxTextureSize(); -} - -void QGLTextureGlyphCache::clear() -{ - m_textureResource->free(); - m_textureResource = 0; - - m_w = 0; - m_h = 0; - m_cx = 0; - m_cy = 0; - m_currentRowHeight = 0; - coords.clear(); -} - -QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h deleted file mode 100644 index 7c12ce8998..0000000000 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTEXTUREGLYPHCACHE_GL_P_H -#define QTEXTUREGLYPHCACHE_GL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qtextureglyphcache_p.h> -#include <private/qgl_p.h> -#include <qglshaderprogram.h> -#include <qglframebufferobject.h> -#include <qopenglfunctions.h> - -// #define QT_GL_TEXTURE_GLYPH_CACHE_DEBUG - -QT_BEGIN_NAMESPACE - -class QGL2PaintEngineExPrivate; - -struct QGLGlyphTexture : public QOpenGLSharedResource -{ - QGLGlyphTexture(const QGLContext *ctx) - : QOpenGLSharedResource(ctx->contextHandle()->shareGroup()) - , m_fbo(0) - , m_width(0) - , m_height(0) - { - if (ctx && QGLFramebufferObject::hasOpenGLFramebufferObjects() && !ctx->d_ptr->workaround_brokenFBOReadBack) - ctx->contextHandle()->functions()->glGenFramebuffers(1, &m_fbo); - -#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG - qDebug(" -> QGLGlyphTexture() %p for context %p.", this, ctx); -#endif - } - - void freeResource(QOpenGLContext *context) override - { - const QGLContext *ctx = QGLContext::fromOpenGLContext(context); -#ifdef QT_GL_TEXTURE_GLYPH_CACHE_DEBUG - qDebug("~QGLGlyphTexture() %p for context %p.", this, ctx); -#else - Q_UNUSED(ctx); -#endif - if (ctx && m_fbo) - ctx->contextHandle()->functions()->glDeleteFramebuffers(1, &m_fbo); - if (m_width || m_height) - ctx->contextHandle()->functions()->glDeleteTextures(1, &m_texture); - } - - void invalidateResource() override - { - m_texture = 0; - m_fbo = 0; - m_width = 0; - m_height = 0; - } - - GLuint m_texture; - GLuint m_fbo; - int m_width; - int m_height; -}; - -class Q_OPENGL_EXPORT QGLTextureGlyphCache : public QImageTextureGlyphCache -{ -public: - QGLTextureGlyphCache(QFontEngine::GlyphFormat format, const QTransform &matrix); - ~QGLTextureGlyphCache(); - - virtual void createTextureData(int width, int height) override; - virtual void resizeTextureData(int width, int height) override; - virtual void fillTexture(const Coord &c, glyph_t glyph, QFixed subPixelPosition) override; - virtual int glyphPadding() const override; - virtual int maxTextureWidth() const override; - virtual int maxTextureHeight() const override; - - inline GLuint texture() const { - QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this); - QGLGlyphTexture *glyphTexture = that->m_textureResource; - return glyphTexture ? glyphTexture->m_texture : 0; - } - - inline int width() const { - QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this); - QGLGlyphTexture *glyphTexture = that->m_textureResource; - return glyphTexture ? glyphTexture->m_width : 0; - } - inline int height() const { - QGLTextureGlyphCache *that = const_cast<QGLTextureGlyphCache *>(this); - QGLGlyphTexture *glyphTexture = that->m_textureResource; - return glyphTexture ? glyphTexture->m_height : 0; - } - - inline void setPaintEnginePrivate(QGL2PaintEngineExPrivate *p) { pex = p; } - - inline const QOpenGLContextGroup *contextGroup() const { return m_textureResource ? m_textureResource->group() : nullptr; } - - inline int serialNumber() const { return m_serialNumber; } - - enum FilterMode { - Nearest, - Linear - }; - FilterMode filterMode() const { return m_filterMode; } - void setFilterMode(FilterMode m) { m_filterMode = m; } - - void clear(); - -private: - QGLGlyphTexture *m_textureResource; - - QGL2PaintEngineExPrivate *pex; - QGLShaderProgram *m_blitProgram; - FilterMode m_filterMode; - - GLfloat m_vertexCoordinateArray[8]; - GLfloat m_textureCoordinateArray[8]; - - int m_serialNumber; -}; - -QT_END_NAMESPACE - -#endif - diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 8b2349ff2f..811eecaeba 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -1,57 +1,14 @@ TARGET = QtOpenGL -QT = core-private gui-private widgets-private +QT = core-private gui-private DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH -msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x63000000 -solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2 - QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf qtConfig(opengl): CONFIG += opengl qtConfig(opengles2): CONFIG += opengles2 -HEADERS += qgl.h \ - qgl_p.h \ - qglcolormap.h \ - qglfunctions.h \ - qglpixelbuffer.h \ - qglpixelbuffer_p.h \ - qglframebufferobject.h \ - qglframebufferobject_p.h \ - qglpaintdevice_p.h \ - qglbuffer.h \ - qtopenglglobal.h - -SOURCES += qgl.cpp \ - qglcolormap.cpp \ - qglfunctions.cpp \ - qglpixelbuffer.cpp \ - qglframebufferobject.cpp \ - qglpaintdevice.cpp \ - qglbuffer.cpp \ - -HEADERS += qglshaderprogram.h \ - gl2paintengineex/qglgradientcache_p.h \ - gl2paintengineex/qglengineshadermanager_p.h \ - gl2paintengineex/qgl2pexvertexarray_p.h \ - gl2paintengineex/qpaintengineex_opengl2_p.h \ - gl2paintengineex/qglengineshadersource_p.h \ - gl2paintengineex/qglcustomshaderstage_p.h \ - gl2paintengineex/qtextureglyphcache_gl_p.h \ - gl2paintengineex/qglshadercache_p.h - -SOURCES += qglshaderprogram.cpp \ - gl2paintengineex/qglgradientcache.cpp \ - gl2paintengineex/qglengineshadermanager.cpp \ - gl2paintengineex/qgl2pexvertexarray.cpp \ - gl2paintengineex/qpaintengineex_opengl2.cpp \ - gl2paintengineex/qglcustomshaderstage.cpp \ - gl2paintengineex/qtextureglyphcache_gl.cpp - -qtConfig(graphicseffect) { - HEADERS += qgraphicsshadereffect_p.h - SOURCES += qgraphicsshadereffect.cpp -} +HEADERS += \ + qtopenglglobal.h load(qt_module) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp deleted file mode 100644 index 4108b70094..0000000000 --- a/src/opengl/qgl.cpp +++ /dev/null @@ -1,5558 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qapplication.h" -#include "qplatformdefs.h" -#include "qgl.h" -#include <qdebug.h> -#include <qglfunctions.h> - -#include <qdatetime.h> - -#include <stdlib.h> // malloc - -#include "qpixmap.h" -#include "qimage.h" -#include "qgl_p.h" - -#include "gl2paintengineex/qpaintengineex_opengl2_p.h" - -#include <qpa/qplatformopenglcontext.h> - -#include <qglpixelbuffer.h> -#include <qglframebufferobject.h> -#include <private/qopenglextensions_p.h> - -#include <private/qimage_p.h> -#include <qpa/qplatformpixmap.h> -#include <private/qglpixelbuffer_p.h> -#include <private/qimagepixmapcleanuphooks_p.h> -#include "qcolormap.h" -#include "qfile.h" -#include <qmutex.h> - -#include "qsurfaceformat.h" -#include <private/qapplication_p.h> -#include <qpa/qplatformopenglcontext.h> -#include <qpa/qplatformwindow.h> - -#ifndef QT_OPENGL_ES_2 -#include <qopenglfunctions_1_1.h> -#endif - -// #define QT_GL_CONTEXT_RESOURCE_DEBUG - -QT_BEGIN_NAMESPACE - -class QGLDefaultExtensions -{ -public: - QGLDefaultExtensions() - { - QGLTemporaryContext tempContext; - Q_ASSERT(QOpenGLContext::currentContext()); - QOpenGLExtensions *ext = qgl_extensions(); - Q_ASSERT(ext); - extensions = ext->openGLExtensions(); - features = ext->openGLFeatures(); - } - - QOpenGLFunctions::OpenGLFeatures features; - QOpenGLExtensions::OpenGLExtensions extensions; -}; - -Q_GLOBAL_STATIC(QGLDefaultExtensions, qtDefaultExtensions) - -bool qgl_hasFeature(QOpenGLFunctions::OpenGLFeature feature) -{ - if (QOpenGLContext::currentContext()) - return QOpenGLContext::currentContext()->functions()->hasOpenGLFeature(feature); - return qtDefaultExtensions()->features & feature; -} - -bool qgl_hasExtension(QOpenGLExtensions::OpenGLExtension extension) -{ - if (QOpenGLContext::currentContext()) - return qgl_extensions()->hasOpenGLExtension(extension); - return qtDefaultExtensions()->extensions & extension; -} - -QOpenGLExtensions::OpenGLExtensions extensions; - -/* - Returns the GL extensions for the current QOpenGLContext. If there is no - current QOpenGLContext, a default context will be created and the extensions - for that context will be returned instead. -*/ -QOpenGLExtensions* qgl_extensions() -{ - if (QOpenGLContext *context = QOpenGLContext::currentContext()) - return static_cast<QOpenGLExtensions *>(context->functions()); - - Q_ASSERT(false); - return 0; -} - -QOpenGLFunctions *qgl_functions() -{ - return qgl_extensions(); // QOpenGLExtensions is just a subclass of QOpenGLFunctions -} - -#ifndef QT_OPENGL_ES_2 -QOpenGLFunctions_1_1 *qgl1_functions() -{ - QOpenGLFunctions_1_1 *f = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_1_1>(); - f->initializeOpenGLFunctions(); - return f; -} -#endif - -struct QGLThreadContext { - ~QGLThreadContext() { - if (context) - context->doneCurrent(); - } - QGLContext *context; -}; - -Q_GLOBAL_STATIC(QGLFormat, qgl_default_format) - -class QGLDefaultOverlayFormat: public QGLFormat -{ -public: - inline QGLDefaultOverlayFormat() - { - setOption(QGL::FormatOption(0xffffU << 16)); // turn off all options - setOption(QGL::DirectRendering); - setPlane(1); - } -}; -Q_GLOBAL_STATIC(QGLDefaultOverlayFormat, defaultOverlayFormatInstance) - -Q_GLOBAL_STATIC(QGLSignalProxy, theSignalProxy) -QGLSignalProxy *QGLSignalProxy::instance() -{ - QGLSignalProxy *proxy = theSignalProxy(); - if (proxy && qApp && proxy->thread() != qApp->thread()) { - if (proxy->thread() == QThread::currentThread()) - proxy->moveToThread(qApp->thread()); - } - return proxy; -} - - -/*! - \namespace QGL - \inmodule QtOpenGL - - \brief The QGL namespace specifies miscellaneous identifiers used - in the Qt OpenGL module. -*/ - -/*! - \enum QGL::FormatOption - - This enum specifies the format options that can be used to configure an OpenGL - context. These are set using QGLFormat::setOption(). - - \value DoubleBuffer Specifies the use of double buffering. - \value DepthBuffer Enables the use of a depth buffer. - \value Rgba Specifies that the context should use RGBA as its pixel format. - \value AlphaChannel Enables the use of an alpha channel. - \value AccumBuffer Enables the use of an accumulation buffer. - \value StencilBuffer Enables the use of a stencil buffer. - \value StereoBuffers Enables the use of a stereo buffers for use with visualization hardware. - \value DirectRendering Specifies that the context is used for direct rendering to a display. - \value HasOverlay Enables the use of an overlay. - \value SampleBuffers Enables the use of sample buffers. - \value DeprecatedFunctions Enables the use of deprecated functionality for OpenGL 3.x - contexts. A context with deprecated functionality enabled is - called a full context in the OpenGL specification. - \value SingleBuffer Specifies the use of a single buffer, as opposed to double buffers. - \value NoDepthBuffer Disables the use of a depth buffer. - \value ColorIndex Specifies that the context should use a color index as its pixel format. - \value NoAlphaChannel Disables the use of an alpha channel. - \value NoAccumBuffer Disables the use of an accumulation buffer. - \value NoStencilBuffer Disables the use of a stencil buffer. - \value NoStereoBuffers Disables the use of stereo buffers. - \value IndirectRendering Specifies that the context is used for indirect rendering to a buffer. - \value NoOverlay Disables the use of an overlay. - \value NoSampleBuffers Disables the use of sample buffers. - \value NoDeprecatedFunctions Disables the use of deprecated functionality for OpenGL 3.x - contexts. A context with deprecated functionality disabled is - called a forward compatible context in the OpenGL specification. -*/ - -/***************************************************************************** - QGLFormat implementation - *****************************************************************************/ - - -/*! - \class QGLFormat - \inmodule QtOpenGL - \obsolete - - \brief The QGLFormat class specifies the display format of an OpenGL - rendering context. - - A display format has several characteristics: - \list - \li \l{setDoubleBuffer()}{Double or single buffering.} - \li \l{setDepth()}{Depth buffer.} - \li \l{setRgba()}{RGBA or color index mode.} - \li \l{setAlpha()}{Alpha channel.} - \li \l{setAccum()}{Accumulation buffer.} - \li \l{setStencil()}{Stencil buffer.} - \li \l{setStereo()}{Stereo buffers.} - \li \l{setDirectRendering()}{Direct rendering.} - \li \l{setOverlay()}{Presence of an overlay.} - \li \l{setPlane()}{Plane of an overlay.} - \li \l{setSampleBuffers()}{Multisample buffers.} - \endlist - - You can also specify preferred bit depths for the color buffer, - depth buffer, alpha buffer, accumulation buffer and the stencil - buffer with the functions: setRedBufferSize(), setGreenBufferSize(), - setBlueBufferSize(), setDepthBufferSize(), setAlphaBufferSize(), - setAccumBufferSize() and setStencilBufferSize(). - - Note that even if you specify that you prefer a 32 bit depth - buffer (e.g. with setDepthBufferSize(32)), the format that is - chosen may not have a 32 bit depth buffer, even if there is a - format available with a 32 bit depth buffer. The main reason for - this is how the system dependant picking algorithms work on the - different platforms, and some format options may have higher - precedence than others. - - You create and tell a QGLFormat object what rendering options you - want from an OpenGL rendering context. - - OpenGL drivers or accelerated hardware may or may not support - advanced features such as alpha channel or stereographic viewing. - If you request some features that the driver/hardware does not - provide when you create a QGLWidget, you will get a rendering - context with the nearest subset of features. - - There are different ways to define the display characteristics of - a rendering context. One is to create a QGLFormat and make it the - default for the entire application: - \snippet code/src_opengl_qgl.cpp 0 - - Or you can specify the desired format when creating an object of - your QGLWidget subclass: - \snippet code/src_opengl_qgl.cpp 1 - - After the widget has been created, you can find out which of the - requested features the system was able to provide: - \snippet code/src_opengl_qgl.cpp 2 - - \legalese - OpenGL is a trademark of Silicon Graphics, Inc. in the - United States and other countries. - \endlegalese - - \sa QGLContext, QGLWidget -*/ - -#ifndef QT_OPENGL_ES - -static inline void transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4]) -{ -#define M(row,col) m[col*4+row] - out[0] = - M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3]; - out[1] = - M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3]; - out[2] = - M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3]; - out[3] = - M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3]; -#undef M -} - -static inline GLint qgluProject(GLdouble objx, GLdouble objy, GLdouble objz, - const GLdouble model[16], const GLdouble proj[16], - const GLint viewport[4], - GLdouble * winx, GLdouble * winy, GLdouble * winz) -{ - GLdouble in[4], out[4]; - - in[0] = objx; - in[1] = objy; - in[2] = objz; - in[3] = 1.0; - transform_point(out, model, in); - transform_point(in, proj, out); - - if (in[3] == 0.0) - return GL_FALSE; - - in[0] /= in[3]; - in[1] /= in[3]; - in[2] /= in[3]; - - *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2; - *winy = viewport[1] + (1 + in[1]) * viewport[3] / 2; - - *winz = (1 + in[2]) / 2; - return GL_TRUE; -} - -#endif // !QT_OPENGL_ES - -/*! - Constructs a QGLFormat object with the following default settings: - \list - \li \l{setDoubleBuffer()}{Double buffer:} Enabled. - \li \l{setDepth()}{Depth buffer:} Enabled. - \li \l{setRgba()}{RGBA:} Enabled (i.e., color index disabled). - \li \l{setAlpha()}{Alpha channel:} Disabled. - \li \l{setAccum()}{Accumulator buffer:} Disabled. - \li \l{setStencil()}{Stencil buffer:} Enabled. - \li \l{setStereo()}{Stereo:} Disabled. - \li \l{setDirectRendering()}{Direct rendering:} Enabled. - \li \l{setOverlay()}{Overlay:} Disabled. - \li \l{setPlane()}{Plane:} 0 (i.e., normal plane). - \li \l{setSampleBuffers()}{Multisample buffers:} Disabled. - \endlist -*/ - -QGLFormat::QGLFormat() -{ - d = new QGLFormatPrivate; -} - - -/*! - Creates a QGLFormat object that is a copy of the current - defaultFormat(). - - If \a options is not 0, the default format is modified by the - specified format options. The \a options parameter should be - QGL::FormatOption values OR'ed together. - - This constructor makes it easy to specify a certain desired format - in classes derived from QGLWidget, for example: - \snippet code/src_opengl_qgl.cpp 3 - - Note that there are QGL::FormatOption values to turn format settings - both on and off, e.g. QGL::DepthBuffer and QGL::NoDepthBuffer, - QGL::DirectRendering and QGL::IndirectRendering, etc. - - The \a plane parameter defaults to 0 and is the plane which this - format should be associated with. Not all OpenGL implementations - supports overlay/underlay rendering planes. - - \sa defaultFormat(), setOption(), setPlane() -*/ - -QGLFormat::QGLFormat(QGL::FormatOptions options, int plane) -{ - d = new QGLFormatPrivate; - QGL::FormatOptions newOpts = options; - d->opts = defaultFormat().d->opts; - d->opts |= (newOpts & 0xffff); - d->opts &= ~(newOpts >> 16); - d->pln = plane; -} - -/*! - \internal -*/ -void QGLFormat::detach() -{ - if (d->ref.loadRelaxed() != 1) { - QGLFormatPrivate *newd = new QGLFormatPrivate(d); - if (!d->ref.deref()) - delete d; - d = newd; - } -} - -/*! - Constructs a copy of \a other. -*/ - -QGLFormat::QGLFormat(const QGLFormat &other) -{ - d = other.d; - d->ref.ref(); -} - -/*! - Assigns \a other to this object. -*/ - -QGLFormat &QGLFormat::operator=(const QGLFormat &other) -{ - if (d != other.d) { - other.d->ref.ref(); - if (!d->ref.deref()) - delete d; - d = other.d; - } - return *this; -} - -/*! - Destroys the QGLFormat. -*/ -QGLFormat::~QGLFormat() -{ - if (!d->ref.deref()) - delete d; -} - -/*! - Returns an OpenGL format for the window format specified by \a format. -*/ -QGLFormat QGLFormat::fromSurfaceFormat(const QSurfaceFormat &format) -{ - QGLFormat retFormat; - if (format.alphaBufferSize() >= 0) - retFormat.setAlphaBufferSize(format.alphaBufferSize()); - if (format.blueBufferSize() >= 0) - retFormat.setBlueBufferSize(format.blueBufferSize()); - if (format.greenBufferSize() >= 0) - retFormat.setGreenBufferSize(format.greenBufferSize()); - if (format.redBufferSize() >= 0) - retFormat.setRedBufferSize(format.redBufferSize()); - if (format.depthBufferSize() >= 0) - retFormat.setDepthBufferSize(format.depthBufferSize()); - if (format.samples() > 1) { - retFormat.setSampleBuffers(true); - retFormat.setSamples(format.samples()); - } - if (format.stencilBufferSize() > 0) { - retFormat.setStencil(true); - retFormat.setStencilBufferSize(format.stencilBufferSize()); - } - retFormat.setSwapInterval(format.swapInterval()); - retFormat.setDoubleBuffer(format.swapBehavior() != QSurfaceFormat::SingleBuffer); - retFormat.setStereo(format.stereo()); - retFormat.setVersion(format.majorVersion(), format.minorVersion()); - retFormat.setProfile(static_cast<QGLFormat::OpenGLContextProfile>(format.profile())); - return retFormat; -} - -/*! - Returns a window format for the OpenGL format specified by \a format. -*/ -QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format) -{ - QSurfaceFormat retFormat; - if (format.alpha()) - retFormat.setAlphaBufferSize(format.alphaBufferSize() == -1 ? 1 : format.alphaBufferSize()); - if (format.blueBufferSize() >= 0) - retFormat.setBlueBufferSize(format.blueBufferSize()); - if (format.greenBufferSize() >= 0) - retFormat.setGreenBufferSize(format.greenBufferSize()); - if (format.redBufferSize() >= 0) - retFormat.setRedBufferSize(format.redBufferSize()); - if (format.depth()) - retFormat.setDepthBufferSize(format.depthBufferSize() == -1 ? 1 : format.depthBufferSize()); - retFormat.setSwapBehavior(format.doubleBuffer() ? QSurfaceFormat::DoubleBuffer : QSurfaceFormat::SingleBuffer); - if (format.sampleBuffers()) - retFormat.setSamples(format.samples() == -1 ? 4 : format.samples()); - if (format.stencil()) - retFormat.setStencilBufferSize(format.stencilBufferSize() == -1 ? 1 : format.stencilBufferSize()); - retFormat.setSwapInterval(format.swapInterval()); - retFormat.setStereo(format.stereo()); - retFormat.setMajorVersion(format.majorVersion()); - retFormat.setMinorVersion(format.minorVersion()); - retFormat.setProfile(static_cast<QSurfaceFormat::OpenGLContextProfile>(format.profile())); - // QGLFormat has no way to set DeprecatedFunctions, that is, to tell that forward - // compatibility should not be requested. Some drivers fail to ignore the fwdcompat - // bit with compatibility profiles so make sure it is not set. - if (format.profile() == QGLFormat::CompatibilityProfile) - retFormat.setOption(QSurfaceFormat::DeprecatedFunctions); - return retFormat; -} - -void QGLContextPrivate::setupSharing() { - Q_Q(QGLContext); - QOpenGLContext *sharedContext = guiGlContext->shareContext(); - if (sharedContext) { - QGLContext *actualSharedContext = QGLContext::fromOpenGLContext(sharedContext); - sharing = true; - QGLContextGroup::addShare(q, actualSharedContext); - } -} - -void QGLContextPrivate::refreshCurrentFbo() -{ - QOpenGLContextPrivate *guiGlContextPrivate = - guiGlContext ? QOpenGLContextPrivate::get(guiGlContext) : 0; - - // if QOpenGLFramebufferObjects have been used in the mean-time, we've lost our cached value - if (guiGlContextPrivate && guiGlContextPrivate->qgl_current_fbo_invalid) { - GLint current; - QOpenGLFunctions *funcs = qgl_functions(); - funcs->glGetIntegerv(GL_FRAMEBUFFER_BINDING, ¤t); - - current_fbo = current; - - guiGlContextPrivate->qgl_current_fbo_invalid = false; - } -} - -void QGLContextPrivate::setCurrentFbo(GLuint fbo) -{ - current_fbo = fbo; - - QOpenGLContextPrivate *guiGlContextPrivate = - guiGlContext ? QOpenGLContextPrivate::get(guiGlContext) : 0; - - if (guiGlContextPrivate) - guiGlContextPrivate->qgl_current_fbo_invalid = false; -} - - -/*! - \fn bool QGLFormat::doubleBuffer() const - - Returns \c true if double buffering is enabled; otherwise returns - false. Double buffering is enabled by default. - - \sa setDoubleBuffer() -*/ - -/*! - If \a enable is true sets double buffering; otherwise sets single - buffering. - - Double buffering is enabled by default. - - Double buffering is a technique where graphics are rendered on an - off-screen buffer and not directly to the screen. When the drawing - has been completed, the program calls a swapBuffers() function to - exchange the screen contents with the buffer. The result is - flicker-free drawing and often better performance. - - Note that single buffered contexts are currently not supported - with EGL. - - \sa doubleBuffer(), QGLContext::swapBuffers(), - QGLWidget::swapBuffers() -*/ - -void QGLFormat::setDoubleBuffer(bool enable) -{ - setOption(enable ? QGL::DoubleBuffer : QGL::SingleBuffer); -} - - -/*! - \fn bool QGLFormat::depth() const - - Returns \c true if the depth buffer is enabled; otherwise returns - false. The depth buffer is enabled by default. - - \sa setDepth(), setDepthBufferSize() -*/ - -/*! - If \a enable is true enables the depth buffer; otherwise disables - the depth buffer. - - The depth buffer is enabled by default. - - The purpose of a depth buffer (or Z-buffering) is to remove hidden - surfaces. Pixels are assigned Z values based on the distance to - the viewer. A pixel with a high Z value is closer to the viewer - than a pixel with a low Z value. This information is used to - decide whether to draw a pixel or not. - - \sa depth(), setDepthBufferSize() -*/ - -void QGLFormat::setDepth(bool enable) -{ - setOption(enable ? QGL::DepthBuffer : QGL::NoDepthBuffer); -} - - -/*! - \fn bool QGLFormat::rgba() const - - Returns \c true if RGBA color mode is set. Returns \c false if color - index mode is set. The default color mode is RGBA. - - \sa setRgba() -*/ - -/*! - If \a enable is true sets RGBA mode. If \a enable is false sets - color index mode. - - The default color mode is RGBA. - - RGBA is the preferred mode for most OpenGL applications. In RGBA - color mode you specify colors as red + green + blue + alpha - quadruplets. - - In color index mode you specify an index into a color lookup - table. - - \sa rgba() -*/ - -void QGLFormat::setRgba(bool enable) -{ - setOption(enable ? QGL::Rgba : QGL::ColorIndex); -} - - -/*! - \fn bool QGLFormat::alpha() const - - Returns \c true if the alpha buffer in the framebuffer is enabled; - otherwise returns \c false. The alpha buffer is disabled by default. - - \sa setAlpha(), setAlphaBufferSize() -*/ - -/*! - If \a enable is true enables the alpha buffer; otherwise disables - the alpha buffer. - - The alpha buffer is disabled by default. - - The alpha buffer is typically used for implementing transparency - or translucency. The A in RGBA specifies the transparency of a - pixel. - - \sa alpha(), setAlphaBufferSize() -*/ - -void QGLFormat::setAlpha(bool enable) -{ - setOption(enable ? QGL::AlphaChannel : QGL::NoAlphaChannel); -} - - -/*! - \fn bool QGLFormat::accum() const - - Returns \c true if the accumulation buffer is enabled; otherwise - returns \c false. The accumulation buffer is disabled by default. - - \sa setAccum(), setAccumBufferSize() -*/ - -/*! - If \a enable is true enables the accumulation buffer; otherwise - disables the accumulation buffer. - - The accumulation buffer is disabled by default. - - The accumulation buffer is used to create blur effects and - multiple exposures. - - \sa accum(), setAccumBufferSize() -*/ - -void QGLFormat::setAccum(bool enable) -{ - setOption(enable ? QGL::AccumBuffer : QGL::NoAccumBuffer); -} - - -/*! - \fn bool QGLFormat::stencil() const - - Returns \c true if the stencil buffer is enabled; otherwise returns - false. The stencil buffer is enabled by default. - - \sa setStencil(), setStencilBufferSize() -*/ - -/*! - If \a enable is true enables the stencil buffer; otherwise - disables the stencil buffer. - - The stencil buffer is enabled by default. - - The stencil buffer masks certain parts of the drawing area so that - masked parts are not drawn on. - - \sa stencil(), setStencilBufferSize() -*/ - -void QGLFormat::setStencil(bool enable) -{ - setOption(enable ? QGL::StencilBuffer: QGL::NoStencilBuffer); -} - - -/*! - \fn bool QGLFormat::stereo() const - - Returns \c true if stereo buffering is enabled; otherwise returns - false. Stereo buffering is disabled by default. - - \sa setStereo() -*/ - -/*! - If \a enable is true enables stereo buffering; otherwise disables - stereo buffering. - - Stereo buffering is disabled by default. - - Stereo buffering provides extra color buffers to generate left-eye - and right-eye images. - - \sa stereo() -*/ - -void QGLFormat::setStereo(bool enable) -{ - setOption(enable ? QGL::StereoBuffers : QGL::NoStereoBuffers); -} - - -/*! - \fn bool QGLFormat::directRendering() const - - Returns \c true if direct rendering is enabled; otherwise returns - false. - - Direct rendering is enabled by default. - - \sa setDirectRendering() -*/ - -/*! - If \a enable is true enables direct rendering; otherwise disables - direct rendering. - - Direct rendering is enabled by default. - - Enabling this option will make OpenGL bypass the underlying window - system and render directly from hardware to the screen, if this is - supported by the system. - - \sa directRendering() -*/ - -void QGLFormat::setDirectRendering(bool enable) -{ - setOption(enable ? QGL::DirectRendering : QGL::IndirectRendering); -} - -/*! - \fn bool QGLFormat::sampleBuffers() const - - Returns \c true if multisample buffer support is enabled; otherwise - returns \c false. - - The multisample buffer is disabled by default. - - \sa setSampleBuffers() -*/ - -/*! - If \a enable is true, a GL context with multisample buffer support - is picked; otherwise ignored. - - \sa sampleBuffers(), setSamples(), samples() -*/ -void QGLFormat::setSampleBuffers(bool enable) -{ - setOption(enable ? QGL::SampleBuffers : QGL::NoSampleBuffers); -} - -/*! - Returns the number of samples per pixel when multisampling is - enabled. By default, the highest number of samples that is - available is used. - - \sa setSampleBuffers(), sampleBuffers(), setSamples() -*/ -int QGLFormat::samples() const -{ - return d->numSamples; -} - -/*! - Set the preferred number of samples per pixel when multisampling - is enabled to \a numSamples. By default, the highest number of - samples available is used. - - \sa setSampleBuffers(), sampleBuffers(), samples() -*/ -void QGLFormat::setSamples(int numSamples) -{ - detach(); - if (numSamples < 0) { - qWarning("QGLFormat::setSamples: Cannot have negative number of samples per pixel %d", numSamples); - return; - } - d->numSamples = numSamples; - setSampleBuffers(numSamples > 0); -} - -/*! - \since 4.2 - - Set the preferred swap interval. This can be used to sync the GL - drawing into a system window to the vertical refresh of the screen. - Setting an \a interval value of 0 will turn the vertical refresh syncing - off, any value higher than 0 will turn the vertical syncing on. - - Under Windows and under X11, where the \c{WGL_EXT_swap_control} - and \c{GLX_SGI_video_sync} extensions are used, the \a interval - parameter can be used to set the minimum number of video frames - that are displayed before a buffer swap will occur. In effect, - setting the \a interval to 10, means there will be 10 vertical - retraces between every buffer swap. - - Under Windows the \c{WGL_EXT_swap_control} extension has to be present, - and under X11 the \c{GLX_SGI_video_sync} extension has to be present. -*/ -void QGLFormat::setSwapInterval(int interval) -{ - detach(); - d->swapInterval = interval; -} - -/*! - \since 4.2 - - Returns the currently set swap interval. -1 is returned if setting - the swap interval isn't supported in the system GL implementation. -*/ -int QGLFormat::swapInterval() const -{ - return d->swapInterval; -} - -/*! - \fn bool QGLFormat::hasOverlay() const - - Returns \c true if overlay plane is enabled; otherwise returns \c false. - - Overlay is disabled by default. - - \sa setOverlay() -*/ - -/*! - If \a enable is true enables an overlay plane; otherwise disables - the overlay plane. - - Enabling the overlay plane will cause QGLWidget to create an - additional context in an overlay plane. See the QGLWidget - documentation for further information. - - \sa hasOverlay() -*/ - -void QGLFormat::setOverlay(bool enable) -{ - setOption(enable ? QGL::HasOverlay : QGL::NoOverlay); -} - -/*! - Returns the plane of this format. The default for normal formats - is 0, which means the normal plane. The default for overlay - formats is 1, which is the first overlay plane. - - \sa setPlane(), defaultOverlayFormat() -*/ -int QGLFormat::plane() const -{ - return d->pln; -} - -/*! - Sets the requested plane to \a plane. 0 is the normal plane, 1 is - the first overlay plane, 2 is the second overlay plane, etc.; -1, - -2, etc. are underlay planes. - - Note that in contrast to other format specifications, the plane - specifications will be matched exactly. This means that if you - specify a plane that the underlying OpenGL system cannot provide, - an \l{QGLWidget::isValid()}{invalid} QGLWidget will be - created. - - \sa plane() -*/ -void QGLFormat::setPlane(int plane) -{ - detach(); - d->pln = plane; -} - -/*! - Sets the format option to \a opt. - - \sa testOption() -*/ - -void QGLFormat::setOption(QGL::FormatOptions opt) -{ - detach(); - if (opt & 0xffff) - d->opts |= opt; - else - d->opts &= ~(opt >> 16); -} - - - -/*! - Returns \c true if format option \a opt is set; otherwise returns \c false. - - \sa setOption() -*/ - -bool QGLFormat::testOption(QGL::FormatOptions opt) const -{ - if (opt & 0xffff) - return (d->opts & opt) != 0; - else - return (d->opts & (opt >> 16)) == 0; -} - -/*! - Set the minimum depth buffer size to \a size. - - \sa depthBufferSize(), setDepth(), depth() -*/ -void QGLFormat::setDepthBufferSize(int size) -{ - detach(); - if (size < 0) { - qWarning("QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size %d", size); - return; - } - d->depthSize = size; - setDepth(size > 0); -} - -/*! - Returns the depth buffer size. - - \sa depth(), setDepth(), setDepthBufferSize() -*/ -int QGLFormat::depthBufferSize() const -{ - return d->depthSize; -} - -/*! - \since 4.2 - - Set the preferred red buffer size to \a size. - - \sa setGreenBufferSize(), setBlueBufferSize(), setAlphaBufferSize() -*/ -void QGLFormat::setRedBufferSize(int size) -{ - detach(); - if (size < 0) { - qWarning("QGLFormat::setRedBufferSize: Cannot set negative red buffer size %d", size); - return; - } - d->redSize = size; -} - -/*! - \since 4.2 - - Returns the red buffer size. - - \sa setRedBufferSize() -*/ -int QGLFormat::redBufferSize() const -{ - return d->redSize; -} - -/*! - \since 4.2 - - Set the preferred green buffer size to \a size. - - \sa setRedBufferSize(), setBlueBufferSize(), setAlphaBufferSize() -*/ -void QGLFormat::setGreenBufferSize(int size) -{ - detach(); - if (size < 0) { - qWarning("QGLFormat::setGreenBufferSize: Cannot set negative green buffer size %d", size); - return; - } - d->greenSize = size; -} - -/*! - \since 4.2 - - Returns the green buffer size. - - \sa setGreenBufferSize() -*/ -int QGLFormat::greenBufferSize() const -{ - return d->greenSize; -} - -/*! - \since 4.2 - - Set the preferred blue buffer size to \a size. - - \sa setRedBufferSize(), setGreenBufferSize(), setAlphaBufferSize() -*/ -void QGLFormat::setBlueBufferSize(int size) -{ - detach(); - if (size < 0) { - qWarning("QGLFormat::setBlueBufferSize: Cannot set negative blue buffer size %d", size); - return; - } - d->blueSize = size; -} - -/*! - \since 4.2 - - Returns the blue buffer size. - - \sa setBlueBufferSize() -*/ -int QGLFormat::blueBufferSize() const -{ - return d->blueSize; -} - -/*! - Set the preferred alpha buffer size to \a size. - This function implicitly enables the alpha channel. - - \sa setRedBufferSize(), setGreenBufferSize(), alphaBufferSize() -*/ -void QGLFormat::setAlphaBufferSize(int size) -{ - detach(); - if (size < 0) { - qWarning("QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size %d", size); - return; - } - d->alphaSize = size; - setAlpha(size > 0); -} - -/*! - Returns the alpha buffer size. - - \sa alpha(), setAlpha(), setAlphaBufferSize() -*/ -int QGLFormat::alphaBufferSize() const -{ - return d->alphaSize; -} - -/*! - Set the preferred accumulation buffer size, where \a size is the - bit depth for each RGBA component. - - \sa accum(), setAccum(), accumBufferSize() -*/ -void QGLFormat::setAccumBufferSize(int size) -{ - detach(); - if (size < 0) { - qWarning("QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size %d", size); - return; - } - d->accumSize = size; - setAccum(size > 0); -} - -/*! - Returns the accumulation buffer size. - - \sa setAccumBufferSize(), accum(), setAccum() -*/ -int QGLFormat::accumBufferSize() const -{ - return d->accumSize; -} - -/*! - Set the preferred stencil buffer size to \a size. - - \sa stencilBufferSize(), setStencil(), stencil() -*/ -void QGLFormat::setStencilBufferSize(int size) -{ - detach(); - if (size < 0) { - qWarning("QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size %d", size); - return; - } - d->stencilSize = size; - setStencil(size > 0); -} - -/*! - Returns the stencil buffer size. - - \sa stencil(), setStencil(), setStencilBufferSize() -*/ -int QGLFormat::stencilBufferSize() const -{ - return d->stencilSize; -} - -/*! - \since 4.7 - - Set the OpenGL version to the \a major and \a minor numbers. If a - context compatible with the requested OpenGL version cannot be - created, a context compatible with version 1.x is created instead. - - \sa majorVersion(), minorVersion() -*/ -void QGLFormat::setVersion(int major, int minor) -{ - if (major < 1 || minor < 0) { - qWarning("QGLFormat::setVersion: Cannot set zero or negative version number %d.%d", major, minor); - return; - } - detach(); - d->majorVersion = major; - d->minorVersion = minor; -} - -/*! - \since 4.7 - - Returns the OpenGL major version. - - \sa setVersion(), minorVersion() -*/ -int QGLFormat::majorVersion() const -{ - return d->majorVersion; -} - -/*! - \since 4.7 - - Returns the OpenGL minor version. - - \sa setVersion(), majorVersion() -*/ -int QGLFormat::minorVersion() const -{ - return d->minorVersion; -} - -/*! - \enum QGLFormat::OpenGLContextProfile - \since 4.7 - - This enum describes the OpenGL context profiles that can be - specified for contexts implementing OpenGL version 3.2 or - higher. These profiles are different from OpenGL ES profiles. - - \value NoProfile OpenGL version is lower than 3.2. - \value CoreProfile Functionality deprecated in OpenGL version 3.0 is not available. - \value CompatibilityProfile Functionality from earlier OpenGL versions is available. -*/ - -/*! - \since 4.7 - - Set the OpenGL context profile to \a profile. The \a profile is - ignored if the requested OpenGL version is less than 3.2. - - \sa profile() -*/ -void QGLFormat::setProfile(OpenGLContextProfile profile) -{ - detach(); - d->profile = profile; -} - -/*! - \since 4.7 - - Returns the OpenGL context profile. - - \sa setProfile() -*/ -QGLFormat::OpenGLContextProfile QGLFormat::profile() const -{ - return d->profile; -} - - -/*! - \fn bool QGLFormat::hasOpenGL() - - Returns \c true if the window system has any OpenGL support; - otherwise returns \c false. - - \warning This function must not be called until the QApplication - object has been created. -*/ -bool QGLFormat::hasOpenGL() -{ - return QApplicationPrivate::platformIntegration() - ->hasCapability(QPlatformIntegration::OpenGL); -} - -/*! - \fn bool QGLFormat::hasOpenGLOverlays() - - Returns \c true if the window system supports OpenGL overlays; - otherwise returns \c false. - - \warning This function must not be called until the QApplication - object has been created. -*/ -bool QGLFormat::hasOpenGLOverlays() -{ - return false; -} - -QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(const QString &versionString) -{ - QGLFormat::OpenGLVersionFlags versionFlags = QGLFormat::OpenGL_Version_None; - - if (versionString.startsWith(QLatin1String("OpenGL ES"))) { - const auto parts = versionString.splitRef(QLatin1Char(' ')); - if (parts.size() >= 3) { - if (parts[2].startsWith(QLatin1String("1."))) { - if (parts[1].endsWith(QLatin1String("-CM"))) { - versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_0 | - QGLFormat::OpenGL_ES_CommonLite_Version_1_0; - if (parts[2].startsWith(QLatin1String("1.1"))) - versionFlags |= QGLFormat::OpenGL_ES_Common_Version_1_1 | - QGLFormat::OpenGL_ES_CommonLite_Version_1_1; - } else { - // Not -CM, must be CL, CommonLite - versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_0; - if (parts[2].startsWith(QLatin1String("1.1"))) - versionFlags |= QGLFormat::OpenGL_ES_CommonLite_Version_1_1; - } - } else { - // OpenGL ES version 2.0 or higher - versionFlags |= QGLFormat::OpenGL_ES_Version_2_0; - } - } else { - // if < 3 parts to the name, it is an unrecognised OpenGL ES - qWarning("Unrecognised OpenGL ES version"); - } - } else { - // not ES, regular OpenGL, the version numbers are first in the string - if (versionString.startsWith(QLatin1String("1."))) { - switch (versionString[2].toLatin1()) { - case '5': - versionFlags |= QGLFormat::OpenGL_Version_1_5; - Q_FALLTHROUGH(); - case '4': - versionFlags |= QGLFormat::OpenGL_Version_1_4; - Q_FALLTHROUGH(); - case '3': - versionFlags |= QGLFormat::OpenGL_Version_1_3; - Q_FALLTHROUGH(); - case '2': - versionFlags |= QGLFormat::OpenGL_Version_1_2; - Q_FALLTHROUGH(); - case '1': - versionFlags |= QGLFormat::OpenGL_Version_1_1; - Q_FALLTHROUGH(); - default: - break; - } - } else if (versionString.startsWith(QLatin1String("2."))) { - versionFlags |= QGLFormat::OpenGL_Version_1_1 | - QGLFormat::OpenGL_Version_1_2 | - QGLFormat::OpenGL_Version_1_3 | - QGLFormat::OpenGL_Version_1_4 | - QGLFormat::OpenGL_Version_1_5 | - QGLFormat::OpenGL_Version_2_0; - if (versionString[2].toLatin1() == '1') - versionFlags |= QGLFormat::OpenGL_Version_2_1; - } else if (versionString.startsWith(QLatin1String("3."))) { - versionFlags |= QGLFormat::OpenGL_Version_1_1 | - QGLFormat::OpenGL_Version_1_2 | - QGLFormat::OpenGL_Version_1_3 | - QGLFormat::OpenGL_Version_1_4 | - QGLFormat::OpenGL_Version_1_5 | - QGLFormat::OpenGL_Version_2_0 | - QGLFormat::OpenGL_Version_2_1 | - QGLFormat::OpenGL_Version_3_0; - switch (versionString[2].toLatin1()) { - case '3': - versionFlags |= QGLFormat::OpenGL_Version_3_3; - Q_FALLTHROUGH(); - case '2': - versionFlags |= QGLFormat::OpenGL_Version_3_2; - Q_FALLTHROUGH(); - case '1': - versionFlags |= QGLFormat::OpenGL_Version_3_1; - Q_FALLTHROUGH(); - case '0': - break; - default: - versionFlags |= QGLFormat::OpenGL_Version_3_1 | - QGLFormat::OpenGL_Version_3_2 | - QGLFormat::OpenGL_Version_3_3; - break; - } - } else if (versionString.startsWith(QLatin1String("4."))) { - versionFlags |= QGLFormat::OpenGL_Version_1_1 | - QGLFormat::OpenGL_Version_1_2 | - QGLFormat::OpenGL_Version_1_3 | - QGLFormat::OpenGL_Version_1_4 | - QGLFormat::OpenGL_Version_1_5 | - QGLFormat::OpenGL_Version_2_0 | - QGLFormat::OpenGL_Version_2_1 | - QGLFormat::OpenGL_Version_3_0 | - QGLFormat::OpenGL_Version_3_1 | - QGLFormat::OpenGL_Version_3_2 | - QGLFormat::OpenGL_Version_3_3 | - QGLFormat::OpenGL_Version_4_0; - switch (versionString[2].toLatin1()) { - case '3': - versionFlags |= QGLFormat::OpenGL_Version_4_3; - Q_FALLTHROUGH(); - case '2': - versionFlags |= QGLFormat::OpenGL_Version_4_2; - Q_FALLTHROUGH(); - case '1': - versionFlags |= QGLFormat::OpenGL_Version_4_1; - Q_FALLTHROUGH(); - case '0': - break; - default: - versionFlags |= QGLFormat::OpenGL_Version_4_1 | - QGLFormat::OpenGL_Version_4_2 | - QGLFormat::OpenGL_Version_4_3; - break; - } - } else { - versionFlags |= QGLFormat::OpenGL_Version_1_1 | - QGLFormat::OpenGL_Version_1_2 | - QGLFormat::OpenGL_Version_1_3 | - QGLFormat::OpenGL_Version_1_4 | - QGLFormat::OpenGL_Version_1_5 | - QGLFormat::OpenGL_Version_2_0 | - QGLFormat::OpenGL_Version_2_1 | - QGLFormat::OpenGL_Version_3_0 | - QGLFormat::OpenGL_Version_3_1 | - QGLFormat::OpenGL_Version_3_2 | - QGLFormat::OpenGL_Version_3_3 | - QGLFormat::OpenGL_Version_4_0 | - QGLFormat::OpenGL_Version_4_1 | - QGLFormat::OpenGL_Version_4_2 | - QGLFormat::OpenGL_Version_4_3; - } - } - return versionFlags; -} - -/*! - \enum QGLFormat::OpenGLVersionFlag - \since 4.2 - - This enum describes the various OpenGL versions that are - recognized by Qt. Use the QGLFormat::openGLVersionFlags() function - to identify which versions that are supported at runtime. - - \value OpenGL_Version_None If no OpenGL is present or if no OpenGL context is current. - - \value OpenGL_Version_1_1 OpenGL version 1.1 or higher is present. - - \value OpenGL_Version_1_2 OpenGL version 1.2 or higher is present. - - \value OpenGL_Version_1_3 OpenGL version 1.3 or higher is present. - - \value OpenGL_Version_1_4 OpenGL version 1.4 or higher is present. - - \value OpenGL_Version_1_5 OpenGL version 1.5 or higher is present. - - \value OpenGL_Version_2_0 OpenGL version 2.0 or higher is present. - Note that version 2.0 supports all the functionality of version 1.5. - - \value OpenGL_Version_2_1 OpenGL version 2.1 or higher is present. - - \value OpenGL_Version_3_0 OpenGL version 3.0 or higher is present. - - \value OpenGL_Version_3_1 OpenGL version 3.1 or higher is present. - Note that OpenGL version 3.1 or higher does not necessarily support all the features of - version 3.0 and lower. - - \value OpenGL_Version_3_2 OpenGL version 3.2 or higher is present. - - \value OpenGL_Version_3_3 OpenGL version 3.3 or higher is present. - - \value OpenGL_Version_4_0 OpenGL version 4.0 or higher is present. - - \value OpenGL_Version_4_1 OpenGL version 4.1 or higher is present. - - \value OpenGL_Version_4_2 OpenGL version 4.2 or higher is present. - - \value OpenGL_Version_4_3 OpenGL version 4.3 or higher is present. - - \value OpenGL_ES_CommonLite_Version_1_0 OpenGL ES version 1.0 Common Lite or higher is present. - - \value OpenGL_ES_Common_Version_1_0 OpenGL ES version 1.0 Common or higher is present. - The Common profile supports all the features of Common Lite. - - \value OpenGL_ES_CommonLite_Version_1_1 OpenGL ES version 1.1 Common Lite or higher is present. - - \value OpenGL_ES_Common_Version_1_1 OpenGL ES version 1.1 Common or higher is present. - The Common profile supports all the features of Common Lite. - - \value OpenGL_ES_Version_2_0 OpenGL ES version 2.0 or higher is present. - Note that OpenGL ES version 2.0 does not support all the features of OpenGL ES 1.x. - So if OpenGL_ES_Version_2_0 is returned, none of the ES 1.x flags are returned. - - See also \l{http://www.opengl.org} for more information about the different - revisions of OpenGL. - - \sa openGLVersionFlags() -*/ - -/*! - \since 4.2 - - Identifies, at runtime, which OpenGL versions that are supported - by the current platform. - - Note that if OpenGL version 1.5 is supported, its predecessors - (i.e., version 1.4 and lower) are also supported. To identify the - support of a particular feature, like multi texturing, test for - the version in which the feature was first introduced (i.e., - version 1.3 in the case of multi texturing) to adapt to the largest - possible group of runtime platforms. - - This function needs a valid current OpenGL context to work; - otherwise it will return OpenGL_Version_None. - - \sa hasOpenGL(), hasOpenGLOverlays() -*/ -QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags() -{ - static bool cachedDefault = false; - static OpenGLVersionFlags defaultVersionFlags = OpenGL_Version_None; - QGLContext *currentCtx = const_cast<QGLContext *>(QGLContext::currentContext()); - QGLTemporaryContext *tmpContext = 0; - - if (currentCtx && currentCtx->d_func()->version_flags_cached) - return currentCtx->d_func()->version_flags; - - if (!currentCtx) { - if (cachedDefault) { - return defaultVersionFlags; - } else { - if (!hasOpenGL()) - return defaultVersionFlags; - tmpContext = new QGLTemporaryContext; - cachedDefault = true; - } - } - - QString versionString(QLatin1String(reinterpret_cast<const char*>(qgl_functions()->glGetString(GL_VERSION)))); - OpenGLVersionFlags versionFlags = qOpenGLVersionFlagsFromString(versionString); - if (currentCtx) { - currentCtx->d_func()->version_flags_cached = true; - currentCtx->d_func()->version_flags = versionFlags; - } - if (tmpContext) { - defaultVersionFlags = versionFlags; - delete tmpContext; - } - - return versionFlags; -} - - -/*! - Returns the default QGLFormat for the application. All QGLWidget - objects that are created use this format unless another format is - specified, e.g. when they are constructed. - - If no special default format has been set using - setDefaultFormat(), the default format is the same as that created - with QGLFormat(). - - \sa setDefaultFormat() -*/ - -QGLFormat QGLFormat::defaultFormat() -{ - return *qgl_default_format(); -} - -/*! - Sets a new default QGLFormat for the application to \a f. For - example, to set single buffering as the default instead of double - buffering, your main() might contain code like this: - \snippet code/src_opengl_qgl.cpp 4 - - \sa defaultFormat() -*/ - -void QGLFormat::setDefaultFormat(const QGLFormat &f) -{ - *qgl_default_format() = f; -} - - -/*! - Returns the default QGLFormat for overlay contexts. - - The default overlay format is: - \list - \li \l{setDoubleBuffer()}{Double buffer:} Disabled. - \li \l{setDepth()}{Depth buffer:} Disabled. - \li \l{setRgba()}{RGBA:} Disabled (i.e., color index enabled). - \li \l{setAlpha()}{Alpha channel:} Disabled. - \li \l{setAccum()}{Accumulator buffer:} Disabled. - \li \l{setStencil()}{Stencil buffer:} Disabled. - \li \l{setStereo()}{Stereo:} Disabled. - \li \l{setDirectRendering()}{Direct rendering:} Enabled. - \li \l{setOverlay()}{Overlay:} Disabled. - \li \l{setSampleBuffers()}{Multisample buffers:} Disabled. - \li \l{setPlane()}{Plane:} 1 (i.e., first overlay plane). - \endlist - - \sa setDefaultFormat() -*/ - -QGLFormat QGLFormat::defaultOverlayFormat() -{ - return *defaultOverlayFormatInstance(); -} - -/*! - Sets a new default QGLFormat for overlay contexts to \a f. This - format is used whenever a QGLWidget is created with a format that - hasOverlay() enabled. - - For example, to get a double buffered overlay context (if - available), use code like this: - - \snippet code/src_opengl_qgl.cpp 5 - - As usual, you can find out after widget creation whether the - underlying OpenGL system was able to provide the requested - specification: - - \snippet code/src_opengl_qgl.cpp 6 - - \sa defaultOverlayFormat() -*/ - -void QGLFormat::setDefaultOverlayFormat(const QGLFormat &f) -{ - QGLFormat *defaultFormat = defaultOverlayFormatInstance(); - *defaultFormat = f; - // Make sure the user doesn't request that the overlays themselves - // have overlays, since it is unlikely that the system supports - // infinitely many planes... - defaultFormat->setOverlay(false); -} - - -/*! - Returns \c true if all the options of the two QGLFormat objects - \a a and \a b are equal; otherwise returns \c false. - - \relates QGLFormat -*/ - -bool operator==(const QGLFormat& a, const QGLFormat& b) -{ - return (a.d == b.d) || ((int) a.d->opts == (int) b.d->opts - && a.d->pln == b.d->pln - && a.d->alphaSize == b.d->alphaSize - && a.d->accumSize == b.d->accumSize - && a.d->stencilSize == b.d->stencilSize - && a.d->depthSize == b.d->depthSize - && a.d->redSize == b.d->redSize - && a.d->greenSize == b.d->greenSize - && a.d->blueSize == b.d->blueSize - && a.d->numSamples == b.d->numSamples - && a.d->swapInterval == b.d->swapInterval - && a.d->majorVersion == b.d->majorVersion - && a.d->minorVersion == b.d->minorVersion - && a.d->profile == b.d->profile); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug dbg, const QGLFormat &f) -{ - const QGLFormatPrivate * const d = f.d; - - QDebugStateSaver saver(dbg); - dbg.nospace() << "QGLFormat(" - << "options " << d->opts - << ", plane " << d->pln - << ", depthBufferSize " << d->depthSize - << ", accumBufferSize " << d->accumSize - << ", stencilBufferSize " << d->stencilSize - << ", redBufferSize " << d->redSize - << ", greenBufferSize " << d->greenSize - << ", blueBufferSize " << d->blueSize - << ", alphaBufferSize " << d->alphaSize - << ", samples " << d->numSamples - << ", swapInterval " << d->swapInterval - << ", majorVersion " << d->majorVersion - << ", minorVersion " << d->minorVersion - << ", profile " << d->profile - << ')'; - - return dbg; -} -#endif - - -/*! - Returns \c false if all the options of the two QGLFormat objects - \a a and \a b are equal; otherwise returns \c true. - - \relates QGLFormat -*/ - -bool operator!=(const QGLFormat& a, const QGLFormat& b) -{ - return !(a == b); -} - -struct QGLContextGroupList { - void append(QGLContextGroup *group) { - QMutexLocker locker(&m_mutex); - m_list.append(group); - } - - void remove(QGLContextGroup *group) { - QMutexLocker locker(&m_mutex); - m_list.removeOne(group); - } - - QList<QGLContextGroup *> m_list; - QRecursiveMutex m_mutex; -}; - -Q_GLOBAL_STATIC(QGLContextGroupList, qt_context_groups) - -/***************************************************************************** - QGLContext implementation - *****************************************************************************/ - -QGLContextGroup::QGLContextGroup(const QGLContext *context) - : m_context(context), m_refs(1) -{ - qt_context_groups()->append(this); -} - -QGLContextGroup::~QGLContextGroup() -{ - qt_context_groups()->remove(this); -} - -const QGLContext *qt_gl_transfer_context(const QGLContext *ctx) -{ - if (!ctx) - return 0; - QList<const QGLContext *> shares - (QGLContextPrivate::contextGroup(ctx)->shares()); - if (shares.size() >= 2) - return (ctx == shares.at(0)) ? shares.at(1) : shares.at(0); - else - return 0; -} - -QGLContextPrivate::QGLContextPrivate(QGLContext *context) - : internal_context(false) - , q_ptr(context) - , texture_destroyer(0) - , functions(0) -{ - group = new QGLContextGroup(context); - - texture_destroyer = new QGLTextureDestroyer; -} - -QGLContextPrivate::~QGLContextPrivate() -{ - delete functions; - - if (!group->m_refs.deref()) { - Q_ASSERT(group->context() == q_ptr); - delete group; - } - - delete texture_destroyer; -} - -void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format) -{ - Q_Q(QGLContext); - glFormat = reqFormat = format; - valid = false; - q->setDevice(dev); - - guiGlContext = 0; - ownContext = false; - fbo = 0; - crWin = false; - initDone = false; - sharing = false; - max_texture_size = -1; - version_flags_cached = false; - version_flags = QGLFormat::OpenGL_Version_None; - current_fbo = 0; - default_fbo = 0; - active_engine = 0; - workaround_needsFullClearOnEveryFrame = false; - workaround_brokenFBOReadBack = false; - workaround_brokenTexSubImage = false; - workaroundsCached = false; - - workaround_brokenTextureFromPixmap = false; - workaround_brokenTextureFromPixmap_init = false; - - workaround_brokenAlphaTexSubImage = false; - workaround_brokenAlphaTexSubImage_init = false; - - for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) - vertexAttributeArraysEnabledState[i] = false; -} - -QGLContext* QGLContext::currentCtx = 0; - -/* - QGLTemporaryContext implementation -*/ -class QGLTemporaryContextPrivate -{ -public: - QWindow *window; - QOpenGLContext *context; - - QGLContext *oldContext; -}; - -QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) - : d(new QGLTemporaryContextPrivate) -{ - d->oldContext = const_cast<QGLContext *>(QGLContext::currentContext()); - - d->window = new QWindow; - d->window->setSurfaceType(QWindow::OpenGLSurface); - d->window->setGeometry(QRect(0, 0, 3, 3)); - d->window->create(); - - d->context = new QOpenGLContext; -#if !defined(QT_OPENGL_ES) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { - // 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); -#else - format.setMajorVersion(4); - format.setMinorVersion(3); -#endif - d->context->setFormat(format); - } -#endif // QT_OPENGL_ES - d->context->create(); - d->context->makeCurrent(d->window); -} - -QGLTemporaryContext::~QGLTemporaryContext() -{ - if (d->oldContext) - d->oldContext->makeCurrent(); - - delete d->context; - delete d->window; -} - -/* - Read back the contents of the currently bound framebuffer, used in - QGLWidget::grabFrameBuffer(), QGLPixelbuffer::toImage() and - QGLFramebufferObject::toImage() -*/ - -static void convertFromGLImage(QImage &img, int w, int h, bool alpha_format, bool include_alpha) -{ - Q_ASSERT(!img.isNull()); - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - // OpenGL gives RGBA; Qt wants ARGB - uint *p = (uint*)img.bits(); - uint *end = p + w*h; - if (alpha_format && include_alpha) { - while (p < end) { - uint a = *p << 24; - *p = (*p >> 8) | a; - p++; - } - } else { - // This is an old legacy fix for PowerPC based Macs, which - // we shouldn't remove - while (p < end) { - *p = 0xff000000 | (*p>>8); - ++p; - } - } - } else { - // OpenGL gives ABGR (i.e. RGBA backwards); Qt wants ARGB - for (int y = 0; y < h; y++) { - uint *q = (uint*)img.scanLine(y); - for (int x=0; x < w; ++x) { - const uint pixel = *q; - if (alpha_format && include_alpha) { - *q = ((pixel << 16) & 0xff0000) | ((pixel >> 16) & 0xff) - | (pixel & 0xff00ff00); - } else { - *q = 0xff000000 | ((pixel << 16) & 0xff0000) - | ((pixel >> 16) & 0xff) | (pixel & 0x00ff00); - } - - q++; - } - } - - } - img = img.mirrored(); -} - -QImage qt_gl_read_frame_buffer(const QSize &size, bool alpha_format, bool include_alpha) -{ - QImage img(size, (alpha_format && include_alpha) ? QImage::Format_ARGB32_Premultiplied - : QImage::Format_RGB32); - if (img.isNull()) - return QImage(); - int w = size.width(); - int h = size.height(); - qgl_functions()->glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); - convertFromGLImage(img, w, h, alpha_format, include_alpha); - return img; -} - -QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha) -{ - QImage img(size, alpha_format ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); - if (img.isNull()) - return QImage(); - int w = size.width(); - int h = size.height(); -#ifndef QT_OPENGL_ES - if (!QOpenGLContext::currentContext()->isOpenGLES()) { - - qgl1_functions()->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; -} - -Q_GLOBAL_STATIC(QGLTextureCache, qt_gl_texture_cache) - -QGLTextureCache::QGLTextureCache() - : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though -{ - QImagePixmapCleanupHooks::instance()->addPlatformPixmapModificationHook(cleanupTexturesForPixampData); - QImagePixmapCleanupHooks::instance()->addPlatformPixmapDestructionHook(cleanupBeforePixmapDestruction); - QImagePixmapCleanupHooks::instance()->addImageHook(cleanupTexturesForCacheKey); -} - -QGLTextureCache::~QGLTextureCache() -{ - QImagePixmapCleanupHooks::instance()->removePlatformPixmapModificationHook(cleanupTexturesForPixampData); - QImagePixmapCleanupHooks::instance()->removePlatformPixmapDestructionHook(cleanupBeforePixmapDestruction); - QImagePixmapCleanupHooks::instance()->removeImageHook(cleanupTexturesForCacheKey); -} - -void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost) -{ - QWriteLocker locker(&m_lock); - const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)}; - const bool inserted = m_cache.insert(cacheKey, texture, cost); - Q_UNUSED(inserted) Q_ASSERT(inserted); -} - -void QGLTextureCache::remove(qint64 key) -{ - QWriteLocker locker(&m_lock); - QMutexLocker groupLocker(&qt_context_groups()->m_mutex); - QList<QGLContextGroup *>::const_iterator it = qt_context_groups()->m_list.constBegin(); - while (it != qt_context_groups()->m_list.constEnd()) { - const QGLTextureCacheKey cacheKey = {key, *it}; - m_cache.remove(cacheKey); - ++it; - } -} - -bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId) -{ - QWriteLocker locker(&m_lock); - QList<QGLTextureCacheKey> keys = m_cache.keys(); - for (int i = 0; i < keys.size(); ++i) { - QGLTexture *tex = m_cache.object(keys.at(i)); - if (tex->id == textureId && tex->context == ctx) { - tex->options |= QGLContext::MemoryManagedBindOption; // forces a glDeleteTextures() call - m_cache.remove(keys.at(i)); - return true; - } - } - return false; -} - -void QGLTextureCache::removeContextTextures(QGLContext* ctx) -{ - QWriteLocker locker(&m_lock); - QList<QGLTextureCacheKey> keys = m_cache.keys(); - for (int i = 0; i < keys.size(); ++i) { - const QGLTextureCacheKey &key = keys.at(i); - if (m_cache.object(key)->context == ctx) - m_cache.remove(key); - } -} - -/* - a hook that removes textures from the cache when a pixmap/image - is deref'ed -*/ -void QGLTextureCache::cleanupTexturesForCacheKey(qint64 cacheKey) -{ - qt_gl_texture_cache()->remove(cacheKey); -} - - -void QGLTextureCache::cleanupTexturesForPixampData(QPlatformPixmap* pmd) -{ - cleanupTexturesForCacheKey(pmd->cacheKey()); -} - -void QGLTextureCache::cleanupBeforePixmapDestruction(QPlatformPixmap* pmd) -{ - // Remove any bound textures first: - cleanupTexturesForPixampData(pmd); -} - -QGLTextureCache *QGLTextureCache::instance() -{ - return qt_gl_texture_cache(); -} - -// DDS format structure -struct DDSFormat { - quint32 dwSize; - quint32 dwFlags; - quint32 dwHeight; - quint32 dwWidth; - quint32 dwLinearSize; - quint32 dummy1; - quint32 dwMipMapCount; - quint32 dummy2[11]; - struct { - quint32 dummy3[2]; - quint32 dwFourCC; - quint32 dummy4[5]; - } ddsPixelFormat; -}; - -// compressed texture pixel formats -#define FOURCC_DXT1 0x31545844 -#define FOURCC_DXT2 0x32545844 -#define FOURCC_DXT3 0x33545844 -#define FOURCC_DXT4 0x34545844 -#define FOURCC_DXT5 0x35545844 - -// ####TODO Properly #ifdef this class to use #define symbols actually defined -// by system GL includes -#ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#endif - -#ifndef GL_COMPRESSED_RGBA_S3TC_DXT1_EXT -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#endif - -#ifndef GL_COMPRESSED_RGBA_S3TC_DXT3_EXT -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#endif - -#ifndef GL_COMPRESSED_RGBA_S3TC_DXT5_EXT -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#endif - -#ifndef GL_GENERATE_MIPMAP_SGIS -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif - -/*! - \class QGLContext - \inmodule QtOpenGL - \obsolete - - \brief The QGLContext class encapsulates an OpenGL rendering context. - - An OpenGL rendering context is a complete set of OpenGL state - variables. The rendering context's \l {QGL::FormatOption} {format} - is set in the constructor, but it can also be set later with - setFormat(). The format options that are actually set are returned - by format(); the options you asked for are returned by - requestedFormat(). Note that after a QGLContext object has been - constructed, the actual OpenGL context must be created by - explicitly calling the \l{create()} - function. The makeCurrent() function makes this context the - current rendering context. You can make \e no context current - using doneCurrent(). The reset() function will reset the context - and make it invalid. - - You can examine properties of the context with, e.g. isValid(), - isSharing(), initialized(), windowCreated() and - overlayTransparentColor(). - - If you're using double buffering you can swap the screen contents - with the off-screen buffer using swapBuffers(). - - Please note that QGLContext is not thread safe. -*/ - -/*! - \enum QGLContext::BindOption - \since 4.6 - - A set of options to decide how to bind a texture using bindTexture(). - - \value NoBindOption Don't do anything, pass the texture straight - through. - - \value InvertedYBindOption Specifies that the texture should be flipped - over the X axis so that the texture coordinate 0,0 corresponds to - the top left corner. Inverting the texture implies a deep copy - prior to upload. - - \value MipmapBindOption Specifies that bindTexture() should try - to generate mipmaps. If the GL implementation supports the \c - GL_SGIS_generate_mipmap extension, mipmaps will be automatically - generated for the texture. Mipmap generation is only supported for - the \c GL_TEXTURE_2D target. - - \value PremultipliedAlphaBindOption Specifies that the image should be - uploaded with premultiplied alpha and does a conversion accordingly. - - \value LinearFilteringBindOption Specifies that the texture filtering - should be set to GL_LINEAR. Default is GL_NEAREST. If mipmap is - also enabled, filtering will be set to GL_LINEAR_MIPMAP_LINEAR. - - \value DefaultBindOption In Qt 4.5 and earlier, bindTexture() - would mirror the image and automatically generate mipmaps. This - option helps preserve this default behavior. - - \omitvalue CanFlipNativePixmapBindOption \omit Used by x11 from pixmap to choose - whether or not it can bind the pixmap upside down or not. \endomit - - \omitvalue MemoryManagedBindOption \omit Used by paint engines to - indicate that the pixmap should be memory managed along side with - the pixmap/image that it stems from, e.g. installing destruction - hooks in them. \endomit - - \omitvalue TemporarilyCachedBindOption \omit Used by paint engines on some - platforms to indicate that the pixmap or image texture is possibly - cached only temporarily and must be destroyed immediately after the use. \endomit - - \omitvalue InternalBindOption -*/ - -/*! - \obsolete - - Constructs an OpenGL context for the given paint \a device, which - can be a widget or a pixmap. The \a format specifies several - display options for the context. - - If the underlying OpenGL/Window system cannot satisfy all the - features requested in \a format, the nearest subset of features - will be used. After creation, the format() method will return the - actual format obtained. - - Note that after a QGLContext object has been constructed, \l - create() must be called explicitly to create the actual OpenGL - context. The context will be \l {isValid()}{invalid} if it was not - possible to obtain a GL context at all. -*/ - -QGLContext::QGLContext(const QGLFormat &format, QPaintDevice *device) - : d_ptr(new QGLContextPrivate(this)) -{ - Q_D(QGLContext); - d->init(device, format); -} - -/*! - Constructs an OpenGL context with the given \a format which - specifies several display options for the context. - - If the underlying OpenGL/Window system cannot satisfy all the - features requested in \a format, the nearest subset of features - will be used. After creation, the format() method will return the - actual format obtained. - - Note that after a QGLContext object has been constructed, \l - create() must be called explicitly to create the actual OpenGL - context. The context will be \l {isValid()}{invalid} if it was not - possible to obtain a GL context at all. - - \sa format(), isValid() -*/ -QGLContext::QGLContext(const QGLFormat &format) - : d_ptr(new QGLContextPrivate(this)) -{ - Q_D(QGLContext); - d->init(0, format); -} - -static void qDeleteQGLContext(void *handle) -{ - QGLContext *context = static_cast<QGLContext *>(handle); - delete context; -} - -QGLContext::QGLContext(QOpenGLContext *context) - : d_ptr(new QGLContextPrivate(this)) -{ - Q_D(QGLContext); - d->init(0, QGLFormat::fromSurfaceFormat(context->format())); - d->guiGlContext = context; - d->guiGlContext->setQGLContextHandle(this, qDeleteQGLContext); - d->ownContext = false; - d->valid = context->isValid(); - d->setupSharing(); -} - -/*! - Returns the OpenGL context handle. -*/ -QOpenGLContext *QGLContext::contextHandle() const -{ - Q_D(const QGLContext); - return d->guiGlContext; -} - -/*! - Returns an OpenGL context for the window context specified by the \a context - parameter. -*/ -QGLContext *QGLContext::fromOpenGLContext(QOpenGLContext *context) -{ - if (!context) - return 0; - if (context->qGLContextHandle()) { - return reinterpret_cast<QGLContext *>(context->qGLContextHandle()); - } - QGLContext *glContext = new QGLContext(context); - //Don't call create on context. This can cause the platformFormat to be set on the widget, which - //will cause the platformWindow to be recreated. - return glContext; -} - -/*! - Destroys the OpenGL context and frees its resources. -*/ - -QGLContext::~QGLContext() -{ - // remove any textures cached in this context - QGLTextureCache::instance()->removeContextTextures(this); - - // clean up resources specific to this context - d_ptr->cleanup(); - - QGLSignalProxy::instance()->emitAboutToDestroyContext(this); - reset(); -} - -void QGLContextPrivate::cleanup() -{ -} - -#define ctx q_ptr -void QGLContextPrivate::setVertexAttribArrayEnabled(int arrayIndex, bool enabled) -{ - Q_Q(QGLContext); - Q_ASSERT(arrayIndex < QT_GL_VERTEX_ARRAY_TRACKED_COUNT); -#ifdef glEnableVertexAttribArray - Q_ASSERT(glEnableVertexAttribArray); -#endif - - if (vertexAttributeArraysEnabledState[arrayIndex] && !enabled) - q->functions()->glDisableVertexAttribArray(arrayIndex); - - if (!vertexAttributeArraysEnabledState[arrayIndex] && enabled) - q->functions()->glEnableVertexAttribArray(arrayIndex); - - vertexAttributeArraysEnabledState[arrayIndex] = enabled; -} - -void QGLContextPrivate::syncGlState() -{ - Q_Q(QGLContext); -#ifdef glEnableVertexAttribArray - Q_ASSERT(glEnableVertexAttribArray); -#endif - for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) { - if (vertexAttributeArraysEnabledState[i]) - q->functions()->glEnableVertexAttribArray(i); - else - q->functions()->glDisableVertexAttribArray(i); - } - -} -#undef ctx - -void QGLContextPrivate::swapRegion(const QRegion &) -{ - Q_Q(QGLContext); - q->swapBuffers(); -} - -/*! - \overload - - Reads the compressed texture file \a fileName and generates a 2D GL - texture from it. - - This function can load DirectDrawSurface (DDS) textures in the - DXT1, DXT3 and DXT5 DDS formats if the \c GL_ARB_texture_compression - and \c GL_EXT_texture_compression_s3tc extensions are supported. - - Since 4.6.1, textures in the ETC1 format can be loaded if the - \c GL_OES_compressed_ETC1_RGB8_texture extension is supported - and the ETC1 texture has been encapsulated in the PVR container format. - Also, textures in the PVRTC2 and PVRTC4 formats can be loaded - if the \c GL_IMG_texture_compression_pvrtc extension is supported. - - \sa deleteTexture() -*/ - -GLuint QGLContext::bindTexture(const QString &fileName) -{ - QGLTexture texture(this); - QSize size = texture.bindCompressedTexture(fileName); - if (!size.isValid()) - return 0; - return texture.id; -} - -static inline QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format) -{ - if (texture_format == GL_BGRA) { - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - return ((src_pixel << 24) & 0xff000000) - | ((src_pixel >> 24) & 0x000000ff) - | ((src_pixel << 8) & 0x00ff0000) - | ((src_pixel >> 8) & 0x0000ff00); - } else { - return src_pixel; - } - } else { // GL_RGBA - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - return (src_pixel << 8) | ((src_pixel >> 24) & 0xff); - } else { - return ((src_pixel << 16) & 0xff0000) - | ((src_pixel >> 16) & 0xff) - | (src_pixel & 0xff00ff00); - } - } -} - -static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum texture_format) -{ - Q_ASSERT(dst.depth() == 32); - Q_ASSERT(img.depth() == 32); - - if (dst.size() != img.size()) { - int target_width = dst.width(); - int target_height = dst.height(); - qreal sx = target_width / qreal(img.width()); - qreal sy = target_height / qreal(img.height()); - - quint32 *dest = (quint32 *) dst.scanLine(0); // NB! avoid detach here - const uchar *srcPixels = img.constScanLine(img.height() - 1); - int sbpl = img.bytesPerLine(); - int dbpl = dst.bytesPerLine(); - - int ix = int(0x00010000 / sx); - int iy = int(0x00010000 / sy); - - quint32 basex = int(0.5 * ix); - quint32 srcy = int(0.5 * iy); - - // scale, swizzle and mirror in one loop - while (target_height--) { - const uint *src = (const quint32 *) (srcPixels - (srcy >> 16) * sbpl); - int srcx = basex; - for (int x=0; x<target_width; ++x) { - dest[x] = qt_gl_convertToGLFormatHelper(src[srcx >> 16], texture_format); - srcx += ix; - } - dest = (quint32 *)(((uchar *) dest) + dbpl); - srcy += iy; - } - } else { - const int width = img.width(); - const int height = img.height(); - const uint *p = (const uint*) img.scanLine(img.height() - 1); - uint *q = (uint*) dst.scanLine(0); - - if (texture_format == GL_BGRA) { - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - // mirror + swizzle - for (int i=0; i < height; ++i) { - const uint *end = p + width; - while (p < end) { - *q = ((*p << 24) & 0xff000000) - | ((*p >> 24) & 0x000000ff) - | ((*p << 8) & 0x00ff0000) - | ((*p >> 8) & 0x0000ff00); - p++; - q++; - } - p -= 2 * width; - } - } else { - const uint bytesPerLine = img.bytesPerLine(); - for (int i=0; i < height; ++i) { - memcpy(q, p, bytesPerLine); - q += width; - p -= width; - } - } - } else { - if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { - for (int i=0; i < height; ++i) { - const uint *end = p + width; - while (p < end) { - *q = (*p << 8) | ((*p >> 24) & 0xff); - p++; - q++; - } - p -= 2 * width; - } - } else { - for (int i=0; i < height; ++i) { - const uint *end = p + width; - while (p < end) { - *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00); - p++; - q++; - } - p -= 2 * width; - } - } - } - } -} - -/*! \internal */ -QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, - QGLContext::BindOptions options) -{ - Q_Q(QGLContext); - - const qint64 key = image.cacheKey(); - QGLTexture *texture = textureCacheLookup(key, target); - if (texture) { - if (image.paintingActive()) { - // A QPainter is active on the image - take the safe route and replace the texture. - q->deleteTexture(texture->id); - texture = 0; - } else { - qgl_functions()->glBindTexture(target, texture->id); - return texture; - } - } - - if (!texture) - texture = bindTexture(image, target, format, key, options); - // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null - Q_ASSERT(texture); - - // Enable the cleanup hooks for this image so that the texture cache entry is removed when the - // image gets deleted: - QImagePixmapCleanupHooks::enableCleanupHooks(image); - - return texture; -} - -// #define QGL_BIND_TEXTURE_DEBUG - -// ####TODO Properly #ifdef this file to use #define symbols actually defined -// by OpenGL/ES includes -#ifndef GL_UNSIGNED_INT_8_8_8_8_REV -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#endif - -// map from Qt's ARGB endianness-dependent format to GL's big-endian RGBA layout -static inline void qgl_byteSwapImage(QImage &img, GLenum pixel_type) -{ - const int width = img.width(); - const int height = img.height(); - - if (pixel_type == GL_UNSIGNED_INT_8_8_8_8_REV - || (pixel_type == GL_UNSIGNED_BYTE && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) - { - for (int i = 0; i < height; ++i) { - uint *p = (uint *) img.scanLine(i); - for (int x = 0; x < width; ++x) - p[x] = ((p[x] << 16) & 0xff0000) | ((p[x] >> 16) & 0xff) | (p[x] & 0xff00ff00); - } - } else { - for (int i = 0; i < height; ++i) { - uint *p = (uint *) img.scanLine(i); - for (int x = 0; x < width; ++x) - p[x] = (p[x] << 8) | ((p[x] >> 24) & 0xff); - } - } -} - -QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint internalFormat, - const qint64 key, QGLContext::BindOptions options) -{ - Q_Q(QGLContext); - QOpenGLFunctions *funcs = qgl_functions(); - -#ifdef QGL_BIND_TEXTURE_DEBUG - printf("QGLContextPrivate::bindTexture(), imageSize=(%d,%d), internalFormat =0x%x, options=%x, key=%llx\n", - image.width(), image.height(), internalFormat, int(options), key); - QTime time; - time.start(); -#endif - -#ifndef QT_NO_DEBUG - // Reset the gl error stack...git - while (funcs->glGetError() != GL_NO_ERROR) ; -#endif - - // Scale the pixmap if needed. GL textures needs to have the - // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL - // 2.0 or use the GL_TEXTURE_RECTANGLE texture target - int tx_w = qNextPowerOfTwo(image.width() - 1); - int tx_h = qNextPowerOfTwo(image.height() - 1); - - QImage img = image; - - if (!qgl_extensions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures) - && !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0) - && (target == GL_TEXTURE_2D && (tx_w != image.width() || tx_h != image.height()))) - { - img = img.scaled(tx_w, tx_h); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - upscaled to %dx%d (%d ms)\n", tx_w, tx_h, time.elapsed()); - -#endif - } - - GLuint filtering = options & QGLContext::LinearFilteringBindOption ? GL_LINEAR : GL_NEAREST; - - GLuint tx_id; - funcs->glGenTextures(1, &tx_id); - funcs->glBindTexture(target, tx_id); - funcs->glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filtering); - - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - bool genMipmap = !ctx->isOpenGLES(); - if (glFormat.directRendering() - && (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::GenerateMipmap)) - && target == GL_TEXTURE_2D - && (options & QGLContext::MipmapBindOption)) - { -#if !defined(QT_OPENGL_ES_2) - if (genMipmap) { - funcs->glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST); - funcs->glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); - } else { - funcs->glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); - genMipmap = true; - } -#else - funcs->glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST); - genMipmap = true; -#endif - funcs->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, options & QGLContext::LinearFilteringBindOption - ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - generating mipmaps (%d ms)\n", time.elapsed()); -#endif - } else { - funcs->glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filtering); - } - - QImage::Format target_format = img.format(); - bool premul = options & QGLContext::PremultipliedAlphaBindOption; - bool needsbyteswap = true; - GLenum externalFormat; - GLuint pixel_type; - if (target_format == QImage::Format_RGBA8888 - || target_format == QImage::Format_RGBA8888_Premultiplied - || target_format == QImage::Format_RGBX8888) { - externalFormat = GL_RGBA; - pixel_type = GL_UNSIGNED_BYTE; - needsbyteswap = false; - } else if (qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::BGRATextureFormat)) { - externalFormat = GL_BGRA; - needsbyteswap = false; - if (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2) - pixel_type = GL_UNSIGNED_INT_8_8_8_8_REV; - else - pixel_type = GL_UNSIGNED_BYTE; - } else { - externalFormat = GL_RGBA; - pixel_type = GL_UNSIGNED_BYTE; - } - - switch (target_format) { - case QImage::Format_ARGB32: - if (premul) { - img = img.convertToFormat(target_format = QImage::Format_ARGB32_Premultiplied); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converted ARGB32 -> ARGB32_Premultiplied (%d ms) \n", time.elapsed()); -#endif - } - break; - case QImage::Format_ARGB32_Premultiplied: - if (!premul) { - img = img.convertToFormat(target_format = QImage::Format_ARGB32); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converted ARGB32_Premultiplied -> ARGB32 (%d ms)\n", time.elapsed()); -#endif - } - break; - case QImage::Format_RGBA8888: - if (premul) { - img = img.convertToFormat(target_format = QImage::Format_RGBA8888_Premultiplied); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converted RGBA8888 -> RGBA8888_Premultiplied (%d ms) \n", time.elapsed()); -#endif - } - break; - case QImage::Format_RGBA8888_Premultiplied: - if (!premul) { - img = img.convertToFormat(target_format = QImage::Format_RGBA8888); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converted RGBA8888_Premultiplied -> RGBA8888 (%d ms) \n", time.elapsed()); -#endif - } - break; - case QImage::Format_RGB16: - pixel_type = GL_UNSIGNED_SHORT_5_6_5; - externalFormat = GL_RGB; - internalFormat = GL_RGB; - needsbyteswap = false; - break; - case QImage::Format_RGB32: - case QImage::Format_RGBX8888: - break; - default: - // Ideally more formats would be converted directly to an RGBA8888 format, - // but we are only guaranteed to have a fast conversion to an ARGB format. - if (img.hasAlphaChannel()) { - img = img.convertToFormat(premul - ? QImage::Format_ARGB32_Premultiplied - : QImage::Format_ARGB32); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converted to 32-bit alpha format (%d ms)\n", time.elapsed()); -#endif - } else { - img = img.convertToFormat(QImage::Format_RGB32); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - converted to 32-bit (%d ms)\n", time.elapsed()); -#endif - } - } - - if (options & QGLContext::InvertedYBindOption) { - if (img.isDetached()) { - int ipl = img.bytesPerLine() / 4; - int h = img.height(); - for (int y=0; y<h/2; ++y) { - int *a = (int *) img.scanLine(y); - int *b = (int *) img.scanLine(h - y - 1); - for (int x=0; x<ipl; ++x) - qSwap(a[x], b[x]); - } - } else { - // Create a new image and copy across. If we use the - // above in-place code then a full copy of the image is - // made before the lines are swapped, which processes the - // data twice. This version should only do it once. - img = img.mirrored(); - } -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - flipped bits over y (%d ms)\n", time.elapsed()); -#endif - } - - if (needsbyteswap) { - // The only case where we end up with a depth different from - // 32 in the switch above is for the RGB16 case, where we do - // not need a byteswap. - Q_ASSERT(img.depth() == 32); - qgl_byteSwapImage(img, pixel_type); -#ifdef QGL_BIND_TEXTURE_DEBUG - printf(" - did byte swapping (%d ms)\n", time.elapsed()); -#endif - } - if (ctx->isOpenGLES()) { - // 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); -#endif - - const QImage &constRef = img; // to avoid detach in bits()... - funcs->glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, - pixel_type, constRef.bits()); - if (genMipmap && ctx->isOpenGLES()) - q->functions()->glGenerateMipmap(target); -#ifndef QT_NO_DEBUG - GLenum error = funcs->glGetError(); - if (error != GL_NO_ERROR) { - qWarning(" - texture upload failed, error code 0x%x, enum: %d (%x)\n", error, target, target); - } -#endif - -#ifdef QGL_BIND_TEXTURE_DEBUG - static int totalUploadTime = 0; - totalUploadTime += time.elapsed(); - printf(" - upload done in %d ms, (accumulated: %d ms)\n", time.elapsed(), totalUploadTime); -#endif - - - // this assumes the size of a texture is always smaller than the max cache size - int cost = img.width()*img.height()*4/1024; - QGLTexture *texture = new QGLTexture(q, tx_id, target, options); - QGLTextureCache::instance()->insert(q, key, texture, cost); - - return texture; -} - -QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target) -{ - Q_Q(QGLContext); - QGLTexture *texture = QGLTextureCache::instance()->getTexture(q, key); - if (texture && texture->target == target - && (texture->context == q || QGLContext::areSharing(q, texture->context))) - { - return texture; - } - return 0; -} - -/*! \internal */ -QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, QGLContext::BindOptions options) -{ - Q_Q(QGLContext); - QPlatformPixmap *pd = pixmap.handle(); - Q_UNUSED(pd); - - const qint64 key = pixmap.cacheKey(); - QGLTexture *texture = textureCacheLookup(key, target); - if (texture) { - if (pixmap.paintingActive()) { - // A QPainter is active on the pixmap - take the safe route and replace the texture. - q->deleteTexture(texture->id); - texture = 0; - } else { - qgl_functions()->glBindTexture(target, texture->id); - return texture; - } - } - - if (!texture) { - QImage image; - QPaintEngine* paintEngine = pixmap.paintEngine(); - if (!paintEngine || paintEngine->type() != QPaintEngine::Raster) - image = pixmap.toImage(); - else { - // QRasterPixmapData::toImage() will deep-copy the backing QImage if there's an active QPainter on it. - // For performance reasons, we don't want that here, so we temporarily redirect the paint engine. - QPaintDevice* currentPaintDevice = paintEngine->paintDevice(); - paintEngine->setPaintDevice(0); - image = pixmap.toImage(); - paintEngine->setPaintDevice(currentPaintDevice); - } - - // If the system depth is 16 and the pixmap doesn't have an alpha channel - // then we convert it to RGB16 in the hope that it gets uploaded as a 16 - // bit texture which is much faster to access than a 32-bit one. - if (pixmap.depth() == 16 && !image.hasAlphaChannel() ) - image = image.convertToFormat(QImage::Format_RGB16); - texture = bindTexture(image, target, format, key, options); - } - // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null - Q_ASSERT(texture); - - if (texture->id > 0) - QImagePixmapCleanupHooks::enableCleanupHooks(pixmap); - - return texture; -} - -/*! \internal */ -int QGLContextPrivate::maxTextureSize() -{ - if (max_texture_size != -1) - return max_texture_size; - - QOpenGLFunctions *funcs = qgl_functions(); - funcs->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - -#ifndef QT_OPENGL_ES - Q_Q(QGLContext); - if (!q->contextHandle()->isOpenGLES()) { - GLenum proxy = GL_PROXY_TEXTURE_2D; - - GLint size; - GLint next = 64; - funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); - gl1funcs->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; - funcs->glTexImage2D(proxy, 0, GL_RGBA, next, next, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - gl1funcs->glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &next); - } while (next > size); - - max_texture_size = size; - } -#endif - - return max_texture_size; -} - -/*! - Returns a QGLFunctions object that is initialized for this context. - */ -QGLFunctions *QGLContext::functions() const -{ - QGLContextPrivate *d = const_cast<QGLContextPrivate *>(d_func()); - if (!d->functions) { - d->functions = new QGLFunctions(this); - d->functions->initializeGLFunctions(this); - } - return d->functions; -} - -/*! - Generates and binds a 2D GL texture to the current context, based - on \a image. The generated texture id is returned and can be used in - later \c glBindTexture() calls. - - \overload -*/ -GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format) -{ - if (image.isNull()) - return 0; - - Q_D(QGLContext); - QGLTexture *texture = d->bindTexture(image, target, format, DefaultBindOption); - return texture->id; -} - -/*! - \since 4.6 - - Generates and binds a 2D GL texture to the current context, based - on \a image. The generated texture id is returned and can be used - in later \c glBindTexture() calls. - - The \a target parameter specifies the texture target. The default - target is \c GL_TEXTURE_2D. - - The \a format parameter sets the internal format for the - texture. The default format is \c GL_RGBA. - - The binding \a options are a set of options used to decide how to - bind the texture to the context. - - The texture that is generated is cached, so multiple calls to - bindTexture() with the same QImage will return the same texture - id. - - Note that we assume default values for the glPixelStore() and - glPixelTransfer() parameters. - - \sa deleteTexture() -*/ -GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format, BindOptions options) -{ - if (image.isNull()) - return 0; - - Q_D(QGLContext); - QGLTexture *texture = d->bindTexture(image, target, format, options); - return texture->id; -} - -/*! \overload - - Generates and binds a 2D GL texture based on \a pixmap. -*/ -GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format) -{ - if (pixmap.isNull()) - return 0; - - Q_D(QGLContext); - QGLTexture *texture = d->bindTexture(pixmap, target, format, DefaultBindOption); - return texture->id; -} - -/*! - \overload - \since 4.6 - - Generates and binds a 2D GL texture to the current context, based - on \a pixmap. -*/ -GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, BindOptions options) -{ - if (pixmap.isNull()) - return 0; - - Q_D(QGLContext); - QGLTexture *texture = d->bindTexture(pixmap, target, format, options); - return texture->id; -} - -/*! - Removes the texture identified by \a id from the texture cache, - and calls glDeleteTextures() to delete the texture from the - context. - - \sa bindTexture() -*/ -void QGLContext::deleteTexture(GLuint id) -{ - if (QGLTextureCache::instance()->remove(this, id)) - return; - qgl_functions()->glDeleteTextures(1, &id); -} - -void qt_add_rect_to_array(const QRectF &r, GLfloat *array) -{ - qreal left = r.left(); - qreal right = r.right(); - qreal top = r.top(); - qreal bottom = r.bottom(); - - array[0] = left; - array[1] = top; - array[2] = right; - array[3] = top; - array[4] = right; - array[5] = bottom; - array[6] = left; - array[7] = bottom; -} - -void qt_add_texcoords_to_array(qreal x1, qreal y1, qreal x2, qreal y2, GLfloat *array) -{ - array[0] = x1; - array[1] = y1; - array[2] = x2; - array[3] = y1; - array[4] = x2; - array[5] = y2; - array[6] = x1; - array[7] = y2; -} - -#if !defined(QT_OPENGL_ES_2) - -static void qDrawTextureRect(const QRectF &target, GLint textureWidth, GLint textureHeight, GLenum textureTarget) -{ - QOpenGLFunctions *funcs = qgl_functions(); - GLfloat tx = 1.0f; - GLfloat ty = 1.0f; - -#ifdef QT_OPENGL_ES - Q_UNUSED(textureWidth); - Q_UNUSED(textureHeight); - Q_UNUSED(textureTarget); -#else - if (textureTarget != GL_TEXTURE_2D && !QOpenGLContext::currentContext()->isOpenGLES()) { - if (textureWidth == -1 || textureHeight == -1) { - QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); - gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); - gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_HEIGHT, &textureHeight); - } - - tx = GLfloat(textureWidth); - ty = GLfloat(textureHeight); - } -#endif - - GLfloat texCoordArray[4*2] = { - 0, ty, tx, ty, tx, 0, 0, 0 - }; - - GLfloat vertexArray[4*2]; - qt_add_rect_to_array(target, vertexArray); - - QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); - gl1funcs->glVertexPointer(2, GL_FLOAT, 0, vertexArray); - gl1funcs->glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); - - gl1funcs->glEnableClientState(GL_VERTEX_ARRAY); - gl1funcs->glEnableClientState(GL_TEXTURE_COORD_ARRAY); - funcs->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - gl1funcs->glDisableClientState(GL_VERTEX_ARRAY); - gl1funcs->glDisableClientState(GL_TEXTURE_COORD_ARRAY); -} - -#endif // !QT_OPENGL_ES_2 - -/*! - \since 4.4 - - This function supports the following use cases: - - \list - \li On OpenGL and OpenGL ES 1.x it draws the given texture, \a textureId, - to the given target rectangle, \a target, in OpenGL model space. The - \a textureTarget should be a 2D texture target. - \li On OpenGL and OpenGL ES 2.x, if a painter is active, not inside a - beginNativePainting / endNativePainting block, and uses the - engine with type QPaintEngine::OpenGL2, the function will draw the given - texture, \a textureId, to the given target rectangle, \a target, - respecting the current painter state. This will let you draw a texture - with the clip, transform, render hints, and composition mode set by the - painter. Note that the texture target needs to be GL_TEXTURE_2D for this - use case, and that this is the only supported use case under OpenGL ES 2.x. - \endlist - -*/ -void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) -{ -#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_ES_2) - 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 src(0, 0, target.width(), target.height()); - QSize size(target.width(), target.height()); - if (eng->drawTexture(target, textureId, size, src)) - return; - } - } -#endif - -#ifndef QT_OPENGL_ES_2 - QOpenGLFunctions *funcs = qgl_functions(); - if (!contextHandle()->isOpenGLES()) { -#ifdef QT_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 = funcs->glIsEnabled(GL_TEXTURE_2D); - GLint oldTexture; - funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); -#endif - - funcs->glEnable(textureTarget); - funcs->glBindTexture(textureTarget, textureId); - - qDrawTextureRect(target, -1, -1, textureTarget); - -#ifdef QT_OPENGL_ES - funcs->glDisable(textureTarget); -#else - if (!wasEnabled) - funcs->glDisable(textureTarget); - funcs->glBindTexture(textureTarget, oldTexture); -#endif - return; - } -#else - Q_UNUSED(target); - Q_UNUSED(textureId); - Q_UNUSED(textureTarget); -#endif - qWarning("drawTexture() with OpenGL ES 2.0 requires an active OpenGL2 paint engine"); -} - -/*! - \since 4.4 - - This function supports the following use cases: - - \list - \li By default it draws the given texture, \a textureId, - at the given \a point in OpenGL model space. The - \a textureTarget should be a 2D texture target. - \li If a painter is active, not inside a - beginNativePainting / endNativePainting block, and uses the - engine with type QPaintEngine::OpenGL2, the function will draw the given - texture, \a textureId, at the given \a point, - respecting the current painter state. This will let you draw a texture - with the clip, transform, render hints, and composition mode set by the - painter. Note that the texture target needs to be GL_TEXTURE_2D for this - use case. - \endlist - - \note This function is not supported under any version of OpenGL ES. -*/ -void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) -{ -#ifdef QT_OPENGL_ES - Q_UNUSED(point); - Q_UNUSED(textureId); - Q_UNUSED(textureTarget); -#else - if (!contextHandle()->isOpenGLES()) { - QOpenGLFunctions *funcs = qgl_functions(); - const bool wasEnabled = funcs->glIsEnabled(GL_TEXTURE_2D); - GLint oldTexture; - funcs->glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTexture); - - funcs->glEnable(textureTarget); - funcs->glBindTexture(textureTarget, textureId); - - GLint textureWidth; - GLint textureHeight; - - QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); - gl1funcs->glGetTexLevelParameteriv(textureTarget, 0, GL_TEXTURE_WIDTH, &textureWidth); - gl1funcs->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; - } - } - - qDrawTextureRect(QRectF(point, QSizeF(textureWidth, textureHeight)), textureWidth, textureHeight, textureTarget); - - if (!wasEnabled) - funcs->glDisable(textureTarget); - funcs->glBindTexture(textureTarget, oldTexture); - return; - } -#endif - qWarning("drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) not supported with OpenGL ES, use rect version instead"); -} - -/*! - This function sets the limit for the texture cache to \a size, - expressed in kilobytes. - - By default, the cache limit is approximately 64 MB. - - \sa textureCacheLimit() -*/ -void QGLContext::setTextureCacheLimit(int size) -{ - QGLTextureCache::instance()->setMaxCost(size); -} - -/*! - Returns the current texture cache limit in kilobytes. - - \sa setTextureCacheLimit() -*/ -int QGLContext::textureCacheLimit() -{ - return QGLTextureCache::instance()->maxCost(); -} - - -/*! - \fn QGLFormat QGLContext::format() const - - Returns the frame buffer format that was obtained (this may be a - subset of what was requested). - - \sa requestedFormat() -*/ - -/*! - \fn QGLFormat QGLContext::requestedFormat() const - - Returns the frame buffer format that was originally requested in - the constructor or setFormat(). - - \sa format() -*/ - -/*! - Sets a \a format for this context. The context is \l{reset()}{reset}. - - Call create() to create a new GL context that tries to match the - new format. - - \snippet code/src_opengl_qgl.cpp 7 - - \sa format(), reset(), create() -*/ - -void QGLContext::setFormat(const QGLFormat &format) -{ - Q_D(QGLContext); - reset(); - d->glFormat = d->reqFormat = format; -} - -/*! - \internal -*/ -void QGLContext::setDevice(QPaintDevice *pDev) -{ - Q_D(QGLContext); - // Do not touch the valid flag here. The context is either a new one and - // valid is not yet set or it is adapted from a valid QOpenGLContext in which - // case it must remain valid. - d->paintDevice = pDev; - if (d->paintDevice && (d->paintDevice->devType() != QInternal::Widget - && d->paintDevice->devType() != QInternal::Pixmap - && d->paintDevice->devType() != QInternal::Pbuffer)) { - qWarning("QGLContext: Unsupported paint device type"); - } -} - -/*! - \fn bool QGLContext::isValid() const - - Returns \c true if a GL rendering context has been successfully - created; otherwise returns \c false. -*/ - -/*! - \fn void QGLContext::setValid(bool valid) - \internal - - Forces the GL rendering context to be valid. -*/ - -/*! - \fn bool QGLContext::isSharing() const - - Returns \c true if this context is sharing its GL context with - another QGLContext, otherwise false is returned. Note that context - sharing might not be supported between contexts with different - formats. -*/ - -/*! - Returns \c true if \a context1 and \a context2 are sharing their - GL resources such as textures, shader programs, etc; - otherwise returns \c false. - - \since 4.6 -*/ -bool QGLContext::areSharing(const QGLContext *context1, const QGLContext *context2) -{ - if (!context1 || !context2) - return false; - return context1->d_ptr->group == context2->d_ptr->group; -} - -/*! - \fn bool QGLContext::deviceIsPixmap() const - - Returns \c true if the paint device of this context is a pixmap; - otherwise returns \c false. - - Since Qt 5 the paint device is never actually a pixmap. renderPixmap() is - however still simulated using framebuffer objects and readbacks, and this - function will return \c true in this case. -*/ - -/*! - \fn bool QGLContext::windowCreated() const - - Returns \c true if a window has been created for this context; - otherwise returns \c false. - - \sa setWindowCreated() -*/ - -/*! - \fn void QGLContext::setWindowCreated(bool on) - - If \a on is true the context has had a window created for it. If - \a on is false no window has been created for the context. - - \sa windowCreated() -*/ - -/*! - \fn uint QGLContext::colorIndex(const QColor& c) const - - \internal - - Returns a colormap index for the color c, in ColorIndex mode. Used - by qglColor() and qglClearColor(). -*/ -uint QGLContext::colorIndex(const QColor&) const -{ - return 0; -} - -/*! - \fn bool QGLContext::initialized() const - - Returns \c true if this context has been initialized, i.e. if - QGLWidget::initializeGL() has been performed on it; otherwise - returns \c false. - - \sa setInitialized() -*/ - -/*! - \fn void QGLContext::setInitialized(bool on) - - If \a on is true the context has been initialized, i.e. - QGLContext::setInitialized() has been called on it. If \a on is - false the context has not been initialized. - - \sa initialized() -*/ - -/*! - \fn const QGLContext* QGLContext::currentContext() - - Returns the current context, i.e. the context to which any OpenGL - commands will currently be directed. Returns 0 if no context is - current. - - \sa makeCurrent() -*/ - -/*! - \fn QColor QGLContext::overlayTransparentColor() const - - If this context is a valid context in an overlay plane, returns - the plane's transparent color. Otherwise returns an \l{QColor::isValid()}{invalid} color. - - The returned color's \l{QColormap::pixel()}{pixel} value is - the index of the transparent color in the colormap of the overlay - plane. (Naturally, the color's RGB values are meaningless.) - - The returned QColor object will generally work as expected only - when passed as the argument to QGLWidget::qglColor() or - QGLWidget::qglClearColor(). Under certain circumstances it can - also be used to draw transparent graphics with a QPainter. -*/ -QColor QGLContext::overlayTransparentColor() const -{ - return QColor(); // Invalid color -} - -/*! - Creates the GL context. Returns \c true if it was successful in - creating a valid GL rendering context on the paint device - specified in the constructor; otherwise returns \c false (i.e. the - context is invalid). - - If the OpenGL implementation on your system does not support the requested - version of OpenGL context, then QGLContext will try to create the closest - matching version. The actual created context properties can be queried - using the QGLFormat returned by the format() function. For example, if - you request a context that supports OpenGL 4.3 Core profile but the driver - and/or hardware only supports version 3.2 Core profile contexts then you will - get a 3.2 Core profile context. - - After successful creation, format() returns the set of features of - the created GL rendering context. - - If \a shareContext points to a valid QGLContext, this method will - try to establish OpenGL display list and texture object sharing - between this context and the \a shareContext. Note that this may - fail if the two contexts have different \l {format()} {formats}. - Use isSharing() to see if sharing is in effect. - - \warning Implementation note: initialization of C++ class - members usually takes place in the class constructor. QGLContext - is an exception because it must be simple to customize. The - virtual functions chooseContext() (and chooseVisual() for X11) can - be reimplemented in a subclass to select a particular context. The - problem is that virtual functions are not properly called during - construction (even though this is correct C++) because C++ - constructs class hierarchies from the bottom up. For this reason - we need a create() function. - - \sa chooseContext(), format(), isValid() -*/ - -bool QGLContext::create(const QGLContext* shareContext) -{ - Q_D(QGLContext); - if (!d->paintDevice && !d->guiGlContext) - return false; - - reset(); - d->valid = chooseContext(shareContext); - if (d->valid && d->paintDevice && d->paintDevice->devType() == QInternal::Widget) { - QWidgetPrivate *wd = qt_widget_private(static_cast<QWidget *>(d->paintDevice)); - wd->usesDoubleBufferedGLContext = d->glFormat.doubleBuffer(); - } - return d->valid; -} - -bool QGLContext::isValid() const -{ - Q_D(const QGLContext); - return d->valid; -} - -void QGLContext::setValid(bool valid) -{ - Q_D(QGLContext); - d->valid = valid; -} - -bool QGLContext::isSharing() const -{ - Q_D(const QGLContext); - return d->group->isSharing(); -} - -QGLFormat QGLContext::format() const -{ - Q_D(const QGLContext); - return d->glFormat; -} - -QGLFormat QGLContext::requestedFormat() const -{ - Q_D(const QGLContext); - return d->reqFormat; -} - - QPaintDevice* QGLContext::device() const -{ - Q_D(const QGLContext); - return d->paintDevice; -} - -bool QGLContext::deviceIsPixmap() const -{ - Q_D(const QGLContext); - return !d->readback_target_size.isEmpty(); -} - - -bool QGLContext::windowCreated() const -{ - Q_D(const QGLContext); - return d->crWin; -} - - -void QGLContext::setWindowCreated(bool on) -{ - Q_D(QGLContext); - d->crWin = on; -} - -bool QGLContext::initialized() const -{ - Q_D(const QGLContext); - return d->initDone; -} - -void QGLContext::setInitialized(bool on) -{ - Q_D(QGLContext); - d->initDone = on; -} - -const QGLContext* QGLContext::currentContext() -{ - if (const QOpenGLContext *threadContext = QOpenGLContext::currentContext()) { - return QGLContext::fromOpenGLContext(const_cast<QOpenGLContext *>(threadContext)); - } - return 0; -} - -void QGLContextPrivate::setCurrentContext(QGLContext *context) -{ - Q_UNUSED(context); -} - -/*! - Moves the QGLContext to the given \a thread. - - Enables calling swapBuffers() and makeCurrent() on the context in - the given thread. -*/ -void QGLContext::moveToThread(QThread *thread) -{ - Q_D(QGLContext); - if (d->guiGlContext) - d->guiGlContext->moveToThread(thread); -} - -/*! - \fn bool QGLContext::chooseContext(const QGLContext* shareContext = 0) - - This semi-internal function is called by create(). It creates a - system-dependent OpenGL handle that matches the format() of \a - shareContext as closely as possible, returning true if successful - or false if a suitable handle could not be found. - - On Windows, it calls the virtual function choosePixelFormat(), - which finds a matching pixel format identifier. On X11, it calls - the virtual function chooseVisual() which finds an appropriate X - visual. On other platforms it may work differently. -*/ -bool QGLContext::chooseContext(const QGLContext* shareContext) -{ - Q_D(QGLContext); - if(!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) { - // Unlike in Qt 4, the only possible target is a widget backed by an OpenGL-based - // QWindow. Pixmaps in particular are not supported anymore as paint devices since - // starting from Qt 5 QPixmap is raster-backed on almost all platforms. - d->valid = false; - }else { - QWidget *widget = static_cast<QWidget *>(d->paintDevice); - QGLFormat glformat = format(); - QSurfaceFormat winFormat = QGLFormat::toSurfaceFormat(glformat); - if (widget->testAttribute(Qt::WA_TranslucentBackground)) - winFormat.setAlphaBufferSize(qMax(winFormat.alphaBufferSize(), 8)); - - QWindow *window = widget->windowHandle(); - if (!window->handle() - || window->surfaceType() != QWindow::OpenGLSurface - || window->requestedFormat() != winFormat) - { - window->setSurfaceType(QWindow::OpenGLSurface); - window->setFormat(winFormat); - window->destroy(); - window->create(); - } - - if (d->ownContext) - delete d->guiGlContext; - d->ownContext = true; - QOpenGLContext *shareGlContext = shareContext ? shareContext->d_func()->guiGlContext : 0; - d->guiGlContext = new QOpenGLContext; - d->guiGlContext->setFormat(winFormat); - d->guiGlContext->setShareContext(shareGlContext); - d->valid = d->guiGlContext->create(); - - if (d->valid) - d->guiGlContext->setQGLContextHandle(this, 0); - - d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format()); - d->setupSharing(); - } - - - return d->valid; -} - -/*! - \fn void QGLContext::reset() - - Resets the context and makes it invalid. - - \sa create(), isValid() -*/ -void QGLContext::reset() -{ - Q_D(QGLContext); - if (!d->valid) - return; - d->cleanup(); - - d->crWin = false; - d->sharing = false; - d->valid = false; - d->transpColor = QColor(); - d->initDone = false; - QGLContextGroup::removeShare(this); - if (d->guiGlContext) { - if (QOpenGLContext::currentContext() == d->guiGlContext) - doneCurrent(); - if (d->ownContext) { - if (d->guiGlContext->thread() == QThread::currentThread()) - delete d->guiGlContext; - else - d->guiGlContext->deleteLater(); - } else - d->guiGlContext->setQGLContextHandle(0,0); - d->guiGlContext = 0; - } - d->ownContext = false; -} - -/*! - \fn void QGLContext::makeCurrent() - - Makes this context the current OpenGL rendering context. All GL - functions you call operate on this context until another context - is made current. - - In some very rare cases the underlying call may fail. If this - occurs an error message is output to stderr. - - If you call this from a thread other than the main UI thread, - make sure you've first pushed the context to the relevant thread - from the UI thread using moveToThread(). -*/ -void QGLContext::makeCurrent() -{ - Q_D(QGLContext); - if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) - return; - - QWidget *widget = static_cast<QWidget *>(d->paintDevice); - if (!widget->windowHandle()) - return; - - if (d->guiGlContext->makeCurrent(widget->windowHandle())) { - if (!d->workaroundsCached) { - d->workaroundsCached = true; - const char *renderer = reinterpret_cast<const char *>(d->guiGlContext->functions()->glGetString(GL_RENDERER)); - if (renderer && strstr(renderer, "Mali")) { - d->workaround_brokenFBOReadBack = true; - } - } - } -} - -/*! - \fn void QGLContext::swapBuffers() const - - Call this to finish a frame of OpenGL rendering, and make sure to - call makeCurrent() again before issuing any further OpenGL commands, - for example as part of a new frame. -*/ -void QGLContext::swapBuffers() const -{ - Q_D(const QGLContext); - if (!d->paintDevice || d->paintDevice->devType() != QInternal::Widget) - return; - - QWidget *widget = static_cast<QWidget *>(d->paintDevice); - if (!widget->windowHandle()) - return; - - d->guiGlContext->swapBuffers(widget->windowHandle()); -} - -/*! - \fn void QGLContext::doneCurrent() - - Makes no GL context the current context. Normally, you do not need - to call this function; QGLContext calls it as necessary. -*/ -void QGLContext::doneCurrent() -{ - Q_D(QGLContext); - d->guiGlContext->doneCurrent(); -} - -/*! - \fn QPaintDevice* QGLContext::device() const - - Returns the paint device set for this context. - - \sa QGLContext::QGLContext() -*/ - -/***************************************************************************** - QGLWidget implementation - *****************************************************************************/ - - -/*! - \class QGLWidget - \inmodule QtOpenGL - \obsolete - - \brief The QGLWidget class is a widget for rendering OpenGL graphics. - - QGLWidget provides functionality for displaying OpenGL graphics - integrated into a Qt application. It is very simple to use. You - inherit from it and use the subclass like any other QWidget, - except that you have the choice between using QPainter and - standard OpenGL rendering commands. - - \note This class is part of the legacy \l {Qt OpenGL} module and, - like the other \c QGL classes, should be avoided in the new - applications. Instead, starting from Qt 5.4, prefer using - QOpenGLWidget and the \c QOpenGL classes. - - QGLWidget provides three convenient virtual functions that you can - reimplement in your subclass to perform the typical OpenGL tasks: - - \list - \li paintGL() - Renders the OpenGL scene. Gets called whenever the widget - needs to be updated. - \li resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets - called whenever the widget has been resized (and also when it - is shown for the first time because all newly created widgets get a - resize event automatically). - \li initializeGL() - Sets up the OpenGL rendering context, defines display - lists, etc. Gets called once before the first time resizeGL() or - paintGL() is called. - \endlist - - Here is a rough outline of how a QGLWidget subclass might look: - - \snippet code/src_opengl_qgl.cpp 8 - - If you need to trigger a repaint from places other than paintGL() - (a typical example is when using \l{QTimer}{timers} to - animate scenes), you should call the widget's updateGL() function. - - Your widget's OpenGL rendering context is made current when - paintGL(), resizeGL(), or initializeGL() is called. If you need to - call the standard OpenGL API functions from other places (e.g. in - your widget's constructor or in your own paint functions), you - must call makeCurrent() first. - - QGLWidget provides functions for requesting a new display - \l{QGLFormat}{format} and you can also create widgets with - customized rendering \l{QGLContext}{contexts}. - - You can also share OpenGL display lists between QGLWidget objects (see - the documentation of the QGLWidget constructors for details). - - Note that under Windows, the QGLContext belonging to a QGLWidget - has to be recreated when the QGLWidget is reparented. This is - necessary due to limitations on the Windows platform. This will - most likely cause problems for users that have subclassed and - installed their own QGLContext on a QGLWidget. It is possible to - work around this issue by putting the QGLWidget inside a dummy - widget and then reparenting the dummy widget, instead of the - QGLWidget. This will side-step the issue altogether, and is what - we recommend for users that need this kind of functionality. - - On \macos, when Qt is built with Cocoa support, a QGLWidget - can't have any sibling widgets placed ontop of itself. This is due - to limitations in the Cocoa API and is not supported by Apple. - - \section1 Overlays - - The QGLWidget creates a GL overlay context in addition to the - normal context if overlays are supported by the underlying system. - - If you want to use overlays, you specify it in the - \l{QGLFormat}{format}. (Note: Overlay must be requested in the format - passed to the QGLWidget constructor.) Your GL widget should also - implement some or all of these virtual methods: - - \list - \li paintOverlayGL() - \li resizeOverlayGL() - \li initializeOverlayGL() - \endlist - - These methods work in the same way as the normal paintGL() etc. - functions, except that they will be called when the overlay - context is made current. You can explicitly make the overlay - context current by using makeOverlayCurrent(), and you can access - the overlay context directly (e.g. to ask for its transparent - color) by calling overlayContext(). - - On X servers in which the default visual is in an overlay plane, - non-GL Qt windows can also be used for overlays. - - \section1 Painting Techniques - - As described above, subclass QGLWidget to render pure 3D content in the - following way: - - \list - \li Reimplement the QGLWidget::initializeGL() and QGLWidget::resizeGL() to - set up the OpenGL state and provide a perspective transformation. - \li Reimplement QGLWidget::paintGL() to paint the 3D scene, calling only - OpenGL functions to draw on the widget. - \endlist - - It is also possible to draw 2D graphics onto a QGLWidget subclass, it is necessary - to reimplement QGLWidget::paintEvent() and do the following: - - \list - \li Construct a QPainter object. - \li Initialize it for use on the widget with the QPainter::begin() function. - \li Draw primitives using QPainter's member functions. - \li Call QPainter::end() to finish painting. - \endlist - - \section1 Threading - - As of Qt version 4.8, support for doing threaded GL rendering has - been improved. There are three scenarios that we currently support: - \list - \li 1. Buffer swapping in a thread. - - Swapping buffers in a double buffered context may be a - synchronous, locking call that may be a costly operation in some - GL implementations. Especially so on embedded devices. It's not - optimal to have the CPU idling while the GPU is doing a buffer - swap. In those cases it is possible to do the rendering in the - main thread and do the actual buffer swap in a separate - thread. This can be done with the following steps: - - 1. Call doneCurrent() in the main thread when the rendering is - finished. - - 2. Call QGLContext::moveToThread(swapThread) to transfer ownership - of the context to the swapping thread. - - 3. Notify the swapping thread that it can grab the context. - - 4. Make the rendering context current in the swapping thread with - makeCurrent() and then call swapBuffers(). - - 5. Call doneCurrent() in the swapping thread. - - 6. Call QGLContext::moveToThread(qApp->thread()) and notify the - main thread that swapping is done. - - Doing this will free up the main thread so that it can continue - with, for example, handling UI events or network requests. Even if - there is a context swap involved, it may be preferable compared to - having the main thread wait while the GPU finishes the swap - operation. Note that this is highly implementation dependent. - - \li 2. Texture uploading in a thread. - - Doing texture uploads in a thread may be very useful for - applications handling large amounts of images that needs to be - displayed, like for instance a photo gallery application. This is - supported in Qt through the existing bindTexture() API. A simple - way of doing this is to create two sharing QGLWidgets. One is made - current in the main GUI thread, while the other is made current in - the texture upload thread. The widget in the uploading thread is - never shown, it is only used for sharing textures with the main - thread. For each texture that is bound via bindTexture(), notify - the main thread so that it can start using the texture. - - \li 3. Using QPainter to draw into a QGLWidget in a thread. - - In Qt 4.8, it is possible to draw into a QGLWidget using a - QPainter in a separate thread. Note that this is also possible for - QGLPixelBuffers and QGLFramebufferObjects. Since this is only - supported in the GL 2 paint engine, OpenGL 2.0 or OpenGL ES 2.0 is - required. - - QGLWidgets can only be created in the main GUI thread. This means - a call to doneCurrent() is necessary to release the GL context - from the main thread, before the widget can be drawn into by - another thread. You then need to call QGLContext::moveToThread() - to transfer ownership of the context to the thread in which you - want to make it current. - Also, the main GUI thread will dispatch resize and - paint events to a QGLWidget when the widget is resized, or parts - of it becomes exposed or needs redrawing. It is therefore - necessary to handle those events because the default - implementations inside QGLWidget will try to make the QGLWidget's - context current, which again will interfere with any threads - rendering into the widget. Reimplement QGLWidget::paintEvent() and - QGLWidget::resizeEvent() to notify the rendering thread that a - resize or update is necessary, and be careful not to call the base - class implementation. If you are rendering an animation, it might - not be necessary to handle the paint event at all since the - rendering thread is doing regular updates. Then it would be enough - to reimplement QGLWidget::paintEvent() to do nothing. - - \endlist - - As a general rule when doing threaded rendering: be aware that - binding and releasing contexts in different threads have to be - synchronized by the user. A GL rendering context can only be - current in one thread at any time. If you try to open a QPainter - on a QGLWidget and the widget's rendering context is current in - another thread, it will fail. - - In addition to this, rendering using raw GL calls in a separate - thread is supported. - - \e{OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other - countries.} - - \sa QOpenGLWidget, QGLPixelBuffer -*/ - -/*! - Constructs an OpenGL widget with a \a parent widget. - - The \l{QGLFormat::defaultFormat()}{default format} is - used. The widget will be \l{isValid()}{invalid} if the - system has no \l{QGLFormat::hasOpenGL()}{OpenGL support}. - - The \a parent and widget flag, \a f, arguments are passed - to the QWidget constructor. - - If \a shareWidget is a valid QGLWidget, this widget will share - OpenGL display lists and texture objects with \a shareWidget. But - if \a shareWidget and this widget have different \l {format()} - {formats}, sharing might not be possible. You can check whether - sharing is in effect by calling isSharing(). - - The initialization of OpenGL rendering state, etc. should be done - by overriding the initializeGL() function, rather than in the - constructor of your QGLWidget subclass. - - \sa QGLFormat::defaultFormat(), {Textures Example} -*/ - -QGLWidget::QGLWidget(QWidget *parent, const QGLWidget* shareWidget, Qt::WindowFlags f) - : QWidget(*(new QGLWidgetPrivate), parent, f) -{ - Q_D(QGLWidget); - d->init(new QGLContext(QGLFormat::defaultFormat(), this), shareWidget); -} - -/*! - \internal - */ -QGLWidget::QGLWidget(QGLWidgetPrivate &dd, const QGLFormat &format, QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f) - : QWidget(dd, parent, f) -{ - Q_D(QGLWidget); - d->init(new QGLContext(format, this), shareWidget); - -} - - -/*! - Constructs an OpenGL widget with parent \a parent. - - The \a format argument specifies the desired - \l{QGLFormat}{rendering options}. - If the underlying OpenGL/Window system - cannot satisfy all the features requested in \a format, the - nearest subset of features will be used. After creation, the - format() method will return the actual format obtained. - - The widget will be \l{isValid()}{invalid} if the system - has no \l{QGLFormat::hasOpenGL()}{OpenGL support}. - - The \a parent and widget flag, \a f, arguments are passed - to the QWidget constructor. - - If \a shareWidget is a valid QGLWidget, this widget will share - OpenGL display lists and texture objects with \a shareWidget. But - if \a shareWidget and this widget have different \l {format()} - {formats}, sharing might not be possible. You can check whether - sharing is in effect by calling isSharing(). - - The initialization of OpenGL rendering state, etc. should be done - by overriding the initializeGL() function, rather than in the - constructor of your QGLWidget subclass. - - \sa QGLFormat::defaultFormat(), isValid() -*/ - -QGLWidget::QGLWidget(const QGLFormat &format, QWidget *parent, const QGLWidget* shareWidget, - Qt::WindowFlags f) - : QWidget(*(new QGLWidgetPrivate), parent, f) -{ - Q_D(QGLWidget); - d->init(new QGLContext(format, this), shareWidget); -} - -/*! - Constructs an OpenGL widget with parent \a parent. - - The \a context argument is a pointer to the QGLContext that - you wish to be bound to this widget. This allows you to pass in - your own QGLContext sub-classes. - - The widget will be \l{isValid()}{invalid} if the system - has no \l{QGLFormat::hasOpenGL()}{OpenGL support}. - - The \a parent and widget flag, \a f, arguments are passed - to the QWidget constructor. - - If \a shareWidget is a valid QGLWidget, this widget will share - OpenGL display lists and texture objects with \a shareWidget. But - if \a shareWidget and this widget have different \l {format()} - {formats}, sharing might not be possible. You can check whether - sharing is in effect by calling isSharing(). - - The initialization of OpenGL rendering state, etc. should be done - by overriding the initializeGL() function, rather than in the - constructor of your QGLWidget subclass. - - \sa QGLFormat::defaultFormat(), isValid() -*/ -QGLWidget::QGLWidget(QGLContext *context, QWidget *parent, const QGLWidget *shareWidget, - Qt::WindowFlags f) - : QWidget(*(new QGLWidgetPrivate), parent, f) -{ - Q_D(QGLWidget); - d->init(context, shareWidget); -} - -/*! - Destroys the widget. -*/ - -QGLWidget::~QGLWidget() -{ - Q_D(QGLWidget); - delete d->glcx; - d->glcx = 0; - d->cleanupColormaps(); -} - -/*! - \fn QGLFormat QGLWidget::format() const - - Returns the format of the contained GL rendering context. -*/ - -/*! - \fn bool QGLWidget::doubleBuffer() const - - Returns \c true if the contained GL rendering context has double - buffering; otherwise returns \c false. - - \sa QGLFormat::doubleBuffer() -*/ - -/*! - \fn void QGLWidget::setAutoBufferSwap(bool on) - - If \a on is true automatic GL buffer swapping is switched on; - otherwise it is switched off. - - If \a on is true and the widget is using a double-buffered format, - the background and foreground GL buffers will automatically be - swapped after each paintGL() call. - - The buffer auto-swapping is on by default. - - \sa autoBufferSwap(), doubleBuffer(), swapBuffers() -*/ - -/*! - \fn bool QGLWidget::autoBufferSwap() const - - Returns \c true if the widget is doing automatic GL buffer swapping; - otherwise returns \c false. - - \sa setAutoBufferSwap() -*/ - -/*! - \fn QFunctionPointer QGLContext::getProcAddress(const QString &proc) const - - Returns a function pointer to the GL extension function passed in - \a proc. \nullptr is returned if a pointer to the function could not be - obtained. -*/ -QFunctionPointer QGLContext::getProcAddress(const QString &procName) const -{ - Q_D(const QGLContext); - return d->guiGlContext->getProcAddress(procName.toLatin1()); -} - -/*! - \fn bool QGLWidget::isValid() const - - Returns \c true if the widget has a valid GL rendering context; - otherwise returns \c false. A widget will be invalid if the system - has no \l{QGLFormat::hasOpenGL()}{OpenGL support}. -*/ - -bool QGLWidget::isValid() const -{ - Q_D(const QGLWidget); - return d->glcx && d->glcx->isValid(); -} - -/*! - \fn bool QGLWidget::isSharing() const - - Returns \c true if this widget's GL context is shared with another GL - context, otherwise false is returned. Context sharing might not be - possible if the widgets use different formats. - - \sa format() -*/ - -bool QGLWidget::isSharing() const -{ - Q_D(const QGLWidget); - return d->glcx->isSharing(); -} - -/*! - \fn void QGLWidget::makeCurrent() - - Makes this widget the current widget for OpenGL operations, i.e. - makes the widget's rendering context the current OpenGL rendering - context. -*/ - -void QGLWidget::makeCurrent() -{ - Q_D(QGLWidget); - d->makeCurrent(); -} - -bool QGLWidgetPrivate::makeCurrent() -{ - glcx->makeCurrent(); - return QGLContext::currentContext() == glcx; -} - -/*! - \fn void QGLWidget::doneCurrent() - - Makes no GL context the current context. Normally, you do not need - to call this function; QGLContext calls it as necessary. However, - it may be useful in multithreaded environments. -*/ - -void QGLWidget::doneCurrent() -{ - Q_D(QGLWidget); - d->glcx->doneCurrent(); -} - -/*! - \fn void QGLWidget::swapBuffers() - - Swaps the screen contents with an off-screen buffer. This only - works if the widget's format specifies double buffer mode. - - Normally, there is no need to explicitly call this function - because it is done automatically after each widget repaint, i.e. - each time after paintGL() has been executed. - - \sa doubleBuffer(), setAutoBufferSwap(), QGLFormat::setDoubleBuffer() -*/ - -void QGLWidget::swapBuffers() -{ - Q_D(QGLWidget); - d->glcx->swapBuffers(); -} - - -/*! - \fn const QGLContext* QGLWidget::overlayContext() const - - Returns the overlay context of this widget, or \nullptr if this - widget has no overlay. - - \sa context() -*/ -const QGLContext* QGLWidget::overlayContext() const -{ - return nullptr; -} - -/*! - \fn void QGLWidget::makeOverlayCurrent() - - Makes the overlay context of this widget current. Use this if you - need to issue OpenGL commands to the overlay context outside of - initializeOverlayGL(), resizeOverlayGL(), and paintOverlayGL(). - - Does nothing if this widget has no overlay. - - \sa makeCurrent() -*/ -void QGLWidget::makeOverlayCurrent() -{ -} - -/*! - \obsolete - - Sets a new format for this widget. - - If the underlying OpenGL/Window system cannot satisfy all the - features requested in \a format, the nearest subset of features will - be used. After creation, the format() method will return the actual - rendering context format obtained. - - The widget will be assigned a new QGLContext, and the initializeGL() - function will be executed for this new context before the first - resizeGL() or paintGL(). - - This method will try to keep display list and texture object sharing - in effect with other QGLWidget objects, but changing the format might make - sharing impossible. Use isSharing() to see if sharing is still in - effect. - - \sa format(), isSharing(), isValid() -*/ - -void QGLWidget::setFormat(const QGLFormat &format) -{ - setContext(new QGLContext(format,this)); -} - - - - -/*! - \fn QGLContext *QGLWidget::context() const - - Returns the context of this widget. - - It is possible that the context is not valid (see isValid()), for - example, if the underlying hardware does not support the format - attributes that were requested. -*/ - -/*! - \fn void QGLWidget::setContext(QGLContext *context, - const QGLContext* shareContext, - bool deleteOldContext) - \obsolete - - Sets a new context for this widget. The QGLContext \a context must - be created using \e new. QGLWidget will delete \a context when - another context is set or when the widget is destroyed. - - If \a context is invalid, QGLContext::create() is performed on - it. The initializeGL() function will then be executed for the new - context before the first resizeGL() or paintGL(). - - If \a context is invalid, this method will try to keep display list - and texture object sharing in effect, or (if \a shareContext points - to a valid context) start display list and texture object sharing - with that context, but sharing might be impossible if the two - contexts have different \l {format()} {formats}. Use isSharing() to - see whether sharing is in effect. - - If \a deleteOldContext is true (the default), the existing context - will be deleted. You may use false here if you have kept a pointer - to the old context (as returned by context()), and want to restore - that context later. - - \note This function is obsolete and should no longer be used. If you were - using it to recreate the context for a QGLWidget, you should instead create a - new QGLWidget or use the QOpenGLContext API in conjunction with QWindow. - There is currently no officially supported way to substitute QGLWidget's - context with your own implementation of QGLContext. - - \sa context(), isSharing() -*/ -void QGLWidget::setContext(QGLContext *context, - const QGLContext* shareContext, - bool deleteOldContext) -{ - Q_D(QGLWidget); - if (context == 0) { - qWarning("QGLWidget::setContext: Cannot set null context"); - return; - } - - if (context->device() == 0) // a context may refere to more than 1 window. - context->setDevice(this); //but its better to point to 1 of them than none of them. - - QGLContext* oldcx = d->glcx; - d->glcx = context; - - if (!d->glcx->isValid()) - d->glcx->create(shareContext ? shareContext : oldcx); - - if (deleteOldContext) - delete oldcx; -} - -/*! - \fn void QGLWidget::updateGL() - - Updates the widget by calling glDraw(). -*/ - -void QGLWidget::updateGL() -{ - Q_D(QGLWidget); - const bool targetIsOffscreen = !d->glcx->d_ptr->readback_target_size.isEmpty(); - if (updatesEnabled() && (testAttribute(Qt::WA_Mapped) || targetIsOffscreen)) - glDraw(); -} - - -/*! - \fn void QGLWidget::updateOverlayGL() - - Updates the widget's overlay (if any). Will cause the virtual - function paintOverlayGL() to be executed. - - The widget's rendering context will become the current context and - initializeGL() will be called if it hasn't already been called. -*/ -void QGLWidget::updateOverlayGL() -{ -} - -/*! - This virtual function is called once before the first call to - paintGL() or resizeGL(), and then once whenever the widget has - been assigned a new QGLContext. Reimplement it in a subclass. - - This function should set up any required OpenGL context rendering - flags, defining display lists, etc. - - There is no need to call makeCurrent() because this has already - been done when this function is called. -*/ - -void QGLWidget::initializeGL() -{ -} - - -/*! - This virtual function is called whenever the widget needs to be - painted. Reimplement it in a subclass. - - There is no need to call makeCurrent() because this has already - been done when this function is called. -*/ - -void QGLWidget::paintGL() -{ - qgl_functions()->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); -} - - -/*! - \fn void QGLWidget::resizeGL(int width , int height) - - This virtual function is called whenever the widget has been - resized. The new size is passed in \a width and \a height. - Reimplement it in a subclass. - - There is no need to call makeCurrent() because this has already - been done when this function is called. -*/ - -void QGLWidget::resizeGL(int, int) -{ -} - - - -/*! - This virtual function is used in the same manner as initializeGL() - except that it operates on the widget's overlay context instead of - the widget's main context. This means that initializeOverlayGL() - is called once before the first call to paintOverlayGL() or - resizeOverlayGL(). Reimplement it in a subclass. - - This function should set up any required OpenGL context rendering - flags, defining display lists, etc. for the overlay context. - - There is no need to call makeOverlayCurrent() because this has - already been done when this function is called. -*/ - -void QGLWidget::initializeOverlayGL() -{ -} - - -/*! - This virtual function is used in the same manner as paintGL() - except that it operates on the widget's overlay context instead of - the widget's main context. This means that paintOverlayGL() is - called whenever the widget's overlay needs to be painted. - Reimplement it in a subclass. - - There is no need to call makeOverlayCurrent() because this has - already been done when this function is called. -*/ - -void QGLWidget::paintOverlayGL() -{ -} - - -/*! - \fn void QGLWidget::resizeOverlayGL(int width , int height) - - This virtual function is used in the same manner as paintGL() - except that it operates on the widget's overlay context instead of - the widget's main context. This means that resizeOverlayGL() is - called whenever the widget has been resized. The new size is - passed in \a width and \a height. Reimplement it in a subclass. - - There is no need to call makeOverlayCurrent() because this has - already been done when this function is called. -*/ - -void QGLWidget::resizeOverlayGL(int, int) -{ -} - -/*!\reimp -*/ -bool QGLWidget::event(QEvent *e) -{ - Q_D(QGLWidget); - - // A re-parent will destroy the window and re-create it. We should not reset the context while it happens. - if (e->type() == QEvent::ParentAboutToChange) - d->parent_changing = true; - - if (e->type() == QEvent::ParentChange) - d->parent_changing = false; - - return QWidget::event(e); -} - -/*! - \fn void QGLWidget::paintEvent(QPaintEvent *event) - - Handles paint events passed in the \a event parameter. Will cause - the virtual paintGL() function to be called. - - The widget's rendering context will become the current context and - initializeGL() will be called if it hasn't already been called. -*/ - -void QGLWidget::paintEvent(QPaintEvent *) -{ - if (updatesEnabled()) { - glDraw(); - updateOverlayGL(); - } -} - - -/*! - \fn void QGLWidget::resizeEvent(QResizeEvent *event) - - Handles resize events that are passed in the \a event parameter. - Calls the virtual function resizeGL(). -*/ -void QGLWidget::resizeEvent(QResizeEvent *e) -{ - Q_D(QGLWidget); - - QWidget::resizeEvent(e); - if (!isValid()) - return; - if (!d->makeCurrent()) - return; - if (!d->glcx->initialized()) - glInit(); - const qreal scaleFactor = (window() && window()->windowHandle()) ? - window()->windowHandle()->devicePixelRatio() : 1.0; - - resizeGL(width() * scaleFactor, height() * scaleFactor); -} - -/*! - Renders the current scene on a pixmap and returns the pixmap. - - You can use this method on both visible and invisible QGLWidget objects. - - Internally the function renders into a framebuffer object and performs pixel - readback. This has a performance penalty, meaning that this function is not - suitable to be called at a high frequency. - - After creating and binding the framebuffer object, the function will call - initializeGL(), resizeGL(), and paintGL(). On the next normal update - initializeGL() and resizeGL() will be triggered again since the size of the - destination pixmap and the QGLWidget's size may differ. - - The size of the pixmap will be \a w pixels wide and \a h pixels high unless - one of these parameters is 0 (the default), in which case the pixmap will - have the same size as the widget. - - Care must be taken when using framebuffer objects in paintGL() in - combination with this function. To switch back to the default framebuffer, - use QGLFramebufferObject::bindDefault(). Binding FBO 0 is wrong since - renderPixmap() uses a custom framebuffer instead of the one provided by the - windowing system. - - \a useContext is ignored. Historically this parameter enabled the usage of - the existing GL context. This is not supported anymore since additional - contexts are never created. - - Overlays are not rendered onto the pixmap. - - If the GL rendering context and the desktop have different bit - depths, the result will most likely look surprising. - - Note that the creation of display lists, modifications of the view - frustum etc. should be done from within initializeGL(). If this is - not done, the temporary QGLContext will not be initialized - properly, and the rendered pixmap may be incomplete/corrupted. -*/ - -QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext) -{ - Q_UNUSED(useContext); - Q_D(QGLWidget); - - QSize sz = size(); - if ((w > 0) && (h > 0)) - sz = QSize(w, h); - - QPixmap pm; - if (d->glcx->isValid()) { - d->glcx->makeCurrent(); - QGLFramebufferObject fbo(sz, QGLFramebufferObject::CombinedDepthStencil); - fbo.bind(); - d->glcx->setInitialized(false); - uint prevDefaultFbo = d->glcx->d_ptr->default_fbo; - d->glcx->d_ptr->default_fbo = fbo.handle(); - d->glcx->d_ptr->readback_target_size = sz; - updateGL(); - fbo.release(); - pm = QPixmap::fromImage(fbo.toImage()); - d->glcx->d_ptr->default_fbo = prevDefaultFbo; - d->glcx->setInitialized(false); - d->glcx->d_ptr->readback_target_size = QSize(); - } - - return pm; -} - -/*! - Returns an image of the frame buffer. If \a withAlpha is true the - alpha channel is included. - - Depending on your hardware, you can explicitly select which color - buffer to grab with a glReadBuffer() call before calling this - function. - - On QNX the back buffer is not preserved when swapBuffers() is called. The back buffer - where this function reads from, might thus not contain the same content as the front buffer. - In order to retrieve what is currently visible on the screen, swapBuffers() - has to be executed prior to this function call. -*/ -QImage QGLWidget::grabFrameBuffer(bool withAlpha) -{ - makeCurrent(); - QImage res; - qreal pixelRatio = devicePixelRatioF(); - int w = pixelRatio * width(); - int h = pixelRatio * height(); - if (format().rgba()) - res = qt_gl_read_frame_buffer(QSize(w, h), format().alpha(), withAlpha); - res.setDevicePixelRatio(pixelRatio); - return res; -} - - - -/*! - Initializes OpenGL for this widget's context. Calls the virtual - function initializeGL(). -*/ - -void QGLWidget::glInit() -{ - Q_D(QGLWidget); - if (!isValid()) - return; - if (!d->makeCurrent()) - return; - initializeGL(); - d->glcx->setInitialized(true); -} - - -/*! - Executes the virtual function paintGL(). - - The widget's rendering context will become the current context and - initializeGL() will be called if it hasn't already been called. -*/ - -void QGLWidget::glDraw() -{ - Q_D(QGLWidget); - if (!isValid()) - return; - if (!d->makeCurrent()) - return; -#ifndef QT_OPENGL_ES - if (d->glcx->deviceIsPixmap() && !d->glcx->contextHandle()->isOpenGLES()) - qgl1_functions()->glDrawBuffer(GL_FRONT); -#endif - QSize readback_target_size = d->glcx->d_ptr->readback_target_size; - if (!d->glcx->initialized()) { - glInit(); - const qreal scaleFactor = (window() && window()->windowHandle()) ? - window()->windowHandle()->devicePixelRatio() : 1.0; - int w, h; - if (readback_target_size.isEmpty()) { - w = d->glcx->device()->width() * scaleFactor; - h = d->glcx->device()->height() * scaleFactor; - } else { - w = readback_target_size.width(); - h = readback_target_size.height(); - } - resizeGL(w, h); // New context needs this "resize" - } - paintGL(); - if (doubleBuffer() && readback_target_size.isEmpty()) { - if (d->autoSwap) - swapBuffers(); - } else { - qgl_functions()->glFlush(); - } -} - -/*! - Convenience function for specifying a drawing color to OpenGL. - Calls glColor4 (in RGBA mode) or glIndex (in color-index mode) - with the color \a c. Applies to this widgets GL context. - - \note This function is not supported on OpenGL/ES 2.0 systems. - - \sa qglClearColor(), QGLContext::currentContext(), QColor -*/ - -void QGLWidget::qglColor(const QColor& c) const -{ -#if !defined(QT_OPENGL_ES_2) -#ifdef QT_OPENGL_ES - qgl_functions()->glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF()); -#else - Q_D(const QGLWidget); - const QGLContext *ctx = QGLContext::currentContext(); - if (ctx && !ctx->contextHandle()->isOpenGLES()) { - if (ctx->format().rgba()) - qgl1_functions()->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()); - qgl1_functions()->glIndexi(i); - } else - qgl1_functions()->glIndexi(ctx->colorIndex(c)); - } -#endif //QT_OPENGL_ES -#else - Q_UNUSED(c); -#endif //QT_OPENGL_ES_2 -} - -/*! - Convenience function for specifying the clearing color to OpenGL. - Calls glClearColor (in RGBA mode) or glClearIndex (in color-index - mode) with the color \a c. Applies to this widgets GL context. - - \sa qglColor(), QGLContext::currentContext(), QColor -*/ - -void QGLWidget::qglClearColor(const QColor& c) const -{ -#ifdef QT_OPENGL_ES - qgl_functions()->glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); -#else - Q_D(const QGLWidget); - const QGLContext *ctx = QGLContext::currentContext(); - if (ctx && !ctx->contextHandle()->isOpenGLES()) { - if (ctx->format().rgba()) - qgl_functions()->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()); - qgl1_functions()->glClearIndex(i); - } else { - qgl1_functions()->glClearIndex(ctx->colorIndex(c)); - } - } else { - qgl_functions()->glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF()); - } -#endif -} - - -/*! - Converts the image \a img into the unnamed format expected by - OpenGL functions such as glTexImage2D(). The returned image is not - usable as a QImage, but QImage::width(), QImage::height() and - QImage::bits() may be used with OpenGL. The GL format used is - \c GL_RGBA. - - \omit ### - - \l opengl/texture example - The following few lines are from the texture example. Most of the - code is irrelevant, so we just quote the relevant bits: - - \quotefromfile opengl/texture/gltexobj.cpp - \skipto tex1 - \printline tex1 - \printline gllogo.bmp - - We create \e tex1 (and another variable) for OpenGL, and load a real - image into \e buf. - - \skipto convertToGLFormat - \printline convertToGLFormat - - A few lines later, we convert \e buf into OpenGL format and store it - in \e tex1. - - \skipto glTexImage2D - \printline glTexImage2D - \printline tex1.bits - - Note the dimension restrictions for texture images as described in - the glTexImage2D() documentation. The width must be 2^m + 2*border - and the height 2^n + 2*border where m and n are integers and - border is either 0 or 1. - - Another function in the same example uses \e tex1 with OpenGL. - - \endomit -*/ - -QImage QGLWidget::convertToGLFormat(const QImage& img) -{ - QImage res(img.size(), QImage::Format_ARGB32); - convertToGLFormatHelper(res, img.convertToFormat(QImage::Format_ARGB32), GL_RGBA); - return res; -} - - -/*! - \fn QGLColormap & QGLWidget::colormap() const - - Returns the colormap for this widget. - - Usually it is only top-level widgets that can have different - colormaps installed. Asking for the colormap of a child widget - will return the colormap for the child's top-level widget. - - If no colormap has been set for this widget, the QGLColormap - returned will be empty. - - \sa setColormap(), QGLColormap::isEmpty() -*/ -const QGLColormap & QGLWidget::colormap() const -{ - Q_D(const QGLWidget); - return d->cmap; -} - -/*! - \fn void QGLWidget::setColormap(const QGLColormap & cmap) - - Set the colormap for this widget to \a cmap. Usually it is only - top-level widgets that can have colormaps installed. - - \sa colormap() -*/ -void QGLWidget::setColormap(const QGLColormap & c) -{ - Q_UNUSED(c); -} - -#ifndef QT_OPENGL_ES - -static void qt_save_gl_state() -{ - QOpenGLFunctions *funcs = qgl_functions(); - QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); - - gl1funcs->glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); - gl1funcs->glPushAttrib(GL_ALL_ATTRIB_BITS); - gl1funcs->glMatrixMode(GL_TEXTURE); - gl1funcs->glPushMatrix(); - gl1funcs->glLoadIdentity(); - gl1funcs->glMatrixMode(GL_PROJECTION); - gl1funcs->glPushMatrix(); - gl1funcs->glMatrixMode(GL_MODELVIEW); - gl1funcs->glPushMatrix(); - - gl1funcs->glShadeModel(GL_FLAT); - funcs->glDisable(GL_CULL_FACE); - funcs->glDisable(GL_LIGHTING); - funcs->glDisable(GL_STENCIL_TEST); - funcs->glDisable(GL_DEPTH_TEST); - funcs->glEnable(GL_BLEND); - funcs->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); -} - -static void qt_restore_gl_state() -{ - QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); - - gl1funcs->glMatrixMode(GL_TEXTURE); - gl1funcs->glPopMatrix(); - gl1funcs->glMatrixMode(GL_PROJECTION); - gl1funcs->glPopMatrix(); - gl1funcs->glMatrixMode(GL_MODELVIEW); - gl1funcs->glPopMatrix(); - gl1funcs->glPopAttrib(); - gl1funcs->glPopClientAttrib(); -} - -static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str, - const QFont &font) -{ - GLfloat color[4]; - qgl_functions()->glGetFloatv(GL_CURRENT_COLOR, &color[0]); - - QColor col; - col.setRgbF(color[0], color[1], color[2],color[3]); - QPen old_pen = p->pen(); - QFont old_font = p->font(); - - p->setPen(col); - p->setFont(font); - p->drawText(x, y, str); - - p->setPen(old_pen); - p->setFont(old_font); -} - -#endif // !QT_OPENGL_ES - -/*! - Renders the string \a str into the GL context of this widget. - - \a x and \a y are specified in window coordinates, with the origin - in the upper left-hand corner of the window. If \a font is not - specified, the currently set application font will be used to - render the string. To change the color of the rendered text you can - use the glColor() call (or the qglColor() convenience function), - just before the renderText() call. - - \note This function clears the stencil buffer. - - \note This function is not supported on OpenGL/ES systems. - - \note This function temporarily disables depth-testing when the - text is drawn. - - \note This function can only be used inside a - QPainter::beginNativePainting()/QPainter::endNativePainting() block - if a painter is active on the QGLWidget. -*/ - -void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font) -{ -#ifndef QT_OPENGL_ES - Q_D(QGLWidget); - if (!d->glcx->contextHandle()->isOpenGLES()) { - Q_D(QGLWidget); - if (str.isEmpty() || !isValid()) - return; - - QOpenGLFunctions *funcs = qgl_functions(); - GLint view[4]; - bool use_scissor_testing = funcs->glIsEnabled(GL_SCISSOR_TEST); - if (!use_scissor_testing) - funcs->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(); - - funcs->glDisable(GL_DEPTH_TEST); - funcs->glViewport(0, 0, width, height); - } 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 - funcs->glScissor(view[0], view[1], view[2], view[3]); - funcs->glEnable(GL_SCISSOR_TEST); - } else if (use_scissor_testing) { - // use the scissor box set by the user - funcs->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; - } -#else // QT_OPENGL_ES - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(str); - Q_UNUSED(font); -#endif - qWarning("QGLWidget::renderText is not supported under OpenGL/ES"); -} - -/*! \overload - - \a x, \a y and \a z are specified in scene or object coordinates - relative to the currently set projection and model matrices. This - can be useful if you want to annotate models with text labels and - have the labels move with the model as it is rotated etc. - - \note This function is not supported on OpenGL/ES systems. - - \note If depth testing is enabled before this function is called, - then the drawn text will be depth-tested against the models that - have already been drawn in the scene. Use \c{glDisable(GL_DEPTH_TEST)} - before calling this function to annotate the models without - depth-testing the text. - - \note This function can only be used inside a - QPainter::beginNativePainting()/QPainter::endNativePainting() block - if a painter is active on the QGLWidget. -*/ -void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font) -{ -#ifndef QT_OPENGL_ES - Q_D(QGLWidget); - if (!d->glcx->contextHandle()->isOpenGLES()) { - Q_D(QGLWidget); - if (str.isEmpty() || !isValid()) - return; - - QOpenGLFunctions *funcs = qgl_functions(); - 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]; - QOpenGLFunctions_1_1 *gl1funcs = qgl1_functions(); - gl1funcs->glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]); - gl1funcs->glGetDoublev(GL_PROJECTION_MATRIX, &proj[0]); - funcs->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); - const int dpr = d->glcx->device()->devicePixelRatioF(); - win_x /= dpr; - win_y /= dpr; - win_y = height - win_y; // y is inverted - - QPaintEngine *engine = paintEngine(); - - QPainter *p; - bool reuse_painter = false; - bool use_depth_testing = funcs->glIsEnabled(GL_DEPTH_TEST); - bool use_scissor_testing = funcs->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()) { - funcs->glScissor(view[0], view[1], view[2], view[3]); - funcs->glEnable(GL_SCISSOR_TEST); - } else if (use_scissor_testing) { - funcs->glEnable(GL_SCISSOR_TEST); - } - funcs->glViewport(0, 0, width * dpr, height * dpr); - gl1funcs->glAlphaFunc(GL_GREATER, 0.0); - funcs->glEnable(GL_ALPHA_TEST); - if (use_depth_testing) - funcs->glEnable(GL_DEPTH_TEST); - - // The only option in Qt 5 is the shader-based OpenGL 2 paint engine. - // Setting fixed pipeline transformations is futile. Instead, pass the - // extra values directly and let the engine figure the matrices out. - static_cast<QGL2PaintEngineEx *>(p->paintEngine())->setTranslateZ(-2 * win_z); - - qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font); - - static_cast<QGL2PaintEngineEx *>(p->paintEngine())->setTranslateZ(0); - - if (!reuse_painter) { - p->end(); - delete p; - setAutoBufferSwap(auto_swap); - d->disable_clear_on_painter_begin = false; - } - - qt_restore_gl_state(); - - return; - } -#else // QT_OPENGL_ES - Q_UNUSED(x); - Q_UNUSED(y); - Q_UNUSED(z); - Q_UNUSED(str); - Q_UNUSED(font); -#endif - qWarning("QGLWidget::renderText is not supported under OpenGL/ES"); -} - -QGLFormat QGLWidget::format() const -{ - Q_D(const QGLWidget); - return d->glcx->format(); -} - -QGLContext *QGLWidget::context() const -{ - Q_D(const QGLWidget); - return d->glcx; -} - -bool QGLWidget::doubleBuffer() const -{ - Q_D(const QGLWidget); - return d->glcx->d_ptr->glFormat.testOption(QGL::DoubleBuffer); -} - -void QGLWidget::setAutoBufferSwap(bool on) -{ - Q_D(QGLWidget); - d->autoSwap = on; -} - -bool QGLWidget::autoBufferSwap() const -{ - Q_D(const QGLWidget); - return d->autoSwap; -} - -/*! - Calls QGLContext:::bindTexture(\a image, \a target, \a format) on the currently - set context. - - \sa deleteTexture() -*/ -GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format) -{ - if (image.isNull()) - return 0; - - Q_D(QGLWidget); - return d->glcx->bindTexture(image, target, format, QGLContext::DefaultBindOption); -} - -/*! - \overload - \since 4.6 - - The binding \a options are a set of options used to decide how to - bind the texture to the context. - */ -GLuint QGLWidget::bindTexture(const QImage &image, GLenum target, GLint format, QGLContext::BindOptions options) -{ - if (image.isNull()) - return 0; - - Q_D(QGLWidget); - return d->glcx->bindTexture(image, target, format, options); -} - - -/*! - Calls QGLContext:::bindTexture(\a pixmap, \a target, \a format) on the currently - set context. - - \sa deleteTexture() -*/ -GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format) -{ - if (pixmap.isNull()) - return 0; - - Q_D(QGLWidget); - return d->glcx->bindTexture(pixmap, target, format, QGLContext::DefaultBindOption); -} - -/*! - \overload - \since 4.6 - - Generates and binds a 2D GL texture to the current context, based - on \a pixmap. The generated texture id is returned and can be used in - - The binding \a options are a set of options used to decide how to - bind the texture to the context. - */ -GLuint QGLWidget::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, - QGLContext::BindOptions options) -{ - Q_D(QGLWidget); - return d->glcx->bindTexture(pixmap, target, format, options); -} - -/*! \overload - - Calls QGLContext::bindTexture(\a fileName) on the currently set context. - - \sa deleteTexture() -*/ -GLuint QGLWidget::bindTexture(const QString &fileName) -{ - Q_D(QGLWidget); - return d->glcx->bindTexture(fileName); -} - -/*! - Calls QGLContext::deleteTexture(\a id) on the currently set - context. - - \sa bindTexture() -*/ -void QGLWidget::deleteTexture(GLuint id) -{ - Q_D(QGLWidget); - d->glcx->deleteTexture(id); -} - -/*! - \since 4.4 - - Calls the corresponding QGLContext::drawTexture() with - \a target, \a textureId, and \a textureTarget for this - widget's context. -*/ -void QGLWidget::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) -{ - Q_D(QGLWidget); - d->glcx->drawTexture(target, textureId, textureTarget); -} - -/*! - \since 4.4 - - Calls the corresponding QGLContext::drawTexture() with - \a point, \a textureId, and \a textureTarget for this - widget's context. -*/ -void QGLWidget::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) -{ - Q_D(QGLWidget); - d->glcx->drawTexture(point, textureId, textureTarget); -} - -Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_gl_2_engine) - -Q_OPENGL_EXPORT QPaintEngine* qt_qgl_paint_engine() -{ - return qt_gl_2_engine()->engine(); -} - -/*! - \internal - - Returns the GL widget's paint engine. -*/ -QPaintEngine *QGLWidget::paintEngine() const -{ - return qt_qgl_paint_engine(); -} - -void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget) -{ - Q_Q(QGLWidget); - q->setAttribute(Qt::WA_PaintOnScreen); - q->setAttribute(Qt::WA_NoSystemBackground); - q->setAutoFillBackground(true); // for compatibility - - mustHaveWindowHandle = 1; - q->setAttribute(Qt::WA_NativeWindow); - q->setWindowFlag(Qt::MSWindowsOwnDC); - - initContext(context, shareWidget); -} - -/* - This is the shared initialization for all platforms. Called from QGLWidgetPrivate::init() -*/ -void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWidget) -{ - Q_Q(QGLWidget); - - glDevice.setWidget(q); - - glcx = 0; - autoSwap = true; - - if (context && !context->device()) - context->setDevice(q); - q->setContext(context, shareWidget ? shareWidget->context() : 0); - - if (!glcx) - glcx = new QGLContext(QGLFormat::defaultFormat(), q); -} - -bool QGLWidgetPrivate::renderCxPm(QPixmap*) -{ - return false; -} - -/*! \internal - Free up any allocated colormaps. This fn is only called for - top-level widgets. -*/ -void QGLWidgetPrivate::cleanupColormaps() -{ -} - -void QGLContextGroup::addShare(const QGLContext *context, const QGLContext *share) { - Q_ASSERT(context && share); - if (context->d_ptr->group == share->d_ptr->group) - return; - - // Make sure 'context' is not already shared with another group of contexts. - Q_ASSERT(context->d_ptr->group->m_refs.loadRelaxed() == 1); - - // Free 'context' group resources and make it use the same resources as 'share'. - QGLContextGroup *group = share->d_ptr->group; - delete context->d_ptr->group; - context->d_ptr->group = group; - group->m_refs.ref(); - - // Maintain a list of all the contexts in each group of sharing contexts. - // The list is empty if the "share" context wasn't sharing already. - if (group->m_shares.isEmpty()) - group->m_shares.append(share); - group->m_shares.append(context); -} - -void QGLContextGroup::removeShare(const QGLContext *context) { - // Remove the context from the group. - QGLContextGroup *group = context->d_ptr->group; - if (group->m_shares.isEmpty()) - return; - group->m_shares.removeAll(context); - - // Update context group representative. - Q_ASSERT(group->m_shares.size() != 0); - if (group->m_context == context) - group->m_context = group->m_shares.at(0); - - // If there is only one context left, then make the list empty. - if (group->m_shares.size() == 1) - group->m_shares.clear(); -} - -QSize QGLTexture::bindCompressedTexture - (const QString& fileName, const char *format) -{ - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly)) - return QSize(); - QByteArray contents = file.readAll(); - file.close(); - return bindCompressedTexture - (contents.constData(), contents.size(), format); -} - -// PVR header format for container files that store textures compressed -// with the ETC1, PVRTC2, and PVRTC4 encodings. Format information from the -// PowerVR SDK at http://www.imgtec.com/powervr/insider/powervr-sdk.asp -// "PVRTexTool Reference Manual, version 1.11f". -struct PvrHeader -{ - quint32 headerSize; - quint32 height; - quint32 width; - quint32 mipMapCount; - quint32 flags; - quint32 dataSize; - quint32 bitsPerPixel; - quint32 redMask; - quint32 greenMask; - quint32 blueMask; - quint32 alphaMask; - quint32 magic; - quint32 surfaceCount; -}; - -#define PVR_MAGIC 0x21525650 // "PVR!" in little-endian - -#define PVR_FORMAT_MASK 0x000000FF -#define PVR_FORMAT_PVRTC2 0x00000018 -#define PVR_FORMAT_PVRTC4 0x00000019 -#define PVR_FORMAT_ETC1 0x00000036 - -#define PVR_HAS_MIPMAPS 0x00000100 -#define PVR_TWIDDLED 0x00000200 -#define PVR_NORMAL_MAP 0x00000400 -#define PVR_BORDER_ADDED 0x00000800 -#define PVR_CUBE_MAP 0x00001000 -#define PVR_FALSE_COLOR_MIPMAPS 0x00002000 -#define PVR_VOLUME_TEXTURE 0x00004000 -#define PVR_ALPHA_IN_TEXTURE 0x00008000 -#define PVR_VERTICAL_FLIP 0x00010000 - -#ifndef GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG -#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00 -#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01 -#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02 -#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 -#endif - -#ifndef GL_ETC1_RGB8_OES -#define GL_ETC1_RGB8_OES 0x8D64 -#endif - -bool QGLTexture::canBindCompressedTexture - (const char *buf, int len, const char *format, bool *hasAlpha) -{ - if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) { - // Compressed texture loading only supported on little-endian - // systems such as x86 and ARM at the moment. - return false; - } - if (!format) { - // Auto-detect the format from the header. - if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) { - *hasAlpha = true; - return true; - } else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) { - const PvrHeader *pvrHeader = - reinterpret_cast<const PvrHeader *>(buf); - *hasAlpha = (pvrHeader->alphaMask != 0); - return true; - } - } else { - // Validate the format against the header. - if (!qstricmp(format, "DDS")) { - if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) { - *hasAlpha = true; - return true; - } - } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) { - if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) { - const PvrHeader *pvrHeader = - reinterpret_cast<const PvrHeader *>(buf); - *hasAlpha = (pvrHeader->alphaMask != 0); - return true; - } - } - } - return false; -} - -#define ctx QGLContext::currentContext() - -QSize QGLTexture::bindCompressedTexture - (const char *buf, int len, const char *format) -{ - if (QSysInfo::ByteOrder != QSysInfo::LittleEndian) { - // Compressed texture loading only supported on little-endian - // systems such as x86 and ARM at the moment. - return QSize(); - } - if (!format) { - // Auto-detect the format from the header. - if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) - return bindCompressedTextureDDS(buf, len); - else if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) - return bindCompressedTexturePVR(buf, len); - } else { - // Validate the format against the header. - if (!qstricmp(format, "DDS")) { - if (len >= 4 && !qstrncmp(buf, "DDS ", 4)) - return bindCompressedTextureDDS(buf, len); - } else if (!qstricmp(format, "PVR") || !qstricmp(format, "ETC1")) { - if (len >= 52 && !qstrncmp(buf + 44, "PVR!", 4)) - return bindCompressedTexturePVR(buf, len); - } - } - return QSize(); -} - -QSize QGLTexture::bindCompressedTextureDDS(const char *buf, int len) -{ - // We only support 2D texture loading at present. - if (target != GL_TEXTURE_2D) - return QSize(); - - // Bail out if the necessary extension is not present. - if (!qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::DDSTextureCompression)) { - qWarning("QGLContext::bindTexture(): DDS texture compression is not supported."); - return QSize(); - } - - const DDSFormat *ddsHeader = reinterpret_cast<const DDSFormat *>(buf + 4); - if (!ddsHeader->dwLinearSize) { - qWarning("QGLContext::bindTexture(): DDS image size is not valid."); - return QSize(); - } - - int blockSize = 16; - GLenum format; - - switch(ddsHeader->ddsPixelFormat.dwFourCC) { - case FOURCC_DXT1: - format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - blockSize = 8; - break; - case FOURCC_DXT3: - format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - break; - case FOURCC_DXT5: - format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - break; - default: - qWarning("QGLContext::bindTexture(): DDS image format not supported."); - return QSize(); - } - - const GLubyte *pixels = - reinterpret_cast<const GLubyte *>(buf + ddsHeader->dwSize + 4); - - QOpenGLFunctions *funcs = qgl_functions(); - funcs->glGenTextures(1, &id); - funcs->glBindTexture(GL_TEXTURE_2D, id); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - int size; - int offset = 0; - int available = len - int(ddsHeader->dwSize + 4); - int w = ddsHeader->dwWidth; - int h = ddsHeader->dwHeight; - - // load mip-maps - for(int i = 0; i < (int) ddsHeader->dwMipMapCount; ++i) { - if (w == 0) w = 1; - if (h == 0) h = 1; - - size = ((w+3)/4) * ((h+3)/4) * blockSize; - if (size > available) - break; - qgl_extensions()->glCompressedTexImage2D(GL_TEXTURE_2D, i, format, w, h, 0, - size, pixels + offset); - offset += size; - available -= size; - - // half size for each mip-map level - w = w/2; - h = h/2; - } - - // DDS images are not inverted. - options &= ~QGLContext::InvertedYBindOption; - - return QSize(ddsHeader->dwWidth, ddsHeader->dwHeight); -} - -QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len) -{ - // We only support 2D texture loading at present. Cube maps later. - if (target != GL_TEXTURE_2D) - return QSize(); - - // Determine which texture format we will be loading. - const PvrHeader *pvrHeader = reinterpret_cast<const PvrHeader *>(buf); - GLenum textureFormat; - quint32 minWidth, minHeight; - switch (pvrHeader->flags & PVR_FORMAT_MASK) { - case PVR_FORMAT_PVRTC2: - if (pvrHeader->alphaMask) - textureFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; - else - textureFormat = GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; - minWidth = 16; - minHeight = 8; - break; - - case PVR_FORMAT_PVRTC4: - if (pvrHeader->alphaMask) - textureFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; - else - textureFormat = GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; - minWidth = 8; - minHeight = 8; - break; - - case PVR_FORMAT_ETC1: - textureFormat = GL_ETC1_RGB8_OES; - minWidth = 4; - minHeight = 4; - break; - - default: - qWarning("QGLContext::bindTexture(): PVR image format 0x%x not supported.", int(pvrHeader->flags & PVR_FORMAT_MASK)); - return QSize(); - } - - // Bail out if the necessary extension is not present. - if (textureFormat == GL_ETC1_RGB8_OES) { - if (!qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::ETC1TextureCompression)) { - qWarning("QGLContext::bindTexture(): ETC1 texture compression is not supported."); - return QSize(); - } - } else { - if (!qgl_extensions()->hasOpenGLExtension(QOpenGLExtensions::PVRTCTextureCompression)) { - qWarning("QGLContext::bindTexture(): PVRTC texture compression is not supported."); - return QSize(); - } - } - - // Boundary check on the buffer size. - quint32 bufferSize = pvrHeader->headerSize + pvrHeader->dataSize; - if (bufferSize > quint32(len)) { - qWarning("QGLContext::bindTexture(): PVR image size is not valid."); - return QSize(); - } - - // Create the texture. - QOpenGLFunctions *funcs = qgl_functions(); - funcs->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - funcs->glGenTextures(1, &id); - funcs->glBindTexture(GL_TEXTURE_2D, id); - if (pvrHeader->mipMapCount) { - if ((options & QGLContext::LinearFilteringBindOption) != 0) { - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } else { - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - } - } else if ((options & QGLContext::LinearFilteringBindOption) != 0) { - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - - // Load the compressed mipmap levels. - const GLubyte *buffer = - reinterpret_cast<const GLubyte *>(buf + pvrHeader->headerSize); - bufferSize = pvrHeader->dataSize; - quint32 level = 0; - quint32 width = pvrHeader->width; - quint32 height = pvrHeader->height; - while (bufferSize > 0 && level <= pvrHeader->mipMapCount) { - quint32 size = - (qMax(width, minWidth) * qMax(height, minHeight) * - pvrHeader->bitsPerPixel) / 8; - if (size > bufferSize) - break; - qgl_extensions()->glCompressedTexImage2D(GL_TEXTURE_2D, GLint(level), textureFormat, - GLsizei(width), GLsizei(height), 0, - GLsizei(size), buffer); - width /= 2; - height /= 2; - buffer += size; - ++level; - } - - // Restore the default pixel alignment for later texture uploads. - funcs->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - - // Set the invert flag for the texture. The "vertical flip" - // flag in PVR is the opposite sense to our sense of inversion. - options.setFlag(QGLContext::InvertedYBindOption, !(pvrHeader->flags & PVR_VERTICAL_FLIP)); - - return QSize(pvrHeader->width, pvrHeader->height); -} - -#undef ctx - -QT_END_NAMESPACE diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h deleted file mode 100644 index f5accbeb3c..0000000000 --- a/src/opengl/qgl.h +++ /dev/null @@ -1,524 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGL_H -#define QGL_H - -#ifndef QT_NO_OPENGL - -#include <QtGui/qopengl.h> -#include <QtWidgets/qwidget.h> -#include <QtGui/qpaintengine.h> -#include <QtOpenGL/qglcolormap.h> -#include <QtCore/qmap.h> -#include <QtCore/qscopedpointer.h> - -#include <QtGui/QSurfaceFormat> - -QT_BEGIN_NAMESPACE - - - - -class QPixmap; -class QGLWidgetPrivate; -class QGLContextPrivate; - -// Namespace class: -namespace QGL -{ - enum FormatOption { - DoubleBuffer = 0x0001, - DepthBuffer = 0x0002, - Rgba = 0x0004, - AlphaChannel = 0x0008, - AccumBuffer = 0x0010, - StencilBuffer = 0x0020, - StereoBuffers = 0x0040, - DirectRendering = 0x0080, - HasOverlay = 0x0100, - SampleBuffers = 0x0200, - DeprecatedFunctions = 0x0400, - SingleBuffer = DoubleBuffer << 16, - NoDepthBuffer = DepthBuffer << 16, - ColorIndex = Rgba << 16, - NoAlphaChannel = AlphaChannel << 16, - NoAccumBuffer = AccumBuffer << 16, - NoStencilBuffer = StencilBuffer << 16, - NoStereoBuffers = StereoBuffers << 16, - IndirectRendering = DirectRendering << 16, - NoOverlay = HasOverlay << 16, - NoSampleBuffers = SampleBuffers << 16, - NoDeprecatedFunctions = DeprecatedFunctions << 16 - }; - Q_DECLARE_FLAGS(FormatOptions, FormatOption) -} - -Q_DECLARE_OPERATORS_FOR_FLAGS(QGL::FormatOptions) - -class QGLFormatPrivate; - -class Q_OPENGL_EXPORT QGLFormat -{ -public: - QGLFormat(); - QGLFormat(QGL::FormatOptions options, int plane = 0); - QGLFormat(const QGLFormat &other); - QGLFormat &operator=(const QGLFormat &other); - ~QGLFormat(); - - void setDepthBufferSize(int size); - int depthBufferSize() const; - - void setAccumBufferSize(int size); - int accumBufferSize() const; - - void setRedBufferSize(int size); - int redBufferSize() const; - - void setGreenBufferSize(int size); - int greenBufferSize() const; - - void setBlueBufferSize(int size); - int blueBufferSize() const; - - void setAlphaBufferSize(int size); - int alphaBufferSize() const; - - void setStencilBufferSize(int size); - int stencilBufferSize() const; - - void setSampleBuffers(bool enable); - bool sampleBuffers() const; - - void setSamples(int numSamples); - int samples() const; - - void setSwapInterval(int interval); - int swapInterval() const; - - bool doubleBuffer() const; - void setDoubleBuffer(bool enable); - bool depth() const; - void setDepth(bool enable); - bool rgba() const; - void setRgba(bool enable); - bool alpha() const; - void setAlpha(bool enable); - bool accum() const; - void setAccum(bool enable); - bool stencil() const; - void setStencil(bool enable); - bool stereo() const; - void setStereo(bool enable); - bool directRendering() const; - void setDirectRendering(bool enable); - bool hasOverlay() const; - void setOverlay(bool enable); - - int plane() const; - void setPlane(int plane); - - void setOption(QGL::FormatOptions opt); - bool testOption(QGL::FormatOptions opt) const; - - static QGLFormat defaultFormat(); - static void setDefaultFormat(const QGLFormat& f); - - static QGLFormat defaultOverlayFormat(); - static void setDefaultOverlayFormat(const QGLFormat& f); - - static bool hasOpenGL(); - static bool hasOpenGLOverlays(); - - void setVersion(int major, int minor); - int majorVersion() const; - int minorVersion() const; - - enum OpenGLContextProfile { - NoProfile, - CoreProfile, - CompatibilityProfile - }; - - void setProfile(OpenGLContextProfile profile); - OpenGLContextProfile profile() const; - - enum OpenGLVersionFlag { - OpenGL_Version_None = 0x00000000, - OpenGL_Version_1_1 = 0x00000001, - OpenGL_Version_1_2 = 0x00000002, - OpenGL_Version_1_3 = 0x00000004, - OpenGL_Version_1_4 = 0x00000008, - OpenGL_Version_1_5 = 0x00000010, - OpenGL_Version_2_0 = 0x00000020, - OpenGL_Version_2_1 = 0x00000040, - OpenGL_ES_Common_Version_1_0 = 0x00000080, - OpenGL_ES_CommonLite_Version_1_0 = 0x00000100, - OpenGL_ES_Common_Version_1_1 = 0x00000200, - OpenGL_ES_CommonLite_Version_1_1 = 0x00000400, - OpenGL_ES_Version_2_0 = 0x00000800, - OpenGL_Version_3_0 = 0x00001000, - OpenGL_Version_3_1 = 0x00002000, - OpenGL_Version_3_2 = 0x00004000, - OpenGL_Version_3_3 = 0x00008000, - OpenGL_Version_4_0 = 0x00010000, - OpenGL_Version_4_1 = 0x00020000, - OpenGL_Version_4_2 = 0x00040000, - OpenGL_Version_4_3 = 0x00080000 - }; - Q_DECLARE_FLAGS(OpenGLVersionFlags, OpenGLVersionFlag) - - static OpenGLVersionFlags openGLVersionFlags(); - - static QGLFormat fromSurfaceFormat(const QSurfaceFormat &format); - static QSurfaceFormat toSurfaceFormat(const QGLFormat &format); -private: - QGLFormatPrivate *d; - - void detach(); - - friend Q_OPENGL_EXPORT bool operator==(const QGLFormat&, const QGLFormat&); - friend Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&); -#ifndef QT_NO_DEBUG_STREAM - friend Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QGLFormat &); -#endif -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QGLFormat::OpenGLVersionFlags) - -Q_OPENGL_EXPORT bool operator==(const QGLFormat&, const QGLFormat&); -Q_OPENGL_EXPORT bool operator!=(const QGLFormat&, const QGLFormat&); - -#ifndef QT_NO_DEBUG_STREAM -Q_OPENGL_EXPORT QDebug operator<<(QDebug, const QGLFormat &); -#endif - -class QGLFunctions; - -class Q_OPENGL_EXPORT QGLContext -{ - Q_DECLARE_PRIVATE(QGLContext) -public: - QGLContext(const QGLFormat& format, QPaintDevice* device); - QGLContext(const QGLFormat& format); - virtual ~QGLContext(); - - virtual bool create(const QGLContext* shareContext = nullptr); - bool isValid() const; - bool isSharing() const; - void reset(); - - static bool areSharing(const QGLContext *context1, const QGLContext *context2); - - QGLFormat format() const; - QGLFormat requestedFormat() const; - void setFormat(const QGLFormat& format); - - void moveToThread(QThread *thread); - - virtual void makeCurrent(); - virtual void doneCurrent(); - - virtual void swapBuffers() const; - - QGLFunctions *functions() const; - - enum BindOption { - NoBindOption = 0x0000, - InvertedYBindOption = 0x0001, - MipmapBindOption = 0x0002, - PremultipliedAlphaBindOption = 0x0004, - LinearFilteringBindOption = 0x0008, - - MemoryManagedBindOption = 0x0010, // internal flag - CanFlipNativePixmapBindOption = 0x0020, // internal flag - TemporarilyCachedBindOption = 0x0040, // internal flag - - DefaultBindOption = LinearFilteringBindOption - | InvertedYBindOption - | MipmapBindOption, - InternalBindOption = MemoryManagedBindOption - | PremultipliedAlphaBindOption - }; - Q_DECLARE_FLAGS(BindOptions, BindOption) - - GLuint bindTexture(const QImage &image, GLenum target, GLint format, - BindOptions options); - GLuint bindTexture(const QPixmap &pixmap, GLenum target, GLint format, - BindOptions options); - - GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, - GLint format = GL_RGBA); - GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, - GLint format = GL_RGBA); - GLuint bindTexture(const QString &fileName); - - void deleteTexture(GLuint tx_id); - - void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); - void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); - - static void setTextureCacheLimit(int size); - static int textureCacheLimit(); - - QFunctionPointer getProcAddress(const QString &proc) const; - QPaintDevice* device() const; - QColor overlayTransparentColor() const; - - static const QGLContext* currentContext(); - - static QGLContext *fromOpenGLContext(QOpenGLContext *platformContext); - QOpenGLContext *contextHandle() const; - -protected: - virtual bool chooseContext(const QGLContext* shareContext = nullptr); - - bool deviceIsPixmap() const; - bool windowCreated() const; - void setWindowCreated(bool on); - bool initialized() const; - void setInitialized(bool on); - - uint colorIndex(const QColor& c) const; - void setValid(bool valid); - void setDevice(QPaintDevice *pDev); - -protected: - static QGLContext* currentCtx; - -private: - QGLContext(QOpenGLContext *windowContext); - - QScopedPointer<QGLContextPrivate> d_ptr; - - friend class QGLPixelBuffer; - friend class QGLPixelBufferPrivate; - friend class QGLWidget; - friend class QGLWidgetPrivate; - friend class QGLGlyphCache; - friend class QGL2PaintEngineEx; - friend class QGL2PaintEngineExPrivate; - friend class QGLEngineShaderManager; - friend class QGLTextureGlyphCache; - friend struct QGLGlyphTexture; - friend class QGLContextGroup; - friend class QGLPixmapBlurFilter; - friend class QGLTexture; - friend QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags(); - friend class QGLFramebufferObject; - friend class QGLFramebufferObjectPrivate; - friend class QGLFBOGLPaintDevice; - friend class QGLPaintDevice; - friend class QGLWidgetGLPaintDevice; - friend class QX11GLSharedContexts; - friend class QGLContextResourceBase; - friend class QSGDistanceFieldGlyphCache; -private: - Q_DISABLE_COPY(QGLContext) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QGLContext::BindOptions) - -class Q_OPENGL_EXPORT QGLWidget : public QWidget -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QGLWidget) -public: - explicit QGLWidget(QWidget* parent=nullptr, - const QGLWidget* shareWidget = nullptr, Qt::WindowFlags f=Qt::WindowFlags()); - explicit QGLWidget(QGLContext *context, QWidget* parent=nullptr, - const QGLWidget* shareWidget = nullptr, Qt::WindowFlags f=Qt::WindowFlags()); - explicit QGLWidget(const QGLFormat& format, QWidget* parent=nullptr, - const QGLWidget* shareWidget = nullptr, Qt::WindowFlags f=Qt::WindowFlags()); - ~QGLWidget(); - - void qglColor(const QColor& c) const; - void qglClearColor(const QColor& c) const; - - bool isValid() const; - bool isSharing() const; - - void makeCurrent(); - void doneCurrent(); - - bool doubleBuffer() const; - void swapBuffers(); - - QGLFormat format() const; - void setFormat(const QGLFormat& format); - - QGLContext* context() const; - void setContext(QGLContext* context, const QGLContext* shareContext = nullptr, - bool deleteOldContext = true); - - QPixmap renderPixmap(int w = 0, int h = 0, bool useContext = false); - QImage grabFrameBuffer(bool withAlpha = false); - - void makeOverlayCurrent(); - const QGLContext* overlayContext() const; - - static QImage convertToGLFormat(const QImage& img); - - const QGLColormap & colormap() const; - void setColormap(const QGLColormap & map); - - void renderText(int x, int y, const QString & str, - const QFont & fnt = QFont()); - void renderText(double x, double y, double z, const QString & str, - const QFont & fnt = QFont()); - QPaintEngine *paintEngine() const override; - - GLuint bindTexture(const QImage &image, GLenum target, GLint format, - QGLContext::BindOptions options); - GLuint bindTexture(const QPixmap &pixmap, GLenum target, GLint format, - QGLContext::BindOptions options); - - GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, - GLint format = GL_RGBA); - GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, - GLint format = GL_RGBA); - - GLuint bindTexture(const QString &fileName); - - void deleteTexture(GLuint tx_id); - - void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); - void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); - -public Q_SLOTS: - virtual void updateGL(); - virtual void updateOverlayGL(); - -protected: - bool event(QEvent *) override; - virtual void initializeGL(); - virtual void resizeGL(int w, int h); - virtual void paintGL(); - - virtual void initializeOverlayGL(); - virtual void resizeOverlayGL(int w, int h); - virtual void paintOverlayGL(); - - void setAutoBufferSwap(bool on); - bool autoBufferSwap() const; - - void paintEvent(QPaintEvent*) override; - void resizeEvent(QResizeEvent*) override; - - virtual void glInit(); - virtual void glDraw(); - - QGLWidget(QGLWidgetPrivate &dd, - const QGLFormat &format = QGLFormat(), - QWidget *parent = nullptr, - const QGLWidget* shareWidget = nullptr, - Qt::WindowFlags f = Qt::WindowFlags()); -private: - Q_DISABLE_COPY(QGLWidget) - - friend class QGLDrawable; - friend class QGLPixelBuffer; - friend class QGLPixelBufferPrivate; - friend class QGLContext; - friend class QGLContextPrivate; - friend class QGLOverlayWidget; - friend class QGLPaintDevice; - friend class QGLWidgetGLPaintDevice; -}; - - -// -// QGLFormat inline functions -// - -inline bool QGLFormat::doubleBuffer() const -{ - return testOption(QGL::DoubleBuffer); -} - -inline bool QGLFormat::depth() const -{ - return testOption(QGL::DepthBuffer); -} - -inline bool QGLFormat::rgba() const -{ - return testOption(QGL::Rgba); -} - -inline bool QGLFormat::alpha() const -{ - return testOption(QGL::AlphaChannel); -} - -inline bool QGLFormat::accum() const -{ - return testOption(QGL::AccumBuffer); -} - -inline bool QGLFormat::stencil() const -{ - return testOption(QGL::StencilBuffer); -} - -inline bool QGLFormat::stereo() const -{ - return testOption(QGL::StereoBuffers); -} - -inline bool QGLFormat::directRendering() const -{ - return testOption(QGL::DirectRendering); -} - -inline bool QGLFormat::hasOverlay() const -{ - return testOption(QGL::HasOverlay); -} - -inline bool QGLFormat::sampleBuffers() const -{ - return testOption(QGL::SampleBuffers); -} - -QT_END_NAMESPACE - -#endif // QT_NO_OPENGL -#endif // QGL_H diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h deleted file mode 100644 index 4e52c0f5e9..0000000000 --- a/src/opengl/qgl_p.h +++ /dev/null @@ -1,556 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGL_P_H -#define QGL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the QGLWidget class. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include "QtOpenGL/qgl.h" -#include "QtOpenGL/qglcolormap.h" -#include "QtCore/qmap.h" -#include "QtCore/qthread.h" -#include "QtCore/qthreadstorage.h" -#include "QtCore/qhashfunctions.h" -#include "QtCore/qatomic.h" -#include "QtWidgets/private/qwidget_p.h" -#include "QtGui/private/qopenglcontext_p.h" -#include "QtGui/private/qopenglextensions_p.h" -#include "qcache.h" -#include "qglpaintdevice_p.h" - -#include <QtGui/QOpenGLContext> - -QT_BEGIN_NAMESPACE - -class QGLContext; -class QGLOverlayWidget; -class QPixmap; -class QOpenGLExtensions; - -class QGLFormatPrivate -{ -public: - QGLFormatPrivate() - : ref(1) - { - opts = QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::DirectRendering - | QGL::StencilBuffer | QGL::DeprecatedFunctions; - pln = 0; - depthSize = accumSize = stencilSize = redSize = greenSize = blueSize = alphaSize = -1; - numSamples = -1; - swapInterval = -1; - majorVersion = 2; - minorVersion = 0; - profile = QGLFormat::NoProfile; - } - QGLFormatPrivate(const QGLFormatPrivate *other) - : ref(1), - opts(other->opts), - pln(other->pln), - depthSize(other->depthSize), - accumSize(other->accumSize), - stencilSize(other->stencilSize), - redSize(other->redSize), - greenSize(other->greenSize), - blueSize(other->blueSize), - alphaSize(other->alphaSize), - numSamples(other->numSamples), - swapInterval(other->swapInterval), - majorVersion(other->majorVersion), - minorVersion(other->minorVersion), - profile(other->profile) - { - } - QAtomicInt ref; - QGL::FormatOptions opts; - int pln; - int depthSize; - int accumSize; - int stencilSize; - int redSize; - int greenSize; - int blueSize; - int alphaSize; - int numSamples; - int swapInterval; - int majorVersion; - int minorVersion; - QGLFormat::OpenGLContextProfile profile; -}; - -class Q_OPENGL_EXPORT QGLWidgetPrivate : public QWidgetPrivate -{ - Q_DECLARE_PUBLIC(QGLWidget) -public: - QGLWidgetPrivate() : QWidgetPrivate() - , disable_clear_on_painter_begin(false) - , parent_changing(false) - { - } - - ~QGLWidgetPrivate() {} - - void init(QGLContext *context, const QGLWidget* shareWidget); - void initContext(QGLContext *context, const QGLWidget* shareWidget); - bool renderCxPm(QPixmap *pixmap); - void cleanupColormaps(); - void aboutToDestroy() override { - if (glcx && !parent_changing) - glcx->reset(); - } - - bool makeCurrent(); - - QGLContext *glcx; - QGLWidgetGLPaintDevice glDevice; - bool autoSwap; - - QGLColormap cmap; - - bool disable_clear_on_painter_begin; - bool parent_changing; -}; - -// QGLContextPrivate has the responsibility of creating context groups. -// QGLContextPrivate maintains the reference counter and destroys -// context groups when needed. -class QGLContextGroup -{ -public: - ~QGLContextGroup(); - - const QGLContext *context() const {return m_context;} - bool isSharing() const { return m_shares.size() >= 2; } - QList<const QGLContext *> shares() const { return m_shares; } - - static void addShare(const QGLContext *context, const QGLContext *share); - static void removeShare(const QGLContext *context); - -private: - QGLContextGroup(const QGLContext *context); - - const QGLContext *m_context; // context group's representative - QList<const QGLContext *> m_shares; - QAtomicInt m_refs; - - friend class QGLContext; - friend class QGLContextPrivate; - friend class QGLContextGroupResourceBase; -}; - -// Get the context that resources for "ctx" will transfer to once -// "ctx" is destroyed. Returns null if nothing is sharing with ctx. -const QGLContext *qt_gl_transfer_context(const QGLContext *); - -/* - QGLTemporaryContext - the main objective of this class is to have a way of - creating a GL context and making it current, without going via QGLWidget - and friends. At certain points during GL initialization we need a current - context in order decide what GL features are available, and to resolve GL - extensions. Having a light-weight way of creating such a context saves - initial application startup time, and it doesn't wind up creating recursive - conflicts. - The class currently uses a private d pointer to hide the platform specific - types. This could possibly been done inline with #ifdef'ery, but it causes - major headaches on e.g. X11 due to namespace pollution. -*/ -class QGLTemporaryContextPrivate; -class QGLTemporaryContext { -public: - explicit QGLTemporaryContext(bool directRendering = true, QWidget *parent = nullptr); - ~QGLTemporaryContext(); - -private: - QScopedPointer<QGLTemporaryContextPrivate> d; -}; - -class QGLTexture; -class QGLTextureDestroyer; - -// This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's -// all the GL2 engine uses: -#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3 - -class QGLContextResourceBase; - -class QGLContextPrivate -{ - Q_DECLARE_PUBLIC(QGLContext) -public: - explicit QGLContextPrivate(QGLContext *context); - ~QGLContextPrivate(); - QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format, - QGLContext::BindOptions options); - QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key, - QGLContext::BindOptions options); - QGLTexture *bindTexture(const QPixmap &pixmap, GLenum target, GLint format, - QGLContext::BindOptions options); - QGLTexture *textureCacheLookup(const qint64 key, GLenum target); - void init(QPaintDevice *dev, const QGLFormat &format); - int maxTextureSize(); - - void cleanup(); - - void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true); - void syncGlState(); // Makes sure the GL context's state is what we think it is - void swapRegion(const QRegion ®ion); - - QOpenGLContext *guiGlContext; - // true if QGLContext owns the QOpenGLContext (for who deletes who) - bool ownContext; - - void setupSharing(); - void refreshCurrentFbo(); - void setCurrentFbo(GLuint fbo); - - QGLFormat glFormat; - QGLFormat reqFormat; - GLuint fbo; - - uint valid : 1; - uint sharing : 1; - uint initDone : 1; - uint crWin : 1; - uint internal_context : 1; - uint version_flags_cached : 1; - - // workarounds for driver/hw bugs on different platforms - uint workaround_needsFullClearOnEveryFrame : 1; - uint workaround_brokenFBOReadBack : 1; - uint workaround_brokenTexSubImage : 1; - uint workaroundsCached : 1; - - uint workaround_brokenTextureFromPixmap : 1; - uint workaround_brokenTextureFromPixmap_init : 1; - - uint workaround_brokenAlphaTexSubImage : 1; - uint workaround_brokenAlphaTexSubImage_init : 1; - - QPaintDevice *paintDevice; - QSize readback_target_size; - QColor transpColor; - QGLContext *q_ptr; - QGLFormat::OpenGLVersionFlags version_flags; - - QGLContextGroup *group; - GLint max_texture_size; - - GLuint current_fbo; - GLuint default_fbo; - QPaintEngine *active_engine; - QGLTextureDestroyer *texture_destroyer; - - QGLFunctions *functions; - - bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT]; - - static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; } - - static void setCurrentContext(QGLContext *context); -}; - -// Temporarily make a context current if not already current or -// shared with the current contex. The previous context is made -// current when the object goes out of scope. -class Q_OPENGL_EXPORT QGLShareContextScope -{ -public: - QGLShareContextScope(const QGLContext *ctx) - : m_oldContext(nullptr) - { - QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext()); - if (currentContext != ctx && !QGLContext::areSharing(ctx, currentContext)) { - m_oldContext = currentContext; - m_ctx = const_cast<QGLContext *>(ctx); - m_ctx->makeCurrent(); - } else { - m_ctx = currentContext; - } - } - - operator QGLContext *() - { - return m_ctx; - } - - QGLContext *operator->() - { - return m_ctx; - } - - ~QGLShareContextScope() - { - if (m_oldContext) - m_oldContext->makeCurrent(); - } - -private: - QGLContext *m_oldContext; - QGLContext *m_ctx; -}; - -QT_END_NAMESPACE -Q_DECLARE_METATYPE(GLuint) -QT_BEGIN_NAMESPACE - -class Q_OPENGL_EXPORT QGLTextureDestroyer -{ -public: - void emitFreeTexture(QGLContext *context, QPlatformPixmap *, GLuint id) { - if (context->contextHandle()) - (new QOpenGLSharedResourceGuard(context->contextHandle(), id, freeTextureFunc))->free(); - } - -private: - static void freeTextureFunc(QOpenGLFunctions *, GLuint id) { - QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &id); - } -}; - -class Q_OPENGL_EXPORT QGLSignalProxy : public QObject -{ - Q_OBJECT -public: - void emitAboutToDestroyContext(const QGLContext *context) { - emit aboutToDestroyContext(context); - } - static QGLSignalProxy *instance(); -Q_SIGNALS: - void aboutToDestroyContext(const QGLContext *context); -}; - -class QGLTexture { -public: - explicit QGLTexture(QGLContext *ctx = nullptr, GLuint tx_id = 0, GLenum tx_target = GL_TEXTURE_2D, - QGLContext::BindOptions opt = QGLContext::DefaultBindOption) - : context(ctx), - id(tx_id), - target(tx_target), - options(opt) - {} - - ~QGLTexture() { - if (options & QGLContext::MemoryManagedBindOption) { - Q_ASSERT(context); - QPlatformPixmap *boundPixmap = nullptr; - context->d_ptr->texture_destroyer->emitFreeTexture(context, boundPixmap, id); - } - } - - QGLContext *context; - GLuint id; - GLenum target; - - QGLContext::BindOptions options; - - bool canBindCompressedTexture - (const char *buf, int len, const char *format, bool *hasAlpha); - QSize bindCompressedTexture - (const QString& fileName, const char *format = nullptr); - QSize bindCompressedTexture - (const char *buf, int len, const char *format = nullptr); - QSize bindCompressedTextureDDS(const char *buf, int len); - QSize bindCompressedTexturePVR(const char *buf, int len); -}; - -struct QGLTextureCacheKey { - qint64 key; - QGLContextGroup *group; -}; - -inline bool operator==(const QGLTextureCacheKey &a, const QGLTextureCacheKey &b) -{ - return a.key == b.key && a.group == b.group; -} - -inline uint qHash(const QGLTextureCacheKey &key) -{ - return qHash(key.key) ^ qHash(key.group); -} - - -class Q_AUTOTEST_EXPORT QGLTextureCache { -public: - QGLTextureCache(); - ~QGLTextureCache(); - - void insert(QGLContext *ctx, qint64 key, QGLTexture *texture, int cost); - void remove(qint64 key); - inline int size(); - inline void setMaxCost(int newMax); - inline int maxCost(); - inline QGLTexture* getTexture(QGLContext *ctx, qint64 key); - - bool remove(QGLContext *ctx, GLuint textureId); - void removeContextTextures(QGLContext *ctx); - static QGLTextureCache *instance(); - static void cleanupTexturesForCacheKey(qint64 cacheKey); - static void cleanupTexturesForPixampData(QPlatformPixmap* pixmap); - static void cleanupBeforePixmapDestruction(QPlatformPixmap* pixmap); - -private: - QCache<QGLTextureCacheKey, QGLTexture> m_cache; - QReadWriteLock m_lock; -}; - -int QGLTextureCache::size() { - QReadLocker locker(&m_lock); - return m_cache.size(); -} - -void QGLTextureCache::setMaxCost(int newMax) -{ - QWriteLocker locker(&m_lock); - m_cache.setMaxCost(newMax); -} - -int QGLTextureCache::maxCost() -{ - QReadLocker locker(&m_lock); - return m_cache.maxCost(); -} - -QGLTexture* QGLTextureCache::getTexture(QGLContext *ctx, qint64 key) -{ - // Can't be a QReadLocker since QCache::object() modifies the cache (reprioritizes the object) - QWriteLocker locker(&m_lock); - const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)}; - return m_cache.object(cacheKey); -} - -Q_OPENGL_EXPORT extern QPaintEngine* qt_qgl_paint_engine(); - -QOpenGLExtensions* qgl_extensions(); -bool qgl_hasFeature(QOpenGLFunctions::OpenGLFeature feature); -bool qgl_hasExtension(QOpenGLExtensions::OpenGLExtension extension); - -// Put a guard around a GL object identifier and its context. -// When the context goes away, a shared context will be used -// in its place. If there are no more shared contexts, then -// the identifier is returned as zero - it is assumed that the -// context destruction cleaned up the identifier in this case. -class QGLSharedResourceGuardBase : public QOpenGLSharedResource -{ -public: - QGLSharedResourceGuardBase(QGLContext *context, GLuint id) - : QOpenGLSharedResource(context->contextHandle()->shareGroup()) - , m_id(id) - { - } - - GLuint id() const - { - return m_id; - } - -protected: - void invalidateResource() override - { - m_id = 0; - } - - void freeResource(QOpenGLContext *context) override - { - if (m_id) { - freeResource(QGLContext::fromOpenGLContext(context), m_id); - } - } - - virtual void freeResource(QGLContext *ctx, GLuint id) = 0; - -private: - GLuint m_id; -}; - -template <typename Func> -class QGLSharedResourceGuard : public QGLSharedResourceGuardBase -{ -public: - QGLSharedResourceGuard(QGLContext *context, GLuint id, Func func) - : QGLSharedResourceGuardBase(context, id) - , m_func(func) - { - } - -protected: - void freeResource(QGLContext *ctx, GLuint id) override - { - m_func(ctx, id); - } - -private: - Func m_func; -}; - -template <typename Func> -QGLSharedResourceGuardBase *createSharedResourceGuard(QGLContext *context, GLuint id, Func cleanupFunc) -{ - return new QGLSharedResourceGuard<Func>(context, id, cleanupFunc); -} - -// this is a class that wraps a QThreadStorage object for storing -// thread local instances of the GL 1 and GL 2 paint engines - -template <class T> -class QGLEngineThreadStorage -{ -public: - QPaintEngine *engine() { - QPaintEngine *&localEngine = storage.localData(); - if (!localEngine) - localEngine = new T; - return localEngine; - } - -private: - QThreadStorage<QPaintEngine *> storage; -}; -QT_END_NAMESPACE - -#endif // QGL_P_H diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp deleted file mode 100644 index bb9c2affbd..0000000000 --- a/src/opengl/qglbuffer.cpp +++ /dev/null @@ -1,568 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtOpenGL/qgl.h> -#include <QtOpenGL/private/qgl_p.h> -#include <private/qopenglextensions_p.h> -#include <QtCore/qatomic.h> -#include "qglbuffer.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QGLBuffer - \inmodule QtOpenGL - \brief The QGLBuffer class provides functions for creating and managing GL buffer objects. - \since 4.7 - \obsolete - \ingroup painting-3D - - Buffer objects are created in the GL server so that the - client application can avoid uploading vertices, indices, - texture image data, etc every time they are needed. - - QGLBuffer objects can be copied around as a reference to the - underlying GL buffer object: - - \snippet code/src_opengl_qglbuffer.cpp 0 - - QGLBuffer performs a shallow copy when objects are copied in this - manner, but does not implement copy-on-write semantics. The original - object will be affected whenever the copy is modified. - - \note This class has been deprecated in favor of QOpenGLBuffer. -*/ - -/*! - \enum QGLBuffer::Type - This enum defines the type of GL buffer object to create with QGLBuffer. - - \value VertexBuffer Vertex buffer object for use when specifying - vertex arrays. - \value IndexBuffer Index buffer object for use with \c{glDrawElements()}. - \value PixelPackBuffer Pixel pack buffer object for reading pixel - data from the GL server (for example, with \c{glReadPixels()}). - Not supported under OpenGL/ES. - \value PixelUnpackBuffer Pixel unpack buffer object for writing pixel - data to the GL server (for example, with \c{glTexImage2D()}). - Not supported under OpenGL/ES. -*/ - -/*! - \enum QGLBuffer::UsagePattern - This enum defines the usage pattern of a QGLBuffer object. - - \value StreamDraw The data will be set once and used a few times - for drawing operations. Under OpenGL/ES 1.1 this is identical - to StaticDraw. - \value StreamRead The data will be set once and used a few times - for reading data back from the GL server. Not supported - under OpenGL/ES. - \value StreamCopy The data will be set once and used a few times - for reading data back from the GL server for use in further - drawing operations. Not supported under OpenGL/ES. - \value StaticDraw The data will be set once and used many times - for drawing operations. - \value StaticRead The data will be set once and used many times - for reading data back from the GL server. Not supported - under OpenGL/ES. - \value StaticCopy The data will be set once and used many times - for reading data back from the GL server for use in further - drawing operations. Not supported under OpenGL/ES. - \value DynamicDraw The data will be modified repeatedly and used - many times for drawing operations. - \value DynamicRead The data will be modified repeatedly and used - many times for reading data back from the GL server. - Not supported under OpenGL/ES. - \value DynamicCopy The data will be modified repeatedly and used - many times for reading data back from the GL server for - use in further drawing operations. Not supported under OpenGL/ES. -*/ - -/*! - \enum QGLBuffer::Access - This enum defines the access mode for QGLBuffer::map(). - - \value ReadOnly The buffer will be mapped for reading only. - \value WriteOnly The buffer will be mapped for writing only. - \value ReadWrite The buffer will be mapped for reading and writing. -*/ - -class QGLBufferPrivate -{ -public: - QGLBufferPrivate(QGLBuffer::Type t) - : ref(1), - type(t), - guard(0), - usagePattern(QGLBuffer::StaticDraw), - actualUsagePattern(QGLBuffer::StaticDraw), - funcs(0) - { - } - - QAtomicInt ref; - QGLBuffer::Type type; - QGLSharedResourceGuardBase *guard; - QGLBuffer::UsagePattern usagePattern; - QGLBuffer::UsagePattern actualUsagePattern; - QOpenGLExtensions *funcs; -}; - -/*! - Constructs a new buffer object of type QGLBuffer::VertexBuffer. - - Note: this constructor just creates the QGLBuffer instance. The actual - buffer object in the GL server is not created until create() is called. - - \sa create() -*/ -QGLBuffer::QGLBuffer() - : d_ptr(new QGLBufferPrivate(QGLBuffer::VertexBuffer)) -{ -} - -/*! - Constructs a new buffer object of \a type. - - Note: this constructor just creates the QGLBuffer instance. The actual - buffer object in the GL server is not created until create() is called. - - \sa create() -*/ -QGLBuffer::QGLBuffer(QGLBuffer::Type type) - : d_ptr(new QGLBufferPrivate(type)) -{ -} - -/*! - Constructs a shallow copy of \a other. - - Note: QGLBuffer does not implement copy-on-write semantics, - so \a other will be affected whenever the copy is modified. -*/ -QGLBuffer::QGLBuffer(const QGLBuffer &other) - : d_ptr(other.d_ptr) -{ - d_ptr->ref.ref(); -} - -#define ctx QGLContext::currentContext(); - -/*! - Destroys this buffer object, including the storage being - used in the GL server. -*/ -QGLBuffer::~QGLBuffer() -{ - if (!d_ptr->ref.deref()) { - destroy(); - delete d_ptr; - } -} - -/*! - Assigns a shallow copy of \a other to this object. - - Note: QGLBuffer does not implement copy-on-write semantics, - so \a other will be affected whenever the copy is modified. -*/ -QGLBuffer &QGLBuffer::operator=(const QGLBuffer &other) -{ - if (d_ptr != other.d_ptr) { - other.d_ptr->ref.ref(); - if (!d_ptr->ref.deref()) { - destroy(); - delete d_ptr; - } - d_ptr = other.d_ptr; - } - return *this; -} - -/*! - Returns the type of buffer represented by this object. -*/ -QGLBuffer::Type QGLBuffer::type() const -{ - Q_D(const QGLBuffer); - return d->type; -} - -/*! - Returns the usage pattern for this buffer object. - The default value is StaticDraw. - - \sa setUsagePattern() -*/ -QGLBuffer::UsagePattern QGLBuffer::usagePattern() const -{ - Q_D(const QGLBuffer); - return d->usagePattern; -} - -/*! - Sets the usage pattern for this buffer object to \a value. - This function must be called before allocate() or write(). - - \sa usagePattern(), allocate(), write() -*/ -void QGLBuffer::setUsagePattern(QGLBuffer::UsagePattern value) -{ - Q_D(QGLBuffer); - d->usagePattern = d->actualUsagePattern = value; -} - -#undef ctx - -namespace { - void freeBufferFunc(QGLContext *ctx, GLuint id) - { - Q_ASSERT(ctx); - ctx->contextHandle()->functions()->glDeleteBuffers(1, &id); - } -} - -/*! - Creates the buffer object in the GL server. Returns \c true if - the object was created; false otherwise. - - This function must be called with a current QGLContext. - The buffer will be bound to and can only be used in - that context (or any other context that is shared with it). - - This function will return false if the GL implementation - does not support buffers, or there is no current QGLContext. - - \sa isCreated(), allocate(), write(), destroy() -*/ -bool QGLBuffer::create() -{ - Q_D(QGLBuffer); - if (d->guard && d->guard->id()) - return true; - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); - if (ctx) { - delete d->funcs; - d->funcs = new QOpenGLExtensions(ctx->contextHandle()); - if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers)) - return false; - - GLuint bufferId = 0; - d->funcs->glGenBuffers(1, &bufferId); - if (bufferId) { - if (d->guard) - d->guard->free(); - - d->guard = createSharedResourceGuard(ctx, bufferId, freeBufferFunc); - return true; - } - } - return false; -} - -#define ctx QGLContext::currentContext() - -/*! - Returns \c true if this buffer has been created; false otherwise. - - \sa create(), destroy() -*/ -bool QGLBuffer::isCreated() const -{ - Q_D(const QGLBuffer); - return d->guard && d->guard->id(); -} - -/*! - Destroys this buffer object, including the storage being - used in the GL server. All references to the buffer will - become invalid. -*/ -void QGLBuffer::destroy() -{ - Q_D(QGLBuffer); - if (d->guard) { - d->guard->free(); - d->guard = 0; - } -} - -/*! - Reads the \a count bytes in this buffer starting at \a offset - into \a data. Returns \c true on success; false if reading from - the buffer is not supported. Buffer reading is not supported - under OpenGL/ES. - - It is assumed that this buffer has been bound to the current context. - - \sa write(), bind() -*/ -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() || !d->funcs->d()->GetBufferSubData) - return false; - while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state. - d->funcs->glGetBufferSubData(d->type, offset, count, data); - return d->funcs->glGetError() == GL_NO_ERROR; -#else - Q_UNUSED(offset); - Q_UNUSED(data); - Q_UNUSED(count); - return false; -#endif -} - -/*! - Replaces the \a count bytes of this buffer starting at \a offset - with the contents of \a data. Any other bytes in the buffer - will be left unmodified. - - It is assumed that create() has been called on this buffer and that - it has been bound to the current context. - - \sa create(), read(), allocate() -*/ -void QGLBuffer::write(int offset, const void *data, int count) -{ -#ifndef QT_NO_DEBUG - if (!isCreated()) - qWarning("QGLBuffer::allocate(): buffer not created"); -#endif - Q_D(QGLBuffer); - if (d->guard && d->guard->id()) - d->funcs->glBufferSubData(d->type, offset, count, data); -} - -/*! - Allocates \a count bytes of space to the buffer, initialized to - the contents of \a data. Any previous contents will be removed. - - It is assumed that create() has been called on this buffer and that - it has been bound to the current context. - - \sa create(), read(), write() -*/ -void QGLBuffer::allocate(const void *data, int count) -{ -#ifndef QT_NO_DEBUG - if (!isCreated()) - qWarning("QGLBuffer::allocate(): buffer not created"); -#endif - Q_D(QGLBuffer); - if (d->guard && d->guard->id()) - d->funcs->glBufferData(d->type, count, data, d->actualUsagePattern); -} - -/*! - \fn void QGLBuffer::allocate(int count) - \overload - - Allocates \a count bytes of space to the buffer. Any previous - contents will be removed. - - It is assumed that create() has been called on this buffer and that - it has been bound to the current context. - - \sa create(), write() -*/ - -/*! - Binds the buffer associated with this object to the current - GL context. Returns \c false if binding was not possible, usually because - type() is not supported on this GL implementation. - - The buffer must be bound to the same QGLContext current when create() - was called, or to another QGLContext that is sharing with it. - Otherwise, false will be returned from this function. - - \sa release(), create() -*/ -bool QGLBuffer::bind() -{ -#ifndef QT_NO_DEBUG - if (!isCreated()) - qWarning("QGLBuffer::bind(): buffer not created"); -#endif - Q_D(const QGLBuffer); - GLuint bufferId = d->guard ? d->guard->id() : 0; - if (bufferId) { - if (d->guard->group() != QOpenGLContextGroup::currentContextGroup()) { -#ifndef QT_NO_DEBUG - qWarning("QGLBuffer::bind: buffer is not valid in the current context"); -#endif - return false; - } - d->funcs->glBindBuffer(d->type, bufferId); - return true; - } else { - return false; - } -} - -/*! - Releases the buffer associated with this object from the - current GL context. - - This function must be called with the same QGLContext current - as when bind() was called on the buffer. - - \sa bind() -*/ -void QGLBuffer::release() -{ -#ifndef QT_NO_DEBUG - if (!isCreated()) - qWarning("QGLBuffer::release(): buffer not created"); -#endif - Q_D(const QGLBuffer); - if (d->guard && d->guard->id()) - d->funcs->glBindBuffer(d->type, 0); -} - -#undef ctx - -/*! - Releases the buffer associated with \a type in the current - QGLContext. - - This function is a direct call to \c{glBindBuffer(type, 0)} - for use when the caller does not know which QGLBuffer has - been bound to the context but wants to make sure that it - is released. - - \snippet code/src_opengl_qglbuffer.cpp 1 -*/ -void QGLBuffer::release(QGLBuffer::Type type) -{ - if (QOpenGLContext *ctx = QOpenGLContext::currentContext()) - ctx->functions()->glBindBuffer(GLenum(type), 0); -} - -#define ctx QGLContext::currentContext() - -/*! - Returns the GL identifier associated with this buffer; zero if - the buffer has not been created. - - \sa isCreated() -*/ -GLuint QGLBuffer::bufferId() const -{ - Q_D(const QGLBuffer); - return d->guard ? d->guard->id() : 0; -} - -#ifndef GL_BUFFER_SIZE -#define GL_BUFFER_SIZE 0x8764 -#endif - -/*! - Returns the size of the data in this buffer, for reading operations. - Returns -1 if fetching the buffer size is not supported, or the - buffer has not been created. - - It is assumed that this buffer has been bound to the current context. - - \sa isCreated(), bind() -*/ -int QGLBuffer::size() const -{ - Q_D(const QGLBuffer); - if (!d->guard || !d->guard->id()) - return -1; - GLint value = -1; - d->funcs->glGetBufferParameteriv(d->type, GL_BUFFER_SIZE, &value); - return value; -} - -/*! - Maps the contents of this buffer into the application's memory - space and returns a pointer to it. Returns null if memory - mapping is not possible. The \a access parameter indicates the - type of access to be performed. - - It is assumed that create() has been called on this buffer and that - it has been bound to the current context. - - This function is only supported under OpenGL/ES if the - \c{GL_OES_mapbuffer} extension is present. - - \sa unmap(), create(), bind() -*/ -void *QGLBuffer::map(QGLBuffer::Access access) -{ - Q_D(QGLBuffer); -#ifndef QT_NO_DEBUG - if (!isCreated()) - qWarning("QGLBuffer::map(): buffer not created"); -#endif - if (!d->guard || !d->guard->id()) - return 0; - return d->funcs->glMapBuffer(d->type, access); -} - -/*! - Unmaps the buffer after it was mapped into the application's - memory space with a previous call to map(). Returns \c true if - the unmap succeeded; false otherwise. - - It is assumed that this buffer has been bound to the current context, - and that it was previously mapped with map(). - - This function is only supported under OpenGL/ES if the - \c{GL_OES_mapbuffer} extension is present. - - \sa map() -*/ -bool QGLBuffer::unmap() -{ - Q_D(QGLBuffer); -#ifndef QT_NO_DEBUG - if (!isCreated()) - qWarning("QGLBuffer::unmap(): buffer not created"); -#endif - if (!d->guard || !d->guard->id()) - return false; - return d->funcs->glUnmapBuffer(d->type) == GL_TRUE; -} - -QT_END_NAMESPACE diff --git a/src/opengl/qglbuffer.h b/src/opengl/qglbuffer.h deleted file mode 100644 index daf5227c66..0000000000 --- a/src/opengl/qglbuffer.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLBUFFER_H -#define QGLBUFFER_H - -#include <QtCore/qscopedpointer.h> -#include <QtOpenGL/qgl.h> - -QT_BEGIN_NAMESPACE - - -class QGLBufferPrivate; - -class Q_OPENGL_EXPORT QGLBuffer -{ -public: - enum Type - { - VertexBuffer = 0x8892, // GL_ARRAY_BUFFER - IndexBuffer = 0x8893, // GL_ELEMENT_ARRAY_BUFFER - PixelPackBuffer = 0x88EB, // GL_PIXEL_PACK_BUFFER - PixelUnpackBuffer = 0x88EC // GL_PIXEL_UNPACK_BUFFER - }; - - QGLBuffer(); - explicit QGLBuffer(QGLBuffer::Type type); - QGLBuffer(const QGLBuffer &other); - ~QGLBuffer(); - - QGLBuffer &operator=(const QGLBuffer &other); - - enum UsagePattern - { - StreamDraw = 0x88E0, // GL_STREAM_DRAW - StreamRead = 0x88E1, // GL_STREAM_READ - StreamCopy = 0x88E2, // GL_STREAM_COPY - StaticDraw = 0x88E4, // GL_STATIC_DRAW - StaticRead = 0x88E5, // GL_STATIC_READ - StaticCopy = 0x88E6, // GL_STATIC_COPY - DynamicDraw = 0x88E8, // GL_DYNAMIC_DRAW - DynamicRead = 0x88E9, // GL_DYNAMIC_READ - DynamicCopy = 0x88EA // GL_DYNAMIC_COPY - }; - - enum Access - { - ReadOnly = 0x88B8, // GL_READ_ONLY - WriteOnly = 0x88B9, // GL_WRITE_ONLY - ReadWrite = 0x88BA // GL_READ_WRITE - }; - - QGLBuffer::Type type() const; - - QGLBuffer::UsagePattern usagePattern() const; - void setUsagePattern(QGLBuffer::UsagePattern value); - - bool create(); - bool isCreated() const; - - void destroy(); - - bool bind(); - void release(); - - static void release(QGLBuffer::Type type); - - GLuint bufferId() const; - - int size() const; - - bool read(int offset, void *data, int count); - void write(int offset, const void *data, int count); - - void allocate(const void *data, int count); - inline void allocate(int count) { allocate(nullptr, count); } - - void *map(QGLBuffer::Access access); - bool unmap(); - -private: - QGLBufferPrivate *d_ptr; - - Q_DECLARE_PRIVATE(QGLBuffer) -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/opengl/qglcolormap.cpp b/src/opengl/qglcolormap.cpp deleted file mode 100644 index f314a9715d..0000000000 --- a/src/opengl/qglcolormap.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QGLColormap - \brief The QGLColormap class is used for installing custom colormaps into - a QGLWidget. - - \obsolete - \inmodule QtOpenGL - \ingroup painting-3D - \ingroup shared - - QGLColormap provides a platform independent way of specifying and - installing indexed colormaps for a QGLWidget. QGLColormap is - especially useful when using the OpenGL color-index mode. - - Under X11 you must use an X server that supports either a \c - PseudoColor or \c DirectColor visual class. If your X server - currently only provides a \c GrayScale, \c TrueColor, \c - StaticColor or \c StaticGray visual, you will not be able to - allocate colorcells for writing. If this is the case, try setting - your X server to 8 bit mode. It should then provide you with at - least a \c PseudoColor visual. Note that you may experience - colormap flashing if your X server is running in 8 bit mode. - - The size() of the colormap is always set to 256 - colors. Note that under Windows you can also install colormaps - in child widgets. - - This class uses \l{implicit sharing} as a memory and speed - optimization. - - Example of use: - \snippet code/src_opengl_qglcolormap.cpp 0 - - \sa QGLWidget::setColormap(), QGLWidget::colormap() -*/ - -/*! - \fn Qt::HANDLE QGLColormap::handle() - - \internal - - Returns the handle for this color map. -*/ - -/*! - \fn void QGLColormap::setHandle(Qt::HANDLE handle) - - \internal - - Sets the handle for this color map to \a handle. -*/ - -#include "qglcolormap.h" - -QT_BEGIN_NAMESPACE - -QGLColormap::QGLColormapData QGLColormap::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0 }; - -/*! - Construct a QGLColormap. -*/ -QGLColormap::QGLColormap() - : d(&shared_null) -{ - d->ref.ref(); -} - - -/*! - Construct a shallow copy of \a map. -*/ -QGLColormap::QGLColormap(const QGLColormap &map) - : d(map.d) -{ - d->ref.ref(); -} - -/*! - Dereferences the QGLColormap and deletes it if this was the last - reference to it. -*/ -QGLColormap::~QGLColormap() -{ - if (!d->ref.deref()) - cleanup(d); -} - -void QGLColormap::cleanup(QGLColormap::QGLColormapData *x) -{ - delete x->cells; - x->cells = 0; - delete x; -} - -/*! - Assign a shallow copy of \a map to this QGLColormap. -*/ -QGLColormap & QGLColormap::operator=(const QGLColormap &map) -{ - map.d->ref.ref(); - if (!d->ref.deref()) - cleanup(d); - d = map.d; - return *this; -} - -/*! - \fn void QGLColormap::detach() - \internal - - Detaches this QGLColormap from the shared block. -*/ - -void QGLColormap::detach_helper() -{ - QGLColormapData *x = new QGLColormapData; - x->ref.storeRelaxed(1); - x->cmapHandle = 0; - x->cells = 0; - if (d->cells) { - x->cells = new QVector<QRgb>(256); - *x->cells = *d->cells; - } - if (!d->ref.deref()) - cleanup(d); - d = x; -} - -/*! - Set cell at index \a idx in the colormap to color \a color. -*/ -void QGLColormap::setEntry(int idx, QRgb color) -{ - detach(); - if (!d->cells) - d->cells = new QVector<QRgb>(256); - d->cells->replace(idx, color); -} - -/*! - Set an array of cells in this colormap. \a count is the number of - colors that should be set, \a colors is the array of colors, and - \a base is the starting index. The first element in \a colors - is set at \a base in the colormap. -*/ -void QGLColormap::setEntries(int count, const QRgb *colors, int base) -{ - detach(); - if (!d->cells) - d->cells = new QVector<QRgb>(256); - - Q_ASSERT_X(colors && base >= 0 && (base + count) <= d->cells->size(), "QGLColormap::setEntries", - "preconditions not met"); - for (int i = 0; i < count; ++i) - setEntry(base + i, colors[i]); -} - -/*! - Returns the QRgb value in the colorcell with index \a idx. -*/ -QRgb QGLColormap::entryRgb(int idx) const -{ - if (d == &shared_null || !d->cells) - return 0; - else - return d->cells->at(idx); -} - -/*! - \overload - - Set the cell with index \a idx in the colormap to color \a color. -*/ -void QGLColormap::setEntry(int idx, const QColor &color) -{ - setEntry(idx, color.rgb()); -} - -/*! - Returns the QRgb value in the colorcell with index \a idx. -*/ -QColor QGLColormap::entryColor(int idx) const -{ - if (d == &shared_null || !d->cells) - return QColor(); - else - return QColor(d->cells->at(idx)); -} - -/*! - Returns \c true if the colormap is empty or it is not in use - by a QGLWidget; otherwise returns \c false. - - A colormap with no color values set is considered to be empty. - For historical reasons, a colormap that has color values set - but which is not in use by a QGLWidget is also considered empty. - - Compare size() with zero to determine if the colormap is empty - regardless of whether it is in use by a QGLWidget or not. - - \sa size() -*/ -bool QGLColormap::isEmpty() const -{ - return d == &shared_null || d->cells == 0 || d->cells->size() == 0 || d->cmapHandle == 0; -} - - -/*! - Returns the number of colorcells in the colormap. -*/ -int QGLColormap::size() const -{ - return d->cells ? d->cells->size() : 0; -} - -/*! - Returns the index of the color \a color. If \a color is not in the - map, -1 is returned. -*/ -int QGLColormap::find(QRgb color) const -{ - if (d->cells) - return d->cells->indexOf(color); - return -1; -} - -/*! - Returns the index of the color that is the closest match to color - \a color. -*/ -int QGLColormap::findNearest(QRgb color) const -{ - int idx = find(color); - if (idx >= 0) - return idx; - int mapSize = size(); - int mindist = 200000; - int r = qRed(color); - int g = qGreen(color); - int b = qBlue(color); - int rx, gx, bx, dist; - for (int i = 0; i < mapSize; ++i) { - QRgb ci = d->cells->at(i); - rx = r - qRed(ci); - gx = g - qGreen(ci); - bx = b - qBlue(ci); - dist = rx * rx + gx * gx + bx * bx; // calculate distance - if (dist < mindist) { // minimal? - mindist = dist; - idx = i; - } - } - return idx; -} - -QT_END_NAMESPACE diff --git a/src/opengl/qglcolormap.h b/src/opengl/qglcolormap.h deleted file mode 100644 index b59b56e040..0000000000 --- a/src/opengl/qglcolormap.h +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLCOLORMAP_H -#define QGLCOLORMAP_H - -#include <QtGui/qcolor.h> -#include <QtCore/qvector.h> -#include <QtOpenGL/qtopenglglobal.h> - -QT_BEGIN_NAMESPACE - - -class Q_OPENGL_EXPORT QGLColormap -{ -public: - QGLColormap(); - QGLColormap(const QGLColormap &); - ~QGLColormap(); - - QGLColormap &operator=(const QGLColormap &); - - bool isEmpty() const; - int size() const; - void detach(); - - void setEntries(int count, const QRgb * colors, int base = 0); - void setEntry(int idx, QRgb color); - void setEntry(int idx, const QColor & color); - QRgb entryRgb(int idx) const; - QColor entryColor(int idx) const; - int find(QRgb color) const; - int findNearest(QRgb color) const; - -protected: - Qt::HANDLE handle() { return d ? d->cmapHandle : nullptr; } - void setHandle(Qt::HANDLE ahandle) { d->cmapHandle = ahandle; } - -private: - struct QGLColormapData { - QBasicAtomicInt ref; - QVector<QRgb> *cells; - Qt::HANDLE cmapHandle; - }; - - QGLColormapData *d; - static struct QGLColormapData shared_null; - static void cleanup(QGLColormapData *x); - void detach_helper(); - - friend class QGLWidget; - friend class QGLWidgetPrivate; -}; - -inline void QGLColormap::detach() -{ - if (d->ref.loadRelaxed() != 1) - detach_helper(); -} - -QT_END_NAMESPACE - -#endif // QGLCOLORMAP_H diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp deleted file mode 100644 index d0f82a85fa..0000000000 --- a/src/opengl/qglframebufferobject.cpp +++ /dev/null @@ -1,1466 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglframebufferobject.h" -#include "qglframebufferobject_p.h" - -#include <qdebug.h> -#include <private/qgl_p.h> -#include <private/qfont_p.h> -#include "gl2paintengineex/qpaintengineex_opengl2_p.h" - -#include <qimage.h> -#include <qwindow.h> - -QT_BEGIN_NAMESPACE - -extern QImage qt_gl_read_frame_buffer(const QSize&, bool, bool); - -#define QGL_FUNC_CONTEXT const QGLContext *ctx = QGLContext::currentContext(); -#define QGL_FUNCP_CONTEXT const QGLContext *ctx = QGLContext::currentContext(); - -#ifndef QT_NO_DEBUG -#define QT_RESET_GLERROR() \ -{ \ - while (QOpenGLContext::currentContext()->functions()->glGetError() != GL_NO_ERROR) {} \ -} -#define QT_CHECK_GLERROR() \ -{ \ - GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); \ - if (err != GL_NO_ERROR) { \ - qDebug("[%s line %d] GL Error: %d", \ - __FILE__, __LINE__, (int)err); \ - } \ -} -#else -#define QT_RESET_GLERROR() {} -#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 - -#ifndef GL_RENDERBUFFER_SAMPLES -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#endif - -#ifndef GL_DEPTH24_STENCIL8 -#define GL_DEPTH24_STENCIL8 0x88F0 -#endif - -#ifndef GL_DEPTH_COMPONENT24 -#define GL_DEPTH_COMPONENT24 0x81A6 -#endif - -#ifndef GL_DEPTH_COMPONENT24_OES -#define GL_DEPTH_COMPONENT24_OES 0x81A6 -#endif - -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif - -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif - -#ifndef GL_DEPTH_STENCIL_ATTACHMENT -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#endif - -#ifndef GL_DEPTH_STENCIL -#define GL_DEPTH_STENCIL 0x84F9 -#endif - -/*! - \class QGLFramebufferObjectFormat - \inmodule QtOpenGL - \brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL - framebuffer object. - - \since 4.6 - \obsolete - - \ingroup painting-3D - - A framebuffer object has several characteristics: - \list - \li \l{setSamples()}{Number of samples per pixels.} - \li \l{setAttachment()}{Depth and/or stencil attachments.} - \li \l{setTextureTarget()}{Texture target.} - \li \l{setInternalTextureFormat()}{Internal texture format.} - \endlist - - Note that the desired attachments or number of samples per pixels might not - be supported by the hardware driver. Call QGLFramebufferObject::format() - after creating a QGLFramebufferObject to find the exact format that was - used to create the frame buffer object. - - \note This class has been deprecated in favor of QOpenGLFramebufferObjectFormat. - - \sa QGLFramebufferObject -*/ - -/*! - \internal -*/ -void QGLFramebufferObjectFormat::detach() -{ - if (d->ref.loadRelaxed() != 1) { - QGLFramebufferObjectFormatPrivate *newd - = new QGLFramebufferObjectFormatPrivate(d); - if (!d->ref.deref()) - delete d; - d = newd; - } -} - -/*! - Creates a QGLFramebufferObjectFormat object for specifying - the format of an OpenGL framebuffer object. - - By default the format specifies a non-multisample framebuffer object with no - attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8. - On OpenGL/ES systems, the default internal format is \c GL_RGBA. - - \sa samples(), attachment(), internalTextureFormat() -*/ - -QGLFramebufferObjectFormat::QGLFramebufferObjectFormat() -{ - d = new QGLFramebufferObjectFormatPrivate; -} - -/*! - Constructs a copy of \a other. -*/ - -QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other) -{ - d = other.d; - d->ref.ref(); -} - -/*! - Assigns \a other to this object. -*/ - -QGLFramebufferObjectFormat &QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other) -{ - if (d != other.d) { - other.d->ref.ref(); - if (!d->ref.deref()) - delete d; - d = other.d; - } - return *this; -} - -/*! - Destroys the QGLFramebufferObjectFormat. -*/ -QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat() -{ - if (!d->ref.deref()) - delete d; -} - -/*! - Sets the number of samples per pixel for a multisample framebuffer object - to \a samples. The default sample count of 0 represents a regular - non-multisample framebuffer object. - - If the desired amount of samples per pixel is not supported by the hardware - then the maximum number of samples per pixel will be used. Note that - multisample framebuffer objects cannot be bound as textures. Also, the - \c{GL_EXT_framebuffer_multisample} extension is required to create a - framebuffer with more than one sample per pixel. - - \sa samples() -*/ -void QGLFramebufferObjectFormat::setSamples(int samples) -{ - detach(); - d->samples = samples; -} - -/*! - Returns the number of samples per pixel if a framebuffer object - is a multisample framebuffer object. Otherwise, returns 0. - The default value is 0. - - \sa setSamples() -*/ -int QGLFramebufferObjectFormat::samples() const -{ - return d->samples; -} - -/*! - \since 4.8 - - Enables mipmapping if \a enabled is true; otherwise disables it. - - Mipmapping is disabled by default. - - If mipmapping is enabled, additional memory will be allocated for - the mipmap levels. The mipmap levels can be updated by binding the - texture and calling glGenerateMipmap(). Mipmapping cannot be enabled - for multisampled framebuffer objects. - - \sa mipmap(), QGLFramebufferObject::texture() -*/ -void QGLFramebufferObjectFormat::setMipmap(bool enabled) -{ - detach(); - d->mipmap = enabled; -} - -/*! - \since 4.8 - - Returns \c true if mipmapping is enabled. - - \sa setMipmap() -*/ -bool QGLFramebufferObjectFormat::mipmap() const -{ - return d->mipmap; -} - -/*! - Sets the attachment configuration of a framebuffer object to \a attachment. - - \sa attachment() -*/ -void QGLFramebufferObjectFormat::setAttachment(QGLFramebufferObject::Attachment attachment) -{ - detach(); - d->attachment = attachment; -} - -/*! - Returns the configuration of the depth and stencil buffers attached to - a framebuffer object. The default is QGLFramebufferObject::NoAttachment. - - \sa setAttachment() -*/ -QGLFramebufferObject::Attachment QGLFramebufferObjectFormat::attachment() const -{ - return d->attachment; -} - -/*! - Sets the texture target of the texture attached to a framebuffer object to - \a target. Ignored for multisample framebuffer objects. - - \sa textureTarget(), samples() -*/ -void QGLFramebufferObjectFormat::setTextureTarget(GLenum target) -{ - detach(); - d->target = target; -} - -/*! - Returns the texture target of the texture attached to a framebuffer object. - Ignored for multisample framebuffer objects. The default is - \c GL_TEXTURE_2D. - - \sa setTextureTarget(), samples() -*/ -GLenum QGLFramebufferObjectFormat::textureTarget() const -{ - return d->target; -} - -/*! - Sets the internal format of a framebuffer object's texture or - multisample framebuffer object's color buffer to - \a internalTextureFormat. - - \sa internalTextureFormat() -*/ -void QGLFramebufferObjectFormat::setInternalTextureFormat(GLenum internalTextureFormat) -{ - detach(); - d->internal_format = internalTextureFormat; -} - -/*! - Returns the internal format of a framebuffer object's texture or - multisample framebuffer object's color buffer. The default is - \c GL_RGBA8 on desktop OpenGL systems, and \c GL_RGBA on - OpenGL/ES systems. - - \sa setInternalTextureFormat() -*/ -GLenum QGLFramebufferObjectFormat::internalTextureFormat() const -{ - return d->internal_format; -} - -/*! - Returns \c true if all the options of this framebuffer object format - are the same as \a other; otherwise returns \c false. -*/ -bool QGLFramebufferObjectFormat::operator==(const QGLFramebufferObjectFormat& other) const -{ - if (d == other.d) - return true; - else - return d->equals(other.d); -} - -/*! - Returns \c false if all the options of this framebuffer object format - are the same as \a other; otherwise returns \c true. -*/ -bool QGLFramebufferObjectFormat::operator!=(const QGLFramebufferObjectFormat& other) const -{ - return !(*this == other); -} - -void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f, - QGLFramebufferObject::Attachment attachment) -{ - fbo = f; - m_thisFBO = fbo->d_func()->fbo(); // This shouldn't be needed - - // The context that the fbo was created in may not have depth - // and stencil buffers, but the fbo itself might. - fboFormat = QGLContext::currentContext()->format(); - if (attachment == QGLFramebufferObject::CombinedDepthStencil) { - fboFormat.setDepth(true); - fboFormat.setStencil(true); - } else if (attachment == QGLFramebufferObject::Depth) { - fboFormat.setDepth(true); - fboFormat.setStencil(false); - } else { - fboFormat.setDepth(false); - fboFormat.setStencil(false); - } - - GLenum format = f->format().internalTextureFormat(); - reqAlpha = (format != GL_RGB -#ifdef GL_RGB5 - && format != GL_RGB5 -#endif -#ifdef GL_RGB8 - && format != GL_RGB8 -#endif - ); -} - -QGLContext *QGLFBOGLPaintDevice::context() const -{ - return const_cast<QGLContext *>(QGLContext::currentContext()); -} - -bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const -{ - QGL_FUNCP_CONTEXT; - if (!ctx) - return false; // Context no longer exists. - GLenum status = ctx->contextHandle()->functions()->glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch(status) { - case GL_NO_ERROR: - case GL_FRAMEBUFFER_COMPLETE: - return true; - case GL_FRAMEBUFFER_UNSUPPORTED: - qDebug("QGLFramebufferObject: Unsupported framebuffer format."); - break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - qDebug("QGLFramebufferObject: Framebuffer incomplete attachment."); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - qDebug("QGLFramebufferObject: Framebuffer incomplete, missing attachment."); - break; -#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT - case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT: - qDebug("QGLFramebufferObject: Framebuffer incomplete, duplicate attachment."); - break; -#endif -#ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same dimensions."); - break; -#endif -#ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS: - qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same format."); - break; -#endif -#ifdef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - qDebug("QGLFramebufferObject: Framebuffer incomplete, missing draw buffer."); - break; -#endif -#ifdef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - qDebug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer."); - break; -#endif -#ifdef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - qDebug("QGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel."); - break; -#endif - default: - qDebug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status; - break; - } - return false; -} - -namespace -{ - void freeFramebufferFunc(QGLContext *ctx, GLuint id) - { - Q_ASSERT(ctx); - ctx->contextHandle()->functions()->glDeleteFramebuffers(1, &id); - } - - void freeRenderbufferFunc(QGLContext *ctx, GLuint id) - { - Q_ASSERT(ctx); - ctx->contextHandle()->functions()->glDeleteRenderbuffers(1, &id); - } - - void freeTextureFunc(QGLContext *ctx, GLuint id) - { - Q_UNUSED(ctx); - ctx->contextHandle()->functions()->glDeleteTextures(1, &id); - } -} - -void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, - QGLFramebufferObject::Attachment attachment, - GLenum texture_target, GLenum internal_format, - GLint samples, bool mipmap) -{ - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); - - funcs.initializeOpenGLFunctions(); - - if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers)) - return; - - ctx->d_ptr->refreshCurrentFbo(); - - size = sz; - target = texture_target; - // texture dimensions - - QT_RESET_GLERROR(); // reset error state - GLuint fbo = 0; - funcs.glGenFramebuffers(1, &fbo); - funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo); - - GLuint texture = 0; - GLuint color_buffer = 0; - GLuint depth_buffer = 0; - GLuint stencil_buffer = 0; - - QT_CHECK_GLERROR(); - // init texture - if (samples == 0) { - funcs.glGenTextures(1, &texture); - funcs.glBindTexture(target, texture); - funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - if (mipmap) { - int width = size.width(); - int height = size.height(); - int level = 0; - while (width > 1 || height > 1) { - width = qMax(1, width >> 1); - height = qMax(1, height >> 1); - ++level; - funcs.glTexImage2D(target, level, internal_format, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - } - } - funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - target, texture, 0); - - QT_CHECK_GLERROR(); - valid = checkFramebufferStatus(); - funcs.glBindTexture(target, 0); - - color_buffer = 0; - } else { - mipmap = false; - GLint maxSamples; - funcs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples); - - samples = qBound(0, int(samples), int(maxSamples)); - - funcs.glGenRenderbuffers(1, &color_buffer); - funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer); - if (funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) && samples > 0) { - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - internal_format, size.width(), size.height()); - } else { - samples = 0; - funcs.glRenderbufferStorage(GL_RENDERBUFFER, internal_format, - size.width(), size.height()); - } - - funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_RENDERBUFFER, color_buffer); - - QT_CHECK_GLERROR(); - valid = checkFramebufferStatus(); - - if (valid) - funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); - } - - // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a - // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer - // might not be supported while separate buffers are, according to QTBUG-12861. - - if (attachment == QGLFramebufferObject::CombinedDepthStencil - && funcs.hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil)) { - // depth and stencil buffer needs another extension - funcs.glGenRenderbuffers(1, &depth_buffer); - funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); - Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer)); -#ifndef Q_OS_WASM - if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH24_STENCIL8, size.width(), size.height()); - else - funcs.glRenderbufferStorage(GL_RENDERBUFFER, - GL_DEPTH24_STENCIL8, size.width(), size.height()); - - stencil_buffer = depth_buffer; - funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, depth_buffer); - funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, stencil_buffer); -#else - // webgl does not allow separate depth and stencil attachments - if (samples != 0) { - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_STENCIL, size.width(), size.height()); - } else { - funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, - size.width(), size.height()); - } - stencil_buffer = depth_buffer; - funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, depth_buffer); -#endif - - valid = checkFramebufferStatus(); - if (!valid) { - funcs.glDeleteRenderbuffers(1, &depth_buffer); - stencil_buffer = depth_buffer = 0; - } - } - - if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil - || (attachment == QGLFramebufferObject::Depth))) - { - funcs.glGenRenderbuffers(1, &depth_buffer); - 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_OES, size.width(), size.height()); - } else { - funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, - GL_DEPTH_COMPONENT16, size.width(), size.height()); - } -#else - if (ctx->contextHandle()->isOpenGLES()) { - 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 - if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) { - funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, - size.width(), size.height()); - } else { - funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, - size.width(), size.height()); - } -#else - if (ctx->contextHandle()->isOpenGLES()) { - 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, - GL_RENDERBUFFER, depth_buffer); - valid = checkFramebufferStatus(); - if (!valid) { - funcs.glDeleteRenderbuffers(1, &depth_buffer); - depth_buffer = 0; - } - } - - if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) { - funcs.glGenRenderbuffers(1, &stencil_buffer); - funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer); - Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer)); - -#ifdef QT_OPENGL_ES - GLenum storage = GL_STENCIL_INDEX8; -#else - GLenum storage = ctx->contextHandle()->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX; -#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(); - if (!valid) { - funcs.glDeleteRenderbuffers(1, &stencil_buffer); - stencil_buffer = 0; - } - } - - // The FBO might have become valid after removing the depth or stencil buffer. - valid = checkFramebufferStatus(); - - if (depth_buffer && stencil_buffer) { - fbo_attachment = QGLFramebufferObject::CombinedDepthStencil; - } else if (depth_buffer) { - fbo_attachment = QGLFramebufferObject::Depth; - } else { - fbo_attachment = QGLFramebufferObject::NoAttachment; - } - - funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo); - if (valid) { - fbo_guard = createSharedResourceGuard(ctx, fbo, freeFramebufferFunc); - if (color_buffer) - color_buffer_guard = createSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc); - else - texture_guard = createSharedResourceGuard(ctx, texture, freeTextureFunc); - if (depth_buffer) - depth_buffer_guard = createSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc); - if (stencil_buffer) { - if (stencil_buffer == depth_buffer) - stencil_buffer_guard = depth_buffer_guard; - else - stencil_buffer_guard = createSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc); - } - } else { - if (color_buffer) - funcs.glDeleteRenderbuffers(1, &color_buffer); - else - funcs.glDeleteTextures(1, &texture); - if (depth_buffer) - funcs.glDeleteRenderbuffers(1, &depth_buffer); - if (stencil_buffer && depth_buffer != stencil_buffer) - funcs.glDeleteRenderbuffers(1, &stencil_buffer); - funcs.glDeleteFramebuffers(1, &fbo); - } - QT_CHECK_GLERROR(); - - format.setTextureTarget(target); - format.setSamples(int(samples)); - format.setAttachment(fbo_attachment); - format.setInternalTextureFormat(internal_format); - format.setMipmap(mipmap); - - glDevice.setFBO(q, attachment); -} - -/*! - \class QGLFramebufferObject - \inmodule QtOpenGL - \brief The QGLFramebufferObject class encapsulates an OpenGL framebuffer object. - \since 4.2 - - \obsolete - - \ingroup painting-3D - - The QGLFramebufferObject class encapsulates an OpenGL framebuffer - object, defined by the \c{GL_EXT_framebuffer_object} extension. In - addition it provides a rendering surface that can be painted on - with a QPainter, rendered to using native GL calls, or both. This - surface can be bound and used as a regular texture in your own GL - drawing code. By default, the QGLFramebufferObject class - generates a 2D GL texture (using the \c{GL_TEXTURE_2D} target), - which is used as the internal rendering target. - - \b{It is important to have a current GL context when creating a - QGLFramebufferObject, otherwise initialization will fail.} - - OpenGL framebuffer objects and pbuffers (see - \l{QGLPixelBuffer}{QGLPixelBuffer}) can both be used to render to - offscreen surfaces, but there are a number of advantages with - using framebuffer objects instead of pbuffers: - - \list 1 - \li A framebuffer object does not require a separate rendering - context, so no context switching will occur when switching - rendering targets. There is an overhead involved in switching - targets, but in general it is cheaper than a context switch to a - pbuffer. - - \li Rendering to dynamic textures (i.e. render-to-texture - functionality) works on all platforms. No need to do explicit copy - calls from a render buffer into a texture, as was necessary on - systems that did not support the \c{render_texture} extension. - - \li It is possible to attach several rendering buffers (or texture - objects) to the same framebuffer object, and render to all of them - without doing a context switch. - - \li The OpenGL framebuffer extension is a pure GL extension with no - system dependant WGL, CGL, or GLX parts. This makes using - framebuffer objects more portable. - \endlist - - When using a QPainter to paint to a QGLFramebufferObject you should take - care that the QGLFramebufferObject is created with the CombinedDepthStencil - attachment for QPainter to be able to render correctly. - Note that you need to create a QGLFramebufferObject with more than one - sample per pixel for primitives to be antialiased when drawing using a - QPainter. To create a multisample framebuffer object you should use one of - the constructors that take a QGLFramebufferObjectFormat parameter, and set - the QGLFramebufferObjectFormat::samples() property to a non-zero value. - - When painting to a QGLFramebufferObject using QPainter, the state of - the current GL context will be altered by the paint engine to reflect - its needs. Applications should not rely upon the GL state being reset - to its original conditions, particularly the current shader program, - GL viewport, texture units, and drawing modes. - - For multisample framebuffer objects a color render buffer is created, - otherwise a texture with the specified texture target is created. - The color render buffer or texture will have the specified internal - format, and will be bound to the \c GL_COLOR_ATTACHMENT0 - attachment in the framebuffer object. - - If you want to use a framebuffer object with multisampling enabled - as a texture, you first need to copy from it to a regular framebuffer - object using QGLContext::blitFramebuffer(). - - \section1 Threading - - As of Qt 4.8, it's possible to draw into a QGLFramebufferObject - using a QPainter in a separate thread. Note that OpenGL 2.0 or - OpenGL ES 2.0 is required for this to work. - - \note This class has been deprecated in favor of QOpenGLFramebufferObject. -*/ - - -/*! - \enum QGLFramebufferObject::Attachment - \since 4.3 - - This enum type is used to configure the depth and stencil buffers - attached to the framebuffer object when it is created. - - \value NoAttachment No attachment is added to the framebuffer object. Note that the - OpenGL depth and stencil tests won't work when rendering to a - framebuffer object without any depth or stencil buffers. - This is the default value. - - \value CombinedDepthStencil If the \c GL_EXT_packed_depth_stencil extension is present, - a combined depth and stencil buffer is attached. - If the extension is not present, only a depth buffer is attached. - - \value Depth A depth buffer is attached to the framebuffer object. - - \sa attachment() -*/ - - -/*! \fn QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) - - Constructs an OpenGL framebuffer object and binds a 2D GL texture - to the buffer of the size \a size. The texture is bound to the - \c GL_COLOR_ATTACHMENT0 target in the framebuffer object. - - The \a target parameter is used to specify the GL texture - target. The default target is \c GL_TEXTURE_2D. Keep in mind that - \c GL_TEXTURE_2D textures must have a power of 2 width and height - (e.g. 256x512), unless you are using OpenGL 2.0 or higher. - - By default, no depth and stencil buffers are attached. This behavior - can be toggled using one of the overloaded constructors. - - The default internal texture format is \c GL_RGBA8 for desktop - OpenGL, and \c GL_RGBA for OpenGL/ES. - - It is important that you have a current GL context set when - creating the QGLFramebufferObject, otherwise the initialization - will fail. - - \sa size(), texture(), attachment() -*/ - -QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) - : d_ptr(new QGLFramebufferObjectPrivate) -{ - Q_D(QGLFramebufferObject); - d->init(this, size, NoAttachment, target, -#ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 -#else - GL_RGBA -#endif - ); -} - -/*! \overload - - Constructs an OpenGL framebuffer object and binds a 2D GL texture - to the buffer of the given \a width and \a height. - - \sa size(), texture() -*/ -QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target) - : d_ptr(new QGLFramebufferObjectPrivate) -{ - Q_D(QGLFramebufferObject); - d->init(this, QSize(width, height), NoAttachment, target, -#ifndef QT_OPENGL_ES_2 - QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8 -#else - GL_RGBA -#endif - ); -} - -/*! \overload - - Constructs an OpenGL framebuffer object of the given \a size based on the - supplied \a format. -*/ - -QGLFramebufferObject::QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format) - : d_ptr(new QGLFramebufferObjectPrivate) -{ - Q_D(QGLFramebufferObject); - d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(), - format.samples(), format.mipmap()); -} - -/*! \overload - - Constructs an OpenGL framebuffer object of the given \a width and \a height - based on the supplied \a format. -*/ - -QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format) - : d_ptr(new QGLFramebufferObjectPrivate) -{ - Q_D(QGLFramebufferObject); - d->init(this, QSize(width, height), format.attachment(), format.textureTarget(), - format.internalTextureFormat(), format.samples(), format.mipmap()); -} - -/*! \overload - - Constructs an OpenGL framebuffer object and binds a texture to the - buffer of the given \a width and \a height. - - The \a attachment parameter describes the depth/stencil buffer - configuration, \a target the texture target and \a internal_format - the internal texture format. The default texture target is \c - GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8 - for desktop OpenGL and \c GL_RGBA for OpenGL/ES. - - \sa size(), texture(), attachment() -*/ -QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment attachment, - GLenum target, GLenum internal_format) - : d_ptr(new QGLFramebufferObjectPrivate) -{ - Q_D(QGLFramebufferObject); - if (!internal_format) -#ifdef QT_OPENGL_ES_2 - internal_format = GL_RGBA; -#else - internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; -#endif - d->init(this, QSize(width, height), attachment, target, internal_format); -} - -/*! \overload - - Constructs an OpenGL framebuffer object and binds a texture to the - buffer of the given \a size. - - The \a attachment parameter describes the depth/stencil buffer - configuration, \a target the texture target and \a internal_format - the internal texture format. The default texture target is \c - GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8 - for desktop OpenGL and \c GL_RGBA for OpenGL/ES. - - \sa size(), texture(), attachment() -*/ -QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachment, - GLenum target, GLenum internal_format) - : d_ptr(new QGLFramebufferObjectPrivate) -{ - Q_D(QGLFramebufferObject); - if (!internal_format) -#ifdef QT_OPENGL_ES_2 - internal_format = GL_RGBA; -#else - internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; -#endif - d->init(this, size, attachment, target, internal_format); -} - -/*! - \fn QGLFramebufferObject::~QGLFramebufferObject() - - Destroys the framebuffer object and frees any allocated resources. -*/ -QGLFramebufferObject::~QGLFramebufferObject() -{ - Q_D(QGLFramebufferObject); - - delete d->engine; - - if (d->texture_guard) - d->texture_guard->free(); - if (d->color_buffer_guard) - d->color_buffer_guard->free(); - if (d->depth_buffer_guard) - d->depth_buffer_guard->free(); - if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard) - d->stencil_buffer_guard->free(); - if (d->fbo_guard) - d->fbo_guard->free(); -} - -/*! - \fn bool QGLFramebufferObject::isValid() const - - Returns \c true if the framebuffer object is valid. - - The framebuffer can become invalid if the initialization process - fails, the user attaches an invalid buffer to the framebuffer - object, or a non-power of two width/height is specified as the - texture size if the texture target is \c{GL_TEXTURE_2D}. - The non-power of two limitation does not apply if the OpenGL version - is 2.0 or higher, or if the GL_ARB_texture_non_power_of_two extension - is present. - - The framebuffer can also become invalid if the QGLContext that - the framebuffer was created within is destroyed and there are - no other shared contexts that can take over ownership of the - framebuffer. -*/ -bool QGLFramebufferObject::isValid() const -{ - Q_D(const QGLFramebufferObject); - return d->valid && d->fbo_guard && d->fbo_guard->id(); -} - -/*! - \fn bool QGLFramebufferObject::bind() - - Switches rendering from the default, windowing system provided - framebuffer to this framebuffer object. - Returns \c true upon success, false otherwise. - - \sa release() -*/ -bool QGLFramebufferObject::bind() -{ - if (!isValid()) - return false; - Q_D(QGLFramebufferObject); - QGL_FUNC_CONTEXT; - if (!ctx) - return false; // Context no longer exists. - const QGLContext *current = QGLContext::currentContext(); -#ifdef QT_DEBUG - if (!current || - QGLContextPrivate::contextGroup(current) != QGLContextPrivate::contextGroup(ctx)) - { - qWarning("QGLFramebufferObject::bind() called from incompatible context"); - } -#endif - d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo()); - d->valid = d->checkFramebufferStatus(); - if (d->valid && current) - current->d_ptr->setCurrentFbo(d->fbo()); - return d->valid; -} - -/*! - \fn bool QGLFramebufferObject::release() - - Switches rendering back to the default, windowing system provided - framebuffer. - Returns \c true upon success, false otherwise. - - \sa bind() -*/ -bool QGLFramebufferObject::release() -{ - if (!isValid()) - return false; - Q_D(QGLFramebufferObject); - QGL_FUNC_CONTEXT; - if (!ctx) - return false; // Context no longer exists. - - const QGLContext *current = QGLContext::currentContext(); - -#ifdef QT_DEBUG - if (!current || - QGLContextPrivate::contextGroup(current) != QGLContextPrivate::contextGroup(ctx)) - { - qWarning("QGLFramebufferObject::release() called from incompatible context"); - } -#endif - - if (current) { - current->d_ptr->setCurrentFbo(current->d_ptr->default_fbo); - d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_ptr->default_fbo); - } - - return true; -} - -/*! - \fn GLuint QGLFramebufferObject::texture() const - - Returns the texture id for the texture attached as the default - rendering target in this framebuffer object. This texture id can - be bound as a normal texture in your own GL code. - - If a multisample framebuffer object is used then the value returned - from this function will be invalid. -*/ -GLuint QGLFramebufferObject::texture() const -{ - Q_D(const QGLFramebufferObject); - return d->texture_guard ? d->texture_guard->id() : 0; -} - -/*! - \fn QSize QGLFramebufferObject::size() const - - Returns the size of the texture attached to this framebuffer - object. -*/ -QSize QGLFramebufferObject::size() const -{ - Q_D(const QGLFramebufferObject); - return d->size; -} - -/*! - Returns the format of this framebuffer object. -*/ -QGLFramebufferObjectFormat QGLFramebufferObject::format() const -{ - Q_D(const QGLFramebufferObject); - return d->format; -} - -/*! - \fn QImage QGLFramebufferObject::toImage() const - - Returns the contents of this framebuffer object as a QImage. - - The returned image has a format of premultiplied ARGB32 or RGB32. The latter is used - only when internalTextureFormat() is set to \c GL_RGB. - - If the rendering in the framebuffer was not done with premultiplied alpha in mind, - create a wrapper QImage with a non-premultiplied format. This is necessary before - performing operations like QImage::save() because otherwise the image data would get - unpremultiplied, even though it was not premultiplied in the first place. To create - such a wrapper without performing a copy of the pixel data, do the following: - - \code - QImage fboImage(fbo.toImage()); - QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_ARGB32); - \endcode - - On QNX the back buffer is not preserved when a buffer swap occures. So this function - might return old content. -*/ -QImage QGLFramebufferObject::toImage() const -{ - Q_D(const QGLFramebufferObject); - if (!d->valid) - return QImage(); - - // qt_gl_read_frame_buffer doesn't work on a multisample FBO - if (format().samples() != 0) { - QGLFramebufferObject temp(size(), QGLFramebufferObjectFormat()); - - QRect rect(QPoint(0, 0), size()); - blitFramebuffer(&temp, rect, const_cast<QGLFramebufferObject *>(this), rect); - - return temp.toImage(); - } - - bool wasBound = isBound(); - if (!wasBound) - const_cast<QGLFramebufferObject *>(this)->bind(); - QImage image = qt_gl_read_frame_buffer(d->size, format().internalTextureFormat() != GL_RGB, true); - if (!wasBound) - const_cast<QGLFramebufferObject *>(this)->release(); - - return image; -} - -Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine) - -/*! \reimp */ -QPaintEngine *QGLFramebufferObject::paintEngine() const -{ - Q_D(const QGLFramebufferObject); - if (d->engine) - return d->engine; - - QPaintEngine *engine = qt_buffer_2_engine()->engine(); - if (engine->isActive() && engine->paintDevice() != this) { - d->engine = new QGL2PaintEngineEx; - return d->engine; - } - return engine; -} - -/*! - \fn bool QGLFramebufferObject::bindDefault() - - Switches rendering back to the default, windowing system provided - framebuffer. - Returns \c true upon success, false otherwise. - - \sa bind(), release() -*/ -bool QGLFramebufferObject::bindDefault() -{ - QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); - - if (ctx) { - QOpenGLFunctions functions(ctx->contextHandle()); - if (!functions.hasOpenGLFeature(QOpenGLFunctions::Framebuffers)) - return false; - - ctx->d_ptr->setCurrentFbo(ctx->d_ptr->default_fbo); - functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->default_fbo); -#ifdef QT_DEBUG - } else { - qWarning("QGLFramebufferObject::bindDefault() called without current context."); -#endif - } - - return ctx != 0; -} - -/*! - \fn bool QGLFramebufferObject::hasOpenGLFramebufferObjects() - - Returns \c true if the OpenGL \c{GL_EXT_framebuffer_object} extension - is present on this system; otherwise returns \c false. -*/ -bool QGLFramebufferObject::hasOpenGLFramebufferObjects() -{ - return qgl_hasFeature(QOpenGLFunctions::Framebuffers); -} - -/*! - \since 4.4 - - Draws the given texture, \a textureId, to the given target rectangle, - \a target, in OpenGL model space. The \a textureTarget should be a 2D - texture target. - - The framebuffer object should be bound when calling this function. - - Equivalent to the corresponding QGLContext::drawTexture(). -*/ -void QGLFramebufferObject::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) -{ - const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget); -} - -/*! - \since 4.4 - - Draws the given texture, \a textureId, at the given \a point in OpenGL - model space. The \a textureTarget should be a 2D texture target. - - The framebuffer object should be bound when calling this function. - - Equivalent to the corresponding QGLContext::drawTexture(). -*/ -void QGLFramebufferObject::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) -{ - const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget); -} - -/*! \reimp */ -int QGLFramebufferObject::metric(PaintDeviceMetric metric) const -{ - Q_D(const QGLFramebufferObject); - - float dpmx = qt_defaultDpiX()*100./2.54; - float dpmy = qt_defaultDpiY()*100./2.54; - int w = d->size.width(); - int h = d->size.height(); - switch (metric) { - case PdmWidth: - return w; - - case PdmHeight: - return h; - - case PdmWidthMM: - return qRound(w * 1000 / dpmx); - - case PdmHeightMM: - return qRound(h * 1000 / dpmy); - - case PdmNumColors: - return 0; - - case PdmDepth: - return 32;//d->depth; - - case PdmDpiX: - return qRound(dpmx * 0.0254); - - case PdmDpiY: - return qRound(dpmy * 0.0254); - - case PdmPhysicalDpiX: - return qRound(dpmx * 0.0254); - - case PdmPhysicalDpiY: - return qRound(dpmy * 0.0254); - - case QPaintDevice::PdmDevicePixelRatio: - return 1; - - case QPaintDevice::PdmDevicePixelRatioScaled: - return 1 * QPaintDevice::devicePixelRatioFScale(); - - default: - qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric); - break; - } - return 0; -} - -/*! - \fn GLuint QGLFramebufferObject::handle() const - - Returns the GL framebuffer object handle for this framebuffer - object (returned by the \c{glGenFrameBuffersEXT()} function). This - handle can be used to attach new images or buffers to the - framebuffer. The user is responsible for cleaning up and - destroying these objects. -*/ -GLuint QGLFramebufferObject::handle() const -{ - Q_D(const QGLFramebufferObject); - return d->fbo(); -} - -/*! \fn int QGLFramebufferObject::devType() const - \internal -*/ - - -/*! - Returns the status of the depth and stencil buffers attached to - this framebuffer object. -*/ - -QGLFramebufferObject::Attachment QGLFramebufferObject::attachment() const -{ - Q_D(const QGLFramebufferObject); - if (d->valid) - return d->fbo_attachment; - return NoAttachment; -} - -/*! - \since 4.5 - - Returns \c true if the framebuffer object is currently bound to a context, - otherwise false is returned. -*/ - -bool QGLFramebufferObject::isBound() const -{ - Q_D(const QGLFramebufferObject); - const QGLContext *current = QGLContext::currentContext(); - if (current) { - current->d_ptr->refreshCurrentFbo(); - return current->d_ptr->current_fbo == d->fbo(); - } - - return false; -} - -/*! - \fn bool QGLFramebufferObject::hasOpenGLFramebufferBlit() - - \since 4.6 - - Returns \c true if the OpenGL \c{GL_EXT_framebuffer_blit} extension - is present on this system; otherwise returns \c false. - - \sa blitFramebuffer() -*/ -bool QGLFramebufferObject::hasOpenGLFramebufferBlit() -{ - return QOpenGLExtensions(QOpenGLContext::currentContext()).hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit); -} - -/*! - \since 4.6 - - Blits from the \a sourceRect rectangle in the \a source framebuffer - object to the \a targetRect rectangle in the \a target framebuffer object. - - If \a source or \a target is 0, the default framebuffer will be used - instead of a framebuffer object as source or target respectively. - - The \a buffers parameter should be a mask consisting of any combination of - \c GL_COLOR_BUFFER_BIT, \c GL_DEPTH_BUFFER_BIT, and - \c GL_STENCIL_BUFFER_BIT. Any buffer type that is not present both - in the source and target buffers is ignored. - - The \a sourceRect and \a targetRect rectangles may have different sizes; - in this case \a buffers should not contain \c GL_DEPTH_BUFFER_BIT or - \c GL_STENCIL_BUFFER_BIT. The \a filter parameter should be set to - \c GL_LINEAR or \c GL_NEAREST, and specifies whether linear or nearest - interpolation should be used when scaling is performed. - - If \a source equals \a target a copy is performed within the same buffer. - Results are undefined if the source and target rectangles overlap and - have different sizes. The sizes must also be the same if any of the - framebuffer objects are multisample framebuffers. - - Note that the scissor test will restrict the blit area if enabled. - - This function will have no effect unless hasOpenGLFramebufferBlit() returns - true. - - \sa hasOpenGLFramebufferBlit() -*/ -void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect, - QGLFramebufferObject *source, const QRect &sourceRect, - GLbitfield buffers, - GLenum filter) -{ - const QGLContext *ctx = QGLContext::currentContext(); - if (!ctx || !ctx->contextHandle()) - return; - - QOpenGLExtensions functions(ctx->contextHandle()); - if (!functions.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)) - return; - - QSurface *surface = ctx->contextHandle()->surface(); - - const int height = static_cast<QWindow *>(surface)->height(); - - const int sh = source ? source->height() : height; - const int th = target ? target->height() : height; - - const int sx0 = sourceRect.left(); - const int sx1 = sourceRect.left() + sourceRect.width(); - const int sy0 = sh - (sourceRect.top() + sourceRect.height()); - const int sy1 = sh - sourceRect.top(); - - const int tx0 = targetRect.left(); - const int tx1 = targetRect.left() + targetRect.width(); - const int ty0 = th - (targetRect.top() + targetRect.height()); - const int ty1 = th - targetRect.top(); - - ctx->d_ptr->refreshCurrentFbo(); - - functions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0); - functions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0); - - functions.glBlitFramebuffer(sx0, sy0, sx1, sy1, - tx0, ty0, tx1, ty1, - buffers, filter); - - functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo); -} - -QT_END_NAMESPACE diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h deleted file mode 100644 index c88063cbb5..0000000000 --- a/src/opengl/qglframebufferobject.h +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLFRAMEBUFFEROBJECT_H -#define QGLFRAMEBUFFEROBJECT_H - -#include <QtOpenGL/qgl.h> -#include <QtGui/qpaintdevice.h> - -QT_BEGIN_NAMESPACE - - -class QGLFramebufferObjectPrivate; -class QGLFramebufferObjectFormat; - -class Q_OPENGL_EXPORT QGLFramebufferObject : public QPaintDevice -{ - Q_DECLARE_PRIVATE(QGLFramebufferObject) -public: - enum Attachment { - NoAttachment, - CombinedDepthStencil, - Depth - }; - - QGLFramebufferObject(const QSize &size, GLenum target = GL_TEXTURE_2D); - QGLFramebufferObject(int width, int height, GLenum target = GL_TEXTURE_2D); - - QGLFramebufferObject(const QSize &size, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0); - QGLFramebufferObject(int width, int height, Attachment attachment, - GLenum target = GL_TEXTURE_2D, GLenum internal_format = 0); - - QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format); - QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format); - - virtual ~QGLFramebufferObject(); - - QGLFramebufferObjectFormat format() const; - - bool isValid() const; - bool isBound() const; - bool bind(); - bool release(); - - GLuint texture() const; - QSize size() const; - QImage toImage() const; - Attachment attachment() const; - - QPaintEngine *paintEngine() const override; - GLuint handle() const; - - static bool bindDefault(); - - static bool hasOpenGLFramebufferObjects(); - - void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); - void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); - - static bool hasOpenGLFramebufferBlit(); - static void blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect, - QGLFramebufferObject *source, const QRect &sourceRect, - GLbitfield buffers = GL_COLOR_BUFFER_BIT, - GLenum filter = GL_NEAREST); - -protected: - int metric(PaintDeviceMetric metric) const override; - int devType() const override { return QInternal::FramebufferObject; } - -private: - Q_DISABLE_COPY(QGLFramebufferObject) - QScopedPointer<QGLFramebufferObjectPrivate> d_ptr; - friend class QGLPaintDevice; - friend class QGLFBOGLPaintDevice; -}; - -class QGLFramebufferObjectFormatPrivate; -class Q_OPENGL_EXPORT QGLFramebufferObjectFormat -{ -public: - QGLFramebufferObjectFormat(); - QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other); - QGLFramebufferObjectFormat &operator=(const QGLFramebufferObjectFormat &other); - ~QGLFramebufferObjectFormat(); - - void setSamples(int samples); - int samples() const; - - void setMipmap(bool enabled); - bool mipmap() const; - - void setAttachment(QGLFramebufferObject::Attachment attachment); - QGLFramebufferObject::Attachment attachment() const; - - void setTextureTarget(GLenum target); - GLenum textureTarget() const; - - void setInternalTextureFormat(GLenum internalTextureFormat); - GLenum internalTextureFormat() const; - - bool operator==(const QGLFramebufferObjectFormat& other) const; - bool operator!=(const QGLFramebufferObjectFormat& other) const; - -private: - QGLFramebufferObjectFormatPrivate *d; - - void detach(); -}; - -QT_END_NAMESPACE - -#endif // QGLFRAMEBUFFEROBJECT_H diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h deleted file mode 100644 index 9d536527c3..0000000000 --- a/src/opengl/qglframebufferobject_p.h +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLFRAMEBUFFEROBJECT_P_H -#define QGLFRAMEBUFFEROBJECT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <qglframebufferobject.h> -#include <private/qglpaintdevice_p.h> -#include <private/qgl_p.h> -#include <private/qopenglextensions_p.h> - -QT_BEGIN_NAMESPACE - -class QGLFramebufferObjectFormatPrivate -{ -public: - QGLFramebufferObjectFormatPrivate() - : ref(1), - samples(0), - attachment(QGLFramebufferObject::NoAttachment), - target(GL_TEXTURE_2D), - mipmap(false) - { -#ifndef QT_OPENGL_ES_2 - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - const bool isES = ctx ? ctx->isOpenGLES() : QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL; - internal_format = isES ? GL_RGBA : GL_RGBA8; -#else - internal_format = GL_RGBA; -#endif - } - QGLFramebufferObjectFormatPrivate - (const QGLFramebufferObjectFormatPrivate *other) - : ref(1), - samples(other->samples), - attachment(other->attachment), - target(other->target), - internal_format(other->internal_format), - mipmap(other->mipmap) - { - } - bool equals(const QGLFramebufferObjectFormatPrivate *other) - { - return samples == other->samples && - attachment == other->attachment && - target == other->target && - internal_format == other->internal_format && - mipmap == other->mipmap; - } - - QAtomicInt ref; - int samples; - QGLFramebufferObject::Attachment attachment; - GLenum target; - GLenum internal_format; - uint mipmap : 1; -}; - -class QGLFBOGLPaintDevice : public QGLPaintDevice -{ -public: - virtual QPaintEngine* paintEngine() const override {return fbo->paintEngine();} - virtual QSize size() const override {return fbo->size();} - virtual QGLContext* context() const override; - virtual QGLFormat format() const override {return fboFormat;} - virtual bool alphaRequested() const override { return reqAlpha; } - - void setFBO(QGLFramebufferObject* f, - QGLFramebufferObject::Attachment attachment); - -private: - QGLFramebufferObject* fbo; - QGLFormat fboFormat; - bool reqAlpha; -}; - -class QGLFramebufferObjectPrivate -{ -public: - QGLFramebufferObjectPrivate() : fbo_guard(nullptr), texture_guard(nullptr), depth_buffer_guard(nullptr) - , stencil_buffer_guard(nullptr), color_buffer_guard(nullptr) - , valid(false), engine(nullptr) {} - ~QGLFramebufferObjectPrivate() {} - - void init(QGLFramebufferObject *q, const QSize& sz, - QGLFramebufferObject::Attachment attachment, - GLenum internal_format, GLenum texture_target, - GLint samples = 0, bool mipmap = false); - bool checkFramebufferStatus() const; - QGLSharedResourceGuardBase *fbo_guard; - QGLSharedResourceGuardBase *texture_guard; - QGLSharedResourceGuardBase *depth_buffer_guard; - QGLSharedResourceGuardBase *stencil_buffer_guard; - QGLSharedResourceGuardBase *color_buffer_guard; - GLenum target; - QSize size; - QGLFramebufferObjectFormat format; - uint valid : 1; - QGLFramebufferObject::Attachment fbo_attachment; - mutable QPaintEngine *engine; - QGLFBOGLPaintDevice glDevice; - QOpenGLExtensions funcs; - - inline GLuint fbo() const { return fbo_guard ? fbo_guard->id() : 0; } -}; - - -QT_END_NAMESPACE - -#endif // QGLFRAMEBUFFEROBJECT_P_H diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp deleted file mode 100644 index b20311bec4..0000000000 --- a/src/opengl/qglfunctions.cpp +++ /dev/null @@ -1,1330 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglfunctions.h" -#include "qgl_p.h" -#include "QtGui/private/qopenglcontext_p.h" -#include <private/qopengl_p.h> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLFunctions - \inmodule QtOpenGL - \brief The QGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API. - \since 4.8 - \obsolete - \ingroup painting-3D - - OpenGL ES 2.0 defines a subset of the OpenGL specification that is - common across many desktop and embedded OpenGL implementations. - However, it can be difficult to use the functions from that subset - because they need to be resolved manually on desktop systems. - - QGLFunctions provides a guaranteed API that is available on all - OpenGL systems and takes care of function resolution on systems - that need it. The recommended way to use QGLFunctions is by - direct inheritance: - - \snippet code/src_opengl_qglfunctions.cpp 0 - - The \c{paintGL()} function can then use any of the OpenGL ES 2.0 - functions without explicit resolution, such as glActiveTexture() - in the following example: - - \snippet code/src_opengl_qglfunctions.cpp 1 - - QGLFunctions can also be used directly for ad-hoc invocation - of OpenGL ES 2.0 functions on all platforms: - - \snippet code/src_opengl_qglfunctions.cpp 2 - - QGLFunctions provides wrappers for all OpenGL ES 2.0 functions, - except those like \c{glDrawArrays()}, \c{glViewport()}, and - \c{glBindTexture()} that don't have portability issues. - - Including the header for QGLFunctions will also define all of - the OpenGL ES 2.0 macro constants that are not already defined by - the system's OpenGL headers, such as \c{GL_TEXTURE1} above. - - The hasOpenGLFeature() and openGLFeatures() functions can be used - to determine if the OpenGL implementation has a major OpenGL ES 2.0 - feature. For example, the following checks if non power of two - textures are available: - - \snippet code/src_opengl_qglfunctions.cpp 3 - - \note This class has been deprecated in favor of QOpenGLFunctions. -*/ - -/*! - \enum QGLFunctions::OpenGLFeature - This enum defines OpenGL ES 2.0 features that may be optional - on other platforms. - - \value Multitexture glActiveTexture() function is available. - \value Shaders Shader functions are available. - \value Buffers Vertex and index buffer functions are available. - \value Framebuffers Framebuffer object functions are available. - \value BlendColor glBlendColor() is available. - \value BlendEquation glBlendEquation() is available. - \value BlendEquationSeparate glBlendEquationSeparate() is available. - \value BlendFuncSeparate glBlendFuncSeparate() is available. - \value BlendSubtract Blend subtract mode is available. - \value CompressedTextures Compressed texture functions are available. - \value Multisample glSampleCoverage() function is available. - \value StencilSeparate Separate stencil functions are available. - \value NPOTTextures Non power of two textures are available. -*/ - -// Hidden private fields for additional extension data. -struct QGLFunctionsPrivateEx : public QGLFunctionsPrivate, public QOpenGLSharedResource -{ - QGLFunctionsPrivateEx(QOpenGLContext *context) - : QGLFunctionsPrivate(QGLContext::fromOpenGLContext(context)) - , QOpenGLSharedResource(context->shareGroup()) - , m_features(-1) - { - funcs = new QOpenGLFunctions(context); - funcs->initializeOpenGLFunctions(); - } - - ~QGLFunctionsPrivateEx() - { - delete funcs; - } - - void invalidateResource() override - { - m_features = -1; - } - - void freeResource(QOpenGLContext *) override - { - // no gl resources to free - } - - int m_features; -}; - -Q_GLOBAL_STATIC(QOpenGLMultiGroupSharedResource, qt_gl_functions_resource) - -static QGLFunctionsPrivateEx *qt_gl_functions(const QGLContext *context = 0) -{ - if (!context) - context = QGLContext::currentContext(); - Q_ASSERT(context); - QGLFunctionsPrivateEx *funcs = - reinterpret_cast<QGLFunctionsPrivateEx *> - (qt_gl_functions_resource()->value<QGLFunctionsPrivateEx>(context->contextHandle())); - return funcs; -} - -/*! - Constructs a default function resolver. The resolver cannot - be used until initializeGLFunctions() is called to specify - the context. - - \sa initializeGLFunctions() -*/ -QGLFunctions::QGLFunctions() - : d_ptr(0) -{ -} - -/*! - Constructs a function resolver for \a context. If \a context - is \nullptr, then the resolver will be created for the current - QGLContext. - - An object constructed in this way can only be used with \a context - and other contexts that share with it. Use initializeGLFunctions() - to change the object's context association. - - \sa initializeGLFunctions() -*/ -QGLFunctions::QGLFunctions(const QGLContext *context) - : d_ptr(qt_gl_functions(context)) -{ -} - -/*! - \fn QGLFunctions::~QGLFunctions() - - Destroys this function resolver. -*/ - -static int qt_gl_resolve_features() -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->isOpenGLES()) { - // 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; - } else { - // OpenGL - 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") || - 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; - - // 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; - } -} - -/*! - Returns the set of features that are present on this system's - OpenGL implementation. - - It is assumed that the QGLContext associated with this function - resolver is current. - - \sa hasOpenGLFeature() -*/ -QGLFunctions::OpenGLFeatures QGLFunctions::openGLFeatures() const -{ - QGLFunctionsPrivateEx *d = static_cast<QGLFunctionsPrivateEx *>(d_ptr); - if (!d) - return { }; - if (d->m_features == -1) - d->m_features = qt_gl_resolve_features(); - return QGLFunctions::OpenGLFeatures(d->m_features); -} - -/*! - Returns \c true if \a feature is present on this system's OpenGL - implementation; false otherwise. - - It is assumed that the QGLContext associated with this function - resolver is current. - - \sa openGLFeatures() -*/ -bool QGLFunctions::hasOpenGLFeature(QGLFunctions::OpenGLFeature feature) const -{ - QGLFunctionsPrivateEx *d = static_cast<QGLFunctionsPrivateEx *>(d_ptr); - if (!d) - return false; - if (d->m_features == -1) - d->m_features = qt_gl_resolve_features(); - return (d->m_features & int(feature)) != 0; -} - -/*! - Initializes GL function resolution for \a context. If \a context - is \nullptr, then the current QGLContext will be used. - - After calling this function, the QGLFunctions object can only be - used with \a context and other contexts that share with it. - Call initializeGLFunctions() again to change the object's context - association. -*/ -void QGLFunctions::initializeGLFunctions(const QGLContext *context) -{ - d_ptr = qt_gl_functions(context); -} - -/*! - \fn void QGLFunctions::glActiveTexture(GLenum texture) - - Convenience function that calls glActiveTexture(\a texture). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glActiveTexture.xml}{glActiveTexture()}. -*/ - -/*! - \fn void QGLFunctions::glAttachShader(GLuint program, GLuint shader) - - Convenience function that calls glAttachShader(\a program, \a shader). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glAttachShader.xml}{glAttachShader()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glBindAttribLocation(GLuint program, GLuint index, const char* name) - - Convenience function that calls glBindAttribLocation(\a program, \a index, \a name). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBindAttribLocation.xml}{glBindAttribLocation()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glBindBuffer(GLenum target, GLuint buffer) - - Convenience function that calls glBindBuffer(\a target, \a buffer). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBindBuffer.xml}{glBindBuffer()}. -*/ - -/*! - \fn void QGLFunctions::glBindFramebuffer(GLenum target, GLuint framebuffer) - - Convenience function that calls glBindFramebuffer(\a target, \a framebuffer). - - Note that Qt will translate a \a framebuffer argument of 0 to the currently - bound QOpenGLContext's defaultFramebufferObject(). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBindFramebuffer.xml}{glBindFramebuffer()}. -*/ - -/*! - \fn void QGLFunctions::glBindRenderbuffer(GLenum target, GLuint renderbuffer) - - Convenience function that calls glBindRenderbuffer(\a target, \a renderbuffer). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBindRenderbuffer.xml}{glBindRenderbuffer()}. -*/ - -/*! - \fn void QGLFunctions::glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) - - Convenience function that calls glBlendColor(\a red, \a green, \a blue, \a alpha). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendColor.xml}{glBlendColor()}. -*/ - -/*! - \fn void QGLFunctions::glBlendEquation(GLenum mode) - - Convenience function that calls glBlendEquation(\a mode). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquation.xml}{glBlendEquation()}. -*/ - -/*! - \fn void QGLFunctions::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) - - Convenience function that calls glBlendEquationSeparate(\a modeRGB, \a modeAlpha). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquationSeparate.xml}{glBlendEquationSeparate()}. -*/ - -/*! - \fn void QGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) - - Convenience function that calls glBlendFuncSeparate(\a srcRGB, \a dstRGB, \a srcAlpha, \a dstAlpha). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBlendFuncSeparate.xml}{glBlendFuncSeparate()}. -*/ - -/*! - \fn void QGLFunctions::glBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage) - - Convenience function that calls glBufferData(\a target, \a size, \a data, \a usage). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBufferData.xml}{glBufferData()}. -*/ - -/*! - \fn void QGLFunctions::glBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data) - - Convenience function that calls glBufferSubData(\a target, \a offset, \a size, \a data). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glBufferSubData.xml}{glBufferSubData()}. -*/ - -/*! - \fn GLenum QGLFunctions::glCheckFramebufferStatus(GLenum target) - - Convenience function that calls glCheckFramebufferStatus(\a target). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glCheckFramebufferStatus.xml}{glCheckFramebufferStatus()}. -*/ - -/*! - \fn void QGLFunctions::glClearDepthf(GLclampf depth) - - Convenience function that calls glClearDepth(\a depth) on - desktop OpenGL systems and glClearDepthf(\a depth) on - embedded OpenGL ES systems. - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glClearDepthf.xml}{glClearDepthf()}. -*/ - -/*! - \fn void QGLFunctions::glCompileShader(GLuint shader) - - Convenience function that calls glCompileShader(\a shader). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glCompileShader.xml}{glCompileShader()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) - - Convenience function that calls glCompressedTexImage2D(\a target, \a level, \a internalformat, \a width, \a height, \a border, \a imageSize, \a data). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexImage2D.xml}{glCompressedTexImage2D()}. -*/ - -/*! - \fn void QGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) - - Convenience function that calls glCompressedTexSubImage2D(\a target, \a level, \a xoffset, \a yoffset, \a width, \a height, \a format, \a imageSize, \a data). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexSubImage2D.xml}{glCompressedTexSubImage2D()}. -*/ - -/*! - \fn GLuint QGLFunctions::glCreateProgram() - - Convenience function that calls glCreateProgram(). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glCreateProgram.xml}{glCreateProgram()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn GLuint QGLFunctions::glCreateShader(GLenum type) - - Convenience function that calls glCreateShader(\a type). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glCreateShader.xml}{glCreateShader()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers) - - Convenience function that calls glDeleteBuffers(\a n, \a buffers). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteBuffers.xml}{glDeleteBuffers()}. -*/ - -/*! - \fn void QGLFunctions::glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) - - Convenience function that calls glDeleteFramebuffers(\a n, \a framebuffers). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteFramebuffers.xml}{glDeleteFramebuffers()}. -*/ - -/*! - \fn void QGLFunctions::glDeleteProgram(GLuint program) - - Convenience function that calls glDeleteProgram(\a program). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteProgram.xml}{glDeleteProgram()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) - - Convenience function that calls glDeleteRenderbuffers(\a n, \a renderbuffers). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteRenderbuffers.xml}{glDeleteRenderbuffers()}. -*/ - -/*! - \fn void QGLFunctions::glDeleteShader(GLuint shader) - - Convenience function that calls glDeleteShader(\a shader). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteShader.xml}{glDeleteShader()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glDepthRangef(GLclampf zNear, GLclampf zFar) - - Convenience function that calls glDepthRange(\a zNear, \a zFar) on - desktop OpenGL systems and glDepthRangef(\a zNear, \a zFar) on - embedded OpenGL ES systems. - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glDepthRangef.xml}{glDepthRangef()}. -*/ - -/*! - \fn void QGLFunctions::glDetachShader(GLuint program, GLuint shader) - - Convenience function that calls glDetachShader(\a program, \a shader). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glDetachShader.xml}{glDetachShader()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glDisableVertexAttribArray(GLuint index) - - Convenience function that calls glDisableVertexAttribArray(\a index). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glDisableVertexAttribArray.xml}{glDisableVertexAttribArray()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glEnableVertexAttribArray(GLuint index) - - Convenience function that calls glEnableVertexAttribArray(\a index). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glEnableVertexAttribArray.xml}{glEnableVertexAttribArray()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) - - Convenience function that calls glFramebufferRenderbuffer(\a target, \a attachment, \a renderbuffertarget, \a renderbuffer). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferRenderbuffer.xml}{glFramebufferRenderbuffer()}. -*/ - -/*! - \fn void QGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) - - Convenience function that calls glFramebufferTexture2D(\a target, \a attachment, \a textarget, \a texture, \a level). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferTexture2D.xml}{glFramebufferTexture2D()}. -*/ - -/*! - \fn void QGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers) - - Convenience function that calls glGenBuffers(\a n, \a buffers). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGenBuffers.xml}{glGenBuffers()}. -*/ - -/*! - \fn void QGLFunctions::glGenerateMipmap(GLenum target) - - Convenience function that calls glGenerateMipmap(\a target). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGenerateMipmap.xml}{glGenerateMipmap()}. -*/ - -/*! - \fn void QGLFunctions::glGenFramebuffers(GLsizei n, GLuint* framebuffers) - - Convenience function that calls glGenFramebuffers(\a n, \a framebuffers). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGenFramebuffers.xml}{glGenFramebuffers()}. -*/ - -/*! - \fn void QGLFunctions::glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) - - Convenience function that calls glGenRenderbuffers(\a n, \a renderbuffers). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGenRenderbuffers.xml}{glGenRenderbuffers()}. -*/ - -/*! - \fn void QGLFunctions::glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) - - Convenience function that calls glGetActiveAttrib(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveAttrib.xml}{glGetActiveAttrib()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) - - Convenience function that calls glGetActiveUniform(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveUniform.xml}{glGetActiveUniform()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) - - Convenience function that calls glGetAttachedShaders(\a program, \a maxcount, \a count, \a shaders). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttachedShaders.xml}{glGetAttachedShaders()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn int QGLFunctions::glGetAttribLocation(GLuint program, const char* name) - - Convenience function that calls glGetAttribLocation(\a program, \a name). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttribLocation.xml}{glGetAttribLocation()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) - - Convenience function that calls glGetBufferParameteriv(\a target, \a pname, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetBufferParameteriv.xml}{glGetBufferParameteriv()}. -*/ - -/*! - \fn void QGLFunctions::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) - - Convenience function that calls glGetFramebufferAttachmentParameteriv(\a target, \a attachment, \a pname, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetFramebufferAttachmentParameteriv.xml}{glGetFramebufferAttachmentParameteriv()}. -*/ - -/*! - \fn void QGLFunctions::glGetProgramiv(GLuint program, GLenum pname, GLint* params) - - Convenience function that calls glGetProgramiv(\a program, \a pname, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramiv.xml}{glGetProgramiv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) - - Convenience function that calls glGetProgramInfoLog(\a program, \a bufsize, \a length, \a infolog). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramInfoLog.xml}{glGetProgramInfoLog()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) - - Convenience function that calls glGetRenderbufferParameteriv(\a target, \a pname, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetRenderbufferParameteriv.xml}{glGetRenderbufferParameteriv()}. -*/ - -/*! - \fn void QGLFunctions::glGetShaderiv(GLuint shader, GLenum pname, GLint* params) - - Convenience function that calls glGetShaderiv(\a shader, \a pname, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderiv.xml}{glGetShaderiv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) - - Convenience function that calls glGetShaderInfoLog(\a shader, \a bufsize, \a length, \a infolog). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderInfoLog.xml}{glGetShaderInfoLog()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) - - Convenience function that calls glGetShaderPrecisionFormat(\a shadertype, \a precisiontype, \a range, \a precision). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderPrecisionFormat.xml}{glGetShaderPrecisionFormat()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) - - Convenience function that calls glGetShaderSource(\a shader, \a bufsize, \a length, \a source). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderSource.xml}{glGetShaderSource()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetUniformfv(GLuint program, GLint location, GLfloat* params) - - Convenience function that calls glGetUniformfv(\a program, \a location, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformfv.xml}{glGetUniformfv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetUniformiv(GLuint program, GLint location, GLint* params) - - Convenience function that calls glGetUniformiv(\a program, \a location, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformiv.xml}{glGetUniformiv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn int QGLFunctions::glGetUniformLocation(GLuint program, const char* name) - - Convenience function that calls glGetUniformLocation(\a program, \a name). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformLocation.xml}{glGetUniformLocation()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) - - Convenience function that calls glGetVertexAttribfv(\a index, \a pname, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribfv.xml}{glGetVertexAttribfv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) - - Convenience function that calls glGetVertexAttribiv(\a index, \a pname, \a params). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribiv.xml}{glGetVertexAttribiv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) - - Convenience function that calls glGetVertexAttribPointerv(\a index, \a pname, \a pointer). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribPointerv.xml}{glGetVertexAttribPointerv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn GLboolean QGLFunctions::glIsBuffer(GLuint buffer) - - Convenience function that calls glIsBuffer(\a buffer). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glIsBuffer.xml}{glIsBuffer()}. -*/ - -/*! - \fn GLboolean QGLFunctions::glIsFramebuffer(GLuint framebuffer) - - Convenience function that calls glIsFramebuffer(\a framebuffer). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glIsFramebuffer.xml}{glIsFramebuffer()}. -*/ - -/*! - \fn GLboolean QGLFunctions::glIsProgram(GLuint program) - - Convenience function that calls glIsProgram(\a program). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glIsProgram.xml}{glIsProgram()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn GLboolean QGLFunctions::glIsRenderbuffer(GLuint renderbuffer) - - Convenience function that calls glIsRenderbuffer(\a renderbuffer). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glIsRenderbuffer.xml}{glIsRenderbuffer()}. -*/ - -/*! - \fn GLboolean QGLFunctions::glIsShader(GLuint shader) - - Convenience function that calls glIsShader(\a shader). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glIsShader.xml}{glIsShader()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glLinkProgram(GLuint program) - - Convenience function that calls glLinkProgram(\a program). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glLinkProgram.xml}{glLinkProgram()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glReleaseShaderCompiler() - - Convenience function that calls glReleaseShaderCompiler(). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glReleaseShaderCompiler.xml}{glReleaseShaderCompiler()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) - - Convenience function that calls glRenderbufferStorage(\a target, \a internalformat, \a width, \a height). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glRenderbufferStorage.xml}{glRenderbufferStorage()}. -*/ - -/*! - \fn void QGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert) - - Convenience function that calls glSampleCoverage(\a value, \a invert). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glSampleCoverage.xml}{glSampleCoverage()}. -*/ - -/*! - \fn void QGLFunctions::glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length) - - Convenience function that calls glShaderBinary(\a n, \a shaders, \a binaryformat, \a binary, \a length). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glShaderBinary.xml}{glShaderBinary()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length) - - Convenience function that calls glShaderSource(\a shader, \a count, \a string, \a length). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glShaderSource.xml}{glShaderSource()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) - - Convenience function that calls glStencilFuncSeparate(\a face, \a func, \a ref, \a mask). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilFuncSeparate.xml}{glStencilFuncSeparate()}. -*/ - -/*! - \fn void QGLFunctions::glStencilMaskSeparate(GLenum face, GLuint mask) - - Convenience function that calls glStencilMaskSeparate(\a face, \a mask). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilMaskSeparate.xml}{glStencilMaskSeparate()}. -*/ - -/*! - \fn void QGLFunctions::glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) - - Convenience function that calls glStencilOpSeparate(\a face, \a fail, \a zfail, \a zpass). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glStencilOpSeparate.xml}{glStencilOpSeparate()}. -*/ - -/*! - \fn void QGLFunctions::glUniform1f(GLint location, GLfloat x) - - Convenience function that calls glUniform1f(\a location, \a x). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1f.xml}{glUniform1f()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform1fv(GLint location, GLsizei count, const GLfloat* v) - - Convenience function that calls glUniform1fv(\a location, \a count, \a v). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1fv.xml}{glUniform1fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform1i(GLint location, GLint x) - - Convenience function that calls glUniform1i(\a location, \a x). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1i.xml}{glUniform1i()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform1iv(GLint location, GLsizei count, const GLint* v) - - Convenience function that calls glUniform1iv(\a location, \a count, \a v). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1iv.xml}{glUniform1iv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform2f(GLint location, GLfloat x, GLfloat y) - - Convenience function that calls glUniform2f(\a location, \a x, \a y). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2f.xml}{glUniform2f()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform2fv(GLint location, GLsizei count, const GLfloat* v) - - Convenience function that calls glUniform2fv(\a location, \a count, \a v). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2fv.xml}{glUniform2fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform2i(GLint location, GLint x, GLint y) - - Convenience function that calls glUniform2i(\a location, \a x, \a y). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2i.xml}{glUniform2i()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform2iv(GLint location, GLsizei count, const GLint* v) - - Convenience function that calls glUniform2iv(\a location, \a count, \a v). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2iv.xml}{glUniform2iv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) - - Convenience function that calls glUniform3f(\a location, \a x, \a y, \a z). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3f.xml}{glUniform3f()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform3fv(GLint location, GLsizei count, const GLfloat* v) - - Convenience function that calls glUniform3fv(\a location, \a count, \a v). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3fv.xml}{glUniform3fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform3i(GLint location, GLint x, GLint y, GLint z) - - Convenience function that calls glUniform3i(\a location, \a x, \a y, \a z). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3i.xml}{glUniform3i()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform3iv(GLint location, GLsizei count, const GLint* v) - - Convenience function that calls glUniform3iv(\a location, \a count, \a v). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3iv.xml}{glUniform3iv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) - - Convenience function that calls glUniform4f(\a location, \a x, \a y, \a z, \a w). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4f.xml}{glUniform4f()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform4fv(GLint location, GLsizei count, const GLfloat* v) - - Convenience function that calls glUniform4fv(\a location, \a count, \a v). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4fv.xml}{glUniform4fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) - - Convenience function that calls glUniform4i(\a location, \a x, \a y, \a z, \a w). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4i.xml}{glUniform4i()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniform4iv(GLint location, GLsizei count, const GLint* v) - - Convenience function that calls glUniform4iv(\a location, \a count, \a v). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4iv.xml}{glUniform4iv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) - - Convenience function that calls glUniformMatrix2fv(\a location, \a count, \a transpose, \a value). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix2fv.xml}{glUniformMatrix2fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) - - Convenience function that calls glUniformMatrix3fv(\a location, \a count, \a transpose, \a value). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix3fv.xml}{glUniformMatrix3fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) - - Convenience function that calls glUniformMatrix4fv(\a location, \a count, \a transpose, \a value). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix4fv.xml}{glUniformMatrix4fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glUseProgram(GLuint program) - - Convenience function that calls glUseProgram(\a program). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glUseProgram.xml}{glUseProgram()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glValidateProgram(GLuint program) - - Convenience function that calls glValidateProgram(\a program). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glValidateProgram.xml}{glValidateProgram()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttrib1f(GLuint indx, GLfloat x) - - Convenience function that calls glVertexAttrib1f(\a indx, \a x). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1f.xml}{glVertexAttrib1f()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttrib1fv(GLuint indx, const GLfloat* values) - - Convenience function that calls glVertexAttrib1fv(\a indx, \a values). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1fv.xml}{glVertexAttrib1fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) - - Convenience function that calls glVertexAttrib2f(\a indx, \a x, \a y). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2f.xml}{glVertexAttrib2f()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttrib2fv(GLuint indx, const GLfloat* values) - - Convenience function that calls glVertexAttrib2fv(\a indx, \a values). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2fv.xml}{glVertexAttrib2fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) - - Convenience function that calls glVertexAttrib3f(\a indx, \a x, \a y, \a z). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3f.xml}{glVertexAttrib3f()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttrib3fv(GLuint indx, const GLfloat* values) - - Convenience function that calls glVertexAttrib3fv(\a indx, \a values). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3fv.xml}{glVertexAttrib3fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) - - Convenience function that calls glVertexAttrib4f(\a indx, \a x, \a y, \a z, \a w). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4f.xml}{glVertexAttrib4f()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttrib4fv(GLuint indx, const GLfloat* values) - - Convenience function that calls glVertexAttrib4fv(\a indx, \a values). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4fv.xml}{glVertexAttrib4fv()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -/*! - \fn void QGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) - - Convenience function that calls glVertexAttribPointer(\a indx, \a size, \a type, \a normalized, \a stride, \a ptr). - - For more information, see the OpenGL ES 2.0 documentation for - \l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttribPointer.xml}{glVertexAttribPointer()}. - - This convenience function will do nothing on OpenGL ES 1.x systems. -*/ - -QGLFunctionsPrivate::QGLFunctionsPrivate(const QGLContext *) - : funcs(0) -{ -} - -QT_END_NAMESPACE diff --git a/src/opengl/qglfunctions.h b/src/opengl/qglfunctions.h deleted file mode 100644 index d8c5249a1a..0000000000 --- a/src/opengl/qglfunctions.h +++ /dev/null @@ -1,1688 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLFUNCTIONS_H -#define QGLFUNCTIONS_H - -#include <QtOpenGL/qgl.h> -#include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglfunctions.h> - -QT_BEGIN_NAMESPACE - -struct QGLFunctionsPrivate; - -class Q_OPENGL_EXPORT QGLFunctions -{ -public: - QGLFunctions(); - explicit QGLFunctions(const QGLContext *context); - ~QGLFunctions() {} - - enum OpenGLFeature - { - Multitexture = 0x0001, - Shaders = 0x0002, - Buffers = 0x0004, - Framebuffers = 0x0008, - BlendColor = 0x0010, - BlendEquation = 0x0020, - BlendEquationSeparate = 0x0040, - BlendFuncSeparate = 0x0080, - BlendSubtract = 0x0100, - CompressedTextures = 0x0200, - Multisample = 0x0400, - StencilSeparate = 0x0800, - NPOTTextures = 0x1000 - }; - Q_DECLARE_FLAGS(OpenGLFeatures, OpenGLFeature) - - QGLFunctions::OpenGLFeatures openGLFeatures() const; - bool hasOpenGLFeature(QGLFunctions::OpenGLFeature feature) const; - - void initializeGLFunctions(const QGLContext *context = nullptr); - - void glActiveTexture(GLenum texture); - void glAttachShader(GLuint program, GLuint shader); - void glBindAttribLocation(GLuint program, GLuint index, const char* name); - void glBindBuffer(GLenum target, GLuint buffer); - void glBindFramebuffer(GLenum target, GLuint framebuffer); - void glBindRenderbuffer(GLenum target, GLuint renderbuffer); - void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - void glBlendEquation(GLenum mode); - void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha); - void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); - void glBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage); - void glBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data); - GLenum glCheckFramebufferStatus(GLenum target); - void glClearDepthf(GLclampf depth); - void glCompileShader(GLuint shader); - void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); - void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); - GLuint glCreateProgram(); - GLuint glCreateShader(GLenum type); - void glDeleteBuffers(GLsizei n, const GLuint* buffers); - void glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers); - void glDeleteProgram(GLuint program); - void glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers); - void glDeleteShader(GLuint shader); - void glDepthRangef(GLclampf zNear, GLclampf zFar); - void glDetachShader(GLuint program, GLuint shader); - void glDisableVertexAttribArray(GLuint index); - void glEnableVertexAttribArray(GLuint index); - void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); - void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); - void glGenBuffers(GLsizei n, GLuint* buffers); - void glGenerateMipmap(GLenum target); - void glGenFramebuffers(GLsizei n, GLuint* framebuffers); - void glGenRenderbuffers(GLsizei n, GLuint* renderbuffers); - void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); - void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); - void glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); - int glGetAttribLocation(GLuint program, const char* name); - void glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params); - void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params); - void glGetProgramiv(GLuint program, GLenum pname, GLint* params); - void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog); - void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params); - void glGetShaderiv(GLuint shader, GLenum pname, GLint* params); - void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog); - void glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); - void glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source); - void glGetUniformfv(GLuint program, GLint location, GLfloat* params); - void glGetUniformiv(GLuint program, GLint location, GLint* params); - int glGetUniformLocation(GLuint program, const char* name); - void glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params); - void glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params); - void glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer); - GLboolean glIsBuffer(GLuint buffer); - GLboolean glIsFramebuffer(GLuint framebuffer); - GLboolean glIsProgram(GLuint program); - GLboolean glIsRenderbuffer(GLuint renderbuffer); - GLboolean glIsShader(GLuint shader); - void glLinkProgram(GLuint program); - void glReleaseShaderCompiler(); - void glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - void glSampleCoverage(GLclampf value, GLboolean invert); - void glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length); - void glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length); - void glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); - void glStencilMaskSeparate(GLenum face, GLuint mask); - void glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); - void glUniform1f(GLint location, GLfloat x); - void glUniform1fv(GLint location, GLsizei count, const GLfloat* v); - void glUniform1i(GLint location, GLint x); - void glUniform1iv(GLint location, GLsizei count, const GLint* v); - void glUniform2f(GLint location, GLfloat x, GLfloat y); - void glUniform2fv(GLint location, GLsizei count, const GLfloat* v); - void glUniform2i(GLint location, GLint x, GLint y); - void glUniform2iv(GLint location, GLsizei count, const GLint* v); - void glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z); - void glUniform3fv(GLint location, GLsizei count, const GLfloat* v); - void glUniform3i(GLint location, GLint x, GLint y, GLint z); - void glUniform3iv(GLint location, GLsizei count, const GLint* v); - void glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void glUniform4fv(GLint location, GLsizei count, const GLfloat* v); - void glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w); - void glUniform4iv(GLint location, GLsizei count, const GLint* v); - void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); - void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); - void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); - void glUseProgram(GLuint program); - void glValidateProgram(GLuint program); - void glVertexAttrib1f(GLuint indx, GLfloat x); - void glVertexAttrib1fv(GLuint indx, const GLfloat* values); - void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y); - void glVertexAttrib2fv(GLuint indx, const GLfloat* values); - void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z); - void glVertexAttrib3fv(GLuint indx, const GLfloat* values); - void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void glVertexAttrib4fv(GLuint indx, const GLfloat* values); - void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); - -private: - QGLFunctionsPrivate *d_ptr; - static bool isInitialized(const QGLFunctionsPrivate *d) { return d != nullptr; } -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QGLFunctions::OpenGLFeatures) - -struct QGLFunctionsPrivate -{ - QGLFunctionsPrivate(const QGLContext *context = nullptr); - QOpenGLFunctions *funcs; -}; - -inline void QGLFunctions::glActiveTexture(GLenum texture) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glActiveTexture(texture); -} - -inline void QGLFunctions::glAttachShader(GLuint program, GLuint shader) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glAttachShader(program, shader); -} - -inline void QGLFunctions::glBindAttribLocation(GLuint program, GLuint index, const char* name) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBindAttribLocation(program, index, name); -} - -inline void QGLFunctions::glBindBuffer(GLenum target, GLuint buffer) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBindBuffer(target, buffer); -} - -inline void QGLFunctions::glBindFramebuffer(GLenum target, GLuint framebuffer) -{ - if (framebuffer == 0) - framebuffer = QOpenGLContext::currentContext()->defaultFramebufferObject(); - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBindFramebuffer(target, framebuffer); -} - -inline void QGLFunctions::glBindRenderbuffer(GLenum target, GLuint renderbuffer) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBindRenderbuffer(target, renderbuffer); -} - -inline void QGLFunctions::glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBlendColor(red, green, blue, alpha); -} - -inline void QGLFunctions::glBlendEquation(GLenum mode) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBlendEquation(mode); -} - -inline void QGLFunctions::glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBlendEquationSeparate(modeRGB, modeAlpha); -} - -inline void QGLFunctions::glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); -} - -inline void QGLFunctions::glBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBufferData(target, size, data, usage); -} - -inline void QGLFunctions::glBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glBufferSubData(target, offset, size, data); -} - -inline GLenum QGLFunctions::glCheckFramebufferStatus(GLenum target) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glCheckFramebufferStatus(target); -} - -inline void QGLFunctions::glClearDepthf(GLclampf depth) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glClearDepthf(depth); -} - -inline void QGLFunctions::glCompileShader(GLuint shader) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glCompileShader(shader); -} - -inline void QGLFunctions::glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data); -} - -inline void QGLFunctions::glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data); -} - -inline GLuint QGLFunctions::glCreateProgram() -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glCreateProgram(); -} - -inline GLuint QGLFunctions::glCreateShader(GLenum type) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glCreateShader(type); -} - -inline void QGLFunctions::glDeleteBuffers(GLsizei n, const GLuint* buffers) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glDeleteBuffers(n, buffers); -} - -inline void QGLFunctions::glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glDeleteFramebuffers(n, framebuffers); -} - -inline void QGLFunctions::glDeleteProgram(GLuint program) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glDeleteProgram(program); -} - -inline void QGLFunctions::glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glDeleteRenderbuffers(n, renderbuffers); -} - -inline void QGLFunctions::glDeleteShader(GLuint shader) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glDeleteShader(shader); -} - -inline void QGLFunctions::glDepthRangef(GLclampf zNear, GLclampf zFar) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glDepthRangef(zNear, zFar); -} - -inline void QGLFunctions::glDetachShader(GLuint program, GLuint shader) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glDetachShader(program, shader); -} - -inline void QGLFunctions::glDisableVertexAttribArray(GLuint index) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glDisableVertexAttribArray(index); -} - -inline void QGLFunctions::glEnableVertexAttribArray(GLuint index) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glEnableVertexAttribArray(index); -} - -inline void QGLFunctions::glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); -} - -inline void QGLFunctions::glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glFramebufferTexture2D(target, attachment, textarget, texture, level); -} - -inline void QGLFunctions::glGenBuffers(GLsizei n, GLuint* buffers) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGenBuffers(n, buffers); -} - -inline void QGLFunctions::glGenerateMipmap(GLenum target) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGenerateMipmap(target); -} - -inline void QGLFunctions::glGenFramebuffers(GLsizei n, GLuint* framebuffers) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGenFramebuffers(n, framebuffers); -} - -inline void QGLFunctions::glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGenRenderbuffers(n, renderbuffers); -} - -inline void QGLFunctions::glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetActiveAttrib(program, index, bufsize, length, size, type, name); -} - -inline void QGLFunctions::glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetActiveUniform(program, index, bufsize, length, size, type, name); -} - -inline void QGLFunctions::glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetAttachedShaders(program, maxcount, count, shaders); -} - -inline int QGLFunctions::glGetAttribLocation(GLuint program, const char* name) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glGetAttribLocation(program, name); -} - -inline void QGLFunctions::glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetBufferParameteriv(target, pname, params); -} - -inline void QGLFunctions::glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); -} - -inline void QGLFunctions::glGetProgramiv(GLuint program, GLenum pname, GLint* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetProgramiv(program, pname, params); -} - -inline void QGLFunctions::glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetProgramInfoLog(program, bufsize, length, infolog); -} - -inline void QGLFunctions::glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetRenderbufferParameteriv(target, pname, params); -} - -inline void QGLFunctions::glGetShaderiv(GLuint shader, GLenum pname, GLint* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetShaderiv(shader, pname, params); -} - -inline void QGLFunctions::glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetShaderInfoLog(shader, bufsize, length, infolog); -} - -inline void QGLFunctions::glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision); -} - -inline void QGLFunctions::glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetShaderSource(shader, bufsize, length, source); -} - -inline void QGLFunctions::glGetUniformfv(GLuint program, GLint location, GLfloat* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetUniformfv(program, location, params); -} - -inline void QGLFunctions::glGetUniformiv(GLuint program, GLint location, GLint* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetUniformiv(program, location, params); -} - -inline int QGLFunctions::glGetUniformLocation(GLuint program, const char* name) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glGetUniformLocation(program, name); -} - -inline void QGLFunctions::glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetVertexAttribfv(index, pname, params); -} - -inline void QGLFunctions::glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetVertexAttribiv(index, pname, params); -} - -inline void QGLFunctions::glGetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glGetVertexAttribPointerv(index, pname, pointer); -} - -inline GLboolean QGLFunctions::glIsBuffer(GLuint buffer) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glIsBuffer(buffer); -} - -inline GLboolean QGLFunctions::glIsFramebuffer(GLuint framebuffer) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glIsFramebuffer(framebuffer); -} - -inline GLboolean QGLFunctions::glIsProgram(GLuint program) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glIsProgram(program); -} - -inline GLboolean QGLFunctions::glIsRenderbuffer(GLuint renderbuffer) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glIsRenderbuffer(renderbuffer); -} - -inline GLboolean QGLFunctions::glIsShader(GLuint shader) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - return d_ptr->funcs->glIsShader(shader); -} - -inline void QGLFunctions::glLinkProgram(GLuint program) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glLinkProgram(program); -} - -inline void QGLFunctions::glReleaseShaderCompiler() -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glReleaseShaderCompiler(); -} - -inline void QGLFunctions::glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glRenderbufferStorage(target, internalformat, width, height); -} - -inline void QGLFunctions::glSampleCoverage(GLclampf value, GLboolean invert) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glSampleCoverage(value, invert); -} - -inline void QGLFunctions::glShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLint length) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glShaderBinary(n, shaders, binaryformat, binary, length); -} - -inline void QGLFunctions::glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glShaderSource(shader, count, string, length); -} - -inline void QGLFunctions::glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glStencilFuncSeparate(face, func, ref, mask); -} - -inline void QGLFunctions::glStencilMaskSeparate(GLenum face, GLuint mask) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glStencilMaskSeparate(face, mask); -} - -inline void QGLFunctions::glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glStencilOpSeparate(face, fail, zfail, zpass); -} - -inline void QGLFunctions::glUniform1f(GLint location, GLfloat x) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform1f(location, x); -} - -inline void QGLFunctions::glUniform1fv(GLint location, GLsizei count, const GLfloat* v) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform1fv(location, count, v); -} - -inline void QGLFunctions::glUniform1i(GLint location, GLint x) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform1i(location, x); -} - -inline void QGLFunctions::glUniform1iv(GLint location, GLsizei count, const GLint* v) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform1iv(location, count, v); -} - -inline void QGLFunctions::glUniform2f(GLint location, GLfloat x, GLfloat y) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform2f(location, x, y); -} - -inline void QGLFunctions::glUniform2fv(GLint location, GLsizei count, const GLfloat* v) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform2fv(location, count, v); -} - -inline void QGLFunctions::glUniform2i(GLint location, GLint x, GLint y) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform2i(location, x, y); -} - -inline void QGLFunctions::glUniform2iv(GLint location, GLsizei count, const GLint* v) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform2iv(location, count, v); -} - -inline void QGLFunctions::glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform3f(location, x, y, z); -} - -inline void QGLFunctions::glUniform3fv(GLint location, GLsizei count, const GLfloat* v) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform3fv(location, count, v); -} - -inline void QGLFunctions::glUniform3i(GLint location, GLint x, GLint y, GLint z) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform3i(location, x, y, z); -} - -inline void QGLFunctions::glUniform3iv(GLint location, GLsizei count, const GLint* v) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform3iv(location, count, v); -} - -inline void QGLFunctions::glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform4f(location, x, y, z, w); -} - -inline void QGLFunctions::glUniform4fv(GLint location, GLsizei count, const GLfloat* v) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform4fv(location, count, v); -} - -inline void QGLFunctions::glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform4i(location, x, y, z, w); -} - -inline void QGLFunctions::glUniform4iv(GLint location, GLsizei count, const GLint* v) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniform4iv(location, count, v); -} - -inline void QGLFunctions::glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniformMatrix2fv(location, count, transpose, value); -} - -inline void QGLFunctions::glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniformMatrix3fv(location, count, transpose, value); -} - -inline void QGLFunctions::glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUniformMatrix4fv(location, count, transpose, value); -} - -inline void QGLFunctions::glUseProgram(GLuint program) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glUseProgram(program); -} - -inline void QGLFunctions::glValidateProgram(GLuint program) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glValidateProgram(program); -} - -inline void QGLFunctions::glVertexAttrib1f(GLuint indx, GLfloat x) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttrib1f(indx, x); -} - -inline void QGLFunctions::glVertexAttrib1fv(GLuint indx, const GLfloat* values) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttrib1fv(indx, values); -} - -inline void QGLFunctions::glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttrib2f(indx, x, y); -} - -inline void QGLFunctions::glVertexAttrib2fv(GLuint indx, const GLfloat* values) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttrib2fv(indx, values); -} - -inline void QGLFunctions::glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttrib3f(indx, x, y, z); -} - -inline void QGLFunctions::glVertexAttrib3fv(GLuint indx, const GLfloat* values) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttrib3fv(indx, values); -} - -inline void QGLFunctions::glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttrib4f(indx, x, y, z, w); -} - -inline void QGLFunctions::glVertexAttrib4fv(GLuint indx, const GLfloat* values) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttrib4fv(indx, values); -} - -inline void QGLFunctions::glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) -{ - Q_ASSERT(QGLFunctions::isInitialized(d_ptr)); - d_ptr->funcs->glVertexAttribPointer(indx, size, type, normalized, stride, ptr); -} - -#ifndef GL_ACTIVE_ATTRIBUTE_MAX_LENGTH -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#endif -#ifndef GL_ACTIVE_ATTRIBUTES -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#endif -#ifndef GL_ACTIVE_TEXTURE -#define GL_ACTIVE_TEXTURE 0x84E0 -#endif -#ifndef GL_ACTIVE_UNIFORM_MAX_LENGTH -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#endif -#ifndef GL_ACTIVE_UNIFORMS -#define GL_ACTIVE_UNIFORMS 0x8B86 -#endif -#ifndef GL_ALIASED_LINE_WIDTH_RANGE -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#endif -#ifndef GL_ALIASED_POINT_SIZE_RANGE -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#endif -#ifndef GL_ALPHA -#define GL_ALPHA 0x1906 -#endif -#ifndef GL_ALPHA_BITS -#define GL_ALPHA_BITS 0x0D55 -#endif -#ifndef GL_ALWAYS -#define GL_ALWAYS 0x0207 -#endif -#ifndef GL_ARRAY_BUFFER -#define GL_ARRAY_BUFFER 0x8892 -#endif -#ifndef GL_ARRAY_BUFFER_BINDING -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#endif -#ifndef GL_ATTACHED_SHADERS -#define GL_ATTACHED_SHADERS 0x8B85 -#endif -#ifndef GL_BACK -#define GL_BACK 0x0405 -#endif -#ifndef GL_BLEND -#define GL_BLEND 0x0BE2 -#endif -#ifndef GL_BLEND_COLOR -#define GL_BLEND_COLOR 0x8005 -#endif -#ifndef GL_BLEND_DST_ALPHA -#define GL_BLEND_DST_ALPHA 0x80CA -#endif -#ifndef GL_BLEND_DST_RGB -#define GL_BLEND_DST_RGB 0x80C8 -#endif -#ifndef GL_BLEND_EQUATION -#define GL_BLEND_EQUATION 0x8009 -#endif -#ifndef GL_BLEND_EQUATION_ALPHA -#define GL_BLEND_EQUATION_ALPHA 0x883D -#endif -#ifndef GL_BLEND_EQUATION_RGB -#define GL_BLEND_EQUATION_RGB 0x8009 -#endif -#ifndef GL_BLEND_SRC_ALPHA -#define GL_BLEND_SRC_ALPHA 0x80CB -#endif -#ifndef GL_BLEND_SRC_RGB -#define GL_BLEND_SRC_RGB 0x80C9 -#endif -#ifndef GL_BLUE_BITS -#define GL_BLUE_BITS 0x0D54 -#endif -#ifndef GL_BOOL -#define GL_BOOL 0x8B56 -#endif -#ifndef GL_BOOL_VEC2 -#define GL_BOOL_VEC2 0x8B57 -#endif -#ifndef GL_BOOL_VEC3 -#define GL_BOOL_VEC3 0x8B58 -#endif -#ifndef GL_BOOL_VEC4 -#define GL_BOOL_VEC4 0x8B59 -#endif -#ifndef GL_BUFFER_SIZE -#define GL_BUFFER_SIZE 0x8764 -#endif -#ifndef GL_BUFFER_USAGE -#define GL_BUFFER_USAGE 0x8765 -#endif -#ifndef GL_BYTE -#define GL_BYTE 0x1400 -#endif -#ifndef GL_CCW -#define GL_CCW 0x0901 -#endif -#ifndef GL_CLAMP_TO_EDGE -#define GL_CLAMP_TO_EDGE 0x812F -#endif -#ifndef GL_COLOR_ATTACHMENT0 -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#endif -#ifndef GL_COLOR_BUFFER_BIT -#define GL_COLOR_BUFFER_BIT 0x00004000 -#endif -#ifndef GL_COLOR_CLEAR_VALUE -#define GL_COLOR_CLEAR_VALUE 0x0C22 -#endif -#ifndef GL_COLOR_WRITEMASK -#define GL_COLOR_WRITEMASK 0x0C23 -#endif -#ifndef GL_COMPILE_STATUS -#define GL_COMPILE_STATUS 0x8B81 -#endif -#ifndef GL_COMPRESSED_TEXTURE_FORMATS -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#endif -#ifndef GL_CONSTANT_ALPHA -#define GL_CONSTANT_ALPHA 0x8003 -#endif -#ifndef GL_CONSTANT_COLOR -#define GL_CONSTANT_COLOR 0x8001 -#endif -#ifndef GL_CULL_FACE -#define GL_CULL_FACE 0x0B44 -#endif -#ifndef GL_CULL_FACE_MODE -#define GL_CULL_FACE_MODE 0x0B45 -#endif -#ifndef GL_CURRENT_PROGRAM -#define GL_CURRENT_PROGRAM 0x8B8D -#endif -#ifndef GL_CURRENT_VERTEX_ATTRIB -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#endif -#ifndef GL_CW -#define GL_CW 0x0900 -#endif -#ifndef GL_DECR -#define GL_DECR 0x1E03 -#endif -#ifndef GL_DECR_WRAP -#define GL_DECR_WRAP 0x8508 -#endif -#ifndef GL_DELETE_STATUS -#define GL_DELETE_STATUS 0x8B80 -#endif -#ifndef GL_DEPTH_ATTACHMENT -#define GL_DEPTH_ATTACHMENT 0x8D00 -#endif -#ifndef GL_DEPTH_BITS -#define GL_DEPTH_BITS 0x0D56 -#endif -#ifndef GL_DEPTH_BUFFER_BIT -#define GL_DEPTH_BUFFER_BIT 0x00000100 -#endif -#ifndef GL_DEPTH_CLEAR_VALUE -#define GL_DEPTH_CLEAR_VALUE 0x0B73 -#endif -#ifndef GL_DEPTH_COMPONENT -#define GL_DEPTH_COMPONENT 0x1902 -#endif -#ifndef GL_DEPTH_COMPONENT16 -#define GL_DEPTH_COMPONENT16 0x81A5 -#endif -#ifndef GL_DEPTH_FUNC -#define GL_DEPTH_FUNC 0x0B74 -#endif -#ifndef GL_DEPTH_RANGE -#define GL_DEPTH_RANGE 0x0B70 -#endif -#ifndef GL_DEPTH_TEST -#define GL_DEPTH_TEST 0x0B71 -#endif -#ifndef GL_DEPTH_WRITEMASK -#define GL_DEPTH_WRITEMASK 0x0B72 -#endif -#ifndef GL_DITHER -#define GL_DITHER 0x0BD0 -#endif -#ifndef GL_DONT_CARE -#define GL_DONT_CARE 0x1100 -#endif -#ifndef GL_DST_ALPHA -#define GL_DST_ALPHA 0x0304 -#endif -#ifndef GL_DST_COLOR -#define GL_DST_COLOR 0x0306 -#endif -#ifndef GL_DYNAMIC_DRAW -#define GL_DYNAMIC_DRAW 0x88E8 -#endif -#ifndef GL_ELEMENT_ARRAY_BUFFER -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#endif -#ifndef GL_ELEMENT_ARRAY_BUFFER_BINDING -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#endif -#ifndef GL_EQUAL -#define GL_EQUAL 0x0202 -#endif -#ifndef GL_EXTENSIONS -#define GL_EXTENSIONS 0x1F03 -#endif -#ifndef GL_FALSE -#define GL_FALSE 0 -#endif -#ifndef GL_FASTEST -#define GL_FASTEST 0x1101 -#endif -#ifndef GL_FIXED -#define GL_FIXED 0x140C -#endif -#ifndef GL_FLOAT -#define GL_FLOAT 0x1406 -#endif -#ifndef GL_FLOAT_MAT2 -#define GL_FLOAT_MAT2 0x8B5A -#endif -#ifndef GL_FLOAT_MAT3 -#define GL_FLOAT_MAT3 0x8B5B -#endif -#ifndef GL_FLOAT_MAT4 -#define GL_FLOAT_MAT4 0x8B5C -#endif -#ifndef GL_FLOAT_VEC2 -#define GL_FLOAT_VEC2 0x8B50 -#endif -#ifndef GL_FLOAT_VEC3 -#define GL_FLOAT_VEC3 0x8B51 -#endif -#ifndef GL_FLOAT_VEC4 -#define GL_FLOAT_VEC4 0x8B52 -#endif -#ifndef GL_FRAGMENT_SHADER -#define GL_FRAGMENT_SHADER 0x8B30 -#endif -#ifndef GL_FRAMEBUFFER -#define GL_FRAMEBUFFER 0x8D40 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#endif -#ifndef GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#endif -#ifndef GL_FRAMEBUFFER_BINDING -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#endif -#ifndef GL_FRAMEBUFFER_COMPLETE -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#endif -#ifndef GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#endif -#ifndef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 -#endif -#ifndef GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#endif -#ifndef GL_FRAMEBUFFER_UNSUPPORTED -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#endif -#ifndef GL_FRONT -#define GL_FRONT 0x0404 -#endif -#ifndef GL_FRONT_AND_BACK -#define GL_FRONT_AND_BACK 0x0408 -#endif -#ifndef GL_FRONT_FACE -#define GL_FRONT_FACE 0x0B46 -#endif -#ifndef GL_FUNC_ADD -#define GL_FUNC_ADD 0x8006 -#endif -#ifndef GL_FUNC_REVERSE_SUBTRACT -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#endif -#ifndef GL_FUNC_SUBTRACT -#define GL_FUNC_SUBTRACT 0x800A -#endif -#ifndef GL_GENERATE_MIPMAP_HINT -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#endif -#ifndef GL_GEQUAL -#define GL_GEQUAL 0x0206 -#endif -#ifndef GL_GREATER -#define GL_GREATER 0x0204 -#endif -#ifndef GL_GREEN_BITS -#define GL_GREEN_BITS 0x0D53 -#endif -#ifndef GL_HIGH_FLOAT -#define GL_HIGH_FLOAT 0x8DF2 -#endif -#ifndef GL_HIGH_INT -#define GL_HIGH_INT 0x8DF5 -#endif -#ifndef GL_IMPLEMENTATION_COLOR_READ_FORMAT -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B -#endif -#ifndef GL_IMPLEMENTATION_COLOR_READ_TYPE -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#endif -#ifndef GL_INCR -#define GL_INCR 0x1E02 -#endif -#ifndef GL_INCR_WRAP -#define GL_INCR_WRAP 0x8507 -#endif -#ifndef GL_INFO_LOG_LENGTH -#define GL_INFO_LOG_LENGTH 0x8B84 -#endif -#ifndef GL_INT -#define GL_INT 0x1404 -#endif -#ifndef GL_INT_VEC2 -#define GL_INT_VEC2 0x8B53 -#endif -#ifndef GL_INT_VEC3 -#define GL_INT_VEC3 0x8B54 -#endif -#ifndef GL_INT_VEC4 -#define GL_INT_VEC4 0x8B55 -#endif -#ifndef GL_INVALID_ENUM -#define GL_INVALID_ENUM 0x0500 -#endif -#ifndef GL_INVALID_FRAMEBUFFER_OPERATION -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#endif -#ifndef GL_INVALID_OPERATION -#define GL_INVALID_OPERATION 0x0502 -#endif -#ifndef GL_INVALID_VALUE -#define GL_INVALID_VALUE 0x0501 -#endif -#ifndef GL_INVERT -#define GL_INVERT 0x150A -#endif -#ifndef GL_KEEP -#define GL_KEEP 0x1E00 -#endif -#ifndef GL_LEQUAL -#define GL_LEQUAL 0x0203 -#endif -#ifndef GL_LESS -#define GL_LESS 0x0201 -#endif -#ifndef GL_LINEAR -#define GL_LINEAR 0x2601 -#endif -#ifndef GL_LINEAR_MIPMAP_LINEAR -#define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#endif -#ifndef GL_LINEAR_MIPMAP_NEAREST -#define GL_LINEAR_MIPMAP_NEAREST 0x2701 -#endif -#ifndef GL_LINE_LOOP -#define GL_LINE_LOOP 0x0002 -#endif -#ifndef GL_LINES -#define GL_LINES 0x0001 -#endif -#ifndef GL_LINE_STRIP -#define GL_LINE_STRIP 0x0003 -#endif -#ifndef GL_LINE_WIDTH -#define GL_LINE_WIDTH 0x0B21 -#endif -#ifndef GL_LINK_STATUS -#define GL_LINK_STATUS 0x8B82 -#endif -#ifndef GL_LOW_FLOAT -#define GL_LOW_FLOAT 0x8DF0 -#endif -#ifndef GL_LOW_INT -#define GL_LOW_INT 0x8DF3 -#endif -#ifndef GL_LUMINANCE -#define GL_LUMINANCE 0x1909 -#endif -#ifndef GL_LUMINANCE_ALPHA -#define GL_LUMINANCE_ALPHA 0x190A -#endif -#ifndef GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#endif -#ifndef GL_MAX_CUBE_MAP_TEXTURE_SIZE -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#endif -#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#endif -#ifndef GL_MAX_RENDERBUFFER_SIZE -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#endif -#ifndef GL_MAX_TEXTURE_IMAGE_UNITS -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#endif -#ifndef GL_MAX_TEXTURE_SIZE -#define GL_MAX_TEXTURE_SIZE 0x0D33 -#endif -#ifndef GL_MAX_VARYING_VECTORS -#define GL_MAX_VARYING_VECTORS 0x8DFC -#endif -#ifndef GL_MAX_VERTEX_ATTRIBS -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#endif -#ifndef GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#endif -#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#endif -#ifndef GL_MAX_VIEWPORT_DIMS -#define GL_MAX_VIEWPORT_DIMS 0x0D3A -#endif -#ifndef GL_MEDIUM_FLOAT -#define GL_MEDIUM_FLOAT 0x8DF1 -#endif -#ifndef GL_MEDIUM_INT -#define GL_MEDIUM_INT 0x8DF4 -#endif -#ifndef GL_MIRRORED_REPEAT -#define GL_MIRRORED_REPEAT 0x8370 -#endif -#ifndef GL_NEAREST -#define GL_NEAREST 0x2600 -#endif -#ifndef GL_NEAREST_MIPMAP_LINEAR -#define GL_NEAREST_MIPMAP_LINEAR 0x2702 -#endif -#ifndef GL_NEAREST_MIPMAP_NEAREST -#define GL_NEAREST_MIPMAP_NEAREST 0x2700 -#endif -#ifndef GL_NEVER -#define GL_NEVER 0x0200 -#endif -#ifndef GL_NICEST -#define GL_NICEST 0x1102 -#endif -#ifndef GL_NO_ERROR -#define GL_NO_ERROR 0 -#endif -#ifndef GL_NONE -#define GL_NONE 0 -#endif -#ifndef GL_NOTEQUAL -#define GL_NOTEQUAL 0x0205 -#endif -#ifndef GL_NUM_COMPRESSED_TEXTURE_FORMATS -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#endif -#ifndef GL_NUM_SHADER_BINARY_FORMATS -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#endif -#ifndef GL_ONE -#define GL_ONE 1 -#endif -#ifndef GL_ONE_MINUS_CONSTANT_ALPHA -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#endif -#ifndef GL_ONE_MINUS_CONSTANT_COLOR -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#endif -#ifndef GL_ONE_MINUS_DST_ALPHA -#define GL_ONE_MINUS_DST_ALPHA 0x0305 -#endif -#ifndef GL_ONE_MINUS_DST_COLOR -#define GL_ONE_MINUS_DST_COLOR 0x0307 -#endif -#ifndef GL_ONE_MINUS_SRC_ALPHA -#define GL_ONE_MINUS_SRC_ALPHA 0x0303 -#endif -#ifndef GL_ONE_MINUS_SRC_COLOR -#define GL_ONE_MINUS_SRC_COLOR 0x0301 -#endif -#ifndef GL_OUT_OF_MEMORY -#define GL_OUT_OF_MEMORY 0x0505 -#endif -#ifndef GL_PACK_ALIGNMENT -#define GL_PACK_ALIGNMENT 0x0D05 -#endif -#ifndef GL_POINTS -#define GL_POINTS 0x0000 -#endif -#ifndef GL_POLYGON_OFFSET_FACTOR -#define GL_POLYGON_OFFSET_FACTOR 0x8038 -#endif -#ifndef GL_POLYGON_OFFSET_FILL -#define GL_POLYGON_OFFSET_FILL 0x8037 -#endif -#ifndef GL_POLYGON_OFFSET_UNITS -#define GL_POLYGON_OFFSET_UNITS 0x2A00 -#endif -#ifndef GL_RED_BITS -#define GL_RED_BITS 0x0D52 -#endif -#ifndef GL_RENDERBUFFER -#define GL_RENDERBUFFER 0x8D41 -#endif -#ifndef GL_RENDERBUFFER_ALPHA_SIZE -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#endif -#ifndef GL_RENDERBUFFER_BINDING -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#endif -#ifndef GL_RENDERBUFFER_BLUE_SIZE -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#endif -#ifndef GL_RENDERBUFFER_DEPTH_SIZE -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#endif -#ifndef GL_RENDERBUFFER_GREEN_SIZE -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#endif -#ifndef GL_RENDERBUFFER_HEIGHT -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#endif -#ifndef GL_RENDERBUFFER_INTERNAL_FORMAT -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#endif -#ifndef GL_RENDERBUFFER_RED_SIZE -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#endif -#ifndef GL_RENDERBUFFER_STENCIL_SIZE -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#endif -#ifndef GL_RENDERBUFFER_WIDTH -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#endif -#ifndef GL_RENDERER -#define GL_RENDERER 0x1F01 -#endif -#ifndef GL_REPEAT -#define GL_REPEAT 0x2901 -#endif -#ifndef GL_REPLACE -#define GL_REPLACE 0x1E01 -#endif -#ifndef GL_RGB -#define GL_RGB 0x1907 -#endif -#ifndef GL_RGB565 -#define GL_RGB565 0x8D62 -#endif -#ifndef GL_RGB5_A1 -#define GL_RGB5_A1 0x8057 -#endif -#ifndef GL_RGBA -#define GL_RGBA 0x1908 -#endif -#ifndef GL_RGBA4 -#define GL_RGBA4 0x8056 -#endif -#ifndef GL_BGRA -#define GL_BGRA 0x80E1 -#endif -#ifndef GL_SAMPLE_ALPHA_TO_COVERAGE -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#endif -#ifndef GL_SAMPLE_BUFFERS -#define GL_SAMPLE_BUFFERS 0x80A8 -#endif -#ifndef GL_SAMPLE_COVERAGE -#define GL_SAMPLE_COVERAGE 0x80A0 -#endif -#ifndef GL_SAMPLE_COVERAGE_INVERT -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#endif -#ifndef GL_SAMPLE_COVERAGE_VALUE -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#endif -#ifndef GL_SAMPLER_2D -#define GL_SAMPLER_2D 0x8B5E -#endif -#ifndef GL_SAMPLER_CUBE -#define GL_SAMPLER_CUBE 0x8B60 -#endif -#ifndef GL_SAMPLES -#define GL_SAMPLES 0x80A9 -#endif -#ifndef GL_SCISSOR_BOX -#define GL_SCISSOR_BOX 0x0C10 -#endif -#ifndef GL_SCISSOR_TEST -#define GL_SCISSOR_TEST 0x0C11 -#endif -#ifndef GL_SHADER_BINARY_FORMATS -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#endif -#ifndef GL_SHADER_COMPILER -#define GL_SHADER_COMPILER 0x8DFA -#endif -#ifndef GL_SHADER_SOURCE_LENGTH -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#endif -#ifndef GL_SHADER_TYPE -#define GL_SHADER_TYPE 0x8B4F -#endif -#ifndef GL_SHADING_LANGUAGE_VERSION -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#endif -#ifndef GL_SHORT -#define GL_SHORT 0x1402 -#endif -#ifndef GL_SRC_ALPHA -#define GL_SRC_ALPHA 0x0302 -#endif -#ifndef GL_SRC_ALPHA_SATURATE -#define GL_SRC_ALPHA_SATURATE 0x0308 -#endif -#ifndef GL_SRC_COLOR -#define GL_SRC_COLOR 0x0300 -#endif -#ifndef GL_STATIC_DRAW -#define GL_STATIC_DRAW 0x88E4 -#endif -#ifndef GL_STENCIL_ATTACHMENT -#define GL_STENCIL_ATTACHMENT 0x8D20 -#endif -#ifndef GL_STENCIL_BACK_FAIL -#define GL_STENCIL_BACK_FAIL 0x8801 -#endif -#ifndef GL_STENCIL_BACK_FUNC -#define GL_STENCIL_BACK_FUNC 0x8800 -#endif -#ifndef GL_STENCIL_BACK_PASS_DEPTH_FAIL -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#endif -#ifndef GL_STENCIL_BACK_PASS_DEPTH_PASS -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#endif -#ifndef GL_STENCIL_BACK_REF -#define GL_STENCIL_BACK_REF 0x8CA3 -#endif -#ifndef GL_STENCIL_BACK_VALUE_MASK -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#endif -#ifndef GL_STENCIL_BACK_WRITEMASK -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#endif -#ifndef GL_STENCIL_BITS -#define GL_STENCIL_BITS 0x0D57 -#endif -#ifndef GL_STENCIL_BUFFER_BIT -#define GL_STENCIL_BUFFER_BIT 0x00000400 -#endif -#ifndef GL_STENCIL_CLEAR_VALUE -#define GL_STENCIL_CLEAR_VALUE 0x0B91 -#endif -#ifndef GL_STENCIL_FAIL -#define GL_STENCIL_FAIL 0x0B94 -#endif -#ifndef GL_STENCIL_FUNC -#define GL_STENCIL_FUNC 0x0B92 -#endif -#ifndef GL_STENCIL_INDEX -#define GL_STENCIL_INDEX 0x1901 -#endif -#ifndef GL_STENCIL_INDEX8 -#define GL_STENCIL_INDEX8 0x8D48 -#endif -#ifndef GL_STENCIL_PASS_DEPTH_FAIL -#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 -#endif -#ifndef GL_STENCIL_PASS_DEPTH_PASS -#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 -#endif -#ifndef GL_STENCIL_REF -#define GL_STENCIL_REF 0x0B97 -#endif -#ifndef GL_STENCIL_TEST -#define GL_STENCIL_TEST 0x0B90 -#endif -#ifndef GL_STENCIL_VALUE_MASK -#define GL_STENCIL_VALUE_MASK 0x0B93 -#endif -#ifndef GL_STENCIL_WRITEMASK -#define GL_STENCIL_WRITEMASK 0x0B98 -#endif -#ifndef GL_STREAM_DRAW -#define GL_STREAM_DRAW 0x88E0 -#endif -#ifndef GL_SUBPIXEL_BITS -#define GL_SUBPIXEL_BITS 0x0D50 -#endif -#ifndef GL_TEXTURE0 -#define GL_TEXTURE0 0x84C0 -#endif -#ifndef GL_TEXTURE -#define GL_TEXTURE 0x1702 -#endif -#ifndef GL_TEXTURE10 -#define GL_TEXTURE10 0x84CA -#endif -#ifndef GL_TEXTURE1 -#define GL_TEXTURE1 0x84C1 -#endif -#ifndef GL_TEXTURE11 -#define GL_TEXTURE11 0x84CB -#endif -#ifndef GL_TEXTURE12 -#define GL_TEXTURE12 0x84CC -#endif -#ifndef GL_TEXTURE13 -#define GL_TEXTURE13 0x84CD -#endif -#ifndef GL_TEXTURE14 -#define GL_TEXTURE14 0x84CE -#endif -#ifndef GL_TEXTURE15 -#define GL_TEXTURE15 0x84CF -#endif -#ifndef GL_TEXTURE16 -#define GL_TEXTURE16 0x84D0 -#endif -#ifndef GL_TEXTURE17 -#define GL_TEXTURE17 0x84D1 -#endif -#ifndef GL_TEXTURE18 -#define GL_TEXTURE18 0x84D2 -#endif -#ifndef GL_TEXTURE19 -#define GL_TEXTURE19 0x84D3 -#endif -#ifndef GL_TEXTURE20 -#define GL_TEXTURE20 0x84D4 -#endif -#ifndef GL_TEXTURE2 -#define GL_TEXTURE2 0x84C2 -#endif -#ifndef GL_TEXTURE21 -#define GL_TEXTURE21 0x84D5 -#endif -#ifndef GL_TEXTURE22 -#define GL_TEXTURE22 0x84D6 -#endif -#ifndef GL_TEXTURE23 -#define GL_TEXTURE23 0x84D7 -#endif -#ifndef GL_TEXTURE24 -#define GL_TEXTURE24 0x84D8 -#endif -#ifndef GL_TEXTURE25 -#define GL_TEXTURE25 0x84D9 -#endif -#ifndef GL_TEXTURE26 -#define GL_TEXTURE26 0x84DA -#endif -#ifndef GL_TEXTURE27 -#define GL_TEXTURE27 0x84DB -#endif -#ifndef GL_TEXTURE28 -#define GL_TEXTURE28 0x84DC -#endif -#ifndef GL_TEXTURE29 -#define GL_TEXTURE29 0x84DD -#endif -#ifndef GL_TEXTURE_2D -#define GL_TEXTURE_2D 0x0DE1 -#endif -#ifndef GL_TEXTURE30 -#define GL_TEXTURE30 0x84DE -#endif -#ifndef GL_TEXTURE3 -#define GL_TEXTURE3 0x84C3 -#endif -#ifndef GL_TEXTURE31 -#define GL_TEXTURE31 0x84DF -#endif -#ifndef GL_TEXTURE4 -#define GL_TEXTURE4 0x84C4 -#endif -#ifndef GL_TEXTURE5 -#define GL_TEXTURE5 0x84C5 -#endif -#ifndef GL_TEXTURE6 -#define GL_TEXTURE6 0x84C6 -#endif -#ifndef GL_TEXTURE7 -#define GL_TEXTURE7 0x84C7 -#endif -#ifndef GL_TEXTURE8 -#define GL_TEXTURE8 0x84C8 -#endif -#ifndef GL_TEXTURE9 -#define GL_TEXTURE9 0x84C9 -#endif -#ifndef GL_TEXTURE_BINDING_2D -#define GL_TEXTURE_BINDING_2D 0x8069 -#endif -#ifndef GL_TEXTURE_BINDING_CUBE_MAP -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#endif -#ifndef GL_TEXTURE_CUBE_MAP -#define GL_TEXTURE_CUBE_MAP 0x8513 -#endif -#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_X -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#endif -#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_Y -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#endif -#ifndef GL_TEXTURE_CUBE_MAP_NEGATIVE_Z -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#endif -#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_X -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#endif -#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_Y -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#endif -#ifndef GL_TEXTURE_CUBE_MAP_POSITIVE_Z -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#endif -#ifndef GL_TEXTURE_MAG_FILTER -#define GL_TEXTURE_MAG_FILTER 0x2800 -#endif -#ifndef GL_TEXTURE_MIN_FILTER -#define GL_TEXTURE_MIN_FILTER 0x2801 -#endif -#ifndef GL_TEXTURE_WRAP_S -#define GL_TEXTURE_WRAP_S 0x2802 -#endif -#ifndef GL_TEXTURE_WRAP_T -#define GL_TEXTURE_WRAP_T 0x2803 -#endif -#ifndef GL_TRIANGLE_FAN -#define GL_TRIANGLE_FAN 0x0006 -#endif -#ifndef GL_TRIANGLES -#define GL_TRIANGLES 0x0004 -#endif -#ifndef GL_TRIANGLE_STRIP -#define GL_TRIANGLE_STRIP 0x0005 -#endif -#ifndef GL_TRUE -#define GL_TRUE 1 -#endif -#ifndef GL_UNPACK_ALIGNMENT -#define GL_UNPACK_ALIGNMENT 0x0CF5 -#endif -#ifndef GL_UNSIGNED_BYTE -#define GL_UNSIGNED_BYTE 0x1401 -#endif -#ifndef GL_UNSIGNED_INT -#define GL_UNSIGNED_INT 0x1405 -#endif -#ifndef GL_UNSIGNED_SHORT -#define GL_UNSIGNED_SHORT 0x1403 -#endif -#ifndef GL_UNSIGNED_SHORT_4_4_4_4 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#endif -#ifndef GL_UNSIGNED_SHORT_5_5_5_1 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#endif -#ifndef GL_UNSIGNED_SHORT_5_6_5 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#endif -#ifndef GL_VALIDATE_STATUS -#define GL_VALIDATE_STATUS 0x8B83 -#endif -#ifndef GL_VENDOR -#define GL_VENDOR 0x1F00 -#endif -#ifndef GL_VERSION -#define GL_VERSION 0x1F02 -#endif -#ifndef GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#endif -#ifndef GL_VERTEX_ATTRIB_ARRAY_ENABLED -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#endif -#ifndef GL_VERTEX_ATTRIB_ARRAY_NORMALIZED -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#endif -#ifndef GL_VERTEX_ATTRIB_ARRAY_POINTER -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#endif -#ifndef GL_VERTEX_ATTRIB_ARRAY_SIZE -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#endif -#ifndef GL_VERTEX_ATTRIB_ARRAY_STRIDE -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#endif -#ifndef GL_VERTEX_ATTRIB_ARRAY_TYPE -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#endif -#ifndef GL_VERTEX_SHADER -#define GL_VERTEX_SHADER 0x8B31 -#endif -#ifndef GL_VIEWPORT -#define GL_VIEWPORT 0x0BA2 -#endif -#ifndef GL_ZERO -#define GL_ZERO 0 -#endif - -QT_END_NAMESPACE - -#endif diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp deleted file mode 100644 index c5151f66bb..0000000000 --- a/src/opengl/qglpaintdevice.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/qglpaintdevice_p.h> -#include <private/qgl_p.h> -#include <private/qglpixelbuffer_p.h> -#include <private/qglframebufferobject_p.h> -#include <qopenglfunctions.h> -#include <qwindow.h> - -QT_BEGIN_NAMESPACE - -QGLPaintDevice::QGLPaintDevice() - : m_thisFBO(0) -{ -} - -QGLPaintDevice::~QGLPaintDevice() -{ -} - -int QGLPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric) const -{ - switch(metric) { - case PdmWidth: - return size().width(); - case PdmHeight: - return size().height(); - case PdmDepth: { - const QGLFormat f = format(); - return f.redBufferSize() + f.greenBufferSize() + f.blueBufferSize() + f.alphaBufferSize(); - } - case PdmDevicePixelRatio: - return 1; - case PdmDevicePixelRatioScaled: - return 1 * QPaintDevice::devicePixelRatioFScale(); - default: - qWarning("QGLPaintDevice::metric() - metric %d not known", metric); - return 0; - } -} - -void QGLPaintDevice::beginPaint() -{ - // Make sure our context is the current one: - QGLContext *ctx = context(); - ctx->makeCurrent(); - - ctx->d_func()->refreshCurrentFbo(); - - // Record the currently bound FBO so we can restore it again - // in endPaint() and bind this device's FBO - // - // Note: m_thisFBO could be zero if the paint device is not - // backed by an FBO (e.g. window back buffer). But there could - // be a previous FBO bound to the context which we need to - // explicitly unbind. Otherwise the painting will go into - // the previous FBO instead of to the window. - m_previousFBO = ctx->d_func()->current_fbo; - - if (m_previousFBO != m_thisFBO) { - ctx->d_func()->setCurrentFbo(m_thisFBO); - ctx->contextHandle()->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_thisFBO); - } - - // Set the default fbo for the context to m_thisFBO so that - // if some raw GL code between beginNativePainting() and - // endNativePainting() calls QGLFramebufferObject::release(), - // painting will revert to the window surface's fbo. - ctx->d_ptr->default_fbo = m_thisFBO; -} - -void QGLPaintDevice::ensureActiveTarget() -{ - QGLContext* ctx = context(); - if (ctx != QGLContext::currentContext()) - ctx->makeCurrent(); - - ctx->d_func()->refreshCurrentFbo(); - - if (ctx->d_ptr->current_fbo != m_thisFBO) { - ctx->d_func()->setCurrentFbo(m_thisFBO); - ctx->contextHandle()->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_thisFBO); - } - - ctx->d_ptr->default_fbo = m_thisFBO; -} - -void QGLPaintDevice::endPaint() -{ - // Make sure the FBO bound at beginPaint is re-bound again here: - QGLContext *ctx = context(); - ctx->makeCurrent(); - - ctx->d_func()->refreshCurrentFbo(); - - if (m_previousFBO != ctx->d_func()->current_fbo) { - ctx->d_func()->setCurrentFbo(m_previousFBO); - ctx->contextHandle()->functions()->glBindFramebuffer(GL_FRAMEBUFFER, m_previousFBO); - } - - ctx->d_ptr->default_fbo = 0; -} - -QGLFormat QGLPaintDevice::format() const -{ - return context()->format(); -} - -bool QGLPaintDevice::alphaRequested() const -{ - return context()->d_func()->reqFormat.alpha(); -} - -bool QGLPaintDevice::isFlipped() const -{ - return false; -} - -////////////////// QGLWidgetGLPaintDevice ////////////////// - -QGLWidgetGLPaintDevice::QGLWidgetGLPaintDevice() -{ -} - -QPaintEngine* QGLWidgetGLPaintDevice::paintEngine() const -{ - return glWidget->paintEngine(); -} - -void QGLWidgetGLPaintDevice::setWidget(QGLWidget* w) -{ - glWidget = w; -} - -void QGLWidgetGLPaintDevice::beginPaint() -{ - QGLPaintDevice::beginPaint(); - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - if (!glWidget->d_func()->disable_clear_on_painter_begin && glWidget->autoFillBackground()) { - if (glWidget->testAttribute(Qt::WA_TranslucentBackground)) - funcs->glClearColor(0.0, 0.0, 0.0, 0.0); - else { - const QColor &c = glWidget->palette().brush(glWidget->backgroundRole()).color(); - float alpha = c.alphaF(); - funcs->glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); - } - if (context()->d_func()->workaround_needsFullClearOnEveryFrame) - funcs->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - else - funcs->glClear(GL_COLOR_BUFFER_BIT); - } -} - -void QGLWidgetGLPaintDevice::endPaint() -{ - if (glWidget->autoBufferSwap()) - glWidget->swapBuffers(); - QGLPaintDevice::endPaint(); -} - - -QSize QGLWidgetGLPaintDevice::size() const -{ - return glWidget->size() * (glWidget->windowHandle() ? - glWidget->windowHandle()->devicePixelRatio() : qApp->devicePixelRatio()); -} - -QGLContext* QGLWidgetGLPaintDevice::context() const -{ - return const_cast<QGLContext*>(glWidget->context()); -} - -// returns the QGLPaintDevice for the given QPaintDevice -QGLPaintDevice* QGLPaintDevice::getDevice(QPaintDevice* pd) -{ - QGLPaintDevice* glpd = 0; - - switch(pd->devType()) { - case QInternal::Widget: - // Should not be called on a non-gl widget: - Q_ASSERT(qobject_cast<QGLWidget*>(static_cast<QWidget*>(pd))); - glpd = &(static_cast<QGLWidget*>(pd)->d_func()->glDevice); - break; - case QInternal::Pbuffer: - glpd = &(static_cast<QGLPixelBuffer*>(pd)->d_func()->glDevice); - break; - case QInternal::FramebufferObject: - glpd = &(static_cast<QGLFramebufferObject*>(pd)->d_func()->glDevice); - break; - case QInternal::Pixmap: { - qWarning("Pixmap type not supported for GL rendering"); - break; - } - default: - qWarning("QGLPaintDevice::getDevice() - Unknown device type %d", pd->devType()); - break; - } - - return glpd; -} - -QT_END_NAMESPACE diff --git a/src/opengl/qglpaintdevice_p.h b/src/opengl/qglpaintdevice_p.h deleted file mode 100644 index bfecdabd53..0000000000 --- a/src/opengl/qglpaintdevice_p.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLPAINTDEVICE_P_H -#define QGLPAINTDEVICE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the Qt OpenGL module. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - - -#include <qpaintdevice.h> -#include <QtOpenGL/qgl.h> - - -QT_BEGIN_NAMESPACE - -class Q_OPENGL_EXPORT QGLPaintDevice : public QPaintDevice -{ -public: - QGLPaintDevice(); - virtual ~QGLPaintDevice(); - - int devType() const override {return QInternal::OpenGL;} - - virtual void beginPaint(); - virtual void ensureActiveTarget(); - virtual void endPaint(); - - virtual QGLContext* context() const = 0; - virtual QGLFormat format() const; - virtual QSize size() const = 0; - virtual bool alphaRequested() const; - virtual bool isFlipped() const; - - // returns the QGLPaintDevice for the given QPaintDevice - static QGLPaintDevice* getDevice(QPaintDevice*); - -protected: - int metric(QPaintDevice::PaintDeviceMetric metric) const override; - GLuint m_previousFBO; - GLuint m_thisFBO; -}; - - -// Wraps a QGLWidget -class QGLWidget; -class Q_OPENGL_EXPORT QGLWidgetGLPaintDevice : public QGLPaintDevice -{ -public: - QGLWidgetGLPaintDevice(); - - virtual QPaintEngine* paintEngine() const override; - - // QGLWidgets need to do swapBufers in endPaint: - virtual void beginPaint() override; - virtual void endPaint() override; - virtual QSize size() const override; - virtual QGLContext* context() const override; - - void setWidget(QGLWidget*); - -private: - friend class QGLWidget; - QGLWidget *glWidget; -}; - -QT_END_NAMESPACE - -#endif // QGLPAINTDEVICE_P_H diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp deleted file mode 100644 index e2f434ac3c..0000000000 --- a/src/opengl/qglpixelbuffer.cpp +++ /dev/null @@ -1,654 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \class QGLPixelBuffer - \inmodule QtOpenGL - \brief The QGLPixelBuffer class encapsulates an OpenGL pbuffer. - \since 4.1 - \obsolete - - \ingroup painting-3D - - Rendering into a pbuffer is normally done using full hardware - acceleration. This can be significantly faster than rendering - into a QPixmap. - - There are three approaches to using this class: - - \list 1 - \li \b{We can draw into the pbuffer and convert it to a QImage - using toImage().} This is normally much faster than calling - QGLWidget::renderPixmap(). - - \li \b{We can draw into the pbuffer and copy the contents into - an OpenGL texture using updateDynamicTexture().} This allows - us to create dynamic textures and works on all systems - with pbuffer support. - - \li \b{On systems that support it, we can bind the pbuffer to - an OpenGL texture.} The texture is then updated automatically - when the pbuffer contents change, eliminating the need for - additional copy operations. This is supported only on Windows - and \macos systems that provide the \c render_texture - extension. Note that under Windows, a multi-sampled pbuffer - can't be used in conjunction with the \c render_texture - extension. If a multi-sampled pbuffer is requested under - Windows, the \c render_texture extension is turned off for that - pbuffer. - - - \endlist - - \note This class has been deprecated, use QOpenGLFramebufferObject - for offscreen rendering. - - \section1 Threading - - As of Qt 4.8, it's possible to render into a QGLPixelBuffer using - a QPainter in a separate thread. Note that OpenGL 2.0 or OpenGL ES - 2.0 is required for this to work. - - Pbuffers are provided by the OpenGL \c pbuffer extension; call - hasOpenGLPbuffer() to find out if the system provides pbuffers. -*/ - -#include <private/qopenglextensions_p.h> - -#include <QtCore/qglobal.h> -#include <QtGui/qopenglframebufferobject.h> - -#include "gl2paintengineex/qpaintengineex_opengl2_p.h" - -#include <qglframebufferobject.h> -#include <qglpixelbuffer.h> -#include <private/qglpixelbuffer_p.h> -#include <private/qfont_p.h> -#include <qimage.h> - -QT_BEGIN_NAMESPACE - -extern QImage qt_gl_read_frame_buffer(const QSize&, bool, bool); - - -QGLContext* QGLPBufferGLPaintDevice::context() const -{ - return pbuf->d_func()->qctx; -} - -void QGLPBufferGLPaintDevice::beginPaint() -{ - pbuf->makeCurrent(); - QGLPaintDevice::beginPaint(); -} - -void QGLPBufferGLPaintDevice::endPaint() -{ - QOpenGLContext::currentContext()->functions()->glFlush(); - QGLPaintDevice::endPaint(); -} - -void QGLPBufferGLPaintDevice::setFbo(GLuint fbo) -{ - m_thisFBO = fbo; -} - -void QGLPBufferGLPaintDevice::setPBuffer(QGLPixelBuffer* pb) -{ - pbuf = pb; -} - -void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget) -{ - Q_Q(QGLPixelBuffer); - if(init(size, format, shareWidget)) { - req_size = size; - req_format = format; - req_shareWidget = shareWidget; - invalid = false; - glDevice.setPBuffer(q); - } -} - -/*! - Constructs an OpenGL pbuffer of the given \a size. If no \a - format is specified, the \l{QGLFormat::defaultFormat()}{default - format} is used. If the \a shareWidget parameter points to a - valid QGLWidget, the pbuffer will share its context with \a - shareWidget. - - If you intend to bind this pbuffer as a dynamic texture, the width - and height components of \c size must be powers of two (e.g., 512 - x 128). - - \sa size(), format() -*/ -QGLPixelBuffer::QGLPixelBuffer(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget) - : d_ptr(new QGLPixelBufferPrivate(this)) -{ - Q_D(QGLPixelBuffer); - d->common_init(size, format, shareWidget); -} - - -/*! \overload - - Constructs an OpenGL pbuffer with the \a width and \a height. If - no \a format is specified, the - \l{QGLFormat::defaultFormat()}{default format} is used. If the \a - shareWidget parameter points to a valid QGLWidget, the pbuffer - will share its context with \a shareWidget. - - If you intend to bind this pbuffer as a dynamic texture, the width - and height components of \c size must be powers of two (e.g., 512 - x 128). - - \sa size(), format() -*/ -QGLPixelBuffer::QGLPixelBuffer(int width, int height, const QGLFormat &format, QGLWidget *shareWidget) - : d_ptr(new QGLPixelBufferPrivate(this)) -{ - Q_D(QGLPixelBuffer); - d->common_init(QSize(width, height), format, shareWidget); -} - - -/*! \fn QGLPixelBuffer::~QGLPixelBuffer() - - Destroys the pbuffer and frees any allocated resources. -*/ -QGLPixelBuffer::~QGLPixelBuffer() -{ - Q_D(QGLPixelBuffer); - - // defined in qpaintengine_opengl.cpp - QGLContext *current = const_cast<QGLContext *>(QGLContext::currentContext()); - if (current != d->qctx) - makeCurrent(); - d->cleanup(); - if (current && current != d->qctx) - current->makeCurrent(); -} - -/*! \fn bool QGLPixelBuffer::makeCurrent() - - Makes this pbuffer the current OpenGL rendering context. Returns - true on success; otherwise returns \c false. - - \sa QGLContext::makeCurrent(), doneCurrent() -*/ - -bool QGLPixelBuffer::makeCurrent() -{ - Q_D(QGLPixelBuffer); - if (d->invalid) - return false; - d->qctx->makeCurrent(); - if (!d->fbo) { - QOpenGLFramebufferObjectFormat format; - if (d->req_format.stencil()) - format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - else if (d->req_format.depth()) - format.setAttachment(QOpenGLFramebufferObject::Depth); - if (d->req_format.sampleBuffers()) - format.setSamples(d->req_format.samples()); - d->fbo = new QOpenGLFramebufferObject(d->req_size, format); - d->fbo->bind(); - d->glDevice.setFbo(d->fbo->handle()); - QOpenGLContext::currentContext()->functions()->glViewport(0, 0, d->req_size.width(), d->req_size.height()); - } - return true; -} - -/*! \fn bool QGLPixelBuffer::doneCurrent() - - Makes no context the current OpenGL context. Returns \c true on - success; otherwise returns \c false. -*/ - -bool QGLPixelBuffer::doneCurrent() -{ - Q_D(QGLPixelBuffer); - if (d->invalid) - return false; - d->qctx->doneCurrent(); - return true; -} - -/*! - Returns the context of this pixelbuffer. -*/ -QGLContext *QGLPixelBuffer::context() const -{ - Q_D(const QGLPixelBuffer); - return d->qctx; -} - -/*! - \fn GLuint QGLPixelBuffer::generateDynamicTexture() const - - Generates and binds a 2D GL texture that is the same size as the - pbuffer, and returns the texture's ID. This can be used in - conjunction with bindToDynamicTexture() and - updateDynamicTexture(). - - \sa size() -*/ - -/*! \fn bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id) - - Binds the texture specified by \a texture_id to this pbuffer. - Returns \c true on success; otherwise returns \c false. - - The texture must be of the same size and format as the pbuffer. - - To unbind the texture, call releaseFromDynamicTexture(). While - the texture is bound, it is updated automatically when the - pbuffer contents change, eliminating the need for additional copy - operations. - - Example: - - \snippet code/src_opengl_qglpixelbuffer.cpp 0 - - \warning This function uses the \c {render_texture} extension, - which is currently not supported under X11. An alternative that - works on all systems (including X11) is to manually copy the - pbuffer contents to a texture using updateDynamicTexture(). - - \warning For the bindToDynamicTexture() call to succeed on the - \macos, the pbuffer needs a shared context, i.e. the - QGLPixelBuffer must be created with a share widget. - - \sa generateDynamicTexture(), releaseFromDynamicTexture() -*/ - -/*! \fn void QGLPixelBuffer::releaseFromDynamicTexture() - - Releases the pbuffer from any previously bound texture. - - \sa bindToDynamicTexture() -*/ - -/*! \fn bool QGLPixelBuffer::hasOpenGLPbuffers() - - Returns \c true if the OpenGL \c pbuffer extension is present on - this system; otherwise returns \c false. -*/ - -/*! - Copies the pbuffer contents into the texture specified with \a - texture_id. - - The texture must be of the same size and format as the pbuffer. - - Example: - - \snippet code/src_opengl_qglpixelbuffer.cpp 1 - - An alternative on Windows and \macos systems that support the - \c render_texture extension is to use bindToDynamicTexture() to - get dynamic updates of the texture. - - \sa generateDynamicTexture(), bindToDynamicTexture() -*/ -void QGLPixelBuffer::updateDynamicTexture(GLuint texture_id) const -{ - Q_D(const QGLPixelBuffer); - if (d->invalid || !d->fbo) - return; - - const QGLContext *ctx = QGLContext::currentContext(); - if (!ctx) - return; - -#undef glBindFramebuffer - -#ifndef GL_READ_FRAMEBUFFER -#define GL_READ_FRAMEBUFFER 0x8CA8 -#endif - -#ifndef GL_DRAW_FRAMEBUFFER -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#endif - - QOpenGLExtensions extensions(ctx->contextHandle()); - - ctx->d_ptr->refreshCurrentFbo(); - - if (d->blit_fbo) { - QOpenGLFramebufferObject::blitFramebuffer(d->blit_fbo, d->fbo); - extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, d->blit_fbo->handle()); - } - - extensions.glBindTexture(GL_TEXTURE_2D, texture_id); -#ifndef QT_OPENGL_ES - GLenum format = ctx->contextHandle()->isOpenGLES() ? GL_RGBA : GL_RGBA8; - extensions.glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, d->req_size.width(), d->req_size.height(), 0); -#else - extensions.glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, d->req_size.width(), d->req_size.height(), 0); -#endif - - if (d->blit_fbo) - extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, ctx->d_func()->current_fbo); -} - -/*! - Returns the size of the pbuffer. -*/ -QSize QGLPixelBuffer::size() const -{ - Q_D(const QGLPixelBuffer); - return d->req_size; -} - -/*! - Returns the contents of the pbuffer as a QImage. -*/ -QImage QGLPixelBuffer::toImage() const -{ - Q_D(const QGLPixelBuffer); - if (d->invalid) - return QImage(); - - const_cast<QGLPixelBuffer *>(this)->makeCurrent(); - if (d->fbo) - d->fbo->bind(); - return qt_gl_read_frame_buffer(d->req_size, d->format.alpha(), true); -} - -/*! - Returns the native pbuffer handle. -*/ -Qt::HANDLE QGLPixelBuffer::handle() const -{ - Q_D(const QGLPixelBuffer); - if (d->invalid) - return 0; - return (Qt::HANDLE) d->pbuf; -} - -/*! - Returns \c true if this pbuffer is valid; otherwise returns \c false. -*/ -bool QGLPixelBuffer::isValid() const -{ - Q_D(const QGLPixelBuffer); - return !d->invalid; -} - -Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine) - -/*! \reimp */ -QPaintEngine *QGLPixelBuffer::paintEngine() const -{ - return qt_buffer_2_engine()->engine(); -} - -/*! \reimp */ -int QGLPixelBuffer::metric(PaintDeviceMetric metric) const -{ - Q_D(const QGLPixelBuffer); - - float dpmx = qt_defaultDpiX()*100./2.54; - float dpmy = qt_defaultDpiY()*100./2.54; - int w = d->req_size.width(); - int h = d->req_size.height(); - switch (metric) { - case PdmWidth: - return w; - - case PdmHeight: - return h; - - case PdmWidthMM: - return qRound(w * 1000 / dpmx); - - case PdmHeightMM: - return qRound(h * 1000 / dpmy); - - case PdmNumColors: - return 0; - - case PdmDepth: - return 32;//d->depth; - - case PdmDpiX: - return qRound(dpmx * 0.0254); - - case PdmDpiY: - return qRound(dpmy * 0.0254); - - case PdmPhysicalDpiX: - return qRound(dpmx * 0.0254); - - case PdmPhysicalDpiY: - return qRound(dpmy * 0.0254); - - case QPaintDevice::PdmDevicePixelRatio: - return 1; - - case QPaintDevice::PdmDevicePixelRatioScaled: - return QPaintDevice::devicePixelRatioFScale(); - - default: - qWarning("QGLPixelBuffer::metric(), Unhandled metric type: %d\n", metric); - break; - } - return 0; -} - -/*! - Generates and binds a 2D GL texture to the current context, based - on \a image. The generated texture id is returned and can be used - in later glBindTexture() calls. - - The \a target parameter specifies the texture target. - - Equivalent to calling QGLContext::bindTexture(). - - \sa deleteTexture() -*/ -GLuint QGLPixelBuffer::bindTexture(const QImage &image, GLenum target) -{ - Q_D(QGLPixelBuffer); -#ifndef QT_OPENGL_ES - GLenum format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; - return d->qctx->bindTexture(image, target, GLint(format)); -#else - return d->qctx->bindTexture(image, target, GL_RGBA); -#endif -} - -/*! \overload - - Generates and binds a 2D GL texture based on \a pixmap. - - Equivalent to calling QGLContext::bindTexture(). - - \sa deleteTexture() -*/ -GLuint QGLPixelBuffer::bindTexture(const QPixmap &pixmap, GLenum target) -{ - Q_D(QGLPixelBuffer); -#ifndef QT_OPENGL_ES - GLenum format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8; - return d->qctx->bindTexture(pixmap, target, GLint(format)); -#else - return d->qctx->bindTexture(pixmap, target, GL_RGBA); -#endif -} - -/*! \overload - - Reads the DirectDrawSurface (DDS) compressed file \a fileName and - generates a 2D GL texture from it. - - Equivalent to calling QGLContext::bindTexture(). - - \sa deleteTexture() -*/ -GLuint QGLPixelBuffer::bindTexture(const QString &fileName) -{ - Q_D(QGLPixelBuffer); - return d->qctx->bindTexture(fileName); -} - -/*! - Removes the texture identified by \a texture_id from the texture cache. - - Equivalent to calling QGLContext::deleteTexture(). - */ -void QGLPixelBuffer::deleteTexture(GLuint texture_id) -{ - Q_D(QGLPixelBuffer); - d->qctx->deleteTexture(texture_id); -} - -/*! - \since 4.4 - - Draws the given texture, \a textureId, to the given target rectangle, - \a target, in OpenGL model space. The \a textureTarget should be a 2D - texture target. - - Equivalent to the corresponding QGLContext::drawTexture(). -*/ -void QGLPixelBuffer::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget) -{ - Q_D(QGLPixelBuffer); - d->qctx->drawTexture(target, textureId, textureTarget); -} - -/*! - \since 4.4 - - Draws the given texture, \a textureId, at the given \a point in OpenGL model - space. The textureTarget parameter should be a 2D texture target. - - Equivalent to the corresponding QGLContext::drawTexture(). -*/ -void QGLPixelBuffer::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget) -{ - Q_D(QGLPixelBuffer); - d->qctx->drawTexture(point, textureId, textureTarget); -} - -/*! - Returns the format of the pbuffer. The format may be different - from the one that was requested. -*/ -QGLFormat QGLPixelBuffer::format() const -{ - Q_D(const QGLPixelBuffer); - return d->format; -} - -/*! \fn int QGLPixelBuffer::devType() const - \internal -*/ - -bool QGLPixelBufferPrivate::init(const QSize &, const QGLFormat &f, QGLWidget *shareWidget) -{ - widget = new QGLWidget(f, 0, shareWidget); - widget->resize(1, 1); - qctx = const_cast<QGLContext *>(widget->context()); - return widget->isValid(); -} - -bool QGLPixelBufferPrivate::cleanup() -{ - delete fbo; - fbo = 0; - delete blit_fbo; - blit_fbo = 0; - delete widget; - widget = 0; - return true; -} - -bool QGLPixelBuffer::bindToDynamicTexture(GLuint texture_id) -{ - Q_UNUSED(texture_id); - return false; -} - -void QGLPixelBuffer::releaseFromDynamicTexture() -{ -} - -GLuint QGLPixelBuffer::generateDynamicTexture() const -{ - Q_D(const QGLPixelBuffer); - if (!d->fbo) - return 0; - - if (d->fbo->format().samples() > 0 - && QOpenGLExtensions(QOpenGLContext::currentContext()) - .hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit)) - { - if (!d->blit_fbo) - const_cast<QOpenGLFramebufferObject *&>(d->blit_fbo) = new QOpenGLFramebufferObject(d->req_size); - } else { - return d->fbo->texture(); - } - - GLuint texture; - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - - funcs->glGenTextures(1, &texture); - funcs->glBindTexture(GL_TEXTURE_2D, texture); - - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, d->req_size.width(), d->req_size.height(), 0, - GL_RGBA, GL_UNSIGNED_BYTE, 0); - - return texture; -} - -bool QGLPixelBuffer::hasOpenGLPbuffers() -{ - return QGLFramebufferObject::hasOpenGLFramebufferObjects(); -} - -QT_END_NAMESPACE diff --git a/src/opengl/qglpixelbuffer.h b/src/opengl/qglpixelbuffer.h deleted file mode 100644 index f5d7929c35..0000000000 --- a/src/opengl/qglpixelbuffer.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLPIXELBUFFER_H -#define QGLPIXELBUFFER_H - -#include <QtOpenGL/qgl.h> -#include <QtGui/qpaintdevice.h> - -QT_BEGIN_NAMESPACE - - -class QGLPixelBufferPrivate; - -class Q_OPENGL_EXPORT QGLPixelBuffer : public QPaintDevice -{ - Q_DECLARE_PRIVATE(QGLPixelBuffer) -public: - QGLPixelBuffer(const QSize &size, const QGLFormat &format = QGLFormat::defaultFormat(), - QGLWidget *shareWidget = nullptr); - QGLPixelBuffer(int width, int height, const QGLFormat &format = QGLFormat::defaultFormat(), - QGLWidget *shareWidget = nullptr); - virtual ~QGLPixelBuffer(); - - bool isValid() const; - bool makeCurrent(); - bool doneCurrent(); - - QGLContext *context() const; - - GLuint generateDynamicTexture() const; - bool bindToDynamicTexture(GLuint texture); - void releaseFromDynamicTexture(); - void updateDynamicTexture(GLuint texture_id) const; - - GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D); - GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D); - GLuint bindTexture(const QString &fileName); - void deleteTexture(GLuint texture_id); - - void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); - void drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); - - QSize size() const; - Qt::HANDLE handle() const; - QImage toImage() const; - - QPaintEngine *paintEngine() const override; - QGLFormat format() const; - - static bool hasOpenGLPbuffers(); - -protected: - int metric(PaintDeviceMetric metric) const override; - int devType() const override { return QInternal::Pbuffer; } - -private: - Q_DISABLE_COPY(QGLPixelBuffer) - QScopedPointer<QGLPixelBufferPrivate> d_ptr; - friend class QGLDrawable; - friend class QGLPaintDevice; - friend class QGLPBufferGLPaintDevice; - friend class QGLContextPrivate; -}; - -QT_END_NAMESPACE - -#endif // QGLPIXELBUFFER_H diff --git a/src/opengl/qglpixelbuffer_p.h b/src/opengl/qglpixelbuffer_p.h deleted file mode 100644 index 2729ade2b6..0000000000 --- a/src/opengl/qglpixelbuffer_p.h +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLPIXELBUFFER_P_H -#define QGLPIXELBUFFER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "QtOpenGL/qglpixelbuffer.h" -#include <private/qgl_p.h> -#include <private/qglpaintdevice_p.h> - -QT_BEGIN_NAMESPACE - -class QEglContext; -class QOpenGLFramebufferObject; - -class QGLPBufferGLPaintDevice : public QGLPaintDevice -{ -public: - QPaintEngine* paintEngine() const override {return pbuf->paintEngine();} - QSize size() const override {return pbuf->size();} - QGLContext* context() const override; - void beginPaint() override; - void endPaint() override; - void setPBuffer(QGLPixelBuffer* pb); - void setFbo(GLuint fbo); -private: - QGLPixelBuffer* pbuf; -}; - -class QGLPixelBufferPrivate { - Q_DECLARE_PUBLIC(QGLPixelBuffer) -public: - QGLPixelBufferPrivate(QGLPixelBuffer *q) : q_ptr(q), invalid(true), qctx(nullptr), widget(nullptr), fbo(nullptr), blit_fbo(nullptr), pbuf(nullptr), ctx(nullptr) - { - } - bool init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget); - void common_init(const QSize &size, const QGLFormat &f, QGLWidget *shareWidget); - bool cleanup(); - - QGLPixelBuffer *q_ptr; - bool invalid; - QGLContext *qctx; - QGLPBufferGLPaintDevice glDevice; - QGLWidget *widget; - QOpenGLFramebufferObject *fbo; - QOpenGLFramebufferObject *blit_fbo; - QGLFormat format; - - QGLFormat req_format; - QPointer<QGLWidget> req_shareWidget; - QSize req_size; - - //stubs - void *pbuf; - void *ctx; -}; - -QT_END_NAMESPACE - -#endif // QGLPIXELBUFFER_P_H diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp deleted file mode 100644 index 35f60318be..0000000000 --- a/src/opengl/qglshaderprogram.cpp +++ /dev/null @@ -1,3237 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qglshaderprogram.h" -#include <private/qopenglextensions_p.h> -#include "qgl_p.h" -#include <QtCore/private/qobject_p.h> -#include <QtCore/qdebug.h> -#include <QtCore/qfile.h> -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qvector.h> -#include <QDebug> - -QT_BEGIN_NAMESPACE - -/*! - \class QGLShaderProgram - \inmodule QtOpenGL - \brief The QGLShaderProgram class allows OpenGL shader programs to be linked and used. - \since 4.6 - \obsolete - \ingroup painting-3D - - \section1 Introduction - - This class supports shader programs written in the OpenGL Shading - Language (GLSL) and in the OpenGL/ES Shading Language (GLSL/ES). - - QGLShader and QGLShaderProgram shelter the programmer from the details of - compiling and linking vertex and fragment shaders. - - The following example creates a vertex shader program using the - supplied source \c{code}. Once compiled and linked, the shader - program is activated in the current QGLContext by calling - QGLShaderProgram::bind(): - - \snippet code/src_opengl_qglshaderprogram.cpp 0 - - \section1 Writing Portable Shaders - - Shader programs can be difficult to reuse across OpenGL implementations - because of varying levels of support for standard vertex attributes and - uniform variables. In particular, GLSL/ES lacks all of the - standard variables that are present on desktop OpenGL systems: - \c{gl_Vertex}, \c{gl_Normal}, \c{gl_Color}, and so on. Desktop OpenGL - lacks the variable qualifiers \c{highp}, \c{mediump}, and \c{lowp}. - - The QGLShaderProgram class makes the process of writing portable shaders - easier by prefixing all shader programs with the following lines on - desktop OpenGL: - - \code - #define highp - #define mediump - #define lowp - \endcode - - This makes it possible to run most GLSL/ES shader programs - on desktop systems. The programmer should restrict themselves - to just features that are present in GLSL/ES, and avoid - standard variable names that only work on the desktop. - - \section1 Simple Shader Example - - \snippet code/src_opengl_qglshaderprogram.cpp 1 - - With the above shader program active, we can draw a green triangle - as follows: - - \snippet code/src_opengl_qglshaderprogram.cpp 2 - - \section1 Binary Shaders and Programs - - Binary shaders may be specified using \c{glShaderBinary()} on - the return value from QGLShader::shaderId(). The QGLShader instance - containing the binary can then be added to the shader program with - addShader() and linked in the usual fashion with link(). - - Binary programs may be specified using \c{glProgramBinaryOES()} - on the return value from programId(). Then the application should - call link(), which will notice that the program has already been - specified and linked, allowing other operations to be performed - on the shader program. - - \note This class has been deprecated in favor of QOpenGLShaderProgram. - - \sa QGLShader -*/ - -/*! - \class QGLShader - \inmodule QtOpenGL - \brief The QGLShader class allows OpenGL shaders to be compiled. - \since 4.6 - \obsolete - \ingroup painting-3D - - This class supports shaders written in the OpenGL Shading Language (GLSL) - and in the OpenGL/ES Shading Language (GLSL/ES). - - QGLShader and QGLShaderProgram shelter the programmer from the details of - compiling and linking vertex and fragment shaders. - - \note This class has been deprecated in favor of QOpenGLShader. - - \sa QGLShaderProgram -*/ - -/*! - \enum QGLShader::ShaderTypeBit - This enum specifies the type of QGLShader that is being created. - - \value Vertex Vertex shader written in the OpenGL Shading Language (GLSL). - \value Fragment Fragment shader written in the OpenGL Shading Language (GLSL). - \value Geometry Geometry shaders written in the OpenGL Shading - Language (GLSL), based on the GL_EXT_geometry_shader4 extension. -*/ - -#ifndef GL_FRAGMENT_SHADER -#define GL_FRAGMENT_SHADER 0x8B30 -#endif -#ifndef GL_VERTEX_SHADER -#define GL_VERTEX_SHADER 0x8B31 -#endif -#ifndef GL_COMPILE_STATUS -#define GL_COMPILE_STATUS 0x8B81 -#endif -#ifndef GL_LINK_STATUS -#define GL_LINK_STATUS 0x8B82 -#endif -#ifndef GL_INFO_LOG_LENGTH -#define GL_INFO_LOG_LENGTH 0x8B84 -#endif -#ifndef GL_ACTIVE_UNIFORMS -#define GL_ACTIVE_UNIFORMS 0x8B86 -#endif -#ifndef GL_ACTIVE_UNIFORM_MAX_LENGTH -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#endif -#ifndef GL_ACTIVE_ATTRIBUTES -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#endif -#ifndef GL_ACTIVE_ATTRIBUTE_MAX_LENGTH -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#endif -#ifndef GL_CURRENT_VERTEX_ATTRIB -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#endif -#ifndef GL_SHADER_SOURCE_LENGTH -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#endif -#ifndef GL_SHADER_BINARY_FORMATS -#define GL_SHADER_BINARY_FORMATS 0x8DF8 -#endif -#ifndef GL_NUM_SHADER_BINARY_FORMATS -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#endif - -class QGLShaderPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QGLShader) -public: - QGLShaderPrivate(const QGLContext *ctx, QGLShader::ShaderType type) - : shaderGuard(0) - , shaderType(type) - , compiled(false) - , glfuncs(new QOpenGLFunctions(ctx->contextHandle())) - { - } - ~QGLShaderPrivate(); - - QGLSharedResourceGuardBase *shaderGuard; - QGLShader::ShaderType shaderType; - bool compiled; - QString log; - - QOpenGLFunctions *glfuncs; - - bool create(); - bool compile(QGLShader *q); - void deleteShader(); -}; - -namespace { - void freeShaderFunc(QGLContext *ctx, GLuint id) - { - Q_ASSERT(ctx); - ctx->contextHandle()->functions()->glDeleteShader(id); - } -} - -#define ctx QGLContext::currentContext() - -QGLShaderPrivate::~QGLShaderPrivate() -{ - delete glfuncs; - if (shaderGuard) - shaderGuard->free(); -} - -bool QGLShaderPrivate::create() -{ - QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext()); - if (!context) - return false; - - if (glfuncs->hasOpenGLFeature(QOpenGLFunctions::Shaders)) { - GLuint shader; - if (shaderType == QGLShader::Vertex) - shader = glfuncs->glCreateShader(GL_VERTEX_SHADER); -#if !defined(QT_OPENGL_ES_2) - else if (shaderType == QGLShader::Geometry - && !context->contextHandle()->isOpenGLES()) - shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER_EXT); -#endif - else - shader = glfuncs->glCreateShader(GL_FRAGMENT_SHADER); - if (!shader) { - qWarning("Could not create shader of type %d.", int(shaderType)); - return false; - } - shaderGuard = createSharedResourceGuard(context, shader, freeShaderFunc); - return true; - } else { - return false; - } -} - -bool QGLShaderPrivate::compile(QGLShader *q) -{ - GLuint shader = shaderGuard ? shaderGuard->id() : 0; - if (!shader) - return false; - glfuncs->glCompileShader(shader); - GLint value = 0; - glfuncs->glGetShaderiv(shader, GL_COMPILE_STATUS, &value); - compiled = (value != 0); - value = 0; - glfuncs->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &value); - if (!compiled && value > 1) { - char *logbuf = new char [value]; - GLint len; - glfuncs->glGetShaderInfoLog(shader, value, &len, logbuf); - log = QString::fromLatin1(logbuf); - QString name = q->objectName(); - - const char *types[] = { - "Fragment", - "Vertex", - "Geometry", - "" - }; - - const char *type = types[3]; - if (shaderType == QGLShader::Fragment) - type = types[0]; - else if (shaderType == QGLShader::Vertex) - type = types[1]; - else if (shaderType == QGLShader::Geometry) - type = types[2]; - - if (name.isEmpty()) - qWarning("QGLShader::compile(%s): %s", type, qPrintable(log)); - else - qWarning("QGLShader::compile(%s)[%s]: %s", type, qPrintable(name), qPrintable(log)); - - delete [] logbuf; - } - return compiled; -} - -void QGLShaderPrivate::deleteShader() -{ - if (shaderGuard) { - shaderGuard->free(); - shaderGuard = 0; - } -} - -/*! - Constructs a new QGLShader object of the specified \a type - and attaches it to \a parent. If shader programs are not supported, - QGLShaderProgram::hasOpenGLShaderPrograms() will return false. - - This constructor is normally followed by a call to compileSourceCode() - or compileSourceFile(). - - The shader will be associated with the current QGLContext. - - \sa compileSourceCode(), compileSourceFile() -*/ -QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent) - : QObject(*new QGLShaderPrivate(QGLContext::currentContext(), type), parent) -{ - Q_D(QGLShader); - d->create(); -} - -/*! - Constructs a new QGLShader object of the specified \a type - and attaches it to \a parent. If shader programs are not supported, - then QGLShaderProgram::hasOpenGLShaderPrograms() will return false. - - This constructor is normally followed by a call to compileSourceCode() - or compileSourceFile(). - - The shader will be associated with \a context. - - \sa compileSourceCode(), compileSourceFile() -*/ -QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent) - : QObject(*new QGLShaderPrivate(context ? context : QGLContext::currentContext(), type), parent) -{ - Q_D(QGLShader); -#ifndef QT_NO_DEBUG - if (context && !QGLContext::areSharing(context, QGLContext::currentContext())) { - qWarning("QGLShader::QGLShader: \'context\' must be the current context or sharing with it."); - return; - } -#endif - d->create(); -} - -/*! - Deletes this shader. If the shader has been attached to a - QGLShaderProgram object, then the actual shader will stay around - until the QGLShaderProgram is destroyed. -*/ -QGLShader::~QGLShader() -{ -} - -/*! - Returns the type of this shader. -*/ -QGLShader::ShaderType QGLShader::shaderType() const -{ - Q_D(const QGLShader); - return d->shaderType; -} - -// The precision qualifiers are useful on OpenGL/ES systems, -// but usually not present on desktop systems. Define the -// keywords to empty strings on desktop systems. -#if !defined(QT_OPENGL_ES) || defined(QT_OPENGL_FORCE_SHADER_DEFINES) -#define QGL_DEFINE_QUALIFIERS 1 -static const char qualifierDefines[] = - "#define lowp\n" - "#define mediump\n" - "#define highp\n"; - -#else - -// The "highp" qualifier doesn't exist in fragment shaders -// on all ES platforms. When it doesn't exist, use "mediump". -#define QGL_REDEFINE_HIGHP 1 -static const char redefineHighp[] = - "#ifndef GL_FRAGMENT_PRECISION_HIGH\n" - "#define highp mediump\n" - "#endif\n"; -#endif - -/*! - Sets the \a source code for this shader and compiles it. - Returns \c true if the source was successfully compiled, false otherwise. - - \sa compileSourceFile() -*/ -bool QGLShader::compileSourceCode(const char *source) -{ - Q_D(QGLShader); - if (d->shaderGuard && d->shaderGuard->id()) { - QVarLengthArray<const char *, 4> src; - QVarLengthArray<GLint, 4> srclen; - int headerLen = 0; - while (source && source[headerLen] == '#') { - // Skip #version and #extension directives at the start of - // the shader code. We need to insert the qualifierDefines - // and redefineHighp just after them. - if (qstrncmp(source + headerLen, "#version", 8) != 0 && - qstrncmp(source + headerLen, "#extension", 10) != 0) { - break; - } - while (source[headerLen] != '\0' && source[headerLen] != '\n') - ++headerLen; - if (source[headerLen] == '\n') - ++headerLen; - } - if (headerLen > 0) { - src.append(source); - srclen.append(GLint(headerLen)); - } -#ifdef QGL_DEFINE_QUALIFIERS - if (!QOpenGLContext::currentContext()->isOpenGLES()) { - src.append(qualifierDefines); - srclen.append(GLint(sizeof(qualifierDefines) - 1)); - } -#endif -#ifdef QGL_REDEFINE_HIGHP - if (d->shaderType == Fragment - && QOpenGLContext::currentContext()->isOpenGLES()) { - src.append(redefineHighp); - srclen.append(GLint(sizeof(redefineHighp) - 1)); - } -#endif - src.append(source + headerLen); - srclen.append(GLint(qstrlen(source + headerLen))); - d->glfuncs->glShaderSource(d->shaderGuard->id(), src.size(), src.data(), srclen.data()); - return d->compile(this); - } else { - return false; - } -} - -/*! - \overload - - Sets the \a source code for this shader and compiles it. - Returns \c true if the source was successfully compiled, false otherwise. - - \sa compileSourceFile() -*/ -bool QGLShader::compileSourceCode(const QByteArray& source) -{ - return compileSourceCode(source.constData()); -} - -/*! - \overload - - Sets the \a source code for this shader and compiles it. - Returns \c true if the source was successfully compiled, false otherwise. - - \sa compileSourceFile() -*/ -bool QGLShader::compileSourceCode(const QString& source) -{ - return compileSourceCode(source.toLatin1().constData()); -} - -/*! - Sets the source code for this shader to the contents of \a fileName - and compiles it. Returns \c true if the file could be opened and the - source compiled, false otherwise. - - \sa compileSourceCode() -*/ -bool QGLShader::compileSourceFile(const QString& fileName) -{ - QFile file(fileName); - if (!file.open(QFile::ReadOnly)) { - qWarning() << "QGLShader: Unable to open file" << fileName; - return false; - } - - QByteArray contents = file.readAll(); - return compileSourceCode(contents.constData()); -} - -/*! - Returns the source code for this shader. - - \sa compileSourceCode() -*/ -QByteArray QGLShader::sourceCode() const -{ - Q_D(const QGLShader); - GLuint shader = d->shaderGuard ? d->shaderGuard->id() : 0; - if (!shader) - return QByteArray(); - GLint size = 0; - d->glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size); - if (size <= 0) - return QByteArray(); - GLint len = 0; - char *source = new char [size]; - d->glfuncs->glGetShaderSource(shader, size, &len, source); - QByteArray src(source); - delete [] source; - return src; -} - -/*! - Returns \c true if this shader has been compiled; false otherwise. - - \sa compileSourceCode(), compileSourceFile() -*/ -bool QGLShader::isCompiled() const -{ - Q_D(const QGLShader); - return d->compiled; -} - -/*! - Returns the errors and warnings that occurred during the last compile. - - \sa compileSourceCode(), compileSourceFile() -*/ -QString QGLShader::log() const -{ - Q_D(const QGLShader); - return d->log; -} - -/*! - Returns the OpenGL identifier associated with this shader. - - \sa QGLShaderProgram::programId() -*/ -GLuint QGLShader::shaderId() const -{ - Q_D(const QGLShader); - return d->shaderGuard ? d->shaderGuard->id() : 0; -} - -#undef ctx - -class ShaderProgramOpenGLFunctions : public QOpenGLFunctions -{ -public: - ShaderProgramOpenGLFunctions() - : QOpenGLFunctions() - , glProgramParameteri(0) - { - } - - typedef void (QOPENGLF_APIENTRYP type_glProgramParameteri)(GLuint program, GLenum pname, GLint value); - - void initializeGeometryShaderFunctions() - { - QOpenGLContext *context = QOpenGLContext::currentContext(); - if (!context->isOpenGLES()) { - glProgramParameteri = (type_glProgramParameteri) - context->getProcAddress("glProgramParameteri"); - - if (!glProgramParameteri) { - glProgramParameteri = (type_glProgramParameteri) - context->getProcAddress("glProgramParameteriEXT"); - } - } - } - - type_glProgramParameteri glProgramParameteri; -}; - -class QGLShaderProgramPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QGLShaderProgram) -public: - QGLShaderProgramPrivate(const QGLContext *) - : programGuard(0) - , linked(false) - , inited(false) - , removingShaders(false) - , geometryVertexCount(64) - , geometryInputType(0) - , geometryOutputType(0) - , glfuncs(new ShaderProgramOpenGLFunctions) - { - } - ~QGLShaderProgramPrivate(); - - QGLSharedResourceGuardBase *programGuard; - bool linked; - bool inited; - bool removingShaders; - - int geometryVertexCount; - GLenum geometryInputType; - GLenum geometryOutputType; - - QString log; - QList<QGLShader *> shaders; - QList<QGLShader *> anonShaders; - - ShaderProgramOpenGLFunctions *glfuncs; - - bool hasShader(QGLShader::ShaderType type) const; -}; - -namespace { - void freeProgramFunc(QGLContext *ctx, GLuint id) - { - Q_ASSERT(ctx); - ctx->contextHandle()->functions()->glDeleteProgram(id); - } -} - - -QGLShaderProgramPrivate::~QGLShaderProgramPrivate() -{ - delete glfuncs; - if (programGuard) - programGuard->free(); -} - -bool QGLShaderProgramPrivate::hasShader(QGLShader::ShaderType type) const -{ - for (QGLShader *shader : shaders) { - if (shader->shaderType() == type) - return true; - } - return false; -} - -#define ctx QGLContext::currentContext() - -/*! - Constructs a new shader program and attaches it to \a parent. - The program will be invalid until addShader() is called. - - The shader program will be associated with the current QGLContext. - - \sa addShader() -*/ -QGLShaderProgram::QGLShaderProgram(QObject *parent) - : QObject(*new QGLShaderProgramPrivate(QGLContext::currentContext()), parent) -{ -} - -/*! - Constructs a new shader program and attaches it to \a parent. - The program will be invalid until addShader() is called. - - The shader program will be associated with \a context. - - \sa addShader() -*/ -QGLShaderProgram::QGLShaderProgram(const QGLContext *context, QObject *parent) - : QObject(*new QGLShaderProgramPrivate(context), parent) -{ -} - -/*! - Deletes this shader program. -*/ -QGLShaderProgram::~QGLShaderProgram() -{ -} - -bool QGLShaderProgram::init() -{ - Q_D(QGLShaderProgram); - if ((d->programGuard && d->programGuard->id()) || d->inited) - return true; - d->inited = true; - QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext()); - if (!context) - return false; - d->glfuncs->initializeOpenGLFunctions(); - d->glfuncs->initializeGeometryShaderFunctions(); - if (d->glfuncs->hasOpenGLFeature(QOpenGLFunctions::Shaders)) { - GLuint program = d->glfuncs->glCreateProgram(); - if (!program) { - qWarning("QGLShaderProgram: could not create shader program"); - return false; - } - if (d->programGuard) - delete d->programGuard; - d->programGuard = createSharedResourceGuard(context, program, freeProgramFunc); - return true; - } else { - qWarning("QGLShaderProgram: shader programs are not supported"); - return false; - } -} - -/*! - Adds a compiled \a shader to this shader program. Returns \c true - if the shader could be added, or false otherwise. - - Ownership of the \a shader object remains with the caller. - It will not be deleted when this QGLShaderProgram instance - is deleted. This allows the caller to add the same shader - to multiple shader programs. - - \sa addShaderFromSourceCode(), addShaderFromSourceFile() - \sa removeShader(), link(), removeAllShaders() -*/ -bool QGLShaderProgram::addShader(QGLShader *shader) -{ - Q_D(QGLShaderProgram); - if (!init()) - return false; - if (d->shaders.contains(shader)) - return true; // Already added to this shader program. - if (d->programGuard && d->programGuard->id() && shader) { - if (!shader->d_func()->shaderGuard || !shader->d_func()->shaderGuard->id()) - return false; - if (d->programGuard->group() != shader->d_func()->shaderGuard->group()) { - qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context."); - return false; - } - d->glfuncs->glAttachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id()); - d->linked = false; // Program needs to be relinked. - d->shaders.append(shader); - connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed())); - return true; - } else { - return false; - } -} - -/*! - Compiles \a source as a shader of the specified \a type and - adds it to this shader program. Returns \c true if compilation - was successful, false otherwise. The compilation errors - and warnings will be made available via log(). - - This function is intended to be a short-cut for quickly - adding vertex and fragment shaders to a shader program without - creating an instance of QGLShader first. - - \sa addShader(), addShaderFromSourceFile() - \sa removeShader(), link(), log(), removeAllShaders() -*/ -bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const char *source) -{ - Q_D(QGLShaderProgram); - if (!init()) - return false; - QGLShader *shader = new QGLShader(type, this); - if (!shader->compileSourceCode(source)) { - d->log = shader->log(); - delete shader; - return false; - } - d->anonShaders.append(shader); - return addShader(shader); -} - -/*! - \overload - - Compiles \a source as a shader of the specified \a type and - adds it to this shader program. Returns \c true if compilation - was successful, false otherwise. The compilation errors - and warnings will be made available via log(). - - This function is intended to be a short-cut for quickly - adding vertex and fragment shaders to a shader program without - creating an instance of QGLShader first. - - \sa addShader(), addShaderFromSourceFile() - \sa removeShader(), link(), log(), removeAllShaders() -*/ -bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QByteArray& source) -{ - return addShaderFromSourceCode(type, source.constData()); -} - -/*! - \overload - - Compiles \a source as a shader of the specified \a type and - adds it to this shader program. Returns \c true if compilation - was successful, false otherwise. The compilation errors - and warnings will be made available via log(). - - This function is intended to be a short-cut for quickly - adding vertex and fragment shaders to a shader program without - creating an instance of QGLShader first. - - \sa addShader(), addShaderFromSourceFile() - \sa removeShader(), link(), log(), removeAllShaders() -*/ -bool QGLShaderProgram::addShaderFromSourceCode(QGLShader::ShaderType type, const QString& source) -{ - return addShaderFromSourceCode(type, source.toLatin1().constData()); -} - -/*! - Compiles the contents of \a fileName as a shader of the specified - \a type and adds it to this shader program. Returns \c true if - compilation was successful, false otherwise. The compilation errors - and warnings will be made available via log(). - - This function is intended to be a short-cut for quickly - adding vertex and fragment shaders to a shader program without - creating an instance of QGLShader first. - - \sa addShader(), addShaderFromSourceCode() -*/ -bool QGLShaderProgram::addShaderFromSourceFile - (QGLShader::ShaderType type, const QString& fileName) -{ - Q_D(QGLShaderProgram); - if (!init()) - return false; - QGLShader *shader = new QGLShader(type, this); - if (!shader->compileSourceFile(fileName)) { - d->log = shader->log(); - delete shader; - return false; - } - d->anonShaders.append(shader); - return addShader(shader); -} - -/*! - Removes \a shader from this shader program. The object is not deleted. - - The shader program must be valid in the current QGLContext. - - \sa addShader(), link(), removeAllShaders() -*/ -void QGLShaderProgram::removeShader(QGLShader *shader) -{ - Q_D(QGLShaderProgram); - if (d->programGuard && d->programGuard->id() - && shader && shader->d_func()->shaderGuard) - { - d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id()); - } - d->linked = false; // Program needs to be relinked. - if (shader) { - d->shaders.removeAll(shader); - d->anonShaders.removeAll(shader); - disconnect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed())); - } -} - -/*! - Returns a list of all shaders that have been added to this shader - program using addShader(). - - \sa addShader(), removeShader() -*/ -QList<QGLShader *> QGLShaderProgram::shaders() const -{ - Q_D(const QGLShaderProgram); - return d->shaders; -} - -/*! - Removes all of the shaders that were added to this program previously. - The QGLShader objects for the shaders will not be deleted if they - were constructed externally. QGLShader objects that are constructed - internally by QGLShaderProgram will be deleted. - - \sa addShader(), removeShader() -*/ -void QGLShaderProgram::removeAllShaders() -{ - Q_D(QGLShaderProgram); - d->removingShaders = true; - if (d->programGuard) { - if (const auto programGuardId = d->programGuard->id()) { - for (QGLShader *shader : qAsConst(d->shaders)) { - if (shader && shader->d_func()->shaderGuard) - d->glfuncs->glDetachShader(programGuardId, shader->d_func()->shaderGuard->id()); - } - } - } - // Delete shader objects that were created anonymously. - qDeleteAll(d->anonShaders); - d->shaders.clear(); - d->anonShaders.clear(); - d->linked = false; // Program needs to be relinked. - d->removingShaders = false; -} - -/*! - Links together the shaders that were added to this program with - addShader(). Returns \c true if the link was successful or - false otherwise. If the link failed, the error messages can - be retrieved with log(). - - Subclasses can override this function to initialize attributes - and uniform variables for use in specific shader programs. - - If the shader program was already linked, calling this - function again will force it to be re-linked. - - \sa addShader(), log() -*/ -bool QGLShaderProgram::link() -{ - Q_D(QGLShaderProgram); - GLuint program = d->programGuard ? d->programGuard->id() : 0; - if (!program) - return false; - - GLint value; - if (d->shaders.isEmpty()) { - // If there are no explicit shaders, then it is possible that the - // application added a program binary with glProgramBinaryOES(), - // or otherwise populated the shaders itself. Check to see if the - // program is already linked and bail out if so. - value = 0; - d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value); - d->linked = (value != 0); - if (d->linked) - return true; - } - -#if !defined(QT_OPENGL_ES_2) - // Set up the geometry shader parameters - if (!QOpenGLContext::currentContext()->isOpenGLES() - && d->glfuncs->glProgramParameteri) { - for (QGLShader *shader : qAsConst(d->shaders)) { - if (shader->shaderType() & QGLShader::Geometry) { - d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_INPUT_TYPE_EXT, - d->geometryInputType); - d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, - d->geometryOutputType); - d->glfuncs->glProgramParameteri(program, GL_GEOMETRY_VERTICES_OUT_EXT, - d->geometryVertexCount); - break; - } - } - } -#endif - - d->glfuncs->glLinkProgram(program); - value = 0; - d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value); - d->linked = (value != 0); - value = 0; - d->glfuncs->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value); - d->log = QString(); - if (value > 1) { - char *logbuf = new char [value]; - GLint len; - d->glfuncs->glGetProgramInfoLog(program, value, &len, logbuf); - d->log = QString::fromLatin1(logbuf); - QString name = objectName(); - if (!d->linked) { - if (name.isEmpty()) - qWarning() << "QGLShader::link:" << d->log; - else - qWarning() << "QGLShader::link[" << name << "]:" << d->log; - } - delete [] logbuf; - } - return d->linked; -} - -/*! - Returns \c true if this shader program has been linked; false otherwise. - - \sa link() -*/ -bool QGLShaderProgram::isLinked() const -{ - Q_D(const QGLShaderProgram); - return d->linked; -} - -/*! - Returns the errors and warnings that occurred during the last link() - or addShader() with explicitly specified source code. - - \sa link() -*/ -QString QGLShaderProgram::log() const -{ - Q_D(const QGLShaderProgram); - return d->log; -} - -/*! - Binds this shader program to the active QGLContext and makes - it the current shader program. Any previously bound shader program - is released. This is equivalent to calling \c{glUseProgram()} on - programId(). Returns \c true if the program was successfully bound; - false otherwise. If the shader program has not yet been linked, - or it needs to be re-linked, this function will call link(). - - \sa link(), release() -*/ -bool QGLShaderProgram::bind() -{ - Q_D(QGLShaderProgram); - GLuint program = d->programGuard ? d->programGuard->id() : 0; - if (!program) - return false; - if (!d->linked && !link()) - return false; -#ifndef QT_NO_DEBUG - if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup()) { - qWarning("QGLShaderProgram::bind: program is not valid in the current context."); - return false; - } -#endif - d->glfuncs->glUseProgram(program); - return true; -} - -#undef ctx -#define ctx QGLContext::currentContext() - -/*! - Releases the active shader program from the current QGLContext. - This is equivalent to calling \c{glUseProgram(0)}. - - \sa bind() -*/ -void QGLShaderProgram::release() -{ - Q_D(QGLShaderProgram); -#ifndef QT_NO_DEBUG - if (d->programGuard && d->programGuard->group() != QOpenGLContextGroup::currentContextGroup()) - qWarning("QGLShaderProgram::release: program is not valid in the current context."); -#endif - d->glfuncs->glUseProgram(0); -} - -/*! - Returns the OpenGL identifier associated with this shader program. - - \sa QGLShader::shaderId() -*/ -GLuint QGLShaderProgram::programId() const -{ - Q_D(const QGLShaderProgram); - GLuint id = d->programGuard ? d->programGuard->id() : 0; - if (id) - return id; - - // Create the identifier if we don't have one yet. This is for - // applications that want to create the attached shader configuration - // themselves, particularly those using program binaries. - if (!const_cast<QGLShaderProgram *>(this)->init()) - return 0; - return d->programGuard ? d->programGuard->id() : 0; -} - -/*! - Binds the attribute \a name to the specified \a location. This - function can be called before or after the program has been linked. - Any attributes that have not been explicitly bound when the program - is linked will be assigned locations automatically. - - When this function is called after the program has been linked, - the program will need to be relinked for the change to take effect. - - \sa attributeLocation() -*/ -void QGLShaderProgram::bindAttributeLocation(const char *name, int location) -{ - Q_D(QGLShaderProgram); - if (!init() || !d->programGuard || !d->programGuard->id()) - return; - d->glfuncs->glBindAttribLocation(d->programGuard->id(), location, name); - d->linked = false; // Program needs to be relinked. -} - -/*! - \overload - - Binds the attribute \a name to the specified \a location. This - function can be called before or after the program has been linked. - Any attributes that have not been explicitly bound when the program - is linked will be assigned locations automatically. - - When this function is called after the program has been linked, - the program will need to be relinked for the change to take effect. - - \sa attributeLocation() -*/ -void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location) -{ - bindAttributeLocation(name.constData(), location); -} - -/*! - \overload - - Binds the attribute \a name to the specified \a location. This - function can be called before or after the program has been linked. - Any attributes that have not been explicitly bound when the program - is linked will be assigned locations automatically. - - When this function is called after the program has been linked, - the program will need to be relinked for the change to take effect. - - \sa attributeLocation() -*/ -void QGLShaderProgram::bindAttributeLocation(const QString& name, int location) -{ - bindAttributeLocation(name.toLatin1().constData(), location); -} - -/*! - Returns the location of the attribute \a name within this shader - program's parameter list. Returns -1 if \a name is not a valid - attribute for this shader program. - - \sa uniformLocation(), bindAttributeLocation() -*/ -int QGLShaderProgram::attributeLocation(const char *name) const -{ - Q_D(const QGLShaderProgram); - if (d->linked && d->programGuard && d->programGuard->id()) { - return d->glfuncs->glGetAttribLocation(d->programGuard->id(), name); - } else { - qWarning() << "QGLShaderProgram::attributeLocation(" << name - << "): shader program is not linked"; - return -1; - } -} - -/*! - \overload - - Returns the location of the attribute \a name within this shader - program's parameter list. Returns -1 if \a name is not a valid - attribute for this shader program. - - \sa uniformLocation(), bindAttributeLocation() -*/ -int QGLShaderProgram::attributeLocation(const QByteArray& name) const -{ - return attributeLocation(name.constData()); -} - -/*! - \overload - - Returns the location of the attribute \a name within this shader - program's parameter list. Returns -1 if \a name is not a valid - attribute for this shader program. - - \sa uniformLocation(), bindAttributeLocation() -*/ -int QGLShaderProgram::attributeLocation(const QString& name) const -{ - return attributeLocation(name.toLatin1().constData()); -} - -/*! - Sets the attribute at \a location in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(int location, GLfloat value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glVertexAttrib1fv(location, &value); -} - -/*! - \overload - - Sets the attribute called \a name in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(const char *name, GLfloat value) -{ - setAttributeValue(attributeLocation(name), value); -} - -/*! - Sets the attribute at \a location in the current context to - the 2D vector (\a x, \a y). - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[2] = {x, y}; - d->glfuncs->glVertexAttrib2fv(location, values); - } -} - -/*! - \overload - - Sets the attribute called \a name in the current context to - the 2D vector (\a x, \a y). - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(const char *name, GLfloat x, GLfloat y) -{ - setAttributeValue(attributeLocation(name), x, y); -} - -/*! - Sets the attribute at \a location in the current context to - the 3D vector (\a x, \a y, \a z). - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue - (int location, GLfloat x, GLfloat y, GLfloat z) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[3] = {x, y, z}; - d->glfuncs->glVertexAttrib3fv(location, values); - } -} - -/*! - \overload - - Sets the attribute called \a name in the current context to - the 3D vector (\a x, \a y, \a z). - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue - (const char *name, GLfloat x, GLfloat y, GLfloat z) -{ - setAttributeValue(attributeLocation(name), x, y, z); -} - -/*! - Sets the attribute at \a location in the current context to - the 4D vector (\a x, \a y, \a z, \a w). - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue - (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[4] = {x, y, z, w}; - d->glfuncs->glVertexAttrib4fv(location, values); - } -} - -/*! - \overload - - Sets the attribute called \a name in the current context to - the 4D vector (\a x, \a y, \a z, \a w). - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue - (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - setAttributeValue(attributeLocation(name), x, y, z, w); -} - -/*! - Sets the attribute at \a location in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(int location, const QVector2D& value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value)); -} - -/*! - \overload - - Sets the attribute called \a name in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(const char *name, const QVector2D& value) -{ - setAttributeValue(attributeLocation(name), value); -} - -/*! - Sets the attribute at \a location in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(int location, const QVector3D& value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value)); -} - -/*! - \overload - - Sets the attribute called \a name in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(const char *name, const QVector3D& value) -{ - setAttributeValue(attributeLocation(name), value); -} - -/*! - Sets the attribute at \a location in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(int location, const QVector4D& value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value)); -} - -/*! - \overload - - Sets the attribute called \a name in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(const char *name, const QVector4D& value) -{ - setAttributeValue(attributeLocation(name), value); -} - -/*! - Sets the attribute at \a location in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(int location, const QColor& value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()), - GLfloat(value.blueF()), GLfloat(value.alphaF())}; - d->glfuncs->glVertexAttrib4fv(location, values); - } -} - -/*! - \overload - - Sets the attribute called \a name in the current context to \a value. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue(const char *name, const QColor& value) -{ - setAttributeValue(attributeLocation(name), value); -} - -/*! - Sets the attribute at \a location in the current context to the - contents of \a values, which contains \a columns elements, each - consisting of \a rows elements. The \a rows value should be - 1, 2, 3, or 4. This function is typically used to set matrix - values and column vectors. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue - (int location, const GLfloat *values, int columns, int rows) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (rows < 1 || rows > 4) { - qWarning() << "QGLShaderProgram::setAttributeValue: rows" << rows << "not supported"; - return; - } - if (location != -1) { - while (columns-- > 0) { - if (rows == 1) - d->glfuncs->glVertexAttrib1fv(location, values); - else if (rows == 2) - d->glfuncs->glVertexAttrib2fv(location, values); - else if (rows == 3) - d->glfuncs->glVertexAttrib3fv(location, values); - else - d->glfuncs->glVertexAttrib4fv(location, values); - values += rows; - ++location; - } - } -} - -/*! - \overload - - Sets the attribute called \a name in the current context to the - contents of \a values, which contains \a columns elements, each - consisting of \a rows elements. The \a rows value should be - 1, 2, 3, or 4. This function is typically used to set matrix - values and column vectors. - - \sa setUniformValue() -*/ -void QGLShaderProgram::setAttributeValue - (const char *name, const GLfloat *values, int columns, int rows) -{ - setAttributeValue(attributeLocation(name), values, columns, rows); -} - -/*! - Sets an array of vertex \a values on the attribute at \a location - in this shader program. The \a tupleSize indicates the number of - components per vertex (1, 2, 3, or 4), and the \a stride indicates - the number of bytes between vertices. A default \a stride value - of zero indicates that the vertices are densely packed in \a values. - - The array will become active when enableAttributeArray() is called - on the \a location. Otherwise the value specified with - setAttributeValue() for \a location will be used. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray() -*/ -void QGLShaderProgram::setAttributeArray - (int location, const GLfloat *values, int tupleSize, int stride) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - d->glfuncs->glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE, - stride, values); - } -} - -/*! - Sets an array of 2D vertex \a values on the attribute at \a location - in this shader program. The \a stride indicates the number of bytes - between vertices. A default \a stride value of zero indicates that - the vertices are densely packed in \a values. - - The array will become active when enableAttributeArray() is called - on the \a location. Otherwise the value specified with - setAttributeValue() for \a location will be used. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray() -*/ -void QGLShaderProgram::setAttributeArray - (int location, const QVector2D *values, int stride) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - d->glfuncs->glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE, - stride, values); - } -} - -/*! - Sets an array of 3D vertex \a values on the attribute at \a location - in this shader program. The \a stride indicates the number of bytes - between vertices. A default \a stride value of zero indicates that - the vertices are densely packed in \a values. - - The array will become active when enableAttributeArray() is called - on the \a location. Otherwise the value specified with - setAttributeValue() for \a location will be used. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray() -*/ -void QGLShaderProgram::setAttributeArray - (int location, const QVector3D *values, int stride) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - d->glfuncs->glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, - stride, values); - } -} - -/*! - Sets an array of 4D vertex \a values on the attribute at \a location - in this shader program. The \a stride indicates the number of bytes - between vertices. A default \a stride value of zero indicates that - the vertices are densely packed in \a values. - - The array will become active when enableAttributeArray() is called - on the \a location. Otherwise the value specified with - setAttributeValue() for \a location will be used. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray() -*/ -void QGLShaderProgram::setAttributeArray - (int location, const QVector4D *values, int stride) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - d->glfuncs->glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, - stride, values); - } -} - -/*! - Sets an array of vertex \a values on the attribute at \a location - in this shader program. The \a stride indicates the number of bytes - between vertices. A default \a stride value of zero indicates that - the vertices are densely packed in \a values. - - The \a type indicates the type of elements in the \a values array, - usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a tupleSize - indicates the number of components per vertex: 1, 2, 3, or 4. - - The array will become active when enableAttributeArray() is called - on the \a location. Otherwise the value specified with - setAttributeValue() for \a location will be used. - - The setAttributeBuffer() function can be used to set the attribute - array to an offset within a vertex buffer. - - \note Normalization will be enabled. If this is not desired, call - glVertexAttribPointer directly through QGLFunctions. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray(), setAttributeBuffer() - \since 4.7 -*/ -void QGLShaderProgram::setAttributeArray - (int location, GLenum type, const void *values, int tupleSize, int stride) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, - stride, values); - } -} - -/*! - \overload - - Sets an array of vertex \a values on the attribute called \a name - in this shader program. The \a tupleSize indicates the number of - components per vertex (1, 2, 3, or 4), and the \a stride indicates - the number of bytes between vertices. A default \a stride value - of zero indicates that the vertices are densely packed in \a values. - - The array will become active when enableAttributeArray() is called - on \a name. Otherwise the value specified with setAttributeValue() - for \a name will be used. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray() -*/ -void QGLShaderProgram::setAttributeArray - (const char *name, const GLfloat *values, int tupleSize, int stride) -{ - setAttributeArray(attributeLocation(name), values, tupleSize, stride); -} - -/*! - \overload - - Sets an array of 2D vertex \a values on the attribute called \a name - in this shader program. The \a stride indicates the number of bytes - between vertices. A default \a stride value of zero indicates that - the vertices are densely packed in \a values. - - The array will become active when enableAttributeArray() is called - on \a name. Otherwise the value specified with setAttributeValue() - for \a name will be used. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray() -*/ -void QGLShaderProgram::setAttributeArray - (const char *name, const QVector2D *values, int stride) -{ - setAttributeArray(attributeLocation(name), values, stride); -} - -/*! - \overload - - Sets an array of 3D vertex \a values on the attribute called \a name - in this shader program. The \a stride indicates the number of bytes - between vertices. A default \a stride value of zero indicates that - the vertices are densely packed in \a values. - - The array will become active when enableAttributeArray() is called - on \a name. Otherwise the value specified with setAttributeValue() - for \a name will be used. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray() -*/ -void QGLShaderProgram::setAttributeArray - (const char *name, const QVector3D *values, int stride) -{ - setAttributeArray(attributeLocation(name), values, stride); -} - -/*! - \overload - - Sets an array of 4D vertex \a values on the attribute called \a name - in this shader program. The \a stride indicates the number of bytes - between vertices. A default \a stride value of zero indicates that - the vertices are densely packed in \a values. - - The array will become active when enableAttributeArray() is called - on \a name. Otherwise the value specified with setAttributeValue() - for \a name will be used. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray() -*/ -void QGLShaderProgram::setAttributeArray - (const char *name, const QVector4D *values, int stride) -{ - setAttributeArray(attributeLocation(name), values, stride); -} - -/*! - \overload - - Sets an array of vertex \a values on the attribute called \a name - in this shader program. The \a stride indicates the number of bytes - between vertices. A default \a stride value of zero indicates that - the vertices are densely packed in \a values. - - The \a type indicates the type of elements in the \a values array, - usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a tupleSize - indicates the number of components per vertex: 1, 2, 3, or 4. - - The array will become active when enableAttributeArray() is called - on the \a name. Otherwise the value specified with - setAttributeValue() for \a name will be used. - - The setAttributeBuffer() function can be used to set the attribute - array to an offset within a vertex buffer. - - \sa setAttributeValue(), setUniformValue(), enableAttributeArray() - \sa disableAttributeArray(), setAttributeBuffer() - \since 4.7 -*/ -void QGLShaderProgram::setAttributeArray - (const char *name, GLenum type, const void *values, int tupleSize, int stride) -{ - setAttributeArray(attributeLocation(name), type, values, tupleSize, stride); -} - -/*! - Sets an array of vertex values on the attribute at \a location in - this shader program, starting at a specific \a offset in the - currently bound vertex buffer. The \a stride indicates the number - of bytes between vertices. A default \a stride value of zero - indicates that the vertices are densely packed in the value array. - - The \a type indicates the type of elements in the vertex value - array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a - tupleSize indicates the number of components per vertex: 1, 2, 3, - or 4. - - The array will become active when enableAttributeArray() is called - on the \a location. Otherwise the value specified with - setAttributeValue() for \a location will be used. - - \note Normalization will be enabled. If this is not desired, call - glVertexAttribPointer directly though QGLFunctions. - - \sa setAttributeArray() - \since 4.7 -*/ -void QGLShaderProgram::setAttributeBuffer - (int location, GLenum type, int offset, int tupleSize, int stride) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride, - reinterpret_cast<const void *>(qintptr(offset))); - } -} - -/*! - \overload - - Sets an array of vertex values on the attribute called \a name - in this shader program, starting at a specific \a offset in the - currently bound vertex buffer. The \a stride indicates the number - of bytes between vertices. A default \a stride value of zero - indicates that the vertices are densely packed in the value array. - - The \a type indicates the type of elements in the vertex value - array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc. The \a - tupleSize indicates the number of components per vertex: 1, 2, 3, - or 4. - - The array will become active when enableAttributeArray() is called - on the \a name. Otherwise the value specified with - setAttributeValue() for \a name will be used. - - \sa setAttributeArray() - \since 4.7 -*/ -void QGLShaderProgram::setAttributeBuffer - (const char *name, GLenum type, int offset, int tupleSize, int stride) -{ - setAttributeBuffer(attributeLocation(name), type, offset, tupleSize, stride); -} - -/*! - Enables the vertex array at \a location in this shader program - so that the value set by setAttributeArray() on \a location - will be used by the shader program. - - \sa disableAttributeArray(), setAttributeArray(), setAttributeValue() - \sa setUniformValue() -*/ -void QGLShaderProgram::enableAttributeArray(int location) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glEnableVertexAttribArray(location); -} - -/*! - \overload - - Enables the vertex array called \a name in this shader program - so that the value set by setAttributeArray() on \a name - will be used by the shader program. - - \sa disableAttributeArray(), setAttributeArray(), setAttributeValue() - \sa setUniformValue() -*/ -void QGLShaderProgram::enableAttributeArray(const char *name) -{ - enableAttributeArray(attributeLocation(name)); -} - -/*! - Disables the vertex array at \a location in this shader program - that was enabled by a previous call to enableAttributeArray(). - - \sa enableAttributeArray(), setAttributeArray(), setAttributeValue() - \sa setUniformValue() -*/ -void QGLShaderProgram::disableAttributeArray(int location) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glDisableVertexAttribArray(location); -} - -/*! - \overload - - Disables the vertex array called \a name in this shader program - that was enabled by a previous call to enableAttributeArray(). - - \sa enableAttributeArray(), setAttributeArray(), setAttributeValue() - \sa setUniformValue() -*/ -void QGLShaderProgram::disableAttributeArray(const char *name) -{ - disableAttributeArray(attributeLocation(name)); -} - -/*! - Returns the location of the uniform variable \a name within this shader - program's parameter list. Returns -1 if \a name is not a valid - uniform variable for this shader program. - - \sa attributeLocation() -*/ -int QGLShaderProgram::uniformLocation(const char *name) const -{ - Q_D(const QGLShaderProgram); - Q_UNUSED(d); - if (d->linked && d->programGuard && d->programGuard->id()) { - return d->glfuncs->glGetUniformLocation(d->programGuard->id(), name); - } else { - qWarning() << "QGLShaderProgram::uniformLocation(" << name - << "): shader program is not linked"; - return -1; - } -} - -/*! - \overload - - Returns the location of the uniform variable \a name within this shader - program's parameter list. Returns -1 if \a name is not a valid - uniform variable for this shader program. - - \sa attributeLocation() -*/ -int QGLShaderProgram::uniformLocation(const QByteArray& name) const -{ - return uniformLocation(name.constData()); -} - -/*! - \overload - - Returns the location of the uniform variable \a name within this shader - program's parameter list. Returns -1 if \a name is not a valid - uniform variable for this shader program. - - \sa attributeLocation() -*/ -int QGLShaderProgram::uniformLocation(const QString& name) const -{ - return uniformLocation(name.toLatin1().constData()); -} - -/*! - Sets the uniform variable at \a location in the current context to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, GLfloat value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glUniform1fv(location, 1, &value); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, GLfloat value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, GLint value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glUniform1i(location, value); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, GLint value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context to \a value. - This function should be used when setting sampler values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, GLuint value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glUniform1i(location, value); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to \a value. This function should be used when setting sampler values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, GLuint value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context to - the 2D vector (\a x, \a y). - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[2] = {x, y}; - d->glfuncs->glUniform2fv(location, 1, values); - } -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context to - the 2D vector (\a x, \a y). - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, GLfloat x, GLfloat y) -{ - setUniformValue(uniformLocation(name), x, y); -} - -/*! - Sets the uniform variable at \a location in the current context to - the 3D vector (\a x, \a y, \a z). - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue - (int location, GLfloat x, GLfloat y, GLfloat z) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[3] = {x, y, z}; - d->glfuncs->glUniform3fv(location, 1, values); - } -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context to - the 3D vector (\a x, \a y, \a z). - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue - (const char *name, GLfloat x, GLfloat y, GLfloat z) -{ - setUniformValue(uniformLocation(name), x, y, z); -} - -/*! - Sets the uniform variable at \a location in the current context to - the 4D vector (\a x, \a y, \a z, \a w). - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue - (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[4] = {x, y, z, w}; - d->glfuncs->glUniform4fv(location, 1, values); - } -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context to - the 4D vector (\a x, \a y, \a z, \a w). - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue - (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - setUniformValue(uniformLocation(name), x, y, z, w); -} - -/*! - Sets the uniform variable at \a location in the current context to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QVector2D& value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QVector2D& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QVector3D& value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QVector3D& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QVector4D& value) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value)); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QVector4D& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context to - the red, green, blue, and alpha components of \a color. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QColor& color) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()), - GLfloat(color.blueF()), GLfloat(color.alphaF())}; - d->glfuncs->glUniform4fv(location, 1, values); - } -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context to - the red, green, blue, and alpha components of \a color. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QColor& color) -{ - setUniformValue(uniformLocation(name), color); -} - -/*! - Sets the uniform variable at \a location in the current context to - the x and y coordinates of \a point. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QPoint& point) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())}; - d->glfuncs->glUniform2fv(location, 1, values); - } -} - -/*! - \overload - - Sets the uniform variable associated with \a name in the current - context to the x and y coordinates of \a point. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QPoint& point) -{ - setUniformValue(uniformLocation(name), point); -} - -/*! - Sets the uniform variable at \a location in the current context to - the x and y coordinates of \a point. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QPointF& point) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())}; - d->glfuncs->glUniform2fv(location, 1, values); - } -} - -/*! - \overload - - Sets the uniform variable associated with \a name in the current - context to the x and y coordinates of \a point. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QPointF& point) -{ - setUniformValue(uniformLocation(name), point); -} - -/*! - Sets the uniform variable at \a location in the current context to - the width and height of the given \a size. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QSize& size) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())}; - d->glfuncs->glUniform2fv(location, 1, values); - } -} - -/*! - \overload - - Sets the uniform variable associated with \a name in the current - context to the width and height of the given \a size. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QSize& size) -{ - setUniformValue(uniformLocation(name), size); -} - -/*! - Sets the uniform variable at \a location in the current context to - the width and height of the given \a size. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QSizeF& size) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) { - GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())}; - d->glfuncs->glUniform2fv(location, 1, values); - } -} - -/*! - \overload - - Sets the uniform variable associated with \a name in the current - context to the width and height of the given \a size. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QSizeF& size) -{ - setUniformValue(uniformLocation(name), size); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 2x2 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 2x2 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 2x3 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniform3fv(location, 2, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 2x3 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 2x4 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniform4fv(location, 2, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 2x4 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 3x2 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniform2fv(location, 3, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 3x2 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 3x3 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 3x3 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 3x4 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniform4fv(location, 3, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 3x4 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 4x2 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniform2fv(location, 4, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 4x2 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 4x3 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniform3fv(location, 4, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 4x3 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context - to a 4x4 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value) -{ - Q_D(QGLShaderProgram); - d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value.constData()); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 4x4 matrix \a value. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - \overload - - Sets the uniform variable at \a location in the current context - to a 2x2 matrix \a value. The matrix elements must be specified - in column-major order. - - \sa setAttributeValue() - \since 4.7 -*/ -void QGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2]) -{ - Q_D(QGLShaderProgram); - if (location != -1) - d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value[0]); -} - -/*! - \overload - - Sets the uniform variable at \a location in the current context - to a 3x3 matrix \a value. The matrix elements must be specified - in column-major order. - - \sa setAttributeValue() - \since 4.7 -*/ -void QGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3]) -{ - Q_D(QGLShaderProgram); - if (location != -1) - d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value[0]); -} - -/*! - \overload - - Sets the uniform variable at \a location in the current context - to a 4x4 matrix \a value. The matrix elements must be specified - in column-major order. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4]) -{ - Q_D(QGLShaderProgram); - if (location != -1) - d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value[0]); -} - - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 2x2 matrix \a value. The matrix elements must be specified - in column-major order. - - \sa setAttributeValue() - \since 4.7 -*/ -void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[2][2]) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 3x3 matrix \a value. The matrix elements must be specified - in column-major order. - - \sa setAttributeValue() - \since 4.7 -*/ -void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[3][3]) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context - to a 4x4 matrix \a value. The matrix elements must be specified - in column-major order. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValue(const char *name, const GLfloat value[4][4]) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable at \a location in the current context to a - 3x3 transformation matrix \a value that is specified as a QTransform value. - - To set a QTransform value as a 4x4 matrix in a shader, use - \c{setUniformValue(location, QMatrix4x4(value))}. -*/ -void QGLShaderProgram::setUniformValue(int location, const QTransform& value) -{ - Q_D(QGLShaderProgram); - if (location != -1) { - GLfloat mat[3][3] = { - {GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())}, - {GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())}, - {GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())} - }; - d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]); - } -} - -/*! - \overload - - Sets the uniform variable called \a name in the current context to a - 3x3 transformation matrix \a value that is specified as a QTransform value. - - To set a QTransform value as a 4x4 matrix in a shader, use - \c{setUniformValue(name, QMatrix4x4(value))}. -*/ -void QGLShaderProgram::setUniformValue - (const char *name, const QTransform& value) -{ - setUniformValue(uniformLocation(name), value); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count) -{ - Q_D(QGLShaderProgram); - if (location != -1) - d->glfuncs->glUniform1iv(location, count, values); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray - (const char *name, const GLint *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count elements of \a values. This overload - should be used when setting an array of sampler values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count) -{ - Q_D(QGLShaderProgram); - if (location != -1) - d->glfuncs->glUniform1iv(location, count, reinterpret_cast<const GLint *>(values)); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count elements of \a values. This overload - should be used when setting an array of sampler values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray - (const char *name, const GLuint *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count elements of \a values. Each element - has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize) -{ - Q_D(QGLShaderProgram); - if (location != -1) { - if (tupleSize == 1) - d->glfuncs->glUniform1fv(location, count, values); - else if (tupleSize == 2) - d->glfuncs->glUniform2fv(location, count, values); - else if (tupleSize == 3) - d->glfuncs->glUniform3fv(location, count, values); - else if (tupleSize == 4) - d->glfuncs->glUniform4fv(location, count, values); - else - qWarning() << "QGLShaderProgram::setUniformValue: size" << tupleSize << "not supported"; - } -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count elements of \a values. Each element - has \a tupleSize components. The \a tupleSize must be 1, 2, 3, or 4. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray - (const char *name, const GLfloat *values, int count, int tupleSize) -{ - setUniformValueArray(uniformLocation(name), values, count, tupleSize); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 2D vector elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count) -{ - Q_D(QGLShaderProgram); - if (location != -1) - d->glfuncs->glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values)); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 2D vector elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QVector2D *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 3D vector elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count) -{ - Q_D(QGLShaderProgram); - if (location != -1) - d->glfuncs->glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values)); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 3D vector elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QVector3D *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 4D vector elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - if (location != -1) - d->glfuncs->glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values)); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 4D vector elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -// We have to repack matrix arrays from qreal to GLfloat. -#define setUniformMatrixArray(func,location,values,count,type,cols,rows) \ - if (location == -1 || count <= 0) \ - return; \ - if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \ - func(location, count, GL_FALSE, \ - reinterpret_cast<const GLfloat *>(values[0].constData())); \ - } else { \ - QVarLengthArray<GLfloat> temp(cols * rows * count); \ - for (int index = 0; index < count; ++index) { \ - for (int index2 = 0; index2 < (cols * rows); ++index2) { \ - temp.data()[cols * rows * index + index2] = \ - values[index].constData()[index2]; \ - } \ - } \ - func(location, count, GL_FALSE, temp.constData()); \ - } -#define setUniformGenericMatrixArray(colfunc,location,values,count,type,cols,rows) \ - if (location == -1 || count <= 0) \ - return; \ - if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \ - const GLfloat *data = reinterpret_cast<const GLfloat *> \ - (values[0].constData()); \ - colfunc(location, count * cols, data); \ - } else { \ - QVarLengthArray<GLfloat> temp(cols * rows * count); \ - for (int index = 0; index < count; ++index) { \ - for (int index2 = 0; index2 < (cols * rows); ++index2) { \ - temp.data()[cols * rows * index + index2] = \ - values[index].constData()[index2]; \ - } \ - } \ - colfunc(location, count * cols, temp.constData()); \ - } - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 2x2 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformMatrixArray - (d->glfuncs->glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 2x2 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x2 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 2x3 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformGenericMatrixArray - (d->glfuncs->glUniform3fv, location, values, count, - QMatrix2x3, 2, 3); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 2x3 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x3 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 2x4 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformGenericMatrixArray - (d->glfuncs->glUniform4fv, location, values, count, - QMatrix2x4, 2, 4); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 2x4 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x4 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 3x2 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformGenericMatrixArray - (d->glfuncs->glUniform2fv, location, values, count, - QMatrix3x2, 3, 2); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 3x2 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x2 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 3x3 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformMatrixArray - (d->glfuncs->glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 3x3 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x3 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 3x4 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformGenericMatrixArray - (d->glfuncs->glUniform4fv, location, values, count, - QMatrix3x4, 3, 4); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 3x4 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x4 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 4x2 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformGenericMatrixArray - (d->glfuncs->glUniform2fv, location, values, count, - QMatrix4x2, 4, 2); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 4x2 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x2 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 4x3 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformGenericMatrixArray - (d->glfuncs->glUniform3fv, location, values, count, - QMatrix4x3, 4, 3); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 4x3 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x3 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -/*! - Sets the uniform variable array at \a location in the current - context to the \a count 4x4 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count) -{ - Q_D(QGLShaderProgram); - Q_UNUSED(d); - setUniformMatrixArray - (d->glfuncs->glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4); -} - -/*! - \overload - - Sets the uniform variable array called \a name in the current - context to the \a count 4x4 matrix elements of \a values. - - \sa setAttributeValue() -*/ -void QGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *values, int count) -{ - setUniformValueArray(uniformLocation(name), values, count); -} - -#undef ctx - -/*! - Returns the hardware limit for how many vertices a geometry shader - can output. - - \since 4.7 - - \sa setGeometryOutputVertexCount() -*/ -int QGLShaderProgram::maxGeometryOutputVertices() const -{ - GLint n = 0; -#if !defined(QT_OPENGL_ES_2) - Q_D(const QGLShaderProgram); - if (!QOpenGLContext::currentContext()->isOpenGLES()) - d->glfuncs->glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, &n); -#endif - return n; -} - -/*! - Sets the maximum number of vertices the current geometry shader - program will produce, if active, to \a count. - - \since 4.7 - - This parameter takes effect the next time the program is linked. -*/ -void QGLShaderProgram::setGeometryOutputVertexCount(int count) -{ -#ifndef QT_NO_DEBUG - int max = maxGeometryOutputVertices(); - if (count > max) { - qWarning("QGLShaderProgram::setGeometryOutputVertexCount: count: %d higher than maximum: %d", - count, max); - } -#endif - d_func()->geometryVertexCount = count; -} - - -/*! - Returns the maximum number of vertices the current geometry shader - program will produce, if active. - - \since 4.7 - - This parameter takes effect the ntext time the program is linked. -*/ -int QGLShaderProgram::geometryOutputVertexCount() const -{ - return d_func()->geometryVertexCount; -} - - -/*! - Sets the input type from \a inputType. - - This parameter takes effect the next time the program is linked. -*/ -void QGLShaderProgram::setGeometryInputType(GLenum inputType) -{ - d_func()->geometryInputType = inputType; -} - - -/*! - Returns the geometry shader input type, if active. - - This parameter takes effect the next time the program is linked. - - \since 4.7 - */ - -GLenum QGLShaderProgram::geometryInputType() const -{ - return d_func()->geometryInputType; -} - - -/*! - Sets the output type from the geometry shader, if active, to - \a outputType. - - This parameter takes effect the next time the program is linked. - - \since 4.7 -*/ -void QGLShaderProgram::setGeometryOutputType(GLenum outputType) -{ - d_func()->geometryOutputType = outputType; -} - - -/*! - Returns the geometry shader output type, if active. - - This parameter takes effect the next time the program is linked. - - \since 4.7 - */ -GLenum QGLShaderProgram::geometryOutputType() const -{ - return d_func()->geometryOutputType; -} - - -/*! - Returns \c true if shader programs written in the OpenGL Shading - Language (GLSL) are supported on this system; false otherwise. - - The \a context is used to resolve the GLSL extensions. - If \a context is \nullptr, then QGLContext::currentContext() is - used. -*/ -bool QGLShaderProgram::hasOpenGLShaderPrograms(const QGLContext *context) -{ -#if !defined(QT_OPENGL_ES_2) - if (!context) - context = QGLContext::currentContext(); - if (!context) - return false; - - QOpenGLFunctions functions(context->contextHandle()); - return functions.hasOpenGLFeature(QOpenGLFunctions::Shaders); -#else - Q_UNUSED(context); - return true; -#endif -} - -/*! - \internal -*/ -void QGLShaderProgram::shaderDestroyed() -{ - Q_D(QGLShaderProgram); - QGLShader *shader = qobject_cast<QGLShader *>(sender()); - if (shader && !d->removingShaders) - removeShader(shader); -} - - -#undef ctx -#undef context - -/*! - Returns \c true if shader programs of type \a type are supported on - this system; false otherwise. - - The \a context is used to resolve the GLSL extensions. - If \a context is \nullptr, then QGLContext::currentContext() is - used. - - \since 4.7 -*/ -bool QGLShader::hasOpenGLShaders(ShaderType type, const QGLContext *context) -{ - if (!context) - context = QGLContext::currentContext(); - if (!context) - return false; - - if ((type & ~(Geometry | Vertex | Fragment)) || type == 0) - return false; - - QOpenGLFunctions functions(context->contextHandle()); - bool resolved = functions.hasOpenGLFeature(QOpenGLFunctions::Shaders); - if (!resolved) - return false; - - if ((type & Geometry) && !QByteArray((const char *) functions.glGetString(GL_EXTENSIONS)).contains("GL_EXT_geometry_shader4")) - return false; - - return true; -} - -QT_END_NAMESPACE diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h deleted file mode 100644 index 3ce88197d2..0000000000 --- a/src/opengl/qglshaderprogram.h +++ /dev/null @@ -1,303 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLSHADERPROGRAM_H -#define QGLSHADERPROGRAM_H - -#include <QtOpenGL/qgl.h> -#include <QtGui/qvector2d.h> -#include <QtGui/qvector3d.h> -#include <QtGui/qvector4d.h> -#include <QtGui/qmatrix4x4.h> - -QT_BEGIN_NAMESPACE - - -class QGLShaderProgram; -class QGLShaderPrivate; - -class Q_OPENGL_EXPORT QGLShader : public QObject -{ - Q_OBJECT -public: - enum ShaderTypeBit - { - Vertex = 0x0001, - Fragment = 0x0002, - Geometry = 0x0004 - }; - Q_DECLARE_FLAGS(ShaderType, ShaderTypeBit) - - explicit QGLShader(QGLShader::ShaderType type, QObject *parent = nullptr); - QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent = nullptr); - virtual ~QGLShader(); - - QGLShader::ShaderType shaderType() const; - - bool compileSourceCode(const char *source); - bool compileSourceCode(const QByteArray& source); - bool compileSourceCode(const QString& source); - bool compileSourceFile(const QString& fileName); - - QByteArray sourceCode() const; - - bool isCompiled() const; - QString log() const; - - GLuint shaderId() const; - - static bool hasOpenGLShaders(ShaderType type, const QGLContext *context = nullptr); - -private: - friend class QGLShaderProgram; - - Q_DISABLE_COPY(QGLShader) - Q_DECLARE_PRIVATE(QGLShader) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QGLShader::ShaderType) - - -class QGLShaderProgramPrivate; - -class Q_OPENGL_EXPORT QGLShaderProgram : public QObject -{ - Q_OBJECT -public: - explicit QGLShaderProgram(QObject *parent = nullptr); - explicit QGLShaderProgram(const QGLContext *context, QObject *parent = nullptr); - virtual ~QGLShaderProgram(); - - bool addShader(QGLShader *shader); - void removeShader(QGLShader *shader); - QList<QGLShader *> shaders() const; - - bool addShaderFromSourceCode(QGLShader::ShaderType type, const char *source); - bool addShaderFromSourceCode(QGLShader::ShaderType type, const QByteArray& source); - bool addShaderFromSourceCode(QGLShader::ShaderType type, const QString& source); - bool addShaderFromSourceFile(QGLShader::ShaderType type, const QString& fileName); - - void removeAllShaders(); - - virtual bool link(); - bool isLinked() const; - QString log() const; - - bool bind(); - void release(); - - GLuint programId() const; - - int maxGeometryOutputVertices() const; - - void setGeometryOutputVertexCount(int count); - int geometryOutputVertexCount() const; - - void setGeometryInputType(GLenum inputType); - GLenum geometryInputType() const; - - void setGeometryOutputType(GLenum outputType); - GLenum geometryOutputType() const; - - void bindAttributeLocation(const char *name, int location); - void bindAttributeLocation(const QByteArray& name, int location); - void bindAttributeLocation(const QString& name, int location); - - int attributeLocation(const char *name) const; - int attributeLocation(const QByteArray& name) const; - int attributeLocation(const QString& name) const; - - void setAttributeValue(int location, GLfloat value); - void setAttributeValue(int location, GLfloat x, GLfloat y); - void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z); - void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void setAttributeValue(int location, const QVector2D& value); - void setAttributeValue(int location, const QVector3D& value); - void setAttributeValue(int location, const QVector4D& value); - void setAttributeValue(int location, const QColor& value); - void setAttributeValue(int location, const GLfloat *values, int columns, int rows); - - void setAttributeValue(const char *name, GLfloat value); - void setAttributeValue(const char *name, GLfloat x, GLfloat y); - void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z); - void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void setAttributeValue(const char *name, const QVector2D& value); - void setAttributeValue(const char *name, const QVector3D& value); - void setAttributeValue(const char *name, const QVector4D& value); - void setAttributeValue(const char *name, const QColor& value); - void setAttributeValue(const char *name, const GLfloat *values, int columns, int rows); - - void setAttributeArray - (int location, const GLfloat *values, int tupleSize, int stride = 0); - void setAttributeArray - (int location, const QVector2D *values, int stride = 0); - void setAttributeArray - (int location, const QVector3D *values, int stride = 0); - void setAttributeArray - (int location, const QVector4D *values, int stride = 0); - void setAttributeArray - (int location, GLenum type, const void *values, int tupleSize, int stride = 0); - void setAttributeArray - (const char *name, const GLfloat *values, int tupleSize, int stride = 0); - void setAttributeArray - (const char *name, const QVector2D *values, int stride = 0); - void setAttributeArray - (const char *name, const QVector3D *values, int stride = 0); - void setAttributeArray - (const char *name, const QVector4D *values, int stride = 0); - void setAttributeArray - (const char *name, GLenum type, const void *values, int tupleSize, int stride = 0); - - void setAttributeBuffer - (int location, GLenum type, int offset, int tupleSize, int stride = 0); - void setAttributeBuffer - (const char *name, GLenum type, int offset, int tupleSize, int stride = 0); - - void enableAttributeArray(int location); - void enableAttributeArray(const char *name); - void disableAttributeArray(int location); - void disableAttributeArray(const char *name); - - int uniformLocation(const char *name) const; - int uniformLocation(const QByteArray& name) const; - int uniformLocation(const QString& name) const; - - void setUniformValue(int location, GLfloat value); - void setUniformValue(int location, GLint value); - void setUniformValue(int location, GLuint value); - void setUniformValue(int location, GLfloat x, GLfloat y); - void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z); - void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void setUniformValue(int location, const QVector2D& value); - void setUniformValue(int location, const QVector3D& value); - void setUniformValue(int location, const QVector4D& value); - void setUniformValue(int location, const QColor& color); - void setUniformValue(int location, const QPoint& point); - void setUniformValue(int location, const QPointF& point); - void setUniformValue(int location, const QSize& size); - void setUniformValue(int location, const QSizeF& size); - void setUniformValue(int location, const QMatrix2x2& value); - void setUniformValue(int location, const QMatrix2x3& value); - void setUniformValue(int location, const QMatrix2x4& value); - void setUniformValue(int location, const QMatrix3x2& value); - void setUniformValue(int location, const QMatrix3x3& value); - void setUniformValue(int location, const QMatrix3x4& value); - void setUniformValue(int location, const QMatrix4x2& value); - void setUniformValue(int location, const QMatrix4x3& value); - void setUniformValue(int location, const QMatrix4x4& value); - void setUniformValue(int location, const GLfloat value[2][2]); - void setUniformValue(int location, const GLfloat value[3][3]); - void setUniformValue(int location, const GLfloat value[4][4]); - void setUniformValue(int location, const QTransform& value); - - void setUniformValue(const char *name, GLfloat value); - void setUniformValue(const char *name, GLint value); - void setUniformValue(const char *name, GLuint value); - void setUniformValue(const char *name, GLfloat x, GLfloat y); - void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z); - void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void setUniformValue(const char *name, const QVector2D& value); - void setUniformValue(const char *name, const QVector3D& value); - void setUniformValue(const char *name, const QVector4D& value); - void setUniformValue(const char *name, const QColor& color); - void setUniformValue(const char *name, const QPoint& point); - void setUniformValue(const char *name, const QPointF& point); - void setUniformValue(const char *name, const QSize& size); - void setUniformValue(const char *name, const QSizeF& size); - void setUniformValue(const char *name, const QMatrix2x2& value); - void setUniformValue(const char *name, const QMatrix2x3& value); - void setUniformValue(const char *name, const QMatrix2x4& value); - void setUniformValue(const char *name, const QMatrix3x2& value); - void setUniformValue(const char *name, const QMatrix3x3& value); - void setUniformValue(const char *name, const QMatrix3x4& value); - void setUniformValue(const char *name, const QMatrix4x2& value); - void setUniformValue(const char *name, const QMatrix4x3& value); - void setUniformValue(const char *name, const QMatrix4x4& value); - void setUniformValue(const char *name, const GLfloat value[2][2]); - void setUniformValue(const char *name, const GLfloat value[3][3]); - void setUniformValue(const char *name, const GLfloat value[4][4]); - void setUniformValue(const char *name, const QTransform& value); - - void setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize); - void setUniformValueArray(int location, const GLint *values, int count); - void setUniformValueArray(int location, const GLuint *values, int count); - void setUniformValueArray(int location, const QVector2D *values, int count); - void setUniformValueArray(int location, const QVector3D *values, int count); - void setUniformValueArray(int location, const QVector4D *values, int count); - void setUniformValueArray(int location, const QMatrix2x2 *values, int count); - void setUniformValueArray(int location, const QMatrix2x3 *values, int count); - void setUniformValueArray(int location, const QMatrix2x4 *values, int count); - void setUniformValueArray(int location, const QMatrix3x2 *values, int count); - void setUniformValueArray(int location, const QMatrix3x3 *values, int count); - void setUniformValueArray(int location, const QMatrix3x4 *values, int count); - void setUniformValueArray(int location, const QMatrix4x2 *values, int count); - void setUniformValueArray(int location, const QMatrix4x3 *values, int count); - void setUniformValueArray(int location, const QMatrix4x4 *values, int count); - - void setUniformValueArray(const char *name, const GLfloat *values, int count, int tupleSize); - void setUniformValueArray(const char *name, const GLint *values, int count); - void setUniformValueArray(const char *name, const GLuint *values, int count); - void setUniformValueArray(const char *name, const QVector2D *values, int count); - void setUniformValueArray(const char *name, const QVector3D *values, int count); - void setUniformValueArray(const char *name, const QVector4D *values, int count); - void setUniformValueArray(const char *name, const QMatrix2x2 *values, int count); - void setUniformValueArray(const char *name, const QMatrix2x3 *values, int count); - void setUniformValueArray(const char *name, const QMatrix2x4 *values, int count); - void setUniformValueArray(const char *name, const QMatrix3x2 *values, int count); - void setUniformValueArray(const char *name, const QMatrix3x3 *values, int count); - void setUniformValueArray(const char *name, const QMatrix3x4 *values, int count); - void setUniformValueArray(const char *name, const QMatrix4x2 *values, int count); - void setUniformValueArray(const char *name, const QMatrix4x3 *values, int count); - void setUniformValueArray(const char *name, const QMatrix4x4 *values, int count); - - static bool hasOpenGLShaderPrograms(const QGLContext *context = nullptr); - -private Q_SLOTS: - void shaderDestroyed(); - -private: - Q_DISABLE_COPY(QGLShaderProgram) - Q_DECLARE_PRIVATE(QGLShaderProgram) - - bool init(); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/opengl/qgraphicsshadereffect.cpp b/src/opengl/qgraphicsshadereffect.cpp deleted file mode 100644 index 97b83a6b3d..0000000000 --- a/src/opengl/qgraphicsshadereffect.cpp +++ /dev/null @@ -1,272 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgraphicsshadereffect_p.h" - -#include "qglshaderprogram.h" -#include "gl2paintengineex/qglcustomshaderstage_p.h" -#define QGL_HAVE_CUSTOM_SHADERS 1 -#include <QtGui/qpainter.h> -#include <QtWidgets/qgraphicsitem.h> -#include <private/qgraphicseffect_p.h> - -QT_BEGIN_NAMESPACE - -/*# - \class QGraphicsShaderEffect - \inmodule QtOpenGL - \brief The QGraphicsShaderEffect class is the base class for creating - custom GLSL shader effects in a QGraphicsScene. - \since 4.6 - \ingroup multimedia - \ingroup graphicsview-api - - The specific effect is defined by a fragment of GLSL source code - supplied to setPixelShaderFragment(). This source code must define a - function with the signature - \c{lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords)} - that returns the source pixel value - to use in the paint engine's shader program. The shader fragment - is linked with the regular shader code used by the GL2 paint engine - to construct a complete QGLShaderProgram. - - The following example shader converts the incoming pixmap to - grayscale and then applies a colorize operation using the - \c effectColor value: - - \snippet code/src_opengl_qgraphicsshadereffect.cpp 0 - - To use this shader code, it is necessary to define a subclass - of QGraphicsShaderEffect as follows: - - \snippet code/src_opengl_qgraphicsshadereffect.cpp 1 - - The setUniforms() function is called when the effect is about - to be used for drawing to give the subclass the opportunity to - set effect-specific uniform variables. - - QGraphicsShaderEffect is only supported when the GL2 paint engine - is in use. When any other paint engine is in use (GL1, raster, etc), - the drawItem() method will draw its item argument directly with - no effect applied. - - \sa QGraphicsEffect -*/ - -static const char qglslDefaultImageFragmentShader[] = "\ - lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords) { \ - return texture2D(imageTexture, textureCoords); \ - }\n"; - -#ifdef QGL_HAVE_CUSTOM_SHADERS - -class QGLCustomShaderEffectStage : public QGLCustomShaderStage -{ -public: - QGLCustomShaderEffectStage - (QGraphicsShaderEffect *e, const QByteArray& source) - : QGLCustomShaderStage(), - effect(e) - { - setSource(source); - } - - void setUniforms(QGLShaderProgram *program) override; - - QGraphicsShaderEffect *effect; -}; - -void QGLCustomShaderEffectStage::setUniforms(QGLShaderProgram *program) -{ - effect->setUniforms(program); -} - -#endif - -class QGraphicsShaderEffectPrivate : public QGraphicsEffectPrivate -{ - Q_DECLARE_PUBLIC(QGraphicsShaderEffect) -public: - QGraphicsShaderEffectPrivate() - : pixelShaderFragment(qglslDefaultImageFragmentShader) -#ifdef QGL_HAVE_CUSTOM_SHADERS - , customShaderStage(0) -#endif - { - } - - QByteArray pixelShaderFragment; -#ifdef QGL_HAVE_CUSTOM_SHADERS - QGLCustomShaderEffectStage *customShaderStage; -#endif -}; - -/*# - Constructs a shader effect and attaches it to \a parent. -*/ -QGraphicsShaderEffect::QGraphicsShaderEffect(QObject *parent) - : QGraphicsEffect(*new QGraphicsShaderEffectPrivate(), parent) -{ -} - -/*# - Destroys this shader effect. -*/ -QGraphicsShaderEffect::~QGraphicsShaderEffect() -{ -#ifdef QGL_HAVE_CUSTOM_SHADERS - Q_D(QGraphicsShaderEffect); - delete d->customShaderStage; -#endif -} - -/*# - Returns the source code for the pixel shader fragment for - this shader effect. The default is a shader that copies - its incoming pixmap directly to the output with no effect - applied. - - \sa setPixelShaderFragment() -*/ -QByteArray QGraphicsShaderEffect::pixelShaderFragment() const -{ - Q_D(const QGraphicsShaderEffect); - return d->pixelShaderFragment; -} - -/*# - Sets the source code for the pixel shader fragment for - this shader effect to \a code. - - The \a code must define a GLSL function with the signature - \c{lowp vec4 customShader(lowp sampler2D imageTexture, highp vec2 textureCoords)} - that returns the source pixel value to use in the paint engine's - shader program. The following is the default pixel shader fragment, - which draws a pixmap with no effect applied: - - \snippet code/src_opengl_qgraphicsshadereffect.cpp 2 - - \sa pixelShaderFragment(), setUniforms() -*/ -void QGraphicsShaderEffect::setPixelShaderFragment(const QByteArray& code) -{ - Q_D(QGraphicsShaderEffect); - if (d->pixelShaderFragment != code) { - d->pixelShaderFragment = code; -#ifdef QGL_HAVE_CUSTOM_SHADERS - delete d->customShaderStage; - d->customShaderStage = 0; -#endif - } -} - -/*# - \reimp -*/ -void QGraphicsShaderEffect::draw(QPainter *painter) -{ - Q_D(QGraphicsShaderEffect); - -#ifdef QGL_HAVE_CUSTOM_SHADERS - // Set the custom shader on the paint engine. The setOnPainter() - // call may fail if the paint engine is not GL2. In that case, - // we fall through to drawing the pixmap normally. - if (!d->customShaderStage) { - d->customShaderStage = new QGLCustomShaderEffectStage - (this, d->pixelShaderFragment); - } - bool usingShader = d->customShaderStage->setOnPainter(painter); - - QPoint offset; - if (sourceIsPixmap()) { - // No point in drawing in device coordinates (pixmap will be scaled anyways). - const QPixmap pixmap = sourcePixmap(Qt::LogicalCoordinates, &offset); - painter->drawPixmap(offset, pixmap); - } else { - // Draw pixmap in device coordinates to avoid pixmap scaling. - const QPixmap pixmap = sourcePixmap(Qt::DeviceCoordinates, &offset); - QTransform restoreTransform = painter->worldTransform(); - painter->setWorldTransform(QTransform()); - painter->drawPixmap(offset, pixmap); - painter->setWorldTransform(restoreTransform); - } - - // Remove the custom shader to return to normal painting operations. - if (usingShader) - d->customShaderStage->removeFromPainter(painter); -#else - drawSource(painter); -#endif -} - -/*# - Sets the custom uniform variables on this shader effect to - be dirty. The setUniforms() function will be called the next - time the shader program corresponding to this effect is used. - - This function is typically called by subclasses when an - effect-specific parameter is changed by the application. - - \sa setUniforms() -*/ -void QGraphicsShaderEffect::setUniformsDirty() -{ -#ifdef QGL_HAVE_CUSTOM_SHADERS - Q_D(QGraphicsShaderEffect); - if (d->customShaderStage) - d->customShaderStage->setUniformsDirty(); -#endif -} - -/*# - Sets custom uniform variables on the current GL context when - \a program is about to be used by the paint engine. - - This function should be overridden if the shader set with - setPixelShaderFragment() has additional parameters beyond - those that the paint engine normally sets itself. - - \sa setUniformsDirty() -*/ -void QGraphicsShaderEffect::setUniforms(QGLShaderProgram *program) -{ - Q_UNUSED(program); -} - -QT_END_NAMESPACE diff --git a/src/opengl/qgraphicsshadereffect_p.h b/src/opengl/qgraphicsshadereffect_p.h deleted file mode 100644 index 218caa2936..0000000000 --- a/src/opengl/qgraphicsshadereffect_p.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGRAPHICSSHADEREFFECT_P_H -#define QGRAPHICSSHADEREFFECT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtWidgets/qgraphicseffect.h> - -#include <QtOpenGL/qtopenglglobal.h> - -QT_REQUIRE_CONFIG(graphicseffect); - -QT_BEGIN_NAMESPACE - -class QGLShaderProgram; -class QGLCustomShaderEffectStage; -class QGraphicsShaderEffectPrivate; - -class Q_OPENGL_EXPORT QGraphicsShaderEffect : public QGraphicsEffect -{ - Q_OBJECT -public: - QGraphicsShaderEffect(QObject *parent = nullptr); - virtual ~QGraphicsShaderEffect(); - - QByteArray pixelShaderFragment() const; - void setPixelShaderFragment(const QByteArray& code); - -protected: - void draw(QPainter *painter) override; - void setUniformsDirty(); - virtual void setUniforms(QGLShaderProgram *program); - -private: - Q_DECLARE_PRIVATE(QGraphicsShaderEffect) - Q_DISABLE_COPY_MOVE(QGraphicsShaderEffect) - - friend class QGLCustomShaderEffectStage; -}; - -QT_END_NAMESPACE - -#endif // QGRAPHICSSHADEREFFECT_P_H diff --git a/tests/auto/opengl/opengl.pro b/tests/auto/opengl/opengl.pro index 963cda170d..a220deae24 100644 --- a/tests/auto/opengl/opengl.pro +++ b/tests/auto/opengl/opengl.pro @@ -1,6 +1,2 @@ -TEMPLATE=subdirs -SUBDIRS=\ - qgl \ - qglbuffer \ - qglfunctions \ - qglthreads \ +TEMPLATE = subdirs +#SUBDIRS = diff --git a/tests/auto/opengl/qgl/.gitignore b/tests/auto/opengl/qgl/.gitignore deleted file mode 100644 index bb6e921035..0000000000 --- a/tests/auto/opengl/qgl/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tst_qgl diff --git a/tests/auto/opengl/qgl/BLACKLIST b/tests/auto/opengl/qgl/BLACKLIST deleted file mode 100644 index ec75ea16eb..0000000000 --- a/tests/auto/opengl/qgl/BLACKLIST +++ /dev/null @@ -1,8 +0,0 @@ -[graphicsViewClipping] -ubuntu-16.04 -rhel-7.6 -opensuse-leap -ubuntu-18.04 -rhel-7.4 -opensuse-42.3 - diff --git a/tests/auto/opengl/qgl/qgl.pro b/tests/auto/opengl/qgl/qgl.pro deleted file mode 100644 index af930c5be7..0000000000 --- a/tests/auto/opengl/qgl/qgl.pro +++ /dev/null @@ -1,11 +0,0 @@ -############################################################ -# Project file for autotest for file qgl.h -############################################################ - -CONFIG += testcase -TARGET = tst_qgl -requires(qtHaveModule(opengl)) -QT += widgets widgets-private opengl-private gui-private core-private testlib - -SOURCES += tst_qgl.cpp -RESOURCES = qgl.qrc diff --git a/tests/auto/opengl/qgl/qgl.qrc b/tests/auto/opengl/qgl/qgl.qrc deleted file mode 100644 index 70f425c1b9..0000000000 --- a/tests/auto/opengl/qgl/qgl.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<!DOCTYPE RCC><RCC version="1.0"> -<qresource> - <file alias="designer.png">../../gui/image/qpixmap/images/designer.png</file> -</qresource> -</RCC> diff --git a/tests/auto/opengl/qgl/tst_qgl.cpp b/tests/auto/opengl/qgl/tst_qgl.cpp deleted file mode 100644 index 3cc9592fb1..0000000000 --- a/tests/auto/opengl/qgl/tst_qgl.cpp +++ /dev/null @@ -1,2524 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include <QtTest/QtTest> - -#include <qcoreapplication.h> -#include <qdebug.h> -#include <qgl.h> -#include <qglpixelbuffer.h> -#include <qglframebufferobject.h> -#include <qglcolormap.h> -#include <qpaintengine.h> -#include <qopenglfunctions.h> -#include <qopenglframebufferobject.h> -#include <qopenglpaintdevice.h> - -#include <QGraphicsView> -#include <QGraphicsProxyWidget> -#include <QVBoxLayout> - -#ifdef QT_BUILD_INTERNAL -#include <qpa/qplatformpixmap.h> -#include <QtOpenGL/private/qgl_p.h> -#include <QtGui/private/qimage_p.h> -#include <QtGui/private/qimagepixmapcleanuphooks_p.h> -#include <QtGui/private/qopenglextensions_p.h> -#endif - -class tst_QGL : public QObject -{ -Q_OBJECT - -public: - tst_QGL(); - virtual ~tst_QGL(); - - static void initMain(); - -private slots: - void initTestCase(); - void getSetCheck(); -#ifdef QT_BUILD_INTERNAL - void qglContextDefaultBindTexture(); - void openGLVersionCheck(); - void shareRegister(); - void textureCleanup(); -#endif - void partialGLWidgetUpdates_data(); - void partialGLWidgetUpdates(); - void glWidgetWithAlpha(); - void glWidgetRendering(); - void glFBOSimpleRendering(); - void glFBORendering(); - void currentFboSync(); - void multipleFBOInterleavedRendering(); - void glFBOUseInGLWidget(); - void glPBufferRendering(); - void glWidgetReparent(); - void glWidgetRenderPixmap(); - void colormap(); - void fboFormat(); - void testDontCrashOnDanglingResources(); - void replaceClipping(); - void clipTest(); - void destroyFBOAfterContext(); - void threadImages(); - void nullRectCrash(); - void graphicsViewClipping(); - void extensions(); -}; - -tst_QGL::tst_QGL() -{ -} - -tst_QGL::~tst_QGL() -{ -} - -void tst_QGL::initMain() -{ - QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); -} - -void tst_QGL::initTestCase() -{ - QGLWidget glWidget; - if (!glWidget.isValid()) - QSKIP("QGL is not supported on the test system"); -} - -class MyGLContext : public QGLContext -{ -public: - MyGLContext(const QGLFormat& format) : QGLContext(format) {} - bool windowCreated() const { return QGLContext::windowCreated(); } - void setWindowCreated(bool on) { QGLContext::setWindowCreated(on); } - bool initialized() const { return QGLContext::initialized(); } - void setInitialized(bool on) { QGLContext::setInitialized(on); } -}; - -class MyGLWidget : public QGLWidget -{ -public: - MyGLWidget() : QGLWidget() {} - bool autoBufferSwap() const { return QGLWidget::autoBufferSwap(); } - void setAutoBufferSwap(bool on) { QGLWidget::setAutoBufferSwap(on); } -}; - -static int appDefaultDepth() -{ - static int depth = 0; - if (depth == 0) { - QPixmap pm(1, 1); - depth = pm.depth(); - } - return depth; -} - -// Using INT_MIN and INT_MAX will cause failures on systems -// where "int" is 64-bit, so use the explicit values instead. -#define TEST_INT_MIN (-2147483647 - 1) -#define TEST_INT_MAX 2147483647 - -// Testing get/set functions -void tst_QGL::getSetCheck() -{ - QGLFormat obj1; - // int QGLFormat::depthBufferSize() - // void QGLFormat::setDepthBufferSize(int) - QCOMPARE(-1, obj1.depthBufferSize()); - obj1.setDepthBufferSize(0); - QCOMPARE(0, obj1.depthBufferSize()); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size -2147483648"); - obj1.setDepthBufferSize(TEST_INT_MIN); - QCOMPARE(0, obj1.depthBufferSize()); // Makes no sense with a negative buffer size - obj1.setDepthBufferSize(3); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setDepthBufferSize: Cannot set negative depth buffer size -1"); - obj1.setDepthBufferSize(-1); - QCOMPARE(3, obj1.depthBufferSize()); - obj1.setDepthBufferSize(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.depthBufferSize()); - - // int QGLFormat::accumBufferSize() - // void QGLFormat::setAccumBufferSize(int) - QCOMPARE(-1, obj1.accumBufferSize()); - obj1.setAccumBufferSize(0); - QCOMPARE(0, obj1.accumBufferSize()); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size -2147483648"); - obj1.setAccumBufferSize(TEST_INT_MIN); - QCOMPARE(0, obj1.accumBufferSize()); // Makes no sense with a negative buffer size - obj1.setAccumBufferSize(3); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAccumBufferSize: Cannot set negative accumulate buffer size -1"); - obj1.setAccumBufferSize(-1); - QCOMPARE(3, obj1.accumBufferSize()); - obj1.setAccumBufferSize(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.accumBufferSize()); - - // int QGLFormat::redBufferSize() - // void QGLFormat::setRedBufferSize(int) - QCOMPARE(-1, obj1.redBufferSize()); - obj1.setRedBufferSize(0); - QCOMPARE(0, obj1.redBufferSize()); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setRedBufferSize: Cannot set negative red buffer size -2147483648"); - obj1.setRedBufferSize(TEST_INT_MIN); - QCOMPARE(0, obj1.redBufferSize()); // Makes no sense with a negative buffer size - obj1.setRedBufferSize(3); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setRedBufferSize: Cannot set negative red buffer size -1"); - obj1.setRedBufferSize(-1); - QCOMPARE(3, obj1.redBufferSize()); - obj1.setRedBufferSize(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.redBufferSize()); - - // int QGLFormat::greenBufferSize() - // void QGLFormat::setGreenBufferSize(int) - QCOMPARE(-1, obj1.greenBufferSize()); - obj1.setGreenBufferSize(0); - QCOMPARE(0, obj1.greenBufferSize()); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setGreenBufferSize: Cannot set negative green buffer size -2147483648"); - obj1.setGreenBufferSize(TEST_INT_MIN); - QCOMPARE(0, obj1.greenBufferSize()); // Makes no sense with a negative buffer size - obj1.setGreenBufferSize(3); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setGreenBufferSize: Cannot set negative green buffer size -1"); - obj1.setGreenBufferSize(-1); - QCOMPARE(3, obj1.greenBufferSize()); - obj1.setGreenBufferSize(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.greenBufferSize()); - - // int QGLFormat::blueBufferSize() - // void QGLFormat::setBlueBufferSize(int) - QCOMPARE(-1, obj1.blueBufferSize()); - obj1.setBlueBufferSize(0); - QCOMPARE(0, obj1.blueBufferSize()); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setBlueBufferSize: Cannot set negative blue buffer size -2147483648"); - obj1.setBlueBufferSize(TEST_INT_MIN); - QCOMPARE(0, obj1.blueBufferSize()); // Makes no sense with a negative buffer size - obj1.setBlueBufferSize(3); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setBlueBufferSize: Cannot set negative blue buffer size -1"); - obj1.setBlueBufferSize(-1); - QCOMPARE(3, obj1.blueBufferSize()); - obj1.setBlueBufferSize(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.blueBufferSize()); - - // int QGLFormat::alphaBufferSize() - // void QGLFormat::setAlphaBufferSize(int) - QCOMPARE(-1, obj1.alphaBufferSize()); - QCOMPARE(false, obj1.alpha()); - QVERIFY(!obj1.testOption(QGL::AlphaChannel)); - QVERIFY(obj1.testOption(QGL::NoAlphaChannel)); - obj1.setAlphaBufferSize(1); - QCOMPARE(true, obj1.alpha()); // setAlphaBufferSize() enables alpha. - QCOMPARE(1, obj1.alphaBufferSize()); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size -2147483648"); - obj1.setAlphaBufferSize(TEST_INT_MIN); - QCOMPARE(1, obj1.alphaBufferSize()); // Makes no sense with a negative buffer size - obj1.setAlphaBufferSize(3); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setAlphaBufferSize: Cannot set negative alpha buffer size -1"); - obj1.setAlphaBufferSize(-1); - QCOMPARE(3, obj1.alphaBufferSize()); - obj1.setAlphaBufferSize(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.alphaBufferSize()); - - // int QGLFormat::stencilBufferSize() - // void QGLFormat::setStencilBufferSize(int) - QCOMPARE(-1, obj1.stencilBufferSize()); - obj1.setStencilBufferSize(1); - QCOMPARE(1, obj1.stencilBufferSize()); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size -2147483648"); - obj1.setStencilBufferSize(TEST_INT_MIN); - QCOMPARE(1, obj1.stencilBufferSize()); // Makes no sense with a negative buffer size - obj1.setStencilBufferSize(3); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setStencilBufferSize: Cannot set negative stencil buffer size -1"); - obj1.setStencilBufferSize(-1); - QCOMPARE(3, obj1.stencilBufferSize()); - obj1.setStencilBufferSize(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.stencilBufferSize()); - - // bool QGLFormat::sampleBuffers() - // void QGLFormat::setSampleBuffers(bool) - QCOMPARE(false, obj1.sampleBuffers()); - QVERIFY(!obj1.testOption(QGL::SampleBuffers)); - QVERIFY(obj1.testOption(QGL::NoSampleBuffers)); - - obj1.setSampleBuffers(false); - QCOMPARE(false, obj1.sampleBuffers()); - QVERIFY(obj1.testOption(QGL::NoSampleBuffers)); - obj1.setSampleBuffers(true); - QCOMPARE(true, obj1.sampleBuffers()); - QVERIFY(obj1.testOption(QGL::SampleBuffers)); - - // int QGLFormat::samples() - // void QGLFormat::setSamples(int) - QCOMPARE(-1, obj1.samples()); - obj1.setSamples(0); - QCOMPARE(0, obj1.samples()); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setSamples: Cannot have negative number of samples per pixel -2147483648"); - obj1.setSamples(TEST_INT_MIN); - QCOMPARE(0, obj1.samples()); // Makes no sense with a negative sample size - obj1.setSamples(3); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setSamples: Cannot have negative number of samples per pixel -1"); - obj1.setSamples(-1); - QCOMPARE(3, obj1.samples()); - obj1.setSamples(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.samples()); - - // int QGLFormat::swapInterval() - // void QGLFormat::setSwapInterval(int) - QCOMPARE(-1, obj1.swapInterval()); - obj1.setSwapInterval(0); - QCOMPARE(0, obj1.swapInterval()); - obj1.setSwapInterval(TEST_INT_MIN); - QCOMPARE(TEST_INT_MIN, obj1.swapInterval()); - obj1.setSwapInterval(-1); - QCOMPARE(-1, obj1.swapInterval()); - obj1.setSwapInterval(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.swapInterval()); - - // bool QGLFormat::doubleBuffer() - // void QGLFormat::setDoubleBuffer(bool) - QCOMPARE(true, obj1.doubleBuffer()); - QVERIFY(obj1.testOption(QGL::DoubleBuffer)); - QVERIFY(!obj1.testOption(QGL::SingleBuffer)); - obj1.setDoubleBuffer(false); - QCOMPARE(false, obj1.doubleBuffer()); - QVERIFY(!obj1.testOption(QGL::DoubleBuffer)); - QVERIFY(obj1.testOption(QGL::SingleBuffer)); - obj1.setDoubleBuffer(true); - QCOMPARE(true, obj1.doubleBuffer()); - QVERIFY(obj1.testOption(QGL::DoubleBuffer)); - QVERIFY(!obj1.testOption(QGL::SingleBuffer)); - - // bool QGLFormat::depth() - // void QGLFormat::setDepth(bool) - QCOMPARE(true, obj1.depth()); - QVERIFY(obj1.testOption(QGL::DepthBuffer)); - QVERIFY(!obj1.testOption(QGL::NoDepthBuffer)); - obj1.setDepth(false); - QCOMPARE(false, obj1.depth()); - QVERIFY(!obj1.testOption(QGL::DepthBuffer)); - QVERIFY(obj1.testOption(QGL::NoDepthBuffer)); - obj1.setDepth(true); - QCOMPARE(true, obj1.depth()); - QVERIFY(obj1.testOption(QGL::DepthBuffer)); - QVERIFY(!obj1.testOption(QGL::NoDepthBuffer)); - - // bool QGLFormat::rgba() - // void QGLFormat::setRgba(bool) - QCOMPARE(true, obj1.rgba()); - QVERIFY(obj1.testOption(QGL::Rgba)); - QVERIFY(!obj1.testOption(QGL::ColorIndex)); - obj1.setRgba(false); - QCOMPARE(false, obj1.rgba()); - QVERIFY(!obj1.testOption(QGL::Rgba)); - QVERIFY(obj1.testOption(QGL::ColorIndex)); - obj1.setRgba(true); - QCOMPARE(true, obj1.rgba()); - QVERIFY(obj1.testOption(QGL::Rgba)); - QVERIFY(!obj1.testOption(QGL::ColorIndex)); - - // bool QGLFormat::alpha() - // void QGLFormat::setAlpha(bool) - QVERIFY(obj1.testOption(QGL::AlphaChannel)); - QVERIFY(!obj1.testOption(QGL::NoAlphaChannel)); - obj1.setAlpha(false); - QCOMPARE(false, obj1.alpha()); - QVERIFY(!obj1.testOption(QGL::AlphaChannel)); - QVERIFY(obj1.testOption(QGL::NoAlphaChannel)); - obj1.setAlpha(true); - QCOMPARE(true, obj1.alpha()); - QVERIFY(obj1.testOption(QGL::AlphaChannel)); - QVERIFY(!obj1.testOption(QGL::NoAlphaChannel)); - - // bool QGLFormat::accum() - // void QGLFormat::setAccum(bool) - obj1.setAccumBufferSize(0); - QCOMPARE(false, obj1.accum()); - QVERIFY(!obj1.testOption(QGL::AccumBuffer)); - QVERIFY(obj1.testOption(QGL::NoAccumBuffer)); - obj1.setAccum(false); - QCOMPARE(false, obj1.accum()); - QVERIFY(!obj1.testOption(QGL::AccumBuffer)); - QVERIFY(obj1.testOption(QGL::NoAccumBuffer)); - obj1.setAccum(true); - QCOMPARE(true, obj1.accum()); - QVERIFY(obj1.testOption(QGL::AccumBuffer)); - QVERIFY(!obj1.testOption(QGL::NoAccumBuffer)); - - // bool QGLFormat::stencil() - // void QGLFormat::setStencil(bool) - QCOMPARE(true, obj1.stencil()); - QVERIFY(obj1.testOption(QGL::StencilBuffer)); - QVERIFY(!obj1.testOption(QGL::NoStencilBuffer)); - obj1.setStencil(false); - QCOMPARE(false, obj1.stencil()); - QVERIFY(!obj1.testOption(QGL::StencilBuffer)); - QVERIFY(obj1.testOption(QGL::NoStencilBuffer)); - obj1.setStencil(true); - QCOMPARE(true, obj1.stencil()); - QVERIFY(obj1.testOption(QGL::StencilBuffer)); - QVERIFY(!obj1.testOption(QGL::NoStencilBuffer)); - - // bool QGLFormat::stereo() - // void QGLFormat::setStereo(bool) - QCOMPARE(false, obj1.stereo()); - QVERIFY(!obj1.testOption(QGL::StereoBuffers)); - QVERIFY(obj1.testOption(QGL::NoStereoBuffers)); - obj1.setStereo(false); - QCOMPARE(false, obj1.stereo()); - QVERIFY(!obj1.testOption(QGL::StereoBuffers)); - QVERIFY(obj1.testOption(QGL::NoStereoBuffers)); - obj1.setStereo(true); - QCOMPARE(true, obj1.stereo()); - QVERIFY(obj1.testOption(QGL::StereoBuffers)); - QVERIFY(!obj1.testOption(QGL::NoStereoBuffers)); - - // bool QGLFormat::directRendering() - // void QGLFormat::setDirectRendering(bool) - QCOMPARE(true, obj1.directRendering()); - QVERIFY(obj1.testOption(QGL::DirectRendering)); - QVERIFY(!obj1.testOption(QGL::IndirectRendering)); - obj1.setDirectRendering(false); - QCOMPARE(false, obj1.directRendering()); - QVERIFY(!obj1.testOption(QGL::DirectRendering)); - QVERIFY(obj1.testOption(QGL::IndirectRendering)); - obj1.setDirectRendering(true); - QCOMPARE(true, obj1.directRendering()); - QVERIFY(obj1.testOption(QGL::DirectRendering)); - QVERIFY(!obj1.testOption(QGL::IndirectRendering)); - - // bool QGLFormat::overlay() - // void QGLFormat::setOverlay(bool) - QCOMPARE(false, obj1.hasOverlay()); - QVERIFY(!obj1.testOption(QGL::HasOverlay)); - QVERIFY(obj1.testOption(QGL::NoOverlay)); - obj1.setOverlay(false); - QCOMPARE(false, obj1.hasOverlay()); - QVERIFY(!obj1.testOption(QGL::HasOverlay)); - QVERIFY(obj1.testOption(QGL::NoOverlay)); - obj1.setOverlay(true); - QCOMPARE(true, obj1.hasOverlay()); - QVERIFY(obj1.testOption(QGL::HasOverlay)); - QVERIFY(!obj1.testOption(QGL::NoOverlay)); - - // int QGLFormat::plane() - // void QGLFormat::setPlane(int) - QCOMPARE(0, obj1.plane()); - obj1.setPlane(0); - QCOMPARE(0, obj1.plane()); - obj1.setPlane(TEST_INT_MIN); - QCOMPARE(TEST_INT_MIN, obj1.plane()); - obj1.setPlane(TEST_INT_MAX); - QCOMPARE(TEST_INT_MAX, obj1.plane()); - - // int QGLFormat::major/minorVersion() - // void QGLFormat::setVersion(int, int) - QCOMPARE(obj1.majorVersion(), 2); - QCOMPARE(obj1.minorVersion(), 0); - obj1.setVersion(3, 2); - QCOMPARE(obj1.majorVersion(), 3); - QCOMPARE(obj1.minorVersion(), 2); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setVersion: Cannot set zero or negative version number 0.1"); - obj1.setVersion(0, 1); - QCOMPARE(obj1.majorVersion(), 3); - QCOMPARE(obj1.minorVersion(), 2); - QTest::ignoreMessage(QtWarningMsg, "QGLFormat::setVersion: Cannot set zero or negative version number 3.-1"); - obj1.setVersion(3, -1); - QCOMPARE(obj1.majorVersion(), 3); - QCOMPARE(obj1.minorVersion(), 2); - obj1.setVersion(TEST_INT_MAX, TEST_INT_MAX - 1); - QCOMPARE(obj1.majorVersion(), TEST_INT_MAX); - QCOMPARE(obj1.minorVersion(), TEST_INT_MAX - 1); - - - // operator== and operator!= for QGLFormat - QGLFormat format1; - QGLFormat format2; - - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - format1.setDoubleBuffer(false); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setDoubleBuffer(false); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setDepthBufferSize(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setDepthBufferSize(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setAccumBufferSize(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setAccumBufferSize(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setRedBufferSize(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setRedBufferSize(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setGreenBufferSize(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setGreenBufferSize(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setBlueBufferSize(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setBlueBufferSize(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setAlphaBufferSize(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setAlphaBufferSize(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setStencilBufferSize(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setStencilBufferSize(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setSamples(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setSamples(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setSwapInterval(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setSwapInterval(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setPlane(8); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setPlane(8); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setVersion(3, 2); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setVersion(3, 2); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setProfile(QGLFormat::CoreProfile); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setProfile(QGLFormat::CoreProfile); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - format1.setOption(QGL::NoDeprecatedFunctions); - QVERIFY(!(format1 == format2)); - QVERIFY(format1 != format2); - format2.setOption(QGL::NoDeprecatedFunctions); - QCOMPARE(format1, format2); - QVERIFY(!(format1 != format2)); - - // Copy constructor and assignment for QGLFormat. - QGLFormat format3(format1); - QGLFormat format4; - QCOMPARE(format1, format3); - QVERIFY(format1 != format4); - format4 = format1; - QCOMPARE(format1, format4); - - // Check that modifying a copy doesn't affect the original. - format3.setRedBufferSize(16); - format4.setPlane(16); - QCOMPARE(format1.redBufferSize(), 8); - QCOMPARE(format1.plane(), 8); - - // Check the QGLFormat constructor that takes an option list. - QGLFormat format5 - (QGL::DepthBuffer | QGL::StereoBuffers | QGL::ColorIndex, 3); - QVERIFY(format5.depth()); - QVERIFY(format5.stereo()); - QVERIFY(format5.doubleBuffer()); // From defaultFormat() - QVERIFY(!format5.hasOverlay()); // From defaultFormat() - QVERIFY(!format5.rgba()); - QCOMPARE(format5.plane(), 3); - - // The default format should be the same as QGLFormat(). - QCOMPARE(QGLFormat::defaultFormat(), QGLFormat()); - - // Modify the default format and check that it was changed. - QGLFormat::setDefaultFormat(format1); - QCOMPARE(QGLFormat::defaultFormat(), format1); - - // Restore the default format. - QGLFormat::setDefaultFormat(QGLFormat()); - QCOMPARE(QGLFormat::defaultFormat(), QGLFormat()); - - // Check the default overlay format's expected values. - QGLFormat overlay(QGLFormat::defaultOverlayFormat()); - QCOMPARE(overlay.depthBufferSize(), -1); - QCOMPARE(overlay.accumBufferSize(), -1); - QCOMPARE(overlay.redBufferSize(), -1); - QCOMPARE(overlay.greenBufferSize(), -1); - QCOMPARE(overlay.blueBufferSize(), -1); - QCOMPARE(overlay.alphaBufferSize(), -1); - QCOMPARE(overlay.samples(), -1); - QCOMPARE(overlay.swapInterval(), -1); - QCOMPARE(overlay.plane(), 1); - QVERIFY(!overlay.sampleBuffers()); - QVERIFY(!overlay.doubleBuffer()); - QVERIFY(!overlay.depth()); - QVERIFY(!overlay.rgba()); - QVERIFY(!overlay.alpha()); - QVERIFY(!overlay.accum()); - QVERIFY(!overlay.stencil()); - QVERIFY(!overlay.stereo()); - QVERIFY(overlay.directRendering()); // Only option that should be on. - QVERIFY(!overlay.hasOverlay()); // Overlay doesn't need an overlay! - - // Modify the default overlay format and check that it was changed. - QGLFormat::setDefaultOverlayFormat(format1); - QCOMPARE(QGLFormat::defaultOverlayFormat(), format1); - - // Restore the default overlay format. - QGLFormat::setDefaultOverlayFormat(overlay); - QCOMPARE(QGLFormat::defaultOverlayFormat(), overlay); - - MyGLContext obj2(obj1); - // bool QGLContext::windowCreated() - // void QGLContext::setWindowCreated(bool) - obj2.setWindowCreated(false); - QCOMPARE(false, obj2.windowCreated()); - obj2.setWindowCreated(true); - QCOMPARE(true, obj2.windowCreated()); - - // bool QGLContext::initialized() - // void QGLContext::setInitialized(bool) - obj2.setInitialized(false); - QCOMPARE(false, obj2.initialized()); - obj2.setInitialized(true); - QCOMPARE(true, obj2.initialized()); - - MyGLWidget obj3; - // bool QGLWidget::autoBufferSwap() - // void QGLWidget::setAutoBufferSwap(bool) - obj3.setAutoBufferSwap(false); - QCOMPARE(false, obj3.autoBufferSwap()); - obj3.setAutoBufferSwap(true); - QCOMPARE(true, obj3.autoBufferSwap()); -} - -#ifdef QT_BUILD_INTERNAL -QT_BEGIN_NAMESPACE -extern QGLFormat::OpenGLVersionFlags qOpenGLVersionFlagsFromString(const QString &versionString); -QT_END_NAMESPACE -#endif - -#ifdef QT_BUILD_INTERNAL -void tst_QGL::openGLVersionCheck() -{ - QString versionString; - QGLFormat::OpenGLVersionFlags expectedFlag; - QGLFormat::OpenGLVersionFlags versionFlag; - - versionString = "1.1 Irix 6.5"; - expectedFlag = QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "1.2 Microsoft"; - expectedFlag = QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "1.2.1"; - expectedFlag = QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "1.3 NVIDIA"; - expectedFlag = QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "1.4"; - expectedFlag = QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "1.5 NVIDIA"; - expectedFlag = QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "2.0.2 NVIDIA 87.62"; - expectedFlag = QGLFormat::OpenGL_Version_2_0 | QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "2.1 NVIDIA"; - expectedFlag = QGLFormat::OpenGL_Version_2_1 | QGLFormat::OpenGL_Version_2_0 | QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "2.1"; - expectedFlag = QGLFormat::OpenGL_Version_2_1 | QGLFormat::OpenGL_Version_2_0 | QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "OpenGL ES-CM 1.0 ATI"; - expectedFlag = QGLFormat::OpenGL_ES_Common_Version_1_0 | QGLFormat::OpenGL_ES_CommonLite_Version_1_0; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "OpenGL ES-CL 1.0 ATI"; - expectedFlag = QGLFormat::OpenGL_ES_CommonLite_Version_1_0; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "OpenGL ES-CM 1.1 ATI"; - expectedFlag = QGLFormat::OpenGL_ES_Common_Version_1_1 | QGLFormat::OpenGL_ES_CommonLite_Version_1_1 | QGLFormat::OpenGL_ES_Common_Version_1_0 | QGLFormat::OpenGL_ES_CommonLite_Version_1_0; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "OpenGL ES-CL 1.1 ATI"; - expectedFlag = QGLFormat::OpenGL_ES_CommonLite_Version_1_1 | QGLFormat::OpenGL_ES_CommonLite_Version_1_0; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "OpenGL ES 2.0 ATI"; - expectedFlag = QGLFormat::OpenGL_ES_Version_2_0; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - versionString = "3.0"; - expectedFlag = QGLFormat::OpenGL_Version_3_0 | QGLFormat::OpenGL_Version_2_1 | QGLFormat::OpenGL_Version_2_0 | QGLFormat::OpenGL_Version_1_5 | QGLFormat::OpenGL_Version_1_4 | QGLFormat::OpenGL_Version_1_3 | QGLFormat::OpenGL_Version_1_2 | QGLFormat::OpenGL_Version_1_1; - versionFlag = qOpenGLVersionFlagsFromString(versionString); - QCOMPARE(versionFlag, expectedFlag); - - QGLWidget glWidget; - glWidget.show(); - glWidget.makeCurrent(); - - // This is unfortunately the only test we can make on the actual openGLVersionFlags() - // However, the complicated parts are in openGLVersionFlags(const QString &versionString) - // tested above - -#if defined(QT_OPENGL_ES_2) - QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0); -#else - if (QOpenGLContext::currentContext()->isOpenGLES()) - QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0); - else - QVERIFY(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_1); -#endif //defined(QT_OPENGL_ES_2) -} -#endif //QT_BUILD_INTERNAL - -static bool fuzzyComparePixels(const QRgb testPixel, const QRgb refPixel, const char* file, int line, int x = -1, int y = -1) -{ - static int maxFuzz = 1; - static bool maxFuzzSet = false; - - // On 16 bpp systems, we need to allow for more fuzz: - if (!maxFuzzSet) { - maxFuzzSet = true; - if (appDefaultDepth() < 24) - maxFuzz = 32; - } - - int redFuzz = qAbs(qRed(testPixel) - qRed(refPixel)); - int greenFuzz = qAbs(qGreen(testPixel) - qGreen(refPixel)); - int blueFuzz = qAbs(qBlue(testPixel) - qBlue(refPixel)); - int alphaFuzz = qAbs(qAlpha(testPixel) - qAlpha(refPixel)); - - if (refPixel != 0 && testPixel == 0) { - QString msg; - if (x >= 0) { - msg = QString("Test pixel [%1, %2] is null (black) when it should be (%3,%4,%5,%6)") - .arg(x).arg(y) - .arg(qRed(refPixel)).arg(qGreen(refPixel)).arg(qBlue(refPixel)).arg(qAlpha(refPixel)); - } else { - msg = QString("Test pixel is null (black) when it should be (%2,%3,%4,%5)") - .arg(qRed(refPixel)).arg(qGreen(refPixel)).arg(qBlue(refPixel)).arg(qAlpha(refPixel)); - } - - QTest::qFail(msg.toLatin1(), file, line); - return false; - } - - if (redFuzz > maxFuzz || greenFuzz > maxFuzz || blueFuzz > maxFuzz || alphaFuzz > maxFuzz) { - QString msg; - - if (x >= 0) - msg = QString("Pixel [%1,%2]: ").arg(x).arg(y); - else - msg = QString("Pixel "); - - msg += QString("Max fuzz (%1) exceeded: (%2,%3,%4,%5) vs (%6,%7,%8,%9)") - .arg(maxFuzz) - .arg(qRed(testPixel)).arg(qGreen(testPixel)).arg(qBlue(testPixel)).arg(qAlpha(testPixel)) - .arg(qRed(refPixel)).arg(qGreen(refPixel)).arg(qBlue(refPixel)).arg(qAlpha(refPixel)); - QTest::qFail(msg.toLatin1(), file, line); - return false; - } - return true; -} - -static void fuzzyCompareImages(const QImage &testImage, const QImage &referenceImage, const char* file, int line) -{ - QCOMPARE(testImage.width(), referenceImage.width()); - QCOMPARE(testImage.height(), referenceImage.height()); - - for (int y = 0; y < testImage.height(); y++) { - for (int x = 0; x < testImage.width(); x++) { - if (!fuzzyComparePixels(testImage.pixel(x, y), referenceImage.pixel(x, y), file, line, x, y)) { - // Might as well save the images for easier debugging: - referenceImage.save("referenceImage.png"); - testImage.save("testImage.png"); - return; - } - } - } -} - -#define QFUZZY_COMPARE_IMAGES(A,B) \ - fuzzyCompareImages(A, B, __FILE__, __LINE__) - -#define QFUZZY_COMPARE_PIXELS(A,B) \ - fuzzyComparePixels(A, B, __FILE__, __LINE__) - -class UnclippedWidget : public QWidget -{ -public: - bool painted; - - UnclippedWidget() - : painted(false) - { - } - - void paintEvent(QPaintEvent *) - { - QPainter p(this); - p.fillRect(rect().adjusted(-1000, -1000, 1000, 1000), Qt::black); - - painted = true; - } -}; - -void tst_QGL::graphicsViewClipping() -{ - const int size = 64; - UnclippedWidget *widget = new UnclippedWidget; - widget->setFixedSize(size, size); - - QGraphicsScene scene; - - scene.addWidget(widget)->setPos(0, 0); - - QGraphicsView view(&scene); - // Use Qt::Tool as fully decorated windows have a minimum width of 160 on Windows. - view.setWindowFlags(view.windowFlags() | Qt::Tool); - view.setBackgroundBrush(Qt::white); - view.resize(2*size, 2*size); - - QGLWidget *viewport = new QGLWidget; - view.setViewport(viewport); - view.show(); - qApp->setActiveWindow(&view); - - if (!viewport->isValid()) - return; - - scene.setSceneRect(view.viewport()->rect()); - - QVERIFY(QTest::qWaitForWindowExposed(view.viewport()->windowHandle())); - #ifdef Q_OS_MAC - // The black rectangle jumps from the center to the upper left for some reason. - QTest::qWait(100); - #endif - - QTRY_VERIFY(widget->painted); - - QImage image = viewport->grabFrameBuffer(); - QImage expected = image; - - QPainter p(&expected); - p.fillRect(expected.rect(), Qt::white); - p.fillRect(QRect(0, 0, size, size), Qt::black); - p.end(); - - QFUZZY_COMPARE_IMAGES(image, expected); -} - -void tst_QGL::partialGLWidgetUpdates_data() -{ - QTest::addColumn<bool>("doubleBufferedContext"); - QTest::addColumn<bool>("autoFillBackground"); - QTest::addColumn<bool>("supportsPartialUpdates"); - - QTest::newRow("Double buffered context") << true << true << false; - QTest::newRow("Double buffered context without auto-fill background") << true << false << false; - QTest::newRow("Single buffered context") << false << true << false; - QTest::newRow("Single buffered context without auto-fill background") << false << false << true; -} - -void tst_QGL::partialGLWidgetUpdates() -{ - QFETCH(bool, doubleBufferedContext); - QFETCH(bool, autoFillBackground); - QFETCH(bool, supportsPartialUpdates); - - class MyGLWidget : public QGLWidget - { - public: - QRegion paintEventRegion; - void paintEvent(QPaintEvent *e) - { - paintEventRegion = e->region(); - } - }; - - QGLFormat format = QGLFormat::defaultFormat(); - format.setDoubleBuffer(doubleBufferedContext); - QGLFormat::setDefaultFormat(format); - - MyGLWidget widget; - widget.setFixedSize(150, 150); - widget.setAutoFillBackground(autoFillBackground); - widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); - QCoreApplication::processEvents(); // Process all queued paint events - - if (widget.format().doubleBuffer() != doubleBufferedContext) - QSKIP("Platform does not support requested format"); - - widget.paintEventRegion = QRegion(); - widget.repaint(50, 50, 50, 50); - - if (supportsPartialUpdates) - QCOMPARE(widget.paintEventRegion, QRegion(50, 50, 50, 50)); - else - QCOMPARE(widget.paintEventRegion, QRegion(widget.rect())); -} - - -// This tests that rendering to a QGLPBuffer using QPainter works. -void tst_QGL::glPBufferRendering() -{ - if (!QGLPixelBuffer::hasOpenGLPbuffers()) - QSKIP("QGLPixelBuffer not supported on this platform"); - - QGLPixelBuffer* pbuf = new QGLPixelBuffer(128, 128); - - QPainter p; - bool begun = p.begin(pbuf); - QVERIFY(begun); - - QPaintEngine::Type engineType = p.paintEngine()->type(); - QVERIFY(engineType == QPaintEngine::OpenGL || engineType == QPaintEngine::OpenGL2); - - p.fillRect(0, 0, 128, 128, Qt::red); - p.fillRect(32, 32, 64, 64, Qt::blue); - p.end(); - - QImage fb = pbuf->toImage(); - delete pbuf; - - QImage reference(128, 128, fb.format()); - p.begin(&reference); - p.fillRect(0, 0, 128, 128, Qt::red); - p.fillRect(32, 32, 64, 64, Qt::blue); - p.end(); - - QFUZZY_COMPARE_IMAGES(fb, reference); -} - -void tst_QGL::glWidgetWithAlpha() -{ - QGLWidget* w = new QGLWidget(QGLFormat(QGL::AlphaChannel)); - w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); - - delete w; -} - - -void qt_opengl_draw_test_pattern(QPainter* painter, int width, int height) -{ - QPainterPath intersectingPath; - intersectingPath.moveTo(0, 0); - intersectingPath.lineTo(100, 0); - intersectingPath.lineTo(0, 100); - intersectingPath.lineTo(100, 100); - intersectingPath.closeSubpath(); - - QPainterPath trianglePath; - trianglePath.moveTo(50, 0); - trianglePath.lineTo(100, 100); - trianglePath.lineTo(0, 100); - trianglePath.closeSubpath(); - - painter->setTransform(QTransform()); // reset xform - painter->fillRect(-1, -1, width+2, height+2, Qt::red); // Background - painter->translate(14, 14); - painter->fillPath(intersectingPath, Qt::blue); // Test stencil buffer works - painter->translate(128, 0); - painter->setClipPath(trianglePath); // Test depth buffer works - painter->setTransform(QTransform()); // reset xform ready for fill - painter->fillRect(-1, -1, width+2, height+2, Qt::green); -} - -void qt_opengl_check_test_pattern(const QImage& img) -{ - // As we're doing more than trivial painting, we can't just compare to - // an image rendered with raster. Instead, we sample at well-defined - // test-points: - QFUZZY_COMPARE_PIXELS(img.pixel(39, 64), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(img.pixel(89, 64), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(img.pixel(64, 39), QColor(Qt::blue).rgb()); - QFUZZY_COMPARE_PIXELS(img.pixel(64, 89), QColor(Qt::blue).rgb()); - - QFUZZY_COMPARE_PIXELS(img.pixel(167, 39), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(img.pixel(217, 39), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(img.pixel(192, 64), QColor(Qt::green).rgb()); -} - -class GLWidget : public QGLWidget -{ -public: - GLWidget(QWidget* p = 0) - : QGLWidget(p), beginOk(false), engineType(QPaintEngine::MaxUser) {} - bool beginOk; - QPaintEngine::Type engineType; - void paintGL() - { - QPainter p; - beginOk = p.begin(this); - QPaintEngine* pe = p.paintEngine(); - engineType = pe->type(); - - qt_opengl_draw_test_pattern(&p, width(), height()); - - // No p.end() or swap buffers, should be done automatically - } - -}; - -void tst_QGL::glWidgetRendering() -{ - GLWidget w; - w.resize(256, 128); - w.show(); - - QVERIFY(QTest::qWaitForWindowExposed(&w)); - - QVERIFY(w.beginOk); - QVERIFY(w.engineType == QPaintEngine::OpenGL || w.engineType == QPaintEngine::OpenGL2); - -#if defined(Q_OS_QNX) - // glReadPixels reads from the back buffer. On QNX the buffer is not preserved - // after a buffer swap. This is why we have to swap the buffer explicitly before calling - // grabFrameBuffer to retrieve the content of the front buffer. - w.swapBuffers(); -#endif - QImage fb = w.grabFrameBuffer(false); - qt_opengl_check_test_pattern(fb); -} - -void tst_QGL::glFBOSimpleRendering() -{ - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) - QSKIP("QGLFramebufferObject not supported on this platform"); - - QGLWidget glw; - glw.makeCurrent(); - - // No multisample with combined depth/stencil attachment: - QGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QGLFramebufferObject::NoAttachment); - - QGLFramebufferObject *fbo = new QGLFramebufferObject(200, 100, fboFormat); - - fbo->bind(); - - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - funcs->glClearColor(1.0, 0.0, 0.0, 1.0); - funcs->glClear(GL_COLOR_BUFFER_BIT); - funcs->glFinish(); - - QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); - QImage reference(fb.size(), QImage::Format_RGB32); - reference.fill(0xffff0000); - - QFUZZY_COMPARE_IMAGES(fb, reference); - - delete fbo; -} - -// NOTE: This tests that CombinedDepthStencil attachment works by assuming the -// GL2 engine is being used and is implemented the same way as it was when -// this autotest was written. If this is not the case, there may be some -// false-positives: I.e. The test passes when either the depth or stencil -// buffer is actually missing. But that's probably ok anyway. -void tst_QGL::glFBORendering() -{ -#if defined(Q_OS_QNX) - QSKIP("Reading the QGLFramebufferObject is unsupported on this platform"); -#endif - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) - QSKIP("QGLFramebufferObject not supported on this platform"); - - QGLWidget glw; - glw.makeCurrent(); - - // No multisample with combined depth/stencil attachment: - QGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - - // Don't complicate things by using NPOT: - QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat); - - if (fbo->attachment() != QGLFramebufferObject::CombinedDepthStencil) { - delete fbo; - QSKIP("FBOs missing combined depth~stencil support"); - } - - QPainter fboPainter; - bool painterBegun = fboPainter.begin(fbo); - QVERIFY(painterBegun); - - qt_opengl_draw_test_pattern(&fboPainter, fbo->width(), fbo->height()); - - fboPainter.end(); - - QImage fb = fbo->toImage().convertToFormat(QImage::Format_RGB32); - delete fbo; - - qt_opengl_check_test_pattern(fb); -} - -class QOpenGLFramebufferObjectPaintDevice : public QOpenGLPaintDevice -{ -public: - QOpenGLFramebufferObjectPaintDevice(int width, int height) - : QOpenGLPaintDevice(width, height) - , m_fbo(width, height, QOpenGLFramebufferObject::CombinedDepthStencil) - { - } - - void ensureActiveTarget() - { - m_fbo.bind(); - } - - QImage toImage() const - { - return m_fbo.toImage(); - } - -private: - QOpenGLFramebufferObject m_fbo; -}; - -void tst_QGL::currentFboSync() -{ - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) - QSKIP("QGLFramebufferObject not supported on this platform"); - -#if defined(Q_OS_QNX) - QSKIP("Reading the QGLFramebufferObject is unsupported on this platform"); -#endif - - QGLWidget glw; - glw.makeCurrent(); - - // For some reason we offer inter-operatibility between QGL and QOpenGL - // paint engines. (?!) Let's check if the two engines can be used to perform - // drawing in turns on different targets within the same context. - - { - QGLFramebufferObject fbo1(256, 256, QGLFramebufferObject::CombinedDepthStencil); - - QOpenGLFramebufferObjectPaintDevice fbo2(256, 256); - - QImage sourceImage(256, 256, QImage::Format_ARGB32_Premultiplied); - QPainter sourcePainter(&sourceImage); - qt_opengl_draw_test_pattern(&sourcePainter, 256, 256); - - QPainter fbo1Painter(&fbo1); - - QPainter fbo2Painter(&fbo2); - fbo2Painter.drawImage(0, 0, sourceImage); - fbo2Painter.end(); - - QImage fbo2Image = fbo2.toImage(); - - fbo1Painter.drawImage(0, 0, sourceImage); - fbo1Painter.end(); - - QGLFramebufferObject::bindDefault(); - - // Convert the QGLFBO's result since QOpenGLFBO uses a wider - // variety of possible return formats. - QCOMPARE(fbo1.toImage().convertToFormat(fbo2Image.format()), fbo2Image); - } - - { - QGLFramebufferObject fbo1(512, 512, QGLFramebufferObject::CombinedDepthStencil); - - QOpenGLFramebufferObjectPaintDevice fbo2(256, 256); - - QImage sourceImage(256, 256, QImage::Format_ARGB32_Premultiplied); - QPainter sourcePainter(&sourceImage); - qt_opengl_draw_test_pattern(&sourcePainter, 256, 256); - - QPainter fbo2Painter(&fbo2); - fbo2Painter.drawImage(0, 0, sourceImage); - QImage fbo2Image1 = fbo2.toImage(); - fbo2Painter.fillRect(0, 0, 256, 256, Qt::white); - - QPainter fbo1Painter(&fbo1); - fbo1Painter.drawImage(0, 0, sourceImage); - fbo1Painter.end(); - - // check that the OpenGL paint engine now knows it needs to sync - fbo2Painter.drawImage(0, 0, sourceImage); - QImage fbo2Image2 = fbo2.toImage(); - - fbo2Painter.end(); - - QCOMPARE(fbo2Image1, fbo2Image2); - } -} - -// Tests multiple QPainters active on different FBOs at the same time, with -// interleaving painting. Performance-wise, this is sub-optimal, but it still -// has to work flawlessly -void tst_QGL::multipleFBOInterleavedRendering() -{ - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) - QSKIP("QGLFramebufferObject not supported on this platform"); - - QGLWidget glw; - glw.makeCurrent(); - - // No multisample with combined depth/stencil attachment: - QGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - - QGLFramebufferObject *fbo1 = new QGLFramebufferObject(256, 128, fboFormat); - QGLFramebufferObject *fbo2 = new QGLFramebufferObject(256, 128, fboFormat); - QGLFramebufferObject *fbo3 = new QGLFramebufferObject(256, 128, fboFormat); - - if ( (fbo1->attachment() != QGLFramebufferObject::CombinedDepthStencil) || - (fbo2->attachment() != QGLFramebufferObject::CombinedDepthStencil) || - (fbo3->attachment() != QGLFramebufferObject::CombinedDepthStencil) ) - { - delete fbo1; - delete fbo2; - delete fbo3; - QSKIP("FBOs missing combined depth~stencil support"); - } - - QPainter fbo1Painter; - QPainter fbo2Painter; - QPainter fbo3Painter; - - QVERIFY(fbo1Painter.begin(fbo1)); - QVERIFY(fbo2Painter.begin(fbo2)); - QVERIFY(fbo3Painter.begin(fbo3)); - - // Confirm we're using the GL2 engine, as interleaved rendering isn't supported - // on the GL1 engine: - if (fbo1Painter.paintEngine()->type() != QPaintEngine::OpenGL2) - QSKIP("Interleaved GL rendering requires OpenGL 2.0 or higher"); - - QPainterPath intersectingPath; - intersectingPath.moveTo(0, 0); - intersectingPath.lineTo(100, 0); - intersectingPath.lineTo(0, 100); - intersectingPath.lineTo(100, 100); - intersectingPath.closeSubpath(); - - QPainterPath trianglePath; - trianglePath.moveTo(50, 0); - trianglePath.lineTo(100, 100); - trianglePath.lineTo(0, 100); - trianglePath.closeSubpath(); - - fbo1Painter.fillRect(0, 0, fbo1->width(), fbo1->height(), Qt::red); // Background - fbo2Painter.fillRect(0, 0, fbo2->width(), fbo2->height(), Qt::green); // Background - fbo3Painter.fillRect(0, 0, fbo3->width(), fbo3->height(), Qt::blue); // Background - - fbo1Painter.translate(14, 14); - fbo2Painter.translate(14, 14); - fbo3Painter.translate(14, 14); - - fbo1Painter.fillPath(intersectingPath, Qt::blue); // Test stencil buffer works - fbo2Painter.fillPath(intersectingPath, Qt::red); // Test stencil buffer works - fbo3Painter.fillPath(intersectingPath, Qt::green); // Test stencil buffer works - - fbo1Painter.translate(128, 0); - fbo2Painter.translate(128, 0); - fbo3Painter.translate(128, 0); - - fbo1Painter.setClipPath(trianglePath); - fbo2Painter.setClipPath(trianglePath); - fbo3Painter.setClipPath(trianglePath); - - fbo1Painter.setTransform(QTransform()); // reset xform - fbo2Painter.setTransform(QTransform()); // reset xform - fbo3Painter.setTransform(QTransform()); // reset xform - - fbo1Painter.fillRect(0, 0, fbo1->width(), fbo1->height(), Qt::green); - fbo2Painter.fillRect(0, 0, fbo2->width(), fbo2->height(), Qt::blue); - fbo3Painter.fillRect(0, 0, fbo3->width(), fbo3->height(), Qt::red); - - fbo1Painter.end(); - fbo2Painter.end(); - fbo3Painter.end(); - - QImage fb1 = fbo1->toImage().convertToFormat(QImage::Format_RGB32); - QImage fb2 = fbo2->toImage().convertToFormat(QImage::Format_RGB32); - QImage fb3 = fbo3->toImage().convertToFormat(QImage::Format_RGB32); - delete fbo1; - delete fbo2; - delete fbo3; - - // As we're doing more than trivial painting, we can't just compare to - // an image rendered with raster. Instead, we sample at well-defined - // test-points: - QFUZZY_COMPARE_PIXELS(fb1.pixel(39, 64), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(fb1.pixel(89, 64), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(fb1.pixel(64, 39), QColor(Qt::blue).rgb()); - QFUZZY_COMPARE_PIXELS(fb1.pixel(64, 89), QColor(Qt::blue).rgb()); - QFUZZY_COMPARE_PIXELS(fb1.pixel(167, 39), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(fb1.pixel(217, 39), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(fb1.pixel(192, 64), QColor(Qt::green).rgb()); - - QFUZZY_COMPARE_PIXELS(fb2.pixel(39, 64), QColor(Qt::green).rgb()); - QFUZZY_COMPARE_PIXELS(fb2.pixel(89, 64), QColor(Qt::green).rgb()); - QFUZZY_COMPARE_PIXELS(fb2.pixel(64, 39), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(fb2.pixel(64, 89), QColor(Qt::red).rgb()); - QFUZZY_COMPARE_PIXELS(fb2.pixel(167, 39), QColor(Qt::green).rgb()); - QFUZZY_COMPARE_PIXELS(fb2.pixel(217, 39), QColor(Qt::green).rgb()); - QFUZZY_COMPARE_PIXELS(fb2.pixel(192, 64), QColor(Qt::blue).rgb()); - - QFUZZY_COMPARE_PIXELS(fb3.pixel(39, 64), QColor(Qt::blue).rgb()); - QFUZZY_COMPARE_PIXELS(fb3.pixel(89, 64), QColor(Qt::blue).rgb()); - QFUZZY_COMPARE_PIXELS(fb3.pixel(64, 39), QColor(Qt::green).rgb()); - QFUZZY_COMPARE_PIXELS(fb3.pixel(64, 89), QColor(Qt::green).rgb()); - QFUZZY_COMPARE_PIXELS(fb3.pixel(167, 39), QColor(Qt::blue).rgb()); - QFUZZY_COMPARE_PIXELS(fb3.pixel(217, 39), QColor(Qt::blue).rgb()); - QFUZZY_COMPARE_PIXELS(fb3.pixel(192, 64), QColor(Qt::red).rgb()); -} - -class FBOUseInGLWidget : public QGLWidget -{ -public: - bool widgetPainterBeginOk; - bool fboPainterBeginOk; - QImage fboImage; -protected: - void paintEvent(QPaintEvent*) - { - QPainter widgetPainter; - widgetPainterBeginOk = widgetPainter.begin(this); - QGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QGLFramebufferObject::NoAttachment); - QGLFramebufferObject *fbo = new QGLFramebufferObject(100, 100, fboFormat); - - QPainter fboPainter; - fboPainterBeginOk = fboPainter.begin(fbo); - fboPainter.fillRect(-1, -1, 130, 130, Qt::red); - fboPainter.end(); - fboImage = fbo->toImage(); - - widgetPainter.fillRect(-1, -1, width()+2, height()+2, Qt::blue); - - delete fbo; - } - -}; - -void tst_QGL::glFBOUseInGLWidget() -{ - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) - QSKIP("QGLFramebufferObject not supported on this platform"); - - FBOUseInGLWidget w; - w.resize(100, 100); - w.showNormal(); - - QVERIFY(QTest::qWaitForWindowExposed(&w)); - - QVERIFY(w.widgetPainterBeginOk); - QVERIFY(w.fboPainterBeginOk); - -#if defined(Q_OS_QNX) - // glReadPixels reads from the back buffer. On QNX the buffer is not preserved - // after a buffer swap. This is why we have to swap the buffer explicitly before calling - // grabFrameBuffer to retrieve the content of the front buffer - w.swapBuffers(); -#endif - - QImage widgetFB = w.grabFrameBuffer(false); - QImage widgetReference(widgetFB.size(), widgetFB.format()); - widgetReference.fill(0xff0000ff); - QFUZZY_COMPARE_IMAGES(widgetFB, widgetReference); - - QImage fboReference(w.fboImage.size(), w.fboImage.format()); - fboReference.fill(0xffff0000); - QFUZZY_COMPARE_IMAGES(w.fboImage, fboReference); -} - -void tst_QGL::glWidgetReparent() -{ - // Try it as a top-level first: - GLWidget *widget = new GLWidget; - widget->setObjectName(QStringLiteral("glWidget1")); - widget->setGeometry(0, 0, 200, 30); - widget->show(); - - QWidget grandParentWidget; - grandParentWidget.setObjectName(QStringLiteral("grandParentWidget")); - grandParentWidget.setPalette(Qt::blue); - QVBoxLayout grandParentLayout(&grandParentWidget); - - QWidget parentWidget(&grandParentWidget); - parentWidget.setObjectName(QStringLiteral("parentWidget")); - grandParentLayout.addWidget(&parentWidget); - parentWidget.setPalette(Qt::green); - parentWidget.setAutoFillBackground(true); - QVBoxLayout parentLayout(&parentWidget); - - grandParentWidget.setGeometry(0, 100, 200, 200); - grandParentWidget.show(); - - QVERIFY(QTest::qWaitForWindowExposed(widget)); - QVERIFY(QTest::qWaitForWindowExposed(&grandParentWidget)); - - QVERIFY(parentWidget.children().count() == 1); // The layout - - // Now both widgets should be created & shown, time to re-parent: - parentLayout.addWidget(widget); - - QVERIFY(QTest::qWaitForWindowExposed(&grandParentWidget)); - - QVERIFY(parentWidget.children().count() == 2); // Layout & glwidget - QVERIFY(parentWidget.children().contains(widget)); - QTRY_VERIFY(widget->height() > 30); - - delete widget; - - QVERIFY(QTest::qWaitForWindowExposed(&grandParentWidget)); - - QVERIFY(parentWidget.children().count() == 1); // The layout - - // Now do pretty much the same thing, but don't show the - // widget first: - widget = new GLWidget; - widget->setObjectName(QStringLiteral("glWidget2")); - parentLayout.addWidget(widget); - - QVERIFY(QTest::qWaitForWindowExposed(&grandParentWidget)); - - QVERIFY(parentWidget.children().count() == 2); // Layout & glwidget - QVERIFY(parentWidget.children().contains(widget)); - QVERIFY(widget->height() > 30); - - delete widget; -} - -class RenderPixmapWidget : public QGLWidget -{ -protected: - void initializeGL() { - // Set some gl state: - QOpenGLContext::currentContext()->functions()->glClearColor(1.0, 0.0, 0.0, 1.0); - } - - void paintGL() { - QOpenGLContext::currentContext()->functions()->glClear(GL_COLOR_BUFFER_BIT); - } -}; - -void tst_QGL::glWidgetRenderPixmap() -{ - RenderPixmapWidget *w = new RenderPixmapWidget; - - QSize pmSize = QSize(100, 100); - QPixmap pm = w->renderPixmap(pmSize.width(), pmSize.height(), false); - - delete w; - - QImage fb = pm.toImage().convertToFormat(QImage::Format_RGB32); - QImage reference(pmSize, QImage::Format_RGB32); - reference.fill(0xffff0000); - - QFUZZY_COMPARE_IMAGES(fb, reference); -} - -class ColormapExtended : public QGLColormap -{ -public: - ColormapExtended() {} - - Qt::HANDLE handle() { return QGLColormap::handle(); } - void setHandle(Qt::HANDLE handle) { QGLColormap::setHandle(handle); } -}; - -void tst_QGL::colormap() -{ - // Check the properties of the default empty colormap. - QGLColormap cmap1; - QVERIFY(cmap1.isEmpty()); - QCOMPARE(cmap1.size(), 0); - QCOMPARE(cmap1.entryRgb(0), QRgb(0)); - QCOMPARE(cmap1.entryRgb(-1), QRgb(0)); - QCOMPARE(cmap1.entryRgb(100), QRgb(0)); - QVERIFY(!cmap1.entryColor(0).isValid()); - QVERIFY(!cmap1.entryColor(-1).isValid()); - QVERIFY(!cmap1.entryColor(100).isValid()); - QCOMPARE(cmap1.find(qRgb(255, 0, 0)), -1); - QCOMPARE(cmap1.findNearest(qRgb(255, 0, 0)), -1); - - // Set an entry and re-test. - cmap1.setEntry(56, qRgb(255, 0, 0)); - // The colormap is still considered "empty" even though it - // has entries in it now. The isEmpty() method is used to - // detect when the colormap is in use by a GL widget, - // not to detect when it is empty! - QVERIFY(cmap1.isEmpty()); - QCOMPARE(cmap1.size(), 256); - QCOMPARE(cmap1.entryRgb(0), QRgb(0)); - QVERIFY(cmap1.entryColor(0) == QColor(0, 0, 0, 255)); - QVERIFY(cmap1.entryRgb(56) == qRgb(255, 0, 0)); - QVERIFY(cmap1.entryColor(56) == QColor(255, 0, 0, 255)); - QCOMPARE(cmap1.find(qRgb(255, 0, 0)), 56); - QCOMPARE(cmap1.findNearest(qRgb(255, 0, 0)), 56); - - // Set some more entries. - static QRgb const colors[] = { - qRgb(255, 0, 0), - qRgb(0, 255, 0), - qRgb(255, 255, 255), - qRgb(0, 0, 255), - qRgb(0, 0, 0) - }; - cmap1.setEntry(57, QColor(0, 255, 0)); - cmap1.setEntries(3, colors + 2, 58); - cmap1.setEntries(5, colors, 251); - int idx; - for (idx = 0; idx < 5; ++idx) { - QVERIFY(cmap1.entryRgb(56 + idx) == colors[idx]); - QVERIFY(cmap1.entryColor(56 + idx) == QColor(colors[idx])); - QVERIFY(cmap1.entryRgb(251 + idx) == colors[idx]); - QVERIFY(cmap1.entryColor(251 + idx) == QColor(colors[idx])); - } - QCOMPARE(cmap1.size(), 256); - - // Perform color lookups. - QCOMPARE(cmap1.find(qRgb(255, 0, 0)), 56); - QCOMPARE(cmap1.find(qRgb(0, 0, 0)), 60); // Actually finds 0, 0, 0, 255. - QCOMPARE(cmap1.find(qRgba(0, 0, 0, 0)), 0); - QCOMPARE(cmap1.find(qRgb(0, 255, 0)), 57); - QCOMPARE(cmap1.find(qRgb(255, 255, 255)), 58); - QCOMPARE(cmap1.find(qRgb(0, 0, 255)), 59); - QCOMPARE(cmap1.find(qRgb(140, 0, 0)), -1); - QCOMPARE(cmap1.find(qRgb(0, 140, 0)), -1); - QCOMPARE(cmap1.find(qRgb(0, 0, 140)), -1); - QCOMPARE(cmap1.find(qRgb(64, 0, 0)), -1); - QCOMPARE(cmap1.find(qRgb(0, 64, 0)), -1); - QCOMPARE(cmap1.find(qRgb(0, 0, 64)), -1); - QCOMPARE(cmap1.findNearest(qRgb(255, 0, 0)), 56); - QCOMPARE(cmap1.findNearest(qRgb(0, 0, 0)), 60); - QCOMPARE(cmap1.findNearest(qRgba(0, 0, 0, 0)), 0); - QCOMPARE(cmap1.findNearest(qRgb(0, 255, 0)), 57); - QCOMPARE(cmap1.findNearest(qRgb(255, 255, 255)), 58); - QCOMPARE(cmap1.findNearest(qRgb(0, 0, 255)), 59); - QCOMPARE(cmap1.findNearest(qRgb(140, 0, 0)), 56); - QCOMPARE(cmap1.findNearest(qRgb(0, 140, 0)), 57); - QCOMPARE(cmap1.findNearest(qRgb(0, 0, 140)), 59); - QCOMPARE(cmap1.findNearest(qRgb(64, 0, 0)), 0); - QCOMPARE(cmap1.findNearest(qRgb(0, 64, 0)), 0); - QCOMPARE(cmap1.findNearest(qRgb(0, 0, 64)), 0); - - // Make some copies of the colormap and check that they are the same. - QGLColormap cmap2(cmap1); - QGLColormap cmap3; - cmap3 = cmap1; - QVERIFY(cmap2.isEmpty()); - QVERIFY(cmap3.isEmpty()); - QCOMPARE(cmap2.size(), 256); - QCOMPARE(cmap3.size(), 256); - for (idx = 0; idx < 256; ++idx) { - QCOMPARE(cmap1.entryRgb(idx), cmap2.entryRgb(idx)); - QCOMPARE(cmap1.entryRgb(idx), cmap3.entryRgb(idx)); - } - - // Modify an entry in one of the copies and recheck the original. - cmap2.setEntry(45, qRgb(255, 0, 0)); - for (idx = 0; idx < 256; ++idx) { - if (idx != 45) - QCOMPARE(cmap1.entryRgb(idx), cmap2.entryRgb(idx)); - else - QCOMPARE(cmap2.entryRgb(45), qRgb(255, 0, 0)); - QCOMPARE(cmap1.entryRgb(idx), cmap3.entryRgb(idx)); - } - - // Check that setting the handle will cause isEmpty() to work right. - ColormapExtended cmap4; - cmap4.setEntry(56, qRgb(255, 0, 0)); - QVERIFY(cmap4.isEmpty()); - QCOMPARE(cmap4.size(), 256); - cmap4.setHandle(Qt::HANDLE(42)); - QCOMPARE(cmap4.handle(), Qt::HANDLE(42)); - QVERIFY(!cmap4.isEmpty()); - QCOMPARE(cmap4.size(), 256); -} - -#ifndef GL_TEXTURE_3D -#define GL_TEXTURE_3D 0x806F -#endif - -#ifndef GL_RGB16 -#define GL_RGB16 0x8054 -#endif - -void tst_QGL::fboFormat() -{ - // Check the initial conditions. - QGLFramebufferObjectFormat format1; - QCOMPARE(format1.samples(), 0); - QCOMPARE(format1.attachment(), QGLFramebufferObject::NoAttachment); - QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_2D)); - int expectedFormat = -#ifdef QT_OPENGL_ES_2 - GL_RGBA; -#else - QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8; -#endif - QCOMPARE(int(format1.internalTextureFormat()), expectedFormat); - - // Modify the values and re-check. - format1.setSamples(8); - format1.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - format1.setTextureTarget(GL_TEXTURE_3D); - format1.setInternalTextureFormat(GL_RGB16); - QCOMPARE(format1.samples(), 8); - QCOMPARE(format1.attachment(), QGLFramebufferObject::CombinedDepthStencil); - QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_3D)); - QCOMPARE(int(format1.internalTextureFormat()), int(GL_RGB16)); - - // Make copies and check that they are the same. - QGLFramebufferObjectFormat format2(format1); - QGLFramebufferObjectFormat format3; - QCOMPARE(format2.samples(), 8); - QCOMPARE(format2.attachment(), QGLFramebufferObject::CombinedDepthStencil); - QCOMPARE(int(format2.textureTarget()), int(GL_TEXTURE_3D)); - QCOMPARE(int(format2.internalTextureFormat()), int(GL_RGB16)); - format3 = format1; - QCOMPARE(format3.samples(), 8); - QCOMPARE(format3.attachment(), QGLFramebufferObject::CombinedDepthStencil); - QCOMPARE(int(format3.textureTarget()), int(GL_TEXTURE_3D)); - QCOMPARE(int(format3.internalTextureFormat()), int(GL_RGB16)); - - // Modify the copies and check that the original is unchanged. - format2.setSamples(9); - format3.setTextureTarget(GL_TEXTURE_2D); - QCOMPARE(format1.samples(), 8); - QCOMPARE(format1.attachment(), QGLFramebufferObject::CombinedDepthStencil); - QCOMPARE(int(format1.textureTarget()), int(GL_TEXTURE_3D)); - QCOMPARE(int(format1.internalTextureFormat()), int(GL_RGB16)); - - // operator== and operator!= for QGLFramebufferObjectFormat. - QGLFramebufferObjectFormat format1c; - QGLFramebufferObjectFormat format2c; - - QCOMPARE(format1c, format2c); - QVERIFY(!(format1c != format2c)); - format1c.setSamples(8); - QVERIFY(!(format1c == format2c)); - QVERIFY(format1c != format2c); - format2c.setSamples(8); - QCOMPARE(format1c, format2c); - QVERIFY(!(format1c != format2c)); - - format1c.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - QVERIFY(!(format1c == format2c)); - QVERIFY(format1c != format2c); - format2c.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - QCOMPARE(format1c, format2c); - QVERIFY(!(format1c != format2c)); - - format1c.setTextureTarget(GL_TEXTURE_3D); - QVERIFY(!(format1c == format2c)); - QVERIFY(format1c != format2c); - format2c.setTextureTarget(GL_TEXTURE_3D); - QCOMPARE(format1c, format2c); - QVERIFY(!(format1c != format2c)); - - format1c.setInternalTextureFormat(GL_RGB16); - QVERIFY(!(format1c == format2c)); - QVERIFY(format1c != format2c); - format2c.setInternalTextureFormat(GL_RGB16); - QCOMPARE(format1c, format2c); - QVERIFY(!(format1c != format2c)); - - QGLFramebufferObjectFormat format3c(format1c); - QGLFramebufferObjectFormat format4c; - QCOMPARE(format1c, format3c); - QVERIFY(!(format1c != format3c)); - format3c.setInternalTextureFormat( -#ifdef QT_OPENGL_ES_2 - GL_RGBA -#else - QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8 -#endif - ); - QVERIFY(!(format1c == format3c)); - QVERIFY(format1c != format3c); - - format4c = format1c; - QCOMPARE(format1c, format4c); - QVERIFY(!(format1c != format4c)); - format4c.setInternalTextureFormat( -#ifdef QT_OPENGL_ES_2 - GL_RGBA -#else - QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGL ? GL_RGBA : GL_RGBA8 -#endif - ); - QVERIFY(!(format1c == format4c)); - QVERIFY(format1c != format4c); -} - -void tst_QGL::testDontCrashOnDanglingResources() -{ - // We have a number of Q_GLOBAL_STATICS inside the Qt OpenGL - // module. This test is verify that we don't crash as a result of - // them calling into libgl on application shutdown. - QWidget *widget = new UnclippedWidget(); - widget->show(); - qApp->processEvents(); - widget->hide(); -} - -class ReplaceClippingGLWidget : public QGLWidget -{ -public: - void paint(QPainter *painter) - { - painter->fillRect(rect(), Qt::white); - - QPainterPath path; - path.addRect(0, 0, 100, 100); - path.addRect(50, 50, 100, 100); - - painter->setClipRect(0, 0, 150, 150); - painter->fillPath(path, Qt::red); - - painter->translate(150, 150); - painter->setClipRect(0, 0, 150, 150); - painter->fillPath(path, Qt::red); - } - -protected: - void paintEvent(QPaintEvent*) - { - // clear the stencil with junk - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - funcs->glStencilMask(0xFFFF); - funcs->glClearStencil(0xFFFF); - funcs->glDisable(GL_STENCIL_TEST); - funcs->glDisable(GL_SCISSOR_TEST); - funcs->glClear(GL_STENCIL_BUFFER_BIT); - - QPainter painter(this); - paint(&painter); - } -}; - -void tst_QGL::replaceClipping() -{ - ReplaceClippingGLWidget glw; - glw.resize(300, 300); - glw.show(); - - QVERIFY(QTest::qWaitForWindowExposed(&glw)); - - QImage reference(300, 300, QImage::Format_RGB32); - QPainter referencePainter(&reference); - glw.paint(&referencePainter); - referencePainter.end(); - -#if defined(Q_OS_QNX) - // glReadPixels reads from the back buffer. On QNX the buffer is not preserved - // after a buffer swap. This is why we have to swap the buffer explicitly before calling - // grabFrameBuffer to retrieve the content of the front buffer - glw.swapBuffers(); -#endif - const QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); - - // Sample pixels in a grid pattern which avoids false failures due to - // off-by-one pixel errors on some buggy GL implementations - for (int x = 25; x < reference.width(); x += 50) { - for (int y = 25; y < reference.width(); y += 50) { - QFUZZY_COMPARE_PIXELS(widgetFB.pixel(x, y), reference.pixel(x, y)); - } - } -} - -class ClipTestGLWidget : public QGLWidget -{ -public: - void paint(QPainter *painter) - { - painter->fillRect(-1, -1, width()+2, height()+2, Qt::white); - painter->setClipRect(10, 10, width()-20, height()-20); - painter->fillRect(rect(), Qt::cyan); - - painter->save(); - painter->setClipRect(10, 10, 100, 100, Qt::IntersectClip); - - painter->fillRect(rect(), Qt::blue); - - painter->save(); - painter->setClipRect(10, 10, 50, 50, Qt::IntersectClip); - painter->fillRect(rect(), Qt::red); - painter->restore(); - painter->fillRect(0, 0, 40, 40, Qt::white); - painter->save(); - - painter->setClipRect(0, 0, 35, 35, Qt::IntersectClip); - painter->fillRect(rect(), Qt::black); - painter->restore(); - - painter->fillRect(0, 0, 30, 30, Qt::magenta); - - painter->save(); - painter->setClipRect(60, 10, 50, 50, Qt::ReplaceClip); - painter->fillRect(rect(), Qt::green); - painter->restore(); - - painter->restore(); - - painter->translate(100, 100); - - { - QPainterPath path; - path.addRect(10, 10, 100, 100); - path.addRect(10, 10, 10, 10); - painter->setClipPath(path, Qt::IntersectClip); - } - - painter->fillRect(rect(), Qt::blue); - - painter->save(); - { - QPainterPath path; - path.addRect(10, 10, 50, 50); - path.addRect(10, 10, 10, 10); - painter->setClipPath(path, Qt::IntersectClip); - } - painter->fillRect(rect(), Qt::red); - painter->restore(); - painter->fillRect(0, 0, 40, 40, Qt::white); - painter->save(); - - { - QPainterPath path; - path.addRect(0, 0, 35, 35); - path.addRect(10, 10, 10, 10); - painter->setClipPath(path, Qt::IntersectClip); - } - painter->fillRect(rect(), Qt::black); - painter->restore(); - - painter->fillRect(0, 0, 30, 30, Qt::magenta); - - painter->save(); - { - QPainterPath path; - path.addRect(60, 10, 50, 50); - path.addRect(10, 10, 10, 10); - painter->setClipPath(path, Qt::ReplaceClip); - } - painter->fillRect(rect(), Qt::green); - painter->restore(); - } - -protected: - void paintEvent(QPaintEvent*) - { - QPainter painter(this); - paint(&painter); - } -}; - -void tst_QGL::clipTest() -{ - ClipTestGLWidget glw; - glw.resize(220, 220); - glw.showNormal(); - - QVERIFY(QTest::qWaitForWindowExposed(&glw)); - - QImage reference(glw.size(), QImage::Format_RGB32); - QPainter referencePainter(&reference); - glw.paint(&referencePainter); - referencePainter.end(); - -#if defined(Q_OS_QNX) - // glReadPixels reads from the back buffer. On QNX the buffer is not preserved - // after a buffer swap. This is why we have to swap the buffer explicitly before calling - // grabFrameBuffer to retrieve the content of the front buffer - glw.swapBuffers(); -#endif - const QImage widgetFB = glw.grabFrameBuffer(false).convertToFormat(QImage::Format_RGB32); - - // Sample pixels in a grid pattern which avoids false failures due to - // off-by-one pixel errors on some buggy GL implementations - for (int x = 2; x < reference.width(); x += 5) { - for (int y = 2; y < reference.height(); y += 5) { - QFUZZY_COMPARE_PIXELS(widgetFB.pixel(x, y), reference.pixel(x, y)); - } - } -} - -void tst_QGL::destroyFBOAfterContext() -{ - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) - QSKIP("QGLFramebufferObject not supported on this platform"); - - QGLWidget *glw = new QGLWidget(); - glw->makeCurrent(); - - // No multisample with combined depth/stencil attachment: - QGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - - // Don't complicate things by using NPOT: - QGLFramebufferObject *fbo = new QGLFramebufferObject(256, 128, fboFormat); - - // The handle should be valid until the context is destroyed. - QVERIFY(fbo->handle() != 0); - QVERIFY(fbo->isValid()); - - delete glw; - - // The handle should now be zero. - QVERIFY(!fbo->handle()); - QVERIFY(!fbo->isValid()); - - delete fbo; -} - -#ifdef QT_BUILD_INTERNAL - -class tst_QGLResource -{ -public: - tst_QGLResource(const QGLContext * = 0) {} - ~tst_QGLResource() { ++deletions; } - - static int deletions; -}; - -int tst_QGLResource::deletions = 0; - -#ifdef TODO -Q_GLOBAL_STATIC(QOpenGLContextGroupResource<tst_QGLResource>, qt_shared_test) -#endif //TODO -#endif // QT_BUILD_INTERNAL - -#ifdef QT_BUILD_INTERNAL -void tst_QGL::shareRegister() -{ -#ifdef TODO - // Create a context. - QGLWidget *glw1 = new QGLWidget(); - glw1->makeCurrent(); - - // Nothing should be sharing with glw1's context yet. - QVERIFY(!glw1->isSharing()); - - // Create a guard for the first context. - QOpenGLSharedResourceGuard guard(glw1->context()->contextHandle()); - QCOMPARE(guard.id(), 0); - guard.setId(3); - QCOMPARE(guard.id(), 3); - - // Request a tst_QGLResource object for the first context. - tst_QGLResource *res1 = qt_shared_test()->value(glw1->context()->contextHandle()); - QVERIFY(res1); - QCOMPARE(qt_shared_test()->value(glw1->context()->contextHandle()), res1); - - // Create another context that shares with the first. - QVERIFY(!glw1->isSharing()); - QGLWidget *glw2 = new QGLWidget(0, glw1); - if (!glw2->isSharing()) { - delete glw2; - delete glw1; - QSKIP("Context sharing is not supported"); - } - QVERIFY(glw1->isSharing()); - QVERIFY(glw1->context() != glw2->context()); - - // Check that the first context's resource is also on the second. - QCOMPARE(qt_shared_test()->value(glw1->context()), res1); - QCOMPARE(qt_shared_test()->value(glw2->context()), res1); - - // Guard should still be the same. - QCOMPARE(guard.context(), glw1->context()); - QCOMPARE(guard.id(), 3); - - // Check the sharing relationships. - QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context())); - QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context())); - QVERIFY(QGLContext::areSharing(glw1->context(), glw2->context())); - QVERIFY(QGLContext::areSharing(glw2->context(), glw1->context())); - QVERIFY(!QGLContext::areSharing(0, glw2->context())); - QVERIFY(!QGLContext::areSharing(glw1->context(), 0)); - QVERIFY(!QGLContext::areSharing(0, 0)); - - // Create a third context, not sharing with the others. - QGLWidget *glw3 = new QGLWidget(); - QVERIFY(!glw3->isSharing()); - - // Create a guard on the standalone context. - QGLSharedResourceGuard guard3(glw3->context()); - guard3.setId(5); - - // Request a resource to the third context. - tst_QGLResource *res3 = qt_shared_test()->value(glw3->context()); - QVERIFY(res3); - QCOMPARE(qt_shared_test()->value(glw1->context()), res1); - QCOMPARE(qt_shared_test()->value(glw2->context()), res1); - QCOMPARE(qt_shared_test()->value(glw3->context()), res3); - - // Check the sharing relationships again. - QVERIFY(QGLContext::areSharing(glw1->context(), glw1->context())); - QVERIFY(QGLContext::areSharing(glw2->context(), glw2->context())); - QVERIFY(QGLContext::areSharing(glw1->context(), glw2->context())); - QVERIFY(QGLContext::areSharing(glw2->context(), glw1->context())); - QVERIFY(!QGLContext::areSharing(glw1->context(), glw3->context())); - QVERIFY(!QGLContext::areSharing(glw2->context(), glw3->context())); - QVERIFY(!QGLContext::areSharing(glw3->context(), glw1->context())); - QVERIFY(!QGLContext::areSharing(glw3->context(), glw2->context())); - QVERIFY(QGLContext::areSharing(glw3->context(), glw3->context())); - QVERIFY(!QGLContext::areSharing(0, glw2->context())); - QVERIFY(!QGLContext::areSharing(glw1->context(), 0)); - QVERIFY(!QGLContext::areSharing(0, glw3->context())); - QVERIFY(!QGLContext::areSharing(glw3->context(), 0)); - QVERIFY(!QGLContext::areSharing(0, 0)); - - // Shared guard should still be the same. - QCOMPARE(guard.context(), glw1->context()); - QCOMPARE(guard.id(), 3); - - // Delete the first context. - delete glw1; - - // The second context should no longer register as sharing. - QVERIFY(!glw2->isSharing()); - - // The first context's resource should transfer to the second context. - QCOMPARE(tst_QGLResource::deletions, 0); - QCOMPARE(qt_shared_test()->value(glw2->context()), res1); - QCOMPARE(qt_shared_test()->value(glw3->context()), res3); - - // Shared guard should now be the second context, with the id the same. - QCOMPARE(guard.context(), glw2->context()); - QCOMPARE(guard.id(), 3); - QCOMPARE(guard3.context(), glw3->context()); - QCOMPARE(guard3.id(), 5); - - // Clean up and check that the resources are properly deleted. - delete glw2; - QCOMPARE(tst_QGLResource::deletions, 1); - delete glw3; - QCOMPARE(tst_QGLResource::deletions, 2); - - // Guards should now be null and the id zero. - QVERIFY(guard.context() == 0); - QVERIFY(guard.id() == 0); - QVERIFY(guard3.context() == 0); - QVERIFY(guard3.id() == 0); -#endif //TODO -} -#endif - -// Tests QGLContext::bindTexture with default options -#ifdef QT_BUILD_INTERNAL -void tst_QGL::qglContextDefaultBindTexture() -{ - QGLWidget w; - w.makeCurrent(); - QGLContext *ctx = const_cast<QGLContext*>(w.context()); - - QImage *boundImage = new QImage(256, 256, QImage::Format_RGB32); - boundImage->fill(0xFFFFFFFF); - QPixmap *boundPixmap = new QPixmap(256, 256); - boundPixmap->fill(Qt::red); - - int startCacheItemCount = QGLTextureCache::instance()->size(); - - GLuint boundImageTextureId = ctx->bindTexture(*boundImage); - GLuint boundPixmapTextureId = ctx->bindTexture(*boundPixmap); - - // Make sure the image & pixmap have been added to the cache: - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - // Make sure the image & pixmap have the is_cached flag set: - QVERIFY(QImagePixmapCleanupHooks::isImageCached(*boundImage)); - QVERIFY(QImagePixmapCleanupHooks::isPixmapCached(*boundPixmap)); - - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - // Make sure the texture IDs returned are valid: - QCOMPARE(funcs->glIsTexture(boundImageTextureId), GLboolean(GL_TRUE)); - QCOMPARE(funcs->glIsTexture(boundPixmapTextureId), GLboolean(GL_TRUE)); - - // Make sure the textures are still valid after we delete the image/pixmap: - // Also check that although the textures are left intact, the cache entries are removed: - delete boundImage; - boundImage = 0; - QCOMPARE(funcs->glIsTexture(boundImageTextureId), GLboolean(GL_TRUE)); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - delete boundPixmap; - boundPixmap = 0; - QCOMPARE(funcs->glIsTexture(boundPixmapTextureId), GLboolean(GL_TRUE)); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - - // Finally, make sure QGLContext::deleteTexture deletes the texture IDs: - ctx->deleteTexture(boundImageTextureId); - ctx->deleteTexture(boundPixmapTextureId); - QCOMPARE(funcs->glIsTexture(boundImageTextureId), GLboolean(GL_FALSE)); - QCOMPARE(funcs->glIsTexture(boundPixmapTextureId), GLboolean(GL_FALSE)); -} -#endif - -#ifdef QT_BUILD_INTERNAL -void tst_QGL::textureCleanup() -{ - QGLWidget w; - w.resize(200,200); - w.show(); - QVERIFY(QTest::qWaitForWindowExposed(&w)); - w.makeCurrent(); - - // Test pixmaps which have been loaded via QPixmapCache are removed from the texture cache - // when the pixmap cache is cleared - { - int startCacheItemCount = QGLTextureCache::instance()->size(); - QPainter p(&w); - - QPixmap boundPixmap(":designer.png"); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - - p.drawPixmap(0, 0, boundPixmap); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - // Need to call end for the GL2 paint engine to release references to pixmap if using tfp - p.end(); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - // Check that the texture doesn't get removed from the cache when the pixmap is cleared - // as it should still be in the cache: - boundPixmap = QPixmap(); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - QPixmapCache::clear(); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - } - - // Test pixmaps which have been loaded via QPixmapCache are removed from the texture cache - // when they are explicitly removed from the pixmap cache - { - int startCacheItemCount = QGLTextureCache::instance()->size(); - QPainter p(&w); - - QPixmap boundPixmap(128, 128); - QString cacheKey = QString::fromLatin1("myPixmap"); - QPixmapCache::insert(cacheKey, boundPixmap); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - - p.drawPixmap(0, 0, boundPixmap); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - // Need to call end for the GL2 paint engine to release references to pixmap if using tfp - p.end(); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - // Check that the texture doesn't get removed from the cache when the pixmap is cleared - // as it should still be in the cache: - boundPixmap = QPixmap(); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - // Finally, we check that the texture cache entry is removed when we remove the - // pixmap cache entry, which should hold the last reference: - QPixmapCache::remove(cacheKey); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - } - - // Check images & pixmaps are removed from the cache when they are deleted - { - int startCacheItemCount = QGLTextureCache::instance()->size(); - QPainter p(&w); - - QImage *boundImage = new QImage(256, 256, QImage::Format_RGB32); - boundImage->fill(0xFFFFFFFF); - QPixmap *boundPixmap = new QPixmap(256, 256); - boundPixmap->fill(Qt::red); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - - p.drawImage(0, 0, *boundImage); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - p.drawPixmap(0, 0, *boundPixmap); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - // Need to call end for the GL2 paint engine to release references to pixmap if using tfp - p.end(); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - delete boundImage; - boundImage = 0; - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - delete boundPixmap; - boundPixmap = 0; - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - } - - // Check images & pixmaps are removed from the cache when they are assigned to - { - int startCacheItemCount = QGLTextureCache::instance()->size(); - QPainter p(&w); - - QImage boundImage(256, 256, QImage::Format_RGB32); - boundImage.fill(0xFFFFFFFF); - QPixmap boundPixmap(256, 256); - boundPixmap.fill(Qt::red); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - - p.drawImage(0, 0, boundImage); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - p.drawPixmap(0, 0, boundPixmap); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - // Need to call end for the GL2 paint engine to release references to pixmap if using tfp - p.end(); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - boundImage = QImage(64, 64, QImage::Format_RGB32); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - boundPixmap = QPixmap(64, 64); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - } - - // Check images & pixmaps are removed from the cache when they are modified (detached) - { - int startCacheItemCount = QGLTextureCache::instance()->size(); - QPainter p(&w); - - QImage boundImage(256, 256, QImage::Format_RGB32); - boundImage.fill(0xFFFFFFFF); - QPixmap boundPixmap(256, 256); - boundPixmap.fill(Qt::red); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - - p.drawImage(0, 0, boundImage); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - p.drawPixmap(0, 0, boundPixmap); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - // Need to call end for the GL2 paint engine to release references to pixmap if using tfp - p.end(); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - boundImage.fill(0x00000000); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - boundPixmap.fill(Qt::blue); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - } - - // Check that images/pixmaps aren't removed from the cache if a shallow copy has been made - QImage copyOfImage; - QPixmap copyOfPixmap; - int startCacheItemCount = QGLTextureCache::instance()->size(); - { - QPainter p(&w); - - QImage boundImage(256, 256, QImage::Format_RGB32); - boundImage.fill(0xFFFFFFFF); - QPixmap boundPixmap(256, 256); - boundPixmap.fill(Qt::red); - - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); - - p.drawImage(0, 0, boundImage); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - p.drawPixmap(0, 0, boundPixmap); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - // Need to call end for the GL2 paint engine to release references to pixmap if using tfp - p.end(); - - copyOfImage = boundImage; - copyOfPixmap = boundPixmap; - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - } // boundImage & boundPixmap would have been deleted when they went out of scope - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+2); - - copyOfImage = QImage(); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount+1); - - copyOfPixmap = QPixmap(); - QCOMPARE(QGLTextureCache::instance()->size(), startCacheItemCount); -} -#endif - -namespace ThreadImages { - -class Producer : public QObject -{ - Q_OBJECT -public: - Producer() - { - startTimer(20); - - QThread *thread = new QThread; - thread->start(); - - connect(this, SIGNAL(destroyed()), thread, SLOT(quit())); - - moveToThread(thread); - connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); - } - -signals: - void imageReady(const QImage &image); - -protected: - void timerEvent(QTimerEvent *) - { - QImage image(256, 256, QImage::Format_RGB32); - QLinearGradient g(0, 0, 0, 256); - g.setColorAt(0, QColor(255, 180, 180)); - g.setColorAt(1, Qt::white); - g.setSpread(QGradient::ReflectSpread); - - QBrush brush(g); - brush.setTransform(QTransform::fromTranslate(0, delta)); - delta += 10; - - QPainter p(&image); - p.fillRect(image.rect(), brush); - - if (images.size() > 10) - images.removeFirst(); - - images.append(image); - - emit imageReady(image); - } - -private: - QList<QImage> images; - int delta; -}; - - -class DisplayWidget : public QGLWidget -{ - Q_OBJECT -public: - DisplayWidget(QWidget *parent) : QGLWidget(parent) {} - void paintEvent(QPaintEvent *) - { - QPainter p(this); - p.drawImage(rect(), m_image); - } - -public slots: - void setImage(const QImage &image) - { - m_image = image; - update(); - } - -private: - QImage m_image; -}; - -class Widget : public QWidget -{ - Q_OBJECT -public: - Widget() - : iterations(0) - , display(0) - , producer(new Producer) - { - startTimer(400); - connect(this, SIGNAL(destroyed()), producer, SLOT(deleteLater())); - } - - int iterations; - -protected: - void timerEvent(QTimerEvent *) - { - ++iterations; - - delete display; - display = new DisplayWidget(this); - connect(producer, SIGNAL(imageReady(QImage)), display, SLOT(setImage(QImage))); - - display->setGeometry(rect()); - display->show(); - } - -private: - DisplayWidget *display; - Producer *producer; -}; - -} - -void tst_QGL::threadImages() -{ - ThreadImages::Widget *widget = new ThreadImages::Widget; - widget->show(); - - while (widget->iterations <= 5) { - qApp->processEvents(); - } - - delete widget; -} - -void tst_QGL::nullRectCrash() -{ - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) - QSKIP("QGLFramebufferObject not supported on this platform"); - - QGLWidget glw; - glw.makeCurrent(); - - QGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - - QGLFramebufferObject *fbo = new QGLFramebufferObject(128, 128, fboFormat); - - QPainter fboPainter(fbo); - - fboPainter.setPen(QPen(QColor(255, 127, 127, 127), 2)); - fboPainter.setBrush(QColor(127, 255, 127, 127)); - fboPainter.drawRect(QRectF()); - - fboPainter.end(); -} - -void tst_QGL::extensions() -{ - QGLWidget glw; - glw.makeCurrent(); - - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - QVERIFY(ctx); - QOpenGLFunctions *funcs = ctx->functions(); - QVERIFY(funcs); - QSurfaceFormat format = ctx->format(); - -#ifdef QT_BUILD_INTERNAL - QOpenGLExtensions *exts = static_cast<QOpenGLExtensions *>(funcs); - QOpenGLExtensions::OpenGLExtensions allExts = exts->openGLExtensions(); - // Mipmapping is always available in GL2/GLES2+. Verify this. - if (format.majorVersion() >= 2) - QVERIFY(allExts.testFlag(QOpenGLExtensions::GenerateMipmap)); -#endif - - // Now look for some features should always be available in a given version. - QOpenGLFunctions::OpenGLFeatures allFeatures = funcs->openGLFeatures(); - QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Multitexture)); - if (format.majorVersion() >= 2) { - QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Shaders)); - QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Buffers)); - QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Multisample)); - QVERIFY(!ctx->isOpenGLES() || allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); - QVERIFY(allFeatures.testFlag(QOpenGLFunctions::NPOTTextures) - && allFeatures.testFlag(QOpenGLFunctions::NPOTTextureRepeat)); - if (ctx->isOpenGLES()) { - QVERIFY(!allFeatures.testFlag(QOpenGLFunctions::FixedFunctionPipeline)); - QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); - } - } - if (format.majorVersion() >= 3) - QVERIFY(allFeatures.testFlag(QOpenGLFunctions::Framebuffers)); -} - -QTEST_MAIN(tst_QGL) -#include "tst_qgl.moc" diff --git a/tests/auto/opengl/qglbuffer/qglbuffer.pro b/tests/auto/opengl/qglbuffer/qglbuffer.pro deleted file mode 100644 index f12a191f79..0000000000 --- a/tests/auto/opengl/qglbuffer/qglbuffer.pro +++ /dev/null @@ -1,10 +0,0 @@ -############################################################ -# Project file for autotest for file qglbuffer.h -############################################################ - -CONFIG += testcase -TARGET = tst_qglbuffer -requires(qtHaveModule(opengl)) -QT += opengl widgets testlib - -SOURCES += tst_qglbuffer.cpp diff --git a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp b/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp deleted file mode 100644 index c7d26e757f..0000000000 --- a/tests/auto/opengl/qglbuffer/tst_qglbuffer.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtTest/QtTest> -#include <QtOpenGL/qgl.h> -#include <QtOpenGL/qglbuffer.h> - -class tst_QGLBuffer : public QObject -{ - Q_OBJECT -public: - tst_QGLBuffer() {} - ~tst_QGLBuffer() {} - -private slots: - void vertexBuffer_data(); - void vertexBuffer(); - void indexBuffer_data(); - void indexBuffer(); - void bufferSharing(); - -private: - void testBuffer(QGLBuffer::Type type); -}; - -void tst_QGLBuffer::vertexBuffer_data() -{ - QTest::addColumn<int>("usagePattern"); - - QTest::newRow("StreamDraw") << int(QGLBuffer::StreamDraw); - QTest::newRow("StaticDraw") << int(QGLBuffer::StaticDraw); - QTest::newRow("DynamicDraw") << int(QGLBuffer::DynamicDraw); -} - -void tst_QGLBuffer::vertexBuffer() -{ - testBuffer(QGLBuffer::VertexBuffer); -} - -void tst_QGLBuffer::indexBuffer_data() -{ - vertexBuffer_data(); -} - -void tst_QGLBuffer::indexBuffer() -{ - testBuffer(QGLBuffer::IndexBuffer); -} - -void tst_QGLBuffer::testBuffer(QGLBuffer::Type type) -{ - QFETCH(int, usagePattern); - - QGLWidget w; - w.makeCurrent(); - - // Create the local object, but not the buffer in the server. - QGLBuffer buffer(type); - QCOMPARE(buffer.usagePattern(), QGLBuffer::StaticDraw); - buffer.setUsagePattern(QGLBuffer::UsagePattern(usagePattern)); - - // Check the initial state. - QCOMPARE(buffer.type(), type); - QVERIFY(!buffer.isCreated()); - QCOMPARE(buffer.bufferId(), GLuint(0)); - QCOMPARE(buffer.usagePattern(), QGLBuffer::UsagePattern(usagePattern)); - QCOMPARE(buffer.size(), -1); - - // Should not be able to bind it yet because it isn't created. - QVERIFY(!buffer.bind()); - - // Create the buffer - if this fails, then assume that the - // GL implementation does not support buffers at all. - if (!buffer.create()) - QSKIP("Buffers are not supported on this platform"); - - // Should now have a buffer id. - QVERIFY(buffer.bufferId() != 0); - - // Bind the buffer and upload some data. - QVERIFY(buffer.bind()); - static GLfloat const data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - buffer.allocate(data, sizeof(data)); - - // Check the buffer size. - QCOMPARE(buffer.size(), int(sizeof(data))); - - // Map the buffer and read back its contents. - bool haveMap = false; - GLfloat *mapped = reinterpret_cast<GLfloat *> - (buffer.map(QGLBuffer::ReadOnly)); - if (mapped) { - for (int index = 0; index < 9; ++index) - QCOMPARE(mapped[index], data[index]); - buffer.unmap(); - haveMap = true; - } else { - qWarning("QGLBuffer::map() is not supported on this platform"); - } - - // Read back the buffer contents using read(). - bool haveRead = false; - GLfloat readdata[9]; - if (buffer.read(0, readdata, sizeof(readdata))) { - for (int index = 0; index < 9; ++index) - QCOMPARE(readdata[index], data[index]); - haveRead = true; - } else { - qWarning("QGLBuffer::read() is not supported on this platform"); - } - - // Write some different data to a specific location and check it. - static GLfloat const diffdata[] = {11, 12, 13}; - buffer.write(sizeof(GLfloat) * 3, diffdata, sizeof(diffdata)); - if (haveMap) { - mapped = reinterpret_cast<GLfloat *>(buffer.map(QGLBuffer::ReadOnly)); - QVERIFY(mapped != 0); - for (int index = 0; index < 9; ++index) { - if (index >= 3 && index <= 5) - QCOMPARE(mapped[index], diffdata[index - 3]); - else - QCOMPARE(mapped[index], data[index]); - } - buffer.unmap(); - } - if (haveRead) { - QVERIFY(buffer.read(0, readdata, sizeof(readdata))); - for (int index = 0; index < 9; ++index) { - if (index >= 3 && index <= 5) - QCOMPARE(readdata[index], diffdata[index - 3]); - else - QCOMPARE(readdata[index], data[index]); - } - } - - // Write to the buffer using the return value from map. - if (haveMap) { - mapped = reinterpret_cast<GLfloat *>(buffer.map(QGLBuffer::WriteOnly)); - QVERIFY(mapped != 0); - mapped[6] = 14; - buffer.unmap(); - - mapped = reinterpret_cast<GLfloat *>(buffer.map(QGLBuffer::ReadOnly)); - QVERIFY(mapped != 0); - static GLfloat const diff2data[] = {11, 12, 13, 14}; - for (int index = 0; index < 9; ++index) { - if (index >= 3 && index <= 6) - QCOMPARE(mapped[index], diff2data[index - 3]); - else - QCOMPARE(mapped[index], data[index]); - } - buffer.unmap(); - } - - // Resize the buffer. - buffer.allocate(sizeof(GLfloat) * 20); - QCOMPARE(buffer.size(), int(sizeof(GLfloat) * 20)); - buffer.allocate(0, sizeof(GLfloat) * 32); - QCOMPARE(buffer.size(), int(sizeof(GLfloat) * 32)); - - // Release the buffer. - buffer.release(); -} - -void tst_QGLBuffer::bufferSharing() -{ -#if defined(Q_OS_WIN) - // Needs investigation on Windows: QTBUG-29692 - QSKIP("Unreproducible timeout on Windows (MSVC/MinGW) CI bots"); -#endif - -#if defined(Q_OS_QNX) - QSKIP("Crashes on QNX when destroying the second QGLWidget (see QTBUG-38275)"); -#endif - - QGLWidget *w1 = new QGLWidget(); - w1->makeCurrent(); - - QGLWidget *w2 = new QGLWidget(0, w1); - if (!w2->isSharing()) { - delete w2; - delete w1; - QSKIP("Context sharing is not supported on this platform"); - } - - // Bind the buffer in the first context and write some data to it. - QGLBuffer buffer(QGLBuffer::VertexBuffer); - if (!buffer.create()) - QSKIP("Buffers are not supported on this platform"); - QVERIFY(buffer.isCreated()); - QVERIFY(buffer.bind()); - static GLfloat const data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; - buffer.allocate(data, sizeof(data)); - QCOMPARE(buffer.size(), int(sizeof(data))); - buffer.release(); - - // Bind the buffer in the second context and read back the data. - w2->makeCurrent(); - QVERIFY(buffer.bind()); - QCOMPARE(buffer.size(), int(sizeof(data))); - GLfloat readdata[9]; - if (buffer.read(0, readdata, sizeof(readdata))) { - for (int index = 0; index < 9; ++index) - QCOMPARE(readdata[index], data[index]); - } - buffer.release(); - - // Delete the first context. - delete w1; - - // Make the second context current again because deleting the first - // one will call doneCurrent() even though it wasn't current! - w2->makeCurrent(); - - // The buffer should still be valid in the second context. - QVERIFY(buffer.bufferId() != 0); - QVERIFY(buffer.isCreated()); - QVERIFY(buffer.bind()); - QCOMPARE(buffer.size(), int(sizeof(data))); - buffer.release(); - - // Delete the second context. - delete w2; - - // The buffer should now be invalid. - QCOMPARE(buffer.bufferId(), GLuint(0)); - QVERIFY(!buffer.isCreated()); -} - -QTEST_MAIN(tst_QGLBuffer) - -#include "tst_qglbuffer.moc" diff --git a/tests/auto/opengl/qglfunctions/qglfunctions.pro b/tests/auto/opengl/qglfunctions/qglfunctions.pro deleted file mode 100644 index 9b349eaf34..0000000000 --- a/tests/auto/opengl/qglfunctions/qglfunctions.pro +++ /dev/null @@ -1,6 +0,0 @@ -CONFIG += testcase -TARGET = tst_qglfunctions -requires(qtHaveModule(opengl)) -QT += opengl widgets testlib - -SOURCES += tst_qglfunctions.cpp diff --git a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp b/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp deleted file mode 100644 index 93d06659c9..0000000000 --- a/tests/auto/opengl/qglfunctions/tst_qglfunctions.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtTest/QtTest> -#include <QtOpenGL/qglfunctions.h> - -class tst_QGLFunctions : public QObject -{ - Q_OBJECT -public: - tst_QGLFunctions() {} - ~tst_QGLFunctions() {} - -private slots: - void features(); - void multitexture(); - void blendColor(); - -private: - static bool hasExtension(const char *name); -}; - -bool tst_QGLFunctions::hasExtension(const char *name) -{ - QString extensions = - QString::fromLatin1 - (reinterpret_cast<const char *>(QOpenGLContext::currentContext()->functions()->glGetString(GL_EXTENSIONS))); - return extensions.split(QLatin1Char(' ')).contains - (QString::fromLatin1(name)); -} - -// Check that the reported features are consistent with the platform. -void tst_QGLFunctions::features() -{ - // Before being associated with a context, there should be - // no features enabled. - QGLFunctions funcs; - QVERIFY(!funcs.openGLFeatures()); - 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)); - - // Make a context current. - QGLWidget glw; - if (!glw.isValid()) - QSKIP("Could not create a GL context"); - glw.makeCurrent(); - funcs.initializeGLFunctions(); - - // Validate the features against what we expect for this platform. - if (QOpenGLContext::currentContext()->isOpenGLES()) { -#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)); - - 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. -void tst_QGLFunctions::multitexture() -{ - QOpenGLFunctions funcs; - QGLWidget glw; - if (!glw.isValid()) - QSKIP("Could not create a GL context"); - glw.makeCurrent(); - funcs.initializeOpenGLFunctions(); - - if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Multitexture)) - QSKIP("Multitexture functions are not supported"); - - funcs.glActiveTexture(GL_TEXTURE1); - - GLint active = 0; - funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, &active); - QCOMPARE(active, GL_TEXTURE1); - - funcs.glActiveTexture(GL_TEXTURE0); - - active = 0; - funcs.glGetIntegerv(GL_ACTIVE_TEXTURE, &active); - QCOMPARE(active, GL_TEXTURE0); -} - -// Verify that the glBlendColor() function appears to resolve and work. -void tst_QGLFunctions::blendColor() -{ - QOpenGLFunctions funcs; - QGLWidget glw; - if (!glw.isValid()) - QSKIP("Could not create a GL context"); - glw.makeCurrent(); - funcs.initializeOpenGLFunctions(); - - if (!funcs.hasOpenGLFeature(QOpenGLFunctions::BlendColor)) - QSKIP("glBlendColor() is not supported"); - - funcs.glBlendColor(0.0f, 1.0f, 0.0f, 1.0f); - - GLfloat colors[4] = {0.5f, 0.5f, 0.5f, 0.5f}; - funcs.glGetFloatv(GL_BLEND_COLOR, colors); - - QCOMPARE(colors[0], 0.0f); - QCOMPARE(colors[1], 1.0f); - QCOMPARE(colors[2], 0.0f); - QCOMPARE(colors[3], 1.0f); -} - -QTEST_MAIN(tst_QGLFunctions) - -#include "tst_qglfunctions.moc" diff --git a/tests/auto/opengl/qglthreads/qglthreads.pro b/tests/auto/opengl/qglthreads/qglthreads.pro deleted file mode 100644 index 9aa21fb3a2..0000000000 --- a/tests/auto/opengl/qglthreads/qglthreads.pro +++ /dev/null @@ -1,7 +0,0 @@ -CONFIG += testcase -TARGET = tst_qglthreads -requires(qtHaveModule(opengl)) -QT += opengl widgets testlib gui-private core-private - -HEADERS += tst_qglthreads.h -SOURCES += tst_qglthreads.cpp diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp b/tests/auto/opengl/qglthreads/tst_qglthreads.cpp deleted file mode 100644 index e12f6d9c18..0000000000 --- a/tests/auto/opengl/qglthreads/tst_qglthreads.cpp +++ /dev/null @@ -1,687 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtTest/QtTest> -#include <QtCore/QtCore> -#include <QtGui/QtGui> -#include <private/qguiapplication_p.h> -#include <qpa/qplatformintegration.h> -#include <QtWidgets/QApplication> -#include <QtOpenGL/QtOpenGL> -#include <qelapsedtimer.h> -#include "tst_qglthreads.h" - -#ifndef QT_OPENGL_ES_2 -#include <QtGui/QOpenGLFunctions_1_0> -#endif - -#define RUNNING_TIME 5000 - -tst_QGLThreads::tst_QGLThreads(QObject *parent) - : QObject(parent) -{ -} - -/* - - swapInThread - - The purpose of this testcase is to verify that it is possible to do rendering into - a GL context from the GUI thread, then swap the contents in from a background thread. - - The usecase for this is to have the background thread do the waiting for vertical - sync while the GUI thread is idle. - - Currently the locking is handled directly in the paintEvent(). For the actual usecase - in Qt, the locking is done in the windowsurface before starting any drawing while - unlocking is done after all drawing has been done. - */ - - -class SwapThread : public QThread -{ - Q_OBJECT -public: - SwapThread(QGLWidget *widget) - : m_context(widget->context()) - , m_swapTriggered(false) - { - moveToThread(this); - } - - void run() { - QElapsedTimer timer; - timer.start(); - while (timer.elapsed() < RUNNING_TIME) { - lock(); - waitForReadyToSwap(); - - m_context->makeCurrent(); - m_context->swapBuffers(); - m_context->doneCurrent(); - - m_context->moveToThread(qApp->thread()); - - signalSwapDone(); - unlock(); - } - - m_swapTriggered = false; - } - - void lock() { m_mutex.lock(); } - void unlock() { m_mutex.unlock(); } - - void waitForSwapDone() { if (m_swapTriggered) m_swapDone.wait(&m_mutex); } - void waitForReadyToSwap() { if (!m_swapTriggered) m_readyToSwap.wait(&m_mutex); } - - void signalReadyToSwap() - { - if (!isRunning()) - return; - m_readyToSwap.wakeAll(); - m_swapTriggered = true; - } - - void signalSwapDone() - { - m_swapTriggered = false; - m_swapDone.wakeAll(); - } - -private: - QGLContext *m_context; - QMutex m_mutex; - QWaitCondition m_readyToSwap; - QWaitCondition m_swapDone; - - bool m_swapTriggered; -}; - -class ForegroundWidget : public QGLWidget -{ -public: - ForegroundWidget(const QGLFormat &format) - : QGLWidget(format), m_thread(0) - { - setAutoBufferSwap(false); - } - - void resizeEvent(QResizeEvent *e) - { - m_thread->lock(); - QGLWidget::resizeEvent(e); - m_thread->unlock(); - } - - void paintEvent(QPaintEvent *) - { - m_thread->lock(); - m_thread->waitForSwapDone(); - - makeCurrent(); - QPainter p(this); - p.fillRect(rect(), QColor(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))); - p.setPen(Qt::red); - p.setFont(QFont("SansSerif", 24)); - p.drawText(rect(), Qt::AlignCenter, "This is an autotest"); - p.end(); - doneCurrent(); - - if (m_thread->isRunning()) { - context()->moveToThread(m_thread); - m_thread->signalReadyToSwap(); - } - - m_thread->unlock(); - - update(); - } - - void setThread(SwapThread *thread) { - m_thread = thread; - } - - SwapThread *m_thread; -}; - -void tst_QGLThreads::swapInThread() -{ - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) - QSKIP("No platformsupport for ThreadedOpenGL"); - QGLFormat format; - format.setSwapInterval(1); - ForegroundWidget widget(format); - SwapThread thread(&widget); - widget.setThread(&thread); - widget.show(); - - QVERIFY(QTest::qWaitForWindowExposed(&widget)); - thread.start(); - - while (thread.isRunning()) { - qApp->processEvents(); - } - - widget.hide(); - - QVERIFY(true); -} - -/* - renderInThread - - This test sets up a scene and renders it in a different thread. - For simplicity, the scene is simply a bunch of rectangles, but - if that works, we're in good shape.. - */ - -static inline float qrandom() { return (QRandomGenerator::global()->bounded(100)) / 100.f; } - -void renderAScene(int w, int h) -{ - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - - if (QOpenGLContext::currentContext()->isOpenGLES()) { - 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(); - - funcs->glEnableVertexAttribArray(0); - - for (int i=0; i<1000; ++i) { - GLfloat pos[] = { - (QRandomGenerator::global()->bounded(100)) / 100.f, - (QRandomGenerator::global()->bounded(100)) / 100.f, - (QRandomGenerator::global()->bounded(100)) / 100.f, - (QRandomGenerator::global()->bounded(100)) / 100.f, - (QRandomGenerator::global()->bounded(100)) / 100.f, - (QRandomGenerator::global()->bounded(100)) / 100.f - }; - - funcs->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, pos); - funcs->glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - } - } else { -#ifndef QT_OPENGL_ES_2 - QOpenGLFunctions_1_0 *gl1funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_1_0>(); - gl1funcs->initializeOpenGLFunctions(); - - gl1funcs->glViewport(0, 0, w, h); - - gl1funcs->glMatrixMode(GL_PROJECTION); - gl1funcs->glLoadIdentity(); - gl1funcs->glFrustum(0, w, h, 0, 1, 100); - gl1funcs->glTranslated(0, 0, -1); - - gl1funcs->glMatrixMode(GL_MODELVIEW); - gl1funcs->glLoadIdentity(); - - for (int i=0;i<1000; ++i) { - gl1funcs->glBegin(GL_TRIANGLES); - gl1funcs->glColor3f(qrandom(), qrandom(), qrandom()); - gl1funcs->glVertex2f(qrandom() * w, qrandom() * h); - gl1funcs->glColor3f(qrandom(), qrandom(), qrandom()); - gl1funcs->glVertex2f(qrandom() * w, qrandom() * h); - gl1funcs->glColor3f(qrandom(), qrandom(), qrandom()); - gl1funcs->glVertex2f(qrandom() * w, qrandom() * h); - gl1funcs->glEnd(); - } -#endif - } -} - -class ThreadSafeGLWidget : public QGLWidget -{ -public: - ThreadSafeGLWidget(QWidget *parent = 0) : QGLWidget(parent) {} - void paintEvent(QPaintEvent *) - { - // ignored as we're anyway swapping as fast as we can - }; - - void resizeEvent(QResizeEvent *e) - { - mutex.lock(); - newSize = e->size(); - mutex.unlock(); - }; - - QMutex mutex; - QSize newSize; -}; - -class SceneRenderingThread : public QThread -{ - Q_OBJECT -public: - SceneRenderingThread(ThreadSafeGLWidget *widget) - : m_widget(widget) - { - moveToThread(this); - m_size = widget->size(); - } - - void run() { - QElapsedTimer timer; - timer.start(); - failure = false; - - while (timer.elapsed() < RUNNING_TIME && !failure) { - - m_widget->makeCurrent(); - - m_widget->mutex.lock(); - QSize s = m_widget->newSize; - m_widget->mutex.unlock(); - - QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions(); - if (s != m_size) { - funcs->glViewport(0, 0, s.width(), s.height()); - } - - if (QGLContext::currentContext() != m_widget->context()) { - failure = true; - break; - } - - funcs->glClear(GL_COLOR_BUFFER_BIT); - - int w = m_widget->width(); - int h = m_widget->height(); - - renderAScene(w, h); - - int color; - funcs->glReadPixels(w / 2, h / 2, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); - - m_widget->swapBuffers(); - } - - m_widget->doneCurrent(); - } - - bool failure; - -private: - ThreadSafeGLWidget *m_widget; - QSize m_size; -}; - -void tst_QGLThreads::renderInThread_data() -{ - QTest::addColumn<bool>("resize"); - QTest::addColumn<bool>("update"); - - QTest::newRow("basic") << false << false; - QTest::newRow("with-resize") << true << false; - QTest::newRow("with-update") << false << true; - QTest::newRow("with-resize-and-update") << true << true; -} - -void tst_QGLThreads::renderInThread() -{ - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) - QSKIP("No platformsupport for ThreadedOpenGL"); - - QFETCH(bool, resize); - QFETCH(bool, update); - -#if defined(Q_OS_MACOS) - if (resize) - QSKIP("gldSetZero crashes in render thread, QTBUG-68524"); -#endif - - ThreadSafeGLWidget widget; - widget.resize(200, 200); - SceneRenderingThread thread(&widget); - - widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); - widget.doneCurrent(); - - widget.context()->moveToThread(&thread); - - thread.start(); - - int value = 10; - while (thread.isRunning()) { - if (resize) - widget.resize(200 + value, 200 + value); - if (update) - widget.update(100 + value, 100 + value, 20, 20); - qApp->processEvents(); - value = -value; - - QThread::msleep(100); - } - - QVERIFY(!thread.failure); -} - -class Device -{ -public: - virtual ~Device() {} - virtual QPaintDevice *realPaintDevice() = 0; - virtual void prepareDevice() {} - virtual void moveToThread(QThread *) {} -}; - -class GLWidgetWrapper : public Device -{ -public: - GLWidgetWrapper() { - widget.resize(150, 150); - widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); - widget.doneCurrent(); - } - QPaintDevice *realPaintDevice() { return &widget; } - void moveToThread(QThread *thread) { widget.context()->moveToThread(thread); } - - ThreadSafeGLWidget widget; -}; - -class PixmapWrapper : public Device -{ -public: - PixmapWrapper() { pixmap = new QPixmap(512, 512); } - ~PixmapWrapper() { delete pixmap; } - QPaintDevice *realPaintDevice() { return pixmap; } - - QPixmap *pixmap; -}; - -class PixelBufferWrapper : public Device -{ -public: - PixelBufferWrapper() { pbuffer = new QGLPixelBuffer(512, 512); } - ~PixelBufferWrapper() { delete pbuffer; } - QPaintDevice *realPaintDevice() { return pbuffer; } - void moveToThread(QThread *thread) { pbuffer->context()->moveToThread(thread); } - - QGLPixelBuffer *pbuffer; -}; - - -class FrameBufferObjectWrapper : public Device -{ -public: - FrameBufferObjectWrapper() { - widget.makeCurrent(); - fbo = new QGLFramebufferObject(512, 512); - widget.doneCurrent(); - } - ~FrameBufferObjectWrapper() { delete fbo; } - QPaintDevice *realPaintDevice() { return fbo; } - void prepareDevice() { widget.makeCurrent(); } - void moveToThread(QThread *thread) { widget.context()->moveToThread(thread); } - - ThreadSafeGLWidget widget; - QGLFramebufferObject *fbo; -}; - - -class ThreadPainter : public QObject -{ - Q_OBJECT -public: - ThreadPainter(Device *pd) : device(pd), fail(true) { - pixmap = QPixmap(40, 40); - pixmap.fill(Qt::green); - QPainter p(&pixmap); - p.drawLine(0, 0, 40, 40); - p.drawLine(0, 40, 40, 0); - } - -public slots: - void draw() { - bool beginFailed = false; - QElapsedTimer timer; - timer.start(); - int rotAngle = 10; - device->prepareDevice(); - QPaintDevice *paintDevice = device->realPaintDevice(); - QSize s(paintDevice->width(), paintDevice->height()); - while (timer.elapsed() < RUNNING_TIME) { - QPainter p; - if (!p.begin(paintDevice)) { - beginFailed = true; - break; - } - p.translate(s.width()/2, s.height()/2); - p.rotate(rotAngle); - p.translate(-s.width()/2, -s.height()/2); - p.fillRect(0, 0, s.width(), s.height(), Qt::red); - QRect rect(QPoint(0, 0), s); - p.drawPixmap(10, 10, pixmap); - p.drawTiledPixmap(50, 50, 100, 100, pixmap); - p.drawText(rect.center(), "This is a piece of text"); - p.end(); - rotAngle += 2; - QThread::msleep(20); - } - - device->moveToThread(qApp->thread()); - - fail = beginFailed; - QThread::currentThread()->quit(); - } - - bool failed() { return fail; } - -private: - QPixmap pixmap; - Device *device; - bool fail; -}; - -template <class T> -class PaintThreadManager -{ -public: - PaintThreadManager(int count) : numThreads(count) - { - for (int i=0; i<numThreads; ++i) - devices.append(new T); - // Wait until resize events are processed on the internal - // QGLWidgets of the buffers to suppress errors - // about makeCurrent() from the wrong thread. - QCoreApplication::processEvents(); - for (int i=0; i<numThreads; ++i) { - devices.append(new T); - threads.append(new QThread); - painters.append(new ThreadPainter(devices.at(i))); - painters.at(i)->moveToThread(threads.at(i)); - painters.at(i)->connect(threads.at(i), SIGNAL(started()), painters.at(i), SLOT(draw())); - devices.at(i)->moveToThread(threads.at(i)); - } - } - - ~PaintThreadManager() { - qDeleteAll(threads); - qDeleteAll(painters); - qDeleteAll(devices); - } - - - void start() { - for (int i=0; i<numThreads; ++i) - threads.at(i)->start(); - } - - bool areRunning() { - bool running = false; - for (int i=0; i<numThreads; ++i){ - if (threads.at(i)->isRunning()) - running = true; - } - - return running; - } - - bool failed() { - for (int i=0; i<numThreads; ++i) { - if (painters.at(i)->failed()) - return true; - } - - return false; - } - -private: - QList<QThread *> threads; - QList<Device *> devices; - QList<ThreadPainter *> painters; - int numThreads; -}; - -/* - This test uses QPainter to draw onto different QGLWidgets in - different threads at the same time. The ThreadSafeGLWidget is - necessary to handle paint and resize events that might come from - the main thread at any time while the test is running. The resize - and paint events would cause makeCurrent() calls to be issued from - within the QGLWidget while the widget's context was current in - another thread, which would cause errors. -*/ -void tst_QGLThreads::painterOnGLWidgetInThread() -{ - //QTBUG-46446 tst_qglthreads is unstable on windows 7 - if (QGuiApplication::platformName().compare("windows 7", Qt::CaseInsensitive)) - QSKIP("Doesn't work on this platform. QTBUG-46446"); - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) - QSKIP("No platformsupport for ThreadedOpenGL"); - if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) || - (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) { - QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0."); - } - - PaintThreadManager<GLWidgetWrapper> painterThreads(5); - painterThreads.start(); - - while (painterThreads.areRunning()) { - qApp->processEvents(); - QThread::msleep(100); - } - QVERIFY(!painterThreads.failed()); -} - -/* - This test uses QPainter to draw onto different QPixmaps in - different threads at the same time. -*/ -void tst_QGLThreads::painterOnPixmapInThread() -{ - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL) - || !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) - QSKIP("No platformsupport for ThreadedOpenGL or ThreadedPixmaps"); - PaintThreadManager<PixmapWrapper> painterThreads(5); - painterThreads.start(); - - while (painterThreads.areRunning()) { - qApp->processEvents(); - QThread::msleep(100); - } - QVERIFY(!painterThreads.failed()); -} - -/* This test uses QPainter to draw onto different QGLPixelBuffer - objects in different threads at the same time. -*/ -void tst_QGLThreads::painterOnPboInThread() -{ - //QTBUG-46446 tst_qglthreads is unstable on windows 7 - if (QGuiApplication::platformName().compare("windows 7", Qt::CaseInsensitive)) - QSKIP("Doesn't work on this platform. QTBUG-46446"); - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) - QSKIP("No platformsupport for ThreadedOpenGL"); - if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) || - (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) { - QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0."); - } - - if (!QGLPixelBuffer::hasOpenGLPbuffers()) { - QSKIP("This system doesn't support pbuffers."); - } - - PaintThreadManager<PixelBufferWrapper> painterThreads(5); - painterThreads.start(); - - while (painterThreads.areRunning()) { - qApp->processEvents(); - QThread::msleep(100); - } - QVERIFY(!painterThreads.failed()); -} - -/* This test uses QPainter to draw onto different - QGLFramebufferObjects (bound in a QGLWidget's context) in different - threads at the same time. -*/ -void tst_QGLThreads::painterOnFboInThread() -{ - //QTBUG-46446 tst_qglthreads is unstable on windows 7 - if (QGuiApplication::platformName().compare("windows 7", Qt::CaseInsensitive)) - QSKIP("Doesn't work on this platform. QTBUG-46446"); - if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedOpenGL)) - QSKIP("No platformsupport for ThreadedOpenGL"); - if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) || - (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) { - QSKIP("The OpenGL based threaded QPainter tests requires OpenGL/ES 2.0."); - } - - if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) { - QSKIP("This system doesn't support framebuffer objects."); - } - - PaintThreadManager<FrameBufferObjectWrapper> painterThreads(5); - painterThreads.start(); - - while (painterThreads.areRunning()) { - qApp->processEvents(); - QThread::msleep(100); - } - QVERIFY(!painterThreads.failed()); -} - -int main(int argc, char **argv) -{ - QApplication app(argc, argv); - QTEST_DISABLE_KEYPAD_NAVIGATION \ - - tst_QGLThreads tc; - return QTest::qExec(&tc, argc, argv); -} - -#include "tst_qglthreads.moc" diff --git a/tests/auto/opengl/qglthreads/tst_qglthreads.h b/tests/auto/opengl/qglthreads/tst_qglthreads.h deleted file mode 100644 index e4b496c163..0000000000 --- a/tests/auto/opengl/qglthreads/tst_qglthreads.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TST_QGLTHREADS_H -#define TST_QGLTHREADS_H - -#include <QObject> - -class tst_QGLThreads : public QObject -{ -Q_OBJECT -public: - explicit tst_QGLThreads(QObject *parent = 0); - -private slots: - void swapInThread(); - - void renderInThread_data(); - void renderInThread(); - void painterOnGLWidgetInThread(); - void painterOnPixmapInThread(); - void painterOnPboInThread(); - void painterOnFboInThread(); -}; - -#endif // TST_QGLTHREADS_H diff --git a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp index e3b046e448..352a6314f3 100644 --- a/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp +++ b/tests/auto/widgets/widgets/qmdiarea/tst_qmdiarea.cpp @@ -2694,30 +2694,6 @@ void tst_QMdiArea::nativeSubWindows() foreach (QMdiSubWindow *subWindow, mdiArea.subWindowList()) QVERIFY(subWindow->internalWinId()); } - -#ifndef QT_NO_OPENGL - { - if (!QGLFormat::hasOpenGL()) - QSKIP("QGL not supported on this platform"); - - QMdiArea mdiArea; - QGLWidget *glViewport = new QGLWidget; - mdiArea.setViewport(glViewport); - mdiArea.addSubWindow(new QWidget); - mdiArea.addSubWindow(new QWidget); - mdiArea.show(); - QVERIFY(QTest::qWaitForWindowExposed(&mdiArea)); - - const QGLContext *context = glViewport->context(); - if (!context || !context->isValid()) - QSKIP("QGL is broken, cannot continue test"); - - // The viewport and all the sub-windows must be native. - QVERIFY(mdiArea.viewport()->internalWinId()); - foreach (QMdiSubWindow *subWindow, mdiArea.subWindowList()) - QVERIFY(subWindow->internalWinId()); - } -#endif } void tst_QMdiArea::task_209615() diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.cpp index dfa08b6869..1eaa5f6578 100644 --- a/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.cpp +++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.cpp @@ -56,13 +56,6 @@ void ChipTester::setAntialias(bool enabled) setRenderHint(QPainter::Antialiasing, enabled); } -void ChipTester::setOpenGL(bool enabled) -{ -#ifndef QT_NO_OPENGL - setViewport(enabled ? new QGLWidget(QGLFormat(QGL::SampleBuffers)) : 0); -#endif -} - void ChipTester::setOperation(Operation operation) { this->operation = operation; diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.h b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.h index d85686c94e..e4c9197142 100644 --- a/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.h +++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/chiptester/chiptester.h @@ -51,7 +51,6 @@ public: ChipTester(QWidget *parent = 0); void setAntialias(bool enabled); - void setOpenGL(bool enabled); void runBenchmark(); void setOperation(Operation operation); diff --git a/tests/benchmarks/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/benchmarks/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 9bb5231528..25fc439883 100644 --- a/tests/benchmarks/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/benchmarks/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -382,31 +382,22 @@ void tst_QGraphicsView::mapRectFromScene() void tst_QGraphicsView::chipTester_data() { QTest::addColumn<bool>("antialias"); - QTest::addColumn<bool>("opengl"); QTest::addColumn<int>("operation"); - QTest::newRow("rotate, normal") << false << false << 0; - QTest::newRow("rotate, normal, antialias") << true << false << 0; - QTest::newRow("rotate, opengl") << false << true << 0; - QTest::newRow("rotate, opengl, antialias") << true << true << 0; - QTest::newRow("zoom, normal") << false << false << 1; - QTest::newRow("zoom, normal, antialias") << true << false << 1; - QTest::newRow("zoom, opengl") << false << true << 1; - QTest::newRow("zoom, opengl, antialias") << true << true << 1; - QTest::newRow("translate, normal") << false << false << 2; - QTest::newRow("translate, normal, antialias") << true << false << 2; - QTest::newRow("translate, opengl") << false << true << 2; - QTest::newRow("translate, opengl, antialias") << true << true << 2; + QTest::newRow("rotate") << false << 0; + QTest::newRow("rotate, antialias") << true << 0; + QTest::newRow("zoom") << false << 1; + QTest::newRow("zoom, antialias") << true << 1; + QTest::newRow("translate") << false << 2; + QTest::newRow("translate, antialias") << true << 2; } void tst_QGraphicsView::chipTester() { QFETCH(bool, antialias); - QFETCH(bool, opengl); QFETCH(int, operation); ChipTester tester; tester.setAntialias(antialias); - tester.setOpenGL(opengl); tester.setOperation(ChipTester::Operation(operation)); tester.show(); QVERIFY(QTest::qWaitForWindowExposed(&tester)); |