summaryrefslogtreecommitdiffstats
path: root/examples/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'examples/opengl')
-rw-r--r--examples/opengl/2dpainting/CMakeLists.txt38
-rw-r--r--examples/opengl/CMakeLists.txt15
-rw-r--r--examples/opengl/computegles31/CMakeLists.txt46
-rw-r--r--examples/opengl/computegles31/Qt-logo-medium.pngbin24817 -> 0 bytes
-rw-r--r--examples/opengl/computegles31/computegles31.pro11
-rw-r--r--examples/opengl/computegles31/computegles31.qrc5
-rw-r--r--examples/opengl/computegles31/glwindow.cpp372
-rw-r--r--examples/opengl/computegles31/glwindow.h63
-rw-r--r--examples/opengl/computegles31/main.cpp101
-rw-r--r--examples/opengl/contextinfo/CMakeLists.txt36
-rw-r--r--examples/opengl/contextinfo/contextinfo.pro14
-rw-r--r--examples/opengl/contextinfo/main.cpp25
-rw-r--r--examples/opengl/contextinfo/renderwindow.cpp191
-rw-r--r--examples/opengl/contextinfo/renderwindow.h48
-rw-r--r--examples/opengl/contextinfo/widget.cpp358
-rw-r--r--examples/opengl/contextinfo/widget.h46
-rw-r--r--examples/opengl/cube/CMakeLists.txt38
-rw-r--r--examples/opengl/cube/cube.pngbin30341 -> 88913 bytes
-rw-r--r--examples/opengl/cube/mainwidget.cpp17
-rw-r--r--examples/opengl/doc/images/hellogles3-example.png (renamed from examples/opengl/hellogles3/doc/images/hellogles3-example.png)bin61792 -> 61792 bytes
-rw-r--r--examples/opengl/doc/images/stereoexample-leftbuffer.pngbin0 -> 9987 bytes
-rw-r--r--examples/opengl/doc/images/stereoexample-rightbuffer.pngbin0 -> 10002 bytes
-rw-r--r--examples/opengl/doc/src/2dpainting.qdoc1
-rw-r--r--examples/opengl/doc/src/cube.qdoc11
-rw-r--r--examples/opengl/doc/src/hellogl2.qdoc1
-rw-r--r--examples/opengl/doc/src/hellogles3.qdoc149
-rw-r--r--examples/opengl/doc/src/openglwindow.qdoc4
-rw-r--r--examples/opengl/doc/src/stereoqopenglwidget.qdoc46
-rw-r--r--examples/opengl/hellogl2/CMakeLists.txt38
-rw-r--r--examples/opengl/hellogl2/mainwindow.cpp18
-rw-r--r--examples/opengl/hellogl2/window.cpp80
-rw-r--r--examples/opengl/hellogl2/window.h12
-rw-r--r--examples/opengl/hellogles3/CMakeLists.txt34
-rw-r--r--examples/opengl/hellogles3/doc/src/hellogles3.qdoc22
-rw-r--r--examples/opengl/hellogles3/glwindow.h12
-rw-r--r--examples/opengl/hellowindow/CMakeLists.txt36
-rw-r--r--examples/opengl/hellowindow/hellowindow.cpp305
-rw-r--r--examples/opengl/hellowindow/hellowindow.h72
-rw-r--r--examples/opengl/hellowindow/hellowindow.pro9
-rw-r--r--examples/opengl/hellowindow/main.cpp125
-rw-r--r--examples/opengl/opengl.pro14
-rw-r--r--examples/opengl/openglwindow/CMakeLists.txt34
-rw-r--r--examples/opengl/openglwindow/main.cpp81
-rw-r--r--examples/opengl/openglwindow/openglwindow.h12
-rw-r--r--examples/opengl/paintedwindow/CMakeLists.txt34
-rw-r--r--examples/opengl/paintedwindow/main.cpp18
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.cpp185
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.h57
-rw-r--r--examples/opengl/paintedwindow/paintedwindow.pro8
-rw-r--r--examples/opengl/qopenglwidget/CMakeLists.txt50
-rw-r--r--examples/opengl/qopenglwidget/bubble.cpp99
-rw-r--r--examples/opengl/qopenglwidget/bubble.h39
-rw-r--r--examples/opengl/qopenglwidget/glwidget.cpp540
-rw-r--r--examples/opengl/qopenglwidget/glwidget.h85
-rw-r--r--examples/opengl/qopenglwidget/main.cpp43
-rw-r--r--examples/opengl/qopenglwidget/mainwindow.cpp188
-rw-r--r--examples/opengl/qopenglwidget/mainwindow.h39
-rw-r--r--examples/opengl/qopenglwidget/qopenglwidget.pro15
-rw-r--r--examples/opengl/qopenglwidget/qt.pngbin2991 -> 0 bytes
-rw-r--r--examples/opengl/qopenglwidget/texture.qrc5
-rw-r--r--examples/opengl/qopenglwindow/CMakeLists.txt46
-rw-r--r--examples/opengl/qopenglwindow/background.frag30
-rw-r--r--examples/opengl/qopenglwindow/background_renderer.cpp167
-rw-r--r--examples/opengl/qopenglwindow/background_renderer.h46
-rw-r--r--examples/opengl/qopenglwindow/main.cpp154
-rw-r--r--examples/opengl/qopenglwindow/qopenglwindow.pro16
-rw-r--r--examples/opengl/qopenglwindow/shaders.qrc5
-rw-r--r--examples/opengl/stereoqopenglwidget/CMakeLists.txt42
-rw-r--r--examples/opengl/stereoqopenglwidget/glwidget.cpp277
-rw-r--r--examples/opengl/stereoqopenglwidget/glwidget.h53
-rw-r--r--examples/opengl/stereoqopenglwidget/main.cpp31
-rw-r--r--examples/opengl/stereoqopenglwidget/mainwindow.cpp25
-rw-r--r--examples/opengl/stereoqopenglwidget/mainwindow.h (renamed from examples/opengl/threadedqopenglwidget/mainwindow.h)8
-rw-r--r--examples/opengl/stereoqopenglwidget/stereoqopenglwidget.pro11
-rw-r--r--examples/opengl/textures/CMakeLists.txt38
-rw-r--r--examples/opengl/textures/glwidget.cpp8
-rw-r--r--examples/opengl/textures/main.cpp2
-rw-r--r--examples/opengl/threadedqopenglwidget/CMakeLists.txt38
-rw-r--r--examples/opengl/threadedqopenglwidget/glwidget.cpp71
-rw-r--r--examples/opengl/threadedqopenglwidget/glwidget.h40
-rw-r--r--examples/opengl/threadedqopenglwidget/main.cpp88
-rw-r--r--examples/opengl/threadedqopenglwidget/mainwindow.cpp16
-rw-r--r--examples/opengl/threadedqopenglwidget/renderer.cpp267
-rw-r--r--examples/opengl/threadedqopenglwidget/renderer.h61
-rw-r--r--examples/opengl/threadedqopenglwidget/threadedqopenglwidget.pro13
85 files changed, 910 insertions, 4588 deletions
diff --git a/examples/opengl/2dpainting/CMakeLists.txt b/examples/opengl/2dpainting/CMakeLists.txt
index fe5698c747..b4ae3aa313 100644
--- a/examples/opengl/2dpainting/CMakeLists.txt
+++ b/examples/opengl/2dpainting/CMakeLists.txt
@@ -1,16 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(2dpainting LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/2dpainting")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets)
+qt_standard_project_setup()
+
qt_add_executable(2dpainting
glwidget.cpp glwidget.h
helper.cpp helper.h
@@ -24,16 +21,23 @@ set_target_properties(2dpainting PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(2dpainting PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
- Qt::OpenGLWidgets
- Qt::Widgets
+target_link_libraries(2dpainting PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::OpenGL
+ Qt6::OpenGLWidgets
+ Qt6::Widgets
)
install(TARGETS 2dpainting
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET 2dpainting
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/opengl/CMakeLists.txt b/examples/opengl/CMakeLists.txt
index 17d9c6da5a..09e31defe5 100644
--- a/examples/opengl/CMakeLists.txt
+++ b/examples/opengl/CMakeLists.txt
@@ -1,15 +1,12 @@
-qt_internal_add_example(hellowindow)
-qt_internal_add_example(paintedwindow)
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
qt_internal_add_example(openglwindow)
-qt_internal_add_example(qopenglwindow)
-if(TARGET Qt::Widgets)
- qt_internal_add_example(contextinfo)
- qt_internal_add_example(threadedqopenglwidget)
+qt_internal_add_example(hellogles3)
+if(TARGET Qt6::Widgets)
qt_internal_add_example(2dpainting)
qt_internal_add_example(hellogl2)
- qt_internal_add_example(qopenglwidget)
qt_internal_add_example(cube)
qt_internal_add_example(textures)
- qt_internal_add_example(hellogles3)
- qt_internal_add_example(computegles31)
+ qt_internal_add_example(stereoqopenglwidget)
endif()
diff --git a/examples/opengl/computegles31/CMakeLists.txt b/examples/opengl/computegles31/CMakeLists.txt
deleted file mode 100644
index de976ca00b..0000000000
--- a/examples/opengl/computegles31/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(computegles31 LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/computegles31")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL)
-
-qt_add_executable(computegles31
- glwindow.cpp glwindow.h
- main.cpp
-)
-
-set_target_properties(computegles31 PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(computegles31 PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
-)
-
-# Resources:
-set(computegles31_resource_files
- "Qt-logo-medium.png"
-)
-
-qt_add_resources(computegles31 "computegles31"
- PREFIX
- "/"
- FILES
- ${computegles31_resource_files}
-)
-
-install(TARGETS computegles31
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/opengl/computegles31/Qt-logo-medium.png b/examples/opengl/computegles31/Qt-logo-medium.png
deleted file mode 100644
index a1ca1f1830..0000000000
--- a/examples/opengl/computegles31/Qt-logo-medium.png
+++ /dev/null
Binary files differ
diff --git a/examples/opengl/computegles31/computegles31.pro b/examples/opengl/computegles31/computegles31.pro
deleted file mode 100644
index 8d9b00ba83..0000000000
--- a/examples/opengl/computegles31/computegles31.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-QT += opengl
-
-HEADERS = $$PWD/glwindow.h
-
-SOURCES = $$PWD/glwindow.cpp \
- $$PWD/main.cpp
-
-RESOURCES += computegles31.qrc
-
-target.path = $$[QT_INSTALL_EXAMPLES]/opengl/computegles31
-INSTALLS += target
diff --git a/examples/opengl/computegles31/computegles31.qrc b/examples/opengl/computegles31/computegles31.qrc
deleted file mode 100644
index b99eb0a82e..0000000000
--- a/examples/opengl/computegles31/computegles31.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/">
- <file>Qt-logo-medium.png</file>
- </qresource>
-</RCC>
diff --git a/examples/opengl/computegles31/glwindow.cpp b/examples/opengl/computegles31/glwindow.cpp
deleted file mode 100644
index 98533e714e..0000000000
--- a/examples/opengl/computegles31/glwindow.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "glwindow.h"
-#include <QImage>
-#include <QOpenGLShaderProgram>
-#include <QOpenGLContext>
-#include <QOpenGLFunctions>
-#include <QOpenGLExtraFunctions>
-#include <QOpenGLVertexArrayObject>
-#include <QtGui/qopengl.h>
-#include <QDebug>
-#include <QTimer>
-#include <math.h>
-
-#ifndef GL_READ_WRITE
-#define GL_READ_WRITE 0x88BA
-#endif
-
-#ifndef GL_RGBA8
-#define GL_RGBA8 0x8058
-#endif
-
-#ifndef GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
-#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
-#endif
-
-GLWindow::GLWindow()
-{
- const float animationStart = 0.0;
- const float animationEnd = 10.0;
- const float animationLength = 1000;
-
- m_animationGroup = new QSequentialAnimationGroup(this);
- m_animationGroup->setLoopCount(-1);
-
- m_animationForward = new QPropertyAnimation(this, QByteArrayLiteral("blurRadius"));
- m_animationForward->setStartValue(animationStart);
- m_animationForward->setEndValue(animationEnd);
- m_animationForward->setDuration(animationLength);
- m_animationGroup->addAnimation(m_animationForward);
-
- m_animationBackward = new QPropertyAnimation(this, QByteArrayLiteral("blurRadius"));
- m_animationBackward->setStartValue(animationEnd);
- m_animationBackward->setEndValue(animationStart);
- m_animationBackward->setDuration(animationLength);
- m_animationGroup->addAnimation(m_animationBackward);
-
- m_animationGroup->start();
-}
-
-GLWindow::~GLWindow()
-{
- makeCurrent();
- delete m_texImageInput;
- delete m_texImageProcessed;
- delete m_texImageTmp;
- delete m_shaderDisplay;
- delete m_shaderComputeH;
- delete m_shaderComputeV;
- delete m_animationGroup;
- delete m_animationForward;
- delete m_animationBackward;
- delete m_vao;
-}
-
-void GLWindow::setBlurRadius(float blurRadius)
-{
- int radius = int(blurRadius);
- if (radius != m_blurRadius) {
- m_blurRadius = radius;
- update();
- }
-}
-
-void GLWindow::setAnimating(bool animate)
-{
- m_animate = animate;
- if (animate)
- m_animationGroup->start();
- else
- m_animationGroup->stop();
-}
-
-void GLWindow::keyPressEvent(QKeyEvent *e)
-{
- if (e->key() == Qt::Key_Space) { // pause
- setAnimating(!m_animate);
- }
- update();
-}
-
-
-
-
-static const char *vsDisplaySource =
- "const vec4 vertices[4] = vec4[4] (\n"
- " vec4( -1.0, 1.0, 0.0, 1.0),\n"
- " vec4( -1.0, -1.0, 0.0, 1.0),\n"
- " vec4( 1.0, 1.0, 0.0, 1.0),\n"
- " vec4( 1.0, -1.0, 0.0, 1.0)\n"
- ");\n"
- "const vec2 texCoords[4] = vec2[4] (\n"
- " vec2( 0.0, 1.0),\n"
- " vec2( 0.0, 0.0),\n"
- " vec2( 1.0, 1.0),\n"
- " vec2( 1.0, 0.0)\n"
- ");\n"
- "out vec2 texCoord;\n"
- "uniform mat4 matProjection;\n"
- "uniform vec2 imageRatio;\n"
- "void main() {\n"
- " gl_Position = matProjection * ( vertices[gl_VertexID] * vec4(imageRatio,0,1) );\n"
- " texCoord = texCoords[gl_VertexID];\n"
- "}\n";
-
-static const char *fsDisplaySource =
- "in lowp vec2 texCoord; \n"
- "uniform sampler2D samImage; \n"
- "layout(location = 0) out lowp vec4 color;\n"
- "void main() {\n"
- " lowp vec4 texColor = texture(samImage,texCoord);\n"
- " color = vec4(texColor.rgb, 1.0);\n"
- "}\n";
-
-static const char *csComputeSourceV =
- "#define COMPUTEPATCHSIZE 10 // Setting this to 10 to comply with MAX_COMPUTE_WORK_GROUP_INVOCATIONS for both OpenGL and OpenGLES - see QTBUG-79374 \n"
- "#define IMGFMT rgba8 \n"
- "layout (local_size_x = COMPUTEPATCHSIZE, local_size_y = COMPUTEPATCHSIZE) in;\n"
- "layout(binding=0, IMGFMT) uniform readonly highp image2D inputImage; // Use a sampler to improve performance \n"
- "layout(binding=1, IMGFMT) uniform writeonly highp image2D resultImage;\n"
- "uniform int radius;\n"
- "const float cutoff = 2.2;\n"
-
- "float expFactor() { // a function, otherwise MESA produces error: initializer of global variable `expFactor' must be a constant expression\n"
- " float sigma = clamp(float(radius) / cutoff,0.02,100.0);\n"
- " return 1.0 / (2.0 * sigma * sigma);\n"
- "}\n"
-
- "float gaussian(float distance, float expfactor) {\n"
- " return exp( -(distance * distance) * expfactor);\n"
- "}\n"
-
- "void main() {\n"
- " ivec2 imgSize = imageSize(resultImage);\n"
- " int x = int(gl_GlobalInvocationID.x);\n"
- " int y = int(gl_GlobalInvocationID.y);\n"
- " if ( (x >= imgSize.x) || (y >= imgSize.y) ) return;\n"
- " vec4 sumPixels = vec4(0.0);\n"
- " float sumWeights = 0.0;\n"
- " int left = clamp(x - radius, 0, imgSize.x - 1);\n"
- " int right = clamp(x + radius, 0, imgSize.x - 1);\n"
- " int top = clamp(y - radius, 0, imgSize.y - 1);\n"
- " int bottom = clamp(y + radius, 0, imgSize.y - 1);\n"
- " float expfactor = expFactor();\n"
- " for (int iY = top; iY <= bottom; iY++) {\n"
- " float dy = float(abs(iY - y));\n"
- " vec4 imgValue = imageLoad(inputImage, ivec2(x,iY));\n"
- " float weight = gaussian(dy, expfactor);\n"
- " sumWeights += weight;\n"
- " sumPixels += (imgValue * weight);\n"
- " }\n"
- " sumPixels /= sumWeights;\n"
- " imageStore(resultImage, ivec2(x,y), sumPixels);\n"
- "}\n";
-
-static const char *csComputeSourceH =
- "#define COMPUTEPATCHSIZE 10 \n"
- "#define IMGFMT rgba8 \n"
- "layout (local_size_x = COMPUTEPATCHSIZE, local_size_y = COMPUTEPATCHSIZE) in;\n"
- "layout(binding=0, IMGFMT) uniform readonly highp image2D inputImage; // Use a sampler to improve performance \n"
- "layout(binding=1, IMGFMT) uniform writeonly highp image2D resultImage;\n"
- "uniform int radius;\n"
- "const float cutoff = 2.2;\n"
-
- "float expFactor() { // a function, otherwise MESA produces error: initializer of global variable `expFactor' must be a constant expression\n"
- " float sigma = clamp(float(radius) / cutoff,0.02,100.0);\n"
- " return 1.0 / (2.0 * sigma * sigma);\n"
- "}\n"
-
- "float gaussian(float distance, float expfactor) {\n"
- " return exp( -(distance * distance) * expfactor);\n"
- "}\n"
-
- "void main() {\n"
- " ivec2 imgSize = imageSize(resultImage);\n"
- " int x = int(gl_GlobalInvocationID.x);\n"
- " int y = int(gl_GlobalInvocationID.y);\n"
- " if ( (x >= imgSize.x) || (y >= imgSize.y) ) return;\n"
- " vec4 sumPixels = vec4(0.0);\n"
- " float sumWeights = 0.0;\n"
- " int left = clamp(x - radius, 0, imgSize.x - 1);\n"
- " int right = clamp(x + radius, 0, imgSize.x - 1);\n"
- " int top = clamp(y - radius, 0, imgSize.y - 1);\n"
- " int bottom = clamp(y + radius, 0, imgSize.y - 1);\n"
- " float expfactor = expFactor();\n"
- " for (int iX = left; iX <= right; iX++) {\n"
- " float dx = float(abs(iX - x));\n"
- " vec4 imgValue = imageLoad(inputImage, ivec2(iX,y));\n"
- " float weight = gaussian(dx, expfactor);\n"
- " sumWeights += weight;\n"
- " sumPixels += (imgValue * weight);\n"
- " }\n"
- " sumPixels /= sumWeights;\n"
- " imageStore(resultImage, ivec2(x,y), sumPixels);\n"
- "}\n";
-
-
-
-QByteArray versionedShaderCode(const char *src)
-{
- QByteArray versionedSrc;
-
- if (QOpenGLContext::currentContext()->isOpenGLES())
- versionedSrc.append(QByteArrayLiteral("#version 310 es\n"));
- else
- versionedSrc.append(QByteArrayLiteral("#version 430 core\n"));
-
- versionedSrc.append(src);
- return versionedSrc;
-}
-
-void computeProjection(int winWidth, int winHeight, int imgWidth, int imgHeight, QMatrix4x4 &outProjection, QSizeF &outQuadSize)
-{
- float ratioImg = float(imgWidth) / float(imgHeight);
- float ratioCanvas = float(winWidth) / float(winHeight);
-
- float correction = ratioImg / ratioCanvas;
- float rescaleFactor = 1.0f;
- float quadWidth = 1.0f;
- float quadHeight = 1.0f;
-
- if (correction < 1.0f) // canvas larger than image -- height = 1.0, vertical black bands
- {
- quadHeight = 1.0f;
- quadWidth = 1.0f * ratioImg;
- rescaleFactor = ratioCanvas;
- correction = 1.0f / rescaleFactor;
- }
- else // image larger than canvas -- width = 1.0, horizontal black bands
- {
- quadWidth = 1.0f;
- quadHeight = 1.0f / ratioImg;
- correction = 1.0f / ratioCanvas;
- }
-
- const float frustumWidth = 1.0f * rescaleFactor;
- const float frustumHeight = 1.0f * rescaleFactor * correction;
-
- outProjection = QMatrix4x4();
- outProjection.ortho(
- -frustumWidth,
- frustumWidth,
- -frustumHeight,
- frustumHeight,
- -1.0f,
- 1.0f);
- outQuadSize = QSizeF(quadWidth,quadHeight);
-}
-
-void GLWindow::initializeGL()
-{
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- qDebug() << "Got a "
- << ctx->format().majorVersion()
- << "."
- << ctx->format().minorVersion()
- << ((ctx->format().renderableType() == QSurfaceFormat::OpenGLES) ? (" GLES") : (" GL"))
- << " context";
-
- QImage img(":/Qt-logo-medium.png");
- Q_ASSERT(!img.isNull());
- delete m_texImageInput;
- m_texImageInput = new QOpenGLTexture(img.convertToFormat(QImage::Format_RGBA8888).mirrored());
-
- delete m_texImageTmp;
- m_texImageTmp = new QOpenGLTexture(QOpenGLTexture::Target2D);
- m_texImageTmp->setFormat(m_texImageInput->format());
- m_texImageTmp->setSize(m_texImageInput->width(),m_texImageInput->height());
- m_texImageTmp->allocateStorage(QOpenGLTexture::RGBA,QOpenGLTexture::UInt8); // WTF?
-
- delete m_texImageProcessed;
- m_texImageProcessed = new QOpenGLTexture(QOpenGLTexture::Target2D);
- m_texImageProcessed->setFormat(m_texImageInput->format());
- m_texImageProcessed->setSize(m_texImageInput->width(),m_texImageInput->height());
- m_texImageProcessed->allocateStorage(QOpenGLTexture::RGBA,QOpenGLTexture::UInt8);
-
- m_texImageProcessed->setMagnificationFilter(QOpenGLTexture::Linear);
- m_texImageProcessed->setMinificationFilter(QOpenGLTexture::Linear);
- m_texImageProcessed->setWrapMode(QOpenGLTexture::ClampToEdge);
-
- delete m_shaderDisplay;
- m_shaderDisplay = new QOpenGLShaderProgram;
- // Prepend the correct version directive to the sources. The rest is the
- // same, thanks to the common GLSL syntax.
- m_shaderDisplay->addShaderFromSourceCode(QOpenGLShader::Vertex, versionedShaderCode(vsDisplaySource));
- m_shaderDisplay->addShaderFromSourceCode(QOpenGLShader::Fragment, versionedShaderCode(fsDisplaySource));
- m_shaderDisplay->link();
-
- delete m_shaderComputeV;
- m_shaderComputeV = new QOpenGLShaderProgram;
- m_shaderComputeV->addShaderFromSourceCode(QOpenGLShader::Compute, versionedShaderCode(csComputeSourceV));
- m_shaderComputeV->link();
-
- delete m_shaderComputeH;
- m_shaderComputeH = new QOpenGLShaderProgram;
- m_shaderComputeH->addShaderFromSourceCode(QOpenGLShader::Compute, versionedShaderCode(csComputeSourceH));
- m_shaderComputeH->link();
-
- // Create a VAO. Not strictly required for ES 3, but it is for plain OpenGL core context.
- m_vao = new QOpenGLVertexArrayObject;
- m_vao->create();
-}
-
-void GLWindow::resizeGL(int w, int h)
-{
- computeProjection(w,h,m_texImageInput->width(),m_texImageInput->height(),m_proj,m_quadSize);
-}
-
-QSize getWorkGroups(int workGroupSize, const QSize &imageSize)
-{
- int x = imageSize.width();
- x = (x % workGroupSize) ? (x / workGroupSize) + 1 : (x / workGroupSize);
- int y = imageSize.height();
- y = (y % workGroupSize) ? (y / workGroupSize) + 1 : (y / workGroupSize);
- return QSize(x,y);
-}
-
-void GLWindow::paintGL()
-{
- // Now use QOpenGLExtraFunctions instead of QOpenGLFunctions as we want to
- // do more than what GL(ES) 2.0 offers.
- QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
-
-
- // Process input image
- QSize workGroups = getWorkGroups(10, QSize(m_texImageInput->width(), m_texImageInput->height()));
- // Pass 1
- f->glBindImageTexture(0, m_texImageInput->textureId(), 0, 0, 0, GL_READ_WRITE, GL_RGBA8);
- f->glBindImageTexture(1, m_texImageTmp->textureId(), 0, 0, 0, GL_READ_WRITE, GL_RGBA8);
- m_shaderComputeV->bind();
- m_shaderComputeV->setUniformValue("radius",m_blurRadius);
- f->glDispatchCompute(workGroups.width(),workGroups.height(),1);
- f->glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
- m_shaderComputeV->release();
- // Pass 2
- f->glBindImageTexture(0, m_texImageTmp->textureId(), 0, 0, 0, GL_READ_WRITE, GL_RGBA8);
- f->glBindImageTexture(1, m_texImageProcessed->textureId(), 0, 0, 0, GL_READ_WRITE, GL_RGBA8);
- m_shaderComputeH->bind();
- m_shaderComputeH->setUniformValue("radius",m_blurRadius);
- f->glDispatchCompute(workGroups.width(),workGroups.height(),1);
- f->glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
- m_shaderComputeH->release();
- // Compute cleanup
- f->glBindImageTexture(0, 0, 0, 0, 0, GL_READ_WRITE, GL_RGBA8);
- f->glBindImageTexture(1, 0, 0, 0, 0, GL_READ_WRITE, GL_RGBA8);
-
- // Display processed image
- f->glClearColor(0, 0, 0, 1);
- f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- m_texImageProcessed->bind(0);
- m_shaderDisplay->bind();
- m_shaderDisplay->setUniformValue("matProjection",m_proj);
- m_shaderDisplay->setUniformValue("imageRatio",m_quadSize);
- m_shaderDisplay->setUniformValue("samImage",0);
- m_vao->bind();
- f->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- m_vao->release();
- m_shaderDisplay->release();
- m_texImageProcessed->release(0);
-}
-
diff --git a/examples/opengl/computegles31/glwindow.h b/examples/opengl/computegles31/glwindow.h
deleted file mode 100644
index 268647a7aa..0000000000
--- a/examples/opengl/computegles31/glwindow.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef GLWIDGET_H
-#define GLWIDGET_H
-
-#include <QOpenGLWindow>
-#include <QOpenGLTexture>
-#include <QMatrix4x4>
-#include <QVector3D>
-#include <QKeyEvent>
-#include <QPropertyAnimation>
-#include <QSequentialAnimationGroup>
-#include <QRectF>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLTexture;
-class QOpenGLShaderProgram;
-class QOpenGLBuffer;
-class QOpenGLVertexArrayObject;
-
-QT_END_NAMESPACE
-
-class GLWindow : public QOpenGLWindow
-{
- Q_OBJECT
- Q_PROPERTY(float blurRadius READ blurRadius WRITE setBlurRadius)
-
-public:
- GLWindow();
- ~GLWindow();
-
- void initializeGL() override;
- void resizeGL(int w, int h) override;
- void paintGL() override;
-
- float blurRadius() const { return m_blurRadius; }
- void setBlurRadius(float blurRadius);
-
-protected:
- void keyPressEvent(QKeyEvent *e) override;
- void setAnimating(bool animate);
-
-private:
- QPropertyAnimation *m_animationForward = nullptr;
- QPropertyAnimation *m_animationBackward = nullptr;
- QSequentialAnimationGroup *m_animationGroup;
- QOpenGLTexture *m_texImageInput = nullptr;
- QOpenGLTexture *m_texImageTmp = nullptr;
- QOpenGLTexture *m_texImageProcessed = nullptr;
- QOpenGLShaderProgram *m_shaderDisplay = nullptr;
- QOpenGLShaderProgram *m_shaderComputeV = nullptr;
- QOpenGLShaderProgram *m_shaderComputeH = nullptr;
- QMatrix4x4 m_proj;
- QSizeF m_quadSize;
-
- int m_blurRadius = 0;
- bool m_animate = true;
- QOpenGLVertexArrayObject *m_vao = nullptr;
-};
-
-#endif
diff --git a/examples/opengl/computegles31/main.cpp b/examples/opengl/computegles31/main.cpp
deleted file mode 100644
index 6c29dd4de9..0000000000
--- a/examples/opengl/computegles31/main.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (C) 2017 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QGuiApplication>
-#include <QSurfaceFormat>
-#include <QOffscreenSurface>
-#include <QOpenGLContext>
-#include <QDebug>
-#include <QPair>
-#include "glwindow.h"
-
-bool OGLSupports(int major, int minor, bool gles = false, QSurfaceFormat::OpenGLContextProfile profile = QSurfaceFormat::NoProfile)
-{
- QOpenGLContext ctx;
- QSurfaceFormat fmt;
- fmt.setVersion(major, minor);
- if (gles) {
- fmt.setRenderableType(QSurfaceFormat::OpenGLES);
- } else {
- fmt.setRenderableType(QSurfaceFormat::OpenGL);
- fmt.setProfile(profile);
- }
-
- ctx.setFormat(fmt);
- ctx.create();
- if (!ctx.isValid())
- return false;
- int ctxMajor = ctx.format().majorVersion();
- int ctxMinor = ctx.format().minorVersion();
- bool isGles = (ctx.format().renderableType() == QSurfaceFormat::OpenGLES);
-
- if (isGles != gles) return false;
- if (ctxMajor < major) return false;
- if (ctxMajor == major && ctxMinor < minor)
- return false;
- if (!gles && ctx.format().profile() != profile)
- return false;
- return true;
-}
-
-int main(int argc, char *argv[])
-{
- QGuiApplication app(argc, argv);
-
- qDebug() << "Support for GL 2.0 noprof "<<( OGLSupports(2,0,false) ? "yes" : "no");
- qDebug() << "Support for GL 2.0 core "<<( OGLSupports(2,0,false, QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 2.0 compat "<<( OGLSupports(2,0,false, QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 2.1 noprof "<<( OGLSupports(2,1,false) ? "yes" : "no");
- qDebug() << "Support for GL 2.1 core "<<( OGLSupports(2,1,false, QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 2.1 compat "<<( OGLSupports(2,1,false, QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 3.0 noprof "<<( OGLSupports(3,0,false) ? "yes" : "no");
- qDebug() << "Support for GL 3.0 core "<<( OGLSupports(3,0,false, QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 3.0 compat "<<( OGLSupports(3,0,false, QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 3.1 noprof "<<( OGLSupports(3,1,false) ? "yes" : "no");
- qDebug() << "Support for GL 3.1 core "<<( OGLSupports(3,1,false, QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 3.1 compat "<<( OGLSupports(3,1,false, QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 3.2 core "<<( OGLSupports(3,2,false,QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 3.2 compat "<<( OGLSupports(3,2,false,QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 3.3 core "<<( OGLSupports(3,3,false,QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 3.3 compat "<<( OGLSupports(3,3,false,QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.0 core "<<( OGLSupports(4,0,false,QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.0 compat "<<( OGLSupports(4,0,false,QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.1 core "<<( OGLSupports(4,1,false,QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.1 compat "<<( OGLSupports(4,1,false,QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.2 core "<<( OGLSupports(4,2,false,QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.2 compat "<<( OGLSupports(4,2,false,QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.3 core "<<( OGLSupports(4,3,false,QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.3 compat "<<( OGLSupports(4,3,false,QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.4 core "<<( OGLSupports(4,4,false,QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.4 compat "<<( OGLSupports(4,4,false,QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.5 core "<<( OGLSupports(4,5,false,QSurfaceFormat::CoreProfile) ? "yes" : "no");
- qDebug() << "Support for GL 4.5 compat "<<( OGLSupports(4,5,false,QSurfaceFormat::CompatibilityProfile) ? "yes" : "no");
- qDebug() << "Support for GLES 2.0 "<<( OGLSupports(2,0,true) ? "yes" : "no");
- qDebug() << "Support for GLES 3.0 "<<( OGLSupports(3,0,true) ? "yes" : "no");
- qDebug() << "Support for GLES 3.1 "<<( OGLSupports(3,1,true) ? "yes" : "no");
- qDebug() << "Support for GLES 3.2 "<<( OGLSupports(3,2,true) ? "yes" : "no");
-
- QSurfaceFormat fmt;
- fmt.setDepthBufferSize(24);
-
- // Request OpenGL ES 3.1 context, as this is a GLES example. If not available, go for OpenGL 4.3 core.
- if (OGLSupports(3,1,true)) {
- qDebug("Requesting 3.1 GLES context");
- fmt.setVersion(3, 1);
- fmt.setRenderableType(QSurfaceFormat::OpenGLES);
- } else if (OGLSupports(4,3,false,QSurfaceFormat::CoreProfile)) {
- qDebug("Requesting 4.3 core context");
- fmt.setVersion(4, 3);
- fmt.setRenderableType(QSurfaceFormat::OpenGL);
- fmt.setProfile(QSurfaceFormat::CoreProfile);
- } else {
- qWarning("Error: This system does not support OpenGL Compute Shaders! Exiting.");
- return -1;
- }
- QSurfaceFormat::setDefaultFormat(fmt);
-
- GLWindow glWindow;
- glWindow.showMaximized();
-
- return app.exec();
-}
diff --git a/examples/opengl/contextinfo/CMakeLists.txt b/examples/opengl/contextinfo/CMakeLists.txt
deleted file mode 100644
index 0e51378082..0000000000
--- a/examples/opengl/contextinfo/CMakeLists.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(contextinfo LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/contextinfo")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL Widgets)
-
-qt_add_executable(contextinfo
- main.cpp
- renderwindow.cpp renderwindow.h
- widget.cpp widget.h
-)
-
-set_target_properties(contextinfo PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(contextinfo PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
- Qt::Widgets
-)
-
-install(TARGETS contextinfo
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/opengl/contextinfo/contextinfo.pro b/examples/opengl/contextinfo/contextinfo.pro
deleted file mode 100644
index ae8f4067b6..0000000000
--- a/examples/opengl/contextinfo/contextinfo.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-TEMPLATE = app
-QT += widgets opengl
-requires(qtConfig(filedialog))
-
-SOURCES += main.cpp \
- widget.cpp \
- renderwindow.cpp
-
-HEADERS += widget.h \
- renderwindow.h
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/opengl/contextinfo
-INSTALLS += target
diff --git a/examples/opengl/contextinfo/main.cpp b/examples/opengl/contextinfo/main.cpp
deleted file mode 100644
index 253425ded9..0000000000
--- a/examples/opengl/contextinfo/main.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QApplication>
-#include "widget.h"
-
-int main(int argc, char **argv)
-{
- for (int i = 1; i < argc; ++i) {
- if (!qstrcmp(argv[i], "-g"))
- QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
- else if (!qstrcmp(argv[i], "-s"))
- QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
- else if (!qstrcmp(argv[i], "-d"))
- QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
- }
-
- QApplication app(argc, argv);
-
- Widget w;
- w.resize(700, 800);
- w.show();
-
- return app.exec();
-}
diff --git a/examples/opengl/contextinfo/renderwindow.cpp b/examples/opengl/contextinfo/renderwindow.cpp
deleted file mode 100644
index 64c0f47db9..0000000000
--- a/examples/opengl/contextinfo/renderwindow.cpp
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "renderwindow.h"
-#include <QTimer>
-#include <QMatrix4x4>
-#include <QOpenGLContext>
-#include <QtOpenGL/QOpenGLShaderProgram>
-#include <QOpenGLFunctions>
-
-RenderWindow::RenderWindow(const QSurfaceFormat &format)
- : m_context(nullptr),
- m_initialized(false),
- m_forceGLSL110(false),
- m_angle(0.0f)
-{
- setSurfaceType(QWindow::OpenGLSurface);
- setFormat(format);
- m_context = new QOpenGLContext(this);
- m_context->setFormat(requestedFormat());
- if (!m_context->create()) {
- delete m_context;
- m_context = nullptr;
- }
-}
-
-void RenderWindow::exposeEvent(QExposeEvent *)
-{
- if (isExposed())
- render();
-}
-
-// ES needs the precision qualifiers.
-// On desktop GL QOpenGLShaderProgram inserts dummy defines for highp/mediump/lowp.
-static const char *vertexShaderSource110 =
- "attribute highp vec4 posAttr;\n"
- "attribute lowp vec4 colAttr;\n"
- "varying lowp vec4 col;\n"
- "uniform highp mat4 matrix;\n"
- "void main() {\n"
- " col = colAttr;\n"
- " gl_Position = matrix * posAttr;\n"
- "}\n";
-
-static const char *fragmentShaderSource110 =
- "varying lowp vec4 col;\n"
- "void main() {\n"
- " gl_FragColor = col;\n"
- "}\n";
-
-static const char *vertexShaderSource =
- "#version 150\n"
- "in vec4 posAttr;\n"
- "in vec4 colAttr;\n"
- "out vec4 col;\n"
- "uniform mat4 matrix;\n"
- "void main() {\n"
- " col = colAttr;\n"
- " gl_Position = matrix * posAttr;\n"
- "}\n";
-
-static const char *fragmentShaderSource =
- "#version 150\n"
- "in vec4 col;\n"
- "out vec4 fragColor;\n"
- "void main() {\n"
- " fragColor = col;\n"
- "}\n";
-
-static GLfloat vertices[] = {
- 0.0f, 0.707f,
- -0.5f, -0.5f,
- 0.5f, -0.5f
-};
-
-static GLfloat colors[] = {
- 1.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 1.0f
-};
-
-void RenderWindow::init()
-{
- m_program = new QOpenGLShaderProgram(this);
-
- QSurfaceFormat format = m_context->format();
- bool useNewStyleShader = format.profile() == QSurfaceFormat::CoreProfile;
- // Try to handle 3.0 & 3.1 that do not have the core/compatibility profile concept 3.2+ has.
- // This may still fail since version 150 (3.2) is specified in the sources but it's worth a try.
- if (format.renderableType() == QSurfaceFormat::OpenGL && format.majorVersion() == 3 && format.minorVersion() <= 1)
- useNewStyleShader = !format.testOption(QSurfaceFormat::DeprecatedFunctions);
- if (m_forceGLSL110)
- useNewStyleShader = false;
-
- const char *vsrc = useNewStyleShader ? vertexShaderSource : vertexShaderSource110;
- const char *fsrc = useNewStyleShader ? fragmentShaderSource : fragmentShaderSource110;
- qDebug("Using version %s shader", useNewStyleShader ? "150" : "110");
-
- if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc)) {
- emit error(m_program->log());
- return;
- }
- if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc)) {
- emit error(m_program->log());
- return;
- }
- if (!m_program->link()) {
- emit error(m_program->log());
- return;
- }
-
- m_posAttr = m_program->attributeLocation("posAttr");
- m_colAttr = m_program->attributeLocation("colAttr");
- m_matrixUniform = m_program->uniformLocation("matrix");
-
- m_vbo.create();
- m_vbo.bind();
- m_vbo.allocate(vertices, sizeof(vertices) + sizeof(colors));
- m_vbo.write(sizeof(vertices), colors, sizeof(colors));
- m_vbo.release();
-
- QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
- if (m_vao.isCreated()) // have VAO support, use it
- setupVertexAttribs();
-}
-
-void RenderWindow::setupVertexAttribs()
-{
- m_vbo.bind();
- m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 2);
- m_program->setAttributeBuffer(m_colAttr, GL_FLOAT, sizeof(vertices), 3);
- m_program->enableAttributeArray(m_posAttr);
- m_program->enableAttributeArray(m_colAttr);
- m_vbo.release();
-}
-
-bool RenderWindow::event(QEvent *ev)
-{
- if (ev->type() == QEvent::UpdateRequest)
- render();
- return QWindow::event(ev);
-}
-
-void RenderWindow::render()
-{
- if (!m_context->makeCurrent(this)) {
- emit error(tr("makeCurrent() failed"));
- return;
- }
-
- QOpenGLFunctions *f = m_context->functions();
- if (!m_initialized) {
- m_initialized = true;
- f->glEnable(GL_DEPTH_TEST);
- f->glClearColor(0, 0, 0, 1);
- init();
- emit ready();
- }
-
- if (!m_vbo.isCreated()) // init() failed, don't bother with trying to render
- return;
-
- const qreal retinaScale = devicePixelRatio();
- f->glViewport(0, 0, width() * retinaScale, height() * retinaScale);
- f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- m_program->bind();
- QMatrix4x4 matrix;
- matrix.perspective(60.0f, 4.0f / 3.0f, 0.1f, 100.0f);
- matrix.translate(0.0f, 0.0f, -2.0f);
- matrix.rotate(m_angle, 0.0f, 1.0f, 0.0f);
- m_program->setUniformValue(m_matrixUniform, matrix);
-
- if (m_vao.isCreated())
- m_vao.bind();
- else // no VAO support, set the vertex attribute arrays now
- setupVertexAttribs();
-
- f->glDrawArrays(GL_TRIANGLES, 0, 3);
-
- m_vao.release();
- m_program->release();
-
- // swapInterval is 1 by default which means that swapBuffers() will (hopefully) block
- // and wait for vsync.
- m_context->swapBuffers(this);
-
- m_angle += 1.0f;
-
- requestUpdate();
-}
diff --git a/examples/opengl/contextinfo/renderwindow.h b/examples/opengl/contextinfo/renderwindow.h
deleted file mode 100644
index 964dd601a6..0000000000
--- a/examples/opengl/contextinfo/renderwindow.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef RENDERWINDOW_H
-#define RENDERWINDOW_H
-
-#include <QWindow>
-#include <QOpenGLVertexArrayObject>
-#include <QOpenGLBuffer>
-
-QT_FORWARD_DECLARE_CLASS(QOpenGLContext)
-QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
-
-class RenderWindow : public QWindow
-{
- Q_OBJECT
-
-public:
- RenderWindow(const QSurfaceFormat &format);
- QOpenGLContext *context() { return m_context; }
- void exposeEvent(QExposeEvent *) override;
- void setForceGLSL110(bool enable) { m_forceGLSL110 = enable; }
-
-signals:
- void ready();
- void error(const QString &msg);
-
-protected:
- bool event(QEvent *ev) override;
-
-private slots:
- void render();
-
-private:
- void init();
- void setupVertexAttribs();
-
- QOpenGLContext *m_context;
- bool m_initialized;
- bool m_forceGLSL110;
- QOpenGLShaderProgram *m_program;
- int m_posAttr, m_colAttr, m_matrixUniform;
- QOpenGLVertexArrayObject m_vao;
- QOpenGLBuffer m_vbo;
- float m_angle;
-};
-
-#endif // RENDERWINDOW_H
diff --git a/examples/opengl/contextinfo/widget.cpp b/examples/opengl/contextinfo/widget.cpp
deleted file mode 100644
index a4ae397382..0000000000
--- a/examples/opengl/contextinfo/widget.cpp
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "widget.h"
-#include "renderwindow.h"
-#include <QVBoxLayout>
-#include <QComboBox>
-#include <QGroupBox>
-#include <QRadioButton>
-#include <QCheckBox>
-#include <QHBoxLayout>
-#include <QLabel>
-#include <QList>
-#include <QByteArray>
-#include <QPushButton>
-#include <QTextEdit>
-#include <QSplitter>
-#include <QGuiApplication>
-#include <QSurfaceFormat>
-#include <QOpenGLContext>
-#include <QOpenGLFunctions>
-#include <QDebug>
-#include <QTextStream>
-
-struct Version {
- const char *str;
- int major;
- int minor;
-};
-
-static struct Version versions[] = {
- { "1.0", 1, 0 },
- { "1.1", 1, 1 },
- { "1.2", 1, 2 },
- { "1.3", 1, 3 },
- { "1.4", 1, 4 },
- { "1.5", 1, 5 },
- { "2.0", 2, 0 },
- { "2.1", 2, 1 },
- { "3.0", 3, 0 },
- { "3.1", 3, 1 },
- { "3.2", 3, 2 },
- { "3.3", 3, 3 },
- { "4.0", 4, 0 },
- { "4.1", 4, 1 },
- { "4.2", 4, 2 },
- { "4.3", 4, 3 },
- { "4.4", 4, 4 },
- { "4.5", 4, 5 }
-};
-
-struct Profile {
- const char *str;
- QSurfaceFormat::OpenGLContextProfile profile;
-};
-
-static struct Profile profiles[] = {
- { "none", QSurfaceFormat::NoProfile },
- { "core", QSurfaceFormat::CoreProfile },
- { "compatibility", QSurfaceFormat::CompatibilityProfile }
-};
-
-struct Option {
- const char *str;
- QSurfaceFormat::FormatOption option;
-};
-
-static struct Option options[] = {
- { "deprecated functions (not forward compatible)", QSurfaceFormat::DeprecatedFunctions },
- { "debug context", QSurfaceFormat::DebugContext },
- { "stereo buffers", QSurfaceFormat::StereoBuffers },
- // This is not a QSurfaceFormat option but is helpful to determine if the driver
- // allows compiling old-style shaders with core profile.
- { "force version 110 shaders", QSurfaceFormat::FormatOption(0) }
-};
-
-struct Renderable {
- const char *str;
- QSurfaceFormat::RenderableType renderable;
-};
-
-static struct Renderable renderables[] = {
- { "default", QSurfaceFormat::DefaultRenderableType },
- { "OpenGL", QSurfaceFormat::OpenGL },
- { "OpenGL ES", QSurfaceFormat::OpenGLES }
-};
-
-void Widget::addVersions(QLayout *layout)
-{
- QHBoxLayout *hbox = new QHBoxLayout;
- hbox->setSpacing(20);
- QLabel *label = new QLabel(tr("Context &version: "));
- hbox->addWidget(label);
- m_version = new QComboBox;
- m_version->setMinimumWidth(60);
- label->setBuddy(m_version);
- hbox->addWidget(m_version);
- for (size_t i = 0; i < sizeof(versions) / sizeof(Version); ++i) {
- m_version->addItem(QString::fromLatin1(versions[i].str));
- if (versions[i].major == 2 && versions[i].minor == 0)
- m_version->setCurrentIndex(m_version->count() - 1);
- }
-
- QPushButton *btn = new QPushButton(tr("Create context"));
- connect(btn, &QPushButton::clicked, this, &Widget::start);
- btn->setMinimumSize(120, 40);
- hbox->addWidget(btn);
-
- layout->addItem(hbox);
-}
-
-void Widget::addProfiles(QLayout *layout)
-{
- QGroupBox *groupBox = new QGroupBox(tr("Profile"));
- QVBoxLayout *vbox = new QVBoxLayout;
- for (size_t i = 0; i < sizeof(profiles) / sizeof(Profile); ++i)
- vbox->addWidget(new QRadioButton(QString::fromLatin1(profiles[i].str)));
- static_cast<QRadioButton *>(vbox->itemAt(0)->widget())->setChecked(true);
- groupBox->setLayout(vbox);
- layout->addWidget(groupBox);
- m_profiles = vbox;
-}
-
-void Widget::addOptions(QLayout *layout)
-{
- QGroupBox *groupBox = new QGroupBox(tr("Options"));
- QVBoxLayout *vbox = new QVBoxLayout;
- for (size_t i = 0; i < sizeof(options) / sizeof(Option); ++i)
- vbox->addWidget(new QCheckBox(QString::fromLatin1(options[i].str)));
- groupBox->setLayout(vbox);
- layout->addWidget(groupBox);
- m_options = vbox;
-}
-
-void Widget::addRenderableTypes(QLayout *layout)
-{
- QGroupBox *groupBox = new QGroupBox(tr("Renderable type"));
- QVBoxLayout *vbox = new QVBoxLayout;
- for (size_t i = 0; i < sizeof(renderables) / sizeof(Renderable); ++i)
- vbox->addWidget(new QRadioButton(QString::fromLatin1(renderables[i].str)));
- static_cast<QRadioButton *>(vbox->itemAt(0)->widget())->setChecked(true);
- groupBox->setLayout(vbox);
- layout->addWidget(groupBox);
- m_renderables = vbox;
-}
-
-void Widget::addRenderWindow()
-{
- m_renderWindowLayout->addWidget(m_renderWindowContainer);
-}
-
-static QWidget *widgetWithLayout(QLayout *layout)
-{
- QWidget *w = new QWidget;
- w->setLayout(layout);
- return w;
-}
-
-Widget::Widget(QWidget *parent)
- : QWidget(parent)
-{
- QVBoxLayout *layout = new QVBoxLayout;
- QSplitter *vsplit = new QSplitter(Qt::Vertical);
- layout->addWidget(vsplit);
-
- QSplitter *hsplit = new QSplitter;
-
- QVBoxLayout *settingsLayout = new QVBoxLayout;
- addVersions(settingsLayout);
- addProfiles(settingsLayout);
- addOptions(settingsLayout);
- addRenderableTypes(settingsLayout);
- hsplit->addWidget(widgetWithLayout(settingsLayout));
-
- QVBoxLayout *outputLayout = new QVBoxLayout;
- m_output = new QTextEdit;
- m_output->setReadOnly(true);
- outputLayout->addWidget(m_output);
- m_extensions = new QTextEdit;
- m_extensions->setReadOnly(true);
- outputLayout->addWidget(m_extensions);
- hsplit->addWidget(widgetWithLayout(outputLayout));
-
- hsplit->setStretchFactor(0, 4);
- hsplit->setStretchFactor(1, 6);
- vsplit->addWidget(hsplit);
-
- m_renderWindowLayout = new QVBoxLayout;
- vsplit->addWidget(widgetWithLayout(m_renderWindowLayout));
- vsplit->setStretchFactor(1, 5);
-
- m_renderWindowContainer = new QWidget;
- addRenderWindow();
-
- QString description;
- QTextStream str(&description);
- str << "Qt " << QT_VERSION_STR << ' ' << QGuiApplication::platformName();
- const char *openGlVariables[] =
- {"QT_ANGLE_PLATFORM", "QT_OPENGL", "QT_OPENGL_BUGLIST", "QT_OPENGL_DLL"};
- const size_t variableCount = sizeof(openGlVariables) / sizeof(openGlVariables[0]);
- for (size_t v = 0; v < variableCount; ++v) {
- if (qEnvironmentVariableIsSet(openGlVariables[v]))
- str << ' ' << openGlVariables[v] << '=' << qgetenv(openGlVariables[v]);
- }
- if (QCoreApplication::testAttribute(Qt::AA_UseOpenGLES))
- str << " Qt::AA_UseOpenGLES";
- if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
- str << " Qt::AA_UseSoftwareOpenGL";
- if (QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL))
- str << " Qt::AA_UseDesktopOpenGL";
- layout->addWidget(new QLabel(description));
-
- setLayout(layout);
-}
-
-void Widget::start()
-{
- QSurfaceFormat fmt;
-
- int idx = m_version->currentIndex();
- if (idx < 0)
- return;
- fmt.setVersion(versions[idx].major, versions[idx].minor);
-
- for (size_t i = 0; i < sizeof(profiles) / sizeof(Profile); ++i)
- if (static_cast<QRadioButton *>(m_profiles->itemAt(int(i))->widget())->isChecked()) {
- fmt.setProfile(profiles[i].profile);
- break;
- }
-
- bool forceGLSL110 = false;
- for (size_t i = 0; i < sizeof(options) / sizeof(Option); ++i)
- if (static_cast<QCheckBox *>(m_options->itemAt(int(i))->widget())->isChecked()) {
- if (options[i].option)
- fmt.setOption(options[i].option);
- else if (i == 3)
- forceGLSL110 = true;
- }
-
- for (size_t i = 0; i < sizeof(renderables) / sizeof(Renderable); ++i)
- if (static_cast<QRadioButton *>(m_renderables->itemAt(int(i))->widget())->isChecked()) {
- fmt.setRenderableType(renderables[i].renderable);
- break;
- }
-
- // The example rendering will need a depth buffer.
- fmt.setDepthBufferSize(16);
-
- m_output->clear();
- m_extensions->clear();
- qDebug() << "Requesting surface format" << fmt;
-
- m_renderWindowLayout->removeWidget(m_renderWindowContainer);
- delete m_renderWindowContainer;
-
- RenderWindow *renderWindow = new RenderWindow(fmt);
- if (!renderWindow->context()) {
- m_output->append(tr("Failed to create context"));
- delete renderWindow;
- m_renderWindowContainer = new QWidget;
- addRenderWindow();
- return;
- }
- m_surface = renderWindow;
-
- renderWindow->setForceGLSL110(forceGLSL110);
- connect(renderWindow, &RenderWindow::ready, this, &Widget::renderWindowReady);
- connect(renderWindow, &RenderWindow::error, this, &Widget::renderWindowError);
-
- m_renderWindowContainer = QWidget::createWindowContainer(renderWindow);
- addRenderWindow();
-}
-
-void Widget::printFormat(const QSurfaceFormat &format)
-{
- m_output->append(tr("OpenGL version: %1.%2").arg(format.majorVersion()).arg(format.minorVersion()));
-
- for (size_t i = 0; i < sizeof(profiles) / sizeof(Profile); ++i)
- if (profiles[i].profile == format.profile()) {
- m_output->append(tr("Profile: %1").arg(QString::fromLatin1(profiles[i].str)));
- break;
- }
-
- QString opts;
- for (size_t i = 0; i < sizeof(options) / sizeof(Option); ++i)
- if (format.testOption(options[i].option))
- opts += QString::fromLatin1(options[i].str) + QLatin1Char(' ');
- m_output->append(tr("Options: %1").arg(opts));
-
- for (size_t i = 0; i < sizeof(renderables) / sizeof(Renderable); ++i)
- if (renderables[i].renderable == format.renderableType()) {
- m_output->append(tr("Renderable type: %1").arg(QString::fromLatin1(renderables[i].str)));
- break;
- }
-
- m_output->append(tr("Depth buffer size: %1").arg(QString::number(format.depthBufferSize())));
- m_output->append(tr("Stencil buffer size: %1").arg(QString::number(format.stencilBufferSize())));
- m_output->append(tr("Samples: %1").arg(QString::number(format.samples())));
- m_output->append(tr("Red buffer size: %1").arg(QString::number(format.redBufferSize())));
- m_output->append(tr("Green buffer size: %1").arg(QString::number(format.greenBufferSize())));
- m_output->append(tr("Blue buffer size: %1").arg(QString::number(format.blueBufferSize())));
- m_output->append(tr("Alpha buffer size: %1").arg(QString::number(format.alphaBufferSize())));
- m_output->append(tr("Swap interval: %1").arg(QString::number(format.swapInterval())));
-}
-
-void Widget::renderWindowReady()
-{
- QOpenGLContext *context = QOpenGLContext::currentContext();
- Q_ASSERT(context);
-
- QString vendor, renderer, version, glslVersion;
- const GLubyte *p;
- QOpenGLFunctions *f = context->functions();
- if ((p = f->glGetString(GL_VENDOR)))
- vendor = QString::fromLatin1(reinterpret_cast<const char *>(p));
- if ((p = f->glGetString(GL_RENDERER)))
- renderer = QString::fromLatin1(reinterpret_cast<const char *>(p));
- if ((p = f->glGetString(GL_VERSION)))
- version = QString::fromLatin1(reinterpret_cast<const char *>(p));
- if ((p = f->glGetString(GL_SHADING_LANGUAGE_VERSION)))
- glslVersion = QString::fromLatin1(reinterpret_cast<const char *>(p));
-
- m_output->append(tr("*** Context information ***"));
- m_output->append(tr("Vendor: %1").arg(vendor));
- m_output->append(tr("Renderer: %1").arg(renderer));
- m_output->append(tr("OpenGL version: %1").arg(version));
- m_output->append(tr("GLSL version: %1").arg(glslVersion));
-
- m_output->append(tr("\n*** QSurfaceFormat from context ***"));
- printFormat(context->format());
-
- m_output->append(tr("\n*** QSurfaceFormat from window surface ***"));
- printFormat(m_surface->format());
-
- m_output->append(tr("\n*** Qt build information ***"));
- const char *gltype[] = { "Desktop", "GLES 2", "GLES 1" };
- m_output->append(tr("Qt OpenGL configuration: %1")
- .arg(QString::fromLatin1(gltype[QOpenGLContext::openGLModuleType()])));
-#if defined(Q_OS_WIN)
- using namespace QNativeInterface;
- m_output->append(tr("Qt OpenGL library handle: %1")
- .arg(QString::number(qintptr(QWGLContext::openGLModuleHandle()), 16)));
-#endif
-
- QList<QByteArray> extensionList = context->extensions().values();
- std::sort(extensionList.begin(), extensionList.end());
- m_extensions->append(tr("Found %1 extensions:").arg(extensionList.count()));
- for (const QByteArray &ext : qAsConst(extensionList))
- m_extensions->append(QString::fromLatin1(ext));
-
- m_output->moveCursor(QTextCursor::Start);
- m_extensions->moveCursor(QTextCursor::Start);
-}
-
-void Widget::renderWindowError(const QString &msg)
-{
- m_output->append(tr("An error has occurred:\n%1").arg(msg));
-}
diff --git a/examples/opengl/contextinfo/widget.h b/examples/opengl/contextinfo/widget.h
deleted file mode 100644
index e5c31fcaa7..0000000000
--- a/examples/opengl/contextinfo/widget.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef WIDGET_H
-#define WIDGET_H
-
-#include <QWidget>
-
-QT_FORWARD_DECLARE_CLASS(QComboBox)
-QT_FORWARD_DECLARE_CLASS(QTextEdit)
-QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
-QT_FORWARD_DECLARE_CLASS(QSurfaceFormat)
-QT_FORWARD_DECLARE_CLASS(QSurface)
-
-class Widget : public QWidget
-{
- Q_OBJECT
-
-public:
- explicit Widget(QWidget *parent = nullptr);
-
-private slots:
- void start();
- void renderWindowReady();
- void renderWindowError(const QString &msg);
-
-private:
- void addVersions(QLayout *layout);
- void addProfiles(QLayout *layout);
- void addOptions(QLayout *layout);
- void addRenderableTypes(QLayout *layout);
- void addRenderWindow();
- void printFormat(const QSurfaceFormat &format);
-
- QComboBox *m_version;
- QLayout *m_profiles;
- QLayout *m_options;
- QLayout *m_renderables;
- QTextEdit *m_output;
- QTextEdit *m_extensions;
- QVBoxLayout *m_renderWindowLayout;
- QWidget *m_renderWindowContainer;
- QSurface *m_surface;
-};
-
-#endif // WIDGET_H
diff --git a/examples/opengl/cube/CMakeLists.txt b/examples/opengl/cube/CMakeLists.txt
index 62832e4675..7486d058a4 100644
--- a/examples/opengl/cube/CMakeLists.txt
+++ b/examples/opengl/cube/CMakeLists.txt
@@ -1,16 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(cube LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/cube")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets)
+qt_standard_project_setup()
+
qt_add_executable(cube
geometryengine.cpp geometryengine.h
main.cpp
@@ -22,12 +19,12 @@ set_target_properties(cube PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(cube PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
- Qt::OpenGLWidgets
- Qt::Widgets
+target_link_libraries(cube PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::OpenGL
+ Qt6::OpenGLWidgets
+ Qt6::Widgets
)
# Resources:
@@ -55,7 +52,14 @@ qt6_add_resources(cube "textures"
)
install(TARGETS cube
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET cube
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/opengl/cube/cube.png b/examples/opengl/cube/cube.png
index 42c8c51b3a..c3abbfe84d 100644
--- a/examples/opengl/cube/cube.png
+++ b/examples/opengl/cube/cube.png
Binary files differ
diff --git a/examples/opengl/cube/mainwidget.cpp b/examples/opengl/cube/mainwidget.cpp
index 485bca54f4..e67c93da5a 100644
--- a/examples/opengl/cube/mainwidget.cpp
+++ b/examples/opengl/cube/mainwidget.cpp
@@ -72,14 +72,6 @@ void MainWidget::initializeGL()
initShaders();
initTextures();
-//! [2]
- // Enable depth buffer
- glEnable(GL_DEPTH_TEST);
-
- // Enable back face culling
- glEnable(GL_CULL_FACE);
-//! [2]
-
geometries = new GeometryEngine;
// Use QBasicTimer because its faster than QTimer
@@ -147,7 +139,16 @@ void MainWidget::paintGL()
// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+//! [2]
+ // Enable depth buffer
+ glEnable(GL_DEPTH_TEST);
+
+ // Enable back face culling
+ glEnable(GL_CULL_FACE);
+//! [2]
+
texture->bind();
+ program.bind();
//! [6]
// Calculate model view transformation
diff --git a/examples/opengl/hellogles3/doc/images/hellogles3-example.png b/examples/opengl/doc/images/hellogles3-example.png
index e089b9470a..e089b9470a 100644
--- a/examples/opengl/hellogles3/doc/images/hellogles3-example.png
+++ b/examples/opengl/doc/images/hellogles3-example.png
Binary files differ
diff --git a/examples/opengl/doc/images/stereoexample-leftbuffer.png b/examples/opengl/doc/images/stereoexample-leftbuffer.png
new file mode 100644
index 0000000000..6ae7d5118b
--- /dev/null
+++ b/examples/opengl/doc/images/stereoexample-leftbuffer.png
Binary files differ
diff --git a/examples/opengl/doc/images/stereoexample-rightbuffer.png b/examples/opengl/doc/images/stereoexample-rightbuffer.png
new file mode 100644
index 0000000000..3e2dc3c671
--- /dev/null
+++ b/examples/opengl/doc/images/stereoexample-rightbuffer.png
Binary files differ
diff --git a/examples/opengl/doc/src/2dpainting.qdoc b/examples/opengl/doc/src/2dpainting.qdoc
index 934097f38e..5196c78937 100644
--- a/examples/opengl/doc/src/2dpainting.qdoc
+++ b/examples/opengl/doc/src/2dpainting.qdoc
@@ -5,6 +5,7 @@
\example 2dpainting
\title 2D Painting Example
\ingroup examples-widgets-opengl
+ \examplecategory {Graphics}
\brief The 2D Painting example shows how QPainter and QOpenGLWidget can be
used together to display accelerated 2D graphics on supported hardware.
diff --git a/examples/opengl/doc/src/cube.qdoc b/examples/opengl/doc/src/cube.qdoc
index e0a1870606..d01985701c 100644
--- a/examples/opengl/doc/src/cube.qdoc
+++ b/examples/opengl/doc/src/cube.qdoc
@@ -5,11 +5,14 @@
\example cube
\ingroup examples-widgets-opengl
\title Cube OpenGL ES 2.0 example
+ \examplecategory {3D}
- \brief The Cube OpenGL ES 2.0 example shows how to write mouse rotatable
- textured 3D cube using OpenGL ES 2.0 with Qt. It shows how to handle
- polygon geometries efficiently and how to write simple vertex and
- fragment shader for programmable graphics pipeline. In addition it
+ \brief Shows how to manually rotate a textured 3D cube with user input.
+
+ The Cube OpenGL ES 2.0 example shows how to manually rotate a textured 3D
+ cube with user input, using OpenGL ES 2.0 with Qt. It shows how to
+ handle polygon geometries efficiently and how to write a simple vertex and
+ fragment shader for a programmable graphics pipeline. In addition it
shows how to use quaternions for representing 3D object orientation.
This example has been written for OpenGL ES 2.0 but it works also on
diff --git a/examples/opengl/doc/src/hellogl2.qdoc b/examples/opengl/doc/src/hellogl2.qdoc
index 3a81b0dfad..29e8ef85cd 100644
--- a/examples/opengl/doc/src/hellogl2.qdoc
+++ b/examples/opengl/doc/src/hellogl2.qdoc
@@ -5,6 +5,7 @@
\example hellogl2
\title Hello GL2 Example
\ingroup examples-widgets-opengl
+ \examplecategory {3D}
\brief The Hello GL2 example demonstrates the basic use of the OpenGL-related classes
provided with Qt.
diff --git a/examples/opengl/doc/src/hellogles3.qdoc b/examples/opengl/doc/src/hellogles3.qdoc
new file mode 100644
index 0000000000..d85f40a29f
--- /dev/null
+++ b/examples/opengl/doc/src/hellogles3.qdoc
@@ -0,0 +1,149 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example hellogles3
+ \title Hello GLES3 Example
+ \ingroup examples-widgets-opengl
+ \examplecategory {Graphics}
+ \examplecategory {Mobile}
+
+ \brief Demonstrates OpenGL ES 3.0 functions via QOpenGLExtraFunctions.
+
+ \image hellogles3-example.png
+ \section1 Overview
+
+ This example demonstrates easy, cross-platform usage of OpenGL ES 3.0
+ functions via QOpenGLExtraFunctions in an application that
+ works identically on desktop platforms with OpenGL 3.3 and mobile/embedded
+ devices with OpenGL ES 3.0.
+
+ This example has no QWidget dependencies, it uses QOpenGLWindow, a
+ convenience subclass of QWindow that allows easy implementation of windows
+ that contain OpenGL-rendered content. In this sense it complements the
+ \l{OpenGL Window Example}, which shows the implementation of an OpenGL-based
+ QWindow without using the convenience subclass.
+
+ The Qt logo shape implementation is included from the \l{Hello GL2 Example}.
+
+ In other aspects pertaining to using OpenGL there are the following
+ differences.
+
+ \list
+ \li The OpenGL context creation has to have a sufficiently high version
+ number for the features that are in use.
+ \li The shader's version directive is different.
+ \endlist
+
+ \section1 Setting up in main.cpp
+
+ Here we instantiate our QGuiApplication, QSurfaceformat and set its
+ \l{QSurfaceFormat::depthBufferSize()}{depth buffer size}:
+
+ \quotefromfile hellogles3/main.cpp
+ \skipto int main(int argc, char *argv[])
+ \printuntil fmt.setDepthBufferSize(24);
+
+ We request an OpenGL 3.3 core or OpenGL ES 3.0 context, depending on
+ QOpenGLContext::openGLModuleType():
+
+ \skipto if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
+ \printuntil QSurfaceFormat::setDefaultFormat(fmt);
+
+ We set the default surface format and instantiate our GLWindow \c glWindow.
+
+ \section1 Implementing GLWindow
+
+ This class delivers the features of the example application.
+
+ To start, \c GLWindow is declared by implementing a subclass of
+ QOpenGLWindow:
+
+ \quotefromfile hellogles3/glwindow.h
+ \skipto class GLWindow : public QOpenGLWindow
+ \printto {
+
+ The following properties are declared using Q_PROPERTY:
+
+ \printto public:
+
+ The following public functions are declared:
+
+ \printto private slots:
+
+ The following private objects are declared:
+
+ \printto };
+
+ On the implementation side, those functions that are not declared inline are
+ implemented (or re-implemented) in \c{glwindow.cpp}. The following selections
+ will cover implementation particulars pertaining to the use of OpenGL ES 3.0.
+
+ \section2 Animations
+
+ The following code pertains to the animations, and won't be explored here:
+
+ \quotefromfile hellogles3/glwindow.cpp
+ \skipto GLWindow::GLWindow()
+ \printto static const char *vertexShaderSource =
+
+ For more information see the documentation for \l QPropertyAnimation,
+ \l QSequentialAnimationGroup.
+
+ \section2 Shaders
+ The shaders are defined like so:
+
+ \printto QByteArray versionedShaderCode(const char *src)
+
+ \note These are OpenGL version agnostic. We take this and append
+ the version like so:
+
+ \printto void GLWindow::initializeGL()
+
+ \section2 Initializing OpenGL
+
+ Initializing the shader program in handled by \c initializeGL():
+
+ \printuntil m_program = new QOpenGLShaderProgram;
+ \skipto m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, versionedShaderCode(vertexShaderSource));
+
+ Now the OpenGL version is prepended and the various matrices and light
+ position is set:
+
+ \printuntil m_lightPosLoc = m_program->uniformLocation("lightPos");
+
+ While not strictly required for ES 3, a vertex array object is created.
+
+ \skipto delete m_vao;
+ \printuntil f->glEnable(GL_CULL_FACE);
+
+ \section2 Resizing the window
+
+ The perspective needs to be aligned with the new window size as so:
+
+ \skipto void GLWindow::resizeGL(int w, int h)
+ \printto void GLWindow::paintGL()
+
+ \section2 Painting
+
+ We use QOpenGLExtraFunctions instead of QOpenGLFunctions as we want to
+ do more than what GL(ES) 2.0 offers:
+
+ \printuntil QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
+
+ We clear the screen and buffers and bind our shader program and texture:
+
+ \printuntil m_texture->bind();
+
+ Logic for handling an initial \c paintGL() call or a call after a
+ \c resizeGL() call is implemented like so:
+
+ \printuntil }
+
+ Last, we demonstrate a function introduced in OpenGL 3.1 or OpenGL ES 3.0:
+
+ \skipto f->glDrawArraysInstanced(GL_TRIANGLES, 0, m_logo.vertexCount(), 32 * 36);
+ \printuntil }
+
+ This works because we earlier requested 3.3 or 3.0 context.
+*/
diff --git a/examples/opengl/doc/src/openglwindow.qdoc b/examples/opengl/doc/src/openglwindow.qdoc
index 1a9d4308ba..cade2f009a 100644
--- a/examples/opengl/doc/src/openglwindow.qdoc
+++ b/examples/opengl/doc/src/openglwindow.qdoc
@@ -4,6 +4,8 @@
/*!
\example openglwindow
\title OpenGL Window Example
+ \ingroup examples-widgets-opengl
+ \examplecategory {Graphics}
\brief This example shows how to create a minimal QWindow based application
for the purpose of using OpenGL.
@@ -12,6 +14,8 @@
\note This is a low level example of how to use QWindow with OpenGL.
In practice you should consider using the higher level QOpenGLWindow class.
+ See the \l{Hello GLES3 Example} for a demonstration of the QOpenGLWindow
+ convenience class.
\section1 OpenGLWindow Super Class
diff --git a/examples/opengl/doc/src/stereoqopenglwidget.qdoc b/examples/opengl/doc/src/stereoqopenglwidget.qdoc
new file mode 100644
index 0000000000..0cb45b9808
--- /dev/null
+++ b/examples/opengl/doc/src/stereoqopenglwidget.qdoc
@@ -0,0 +1,46 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example stereoqopenglwidget
+ \title QOpenGLWidget Stereoscopic Rendering Example
+ \examplecategory {Graphics}
+ \ingroup examples-widgets-opengl
+ \brief This example shows how to create a minimal QOpenGLWidget based
+ application with stereoscopic rendering support.
+
+ \note Support for stereoscopic rendering has certain hardware requirements,
+ such as, a graphics card with stereo support, 3D glasses and specific
+ monitors.
+
+ \note This example renders two images to two separate buffers. When you
+ view the images through 3D glasses, they give a 3D holographic effect.
+
+ \image stereoexample-leftbuffer.png
+
+ The above image is what will be rendered to the left buffer.
+
+ \image stereoexample-rightbuffer.png
+
+ The above image is what will be rendered to the right buffer.
+
+ \section1 Setting the correct surface flag
+ To enable stereoscopic rendering you need to set the flag
+ QSurfaceFormat::StereoBuffers globally. Just doing it on the widget is not enough
+ because of how the flag is handled internally. The safest is to do it on
+ QSurfaceFormat::SetDefaultFormat prior to starting the application.
+
+ \snippet stereoqopenglwidget/main.cpp 1
+
+ \section1 Rendering twice
+ After QSurfaceFormat::StereoBuffers is set, then paintGL() will be called twice,
+ once for each buffer. In paintGL() you can call currentTargetBuffer() to query
+ which TargetBuffer is currently active.
+
+ In the following snippet we slightly translate the matrix to not render the
+ vertices on top of each other. This is a simple example just too see that if the
+ necessary support is there, at runtime you should see two objects, one on the left
+ and one on the right.
+
+ \snippet stereoqopenglwidget/glwidget.cpp 1
+*/
diff --git a/examples/opengl/hellogl2/CMakeLists.txt b/examples/opengl/hellogl2/CMakeLists.txt
index f4b85a329a..74ef4a8c24 100644
--- a/examples/opengl/hellogl2/CMakeLists.txt
+++ b/examples/opengl/hellogl2/CMakeLists.txt
@@ -1,16 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(hellogl2 LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/hellogl2")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets)
+qt_standard_project_setup()
+
qt_add_executable(hellogl2
glwidget.cpp glwidget.h
logo.cpp logo.h
@@ -24,16 +21,23 @@ set_target_properties(hellogl2 PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(hellogl2 PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
- Qt::OpenGLWidgets
- Qt::Widgets
+target_link_libraries(hellogl2 PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::OpenGL
+ Qt6::OpenGLWidgets
+ Qt6::Widgets
)
install(TARGETS hellogl2
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET hellogl2
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/opengl/hellogl2/mainwindow.cpp b/examples/opengl/hellogl2/mainwindow.cpp
index 2416fd6057..5ee2b738c2 100644
--- a/examples/opengl/hellogl2/mainwindow.cpp
+++ b/examples/opengl/hellogl2/mainwindow.cpp
@@ -3,19 +3,19 @@
#include "mainwindow.h"
#include "window.h"
+#include <QApplication>
+#include <QKeySequence>
#include <QMenuBar>
#include <QMenu>
#include <QMessageBox>
MainWindow::MainWindow()
{
- QMenuBar *menuBar = new QMenuBar;
- QMenu *menuWindow = menuBar->addMenu(tr("&Window"));
- QAction *addNew = new QAction(menuWindow);
- addNew->setText(tr("Add new"));
- menuWindow->addAction(addNew);
- connect(addNew, &QAction::triggered, this, &MainWindow::onAddNew);
- setMenuBar(menuBar);
+ QMenu *menuWindow = menuBar()->addMenu(tr("&Window"));
+ menuWindow->addAction(tr("Add new"), QKeySequence(Qt::CTRL | Qt::Key_N),
+ this, &MainWindow::onAddNew);
+ menuWindow->addAction(tr("Quit"), QKeySequence(Qt::CTRL | Qt::Key_Q),
+ qApp, QApplication::closeAllWindows);
onAddNew();
}
@@ -23,8 +23,8 @@ MainWindow::MainWindow()
void MainWindow::onAddNew()
{
if (!centralWidget())
- setCentralWidget(new Window(this));
+ setCentralWidget(new Window);
else
- QMessageBox::information(nullptr, tr("Cannot add new window"),
+ QMessageBox::information(this, tr("Cannot Add New Window"),
tr("Already occupied. Undock first."));
}
diff --git a/examples/opengl/hellogl2/window.cpp b/examples/opengl/hellogl2/window.cpp
index 055dd5b5e3..5a7ddf826f 100644
--- a/examples/opengl/hellogl2/window.cpp
+++ b/examples/opengl/hellogl2/window.cpp
@@ -1,9 +1,8 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-#include "glwidget.h"
#include "window.h"
-#include "mainwindow.h"
+#include "glwidget.h"
#include <QSlider>
#include <QVBoxLayout>
#include <QHBoxLayout>
@@ -11,9 +10,18 @@
#include <QPushButton>
#include <QApplication>
#include <QMessageBox>
+#include <QMainWindow>
-Window::Window(MainWindow *mw)
- : mainWindow(mw)
+static QMainWindow *findMainWindow()
+{
+ for (auto *w : QApplication::topLevelWidgets()) {
+ if (auto *mw = qobject_cast<QMainWindow *>(w))
+ return mw;
+ }
+ return nullptr;
+}
+
+Window::Window()
{
glWidget = new GLWidget;
@@ -28,22 +36,19 @@ Window::Window(MainWindow *mw)
connect(zSlider, &QSlider::valueChanged, glWidget, &GLWidget::setZRotation);
connect(glWidget, &GLWidget::zRotationChanged, zSlider, &QSlider::setValue);
- QVBoxLayout *mainLayout = new QVBoxLayout;
- QHBoxLayout *container = new QHBoxLayout;
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ QWidget *w = new QWidget;
+ QHBoxLayout *container = new QHBoxLayout(w);
container->addWidget(glWidget);
container->addWidget(xSlider);
container->addWidget(ySlider);
container->addWidget(zSlider);
- QWidget *w = new QWidget;
- w->setLayout(container);
mainLayout->addWidget(w);
dockBtn = new QPushButton(tr("Undock"), this);
connect(dockBtn, &QPushButton::clicked, this, &Window::dockUndock);
mainLayout->addWidget(dockBtn);
- setLayout(mainLayout);
-
xSlider->setValue(15 * 16);
ySlider->setValue(345 * 16);
zSlider->setValue(0 * 16);
@@ -64,7 +69,7 @@ QSlider *Window::createSlider()
void Window::keyPressEvent(QKeyEvent *e)
{
- if (e->key() == Qt::Key_Escape)
+ if (isWindow() && e->key() == Qt::Key_Escape)
close();
else
QWidget::keyPressEvent(e);
@@ -72,26 +77,37 @@ void Window::keyPressEvent(QKeyEvent *e)
void Window::dockUndock()
{
- if (parent()) {
- setParent(nullptr);
- setAttribute(Qt::WA_DeleteOnClose);
- move(QGuiApplication::primaryScreen()->size().width() / 2 - width() / 2,
- QGuiApplication::primaryScreen()->size().height() / 2 - height() / 2);
- dockBtn->setText(tr("Dock"));
- show();
- } else {
- if (!mainWindow->centralWidget()) {
- if (mainWindow->isVisible()) {
- setAttribute(Qt::WA_DeleteOnClose, false);
- dockBtn->setText(tr("Undock"));
- mainWindow->setCentralWidget(this);
- } else {
- QMessageBox::information(nullptr, tr("Cannot dock"),
- tr("Main window already closed"));
- }
- } else {
- QMessageBox::information(nullptr, tr("Cannot dock"),
- tr("Main window already occupied"));
- }
+ if (parent())
+ undock();
+ else
+ dock();
+}
+
+void Window::dock()
+{
+ auto *mainWindow = findMainWindow();
+ if (mainWindow == nullptr || !mainWindow->isVisible()) {
+ QMessageBox::information(this, tr("Cannot Dock"),
+ tr("Main window already closed"));
+ return;
}
+ if (mainWindow->centralWidget()) {
+ QMessageBox::information(this, tr("Cannot Dock"),
+ tr("Main window already occupied"));
+ return;
+ }
+ setAttribute(Qt::WA_DeleteOnClose, false);
+ dockBtn->setText(tr("Undock"));
+ mainWindow->setCentralWidget(this);
+}
+
+void Window::undock()
+{
+ setParent(nullptr);
+ setAttribute(Qt::WA_DeleteOnClose);
+ const auto geometry = screen()->availableGeometry();
+ move(geometry.x() + (geometry.width() - width()) / 2,
+ geometry.y() + (geometry.height() - height()) / 2);
+ dockBtn->setText(tr("Dock"));
+ show();
}
diff --git a/examples/opengl/hellogl2/window.h b/examples/opengl/hellogl2/window.h
index f9e0607903..edbd643ae2 100644
--- a/examples/opengl/hellogl2/window.h
+++ b/examples/opengl/hellogl2/window.h
@@ -6,20 +6,17 @@
#include <QWidget>
-QT_BEGIN_NAMESPACE
-class QSlider;
-class QPushButton;
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QSlider)
+QT_FORWARD_DECLARE_CLASS(QPushButton)
class GLWidget;
-class MainWindow;
class Window : public QWidget
{
Q_OBJECT
public:
- Window(MainWindow *mw);
+ Window();
protected:
void keyPressEvent(QKeyEvent *event) override;
@@ -28,6 +25,8 @@ private slots:
void dockUndock();
private:
+ void dock();
+ void undock();
QSlider *createSlider();
GLWidget *glWidget;
@@ -35,7 +34,6 @@ private:
QSlider *ySlider;
QSlider *zSlider;
QPushButton *dockBtn;
- MainWindow *mainWindow;
};
#endif
diff --git a/examples/opengl/hellogles3/CMakeLists.txt b/examples/opengl/hellogles3/CMakeLists.txt
index 2e0c3069fc..07df173a47 100644
--- a/examples/opengl/hellogles3/CMakeLists.txt
+++ b/examples/opengl/hellogles3/CMakeLists.txt
@@ -1,16 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(hellogles3 LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/hellogles3")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL)
+qt_standard_project_setup()
+
qt_add_executable(hellogles3
../hellogl2/logo.cpp ../hellogl2/logo.h
glwindow.cpp glwindow.h
@@ -22,10 +19,10 @@ set_target_properties(hellogles3 PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(hellogles3 PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
+target_link_libraries(hellogles3 PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::OpenGL
)
# Resources:
@@ -41,7 +38,14 @@ qt_add_resources(hellogles3 "hellogles3"
)
install(TARGETS hellogles3
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET hellogles3
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/opengl/hellogles3/doc/src/hellogles3.qdoc b/examples/opengl/hellogles3/doc/src/hellogles3.qdoc
deleted file mode 100644
index cae0bd8b27..0000000000
--- a/examples/opengl/hellogles3/doc/src/hellogles3.qdoc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
-
-/*!
- \example hellogles3
- \title Hello GLES3 Example
- \ingroup examples-widgets-opengl
-
- \brief The Hello GLES3 example demonstrates easy, cross-platform usage of
- OpenGL ES 3.0 functions via QOpenGLExtraFunctions in an application that
- works identically on desktop platforms with OpenGL 3.3 and mobile/embedded
- devices with OpenGL ES 3.0.
-
- The code is always the same, with the exception of two places:
- \list
- \li The OpenGL context creation has to have a sufficiently high version
- number for the features that are in use.
- \li The shader code's version directive is different.
- \endlist
-
- \image hellogles3-example.png
-*/
diff --git a/examples/opengl/hellogles3/glwindow.h b/examples/opengl/hellogles3/glwindow.h
index fc2a0e487e..54bc531af8 100644
--- a/examples/opengl/hellogles3/glwindow.h
+++ b/examples/opengl/hellogles3/glwindow.h
@@ -9,14 +9,10 @@
#include <QVector3D>
#include "../hellogl2/logo.h"
-QT_BEGIN_NAMESPACE
-
-class QOpenGLTexture;
-class QOpenGLShaderProgram;
-class QOpenGLBuffer;
-class QOpenGLVertexArrayObject;
-
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
+QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
+QT_FORWARD_DECLARE_CLASS(QOpenGLBuffer)
+QT_FORWARD_DECLARE_CLASS(QOpenGLVertexArrayObject)
class GLWindow : public QOpenGLWindow
{
diff --git a/examples/opengl/hellowindow/CMakeLists.txt b/examples/opengl/hellowindow/CMakeLists.txt
deleted file mode 100644
index cb86df3595..0000000000
--- a/examples/opengl/hellowindow/CMakeLists.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(hellowindow LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/hellowindow")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL)
-
-qt_add_executable(hellowindow
- hellowindow.cpp hellowindow.h
- main.cpp
-)
-
-set_target_properties(hellowindow PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(hellowindow PUBLIC
- Qt::Core
- Qt::CorePrivate
- Qt::Gui
- Qt::GuiPrivate
- Qt::OpenGL
-)
-
-install(TARGETS hellowindow
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/opengl/hellowindow/hellowindow.cpp b/examples/opengl/hellowindow/hellowindow.cpp
deleted file mode 100644
index c9cad95563..0000000000
--- a/examples/opengl/hellowindow/hellowindow.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "hellowindow.h"
-
-#include <QOpenGLContext>
-#include <QOpenGLFunctions>
-#include <QRandomGenerator>
-#include <qmath.h>
-#include <QElapsedTimer>
-
-Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *screen)
- : m_initialized(false)
- , m_format(format)
-{
- m_context = new QOpenGLContext(this);
- if (screen)
- m_context->setScreen(screen);
- m_context->setFormat(format);
- if (share)
- m_context->setShareContext(share->m_context);
- m_context->create();
-
- m_backgroundColor = QColor::fromRgbF(0.1f, 0.1f, 0.2f, 1.0f);
- m_backgroundColor.setRed(QRandomGenerator::global()->bounded(64));
- m_backgroundColor.setGreen(QRandomGenerator::global()->bounded(128));
- m_backgroundColor.setBlue(QRandomGenerator::global()->bounded(256));
-}
-
-HelloWindow::HelloWindow(const QSharedPointer<Renderer> &renderer, QScreen *screen)
- : m_colorIndex(0), m_renderer(renderer)
-{
- setSurfaceType(QWindow::OpenGLSurface);
- setFlags(Qt::Window | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
-
- setGeometry(QRect(10, 10, 640, 480));
-
- setFormat(renderer->format());
- if (screen)
- setScreen(screen);
-
- create();
-
- updateColor();
-
- connect(renderer.data(), &Renderer::requestUpdate, this, &QWindow::requestUpdate);
-}
-
-void HelloWindow::exposeEvent(QExposeEvent *)
-{
- if (isExposed())
- render();
-}
-
-bool HelloWindow::event(QEvent *ev)
-{
- if (ev->type() == QEvent::UpdateRequest && isExposed())
- render();
- return QWindow::event(ev);
-}
-
-void HelloWindow::render()
-{
- static QElapsedTimer timer;
- if (!timer.isValid())
- timer.start();
- qreal a = (qreal)(((timer.elapsed() * 3) % 36000) / 100.0);
- auto call = [this, r = m_renderer.data(), a, c = color()]() { r->render(this, a, c); };
- QMetaObject::invokeMethod(m_renderer.data(), call);
-}
-
-void HelloWindow::mousePressEvent(QMouseEvent *)
-{
- updateColor();
-}
-
-QColor HelloWindow::color() const
-{
- return m_color;
-}
-
-void HelloWindow::updateColor()
-{
- QColor colors[] =
- {
- QColor(100, 255, 0),
- QColor(0, 100, 255)
- };
-
- m_color = colors[m_colorIndex];
- m_colorIndex = 1 - m_colorIndex;
-}
-
-void Renderer::render(HelloWindow *surface, qreal angle, const QColor &color)
-{
- if (!m_context->makeCurrent(surface))
- return;
-
- QSize viewSize = surface->size();
-
- if (!m_initialized) {
- initialize();
- m_initialized = true;
- }
-
- QOpenGLFunctions *f = m_context->functions();
- f->glViewport(0, 0, viewSize.width() * surface->devicePixelRatio(), viewSize.height() * surface->devicePixelRatio());
- f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- f->glClearColor(m_backgroundColor.redF(), m_backgroundColor.greenF(), m_backgroundColor.blueF(), m_backgroundColor.alphaF());
- f->glFrontFace(GL_CW);
- f->glCullFace(GL_FRONT);
- f->glEnable(GL_CULL_FACE);
- f->glEnable(GL_DEPTH_TEST);
-
- m_program->bind();
- m_vbo.bind();
-
- m_program->enableAttributeArray(vertexAttr);
- m_program->enableAttributeArray(normalAttr);
- m_program->setAttributeBuffer(vertexAttr, GL_FLOAT, 0, 3);
- const int verticesSize = vertices.count() * 3 * sizeof(GLfloat);
- m_program->setAttributeBuffer(normalAttr, GL_FLOAT, verticesSize, 3);
-
- QMatrix4x4 modelview;
- modelview.rotate(angle, 0.0f, 1.0f, 0.0f);
- modelview.rotate(angle, 1.0f, 0.0f, 0.0f);
- modelview.rotate(angle, 0.0f, 0.0f, 1.0f);
- modelview.translate(0.0f, -0.2f, 0.0f);
-
- m_program->setUniformValue(matrixUniform, modelview);
- m_program->setUniformValue(colorUniform, color);
-
- m_context->functions()->glDrawArrays(GL_TRIANGLES, 0, vertices.size());
-
- m_context->swapBuffers(surface);
-
- emit requestUpdate();
-}
-
-Q_GLOBAL_STATIC(QMutex, initMutex)
-
-void Renderer::initialize()
-{
- // Threaded shader compilation can confuse some drivers. Avoid it.
- QMutexLocker lock(initMutex());
-
- QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
- vshader->compileSourceCode(
- "attribute highp vec4 vertex;"
- "attribute mediump vec3 normal;"
- "uniform mediump mat4 matrix;"
- "uniform lowp vec4 sourceColor;"
- "varying mediump vec4 color;"
- "void main(void)"
- "{"
- " vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));"
- " float angle = max(dot(normal, toLight), 0.0);"
- " vec3 col = sourceColor.rgb;"
- " color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);"
- " color = clamp(color, 0.0, 1.0);"
- " gl_Position = matrix * vertex;"
- "}");
-
- QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
- fshader->compileSourceCode(
- "varying mediump vec4 color;"
- "void main(void)"
- "{"
- " gl_FragColor = color;"
- "}");
-
- m_program = new QOpenGLShaderProgram(this);
- m_program->addShader(vshader);
- m_program->addShader(fshader);
- m_program->link();
- m_program->bind();
-
- vertexAttr = m_program->attributeLocation("vertex");
- normalAttr = m_program->attributeLocation("normal");
- matrixUniform = m_program->uniformLocation("matrix");
- colorUniform = m_program->uniformLocation("sourceColor");
-
- createGeometry();
-
- m_vbo.create();
- m_vbo.bind();
- const int verticesSize = vertices.count() * 3 * sizeof(GLfloat);
- m_vbo.allocate(verticesSize * 2);
- m_vbo.write(0, vertices.constData(), verticesSize);
- m_vbo.write(verticesSize, normals.constData(), verticesSize);
-}
-
-void Renderer::createGeometry()
-{
- vertices.clear();
- normals.clear();
-
- qreal x1 = +0.06f;
- qreal y1 = -0.14f;
- qreal x2 = +0.14f;
- qreal y2 = -0.06f;
- qreal x3 = +0.08f;
- qreal y3 = +0.00f;
- qreal x4 = +0.30f;
- qreal y4 = +0.22f;
-
- quad(x1, y1, x2, y2, y2, x2, y1, x1);
- quad(x3, y3, x4, y4, y4, x4, y3, x3);
-
- extrude(x1, y1, x2, y2);
- extrude(x2, y2, y2, x2);
- extrude(y2, x2, y1, x1);
- extrude(y1, x1, x1, y1);
- extrude(x3, y3, x4, y4);
- extrude(x4, y4, y4, x4);
- extrude(y4, x4, y3, x3);
-
- const int NumSectors = 100;
- const qreal sectorAngle = 2 * qreal(M_PI) / NumSectors;
- for (int i = 0; i < NumSectors; ++i) {
- qreal angle = i * sectorAngle;
- qreal x5 = 0.30 * qSin(angle);
- qreal y5 = 0.30 * qCos(angle);
- qreal x6 = 0.20 * qSin(angle);
- qreal y6 = 0.20 * qCos(angle);
-
- angle += sectorAngle;
- qreal x7 = 0.20 * qSin(angle);
- qreal y7 = 0.20 * qCos(angle);
- qreal x8 = 0.30 * qSin(angle);
- qreal y8 = 0.30 * qCos(angle);
-
- quad(x5, y5, x6, y6, x7, y7, x8, y8);
-
- extrude(x6, y6, x7, y7);
- extrude(x8, y8, x5, y5);
- }
-
- for (int i = 0;i < vertices.size();i++)
- vertices[i] *= 2.0f;
-}
-
-void Renderer::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
-{
- vertices << QVector3D(x1, y1, -0.05f);
- vertices << QVector3D(x2, y2, -0.05f);
- vertices << QVector3D(x4, y4, -0.05f);
-
- vertices << QVector3D(x3, y3, -0.05f);
- vertices << QVector3D(x4, y4, -0.05f);
- vertices << QVector3D(x2, y2, -0.05f);
-
- QVector3D n = QVector3D::normal
- (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f));
-
- normals << n;
- normals << n;
- normals << n;
-
- normals << n;
- normals << n;
- normals << n;
-
- vertices << QVector3D(x4, y4, 0.05f);
- vertices << QVector3D(x2, y2, 0.05f);
- vertices << QVector3D(x1, y1, 0.05f);
-
- vertices << QVector3D(x2, y2, 0.05f);
- vertices << QVector3D(x4, y4, 0.05f);
- vertices << QVector3D(x3, y3, 0.05f);
-
- n = QVector3D::normal
- (QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f));
-
- normals << n;
- normals << n;
- normals << n;
-
- normals << n;
- normals << n;
- normals << n;
-}
-
-void Renderer::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
-{
- vertices << QVector3D(x1, y1, +0.05f);
- vertices << QVector3D(x2, y2, +0.05f);
- vertices << QVector3D(x1, y1, -0.05f);
-
- vertices << QVector3D(x2, y2, -0.05f);
- vertices << QVector3D(x1, y1, -0.05f);
- vertices << QVector3D(x2, y2, +0.05f);
-
- QVector3D n = QVector3D::normal
- (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f));
-
- normals << n;
- normals << n;
- normals << n;
-
- normals << n;
- normals << n;
- normals << n;
-}
diff --git a/examples/opengl/hellowindow/hellowindow.h b/examples/opengl/hellowindow/hellowindow.h
deleted file mode 100644
index 51c326c75f..0000000000
--- a/examples/opengl/hellowindow/hellowindow.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QWindow>
-
-#include <QColor>
-#include <QMutex>
-#include <QOpenGLShaderProgram>
-#include <QOpenGLBuffer>
-#include <QSharedPointer>
-#include <QTimer>
-
-class HelloWindow;
-
-class Renderer : public QObject
-{
- Q_OBJECT
-
-public:
- explicit Renderer(const QSurfaceFormat &format, Renderer *share = nullptr,
- QScreen *screen = nullptr);
-
- QSurfaceFormat format() const { return m_format; }
-
-public slots:
- void render(HelloWindow *surface, qreal angle, const QColor &color);
-
-signals:
- void requestUpdate();
-
-private:
- void initialize();
-
- void createGeometry();
- void createBubbles(int number);
- void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4);
- void extrude(qreal x1, qreal y1, qreal x2, qreal y2);
-
- QList<QVector3D> vertices;
- QList<QVector3D> normals;
- int vertexAttr;
- int normalAttr;
- int matrixUniform;
- int colorUniform;
-
- bool m_initialized;
- QSurfaceFormat m_format;
- QOpenGLContext *m_context;
- QOpenGLShaderProgram *m_program;
- QOpenGLBuffer m_vbo;
- QColor m_backgroundColor;
-};
-
-class HelloWindow : public QWindow
-{
-public:
- explicit HelloWindow(const QSharedPointer<Renderer> &renderer, QScreen *screen = nullptr);
-
- QColor color() const;
- void updateColor();
-
-protected:
- bool event(QEvent *ev) override;
- void exposeEvent(QExposeEvent *event) override;
- void mousePressEvent(QMouseEvent *) override;
- void render();
-
-private:
- int m_colorIndex;
- QColor m_color;
- const QSharedPointer<Renderer> m_renderer;
-};
diff --git a/examples/opengl/hellowindow/hellowindow.pro b/examples/opengl/hellowindow/hellowindow.pro
deleted file mode 100644
index 27c274a378..0000000000
--- a/examples/opengl/hellowindow/hellowindow.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-QT += gui-private core-private opengl
-
-HEADERS += hellowindow.h
-SOURCES += hellowindow.cpp main.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/opengl/hellowindow
-INSTALLS += target
-
diff --git a/examples/opengl/hellowindow/main.cpp b/examples/opengl/hellowindow/main.cpp
deleted file mode 100644
index ee4729a493..0000000000
--- a/examples/opengl/hellowindow/main.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "hellowindow.h"
-
-#include <qpa/qplatformintegration.h>
-
-#include <QCommandLineParser>
-#include <QCommandLineOption>
-#include <QGuiApplication>
-#include <QScreen>
-#include <QThread>
-
-int main(int argc, char *argv[])
-{
- QGuiApplication app(argc, argv);
-
- QCoreApplication::setApplicationName("Qt HelloWindow GL Example");
- QCoreApplication::setOrganizationName("QtProject");
- QCoreApplication::setApplicationVersion(QT_VERSION_STR);
- QCommandLineParser parser;
- parser.setApplicationDescription(QCoreApplication::applicationName());
- parser.addHelpOption();
- parser.addVersionOption();
- QCommandLineOption multipleOption("multiple", "Create multiple windows");
- parser.addOption(multipleOption);
- QCommandLineOption multipleSampleOption("multisample", "Multisampling");
- parser.addOption(multipleSampleOption);
- QCommandLineOption multipleScreenOption("multiscreen", "Run on multiple screens");
- parser.addOption(multipleScreenOption);
- QCommandLineOption timeoutOption("timeout", "Close after 10s");
- parser.addOption(timeoutOption);
- parser.process(app);
-
- // Some platforms can only have one window per screen. Therefore we need to differentiate.
- const bool multipleWindows = parser.isSet(multipleOption);
- const bool multipleScreens = parser.isSet(multipleScreenOption);
-
- QScreen *screen = QGuiApplication::primaryScreen();
-
- QRect screenGeometry = screen->availableGeometry();
-
- QSurfaceFormat format;
- format.setDepthBufferSize(16);
- if (parser.isSet(multipleSampleOption))
- format.setSamples(4);
-
- QPoint center = QPoint(screenGeometry.center().x(), screenGeometry.top() + 80);
- QSize windowSize(400, 320);
- int delta = 40;
-
- QList<QWindow *> windows;
- QSharedPointer<Renderer> rendererA(new Renderer(format));
-
- HelloWindow *windowA = new HelloWindow(rendererA);
- windowA->setGeometry(QRect(center, windowSize).translated(-windowSize.width() - delta / 2, 0));
- windowA->setTitle(QStringLiteral("Thread A - Context A"));
- windowA->setVisible(true);
- windows.prepend(windowA);
-
- QList<QThread *> renderThreads;
- if (multipleWindows) {
- QSharedPointer<Renderer> rendererB(new Renderer(format, rendererA.data()));
-
- QThread *renderThread = new QThread;
- rendererB->moveToThread(renderThread);
- renderThreads << renderThread;
-
- HelloWindow *windowB = new HelloWindow(rendererA);
- windowB->setGeometry(QRect(center, windowSize).translated(delta / 2, 0));
- windowB->setTitle(QStringLiteral("Thread A - Context A"));
- windowB->setVisible(true);
- windows.prepend(windowB);
-
- HelloWindow *windowC = new HelloWindow(rendererB);
- windowC->setGeometry(QRect(center, windowSize).translated(-windowSize.width() / 2, windowSize.height() + delta));
- windowC->setTitle(QStringLiteral("Thread B - Context B"));
- windowC->setVisible(true);
- windows.prepend(windowC);
- }
- if (multipleScreens) {
- for (int i = 1; i < QGuiApplication::screens().size(); ++i) {
- QScreen *screen = QGuiApplication::screens().at(i);
- QSharedPointer<Renderer> renderer(new Renderer(format, rendererA.data(), screen));
-
- QThread *renderThread = new QThread;
- renderer->moveToThread(renderThread);
- renderThreads.prepend(renderThread);
-
- QRect screenGeometry = screen->availableGeometry();
- QPoint center = screenGeometry.center();
-
- QSize windowSize = screenGeometry.size() * 0.8;
-
- HelloWindow *window = new HelloWindow(renderer, screen);
- window->setGeometry(QRect(center, windowSize).translated(-windowSize.width() / 2, -windowSize.height() / 2));
-
- QChar id = QChar('B' + i);
- window->setTitle(QStringLiteral("Thread ") + id + QStringLiteral(" - Context ") + id);
- window->setVisible(true);
- windows.prepend(window);
- }
- }
-
- for (int i = 0; i < renderThreads.size(); ++i) {
- QObject::connect(qGuiApp, &QGuiApplication::lastWindowClosed, renderThreads.at(i), &QThread::quit);
- renderThreads.at(i)->start();
- }
-
- // Quit after 10 seconds. For platforms that do not have windows that are closeable.
- if (parser.isSet(timeoutOption))
- QTimer::singleShot(10000, qGuiApp, &QCoreApplication::quit);
-
- const int exitValue = app.exec();
-
- for (int i = 0; i < renderThreads.size(); ++i) {
- renderThreads.at(i)->quit(); // some platforms may not have windows to close so ensure quit()
- renderThreads.at(i)->wait();
- }
-
- qDeleteAll(windows);
- qDeleteAll(renderThreads);
-
- return exitValue;
-}
diff --git a/examples/opengl/opengl.pro b/examples/opengl/opengl.pro
index 907930d7ac..6ee57c7018 100644
--- a/examples/opengl/opengl.pro
+++ b/examples/opengl/opengl.pro
@@ -1,18 +1,12 @@
TEMPLATE = subdirs
-SUBDIRS = hellowindow \
- paintedwindow \
- openglwindow \
- qopenglwindow
+SUBDIRS = openglwindow \
+ hellogles3
qtHaveModule(widgets) {
- SUBDIRS += contextinfo \
- threadedqopenglwidget \
- 2dpainting \
+ SUBDIRS += 2dpainting \
hellogl2 \
- qopenglwidget \
cube \
textures \
- hellogles3 \
- computegles31
+ stereoqopenglwidget
}
diff --git a/examples/opengl/openglwindow/CMakeLists.txt b/examples/opengl/openglwindow/CMakeLists.txt
index 3d5511efc9..0258a42822 100644
--- a/examples/opengl/openglwindow/CMakeLists.txt
+++ b/examples/opengl/openglwindow/CMakeLists.txt
@@ -1,16 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(openglwindow LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/openglwindow")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL)
+qt_standard_project_setup()
+
qt_add_executable(openglwindow
main.cpp
openglwindow.cpp openglwindow.h
@@ -21,14 +18,21 @@ set_target_properties(openglwindow PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(openglwindow PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
+target_link_libraries(openglwindow PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::OpenGL
)
install(TARGETS openglwindow
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET openglwindow
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/opengl/openglwindow/main.cpp b/examples/opengl/openglwindow/main.cpp
index 6813dc9efd..89933fa379 100644
--- a/examples/opengl/openglwindow/main.cpp
+++ b/examples/opengl/openglwindow/main.cpp
@@ -6,10 +6,10 @@
#include <QGuiApplication>
#include <QMatrix4x4>
#include <QOpenGLShaderProgram>
+#include <QOpenGLBuffer>
#include <QScreen>
#include <QtMath>
-
//! [1]
class TriangleWindow : public OpenGLWindow
{
@@ -20,10 +20,8 @@ public:
void render() override;
private:
- GLint m_posAttr = 0;
- GLint m_colAttr = 0;
GLint m_matrixUniform = 0;
-
+ QOpenGLBuffer m_vbo;
QOpenGLShaderProgram *m_program = nullptr;
int m_frame = 0;
};
@@ -48,36 +46,48 @@ int main(int argc, char **argv)
}
//! [2]
-
//! [3]
-static const char *vertexShaderSource =
- "attribute highp vec4 posAttr;\n"
- "attribute lowp vec4 colAttr;\n"
- "varying lowp vec4 col;\n"
- "uniform highp mat4 matrix;\n"
- "void main() {\n"
- " col = colAttr;\n"
- " gl_Position = matrix * posAttr;\n"
- "}\n";
-
-static const char *fragmentShaderSource =
- "varying lowp vec4 col;\n"
- "void main() {\n"
- " gl_FragColor = col;\n"
- "}\n";
+static const char *vertexShaderSource = "attribute highp vec4 posAttr;\n"
+ "attribute lowp vec4 colAttr;\n"
+ "varying lowp vec4 col;\n"
+ "uniform highp mat4 matrix;\n"
+ "void main() {\n"
+ " col = colAttr;\n"
+ " gl_Position = matrix * posAttr;\n"
+ "}\n";
+
+static const char *fragmentShaderSource = "varying lowp vec4 col;\n"
+ "void main() {\n"
+ " gl_FragColor = col;\n"
+ "}\n";
//! [3]
//! [4]
void TriangleWindow::initialize()
{
+ static const GLfloat vertices_colors[] = { +0.0f, +0.707f, 1.0f, 0.0f, 0.0f,
+ -0.5f, -0.500f, 0.0f, 1.0f, 0.0f,
+ +0.5f, -0.500f, 0.0f, 0.0f, 1.0f };
+
+ m_vbo.create();
+ m_vbo.bind();
+ m_vbo.allocate(vertices_colors, sizeof(vertices_colors));
+
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), nullptr);
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
+ reinterpret_cast<void *>(2 * sizeof(GLfloat)));
+
m_program = new QOpenGLShaderProgram(this);
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
+ m_program->bindAttributeLocation("posAttr", 0);
+ m_program->bindAttributeLocation("colAttr", 1);
m_program->link();
- m_posAttr = m_program->attributeLocation("posAttr");
- Q_ASSERT(m_posAttr != -1);
- m_colAttr = m_program->attributeLocation("colAttr");
- Q_ASSERT(m_colAttr != -1);
+ m_program->bind();
+
m_matrixUniform = m_program->uniformLocation("matrix");
Q_ASSERT(m_matrixUniform != -1);
}
@@ -100,28 +110,13 @@ void TriangleWindow::render()
m_program->setUniformValue(m_matrixUniform, matrix);
- static const GLfloat vertices[] = {
- 0.0f, 0.707f,
- -0.5f, -0.5f,
- 0.5f, -0.5f
- };
-
- static const GLfloat colors[] = {
- 1.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 1.0f
- };
-
- glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);
- glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
-
- glEnableVertexAttribArray(m_posAttr);
- glEnableVertexAttribArray(m_colAttr);
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, 3);
- glDisableVertexAttribArray(m_colAttr);
- glDisableVertexAttribArray(m_posAttr);
+ glDisableVertexAttribArray(0);
+ glDisableVertexAttribArray(1);
m_program->release();
diff --git a/examples/opengl/openglwindow/openglwindow.h b/examples/opengl/openglwindow/openglwindow.h
index 7206fc57ef..41bcbab9c4 100644
--- a/examples/opengl/openglwindow/openglwindow.h
+++ b/examples/opengl/openglwindow/openglwindow.h
@@ -1,14 +1,15 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+#ifndef OPENGLWINDOW_H
+#define OPENGLWINDOW_H
+
#include <QWindow>
#include <QOpenGLFunctions>
-QT_BEGIN_NAMESPACE
-class QPainter;
-class QOpenGLContext;
-class QOpenGLPaintDevice;
-QT_END_NAMESPACE
+QT_FORWARD_DECLARE_CLASS(QPainter)
+QT_FORWARD_DECLARE_CLASS(QOpenGLContext)
+QT_FORWARD_DECLARE_CLASS(QOpenGLPaintDevice)
//! [1]
class OpenGLWindow : public QWindow, protected QOpenGLFunctions
@@ -42,3 +43,4 @@ private:
};
//! [1]
+#endif // OPENGLWINDOW_H
diff --git a/examples/opengl/paintedwindow/CMakeLists.txt b/examples/opengl/paintedwindow/CMakeLists.txt
deleted file mode 100644
index f8805eb1dc..0000000000
--- a/examples/opengl/paintedwindow/CMakeLists.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(paintedwindow LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/paintedwindow")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL)
-
-qt_add_executable(paintedwindow
- main.cpp
- paintedwindow.cpp paintedwindow.h
-)
-
-set_target_properties(paintedwindow PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(paintedwindow PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
-)
-
-install(TARGETS paintedwindow
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/opengl/paintedwindow/main.cpp b/examples/opengl/paintedwindow/main.cpp
deleted file mode 100644
index e055e92812..0000000000
--- a/examples/opengl/paintedwindow/main.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QGuiApplication>
-#include <QRect>
-
-#include "paintedwindow.h"
-
-int main(int argc, char **argv)
-{
- QGuiApplication app(argc, argv);
-
- PaintedWindow window;
- window.show();
-
- return app.exec();
-}
-
diff --git a/examples/opengl/paintedwindow/paintedwindow.cpp b/examples/opengl/paintedwindow/paintedwindow.cpp
deleted file mode 100644
index d0b8284157..0000000000
--- a/examples/opengl/paintedwindow/paintedwindow.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "paintedwindow.h"
-
-#include <QGuiApplication>
-#include <QOpenGLContext>
-#include <QOpenGLPaintDevice>
-#include <QPainter>
-#include <QPainterPath>
-#include <QScreen>
-#include <QTimer>
-
-#include <qmath.h>
-
-PaintedWindow::PaintedWindow()
-{
- QSurfaceFormat format;
- format.setStencilBufferSize(8);
- format.setSamples(4);
-
- setSurfaceType(QWindow::OpenGLSurface);
- setFlags(Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint);
- setFormat(format);
-
- create();
-
- m_context = new QOpenGLContext(this);
- m_context->setFormat(format);
- m_context->create();
-
- m_animation = new QPropertyAnimation(this, "rotation");
- m_animation->setStartValue(qreal(0));
- m_animation->setEndValue(qreal(1));
- m_animation->setDuration(500);
-
- QRect screenGeometry = screen()->availableGeometry();
-
- QPoint center = screenGeometry.center();
- QRect windowRect = screen()->isLandscape(screen()->orientation()) ? QRect(0, 0, 640, 480) : QRect(0, 0, 480, 640);
- setGeometry(QRect(center - windowRect.center(), windowRect.size()));
-
- m_rotation = 0;
-
- reportContentOrientationChange(screen()->orientation());
-
- m_targetOrientation = contentOrientation();
- m_nextTargetOrientation = Qt::PrimaryOrientation;
-
- connect(screen(), &QScreen::orientationChanged, this, &PaintedWindow::orientationChanged);
- connect(m_animation, &QAbstractAnimation::finished, this, &PaintedWindow::rotationDone);
- connect(this, &PaintedWindow::rotationChanged, this, QOverload<>::of(&PaintedWindow::paint));
-}
-
-void PaintedWindow::exposeEvent(QExposeEvent *)
-{
- if (isExposed())
- paint();
-}
-
-void PaintedWindow::mousePressEvent(QMouseEvent *)
-{
- Qt::ScreenOrientation o = contentOrientation();
- switch (o) {
- case Qt::LandscapeOrientation:
- orientationChanged(Qt::PortraitOrientation);
- break;
- case Qt::PortraitOrientation:
- orientationChanged(Qt::InvertedLandscapeOrientation);
- break;
- case Qt::InvertedLandscapeOrientation:
- orientationChanged(Qt::InvertedPortraitOrientation);
- break;
- case Qt::InvertedPortraitOrientation:
- orientationChanged(Qt::LandscapeOrientation);
- break;
- default:
- Q_ASSERT(false);
- }
-
- paint();
-}
-
-void PaintedWindow::orientationChanged(Qt::ScreenOrientation newOrientation)
-{
- if (contentOrientation() == newOrientation)
- return;
-
- if (m_animation->state() == QAbstractAnimation::Running) {
- m_nextTargetOrientation = newOrientation;
- return;
- }
-
- QRect rect(0, 0, width(), height());
-
- m_prevImage = QImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
- m_nextImage = QImage(width(), height(), QImage::Format_ARGB32_Premultiplied);
- m_prevImage.fill(0);
- m_nextImage.fill(0);
-
- QPainter p;
- p.begin(&m_prevImage);
- p.setTransform(screen()->transformBetween(contentOrientation(), screen()->orientation(), rect));
- paint(&p, screen()->mapBetween(contentOrientation(), screen()->orientation(), rect));
- p.end();
-
- p.begin(&m_nextImage);
- p.setTransform(screen()->transformBetween(newOrientation, screen()->orientation(), rect));
- paint(&p, screen()->mapBetween(newOrientation, screen()->orientation(), rect));
- p.end();
-
- m_deltaRotation = screen()->angleBetween(newOrientation, contentOrientation());
- if (m_deltaRotation > 180)
- m_deltaRotation = 180 - m_deltaRotation;
-
- m_targetOrientation = newOrientation;
- m_animation->start();
-}
-
-void PaintedWindow::rotationDone()
-{
- reportContentOrientationChange(m_targetOrientation);
- if (m_nextTargetOrientation != Qt::PrimaryOrientation) {
- Q_ASSERT(m_animation->state() != QAbstractAnimation::Running);
- orientationChanged(m_nextTargetOrientation);
- m_nextTargetOrientation = Qt::PrimaryOrientation;
- }
-}
-
-void PaintedWindow::setRotation(qreal r)
-{
- if (r != m_rotation) {
- m_rotation = r;
- emit rotationChanged(r);
- }
-}
-
-void PaintedWindow::paint()
-{
- m_context->makeCurrent(this);
-
- QRect rect(0, 0, width() * devicePixelRatio(), height() * devicePixelRatio());
-
- QOpenGLPaintDevice device(size() * devicePixelRatio());
- QPainter painter(&device);
-
- QPainterPath path;
- path.addEllipse(rect);
- painter.setCompositionMode(QPainter::CompositionMode_Source);
- painter.fillRect(rect, Qt::transparent);
- painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
- painter.fillPath(path, Qt::blue);
-
- if (contentOrientation() != m_targetOrientation) {
- painter.setRenderHint(QPainter::SmoothPixmapTransform);
- painter.save();
- painter.translate(width() / 2, height() / 2);
- painter.rotate(m_deltaRotation * m_rotation);
- painter.translate(-width() / 2, -height() / 2);
- painter.drawImage(0, 0, m_prevImage);
- painter.restore();
- painter.translate(width() / 2, height() / 2);
- painter.rotate(m_deltaRotation * m_rotation - m_deltaRotation);
- painter.translate(-width() / 2, -height() / 2);
- painter.setOpacity(m_rotation);
- painter.drawImage(0, 0, m_nextImage);
- } else {
- QRect mapped = screen()->mapBetween(contentOrientation(), screen()->orientation(), rect);
-
- painter.setTransform(screen()->transformBetween(contentOrientation(), screen()->orientation(), rect));
- paint(&painter, mapped);
- painter.end();
- }
-
- m_context->swapBuffers(this);
-}
-
-void PaintedWindow::paint(QPainter *painter, const QRect &rect)
-{
- painter->setRenderHint(QPainter::Antialiasing);
- QFont font;
- font.setPixelSize(64);
- painter->setFont(font);
- painter->drawText(rect, Qt::AlignCenter, "Hello");
-}
diff --git a/examples/opengl/paintedwindow/paintedwindow.h b/examples/opengl/paintedwindow/paintedwindow.h
deleted file mode 100644
index 3fa781bf2c..0000000000
--- a/examples/opengl/paintedwindow/paintedwindow.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QWindow>
-
-#include <QtGui/qopengl.h>
-#include <QtOpenGL/qopenglshaderprogram.h>
-#include <QtOpenGL/qopenglframebufferobject.h>
-
-#include <QPropertyAnimation>
-
-#include <QColor>
-#include <QImage>
-#include <QTime>
-
-QT_BEGIN_NAMESPACE
-class QOpenGLContext;
-QT_END_NAMESPACE
-
-class PaintedWindow : public QWindow
-{
- Q_OBJECT
- Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged)
-
-public:
- PaintedWindow();
-
- qreal rotation() const { return m_rotation; }
-
-signals:
- void rotationChanged(qreal rotation);
-
-private slots:
- void paint();
- void setRotation(qreal r);
- void orientationChanged(Qt::ScreenOrientation newOrientation);
- void rotationDone();
-
-private:
- void exposeEvent(QExposeEvent *) override;
- void mousePressEvent(QMouseEvent *) override;
-
- void paint(QPainter *painter, const QRect &rect);
-
- QOpenGLContext *m_context;
- qreal m_rotation;
-
- QImage m_prevImage;
- QImage m_nextImage;
- qreal m_deltaRotation;
-
- Qt::ScreenOrientation m_targetOrientation;
- Qt::ScreenOrientation m_nextTargetOrientation;
-
- QPropertyAnimation *m_animation;
- QTimer *m_paintTimer;
-};
diff --git a/examples/opengl/paintedwindow/paintedwindow.pro b/examples/opengl/paintedwindow/paintedwindow.pro
deleted file mode 100644
index 569eebe674..0000000000
--- a/examples/opengl/paintedwindow/paintedwindow.pro
+++ /dev/null
@@ -1,8 +0,0 @@
-QT += opengl
-
-HEADERS += paintedwindow.h
-SOURCES += paintedwindow.cpp main.cpp
-
-# install
-target.path = $$[QT_INSTALL_EXAMPLES]/opengl/paintedwindow
-INSTALLS += target
diff --git a/examples/opengl/qopenglwidget/CMakeLists.txt b/examples/opengl/qopenglwidget/CMakeLists.txt
deleted file mode 100644
index d2c48981da..0000000000
--- a/examples/opengl/qopenglwidget/CMakeLists.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(qopenglwidget LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/qopenglwidget")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets)
-
-qt_add_executable(qopenglwidget
- bubble.cpp bubble.h
- glwidget.cpp glwidget.h
- main.cpp
- mainwindow.cpp mainwindow.h
-)
-
-set_target_properties(qopenglwidget PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(qopenglwidget PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
- Qt::OpenGLWidgets
- Qt::Widgets
-)
-
-# Resources:
-set(texture_resource_files
- "qt.png"
-)
-
-qt6_add_resources(qopenglwidget "texture"
- PREFIX
- "/"
- FILES
- ${texture_resource_files}
-)
-
-install(TARGETS qopenglwidget
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/opengl/qopenglwidget/bubble.cpp b/examples/opengl/qopenglwidget/bubble.cpp
deleted file mode 100644
index 3c32b62113..0000000000
--- a/examples/opengl/qopenglwidget/bubble.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QtWidgets>
-
-#include "bubble.h"
-
-Bubble::Bubble(const QPointF &position, qreal radius, const QPointF &velocity)
- : position(position), vel(velocity), radius(radius)
-{
- innerColor = randomColor();
- outerColor = randomColor();
- updateBrush();
-}
-
-//! [0]
-void Bubble::updateCache()
-{
- delete cache;
- cache = new QImage(qRound(radius * 2 + 2), qRound(radius * 2 + 2), QImage::Format_ARGB32_Premultiplied);
- cache->fill(0x00000000);
- QPainter p(cache);
- p.setRenderHint(QPainter::Antialiasing);
- QPen pen(Qt::white);
- pen.setWidth(2);
- p.setPen(pen);
- p.setBrush(brush);
- p.drawEllipse(1, 1, int(2*radius), int(2*radius));
-}
-//! [0]
-
-Bubble::~Bubble()
-{
- delete cache;
-}
-
-void Bubble::updateBrush()
-{
- QRadialGradient gradient(QPointF(radius, radius), radius,
- QPointF(radius*0.5, radius*0.5));
-
- gradient.setColorAt(0, QColor(255, 255, 255, 255));
- gradient.setColorAt(0.25, innerColor);
- gradient.setColorAt(1, outerColor);
- brush = QBrush(gradient);
- updateCache();
-}
-
-//! [1]
-void Bubble::drawBubble(QPainter *painter)
-{
- painter->save();
- painter->translate(position.x() - radius, position.y() - radius);
- painter->setOpacity(0.8);
- painter->drawImage(0, 0, *cache);
- painter->restore();
-}
-//! [1]
-
-QColor Bubble::randomColor()
-{
- int red = int(185 + QRandomGenerator::global()->bounded(70));
- int green = int(185 + QRandomGenerator::global()->bounded(70));
- int blue = int(205 + QRandomGenerator::global()->bounded(50));
- int alpha = int(91 + QRandomGenerator::global()->bounded(100));
-
- return QColor(red, green, blue, alpha);
-}
-
-void Bubble::move(const QRect &bbox)
-{
- position += vel;
- qreal leftOverflow = position.x() - radius - bbox.left();
- qreal rightOverflow = position.x() + radius - bbox.right();
- qreal topOverflow = position.y() - radius - bbox.top();
- qreal bottomOverflow = position.y() + radius - bbox.bottom();
-
- if (leftOverflow < 0.0) {
- position.setX(position.x() - 2 * leftOverflow);
- vel.setX(-vel.x());
- } else if (rightOverflow > 0.0) {
- position.setX(position.x() - 2 * rightOverflow);
- vel.setX(-vel.x());
- }
-
- if (topOverflow < 0.0) {
- position.setY(position.y() - 2 * topOverflow);
- vel.setY(-vel.y());
- } else if (bottomOverflow > 0.0) {
- position.setY(position.y() - 2 * bottomOverflow);
- vel.setY(-vel.y());
- }
-}
-
-QRectF Bubble::rect()
-{
- return QRectF(position.x() - radius, position.y() - radius,
- 2 * radius, 2 * radius);
-}
diff --git a/examples/opengl/qopenglwidget/bubble.h b/examples/opengl/qopenglwidget/bubble.h
deleted file mode 100644
index 47355ead41..0000000000
--- a/examples/opengl/qopenglwidget/bubble.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef BUBBLE_H
-#define BUBBLE_H
-
-#include <QBrush>
-#include <QColor>
-#include <QPointF>
-#include <QRect>
-#include <QRectF>
-
-QT_FORWARD_DECLARE_CLASS(QPainter)
-
-class Bubble
-{
-public:
- Bubble(const QPointF &position, qreal radius, const QPointF &velocity);
- ~Bubble();
-
- void drawBubble(QPainter *painter);
- void updateBrush();
- void move(const QRect &bbox);
- void updateCache();
- QRectF rect();
-
-private:
- QColor randomColor();
-
- QBrush brush;
- QPointF position;
- QPointF vel;
- qreal radius;
- QColor innerColor;
- QColor outerColor;
- QImage *cache = nullptr;
-};
-
-#endif
diff --git a/examples/opengl/qopenglwidget/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp
deleted file mode 100644
index 96d5d51321..0000000000
--- a/examples/opengl/qopenglwidget/glwidget.cpp
+++ /dev/null
@@ -1,540 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "glwidget.h"
-#include <QPainter>
-#include <QPaintEngine>
-#include <QOpenGLShaderProgram>
-#include <QOpenGLTexture>
-#include <QRandomGenerator>
-#include <QCoreApplication>
-#include <qmath.h>
-
-#include "mainwindow.h"
-#include "bubble.h"
-
-const int bubbleNum = 8;
-
-#ifndef GL_SRGB8_ALPHA8
-#define GL_SRGB8_ALPHA8 0x8C43
-#endif
-
-GLWidget::GLWidget(MainWindow *maybeMainWindow, const QColor &background)
- : m_mainWindow(maybeMainWindow),
- m_background(background)
-{
- setMinimumSize(300, 250);
- if (QCoreApplication::arguments().contains(QStringLiteral("--srgb")))
- setTextureFormat(GL_SRGB8_ALPHA8);
-}
-
-GLWidget::~GLWidget()
-{
- reset();
-}
-
-void GLWidget::reset()
-{
- qDeleteAll(m_bubbles);
- // Leave everything in a state suitable for a subsequent call to
- // initialize(). This matters when coming from the context's
- // aboutToBeDestroyed signal, would not matter when invoked from the
- // destructor.
- m_bubbles.clear();
-
- // And now release all OpenGL resources.
- makeCurrent();
- delete m_texture;
- m_texture = nullptr;
- delete m_program1;
- m_program1 = nullptr;
- delete m_program2;
- m_program2 = nullptr;
- delete m_vshader1;
- m_vshader1 = nullptr;
- delete m_fshader1;
- m_fshader1 = nullptr;
- delete m_vshader2;
- m_vshader2 = nullptr;
- delete m_fshader2;
- m_fshader2 = nullptr;
- m_vbo1.destroy();
- m_vbo2.destroy();
- doneCurrent();
-
- // We are done with the current QOpenGLContext, forget it. If there is a
- // subsequent initialize(), that will then connect to the new context.
- QObject::disconnect(m_contextWatchConnection);
-}
-
-void GLWidget::setScaling(int scale)
-{
- if (scale > 30)
- m_fScale = 1 + qreal(scale - 30) / 30 * 0.25;
- else if (scale < 30)
- m_fScale = 1 - (qreal(30 - scale) / 30 * 0.25);
- else
- m_fScale = 1;
-}
-
-void GLWidget::setLogo()
-{
- m_qtLogo = true;
-}
-
-void GLWidget::setTexture()
-{
- m_qtLogo = false;
-}
-
-void GLWidget::setShowBubbles(bool bubbles)
-{
- m_showBubbles = bubbles;
-}
-
-void GLWidget::paintQtLogo()
-{
- m_program1->enableAttributeArray(m_vertexAttr1);
- m_program1->enableAttributeArray(m_normalAttr1);
-
- m_vbo1.bind();
- // The data in the buffer is placed like this:
- // vertex1.x, vertex1.y, vertex1.z, normal1.x, normal1.y, normal1.z, vertex2.x, ...
- m_program1->setAttributeBuffer(m_vertexAttr1, GL_FLOAT, 0, 3, 6 * sizeof(GLfloat));
- m_program1->setAttributeBuffer(m_normalAttr1, GL_FLOAT, 3 * sizeof(GLfloat), 3, 6 * sizeof(GLfloat));
- m_vbo1.release();
-
- glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
-
- m_program1->disableAttributeArray(m_normalAttr1);
- m_program1->disableAttributeArray(m_vertexAttr1);
-}
-
-void GLWidget::paintTexturedCube()
-{
- m_texture->bind();
-
- if (!m_vbo2.isCreated()) {
- static GLfloat afVertices[] = {
- -0.5, 0.5, 0.5, 0.5,-0.5,0.5,-0.5,-0.5,0.5,
- 0.5, -0.5, 0.5, -0.5,0.5,0.5,0.5,0.5,0.5,
- -0.5, -0.5, -0.5, 0.5,-0.5,-0.5,-0.5,0.5,-0.5,
- 0.5, 0.5, -0.5, -0.5,0.5,-0.5,0.5,-0.5,-0.5,
-
- 0.5, -0.5, -0.5, 0.5,-0.5,0.5,0.5,0.5,-0.5,
- 0.5, 0.5, 0.5, 0.5,0.5,-0.5,0.5,-0.5,0.5,
- -0.5, 0.5, -0.5, -0.5,-0.5,0.5,-0.5,-0.5,-0.5,
- -0.5, -0.5, 0.5, -0.5,0.5,-0.5,-0.5,0.5,0.5,
-
- 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5,
- -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5,
- -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5,
- 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5
- };
-
- static GLfloat afTexCoord[] = {
- 0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
- 1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
- 1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
- 0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
-
- 1.0f,1.0f, 1.0f,0.0f, 0.0f,1.0f,
- 0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f,
- 0.0f,0.0f, 1.0f,1.0f, 1.0f,0.0f,
- 1.0f,1.0f, 0.0f,0.0f, 0.0f,1.0f,
-
- 0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,
- 1.0f,0.0f, 0.0f,1.0f, 0.0f,0.0f,
- 1.0f,0.0f, 1.0f,1.0f, 0.0f,0.0f,
- 0.0f,1.0f, 0.0f,0.0f, 1.0f,1.0f
- };
-
- GLfloat afNormals[] = {
-
- 0,0,-1, 0,0,-1, 0,0,-1,
- 0,0,-1, 0,0,-1, 0,0,-1,
- 0,0,1, 0,0,1, 0,0,1,
- 0,0,1, 0,0,1, 0,0,1,
-
- -1,0,0, -1,0,0, -1,0,0,
- -1,0,0, -1,0,0, -1,0,0,
- 1,0,0, 1,0,0, 1,0,0,
- 1,0,0, 1,0,0, 1,0,0,
-
- 0,-1,0, 0,-1,0, 0,-1,0,
- 0,-1,0, 0,-1,0, 0,-1,0,
- 0,1,0, 0,1,0, 0,1,0,
- 0,1,0, 0,1,0, 0,1,0
- };
-
- m_vbo2.create();
- m_vbo2.bind();
- m_vbo2.allocate(36 * 8 * sizeof(GLfloat));
- m_vbo2.write(0, afVertices, sizeof(afVertices));
- m_vbo2.write(sizeof(afVertices), afTexCoord, sizeof(afTexCoord));
- m_vbo2.write(sizeof(afVertices) + sizeof(afTexCoord), afNormals, sizeof(afNormals));
- m_vbo2.release();
- }
-
- m_program2->setUniformValue(m_textureUniform2, 0); // use texture unit 0
-
- m_program2->enableAttributeArray(m_vertexAttr2);
- m_program2->enableAttributeArray(m_normalAttr2);
- m_program2->enableAttributeArray(m_texCoordAttr2);
-
- m_vbo2.bind();
- // In the buffer we first have 36 vertices (3 floats for each), then 36 texture
- // coordinates (2 floats for each), then 36 normals (3 floats for each).
- m_program2->setAttributeBuffer(m_vertexAttr2, GL_FLOAT, 0, 3);
- m_program2->setAttributeBuffer(m_texCoordAttr2, GL_FLOAT, 36 * 3 * sizeof(GLfloat), 2);
- m_program2->setAttributeBuffer(m_normalAttr2, GL_FLOAT, 36 * 5 * sizeof(GLfloat), 3);
- m_vbo2.release();
-
- glDrawArrays(GL_TRIANGLES, 0, 36);
-
- m_program2->disableAttributeArray(m_vertexAttr2);
- m_program2->disableAttributeArray(m_normalAttr2);
- m_program2->disableAttributeArray(m_texCoordAttr2);
-}
-
-void GLWidget::initializeGL()
-{
- initializeOpenGLFunctions();
-
- m_texture = new QOpenGLTexture(QImage(":/qt.png"));
-
- m_vshader1 = new QOpenGLShader(QOpenGLShader::Vertex);
- const char *vsrc1 =
- "attribute highp vec4 vertex;\n"
- "attribute mediump vec3 normal;\n"
- "uniform mediump mat4 matrix;\n"
- "varying mediump vec4 color;\n"
- "void main(void)\n"
- "{\n"
- " vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
- " float angle = max(dot(normal, toLight), 0.0);\n"
- " vec3 col = vec3(0.40, 1.0, 0.0);\n"
- " color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);\n"
- " color = clamp(color, 0.0, 1.0);\n"
- " gl_Position = matrix * vertex;\n"
- "}\n";
- m_vshader1->compileSourceCode(vsrc1);
-
- m_fshader1 = new QOpenGLShader(QOpenGLShader::Fragment);
- const char *fsrc1 =
- "varying mediump vec4 color;\n"
- "void main(void)\n"
- "{\n"
- " gl_FragColor = color;\n"
- "}\n";
- m_fshader1->compileSourceCode(fsrc1);
-
- m_program1 = new QOpenGLShaderProgram;
- m_program1->addShader(m_vshader1);
- m_program1->addShader(m_fshader1);
- m_program1->link();
-
- m_vertexAttr1 = m_program1->attributeLocation("vertex");
- m_normalAttr1 = m_program1->attributeLocation("normal");
- m_matrixUniform1 = m_program1->uniformLocation("matrix");
-
- m_vshader2 = new QOpenGLShader(QOpenGLShader::Vertex);
- const char *vsrc2 =
- "attribute highp vec4 vertex;\n"
- "attribute highp vec4 texCoord;\n"
- "attribute mediump vec3 normal;\n"
- "uniform mediump mat4 matrix;\n"
- "varying highp vec4 texc;\n"
- "varying mediump float angle;\n"
- "void main(void)\n"
- "{\n"
- " vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
- " angle = max(dot(normal, toLight), 0.0);\n"
- " gl_Position = matrix * vertex;\n"
- " texc = texCoord;\n"
- "}\n";
- m_vshader2->compileSourceCode(vsrc2);
-
- m_fshader2 = new QOpenGLShader(QOpenGLShader::Fragment);
- const char *fsrc2 =
- "varying highp vec4 texc;\n"
- "uniform sampler2D tex;\n"
- "varying mediump float angle;\n"
- "void main(void)\n"
- "{\n"
- " highp vec3 color = texture2D(tex, texc.st).rgb;\n"
- " color = color * 0.2 + color * 0.8 * angle;\n"
- " gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0);\n"
- "}\n";
- m_fshader2->compileSourceCode(fsrc2);
-
- m_program2 = new QOpenGLShaderProgram;
- m_program2->addShader(m_vshader2);
- m_program2->addShader(m_fshader2);
- m_program2->link();
-
- m_vertexAttr2 = m_program2->attributeLocation("vertex");
- m_normalAttr2 = m_program2->attributeLocation("normal");
- m_texCoordAttr2 = m_program2->attributeLocation("texCoord");
- m_matrixUniform2 = m_program2->uniformLocation("matrix");
- m_textureUniform2 = m_program2->uniformLocation("tex");
-
- m_fAngle = 0;
- m_fScale = 1;
-
- createGeometry();
-
- // Use a vertex buffer object. Client-side pointers are old-school and should be avoided.
- m_vbo1.create();
- m_vbo1.bind();
- // For the cube all the data belonging to the texture coordinates and
- // normals is placed separately, after the vertices. Here, for the Qt logo,
- // let's do something different and potentially more efficient: create a
- // properly interleaved data set.
- const int vertexCount = m_vertices.count();
- QList<GLfloat> buf;
- buf.resize(vertexCount * 3 * 2);
- GLfloat *p = buf.data();
- for (int i = 0; i < vertexCount; ++i) {
- *p++ = m_vertices[i].x();
- *p++ = m_vertices[i].y();
- *p++ = m_vertices[i].z();
- *p++ = m_normals[i].x();
- *p++ = m_normals[i].y();
- *p++ = m_normals[i].z();
- }
- m_vbo1.allocate(buf.constData(), buf.count() * sizeof(GLfloat));
- m_vbo1.release();
-
- createBubbles(bubbleNum - m_bubbles.count());
-
- // A well-behaved QOpenGLWidget releases OpenGL resources not only upon
- // destruction, but also when the associated OpenGL context disappears. If
- // the widget continues to exist, the context's destruction will be
- // followed by a call to initialize(). This is not strictly mandatory in
- // widgets that never change their parents.
- m_contextWatchConnection = QObject::connect(context(), &QOpenGLContext::aboutToBeDestroyed, context(), [this] { reset(); });
-}
-
-void GLWidget::paintGL()
-{
- createBubbles(bubbleNum - m_bubbles.count());
-
- QPainter painter;
- painter.begin(this);
-
- painter.beginNativePainting();
-
- glClearColor(m_background.redF(), m_background.greenF(), m_background.blueF(), m_transparent ? 0.0f : 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glFrontFace(GL_CW);
- glCullFace(GL_FRONT);
- glEnable(GL_CULL_FACE);
- glEnable(GL_DEPTH_TEST);
-
- QMatrix4x4 modelview;
- modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f);
- modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f);
- modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f);
- modelview.scale(m_fScale);
- modelview.translate(0.0f, -0.2f, 0.0f);
-
- if (m_qtLogo) {
- m_program1->bind();
- m_program1->setUniformValue(m_matrixUniform1, modelview);
- paintQtLogo();
- m_program1->release();
- } else {
- m_program2->bind();
- m_program2->setUniformValue(m_matrixUniform2, modelview);
- paintTexturedCube();
- m_program2->release();
- }
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
-
- painter.endNativePainting();
-
- if (m_showBubbles) {
- for (Bubble *bubble : qAsConst(m_bubbles))
- bubble->drawBubble(&painter);
- }
-
- if (const int elapsed = m_time.elapsed()) {
- QString framesPerSecond;
- framesPerSecond.setNum(m_frames /(elapsed / 1000.0), 'f', 2);
- painter.setPen(m_transparent ? Qt::black : Qt::white);
- painter.drawText(20, 40, framesPerSecond + " paintGL calls / s");
- }
-
- painter.end();
-
- for (Bubble *bubble : qAsConst(m_bubbles))
- bubble->move(rect());
-
- if (!(m_frames % 100)) {
- m_time.start();
- m_frames = 0;
- }
- m_fAngle += 1.0f;
- ++m_frames;
-
- // When requested, follow the ideal way to animate: Rely on
- // blocking swap and just schedule updates continuously.
- if (!m_mainWindow || !m_mainWindow->timerEnabled())
- update();
-}
-
-void GLWidget::createBubbles(int number)
-{
- for (int i = 0; i < number; ++i) {
- QPointF position(width()*(0.1 + QRandomGenerator::global()->bounded(0.8)),
- height()*(0.1 + QRandomGenerator::global()->bounded(0.8)));
- qreal radius = qMin(width(), height())*(0.0175 + QRandomGenerator::global()->bounded(0.0875));
- QPointF velocity(width()*0.0175*(-0.5 + QRandomGenerator::global()->bounded(1.0)),
- height()*0.0175*(-0.5 + QRandomGenerator::global()->bounded(1.0)));
-
- m_bubbles.append(new Bubble(position, radius, velocity));
- }
-}
-
-void GLWidget::createGeometry()
-{
- m_vertices.clear();
- m_normals.clear();
-
- qreal x1 = +0.06f;
- qreal y1 = -0.14f;
- qreal x2 = +0.14f;
- qreal y2 = -0.06f;
- qreal x3 = +0.08f;
- qreal y3 = +0.00f;
- qreal x4 = +0.30f;
- qreal y4 = +0.22f;
-
- quad(x1, y1, x2, y2, y2, x2, y1, x1);
- quad(x3, y3, x4, y4, y4, x4, y3, x3);
-
- extrude(x1, y1, x2, y2);
- extrude(x2, y2, y2, x2);
- extrude(y2, x2, y1, x1);
- extrude(y1, x1, x1, y1);
- extrude(x3, y3, x4, y4);
- extrude(x4, y4, y4, x4);
- extrude(y4, x4, y3, x3);
-
- const int NumSectors = 100;
- const qreal sectorAngle = 2 * qreal(M_PI) / NumSectors;
-
- for (int i = 0; i < NumSectors; ++i) {
- qreal angle = i * sectorAngle;
- qreal x5 = 0.30 * sin(angle);
- qreal y5 = 0.30 * cos(angle);
- qreal x6 = 0.20 * sin(angle);
- qreal y6 = 0.20 * cos(angle);
-
- angle += sectorAngle;
- qreal x7 = 0.20 * sin(angle);
- qreal y7 = 0.20 * cos(angle);
- qreal x8 = 0.30 * sin(angle);
- qreal y8 = 0.30 * cos(angle);
-
- quad(x5, y5, x6, y6, x7, y7, x8, y8);
-
- extrude(x6, y6, x7, y7);
- extrude(x8, y8, x5, y5);
- }
-
- for (int i = 0;i < m_vertices.size();i++)
- m_vertices[i] *= 2.0f;
-}
-
-void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
-{
- m_vertices << QVector3D(x1, y1, -0.05f);
- m_vertices << QVector3D(x2, y2, -0.05f);
- m_vertices << QVector3D(x4, y4, -0.05f);
-
- m_vertices << QVector3D(x3, y3, -0.05f);
- m_vertices << QVector3D(x4, y4, -0.05f);
- m_vertices << QVector3D(x2, y2, -0.05f);
-
- QVector3D n = QVector3D::normal
- (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f));
-
- m_normals << n;
- m_normals << n;
- m_normals << n;
-
- m_normals << n;
- m_normals << n;
- m_normals << n;
-
- m_vertices << QVector3D(x4, y4, 0.05f);
- m_vertices << QVector3D(x2, y2, 0.05f);
- m_vertices << QVector3D(x1, y1, 0.05f);
-
- m_vertices << QVector3D(x2, y2, 0.05f);
- m_vertices << QVector3D(x4, y4, 0.05f);
- m_vertices << QVector3D(x3, y3, 0.05f);
-
- n = QVector3D::normal
- (QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f));
-
- m_normals << n;
- m_normals << n;
- m_normals << n;
-
- m_normals << n;
- m_normals << n;
- m_normals << n;
-}
-
-void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
-{
- m_vertices << QVector3D(x1, y1, +0.05f);
- m_vertices << QVector3D(x2, y2, +0.05f);
- m_vertices << QVector3D(x1, y1, -0.05f);
-
- m_vertices << QVector3D(x2, y2, -0.05f);
- m_vertices << QVector3D(x1, y1, -0.05f);
- m_vertices << QVector3D(x2, y2, +0.05f);
-
- QVector3D n = QVector3D::normal
- (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f));
-
- m_normals << n;
- m_normals << n;
- m_normals << n;
-
- m_normals << n;
- m_normals << n;
- m_normals << n;
-}
-
-void GLWidget::setTransparent(bool transparent)
-{
- setAttribute(Qt::WA_AlwaysStackOnTop, transparent);
- m_transparent = transparent;
- // Call update() on the top-level window after toggling AlwayStackOnTop to make sure
- // the entire backingstore is updated accordingly.
- window()->update();
-}
-
-void GLWidget::resizeGL(int, int)
-{
- if (m_mainWindow) {
- if (!m_btn) {
- m_btn = new QPushButton("\nAdd widget\n", this);
- connect(m_btn, &QPushButton::clicked, this, [this] { m_mainWindow->addNew(); });
- }
- m_btn->move(20, 80);
- if (!m_btn2) {
- m_btn2 = new QPushButton("\nI prefer tabbed widgets\n", this);
- connect(m_btn2, &QPushButton::clicked, this, [this] { m_mainWindow->showNewWindow(); });
- }
- m_btn2->move(20, 160);
- }
-}
diff --git a/examples/opengl/qopenglwidget/glwidget.h b/examples/opengl/qopenglwidget/glwidget.h
deleted file mode 100644
index de9d11b94c..0000000000
--- a/examples/opengl/qopenglwidget/glwidget.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef GLWIDGET_H
-#define GLWIDGET_H
-
-#include <QOpenGLWidget>
-#include <QOpenGLFunctions>
-#include <QOpenGLBuffer>
-#include <QVector3D>
-#include <QMatrix4x4>
-#include <QElapsedTimer>
-#include <QList>
-#include <QPushButton>
-
-class Bubble;
-class MainWindow;
-
-QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
-QT_FORWARD_DECLARE_CLASS(QOpenGLShader)
-QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
-
-class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
-{
- Q_OBJECT
-public:
- GLWidget(MainWindow *maybeMainWindow, const QColor &background);
- ~GLWidget();
-
-public slots:
- void setScaling(int scale);
- void setLogo();
- void setTexture();
- void setShowBubbles(bool);
- void setTransparent(bool transparent);
-
-protected:
- void resizeGL(int w, int h) override;
- void paintGL() override;
- void initializeGL() override;
-
-private:
- void paintTexturedCube();
- void paintQtLogo();
- void createGeometry();
- void createBubbles(int number);
- void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4);
- void extrude(qreal x1, qreal y1, qreal x2, qreal y2);
- void reset();
-
- MainWindow *m_mainWindow;
- qreal m_fAngle = 0;
- qreal m_fScale = 1;
- bool m_showBubbles = true;
- QList<QVector3D> m_vertices;
- QList<QVector3D> m_normals;
- bool m_qtLogo = true;
- QList<Bubble *> m_bubbles;
- int m_frames = 0;
- QElapsedTimer m_time;
- QOpenGLShader *m_vshader1 = nullptr;
- QOpenGLShader *m_fshader1 = nullptr;
- QOpenGLShader *m_vshader2 = nullptr;
- QOpenGLShader *m_fshader2 = nullptr;
- QOpenGLShaderProgram *m_program1 = nullptr;
- QOpenGLShaderProgram *m_program2 = nullptr;
- QOpenGLTexture *m_texture = nullptr;
- QOpenGLBuffer m_vbo1;
- QOpenGLBuffer m_vbo2;
- int m_vertexAttr1 = 0;
- int m_normalAttr1 = 0;
- int m_matrixUniform1 = 0;
- int m_vertexAttr2 = 0;
- int m_normalAttr2 = 0;
- int m_texCoordAttr2 = 0;
- int m_matrixUniform2 = 0;
- int m_textureUniform2 = 0;
- bool m_transparent = false;
- QPushButton *m_btn = nullptr;
- QPushButton *m_btn2 = nullptr;
- QColor m_background;
- QMetaObject::Connection m_contextWatchConnection;
-};
-
-#endif
diff --git a/examples/opengl/qopenglwidget/main.cpp b/examples/opengl/qopenglwidget/main.cpp
deleted file mode 100644
index 04f1c57f08..0000000000
--- a/examples/opengl/qopenglwidget/main.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QApplication>
-#include <QMainWindow>
-#include <QColorSpace>
-#include <QSurfaceFormat>
-#include <QCommandLineParser>
-#include <QCommandLineOption>
-#include "mainwindow.h"
-
-int main( int argc, char ** argv )
-{
- Q_INIT_RESOURCE(texture);
- QApplication a( argc, argv );
-
- QCoreApplication::setApplicationName("Qt QOpenGLWidget Example");
- QCoreApplication::setOrganizationName("QtProject");
- QCoreApplication::setApplicationVersion(QT_VERSION_STR);
- QCommandLineParser parser;
- parser.setApplicationDescription(QCoreApplication::applicationName());
- parser.addHelpOption();
- parser.addVersionOption();
- QCommandLineOption multipleSampleOption("multisample", "Multisampling");
- parser.addOption(multipleSampleOption);
- QCommandLineOption srgbOption("srgb", "Use sRGB Color Space");
- parser.addOption(srgbOption);
- parser.process(a);
-
- QSurfaceFormat format;
- format.setDepthBufferSize(24);
- format.setStencilBufferSize(8);
- if (parser.isSet(srgbOption))
- format.setColorSpace(QColorSpace::SRgb);
- if (parser.isSet(multipleSampleOption))
- format.setSamples(4);
- QSurfaceFormat::setDefaultFormat(format);
-
- MainWindow mw;
- mw.resize(1280, 720);
- mw.show();
- return a.exec();
-}
diff --git a/examples/opengl/qopenglwidget/mainwindow.cpp b/examples/opengl/qopenglwidget/mainwindow.cpp
deleted file mode 100644
index 409ff7b507..0000000000
--- a/examples/opengl/qopenglwidget/mainwindow.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "mainwindow.h"
-
-#include <QApplication>
-#include <QMenuBar>
-#include <QGroupBox>
-#include <QSlider>
-#include <QLabel>
-#include <QCheckBox>
-#include <QRandomGenerator>
-#include <QSpinBox>
-#include <QScrollArea>
-#include <QTabWidget>
-#include <QTabBar>
-#include <QToolButton>
-
-#include "glwidget.h"
-
-MainWindow::MainWindow()
- : m_nextX(1), m_nextY(1)
-{
- GLWidget *glwidget = new GLWidget(this, qRgb(20, 20, 50));
- m_glWidgets << glwidget;
- QLabel *label = new QLabel(this);
- m_timer = new QTimer(this);
- QSlider *slider = new QSlider(this);
- slider->setOrientation(Qt::Horizontal);
-
- QLabel *updateLabel = new QLabel("Update interval");
- QSpinBox *updateInterval = new QSpinBox(this);
- updateInterval->setSuffix(" ms");
- updateInterval->setValue(10);
- updateInterval->setToolTip("Interval for the timer that calls update().\n"
- "Note that on most systems the swap will block to wait for vsync\n"
- "and therefore an interval < 16 ms will likely lead to a 60 FPS update rate.");
- QGroupBox *updateGroupBox = new QGroupBox(this);
- QCheckBox *timerBased = new QCheckBox("Use timer", this);
- timerBased->setChecked(false);
- timerBased->setToolTip("Toggles using a timer to trigger update().\n"
- "When not set, each paintGL() schedules the next update immediately,\n"
- "expecting the blocking swap to throttle the thread.\n"
- "This shows how unnecessary the timer is in most cases.");
- QCheckBox *transparent = new QCheckBox("Transparent background", this);
- transparent->setToolTip("Toggles Qt::WA_AlwaysStackOnTop and transparent clear color for glClear().\n"
- "Note how the button on top stacks incorrectly when enabling this.");
- QHBoxLayout *updateLayout = new QHBoxLayout;
- updateLayout->addWidget(updateLabel);
- updateLayout->addWidget(updateInterval);
- updateLayout->addWidget(timerBased);
- updateLayout->addWidget(transparent);
- updateGroupBox->setLayout(updateLayout);
-
- slider->setRange(0, 50);
- slider->setSliderPosition(30);
- m_timer->setInterval(10);
- label->setText("A scrollable QOpenGLWidget");
- label->setAlignment(Qt::AlignHCenter);
-
- QGroupBox * groupBox = new QGroupBox(this);
- setCentralWidget(groupBox);
- groupBox->setTitle("QOpenGLWidget Example");
-
- m_layout = new QGridLayout(groupBox);
-
- QScrollArea *scrollArea = new QScrollArea;
- scrollArea->setWidget(glwidget);
-
- m_layout->addWidget(scrollArea,1,0,8,1);
- m_layout->addWidget(label,9,0,1,1);
- m_layout->addWidget(updateGroupBox, 10, 0, 1, 1);
- m_layout->addWidget(slider, 11,0,1,1);
-
- groupBox->setLayout(m_layout);
-
-
- QMenu *fileMenu = menuBar()->addMenu("&File");
- fileMenu->addAction("E&xit", this, &QWidget::close);
- QMenu *showMenu = menuBar()->addMenu("&Show");
- showMenu->addAction("Show 3D Logo", glwidget, &GLWidget::setLogo);
- showMenu->addAction("Show 2D Texture", glwidget, &GLWidget::setTexture);
- QAction *showBubbles = showMenu->addAction("Show bubbles", glwidget, &GLWidget::setShowBubbles);
- showBubbles->setCheckable(true);
- showBubbles->setChecked(true);
- showMenu->addAction("Open tab window", this, &MainWindow::showNewWindow);
- QMenu *helpMenu = menuBar()->addMenu("&Help");
- helpMenu->addAction("About Qt", qApp, &QApplication::aboutQt);
-
- connect(m_timer, &QTimer::timeout, glwidget, QOverload<>::of(&QWidget::update));
-
- connect(slider, &QAbstractSlider::valueChanged, glwidget, &GLWidget::setScaling);
- connect(transparent, &QCheckBox::toggled, glwidget, &GLWidget::setTransparent);
- connect(updateInterval, &QSpinBox::valueChanged,
- this, &MainWindow::updateIntervalChanged);
- connect(timerBased, &QCheckBox::toggled, this, &MainWindow::timerUsageChanged);
- connect(timerBased, &QCheckBox::toggled, updateInterval, &QWidget::setEnabled);
-
- if (timerBased->isChecked())
- m_timer->start();
- else
- updateInterval->setEnabled(false);
-}
-
-void MainWindow::updateIntervalChanged(int value)
-{
- m_timer->setInterval(value);
- if (m_timer->isActive())
- m_timer->start();
-}
-
-void MainWindow::addNew()
-{
- if (m_nextY == 4)
- return;
- GLWidget *w = new GLWidget(nullptr, qRgb(QRandomGenerator::global()->bounded(256),
- QRandomGenerator::global()->bounded(256),
- QRandomGenerator::global()->bounded(256)));
- m_glWidgets << w;
- connect(m_timer, &QTimer::timeout, w, QOverload<>::of(&QWidget::update));
- m_layout->addWidget(w, m_nextY, m_nextX, 1, 1);
- if (m_nextX == 3) {
- m_nextX = 1;
- ++m_nextY;
- } else {
- ++m_nextX;
- }
-}
-
-void MainWindow::timerUsageChanged(bool enabled)
-{
- if (enabled) {
- m_timer->start();
- } else {
- m_timer->stop();
- for (QOpenGLWidget *w : qAsConst(m_glWidgets))
- w->update();
- }
-}
-
-void MainWindow::resizeEvent(QResizeEvent *)
-{
- m_glWidgets[0]->setMinimumSize(size() + QSize(128, 128));
-}
-
-void MainWindow::showNewWindow()
-{
- QTabWidget *tabs = new QTabWidget;
- tabs->resize(800, 600);
-
- QToolButton *tb = new QToolButton;
- tb->setText(QLatin1String("+"));
- tabs->addTab(new QLabel(QLatin1String("Add OpenGL widgets with +")), QString());
- tabs->setTabEnabled(0, false);
- tabs->tabBar()->setTabButton(0, QTabBar::RightSide, tb);
- tabs->tabBar()->setTabsClosable(true);
- QObject::connect(tabs->tabBar(), &QTabBar::tabCloseRequested, tabs, [tabs](int index) {
- tabs->widget(index)->deleteLater();
- });
-
- const QString msgToTopLevel = QLatin1String("Break out to top-level window");
- const QString msgFromTopLevel = QLatin1String("Move back under tab widget");
-
- QObject::connect(tb, &QAbstractButton::clicked, tabs, [=] {
- GLWidget *glwidget = new GLWidget(nullptr, Qt::blue);
- glwidget->resize(tabs->size());
- glwidget->setWindowTitle(QString::asprintf("QOpenGLWidget %p", glwidget));
-
- QPushButton *btn = new QPushButton(msgToTopLevel, glwidget);
- connect(btn, &QPushButton::clicked, glwidget, [=] {
- if (glwidget->parent()) {
- glwidget->setAttribute(Qt::WA_DeleteOnClose, true);
- glwidget->setParent(nullptr);
- glwidget->show();
- btn->setText(msgFromTopLevel);
- } else {
- glwidget->setAttribute(Qt::WA_DeleteOnClose, false);
- tabs->addTab(glwidget, glwidget->windowTitle());
- btn->setText(msgToTopLevel);
- }
- });
-
- tabs->setCurrentIndex(tabs->addTab(glwidget, glwidget->windowTitle()));
- });
-
- tabs->setAttribute(Qt::WA_DeleteOnClose);
- tabs->show();
-}
diff --git a/examples/opengl/qopenglwidget/mainwindow.h b/examples/opengl/qopenglwidget/mainwindow.h
deleted file mode 100644
index 85f11ad764..0000000000
--- a/examples/opengl/qopenglwidget/mainwindow.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef MAINWINDOW_H
-#define MAINWINDOW_H
-
-#include <QMainWindow>
-#include <QTimer>
-#include <QGridLayout>
-
-QT_FORWARD_DECLARE_CLASS(QOpenGLWidget)
-
-class MainWindow : public QMainWindow
-{
- Q_OBJECT
-
-public:
- MainWindow();
- void addNew();
- bool timerEnabled() const { return m_timer->isActive(); }
-
- void resizeEvent(QResizeEvent *);
-
-public slots:
- void showNewWindow();
-
-private slots:
- void updateIntervalChanged(int value);
- void timerUsageChanged(bool enabled);
-
-private:
- QTimer *m_timer;
- QGridLayout *m_layout;
- int m_nextX;
- int m_nextY;
- QList<QOpenGLWidget *> m_glWidgets;
-};
-
-#endif
diff --git a/examples/opengl/qopenglwidget/qopenglwidget.pro b/examples/opengl/qopenglwidget/qopenglwidget.pro
deleted file mode 100644
index 7ac546d7ce..0000000000
--- a/examples/opengl/qopenglwidget/qopenglwidget.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-QT += widgets opengl openglwidgets
-
-SOURCES += main.cpp \
- glwidget.cpp \
- mainwindow.cpp \
- bubble.cpp
-
-HEADERS += glwidget.h \
- mainwindow.h \
- bubble.h
-
-RESOURCES += texture.qrc
-
-target.path = $$[QT_INSTALL_EXAMPLES]/opengl/qopenglwidget
-INSTALLS += target
diff --git a/examples/opengl/qopenglwidget/qt.png b/examples/opengl/qopenglwidget/qt.png
deleted file mode 100644
index 4f68e162de..0000000000
--- a/examples/opengl/qopenglwidget/qt.png
+++ /dev/null
Binary files differ
diff --git a/examples/opengl/qopenglwidget/texture.qrc b/examples/opengl/qopenglwidget/texture.qrc
deleted file mode 100644
index ff1d0e535f..0000000000
--- a/examples/opengl/qopenglwidget/texture.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>qt.png</file>
-</qresource>
-</RCC>
diff --git a/examples/opengl/qopenglwindow/CMakeLists.txt b/examples/opengl/qopenglwindow/CMakeLists.txt
deleted file mode 100644
index 0562cec94c..0000000000
--- a/examples/opengl/qopenglwindow/CMakeLists.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(qopenglwindow LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/qopenglwindow")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL)
-
-qt_add_executable(qopenglwindow
- background_renderer.cpp background_renderer.h
- main.cpp
-)
-
-set_target_properties(qopenglwindow PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(qopenglwindow PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
-)
-
-# Resources:
-set(shaders_resource_files
- "background.frag"
-)
-
-qt_add_resources(qopenglwindow "shaders"
- PREFIX
- "/"
- FILES
- ${shaders_resource_files}
-)
-
-install(TARGETS qopenglwindow
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/opengl/qopenglwindow/background.frag b/examples/opengl/qopenglwindow/background.frag
deleted file mode 100644
index 4af85aae8e..0000000000
--- a/examples/opengl/qopenglwindow/background.frag
+++ /dev/null
@@ -1,30 +0,0 @@
-#define M_PI 3.14159265358979323846
-#define SPEED 10000.0
-
-uniform int currentTime;
-uniform highp vec2 windowSize;
-
-highp float noise(highp vec2 co)
-{
- return 0.5 * fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
-}
-
-highp float curvSpeed()
-{
- return (mod(float(currentTime), SPEED) / SPEED) * (2.0 * M_PI);
-}
-
-highp float curv(int curvCount)
-{
- highp float curv_y = 0.1 *(cos((gl_FragCoord.x / windowSize.x) * (float(curvCount * 2) * M_PI) - curvSpeed())) + 0.5;
- highp float frag_y = gl_FragCoord.y / windowSize.y;
- return 1.0 - abs(curv_y - frag_y);
-}
-
-void main()
-{
- highp float coordNoise = noise(gl_FragCoord.xy);
- highp float proximity = smoothstep(0.85, 1.0, (curv(6) + 1.0) * (coordNoise ));
- highp vec3 color = vec3(coordNoise) * proximity;
- gl_FragColor = vec4(color, 1.0);
-}
diff --git a/examples/opengl/qopenglwindow/background_renderer.cpp b/examples/opengl/qopenglwindow/background_renderer.cpp
deleted file mode 100644
index 5939894dfe..0000000000
--- a/examples/opengl/qopenglwindow/background_renderer.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "background_renderer.h"
-
-#include <qmath.h>
-#include <QFileInfo>
-#include <QTime>
-
-#include <QOpenGLShaderProgram>
-#include <QOpenGLContext>
-#include <QOpenGLFunctions>
-
-#include <math.h>
-
-static const char vertex_shader[] =
- "attribute highp vec3 vertexCoord;"
- "void main() {"
- " gl_Position = vec4(vertexCoord,1.0);"
- "}";
-
-static const char fragment_shader[] =
- "void main() {"
- " gl_FragColor = vec4(0.0,1.0,0.0,1.0);"
- "}";
-
-static const float vertices[] = { -1, -1, 0,
- -1, 1, 0,
- 1, -1, 0,
- 1, 1, 0 };
-
-FragmentToy::FragmentToy(const QString &fragmentSource, QObject *parent)
- : QObject(parent)
- , m_recompile_shaders(true)
-{
- if (QFile::exists(fragmentSource)) {
- QFileInfo info(fragmentSource);
- m_fragment_file_last_modified = info.lastModified();
- m_fragment_file = fragmentSource;
-#if QT_CONFIG(filesystemwatcher)
- m_watcher.addPath(info.canonicalPath());
- QObject::connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &FragmentToy::fileChanged);
-#endif
- }
-}
-
-FragmentToy::~FragmentToy()
- = default;
-
-void FragmentToy::draw(const QSize &windowSize)
-{
- if (!m_program)
- initializeOpenGLFunctions();
-
- glDisable(GL_STENCIL_TEST);
- glDisable(GL_DEPTH_TEST);
-
- glClearColor(0, 0, 0, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- if (!m_vao.isCreated())
- m_vao.create();
-
- QOpenGLVertexArrayObject::Binder binder(&m_vao);
-
- if (!m_vertex_buffer.isCreated()) {
- m_vertex_buffer.create();
- m_vertex_buffer.bind();
- m_vertex_buffer.allocate(vertices, sizeof(vertices));
- m_vertex_buffer.release();
- }
-
- if (!m_program) {
- m_program.reset(new QOpenGLShaderProgram);
- m_program->create();
- m_vertex_shader.reset(new QOpenGLShader(QOpenGLShader::Vertex));
- if (!m_vertex_shader->compileSourceCode(vertex_shader)) {
- qWarning() << "Failed to compile the vertex shader:" << m_vertex_shader->log();
- }
- if (!m_program->addShader(m_vertex_shader.get())) {
- qWarning() << "Failed to add vertex shader to program:" << m_program->log();
- }
- }
-
- if (!m_fragment_shader && m_recompile_shaders) {
- QByteArray data;
- if (m_fragment_file.size()) {
- QFile file(m_fragment_file);
- if (file.open(QIODevice::ReadOnly)) {
- data = file.readAll();
- } else {
- qWarning() << "Failed to load input file, falling back to default";
- data = QByteArray::fromRawData(fragment_shader, sizeof(fragment_shader));
- }
- } else {
- QFile qrcFile(":/background.frag");
- if (qrcFile.open(QIODevice::ReadOnly))
- data = qrcFile.readAll();
- else
- data = QByteArray::fromRawData(fragment_shader, sizeof(fragment_shader));
- }
- if (data.size()) {
- m_fragment_shader.reset(new QOpenGLShader(QOpenGLShader::Fragment));
- if (!m_fragment_shader->compileSourceCode(data)) {
- qWarning() << "Failed to compile fragment shader:" << m_fragment_shader->log();
- m_fragment_shader.reset(nullptr);
- }
- } else {
- qWarning() << "Unknown error, no fragment shader";
- }
-
- if (m_fragment_shader) {
- if (!m_program->addShader(m_fragment_shader.get())) {
- qWarning() << "Failed to add fragment shader to program:" << m_program->log();
- }
- }
- }
-
- if (m_recompile_shaders) {
- m_recompile_shaders = false;
-
- if (m_program->link()) {
- m_vertex_coord_pos = m_program->attributeLocation("vertexCoord");
- } else {
- qWarning() << "Failed to link shader program" << m_program->log();
- }
-
- }
-
- if (!m_program->isLinked())
- return;
-
- m_program->bind();
-
- m_vertex_buffer.bind();
- m_program->setAttributeBuffer("vertexCoord", GL_FLOAT, 0, 3, 0);
- m_program->enableAttributeArray("vertexCoord");
- m_vertex_buffer.release();
-
- m_program->setUniformValue("currentTime", (uint) QDateTime::currentMSecsSinceEpoch());
- m_program->setUniformValue("windowSize", windowSize);
-
- QOpenGLContext::currentContext()->functions()->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
- m_program->release();
-}
-
-void FragmentToy::fileChanged(const QString &path)
-{
- Q_UNUSED(path);
- if (QFile::exists(m_fragment_file)) {
- QFileInfo fragment_source(m_fragment_file);
- if (fragment_source.lastModified() > m_fragment_file_last_modified) {
- m_fragment_file_last_modified = fragment_source.lastModified();
- m_recompile_shaders = true;
- if (m_program) {
- m_program->removeShader(m_fragment_shader.get());
- m_fragment_shader.reset(nullptr);
- }
- }
- } else {
- m_recompile_shaders = true;
- if (m_program) {
- m_program->removeShader(m_fragment_shader.get());
- m_fragment_shader.reset(nullptr);
- }
- }
-}
diff --git a/examples/opengl/qopenglwindow/background_renderer.h b/examples/opengl/qopenglwindow/background_renderer.h
deleted file mode 100644
index 76c0bec6a8..0000000000
--- a/examples/opengl/qopenglwindow/background_renderer.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef FRAGMENT_TOY_H
-#define FRAGMENT_TOY_H
-
-#include <QObject>
-#include <QFile>
-#include <QDateTime>
-#if QT_CONFIG(filesystemwatcher)
-#include <QFileSystemWatcher>
-#endif
-#include <QOpenGLVertexArrayObject>
-#include <QOpenGLBuffer>
-#include <QOpenGLShaderProgram>
-#include <QOpenGLFunctions>
-
-#include <memory>
-
-class FragmentToy : public QObject, protected QOpenGLFunctions
-{
- Q_OBJECT
-public:
- explicit FragmentToy(const QString &fragmentSource, QObject *parent = nullptr);
- ~FragmentToy();
-
- void draw(const QSize &windowSize);
-
-private:
- void fileChanged(const QString &path);
- bool m_recompile_shaders;
-#if QT_CONFIG(filesystemwatcher)
- QFileSystemWatcher m_watcher;
-#endif
- QString m_fragment_file;
- QDateTime m_fragment_file_last_modified;
-
- std::unique_ptr<QOpenGLShaderProgram> m_program;
- std::unique_ptr<QOpenGLShader> m_vertex_shader;
- std::unique_ptr<QOpenGLShader> m_fragment_shader;
- QOpenGLVertexArrayObject m_vao;
- QOpenGLBuffer m_vertex_buffer;
- GLuint m_vertex_coord_pos;
-};
-
-#endif //FRAGMENT_TOY_H
diff --git a/examples/opengl/qopenglwindow/main.cpp b/examples/opengl/qopenglwindow/main.cpp
deleted file mode 100644
index 44810a4ecf..0000000000
--- a/examples/opengl/qopenglwindow/main.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QOpenGLWindow>
-#include <QScreen>
-#include <QPainter>
-#include <QPainterPath>
-#include <QGuiApplication>
-#include <QMatrix4x4>
-#include <QStaticText>
-#include <QKeyEvent>
-
-#include "background_renderer.h"
-
-static QPainterPath painterPathForTriangle()
-{
- static const QPointF bottomLeft(-1.0, -1.0);
- static const QPointF top(0.0, 1.0);
- static const QPointF bottomRight(1.0, -1.0);
-
- QPainterPath path(bottomLeft);
- path.lineTo(top);
- path.lineTo(bottomRight);
- path.closeSubpath();
- return path;
-}
-
-class OpenGLWindow : public QOpenGLWindow
-{
- Q_OBJECT
-
-public:
- OpenGLWindow();
-
-protected:
- void paintGL() override;
- void resizeGL(int w, int h) override;
- void keyPressEvent(QKeyEvent *e) override;
-
-private:
- void setAnimating(bool enabled);
-
- QMatrix4x4 m_window_normalised_matrix;
- QMatrix4x4 m_window_painter_matrix;
- QMatrix4x4 m_projection;
- QMatrix4x4 m_view;
- QMatrix4x4 m_model_triangle;
- QMatrix4x4 m_model_text;
-
- FragmentToy m_fragment_toy;
- QStaticText m_text_layout;
- bool m_animate;
-};
-
-// Use NoPartialUpdate. This means that all the rendering goes directly to
-// the window surface, no additional framebuffer object stands in the
-// middle. This is fine since we will clear the entire framebuffer on each
-// paint. Under the hood this means that the behavior is equivalent to the
-// manual makeCurrent - perform OpenGL calls - swapBuffers loop that is
-// typical in pure QWindow-based applications.
-OpenGLWindow::OpenGLWindow()
- : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate)
- , m_fragment_toy("./background.frag")
- , m_text_layout("The triangle and this text is rendered with QPainter")
- , m_animate(true)
-{
- setGeometry(300, 300, 500, 500);
-
- m_view.lookAt(QVector3D(3,1,1),
- QVector3D(0,0,0),
- QVector3D(0,1,0));
-
- setAnimating(m_animate);
-}
-
-void OpenGLWindow::paintGL()
-{
- m_fragment_toy.draw(size());
-
- QPainter p(this);
- p.setWorldTransform(m_window_normalised_matrix.toTransform());
-
- QMatrix4x4 mvp = m_projection * m_view * m_model_triangle;
- p.setTransform(mvp.toTransform(), true);
-
- p.fillPath(painterPathForTriangle(), QBrush(QGradient(QGradient::NightFade)));
-
- QTransform text_transform = (m_window_painter_matrix * m_view * m_model_text).toTransform();
- p.setTransform(text_transform, false);
- p.setPen(QPen(Qt::black));
- m_text_layout.prepare(text_transform);
- qreal x = - (m_text_layout.size().width() / 2);
- qreal y = 0;
- p.drawStaticText(x, y, m_text_layout);
-
- m_model_triangle.rotate(-1, 0, 1, 0);
- m_model_text.rotate(1, 0, 1, 0);
-}
-
-void OpenGLWindow::resizeGL(int w, int h)
-{
- m_window_normalised_matrix.setToIdentity();
- m_window_normalised_matrix.translate(w / 2.0, h / 2.0);
- m_window_normalised_matrix.scale(w / 2.0, -h / 2.0);
-
- m_window_painter_matrix.setToIdentity();
- m_window_painter_matrix.translate(w / 2.0, h / 2.0);
-
- m_text_layout.setTextWidth(std::max(w * 0.2, 80.0));
-
- m_projection.setToIdentity();
- m_projection.perspective(45.f, qreal(w) / qreal(h), 0.1f, 100.f);
-}
-
-void OpenGLWindow::keyPressEvent(QKeyEvent *e)
-{
- if (e->key() == Qt::Key_P) { // pause
- m_animate = !m_animate;
- setAnimating(m_animate);
- }
-}
-
-void OpenGLWindow::setAnimating(bool enabled)
-{
- if (enabled) {
- // Animate continuously, throttled by the blocking swapBuffers() call the
- // QOpenGLWindow internally executes after each paint. Once that is done
- // (frameSwapped signal is emitted), we schedule a new update. This
- // obviously assumes that the swap interval (see
- // QSurfaceFormat::setSwapInterval()) is non-zero.
- connect(this, &QOpenGLWindow::frameSwapped,
- this, QOverload<>::of(&QPaintDeviceWindow::update));
- update();
- } else {
- disconnect(this, &QOpenGLWindow::frameSwapped,
- this, QOverload<>::of(&QPaintDeviceWindow::update));
- }
-}
-
-int main(int argc, char **argv)
-{
- QGuiApplication app(argc, argv);
-
- OpenGLWindow window;
- QSurfaceFormat fmt;
- fmt.setDepthBufferSize(24);
- fmt.setStencilBufferSize(8);
- window.setFormat(fmt);
- window.show();
-
- return app.exec();
-}
-
-#include "main.moc"
diff --git a/examples/opengl/qopenglwindow/qopenglwindow.pro b/examples/opengl/qopenglwindow/qopenglwindow.pro
deleted file mode 100644
index e7073a324b..0000000000
--- a/examples/opengl/qopenglwindow/qopenglwindow.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-TEMPLATE = app
-TARGET = qopenglwindow
-INCLUDEPATH += .
-QT += opengl
-
-RESOURCES += shaders.qrc
-
-SOURCES += \
- main.cpp \
- background_renderer.cpp
-
-HEADERS += \
- background_renderer.h
-
-target.path = $$[QT_INSTALL_EXAMPLES]/opengl/qopenglwindow
-INSTALLS += target
diff --git a/examples/opengl/qopenglwindow/shaders.qrc b/examples/opengl/qopenglwindow/shaders.qrc
deleted file mode 100644
index 64eefe2c70..0000000000
--- a/examples/opengl/qopenglwindow/shaders.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>background.frag</file>
-</qresource>
-</RCC>
diff --git a/examples/opengl/stereoqopenglwidget/CMakeLists.txt b/examples/opengl/stereoqopenglwidget/CMakeLists.txt
new file mode 100644
index 0000000000..d0fb7a0345
--- /dev/null
+++ b/examples/opengl/stereoqopenglwidget/CMakeLists.txt
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(stereoqopenglwidget LANGUAGES CXX)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets)
+
+qt_add_executable(stereoqopenglwidget
+ glwidget.cpp glwidget.h
+ main.cpp
+ mainwindow.cpp mainwindow.h
+)
+
+set_target_properties(stereoqopenglwidget PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(stereoqopenglwidget PUBLIC
+ Qt6::Core
+ Qt6::Gui
+ Qt6::OpenGL
+ Qt6::OpenGLWidgets
+ Qt6::Widgets
+)
+
+
+install(TARGETS stereoqopenglwidget
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET stereoqopenglwidget
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
+)
+install(SCRIPT ${deploy_script})
diff --git a/examples/opengl/stereoqopenglwidget/glwidget.cpp b/examples/opengl/stereoqopenglwidget/glwidget.cpp
new file mode 100644
index 0000000000..36a6300348
--- /dev/null
+++ b/examples/opengl/stereoqopenglwidget/glwidget.cpp
@@ -0,0 +1,277 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "glwidget.h"
+#include <QPainter>
+#include <QPaintEngine>
+#include <QOpenGLShaderProgram>
+#include <QOpenGLTexture>
+#include <QRandomGenerator>
+#include <QCoreApplication>
+#include <QFileDialog>
+#include <qmath.h>
+
+GLWidget::GLWidget(const QColor &background)
+ : m_background(background)
+{
+ setMinimumSize(300, 250);
+}
+
+GLWidget::~GLWidget()
+{
+ reset();
+}
+
+void GLWidget::saveImage(TargetBuffer targetBuffer)
+{
+ QImage img = grabFramebuffer(targetBuffer);
+ if (img.isNull()) {
+ qFatal("Failed to grab framebuffer");
+ }
+
+ const char *fn =
+ targetBuffer == TargetBuffer::LeftBuffer
+ ? "leftBuffer.png" : "rightBuffer.png";
+
+ QFileDialog fd(this);
+ fd.setAcceptMode(QFileDialog::AcceptSave);
+ fd.setDefaultSuffix("png");
+ fd.selectFile(fn);
+ if (fd.exec() == QDialog::Accepted)
+ img.save(fd.selectedFiles().first());
+}
+
+void GLWidget::reset()
+{
+ // And now release all OpenGL resources.
+ makeCurrent();
+ delete m_program;
+ m_program = nullptr;
+ delete m_vshader;
+ m_vshader = nullptr;
+ delete m_fshader;
+ m_fshader = nullptr;
+ m_vbo.destroy();
+ doneCurrent();
+
+ // We are done with the current QOpenGLContext, forget it. If there is a
+ // subsequent initialize(), that will then connect to the new context.
+ QObject::disconnect(m_contextWatchConnection);
+}
+void GLWidget::initializeGL()
+{
+ initializeOpenGLFunctions();
+
+ m_vshader = new QOpenGLShader(QOpenGLShader::Vertex);
+ const char *vsrc1 =
+ "attribute highp vec4 vertex;\n"
+ "attribute mediump vec3 normal;\n"
+ "uniform mediump mat4 matrix;\n"
+ "varying mediump vec4 color;\n"
+ "void main(void)\n"
+ "{\n"
+ " vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));\n"
+ " float angle = max(dot(normal, toLight), 0.0);\n"
+ " vec3 col = vec3(0.40, 1.0, 0.0);\n"
+ " color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);\n"
+ " color = clamp(color, 0.0, 1.0);\n"
+ " gl_Position = matrix * vertex;\n"
+ "}\n";
+ m_vshader->compileSourceCode(vsrc1);
+
+ m_fshader = new QOpenGLShader(QOpenGLShader::Fragment);
+ const char *fsrc1 =
+ "varying mediump vec4 color;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_FragColor = color;\n"
+ "}\n";
+ m_fshader->compileSourceCode(fsrc1);
+
+ m_program = new QOpenGLShaderProgram;
+ m_program->addShader(m_vshader);
+ m_program->addShader(m_fshader);
+ m_program->link();
+
+
+ m_vertexAttr = m_program->attributeLocation("vertex");
+ m_normalAttr = m_program->attributeLocation("normal");
+ m_matrixUniform = m_program->uniformLocation("matrix");
+
+ createGeometry();
+
+ m_vbo.create();
+ m_vbo.bind();
+ const int vertexCount = m_vertices.count();
+ QList<GLfloat> buf;
+ buf.resize(vertexCount * 3 * 2);
+ GLfloat *p = buf.data();
+ for (int i = 0; i < vertexCount; ++i) {
+ *p++ = m_vertices[i].x();
+ *p++ = m_vertices[i].y();
+ *p++ = m_vertices[i].z();
+ *p++ = m_normals[i].x();
+ *p++ = m_normals[i].y();
+ *p++ = m_normals[i].z();
+ }
+ m_vbo.allocate(buf.constData(), (int)buf.count() * sizeof(GLfloat));
+ m_vbo.release();
+
+ m_contextWatchConnection = QObject::connect(context(), &QOpenGLContext::aboutToBeDestroyed, context(), [this] { reset(); });
+
+ glFrontFace(GL_CW);
+ glCullFace(GL_FRONT);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void GLWidget::paintGL()
+{
+ // When QSurfaceFormat::StereoBuffers is enabled, this function is called twice.
+ // Once where currentTargetBuffer() == QOpenGLWidget::LeftBuffer,
+ // and once where currentTargetBuffer() == QOpenGLWidget::RightBuffer.
+
+ glClearColor(m_background.redF(), m_background.greenF(), m_background.blueF(), 1.0f);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ //! [1]
+ // Slightly translate the model, so that there's a visible difference in each buffer.
+ QMatrix4x4 modelview;
+ if (currentTargetBuffer() == QOpenGLWidget::LeftBuffer)
+ modelview.translate(-0.4f, 0.0f, 0.0f);
+ else if (currentTargetBuffer() == QOpenGLWidget::RightBuffer)
+ modelview.translate(0.4f, 0.0f, 0.0f);
+ //! [1]
+
+ m_program->bind();
+ m_program->setUniformValue(m_matrixUniform, modelview);
+ m_program->enableAttributeArray(m_vertexAttr);
+ m_program->enableAttributeArray(m_normalAttr);
+
+ m_vbo.bind();
+ m_program->setAttributeBuffer(m_vertexAttr, GL_FLOAT, 0, 3, 6 * sizeof(GLfloat));
+ m_program->setAttributeBuffer(m_normalAttr, GL_FLOAT, 3 * sizeof(GLfloat), 3, 6 * sizeof(GLfloat));
+ m_vbo.release();
+
+ glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
+
+ m_program->disableAttributeArray(m_normalAttr);
+ m_program->disableAttributeArray(m_vertexAttr);
+ m_program->release();
+ update();
+}
+
+void GLWidget::createGeometry()
+{
+ m_vertices.clear();
+ m_normals.clear();
+
+ qreal x1 = +0.06f;
+ qreal y1 = -0.14f;
+ qreal x2 = +0.14f;
+ qreal y2 = -0.06f;
+ qreal x3 = +0.08f;
+ qreal y3 = +0.00f;
+ qreal x4 = +0.30f;
+ qreal y4 = +0.22f;
+
+ quad(x1, y1, x2, y2, y2, x2, y1, x1);
+ quad(x3, y3, x4, y4, y4, x4, y3, x3);
+
+ extrude(x1, y1, x2, y2);
+ extrude(x2, y2, y2, x2);
+ extrude(y2, x2, y1, x1);
+ extrude(y1, x1, x1, y1);
+ extrude(x3, y3, x4, y4);
+ extrude(x4, y4, y4, x4);
+ extrude(y4, x4, y3, x3);
+
+ const int NumSectors = 100;
+ const qreal sectorAngle = 2 * qreal(M_PI) / NumSectors;
+
+ for (int i = 0; i < NumSectors; ++i) {
+ qreal angle = i * sectorAngle;
+ qreal x5 = 0.30 * sin(angle);
+ qreal y5 = 0.30 * cos(angle);
+ qreal x6 = 0.20 * sin(angle);
+ qreal y6 = 0.20 * cos(angle);
+
+ angle += sectorAngle;
+ qreal x7 = 0.20 * sin(angle);
+ qreal y7 = 0.20 * cos(angle);
+ qreal x8 = 0.30 * sin(angle);
+ qreal y8 = 0.30 * cos(angle);
+
+ quad(x5, y5, x6, y6, x7, y7, x8, y8);
+
+ extrude(x6, y6, x7, y7);
+ extrude(x8, y8, x5, y5);
+ }
+
+ for (int i = 0;i < m_vertices.size();i++)
+ m_vertices[i] *= 2.0f;
+}
+
+void GLWidget::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
+{
+ m_vertices << QVector3D(x1, y1, -0.05f);
+ m_vertices << QVector3D(x2, y2, -0.05f);
+ m_vertices << QVector3D(x4, y4, -0.05f);
+
+ m_vertices << QVector3D(x3, y3, -0.05f);
+ m_vertices << QVector3D(x4, y4, -0.05f);
+ m_vertices << QVector3D(x2, y2, -0.05f);
+
+ QVector3D n = QVector3D::normal
+ (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f));
+
+ m_normals << n;
+ m_normals << n;
+ m_normals << n;
+
+ m_normals << n;
+ m_normals << n;
+ m_normals << n;
+
+ m_vertices << QVector3D(x4, y4, 0.05f);
+ m_vertices << QVector3D(x2, y2, 0.05f);
+ m_vertices << QVector3D(x1, y1, 0.05f);
+
+ m_vertices << QVector3D(x2, y2, 0.05f);
+ m_vertices << QVector3D(x4, y4, 0.05f);
+ m_vertices << QVector3D(x3, y3, 0.05f);
+
+ n = QVector3D::normal
+ (QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f));
+
+ m_normals << n;
+ m_normals << n;
+ m_normals << n;
+
+ m_normals << n;
+ m_normals << n;
+ m_normals << n;
+}
+
+void GLWidget::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
+{
+ m_vertices << QVector3D(x1, y1, +0.05f);
+ m_vertices << QVector3D(x2, y2, +0.05f);
+ m_vertices << QVector3D(x1, y1, -0.05f);
+
+ m_vertices << QVector3D(x2, y2, -0.05f);
+ m_vertices << QVector3D(x1, y1, -0.05f);
+ m_vertices << QVector3D(x2, y2, +0.05f);
+
+ QVector3D n = QVector3D::normal
+ (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f));
+
+ m_normals << n;
+ m_normals << n;
+ m_normals << n;
+
+ m_normals << n;
+ m_normals << n;
+ m_normals << n;
+}
diff --git a/examples/opengl/stereoqopenglwidget/glwidget.h b/examples/opengl/stereoqopenglwidget/glwidget.h
new file mode 100644
index 0000000000..0014ee37c1
--- /dev/null
+++ b/examples/opengl/stereoqopenglwidget/glwidget.h
@@ -0,0 +1,53 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef GLWIDGET_H
+#define GLWIDGET_H
+
+#include <QOpenGLWidget>
+#include <QOpenGLFunctions>
+#include <QOpenGLBuffer>
+#include <QVector3D>
+#include <QMatrix4x4>
+#include <QElapsedTimer>
+#include <QList>
+#include <QPushButton>
+
+
+QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
+QT_FORWARD_DECLARE_CLASS(QOpenGLShader)
+QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
+
+class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
+{
+ Q_OBJECT
+public:
+ GLWidget(const QColor &background);
+ ~GLWidget();
+
+ void saveImage(QOpenGLWidget::TargetBuffer targetBuffer);
+
+protected:
+ void paintGL() override;
+ void initializeGL() override;
+
+private:
+ void createGeometry();
+ void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4);
+ void extrude(qreal x1, qreal y1, qreal x2, qreal y2);
+ void reset();
+
+ QList<QVector3D> m_vertices;
+ QList<QVector3D> m_normals;
+ QOpenGLShader *m_vshader = nullptr;
+ QOpenGLShader *m_fshader = nullptr;
+ QOpenGLShaderProgram *m_program = nullptr;
+ QOpenGLBuffer m_vbo;
+ int m_vertexAttr;
+ int m_normalAttr;
+ int m_matrixUniform;
+ QColor m_background;
+ QMetaObject::Connection m_contextWatchConnection;
+};
+
+#endif
diff --git a/examples/opengl/stereoqopenglwidget/main.cpp b/examples/opengl/stereoqopenglwidget/main.cpp
new file mode 100644
index 0000000000..8aad756eca
--- /dev/null
+++ b/examples/opengl/stereoqopenglwidget/main.cpp
@@ -0,0 +1,31 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+#include <QSurfaceFormat>
+#include "mainwindow.h"
+
+int main( int argc, char ** argv )
+{
+ QApplication a( argc, argv );
+
+ QCoreApplication::setApplicationName("Qt QOpenGLWidget Stereoscopic Rendering Example");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+
+ //! [1]
+ QSurfaceFormat format;
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+
+ // Enable stereoscopic rendering support
+ format.setStereo(true);
+
+ QSurfaceFormat::setDefaultFormat(format);
+ //! [1]
+
+ MainWindow mw;
+ mw.resize(1280, 720);
+ mw.show();
+ return a.exec();
+}
diff --git a/examples/opengl/stereoqopenglwidget/mainwindow.cpp b/examples/opengl/stereoqopenglwidget/mainwindow.cpp
new file mode 100644
index 0000000000..33f93ba7de
--- /dev/null
+++ b/examples/opengl/stereoqopenglwidget/mainwindow.cpp
@@ -0,0 +1,25 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include <QApplication>
+#include <QMenuBar>
+#include "glwidget.h"
+
+MainWindow::MainWindow()
+{
+ GLWidget *glwidget = new GLWidget(qRgb(20, 20, 50));
+ setCentralWidget(glwidget);
+
+ QMenu *screenShotMenu = menuBar()->addMenu("&Screenshot");
+ screenShotMenu->addAction("Left buffer", this, [glwidget](){
+ glwidget->saveImage(QOpenGLWidget::LeftBuffer);
+ });
+
+ screenShotMenu->addAction("Right buffer", this, [glwidget](){
+ glwidget->saveImage(QOpenGLWidget::RightBuffer);
+ });
+
+ QMenu *helpMenu = menuBar()->addMenu("&Help");
+ helpMenu->addAction("About Qt", qApp, &QApplication::aboutQt);
+}
diff --git a/examples/opengl/threadedqopenglwidget/mainwindow.h b/examples/opengl/stereoqopenglwidget/mainwindow.h
index 2dd8639a63..aa6f722e59 100644
--- a/examples/opengl/threadedqopenglwidget/mainwindow.h
+++ b/examples/opengl/stereoqopenglwidget/mainwindow.h
@@ -4,9 +4,13 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
-#include <QWidget>
+#include <QMainWindow>
+#include <QTimer>
+#include <QGridLayout>
-class MainWindow : public QWidget
+QT_FORWARD_DECLARE_CLASS(QOpenGLWidget)
+
+class MainWindow : public QMainWindow
{
Q_OBJECT
diff --git a/examples/opengl/stereoqopenglwidget/stereoqopenglwidget.pro b/examples/opengl/stereoqopenglwidget/stereoqopenglwidget.pro
new file mode 100644
index 0000000000..197afff571
--- /dev/null
+++ b/examples/opengl/stereoqopenglwidget/stereoqopenglwidget.pro
@@ -0,0 +1,11 @@
+QT += widgets opengl openglwidgets
+
+SOURCES += main.cpp \
+ glwidget.cpp \
+ mainwindow.cpp
+
+HEADERS += glwidget.h \
+ mainwindow.h
+
+target.path = $$[QT_INSTALL_EXAMPLES]/opengl/stereoqopenglwidget
+INSTALLS += target
diff --git a/examples/opengl/textures/CMakeLists.txt b/examples/opengl/textures/CMakeLists.txt
index 1e7d1a402f..2765355c5a 100644
--- a/examples/opengl/textures/CMakeLists.txt
+++ b/examples/opengl/textures/CMakeLists.txt
@@ -1,16 +1,13 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
cmake_minimum_required(VERSION 3.16)
project(textures LANGUAGES CXX)
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/textures")
-
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets)
+qt_standard_project_setup()
+
qt_add_executable(textures
glwidget.cpp glwidget.h
main.cpp
@@ -22,12 +19,12 @@ set_target_properties(textures PROPERTIES
MACOSX_BUNDLE TRUE
)
-target_link_libraries(textures PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
- Qt::OpenGLWidgets
- Qt::Widgets
+target_link_libraries(textures PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::OpenGL
+ Qt6::OpenGLWidgets
+ Qt6::Widgets
)
# Resources:
@@ -48,7 +45,14 @@ qt6_add_resources(textures "textures"
)
install(TARGETS textures
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_app_script(
+ TARGET textures
+ OUTPUT_SCRIPT deploy_script
+ NO_UNSUPPORTED_PLATFORM_ERROR
)
+install(SCRIPT ${deploy_script})
diff --git a/examples/opengl/textures/glwidget.cpp b/examples/opengl/textures/glwidget.cpp
index 9c6828b902..cca08f4c91 100644
--- a/examples/opengl/textures/glwidget.cpp
+++ b/examples/opengl/textures/glwidget.cpp
@@ -46,9 +46,6 @@ void GLWidget::initializeGL()
makeObject();
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
-
#define PROGRAM_VERTEX_ATTRIBUTE 0
#define PROGRAM_TEXCOORD_ATTRIBUTE 1
@@ -91,6 +88,9 @@ void GLWidget::paintGL()
glClearColor(clearColor.redF(), clearColor.greenF(), clearColor.blueF(), clearColor.alphaF());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+
QMatrix4x4 m;
m.ortho(-0.5f, +0.5f, +0.5f, -0.5f, 4.0f, 15.0f);
m.translate(0.0f, 0.0f, -10.0f);
@@ -98,6 +98,8 @@ void GLWidget::paintGL()
m.rotate(yRot / 16.0f, 0.0f, 1.0f, 0.0f);
m.rotate(zRot / 16.0f, 0.0f, 0.0f, 1.0f);
+ vbo.bind();
+ program->bind();
program->setUniformValue("matrix", m);
program->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE);
program->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE);
diff --git a/examples/opengl/textures/main.cpp b/examples/opengl/textures/main.cpp
index c1e91e6257..7e5f0646cb 100644
--- a/examples/opengl/textures/main.cpp
+++ b/examples/opengl/textures/main.cpp
@@ -8,8 +8,6 @@
int main(int argc, char *argv[])
{
- Q_INIT_RESOURCE(textures);
-
QApplication app(argc, argv);
QSurfaceFormat format;
diff --git a/examples/opengl/threadedqopenglwidget/CMakeLists.txt b/examples/opengl/threadedqopenglwidget/CMakeLists.txt
deleted file mode 100644
index 187813afa1..0000000000
--- a/examples/opengl/threadedqopenglwidget/CMakeLists.txt
+++ /dev/null
@@ -1,38 +0,0 @@
-cmake_minimum_required(VERSION 3.16)
-project(threadedqopenglwidget LANGUAGES CXX)
-
-set(CMAKE_AUTOMOC ON)
-
-if(NOT DEFINED INSTALL_EXAMPLESDIR)
- set(INSTALL_EXAMPLESDIR "examples")
-endif()
-
-set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/threadedqopenglwidget")
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL OpenGLWidgets Widgets)
-
-qt_add_executable(threadedqopenglwidget
- renderer.cpp renderer.h
- glwidget.cpp glwidget.h
- main.cpp
- mainwindow.cpp mainwindow.h
-)
-
-set_target_properties(threadedqopenglwidget PROPERTIES
- WIN32_EXECUTABLE TRUE
- MACOSX_BUNDLE TRUE
-)
-
-target_link_libraries(threadedqopenglwidget PUBLIC
- Qt::Core
- Qt::Gui
- Qt::OpenGL
- Qt::OpenGLWidgets
- Qt::Widgets
-)
-
-install(TARGETS threadedqopenglwidget
- RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
- BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
- LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
-)
diff --git a/examples/opengl/threadedqopenglwidget/glwidget.cpp b/examples/opengl/threadedqopenglwidget/glwidget.cpp
deleted file mode 100644
index 6fbc61dd44..0000000000
--- a/examples/opengl/threadedqopenglwidget/glwidget.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "glwidget.h"
-#include "renderer.h"
-
-#include <qmath.h>
-#include <QGuiApplication>
-
-GLWidget::GLWidget(QWidget *parent)
- : QOpenGLWidget(parent)
-{
- setMinimumSize(300, 250);
-
- connect(this, &QOpenGLWidget::aboutToCompose, this, &GLWidget::onAboutToCompose);
- connect(this, &QOpenGLWidget::frameSwapped, this, &GLWidget::onFrameSwapped);
- connect(this, &QOpenGLWidget::aboutToResize, this, &GLWidget::onAboutToResize);
- connect(this, &QOpenGLWidget::resized, this, &GLWidget::onResized);
-
- m_thread = new QThread;
- m_renderer = new Renderer(this);
- m_renderer->moveToThread(m_thread);
- connect(m_thread, &QThread::finished, m_renderer, &QObject::deleteLater);
-
- connect(this, &GLWidget::renderRequested, m_renderer, &Renderer::render);
- connect(m_renderer, &Renderer::contextWanted, this, &GLWidget::grabContext);
-
- m_thread->start();
-}
-
-GLWidget::~GLWidget()
-{
- m_renderer->prepareExit();
- m_thread->quit();
- m_thread->wait();
- delete m_thread;
-}
-
-void GLWidget::onAboutToCompose()
-{
- // We are on the gui thread here. Composition is about to
- // begin. Wait until the render thread finishes.
- m_renderer->lockRenderer();
-}
-
-void GLWidget::onFrameSwapped()
-{
- m_renderer->unlockRenderer();
- // Assuming a blocking swap, our animation is driven purely by the
- // vsync in this example.
- emit renderRequested();
-}
-
-void GLWidget::onAboutToResize()
-{
- m_renderer->lockRenderer();
-}
-
-void GLWidget::onResized()
-{
- m_renderer->unlockRenderer();
-}
-
-void GLWidget::grabContext()
-{
- m_renderer->lockRenderer();
- QMutexLocker lock(m_renderer->grabMutex());
- context()->moveToThread(m_thread);
- m_renderer->grabCond()->wakeAll();
- m_renderer->unlockRenderer();
-}
diff --git a/examples/opengl/threadedqopenglwidget/glwidget.h b/examples/opengl/threadedqopenglwidget/glwidget.h
deleted file mode 100644
index 12f234bc5c..0000000000
--- a/examples/opengl/threadedqopenglwidget/glwidget.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef GLWIDGET_H
-#define GLWIDGET_H
-
-#include <QOpenGLWidget>
-
-QT_FORWARD_DECLARE_CLASS(QThread)
-
-class Renderer;
-
-class GLWidget : public QOpenGLWidget
-{
- Q_OBJECT
-public:
- explicit GLWidget(QWidget *parent = nullptr);
- ~GLWidget();
-
-protected:
- void paintEvent(QPaintEvent *) override { }
-
-signals:
- void renderRequested();
-
-public slots:
- void grabContext();
-
-private slots:
- void onAboutToCompose();
- void onFrameSwapped();
- void onAboutToResize();
- void onResized();
-
-private:
- QThread *m_thread;
- Renderer *m_renderer;
-};
-
-#endif // GLWIDGET_H
diff --git a/examples/opengl/threadedqopenglwidget/main.cpp b/examples/opengl/threadedqopenglwidget/main.cpp
deleted file mode 100644
index efb84877f8..0000000000
--- a/examples/opengl/threadedqopenglwidget/main.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include <QApplication>
-#include <QMainWindow>
-#include <QScreen>
-#include <QShortcut>
-#include <QSurfaceFormat>
-#include <QOpenGLContext>
-#include <QOpenGLFunctions>
-#include <QCommandLineParser>
-#include <QCommandLineOption>
-#include "mainwindow.h"
-#include "glwidget.h"
-
-#include <memory>
-
-static QString getGlString(QOpenGLFunctions *functions, GLenum name)
-{
- if (const GLubyte *p = functions->glGetString(name))
- return QString::fromLatin1(reinterpret_cast<const char *>(p));
- return QString();
-}
-
-int main( int argc, char ** argv )
-{
- QApplication a( argc, argv );
-
- QCoreApplication::setApplicationName("Qt Threaded QOpenGLWidget Example");
- QCoreApplication::setOrganizationName("QtProject");
- QCoreApplication::setApplicationVersion(QT_VERSION_STR);
- QCommandLineParser parser;
- parser.setApplicationDescription(QCoreApplication::applicationName());
- parser.addHelpOption();
- parser.addVersionOption();
- QCommandLineOption singleOption("single", "Single thread");
- parser.addOption(singleOption);
- parser.process(a);
-
- QSurfaceFormat format;
- format.setDepthBufferSize(16);
- QSurfaceFormat::setDefaultFormat(format);
-
- // Two top-level windows with two QOpenGLWidget children in each.
- // The rendering for the four QOpenGLWidgets happens on four separate threads.
-
- GLWidget topLevelGlWidget;
- QPoint pos = topLevelGlWidget.screen()->availableGeometry().topLeft() + QPoint(200, 200);
- topLevelGlWidget.setWindowTitle(QStringLiteral("Threaded QOpenGLWidget example top level"));
- topLevelGlWidget.resize(200, 200);
- topLevelGlWidget.move(pos);
- topLevelGlWidget.show();
- auto *closeShortcut = new QShortcut(Qt::CTRL | Qt::Key_Q, &a, QApplication::closeAllWindows);
- closeShortcut->setContext(Qt::ApplicationShortcut);
-
- const QString glInfo = getGlString(topLevelGlWidget.context()->functions(), GL_VENDOR)
- + QLatin1Char('/') + getGlString(topLevelGlWidget.context()->functions(), GL_RENDERER);
-
- const bool supportsThreading = !glInfo.contains(QLatin1String("nouveau"), Qt::CaseInsensitive)
- && !glInfo.contains(QLatin1String("ANGLE"), Qt::CaseInsensitive)
- && !glInfo.contains(QLatin1String("llvmpipe"), Qt::CaseInsensitive);
-
- const QString toolTip = supportsThreading ? glInfo : glInfo + QStringLiteral("\ndoes not support threaded OpenGL.");
- topLevelGlWidget.setToolTip(toolTip);
-
- std::unique_ptr<MainWindow> mw1;
- std::unique_ptr<MainWindow> mw2;
- if (!parser.isSet(singleOption)) {
- if (supportsThreading) {
- pos += QPoint(100, 100);
- mw1.reset(new MainWindow);
- mw1->setToolTip(toolTip);
- mw1->move(pos);
- mw1->setWindowTitle(QStringLiteral("Threaded QOpenGLWidget example #1"));
- mw1->show();
- pos += QPoint(100, 100);
- mw2.reset(new MainWindow);
- mw2->setToolTip(toolTip);
- mw2->move(pos);
- mw2->setWindowTitle(QStringLiteral("Threaded QOpenGLWidget example #2"));
- mw2->show();
- } else {
- qWarning() << toolTip;
- }
- }
-
- return a.exec();
-}
diff --git a/examples/opengl/threadedqopenglwidget/mainwindow.cpp b/examples/opengl/threadedqopenglwidget/mainwindow.cpp
deleted file mode 100644
index fd08c5713d..0000000000
--- a/examples/opengl/threadedqopenglwidget/mainwindow.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "mainwindow.h"
-#include "glwidget.h"
-
-MainWindow::MainWindow()
-{
- setMinimumSize(800, 400);
- GLWidget *glwidget1 = new GLWidget(this);
- glwidget1->resize(400, 400);
-
- GLWidget *glwidget2 = new GLWidget(this);
- glwidget2->resize(400, 400);
- glwidget2->move(400, 0);
-}
diff --git a/examples/opengl/threadedqopenglwidget/renderer.cpp b/examples/opengl/threadedqopenglwidget/renderer.cpp
deleted file mode 100644
index 2de19fb7a1..0000000000
--- a/examples/opengl/threadedqopenglwidget/renderer.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#include "renderer.h"
-#include <qmath.h>
-#include <QOpenGLWidget>
-#include <QGuiApplication>
-
-static const char VERTEX_SHADER[] = R"(attribute highp vec4 vertex;
-attribute mediump vec3 normal;
-uniform mediump mat4 matrix;
-varying mediump vec4 color;
-void main(void)
-{
- vec3 toLight = normalize(vec3(0.0, 0.3, 1.0));
- float angle = max(dot(normal, toLight), 0.0);
- vec3 col = vec3(0.40, 1.0, 0.0);
- color = vec4(col * 0.2 + col * 0.8 * angle, 1.0);
- color = clamp(color, 0.0, 1.0);
- gl_Position = matrix * vertex;
-}
-)";
-
-static const char FRAGMENT_SHADER[] = R"(varying mediump vec4 color;
-void main(void)
-{
- gl_FragColor = color;
-}
-)";
-
-Renderer::Renderer(QOpenGLWidget *w) :
- m_glwidget(w)
-{
-}
-
-void Renderer::paintQtLogo()
-{
- vbo.bind();
- program.setAttributeBuffer(vertexAttr, GL_FLOAT, 0, 3);
- program.setAttributeBuffer(normalAttr, GL_FLOAT, vertices.count() * 3 * sizeof(GLfloat), 3);
- vbo.release();
-
- program.enableAttributeArray(vertexAttr);
- program.enableAttributeArray(normalAttr);
-
- glDrawArrays(GL_TRIANGLES, 0, vertices.size());
-
- program.disableAttributeArray(normalAttr);
- program.disableAttributeArray(vertexAttr);
-}
-
-// Some OpenGL implementations have serious issues with compiling and linking
-// shaders on multiple threads concurrently. Avoid this.
-Q_GLOBAL_STATIC(QMutex, initMutex)
-
-void Renderer::render()
-{
- if (m_exiting)
- return;
-
- QOpenGLContext *ctx = m_glwidget->context();
- if (!ctx) // QOpenGLWidget not yet initialized
- return;
-
- // Grab the context.
- m_grabMutex.lock();
- emit contextWanted();
- m_grabCond.wait(&m_grabMutex);
- QMutexLocker lock(&m_renderMutex);
- m_grabMutex.unlock();
-
- if (m_exiting)
- return;
-
- Q_ASSERT(ctx->thread() == QThread::currentThread());
-
- // Make the context (and an offscreen surface) current for this thread. The
- // QOpenGLWidget's fbo is bound in the context.
- m_glwidget->makeCurrent();
-
- if (!m_inited) {
- m_inited = true;
- initializeOpenGLFunctions();
-
- QMutexLocker initLock(initMutex());
- QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
- vshader->compileSourceCode(VERTEX_SHADER);
-
- QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
- fshader->compileSourceCode(FRAGMENT_SHADER);
-
- program.addShader(vshader);
- program.addShader(fshader);
- program.link();
-
- vertexAttr = program.attributeLocation("vertex");
- normalAttr = program.attributeLocation("normal");
- matrixUniform = program.uniformLocation("matrix");
-
- m_fAngle = 0;
- m_fScale = 1;
- createGeometry();
-
- vbo.create();
- vbo.bind();
- const int verticesSize = vertices.count() * 3 * sizeof(GLfloat);
- vbo.allocate(verticesSize * 2);
- vbo.write(0, vertices.constData(), verticesSize);
- vbo.write(verticesSize, normals.constData(), verticesSize);
-
- m_elapsed.start();
- }
-
- //qDebug("%p elapsed %lld", QThread::currentThread(), m_elapsed.restart());
-
- glClearColor(0.1f, 0.2f, 0.2f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glFrontFace(GL_CW);
- glCullFace(GL_FRONT);
- glEnable(GL_CULL_FACE);
- glEnable(GL_DEPTH_TEST);
-
- QMatrix4x4 modelview;
- modelview.rotate(m_fAngle, 0.0f, 1.0f, 0.0f);
- modelview.rotate(m_fAngle, 1.0f, 0.0f, 0.0f);
- modelview.rotate(m_fAngle, 0.0f, 0.0f, 1.0f);
- modelview.scale(m_fScale);
- modelview.translate(0.0f, -0.2f, 0.0f);
-
- program.bind();
- program.setUniformValue(matrixUniform, modelview);
- paintQtLogo();
- program.release();
-
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
-
- m_fAngle += 1.0f;
-
- // Make no context current on this thread and move the QOpenGLWidget's
- // context back to the gui thread.
- m_glwidget->doneCurrent();
- ctx->moveToThread(qGuiApp->thread());
-
- // Schedule composition. Note that this will use QueuedConnection, meaning
- // that update() will be invoked on the gui thread.
- QMetaObject::invokeMethod(m_glwidget, "update");
-}
-
-void Renderer::createGeometry()
-{
- vertices.clear();
- normals.clear();
-
- qreal x1 = +0.06f;
- qreal y1 = -0.14f;
- qreal x2 = +0.14f;
- qreal y2 = -0.06f;
- qreal x3 = +0.08f;
- qreal y3 = +0.00f;
- qreal x4 = +0.30f;
- qreal y4 = +0.22f;
-
- quad(x1, y1, x2, y2, y2, x2, y1, x1);
- quad(x3, y3, x4, y4, y4, x4, y3, x3);
-
- extrude(x1, y1, x2, y2);
- extrude(x2, y2, y2, x2);
- extrude(y2, x2, y1, x1);
- extrude(y1, x1, x1, y1);
- extrude(x3, y3, x4, y4);
- extrude(x4, y4, y4, x4);
- extrude(y4, x4, y3, x3);
-
- const int NumSectors = 100;
- const qreal sectorAngle = 2 * qreal(M_PI) / NumSectors;
-
- for (int i = 0; i < NumSectors; ++i) {
- qreal angle = i * sectorAngle;
- qreal sinAngle = sin(angle);
- qreal cosAngle = cos(angle);
- qreal x5 = 0.30 * sinAngle;
- qreal y5 = 0.30 * cosAngle;
- qreal x6 = 0.20 * sinAngle;
- qreal y6 = 0.20 * cosAngle;
-
- angle += sectorAngle;
- sinAngle = sin(angle);
- cosAngle = cos(angle);
- qreal x7 = 0.20 * sinAngle;
- qreal y7 = 0.20 * cosAngle;
- qreal x8 = 0.30 * sinAngle;
- qreal y8 = 0.30 * cosAngle;
-
- quad(x5, y5, x6, y6, x7, y7, x8, y8);
-
- extrude(x6, y6, x7, y7);
- extrude(x8, y8, x5, y5);
- }
-
- for (qsizetype i = 0; i < vertices.size(); ++i)
- vertices[i] *= 2.0f;
-}
-
-void Renderer::quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4)
-{
- vertices << QVector3D(x1, y1, -0.05f);
- vertices << QVector3D(x2, y2, -0.05f);
- vertices << QVector3D(x4, y4, -0.05f);
-
- vertices << QVector3D(x3, y3, -0.05f);
- vertices << QVector3D(x4, y4, -0.05f);
- vertices << QVector3D(x2, y2, -0.05f);
-
- QVector3D n = QVector3D::normal
- (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(x4 - x1, y4 - y1, 0.0f));
-
- normals << n;
- normals << n;
- normals << n;
-
- normals << n;
- normals << n;
- normals << n;
-
- vertices << QVector3D(x4, y4, 0.05f);
- vertices << QVector3D(x2, y2, 0.05f);
- vertices << QVector3D(x1, y1, 0.05f);
-
- vertices << QVector3D(x2, y2, 0.05f);
- vertices << QVector3D(x4, y4, 0.05f);
- vertices << QVector3D(x3, y3, 0.05f);
-
- n = QVector3D::normal
- (QVector3D(x2 - x4, y2 - y4, 0.0f), QVector3D(x1 - x4, y1 - y4, 0.0f));
-
- normals << n;
- normals << n;
- normals << n;
-
- normals << n;
- normals << n;
- normals << n;
-}
-
-void Renderer::extrude(qreal x1, qreal y1, qreal x2, qreal y2)
-{
- vertices << QVector3D(x1, y1, +0.05f);
- vertices << QVector3D(x2, y2, +0.05f);
- vertices << QVector3D(x1, y1, -0.05f);
-
- vertices << QVector3D(x2, y2, -0.05f);
- vertices << QVector3D(x1, y1, -0.05f);
- vertices << QVector3D(x2, y2, +0.05f);
-
- QVector3D n = QVector3D::normal
- (QVector3D(x2 - x1, y2 - y1, 0.0f), QVector3D(0.0f, 0.0f, -0.1f));
-
- normals << n;
- normals << n;
- normals << n;
-
- normals << n;
- normals << n;
- normals << n;
-}
diff --git a/examples/opengl/threadedqopenglwidget/renderer.h b/examples/opengl/threadedqopenglwidget/renderer.h
deleted file mode 100644
index e39f4810f8..0000000000
--- a/examples/opengl/threadedqopenglwidget/renderer.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
-
-#ifndef RENDERER_H
-#define RENDERER_H
-
-#include <QOpenGLFunctions>
-#include <QOpenGLBuffer>
-#include <QOpenGLShaderProgram>
-#include <QVector3D>
-#include <QMatrix4x4>
-#include <QThread>
-#include <QMutex>
-#include <QWaitCondition>
-#include <QElapsedTimer>
-
-QT_FORWARD_DECLARE_CLASS(QOpenGLWidget)
-
-class Renderer : public QObject, protected QOpenGLFunctions
-{
- Q_OBJECT
-
-public:
- explicit Renderer(QOpenGLWidget *w);
- void lockRenderer() { m_renderMutex.lock(); }
- void unlockRenderer() { m_renderMutex.unlock(); }
- QMutex *grabMutex() { return &m_grabMutex; }
- QWaitCondition *grabCond() { return &m_grabCond; }
- void prepareExit() { m_exiting = true; m_grabCond.wakeAll(); }
-
-signals:
- void contextWanted();
-
-public slots:
- void render();
-
-private:
- void paintQtLogo();
- void createGeometry();
- void quad(qreal x1, qreal y1, qreal x2, qreal y2, qreal x3, qreal y3, qreal x4, qreal y4);
- void extrude(qreal x1, qreal y1, qreal x2, qreal y2);
-
- bool m_inited = false;
- qreal m_fAngle = 0;
- qreal m_fScale = 1;
- QList<QVector3D> vertices;
- QList<QVector3D> normals;
- QOpenGLShaderProgram program;
- QOpenGLBuffer vbo;
- int vertexAttr = 0;
- int normalAttr = 0;
- int matrixUniform = 0;
- QOpenGLWidget *m_glwidget = nullptr;
- QMutex m_renderMutex;
- QElapsedTimer m_elapsed;
- QMutex m_grabMutex;
- QWaitCondition m_grabCond;
- bool m_exiting = false;
-};
-
-#endif // RENDERER_H
diff --git a/examples/opengl/threadedqopenglwidget/threadedqopenglwidget.pro b/examples/opengl/threadedqopenglwidget/threadedqopenglwidget.pro
deleted file mode 100644
index 46332ab7cb..0000000000
--- a/examples/opengl/threadedqopenglwidget/threadedqopenglwidget.pro
+++ /dev/null
@@ -1,13 +0,0 @@
-QT += widgets opengl openglwidgets
-
-SOURCES += main.cpp \
- glwidget.cpp \
- mainwindow.cpp \
- renderer.cpp
-
-HEADERS += glwidget.h \
- mainwindow.h \
- renderer.h
-
-target.path = $$[QT_INSTALL_EXAMPLES]/opengl/threadedqopenglwidget
-INSTALLS += target