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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
QT += widgets
|
||||
qtHaveModule(opengl): QT += opengl
|
||||
HEADERS += boat.h \
|
||||
bomb.h \
|
||||
mainwindow.h \
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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>
|
||||
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
color basicColor ff0e3d0e
|
||||
color woodColors ff5e3d33 ffcc9966
|
||||
float woodTubulence 0.1
|
||||
color graniteColors ff000000 ff4d261a ffccb3bf
|
||||
color marbleColors ffe6e6e6 ff998080
|
||||
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,3 @@ SUBDIRS = \
|
|||
weatheranchorlayout
|
||||
|
||||
contains(DEFINES, QT_NO_CURSOR)|!qtConfig(draganddrop): SUBDIRS -= dragdroprobot
|
||||
|
||||
qtHaveModule(opengl):!qtConfig(opengles.):!qtConfig(dynamicgl) {
|
||||
SUBDIRS += boxes
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
@ -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]
|
||||
|
|
@ -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]
|
||||
|
|
@ -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]
|
||||
|
|
@ -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]
|
||||
|
|
@ -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]
|
||||
|
|
@ -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]
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
5558
src/opengl/qgl.cpp
524
src/opengl/qgl.h
|
|
@ -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
|
||||
|
|
@ -1,556 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtOpenGL module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QGL_P_H
|
||||
#define QGL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of the QGLWidget class. This header file may change from
|
||||
// version to version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "QtOpenGL/qgl.h"
|
||||
#include "QtOpenGL/qglcolormap.h"
|
||||
#include "QtCore/qmap.h"
|
||||
#include "QtCore/qthread.h"
|
||||
#include "QtCore/qthreadstorage.h"
|
||||
#include "QtCore/qhashfunctions.h"
|
||||
#include "QtCore/qatomic.h"
|
||||
#include "QtWidgets/private/qwidget_p.h"
|
||||
#include "QtGui/private/qopenglcontext_p.h"
|
||||
#include "QtGui/private/qopenglextensions_p.h"
|
||||
#include "qcache.h"
|
||||
#include "qglpaintdevice_p.h"
|
||||
|
||||
#include <QtGui/QOpenGLContext>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QGLContext;
|
||||
class QGLOverlayWidget;
|
||||
class QPixmap;
|
||||
class QOpenGLExtensions;
|
||||
|
||||
class QGLFormatPrivate
|
||||
{
|
||||
public:
|
||||
QGLFormatPrivate()
|
||||
: ref(1)
|
||||
{
|
||||
opts = QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::DirectRendering
|
||||
| QGL::StencilBuffer | QGL::DeprecatedFunctions;
|
||||
pln = 0;
|
||||
depthSize = accumSize = stencilSize = redSize = greenSize = blueSize = alphaSize = -1;
|
||||
numSamples = -1;
|
||||
swapInterval = -1;
|
||||
majorVersion = 2;
|
||||
minorVersion = 0;
|
||||
profile = QGLFormat::NoProfile;
|
||||
}
|
||||
QGLFormatPrivate(const QGLFormatPrivate *other)
|
||||
: ref(1),
|
||||
opts(other->opts),
|
||||
pln(other->pln),
|
||||
depthSize(other->depthSize),
|
||||
accumSize(other->accumSize),
|
||||
stencilSize(other->stencilSize),
|
||||
redSize(other->redSize),
|
||||
greenSize(other->greenSize),
|
||||
blueSize(other->blueSize),
|
||||
alphaSize(other->alphaSize),
|
||||
numSamples(other->numSamples),
|
||||
swapInterval(other->swapInterval),
|
||||
majorVersion(other->majorVersion),
|
||||
minorVersion(other->minorVersion),
|
||||
profile(other->profile)
|
||||
{
|
||||
}
|
||||
QAtomicInt ref;
|
||||
QGL::FormatOptions opts;
|
||||
int pln;
|
||||
int depthSize;
|
||||
int accumSize;
|
||||
int stencilSize;
|
||||
int redSize;
|
||||
int greenSize;
|
||||
int blueSize;
|
||||
int alphaSize;
|
||||
int numSamples;
|
||||
int swapInterval;
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
QGLFormat::OpenGLContextProfile profile;
|
||||
};
|
||||
|
||||
class Q_OPENGL_EXPORT QGLWidgetPrivate : public QWidgetPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QGLWidget)
|
||||
public:
|
||||
QGLWidgetPrivate() : QWidgetPrivate()
|
||||
, disable_clear_on_painter_begin(false)
|
||||
, parent_changing(false)
|
||||
{
|
||||
}
|
||||
|
||||
~QGLWidgetPrivate() {}
|
||||
|
||||
void init(QGLContext *context, const QGLWidget* shareWidget);
|
||||
void initContext(QGLContext *context, const QGLWidget* shareWidget);
|
||||
bool renderCxPm(QPixmap *pixmap);
|
||||
void cleanupColormaps();
|
||||
void aboutToDestroy() override {
|
||||
if (glcx && !parent_changing)
|
||||
glcx->reset();
|
||||
}
|
||||
|
||||
bool makeCurrent();
|
||||
|
||||
QGLContext *glcx;
|
||||
QGLWidgetGLPaintDevice glDevice;
|
||||
bool autoSwap;
|
||||
|
||||
QGLColormap cmap;
|
||||
|
||||
bool disable_clear_on_painter_begin;
|
||||
bool parent_changing;
|
||||
};
|
||||
|
||||
// QGLContextPrivate has the responsibility of creating context groups.
|
||||
// QGLContextPrivate maintains the reference counter and destroys
|
||||
// context groups when needed.
|
||||
class QGLContextGroup
|
||||
{
|
||||
public:
|
||||
~QGLContextGroup();
|
||||
|
||||
const QGLContext *context() const {return m_context;}
|
||||
bool isSharing() const { return m_shares.size() >= 2; }
|
||||
QList<const QGLContext *> shares() const { return m_shares; }
|
||||
|
||||
static void addShare(const QGLContext *context, const QGLContext *share);
|
||||
static void removeShare(const QGLContext *context);
|
||||
|
||||
private:
|
||||
QGLContextGroup(const QGLContext *context);
|
||||
|
||||
const QGLContext *m_context; // context group's representative
|
||||
QList<const QGLContext *> m_shares;
|
||||
QAtomicInt m_refs;
|
||||
|
||||
friend class QGLContext;
|
||||
friend class QGLContextPrivate;
|
||||
friend class QGLContextGroupResourceBase;
|
||||
};
|
||||
|
||||
// Get the context that resources for "ctx" will transfer to once
|
||||
// "ctx" is destroyed. Returns null if nothing is sharing with ctx.
|
||||
const QGLContext *qt_gl_transfer_context(const QGLContext *);
|
||||
|
||||
/*
|
||||
QGLTemporaryContext - the main objective of this class is to have a way of
|
||||
creating a GL context and making it current, without going via QGLWidget
|
||||
and friends. At certain points during GL initialization we need a current
|
||||
context in order decide what GL features are available, and to resolve GL
|
||||
extensions. Having a light-weight way of creating such a context saves
|
||||
initial application startup time, and it doesn't wind up creating recursive
|
||||
conflicts.
|
||||
The class currently uses a private d pointer to hide the platform specific
|
||||
types. This could possibly been done inline with #ifdef'ery, but it causes
|
||||
major headaches on e.g. X11 due to namespace pollution.
|
||||
*/
|
||||
class QGLTemporaryContextPrivate;
|
||||
class QGLTemporaryContext {
|
||||
public:
|
||||
explicit QGLTemporaryContext(bool directRendering = true, QWidget *parent = nullptr);
|
||||
~QGLTemporaryContext();
|
||||
|
||||
private:
|
||||
QScopedPointer<QGLTemporaryContextPrivate> d;
|
||||
};
|
||||
|
||||
class QGLTexture;
|
||||
class QGLTextureDestroyer;
|
||||
|
||||
// This probably needs to grow to GL_MAX_VERTEX_ATTRIBS, but 3 is ok for now as that's
|
||||
// all the GL2 engine uses:
|
||||
#define QT_GL_VERTEX_ARRAY_TRACKED_COUNT 3
|
||||
|
||||
class QGLContextResourceBase;
|
||||
|
||||
class QGLContextPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QGLContext)
|
||||
public:
|
||||
explicit QGLContextPrivate(QGLContext *context);
|
||||
~QGLContextPrivate();
|
||||
QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format,
|
||||
QGLContext::BindOptions options);
|
||||
QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key,
|
||||
QGLContext::BindOptions options);
|
||||
QGLTexture *bindTexture(const QPixmap &pixmap, GLenum target, GLint format,
|
||||
QGLContext::BindOptions options);
|
||||
QGLTexture *textureCacheLookup(const qint64 key, GLenum target);
|
||||
void init(QPaintDevice *dev, const QGLFormat &format);
|
||||
int maxTextureSize();
|
||||
|
||||
void cleanup();
|
||||
|
||||
void setVertexAttribArrayEnabled(int arrayIndex, bool enabled = true);
|
||||
void syncGlState(); // Makes sure the GL context's state is what we think it is
|
||||
void swapRegion(const QRegion ®ion);
|
||||
|
||||
QOpenGLContext *guiGlContext;
|
||||
// true if QGLContext owns the QOpenGLContext (for who deletes who)
|
||||
bool ownContext;
|
||||
|
||||
void setupSharing();
|
||||
void refreshCurrentFbo();
|
||||
void setCurrentFbo(GLuint fbo);
|
||||
|
||||
QGLFormat glFormat;
|
||||
QGLFormat reqFormat;
|
||||
GLuint fbo;
|
||||
|
||||
uint valid : 1;
|
||||
uint sharing : 1;
|
||||
uint initDone : 1;
|
||||
uint crWin : 1;
|
||||
uint internal_context : 1;
|
||||
uint version_flags_cached : 1;
|
||||
|
||||
// workarounds for driver/hw bugs on different platforms
|
||||
uint workaround_needsFullClearOnEveryFrame : 1;
|
||||
uint workaround_brokenFBOReadBack : 1;
|
||||
uint workaround_brokenTexSubImage : 1;
|
||||
uint workaroundsCached : 1;
|
||||
|
||||
uint workaround_brokenTextureFromPixmap : 1;
|
||||
uint workaround_brokenTextureFromPixmap_init : 1;
|
||||
|
||||
uint workaround_brokenAlphaTexSubImage : 1;
|
||||
uint workaround_brokenAlphaTexSubImage_init : 1;
|
||||
|
||||
QPaintDevice *paintDevice;
|
||||
QSize readback_target_size;
|
||||
QColor transpColor;
|
||||
QGLContext *q_ptr;
|
||||
QGLFormat::OpenGLVersionFlags version_flags;
|
||||
|
||||
QGLContextGroup *group;
|
||||
GLint max_texture_size;
|
||||
|
||||
GLuint current_fbo;
|
||||
GLuint default_fbo;
|
||||
QPaintEngine *active_engine;
|
||||
QGLTextureDestroyer *texture_destroyer;
|
||||
|
||||
QGLFunctions *functions;
|
||||
|
||||
bool vertexAttributeArraysEnabledState[QT_GL_VERTEX_ARRAY_TRACKED_COUNT];
|
||||
|
||||
static inline QGLContextGroup *contextGroup(const QGLContext *ctx) { return ctx->d_ptr->group; }
|
||||
|
||||
static void setCurrentContext(QGLContext *context);
|
||||
};
|
||||
|
||||
// Temporarily make a context current if not already current or
|
||||
// shared with the current contex. The previous context is made
|
||||
// current when the object goes out of scope.
|
||||
class Q_OPENGL_EXPORT QGLShareContextScope
|
||||
{
|
||||
public:
|
||||
QGLShareContextScope(const QGLContext *ctx)
|
||||
: m_oldContext(nullptr)
|
||||
{
|
||||
QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext());
|
||||
if (currentContext != ctx && !QGLContext::areSharing(ctx, currentContext)) {
|
||||
m_oldContext = currentContext;
|
||||
m_ctx = const_cast<QGLContext *>(ctx);
|
||||
m_ctx->makeCurrent();
|
||||
} else {
|
||||
m_ctx = currentContext;
|
||||
}
|
||||
}
|
||||
|
||||
operator QGLContext *()
|
||||
{
|
||||
return m_ctx;
|
||||
}
|
||||
|
||||
QGLContext *operator->()
|
||||
{
|
||||
return m_ctx;
|
||||
}
|
||||
|
||||
~QGLShareContextScope()
|
||||
{
|
||||
if (m_oldContext)
|
||||
m_oldContext->makeCurrent();
|
||||
}
|
||||
|
||||
private:
|
||||
QGLContext *m_oldContext;
|
||||
QGLContext *m_ctx;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
Q_DECLARE_METATYPE(GLuint)
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_OPENGL_EXPORT QGLTextureDestroyer
|
||||
{
|
||||
public:
|
||||
void emitFreeTexture(QGLContext *context, QPlatformPixmap *, GLuint id) {
|
||||
if (context->contextHandle())
|
||||
(new QOpenGLSharedResourceGuard(context->contextHandle(), id, freeTextureFunc))->free();
|
||||
}
|
||||
|
||||
private:
|
||||
static void freeTextureFunc(QOpenGLFunctions *, GLuint id) {
|
||||
QOpenGLContext::currentContext()->functions()->glDeleteTextures(1, &id);
|
||||
}
|
||||
};
|
||||
|
||||
class Q_OPENGL_EXPORT QGLSignalProxy : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
void emitAboutToDestroyContext(const QGLContext *context) {
|
||||
emit aboutToDestroyContext(context);
|
||||
}
|
||||
static QGLSignalProxy *instance();
|
||||
Q_SIGNALS:
|
||||
void aboutToDestroyContext(const QGLContext *context);
|
||||
};
|
||||
|
||||
class QGLTexture {
|
||||
public:
|
||||
explicit QGLTexture(QGLContext *ctx = nullptr, GLuint tx_id = 0, GLenum tx_target = GL_TEXTURE_2D,
|
||||
QGLContext::BindOptions opt = QGLContext::DefaultBindOption)
|
||||
: context(ctx),
|
||||
id(tx_id),
|
||||
target(tx_target),
|
||||
options(opt)
|
||||
{}
|
||||
|
||||
~QGLTexture() {
|
||||
if (options & QGLContext::MemoryManagedBindOption) {
|
||||
Q_ASSERT(context);
|
||||
QPlatformPixmap *boundPixmap = nullptr;
|
||||
context->d_ptr->texture_destroyer->emitFreeTexture(context, boundPixmap, id);
|
||||
}
|
||||
}
|
||||
|
||||
QGLContext *context;
|
||||
GLuint id;
|
||||
GLenum target;
|
||||
|
||||
QGLContext::BindOptions options;
|
||||
|
||||
bool canBindCompressedTexture
|
||||
(const char *buf, int len, const char *format, bool *hasAlpha);
|
||||
QSize bindCompressedTexture
|
||||
(const QString& fileName, const char *format = nullptr);
|
||||
QSize bindCompressedTexture
|
||||
(const char *buf, int len, const char *format = nullptr);
|
||||
QSize bindCompressedTextureDDS(const char *buf, int len);
|
||||
QSize bindCompressedTexturePVR(const char *buf, int len);
|
||||
};
|
||||
|
||||
struct QGLTextureCacheKey {
|
||||
qint64 key;
|
||||
QGLContextGroup *group;
|
||||
};
|
||||
|
||||
inline bool operator==(const QGLTextureCacheKey &a, const QGLTextureCacheKey &b)
|
||||
{
|
||||
return a.key == b.key && a.group == b.group;
|
||||
}
|
||||
|
||||
inline uint qHash(const QGLTextureCacheKey &key)
|
||||
{
|
||||
return qHash(key.key) ^ qHash(key.group);
|
||||
}
|
||||
|
||||
|
||||
class Q_AUTOTEST_EXPORT QGLTextureCache {
|
||||
public:
|
||||
QGLTextureCache();
|
||||
~QGLTextureCache();
|
||||
|
||||
void insert(QGLContext *ctx, qint64 key, QGLTexture *texture, int cost);
|
||||
void remove(qint64 key);
|
||||
inline int size();
|
||||
inline void setMaxCost(int newMax);
|
||||
inline int maxCost();
|
||||
inline QGLTexture* getTexture(QGLContext *ctx, qint64 key);
|
||||
|
||||
bool remove(QGLContext *ctx, GLuint textureId);
|
||||
void removeContextTextures(QGLContext *ctx);
|
||||
static QGLTextureCache *instance();
|
||||
static void cleanupTexturesForCacheKey(qint64 cacheKey);
|
||||
static void cleanupTexturesForPixampData(QPlatformPixmap* pixmap);
|
||||
static void cleanupBeforePixmapDestruction(QPlatformPixmap* pixmap);
|
||||
|
||||
private:
|
||||
QCache<QGLTextureCacheKey, QGLTexture> m_cache;
|
||||
QReadWriteLock m_lock;
|
||||
};
|
||||
|
||||
int QGLTextureCache::size() {
|
||||
QReadLocker locker(&m_lock);
|
||||
return m_cache.size();
|
||||
}
|
||||
|
||||
void QGLTextureCache::setMaxCost(int newMax)
|
||||
{
|
||||
QWriteLocker locker(&m_lock);
|
||||
m_cache.setMaxCost(newMax);
|
||||
}
|
||||
|
||||
int QGLTextureCache::maxCost()
|
||||
{
|
||||
QReadLocker locker(&m_lock);
|
||||
return m_cache.maxCost();
|
||||
}
|
||||
|
||||
QGLTexture* QGLTextureCache::getTexture(QGLContext *ctx, qint64 key)
|
||||
{
|
||||
// Can't be a QReadLocker since QCache::object() modifies the cache (reprioritizes the object)
|
||||
QWriteLocker locker(&m_lock);
|
||||
const QGLTextureCacheKey cacheKey = {key, QGLContextPrivate::contextGroup(ctx)};
|
||||
return m_cache.object(cacheKey);
|
||||
}
|
||||
|
||||
Q_OPENGL_EXPORT extern QPaintEngine* qt_qgl_paint_engine();
|
||||
|
||||
QOpenGLExtensions* qgl_extensions();
|
||||
bool qgl_hasFeature(QOpenGLFunctions::OpenGLFeature feature);
|
||||
bool qgl_hasExtension(QOpenGLExtensions::OpenGLExtension extension);
|
||||
|
||||
// Put a guard around a GL object identifier and its context.
|
||||
// When the context goes away, a shared context will be used
|
||||
// in its place. If there are no more shared contexts, then
|
||||
// the identifier is returned as zero - it is assumed that the
|
||||
// context destruction cleaned up the identifier in this case.
|
||||
class QGLSharedResourceGuardBase : public QOpenGLSharedResource
|
||||
{
|
||||
public:
|
||||
QGLSharedResourceGuardBase(QGLContext *context, GLuint id)
|
||||
: QOpenGLSharedResource(context->contextHandle()->shareGroup())
|
||||
, m_id(id)
|
||||
{
|
||||
}
|
||||
|
||||
GLuint id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
protected:
|
||||
void invalidateResource() override
|
||||
{
|
||||
m_id = 0;
|
||||
}
|
||||
|
||||
void freeResource(QOpenGLContext *context) override
|
||||
{
|
||||
if (m_id) {
|
||||
freeResource(QGLContext::fromOpenGLContext(context), m_id);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void freeResource(QGLContext *ctx, GLuint id) = 0;
|
||||
|
||||
private:
|
||||
GLuint m_id;
|
||||
};
|
||||
|
||||
template <typename Func>
|
||||
class QGLSharedResourceGuard : public QGLSharedResourceGuardBase
|
||||
{
|
||||
public:
|
||||
QGLSharedResourceGuard(QGLContext *context, GLuint id, Func func)
|
||||
: QGLSharedResourceGuardBase(context, id)
|
||||
, m_func(func)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void freeResource(QGLContext *ctx, GLuint id) override
|
||||
{
|
||||
m_func(ctx, id);
|
||||
}
|
||||
|
||||
private:
|
||||
Func m_func;
|
||||
};
|
||||
|
||||
template <typename Func>
|
||||
QGLSharedResourceGuardBase *createSharedResourceGuard(QGLContext *context, GLuint id, Func cleanupFunc)
|
||||
{
|
||||
return new QGLSharedResourceGuard<Func>(context, id, cleanupFunc);
|
||||
}
|
||||
|
||||
// this is a class that wraps a QThreadStorage object for storing
|
||||
// thread local instances of the GL 1 and GL 2 paint engines
|
||||
|
||||
template <class T>
|
||||
class QGLEngineThreadStorage
|
||||
{
|
||||
public:
|
||||
QPaintEngine *engine() {
|
||||
QPaintEngine *&localEngine = storage.localData();
|
||||
if (!localEngine)
|
||||
localEngine = new T;
|
||||
return localEngine;
|
||||
}
|
||||
|
||||
private:
|
||||
QThreadStorage<QPaintEngine *> storage;
|
||||
};
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QGL_P_H
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -1,6 +1,2 @@
|
|||
TEMPLATE=subdirs
|
||||
SUBDIRS=\
|
||||
qgl \
|
||||
qglbuffer \
|
||||
qglfunctions \
|
||||
qglthreads \
|
||||
TEMPLATE = subdirs
|
||||
#SUBDIRS =
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
tst_qgl
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
[graphicsViewClipping]
|
||||
ubuntu-16.04
|
||||
rhel-7.6
|
||||
opensuse-leap
|
||||
ubuntu-18.04
|
||||
rhel-7.4
|
||||
opensuse-42.3
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file alias="designer.png">../../gui/image/qpixmap/images/designer.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
CONFIG += testcase
|
||||
TARGET = tst_qglfunctions
|
||||
requires(qtHaveModule(opengl))
|
||||
QT += opengl widgets testlib
|
||||
|
||||
SOURCES += tst_qglfunctions.cpp
|
||||
|
|
@ -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"
|
||||