Skip to content

Commit c66018b

Browse files
committed
Add OpenGL example
1 parent bbde511 commit c66018b

21 files changed

Lines changed: 1717 additions & 1 deletion

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,5 +385,5 @@ MigrationBackup/
385385
FodyWeavers.xsd
386386
/ build
387387
/Settings.ini
388-
.vscode/settings.json
388+
.vscode/
389389
/.settings

examples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ add_subdirectory(autohidedragndrop)
1010
add_subdirectory(emptydockarea)
1111
add_subdirectory(dockindock)
1212
add_subdirectory(configflags)
13+
add_subdirectory(openGL)

examples/examples.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ SUBDIRS = \
55
autohidedragndrop \
66
centralwidget \
77
simple \
8+
openGL \
89
hideshow \
910
sidebar \
1011
deleteonclose \

examples/openGL/CMakeLists.txt

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
3+
project(OpenGLExample VERSION ${VERSION_SHORT})
4+
5+
set(CMAKE_AUTOUIC ON)
6+
set(CMAKE_AUTOMOC ON)
7+
set(CMAKE_AUTORCC ON)
8+
9+
find_package(
10+
QT NAMES Qt6
11+
COMPONENTS Core
12+
Gui
13+
Widgets
14+
Charts
15+
OpenGLWidgets
16+
Quick
17+
QuickWidgets
18+
ShaderTools
19+
REQUIRED)
20+
21+
find_package(
22+
Qt${QT_VERSION_MAJOR}
23+
COMPONENTS Core
24+
Gui
25+
Widgets
26+
Charts
27+
OpenGLWidgets
28+
Quick
29+
QuickWidgets
30+
ShaderTools
31+
REQUIRED)
32+
33+
set(CMAKE_INCLUDE_CURRENT_DIR ON)
34+
35+
qt_add_executable(
36+
${PROJECT_NAME}
37+
WIN32
38+
main.cpp
39+
mainwindow.cpp
40+
mainwindow.h
41+
glwindow.cpp
42+
glwindow.h
43+
glwidget.h
44+
glwidget.cpp
45+
fbitem.cpp
46+
fbitem.h
47+
logo.cpp
48+
logo.h)
49+
50+
target_include_directories(${PROJECT_NAME}
51+
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
52+
target_link_libraries(${PROJECT_NAME}
53+
PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
54+
55+
qt_add_qml_module(
56+
${PROJECT_NAME}
57+
URI
58+
fbitem
59+
QML_FILES
60+
"test.qml"
61+
RESOURCE_PREFIX
62+
/openGL
63+
NO_RESOURCE_TARGET_PATH)
64+
65+
qt6_add_shaders(
66+
${PROJECT_NAME}
67+
"shaders"
68+
PRECOMPILE
69+
OPTIMIZED
70+
PREFIX
71+
"/openGL"
72+
FILES
73+
"wobble.frag")
74+
75+
# Resources:
76+
set(resource_files "qtlogo.png")
77+
78+
qt_add_resources(${PROJECT_NAME} "OpenGLExample" PREFIX "/" FILES
79+
${resource_files})
80+
81+
target_link_libraries(
82+
${PROJECT_NAME}
83+
PUBLIC Qt${QT_VERSION_MAJOR}::Core
84+
Qt${QT_VERSION_MAJOR}::Gui
85+
Qt${QT_VERSION_MAJOR}::Widgets
86+
Qt${QT_VERSION_MAJOR}::Charts
87+
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
88+
Qt${QT_VERSION_MAJOR}::Quick
89+
Qt${QT_VERSION_MAJOR}::QuickWidgets)
90+
91+
set_target_properties(
92+
${PROJECT_NAME}
93+
PROPERTIES AUTOMOC ON
94+
AUTORCC ON
95+
AUTOUIC ON
96+
CXX_STANDARD 14
97+
CXX_STANDARD_REQUIRED ON
98+
CXX_EXTENSIONS OFF
99+
VERSION ${VERSION_SHORT}
100+
EXPORT_NAME "Qt Advanced Docking System OpenGL Example"
101+
ARCHIVE_OUTPUT_DIRECTORY
102+
"${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
103+
LIBRARY_OUTPUT_DIRECTORY
104+
"${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
105+
RUNTIME_OUTPUT_DIRECTORY
106+
"${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin")
107+
108+
# Define include directories
109+
target_include_directories(
110+
${PROJECT_NAME}
111+
PRIVATE $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
112+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/examples/openGL>
113+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${INSTALL_NAME}>)
114+
115+
install(
116+
TARGETS ${PROJECT_NAME}
117+
BUNDLE DESTINATION .
118+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
119+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
120+
121+
qt_generate_deploy_app_script(TARGET ${PROJECT_NAME} OUTPUT_SCRIPT
122+
deploy_script NO_UNSUPPORTED_PLATFORM_ERROR)
123+
124+
install(SCRIPT ${deploy_script})
125+
126+
qt_generate_deploy_qml_app_script(
127+
TARGET
128+
${PROJECT_NAME}
129+
OUTPUT_SCRIPT
130+
qml_deploy_script
131+
MACOS_BUNDLE_POST_BUILD
132+
NO_UNSUPPORTED_PLATFORM_ERROR
133+
DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM)
134+
135+
install(SCRIPT ${qml_deploy_script})

examples/openGL/fbitem.cpp

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
// Copyright (C) 2017 The Qt Company Ltd.
2+
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3+
4+
#include "fbitem.h"
5+
#include <QOpenGLFramebufferObject>
6+
#include <QOpenGLFunctions>
7+
#include <QMatrix4x4>
8+
9+
FbItem::FbItem(QQuickItem *parent)
10+
: QQuickFramebufferObject(parent),
11+
m_target(0, 0, -1),
12+
m_syncState(AllNeedsSync),
13+
m_multisample(false)
14+
{
15+
}
16+
17+
QQuickFramebufferObject::Renderer *FbItem::createRenderer() const
18+
{
19+
return new FbItemRenderer(m_multisample);
20+
}
21+
22+
void FbItem::setEye(const QVector3D &v)
23+
{
24+
if (m_eye != v) {
25+
m_eye = v;
26+
m_syncState |= CameraNeedsSync;
27+
update();
28+
}
29+
}
30+
31+
void FbItem::setTarget(const QVector3D &v)
32+
{
33+
if (m_target != v) {
34+
m_target = v;
35+
m_syncState |= CameraNeedsSync;
36+
update();
37+
}
38+
}
39+
40+
void FbItem::setRotation(const QVector3D &v)
41+
{
42+
if (m_rotation != v) {
43+
m_rotation = v;
44+
m_syncState |= RotationNeedsSync;
45+
update();
46+
}
47+
}
48+
49+
int FbItem::swapSyncState()
50+
{
51+
int s = m_syncState;
52+
m_syncState = 0;
53+
return s;
54+
}
55+
56+
FbItemRenderer::FbItemRenderer(bool multisample)
57+
: m_inited(false),
58+
m_multisample(multisample),
59+
m_dirty(DirtyAll)
60+
{
61+
m_camera.setToIdentity();
62+
m_baseWorld.setToIdentity();
63+
m_baseWorld.translate(0, 0, -1);
64+
m_world = m_baseWorld;
65+
}
66+
67+
void FbItemRenderer::synchronize(QQuickFramebufferObject *qfbitem)
68+
{
69+
FbItem *item = static_cast<FbItem *>(qfbitem);
70+
int syncState = item->swapSyncState();
71+
if (syncState & FbItem::CameraNeedsSync) {
72+
m_camera.setToIdentity();
73+
m_camera.lookAt(item->eye(), item->eye() + item->target(), QVector3D(0, 1, 0));
74+
m_dirty |= DirtyCamera;
75+
}
76+
if (syncState & FbItem::RotationNeedsSync) {
77+
m_rotation = item->rotation();
78+
m_dirty |= DirtyWorld;
79+
}
80+
}
81+
82+
struct StateBinder
83+
{
84+
StateBinder(FbItemRenderer *r)
85+
: m_r(r) {
86+
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
87+
f->glEnable(GL_DEPTH_TEST);
88+
f->glEnable(GL_CULL_FACE);
89+
f->glDepthMask(GL_TRUE);
90+
f->glDepthFunc(GL_LESS);
91+
f->glFrontFace(GL_CCW);
92+
f->glCullFace(GL_BACK);
93+
m_r->m_program->bind();
94+
}
95+
~StateBinder() {
96+
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
97+
m_r->m_program->release();
98+
f->glDisable(GL_CULL_FACE);
99+
f->glDisable(GL_DEPTH_TEST);
100+
}
101+
FbItemRenderer *m_r;
102+
};
103+
104+
void FbItemRenderer::updateDirtyUniforms()
105+
{
106+
if (m_dirty & DirtyProjection)
107+
m_program->setUniformValue(m_projMatrixLoc, m_proj);
108+
109+
if (m_dirty & DirtyCamera)
110+
m_program->setUniformValue(m_camMatrixLoc, m_camera);
111+
112+
if (m_dirty & DirtyWorld) {
113+
m_program->setUniformValue(m_worldMatrixLoc, m_world);
114+
QMatrix3x3 normalMatrix = m_world.normalMatrix();
115+
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
116+
}
117+
118+
if (m_dirty & DirtyLight)
119+
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
120+
121+
m_dirty = 0;
122+
}
123+
124+
void FbItemRenderer::render()
125+
{
126+
ensureInit();
127+
128+
if (m_vao.isCreated())
129+
m_vao.bind();
130+
else
131+
setupVertexAttribs();
132+
133+
StateBinder state(this);
134+
135+
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
136+
f->glClearColor(0, 0, 0, 0);
137+
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
138+
139+
if (m_dirty & DirtyWorld) {
140+
m_world = m_baseWorld;
141+
m_world.rotate(m_rotation.x(), 1, 0, 0);
142+
m_world.rotate(m_rotation.y(), 0, 1, 0);
143+
m_world.rotate(m_rotation.z(), 0, 0, 1);
144+
}
145+
146+
updateDirtyUniforms();
147+
148+
f->glDrawArrays(GL_TRIANGLES, 0, m_logo.vertexCount());
149+
150+
if (m_vao.isCreated())
151+
m_vao.release();
152+
}
153+
154+
QOpenGLFramebufferObject *FbItemRenderer::createFramebufferObject(const QSize &size)
155+
{
156+
m_dirty |= DirtyProjection;
157+
m_proj.setToIdentity();
158+
m_proj.perspective(45.0f, GLfloat(size.width()) / size.height(), 0.01f, 100.0f);
159+
160+
QOpenGLFramebufferObjectFormat format;
161+
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
162+
format.setSamples(m_multisample ? 4 : 0);
163+
return new QOpenGLFramebufferObject(size, format);
164+
}
165+
166+
void FbItemRenderer::ensureInit()
167+
{
168+
if (m_inited)
169+
return;
170+
171+
m_inited = true;
172+
173+
initBuf();
174+
initProgram();
175+
}
176+
177+
void FbItemRenderer::initBuf()
178+
{
179+
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
180+
181+
m_logoVbo.create();
182+
m_logoVbo.bind();
183+
m_logoVbo.allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));
184+
185+
setupVertexAttribs();
186+
}
187+
188+
void FbItemRenderer::setupVertexAttribs()
189+
{
190+
m_logoVbo.bind();
191+
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
192+
f->glEnableVertexAttribArray(0);
193+
f->glEnableVertexAttribArray(1);
194+
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);
195+
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
196+
m_logoVbo.release();
197+
}
198+
199+
static const char *vertexShaderSource =
200+
"attribute vec4 vertex;\n"
201+
"attribute vec3 normal;\n"
202+
"varying vec3 vert;\n"
203+
"varying vec3 vertNormal;\n"
204+
"uniform mat4 projMatrix;\n"
205+
"uniform mat4 camMatrix;\n"
206+
"uniform mat4 worldMatrix;\n"
207+
"uniform mat3 normalMatrix;\n"
208+
"void main() {\n"
209+
" vert = vertex.xyz;\n"
210+
" vertNormal = normalMatrix * normal;\n"
211+
" gl_Position = projMatrix * camMatrix * worldMatrix * vertex;\n"
212+
"}\n";
213+
214+
static const char *fragmentShaderSource =
215+
"varying highp vec3 vert;\n"
216+
"varying highp vec3 vertNormal;\n"
217+
"uniform highp vec3 lightPos;\n"
218+
"void main() {\n"
219+
" highp vec3 L = normalize(lightPos - vert);\n"
220+
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
221+
" highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
222+
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
223+
" gl_FragColor = vec4(col, 1.0);\n"
224+
"}\n";
225+
226+
void FbItemRenderer::initProgram()
227+
{
228+
m_program.reset(new QOpenGLShaderProgram);
229+
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
230+
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
231+
m_program->bindAttributeLocation("vertex", 0);
232+
m_program->bindAttributeLocation("normal", 1);
233+
m_program->link();
234+
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
235+
m_camMatrixLoc = m_program->uniformLocation("camMatrix");
236+
m_worldMatrixLoc = m_program->uniformLocation("worldMatrix");
237+
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
238+
m_lightPosLoc = m_program->uniformLocation("lightPos");
239+
}

0 commit comments

Comments
 (0)