Remove deprecated QGL* classes

Removes QGL paths in sub-attaq and chip examples.

The boxes example depended on QGL and has been removed.

The corresponding module and test directories for the opengl module are now
empty, but has been left there so we can move the QOpenGL* classes there.

[ChangeLog][QtOpenGL] The deprecated QGL* classes have been removed.

Fixes: QTBUG-74408
Change-Id: I52f56409af8f6901359462a7ba162103d051fe3d
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
bb10
Johan Klokkhammer Helsing 2019-11-29 11:49:28 +01:00
parent bef74b6c3a
commit f08038fca7
107 changed files with 16 additions and 33376 deletions

View File

@ -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);
}

View File

@ -1,5 +1,4 @@
QT += widgets
qtHaveModule(opengl): QT += opengl
HEADERS += boat.h \
bomb.h \
mainwindow.h \

View File

@ -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];
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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

View File

@ -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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -1,5 +0,0 @@
color basicColor ff0e3d0e
color woodColors ff5e3d33 ffcc9966
float woodTubulence 0.1
color graniteColors ff000000 ff4d261a ffccb3bf
color marbleColors ffe6e6e6 ff998080

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -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);
}

View File

@ -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

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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());

View File

@ -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;

View File

@ -14,7 +14,3 @@ SUBDIRS = \
weatheranchorlayout
contains(DEFINES, QT_NO_CURSOR)|!qtConfig(draganddrop): SUBDIRS -= dragdroprobot
qtHaveModule(opengl):!qtConfig(opengles.):!qtConfig(dynamicgl) {
SUBDIRS += boxes
}

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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]

View File

@ -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.

View File

@ -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.
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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 &region);
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,6 +1,2 @@
TEMPLATE=subdirs
SUBDIRS=\
qgl \
qglbuffer \
qglfunctions \
qglthreads \
TEMPLATE = subdirs
#SUBDIRS =

View File

@ -1 +0,0 @@
tst_qgl

View File

@ -1,8 +0,0 @@
[graphicsViewClipping]
ubuntu-16.04
rhel-7.6
opensuse-leap
ubuntu-18.04
rhel-7.4
opensuse-42.3

View File

@ -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

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file alias="designer.png">../../gui/image/qpixmap/images/designer.png</file>
</qresource>
</RCC>

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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"

View File

@ -1,6 +0,0 @@
CONFIG += testcase
TARGET = tst_qglfunctions
requires(qtHaveModule(opengl))
QT += opengl widgets testlib
SOURCES += tst_qglfunctions.cpp

View File

@ -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"

Some files were not shown because too many files have changed in this diff Show More