mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2025-03-31 10:22:39 +08:00
Merge d57448bad7
into df1fa27127
This commit is contained in:
commit
5c328e044c
2
.gitignore
vendored
2
.gitignore
vendored
@ -385,5 +385,5 @@ MigrationBackup/
|
||||
FodyWeavers.xsd
|
||||
/ build
|
||||
/Settings.ini
|
||||
.vscode/settings.json
|
||||
.vscode/
|
||||
/.settings
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <QString>
|
||||
#include <QFile>
|
||||
#include <QApplication>
|
||||
#include <QQuickWindow>
|
||||
#include <QDebug>
|
||||
|
||||
#include <memory>
|
||||
@ -35,6 +36,14 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// https://doc.qt.io/qt-6/qtdatavisualization-known-issues.html
|
||||
// Use either `qputenv("QSG_RHI_BACKEND", "opengl");` or the following line
|
||||
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
|
||||
|
||||
// Disable warnings when attempts are made to convert non-convertible non-native widgets
|
||||
// to native widgets (such as QQuickWidget)
|
||||
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#if QT_VERSION >= 0x050600
|
||||
|
@ -9,3 +9,4 @@ add_subdirectory(autohide)
|
||||
add_subdirectory(autohidedragndrop)
|
||||
add_subdirectory(emptydockarea)
|
||||
add_subdirectory(dockindock)
|
||||
add_subdirectory(openGL)
|
||||
|
@ -5,6 +5,7 @@ SUBDIRS = \
|
||||
autohidedragndrop \
|
||||
centralwidget \
|
||||
simple \
|
||||
openGL \
|
||||
hideshow \
|
||||
sidebar \
|
||||
deleteonclose \
|
||||
|
135
examples/openGL/CMakeLists.txt
Normal file
135
examples/openGL/CMakeLists.txt
Normal file
@ -0,0 +1,135 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(OpenGLExample VERSION ${VERSION_SHORT})
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
find_package(
|
||||
QT NAMES Qt6
|
||||
COMPONENTS Core
|
||||
Gui
|
||||
Widgets
|
||||
Charts
|
||||
OpenGLWidgets
|
||||
Quick
|
||||
QuickWidgets
|
||||
ShaderTools
|
||||
REQUIRED)
|
||||
|
||||
find_package(
|
||||
Qt${QT_VERSION_MAJOR}
|
||||
COMPONENTS Core
|
||||
Gui
|
||||
Widgets
|
||||
Charts
|
||||
OpenGLWidgets
|
||||
Quick
|
||||
QuickWidgets
|
||||
ShaderTools
|
||||
REQUIRED)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
qt_add_executable(
|
||||
${PROJECT_NAME}
|
||||
WIN32
|
||||
main.cpp
|
||||
mainwindow.cpp
|
||||
mainwindow.h
|
||||
glwindow.cpp
|
||||
glwindow.h
|
||||
glwidget.h
|
||||
glwidget.cpp
|
||||
fbitem.cpp
|
||||
fbitem.h
|
||||
logo.cpp
|
||||
logo.h)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../src")
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
|
||||
|
||||
qt_add_qml_module(
|
||||
${PROJECT_NAME}
|
||||
URI
|
||||
fbitem
|
||||
QML_FILES
|
||||
"test.qml"
|
||||
RESOURCE_PREFIX
|
||||
/openGL
|
||||
NO_RESOURCE_TARGET_PATH)
|
||||
|
||||
qt6_add_shaders(
|
||||
${PROJECT_NAME}
|
||||
"shaders"
|
||||
PRECOMPILE
|
||||
OPTIMIZED
|
||||
PREFIX
|
||||
"/openGL"
|
||||
FILES
|
||||
"wobble.frag")
|
||||
|
||||
# Resources:
|
||||
set(resource_files "qtlogo.png")
|
||||
|
||||
qt_add_resources(${PROJECT_NAME} "OpenGLExample" PREFIX "/" FILES
|
||||
${resource_files})
|
||||
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
PUBLIC Qt${QT_VERSION_MAJOR}::Core
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
Qt${QT_VERSION_MAJOR}::Widgets
|
||||
Qt${QT_VERSION_MAJOR}::Charts
|
||||
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
|
||||
Qt${QT_VERSION_MAJOR}::Quick
|
||||
Qt${QT_VERSION_MAJOR}::QuickWidgets)
|
||||
|
||||
set_target_properties(
|
||||
${PROJECT_NAME}
|
||||
PROPERTIES AUTOMOC ON
|
||||
AUTORCC ON
|
||||
AUTOUIC ON
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS OFF
|
||||
VERSION ${VERSION_SHORT}
|
||||
EXPORT_NAME "Qt Advanced Docking System OpenGL Example"
|
||||
ARCHIVE_OUTPUT_DIRECTORY
|
||||
"${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
|
||||
LIBRARY_OUTPUT_DIRECTORY
|
||||
"${CMAKE_BINARY_DIR}/${ads_PlatformDir}/lib"
|
||||
RUNTIME_OUTPUT_DIRECTORY
|
||||
"${CMAKE_BINARY_DIR}/${ads_PlatformDir}/bin")
|
||||
|
||||
# Define include directories
|
||||
target_include_directories(
|
||||
${PROJECT_NAME}
|
||||
PRIVATE $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/examples/openGL>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${INSTALL_NAME}>)
|
||||
|
||||
install(
|
||||
TARGETS ${PROJECT_NAME}
|
||||
BUNDLE DESTINATION .
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
qt_generate_deploy_app_script(TARGET ${PROJECT_NAME} OUTPUT_SCRIPT
|
||||
deploy_script NO_UNSUPPORTED_PLATFORM_ERROR)
|
||||
|
||||
install(SCRIPT ${deploy_script})
|
||||
|
||||
qt_generate_deploy_qml_app_script(
|
||||
TARGET
|
||||
${PROJECT_NAME}
|
||||
OUTPUT_SCRIPT
|
||||
qml_deploy_script
|
||||
MACOS_BUNDLE_POST_BUILD
|
||||
NO_UNSUPPORTED_PLATFORM_ERROR
|
||||
DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM)
|
||||
|
||||
install(SCRIPT ${qml_deploy_script})
|
239
examples/openGL/fbitem.cpp
Normal file
239
examples/openGL/fbitem.cpp
Normal file
@ -0,0 +1,239 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "fbitem.h"
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QMatrix4x4>
|
||||
|
||||
FbItem::FbItem(QQuickItem *parent)
|
||||
: QQuickFramebufferObject(parent),
|
||||
m_target(0, 0, -1),
|
||||
m_syncState(AllNeedsSync),
|
||||
m_multisample(false)
|
||||
{
|
||||
}
|
||||
|
||||
QQuickFramebufferObject::Renderer *FbItem::createRenderer() const
|
||||
{
|
||||
return new FbItemRenderer(m_multisample);
|
||||
}
|
||||
|
||||
void FbItem::setEye(const QVector3D &v)
|
||||
{
|
||||
if (m_eye != v) {
|
||||
m_eye = v;
|
||||
m_syncState |= CameraNeedsSync;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void FbItem::setTarget(const QVector3D &v)
|
||||
{
|
||||
if (m_target != v) {
|
||||
m_target = v;
|
||||
m_syncState |= CameraNeedsSync;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void FbItem::setRotation(const QVector3D &v)
|
||||
{
|
||||
if (m_rotation != v) {
|
||||
m_rotation = v;
|
||||
m_syncState |= RotationNeedsSync;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int FbItem::swapSyncState()
|
||||
{
|
||||
int s = m_syncState;
|
||||
m_syncState = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
FbItemRenderer::FbItemRenderer(bool multisample)
|
||||
: m_inited(false),
|
||||
m_multisample(multisample),
|
||||
m_dirty(DirtyAll)
|
||||
{
|
||||
m_camera.setToIdentity();
|
||||
m_baseWorld.setToIdentity();
|
||||
m_baseWorld.translate(0, 0, -1);
|
||||
m_world = m_baseWorld;
|
||||
}
|
||||
|
||||
void FbItemRenderer::synchronize(QQuickFramebufferObject *qfbitem)
|
||||
{
|
||||
FbItem *item = static_cast<FbItem *>(qfbitem);
|
||||
int syncState = item->swapSyncState();
|
||||
if (syncState & FbItem::CameraNeedsSync) {
|
||||
m_camera.setToIdentity();
|
||||
m_camera.lookAt(item->eye(), item->eye() + item->target(), QVector3D(0, 1, 0));
|
||||
m_dirty |= DirtyCamera;
|
||||
}
|
||||
if (syncState & FbItem::RotationNeedsSync) {
|
||||
m_rotation = item->rotation();
|
||||
m_dirty |= DirtyWorld;
|
||||
}
|
||||
}
|
||||
|
||||
struct StateBinder
|
||||
{
|
||||
StateBinder(FbItemRenderer *r)
|
||||
: m_r(r) {
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
f->glEnable(GL_DEPTH_TEST);
|
||||
f->glEnable(GL_CULL_FACE);
|
||||
f->glDepthMask(GL_TRUE);
|
||||
f->glDepthFunc(GL_LESS);
|
||||
f->glFrontFace(GL_CCW);
|
||||
f->glCullFace(GL_BACK);
|
||||
m_r->m_program->bind();
|
||||
}
|
||||
~StateBinder() {
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
m_r->m_program->release();
|
||||
f->glDisable(GL_CULL_FACE);
|
||||
f->glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
FbItemRenderer *m_r;
|
||||
};
|
||||
|
||||
void FbItemRenderer::updateDirtyUniforms()
|
||||
{
|
||||
if (m_dirty & DirtyProjection)
|
||||
m_program->setUniformValue(m_projMatrixLoc, m_proj);
|
||||
|
||||
if (m_dirty & DirtyCamera)
|
||||
m_program->setUniformValue(m_camMatrixLoc, m_camera);
|
||||
|
||||
if (m_dirty & DirtyWorld) {
|
||||
m_program->setUniformValue(m_worldMatrixLoc, m_world);
|
||||
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
||||
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
|
||||
}
|
||||
|
||||
if (m_dirty & DirtyLight)
|
||||
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
|
||||
|
||||
m_dirty = 0;
|
||||
}
|
||||
|
||||
void FbItemRenderer::render()
|
||||
{
|
||||
ensureInit();
|
||||
|
||||
if (m_vao.isCreated())
|
||||
m_vao.bind();
|
||||
else
|
||||
setupVertexAttribs();
|
||||
|
||||
StateBinder state(this);
|
||||
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
f->glClearColor(0, 0, 0, 0);
|
||||
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (m_dirty & DirtyWorld) {
|
||||
m_world = m_baseWorld;
|
||||
m_world.rotate(m_rotation.x(), 1, 0, 0);
|
||||
m_world.rotate(m_rotation.y(), 0, 1, 0);
|
||||
m_world.rotate(m_rotation.z(), 0, 0, 1);
|
||||
}
|
||||
|
||||
updateDirtyUniforms();
|
||||
|
||||
f->glDrawArrays(GL_TRIANGLES, 0, m_logo.vertexCount());
|
||||
|
||||
if (m_vao.isCreated())
|
||||
m_vao.release();
|
||||
}
|
||||
|
||||
QOpenGLFramebufferObject *FbItemRenderer::createFramebufferObject(const QSize &size)
|
||||
{
|
||||
m_dirty |= DirtyProjection;
|
||||
m_proj.setToIdentity();
|
||||
m_proj.perspective(45.0f, GLfloat(size.width()) / size.height(), 0.01f, 100.0f);
|
||||
|
||||
QOpenGLFramebufferObjectFormat format;
|
||||
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
|
||||
format.setSamples(m_multisample ? 4 : 0);
|
||||
return new QOpenGLFramebufferObject(size, format);
|
||||
}
|
||||
|
||||
void FbItemRenderer::ensureInit()
|
||||
{
|
||||
if (m_inited)
|
||||
return;
|
||||
|
||||
m_inited = true;
|
||||
|
||||
initBuf();
|
||||
initProgram();
|
||||
}
|
||||
|
||||
void FbItemRenderer::initBuf()
|
||||
{
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
|
||||
|
||||
m_logoVbo.create();
|
||||
m_logoVbo.bind();
|
||||
m_logoVbo.allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));
|
||||
|
||||
setupVertexAttribs();
|
||||
}
|
||||
|
||||
void FbItemRenderer::setupVertexAttribs()
|
||||
{
|
||||
m_logoVbo.bind();
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
f->glEnableVertexAttribArray(0);
|
||||
f->glEnableVertexAttribArray(1);
|
||||
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);
|
||||
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
|
||||
m_logoVbo.release();
|
||||
}
|
||||
|
||||
static const char *vertexShaderSource =
|
||||
"attribute vec4 vertex;\n"
|
||||
"attribute vec3 normal;\n"
|
||||
"varying vec3 vert;\n"
|
||||
"varying vec3 vertNormal;\n"
|
||||
"uniform mat4 projMatrix;\n"
|
||||
"uniform mat4 camMatrix;\n"
|
||||
"uniform mat4 worldMatrix;\n"
|
||||
"uniform mat3 normalMatrix;\n"
|
||||
"void main() {\n"
|
||||
" vert = vertex.xyz;\n"
|
||||
" vertNormal = normalMatrix * normal;\n"
|
||||
" gl_Position = projMatrix * camMatrix * worldMatrix * vertex;\n"
|
||||
"}\n";
|
||||
|
||||
static const char *fragmentShaderSource =
|
||||
"varying highp vec3 vert;\n"
|
||||
"varying highp vec3 vertNormal;\n"
|
||||
"uniform highp vec3 lightPos;\n"
|
||||
"void main() {\n"
|
||||
" highp vec3 L = normalize(lightPos - vert);\n"
|
||||
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
|
||||
" highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
|
||||
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
|
||||
" gl_FragColor = vec4(col, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
void FbItemRenderer::initProgram()
|
||||
{
|
||||
m_program.reset(new QOpenGLShaderProgram);
|
||||
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
|
||||
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
|
||||
m_program->bindAttributeLocation("vertex", 0);
|
||||
m_program->bindAttributeLocation("normal", 1);
|
||||
m_program->link();
|
||||
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
|
||||
m_camMatrixLoc = m_program->uniformLocation("camMatrix");
|
||||
m_worldMatrixLoc = m_program->uniformLocation("worldMatrix");
|
||||
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
|
||||
m_lightPosLoc = m_program->uniformLocation("lightPos");
|
||||
}
|
100
examples/openGL/fbitem.h
Normal file
100
examples/openGL/fbitem.h
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef FBITEM_H
|
||||
#define FBITEM_H
|
||||
|
||||
#include <QQuickFramebufferObject>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QVector3D>
|
||||
#include "logo.h"
|
||||
|
||||
struct StateBinder;
|
||||
|
||||
class FbItemRenderer : public QQuickFramebufferObject::Renderer
|
||||
{
|
||||
public:
|
||||
FbItemRenderer(bool multisample);
|
||||
void synchronize(QQuickFramebufferObject *item) override;
|
||||
void render() override;
|
||||
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override;
|
||||
|
||||
private:
|
||||
void ensureInit();
|
||||
void initBuf();
|
||||
void setupVertexAttribs();
|
||||
void initProgram();
|
||||
void updateDirtyUniforms();
|
||||
|
||||
bool m_inited;
|
||||
bool m_multisample;
|
||||
QMatrix4x4 m_proj;
|
||||
QMatrix4x4 m_camera;
|
||||
QMatrix4x4 m_baseWorld;
|
||||
QMatrix4x4 m_world;
|
||||
QOpenGLVertexArrayObject m_vao;
|
||||
QOpenGLBuffer m_logoVbo;
|
||||
Logo m_logo;
|
||||
QScopedPointer<QOpenGLShaderProgram> m_program;
|
||||
int m_projMatrixLoc;
|
||||
int m_camMatrixLoc;
|
||||
int m_worldMatrixLoc;
|
||||
int m_normalMatrixLoc;
|
||||
int m_lightPosLoc;
|
||||
QVector3D m_rotation;
|
||||
|
||||
enum Dirty {
|
||||
DirtyProjection = 0x01,
|
||||
DirtyCamera = 0x02,
|
||||
DirtyWorld = 0x04,
|
||||
DirtyLight = 0x08,
|
||||
DirtyAll = 0xFF
|
||||
};
|
||||
int m_dirty;
|
||||
|
||||
friend struct StateBinder;
|
||||
};
|
||||
|
||||
class FbItem : public QQuickFramebufferObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QVector3D eye READ eye WRITE setEye)
|
||||
Q_PROPERTY(QVector3D target READ target WRITE setTarget)
|
||||
Q_PROPERTY(QVector3D rotation READ rotation WRITE setRotation)
|
||||
Q_PROPERTY(bool multisample READ multisample WRITE setMultisample)
|
||||
QML_ELEMENT
|
||||
|
||||
public:
|
||||
explicit FbItem(QQuickItem *parent = nullptr);
|
||||
|
||||
QQuickFramebufferObject::Renderer *createRenderer() const override;
|
||||
|
||||
QVector3D eye() const { return m_eye; }
|
||||
void setEye(const QVector3D &v);
|
||||
QVector3D target() const { return m_target; }
|
||||
void setTarget(const QVector3D &v);
|
||||
|
||||
QVector3D rotation() const { return m_rotation; }
|
||||
void setRotation(const QVector3D &v);
|
||||
|
||||
enum SyncState {
|
||||
CameraNeedsSync = 0x01,
|
||||
RotationNeedsSync = 0x02,
|
||||
AllNeedsSync = 0xFF
|
||||
};
|
||||
int swapSyncState();
|
||||
|
||||
bool multisample() const { return m_multisample; }
|
||||
void setMultisample(bool m) { m_multisample = m; }
|
||||
|
||||
private:
|
||||
QVector3D m_eye;
|
||||
QVector3D m_target;
|
||||
QVector3D m_rotation;
|
||||
int m_syncState;
|
||||
bool m_multisample;
|
||||
};
|
||||
|
||||
#endif // FBITEM_H
|
261
examples/openGL/glwidget.cpp
Normal file
261
examples/openGL/glwidget.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "glwidget.h"
|
||||
#include <QMouseEvent>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QCoreApplication>
|
||||
#include <math.h>
|
||||
|
||||
bool GLWidget::m_transparent = false;
|
||||
|
||||
GLWidget::GLWidget(QWidget *parent)
|
||||
: QOpenGLWidget(parent)
|
||||
{
|
||||
m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile;
|
||||
// --transparent causes the clear color to be transparent. Therefore, on systems that
|
||||
// support it, the widget will become transparent apart from the logo.
|
||||
if (m_transparent) {
|
||||
QSurfaceFormat fmt = format();
|
||||
fmt.setAlphaBufferSize(8);
|
||||
setFormat(fmt);
|
||||
}
|
||||
|
||||
// Force the display of OpenGL
|
||||
setAttribute(Qt::WA_AlwaysStackOnTop);
|
||||
}
|
||||
|
||||
GLWidget::~GLWidget()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
QSize GLWidget::minimumSizeHint() const
|
||||
{
|
||||
return QSize(50, 50);
|
||||
}
|
||||
|
||||
QSize GLWidget::sizeHint() const
|
||||
{
|
||||
return QSize(400, 400);
|
||||
}
|
||||
|
||||
static void qNormalizeAngle(int &angle)
|
||||
{
|
||||
while (angle < 0)
|
||||
angle += 360 * 16;
|
||||
while (angle > 360 * 16)
|
||||
angle -= 360 * 16;
|
||||
}
|
||||
|
||||
void GLWidget::setXRotation(int angle)
|
||||
{
|
||||
qNormalizeAngle(angle);
|
||||
if (angle != m_xRot) {
|
||||
m_xRot = angle;
|
||||
emit xRotationChanged(angle);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void GLWidget::setYRotation(int angle)
|
||||
{
|
||||
qNormalizeAngle(angle);
|
||||
if (angle != m_yRot) {
|
||||
m_yRot = angle;
|
||||
emit yRotationChanged(angle);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void GLWidget::setZRotation(int angle)
|
||||
{
|
||||
qNormalizeAngle(angle);
|
||||
if (angle != m_zRot) {
|
||||
m_zRot = angle;
|
||||
emit zRotationChanged(angle);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void GLWidget::cleanup()
|
||||
{
|
||||
if (m_program == nullptr){
|
||||
return;
|
||||
}
|
||||
makeCurrent();
|
||||
m_logoVbo.destroy();
|
||||
delete m_program;
|
||||
m_program = nullptr;
|
||||
doneCurrent();
|
||||
QObject::disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup);
|
||||
}
|
||||
|
||||
static const char *vertexShaderSourceCore =
|
||||
"#version 150\n"
|
||||
"in vec4 vertex;\n"
|
||||
"in vec3 normal;\n"
|
||||
"out vec3 vert;\n"
|
||||
"out vec3 vertNormal;\n"
|
||||
"uniform mat4 projMatrix;\n"
|
||||
"uniform mat4 mvMatrix;\n"
|
||||
"uniform mat3 normalMatrix;\n"
|
||||
"void main() {\n"
|
||||
" vert = vertex.xyz;\n"
|
||||
" vertNormal = normalMatrix * normal;\n"
|
||||
" gl_Position = projMatrix * mvMatrix * vertex;\n"
|
||||
"}\n";
|
||||
|
||||
static const char *fragmentShaderSourceCore =
|
||||
"#version 150\n"
|
||||
"in highp vec3 vert;\n"
|
||||
"in highp vec3 vertNormal;\n"
|
||||
"out highp vec4 fragColor;\n"
|
||||
"uniform highp vec3 lightPos;\n"
|
||||
"void main() {\n"
|
||||
" highp vec3 L = normalize(lightPos - vert);\n"
|
||||
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
|
||||
" highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
|
||||
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
|
||||
" fragColor = vec4(col, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char *vertexShaderSource =
|
||||
"attribute vec4 vertex;\n"
|
||||
"attribute vec3 normal;\n"
|
||||
"varying vec3 vert;\n"
|
||||
"varying vec3 vertNormal;\n"
|
||||
"uniform mat4 projMatrix;\n"
|
||||
"uniform mat4 mvMatrix;\n"
|
||||
"uniform mat3 normalMatrix;\n"
|
||||
"void main() {\n"
|
||||
" vert = vertex.xyz;\n"
|
||||
" vertNormal = normalMatrix * normal;\n"
|
||||
" gl_Position = projMatrix * mvMatrix * vertex;\n"
|
||||
"}\n";
|
||||
|
||||
static const char *fragmentShaderSource =
|
||||
"varying highp vec3 vert;\n"
|
||||
"varying highp vec3 vertNormal;\n"
|
||||
"uniform highp vec3 lightPos;\n"
|
||||
"void main() {\n"
|
||||
" highp vec3 L = normalize(lightPos - vert);\n"
|
||||
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
|
||||
" highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
|
||||
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
|
||||
" gl_FragColor = vec4(col, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
void GLWidget::initializeGL()
|
||||
{
|
||||
// In this example the widget's corresponding top-level window can change
|
||||
// several times during the widget's lifetime. Whenever this happens, the
|
||||
// QOpenGLWidget's associated context is destroyed and a new one is created.
|
||||
// Therefore we have to be prepared to clean up the resources on the
|
||||
// aboutToBeDestroyed() signal, instead of the destructor. The emission of
|
||||
// the signal will be followed by an invocation of initializeGL() where we
|
||||
// can recreate all resources.
|
||||
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup, Qt::UniqueConnection);
|
||||
|
||||
initializeOpenGLFunctions();
|
||||
glClearColor(0, 0, 0, m_transparent ? 0 : 1);
|
||||
|
||||
m_program = new QOpenGLShaderProgram;
|
||||
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
|
||||
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource);
|
||||
m_program->bindAttributeLocation("vertex", 0);
|
||||
m_program->bindAttributeLocation("normal", 1);
|
||||
m_program->link();
|
||||
|
||||
m_program->bind();
|
||||
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
|
||||
m_mvMatrixLoc = m_program->uniformLocation("mvMatrix");
|
||||
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
|
||||
m_lightPosLoc = m_program->uniformLocation("lightPos");
|
||||
|
||||
// Create a vertex array object. In OpenGL ES 2.0 and OpenGL 2.x
|
||||
// implementations this is optional and support may not be present
|
||||
// at all. Nonetheless the below code works in all cases and makes
|
||||
// sure there is a VAO when one is needed.
|
||||
m_vao.create();
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
|
||||
|
||||
// Setup our vertex buffer object.
|
||||
m_logoVbo.create();
|
||||
m_logoVbo.bind();
|
||||
m_logoVbo.allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));
|
||||
|
||||
// Store the vertex attribute bindings for the program.
|
||||
setupVertexAttribs();
|
||||
|
||||
// Our camera never changes in this example.
|
||||
m_camera.setToIdentity();
|
||||
m_camera.translate(0, 0, -1);
|
||||
|
||||
// Light position is fixed.
|
||||
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
|
||||
|
||||
m_program->release();
|
||||
}
|
||||
|
||||
void GLWidget::setupVertexAttribs()
|
||||
{
|
||||
m_logoVbo.bind();
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
f->glEnableVertexAttribArray(0);
|
||||
f->glEnableVertexAttribArray(1);
|
||||
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
|
||||
nullptr);
|
||||
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
|
||||
reinterpret_cast<void *>(3 * sizeof(GLfloat)));
|
||||
m_logoVbo.release();
|
||||
}
|
||||
|
||||
void GLWidget::paintGL()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
m_world.setToIdentity();
|
||||
m_world.rotate(180.0f - (m_xRot / 16.0f), 1, 0, 0);
|
||||
m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
|
||||
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
|
||||
|
||||
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
|
||||
m_program->bind();
|
||||
m_program->setUniformValue(m_projMatrixLoc, m_proj);
|
||||
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
|
||||
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
||||
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
|
||||
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_logo.vertexCount());
|
||||
|
||||
m_program->release();
|
||||
}
|
||||
|
||||
void GLWidget::resizeGL(int w, int h)
|
||||
{
|
||||
m_proj.setToIdentity();
|
||||
m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f);
|
||||
}
|
||||
|
||||
void GLWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
m_lastPos = event->position().toPoint();
|
||||
}
|
||||
|
||||
void GLWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
int dx = event->position().toPoint().x() - m_lastPos.x();
|
||||
int dy = event->position().toPoint().y() - m_lastPos.y();
|
||||
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
setXRotation(m_xRot + 8 * dy);
|
||||
setYRotation(m_yRot + 8 * dx);
|
||||
} else if (event->buttons() & Qt::RightButton) {
|
||||
setXRotation(m_xRot + 8 * dy);
|
||||
setZRotation(m_zRot + 8 * dx);
|
||||
}
|
||||
m_lastPos = event->position().toPoint();
|
||||
}
|
67
examples/openGL/glwidget.h
Normal file
67
examples/openGL/glwidget.h
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QOpenGLWidget>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QMatrix4x4>
|
||||
#include "logo.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
|
||||
|
||||
class GLWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GLWidget(QWidget *parent = nullptr);
|
||||
~GLWidget();
|
||||
|
||||
static bool isTransparent() { return m_transparent; }
|
||||
static void setTransparent(bool t) { m_transparent = t; }
|
||||
|
||||
QSize minimumSizeHint() const override;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
public slots:
|
||||
void setXRotation(int angle);
|
||||
void setYRotation(int angle);
|
||||
void setZRotation(int angle);
|
||||
void cleanup();
|
||||
|
||||
signals:
|
||||
void xRotationChanged(int angle);
|
||||
void yRotationChanged(int angle);
|
||||
void zRotationChanged(int angle);
|
||||
|
||||
protected:
|
||||
void initializeGL() override;
|
||||
void paintGL() override;
|
||||
void resizeGL(int width, int height) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
void setupVertexAttribs();
|
||||
|
||||
bool m_core;
|
||||
int m_xRot = 0;
|
||||
int m_yRot = 0;
|
||||
int m_zRot = 0;
|
||||
QPoint m_lastPos;
|
||||
Logo m_logo;
|
||||
QOpenGLVertexArrayObject m_vao;
|
||||
QOpenGLBuffer m_logoVbo;
|
||||
QOpenGLShaderProgram *m_program = nullptr;
|
||||
int m_projMatrixLoc = 0;
|
||||
int m_mvMatrixLoc = 0;
|
||||
int m_normalMatrixLoc = 0;
|
||||
int m_lightPosLoc = 0;
|
||||
QMatrix4x4 m_proj;
|
||||
QMatrix4x4 m_camera;
|
||||
QMatrix4x4 m_world;
|
||||
static bool m_transparent;
|
||||
};
|
238
examples/openGL/glwindow.cpp
Normal file
238
examples/openGL/glwindow.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "glwindow.h"
|
||||
#include <QImage>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLExtraFunctions>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QSequentialAnimationGroup>
|
||||
#include <QTimer>
|
||||
|
||||
GLWindow::GLWindow()
|
||||
{
|
||||
m_world.setToIdentity();
|
||||
m_world.translate(0, 0, -1);
|
||||
m_world.rotate(180, 1, 0, 0);
|
||||
|
||||
QSequentialAnimationGroup *animGroup = new QSequentialAnimationGroup(this);
|
||||
animGroup->setLoopCount(-1);
|
||||
QPropertyAnimation *zAnim0 = new QPropertyAnimation(this, QByteArrayLiteral("z"));
|
||||
zAnim0->setStartValue(1.5f);
|
||||
zAnim0->setEndValue(10.0f);
|
||||
zAnim0->setDuration(2000);
|
||||
animGroup->addAnimation(zAnim0);
|
||||
QPropertyAnimation *zAnim1 = new QPropertyAnimation(this, QByteArrayLiteral("z"));
|
||||
zAnim1->setStartValue(10.0f);
|
||||
zAnim1->setEndValue(50.0f);
|
||||
zAnim1->setDuration(4000);
|
||||
zAnim1->setEasingCurve(QEasingCurve::OutElastic);
|
||||
animGroup->addAnimation(zAnim1);
|
||||
QPropertyAnimation *zAnim2 = new QPropertyAnimation(this, QByteArrayLiteral("z"));
|
||||
zAnim2->setStartValue(50.0f);
|
||||
zAnim2->setEndValue(1.5f);
|
||||
zAnim2->setDuration(2000);
|
||||
animGroup->addAnimation(zAnim2);
|
||||
animGroup->start();
|
||||
|
||||
QPropertyAnimation* rAnim = new QPropertyAnimation(this, QByteArrayLiteral("r"));
|
||||
rAnim->setStartValue(0.0f);
|
||||
rAnim->setEndValue(360.0f);
|
||||
rAnim->setDuration(2000);
|
||||
rAnim->setLoopCount(-1);
|
||||
rAnim->start();
|
||||
|
||||
QTimer::singleShot(4000, this, &GLWindow::startSecondStage);
|
||||
}
|
||||
|
||||
GLWindow::~GLWindow()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void GLWindow::startSecondStage()
|
||||
{
|
||||
QPropertyAnimation* r2Anim = new QPropertyAnimation(this, QByteArrayLiteral("r2"));
|
||||
r2Anim->setStartValue(0.0f);
|
||||
r2Anim->setEndValue(360.0f);
|
||||
r2Anim->setDuration(20000);
|
||||
r2Anim->setLoopCount(-1);
|
||||
r2Anim->start();
|
||||
}
|
||||
|
||||
void GLWindow::setZ(float v)
|
||||
{
|
||||
m_eye.setZ(v);
|
||||
m_uniformsDirty = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void GLWindow::setR(float v)
|
||||
{
|
||||
m_r = v;
|
||||
m_uniformsDirty = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void GLWindow::setR2(float v)
|
||||
{
|
||||
m_r2 = v;
|
||||
m_uniformsDirty = true;
|
||||
update();
|
||||
}
|
||||
|
||||
static const char *vertexShaderSource =
|
||||
"layout(location = 0) in vec4 vertex;\n"
|
||||
"layout(location = 1) in vec3 normal;\n"
|
||||
"out vec3 vert;\n"
|
||||
"out vec3 vertNormal;\n"
|
||||
"out vec3 color;\n"
|
||||
"uniform mat4 projMatrix;\n"
|
||||
"uniform mat4 camMatrix;\n"
|
||||
"uniform mat4 worldMatrix;\n"
|
||||
"uniform mat4 myMatrix;\n"
|
||||
"uniform sampler2D sampler;\n"
|
||||
"void main() {\n"
|
||||
" ivec2 pos = ivec2(gl_InstanceID % 32, gl_InstanceID / 32);\n"
|
||||
" vec2 t = vec2(float(-16 + pos.x) * 0.8, float(-18 + pos.y) * 0.6);\n"
|
||||
" float val = 2.0 * length(texelFetch(sampler, pos, 0).rgb);\n"
|
||||
" mat4 wm = myMatrix * mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, t.x, t.y, val, 1) * worldMatrix;\n"
|
||||
" color = texelFetch(sampler, pos, 0).rgb * vec3(0.4, 1.0, 0.0);\n"
|
||||
" vert = vec3(wm * vertex);\n"
|
||||
" vertNormal = mat3(transpose(inverse(wm))) * normal;\n"
|
||||
" gl_Position = projMatrix * camMatrix * wm * vertex;\n"
|
||||
"}\n";
|
||||
|
||||
static const char *fragmentShaderSource =
|
||||
"in highp vec3 vert;\n"
|
||||
"in highp vec3 vertNormal;\n"
|
||||
"in highp vec3 color;\n"
|
||||
"out highp vec4 fragColor;\n"
|
||||
"uniform highp vec3 lightPos;\n"
|
||||
"void main() {\n"
|
||||
" highp vec3 L = normalize(lightPos - vert);\n"
|
||||
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
|
||||
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
|
||||
" fragColor = vec4(col, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
QByteArray versionedShaderCode(const char *src)
|
||||
{
|
||||
QByteArray versionedSrc;
|
||||
|
||||
if (QOpenGLContext::currentContext()->isOpenGLES())
|
||||
versionedSrc.append(QByteArrayLiteral("#version 300 es\n"));
|
||||
else
|
||||
versionedSrc.append(QByteArrayLiteral("#version 330\n"));
|
||||
|
||||
versionedSrc.append(src);
|
||||
return versionedSrc;
|
||||
}
|
||||
|
||||
void GLWindow::initializeGL()
|
||||
{
|
||||
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWindow::cleanup, Qt::UniqueConnection);
|
||||
|
||||
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
|
||||
|
||||
QImage img(":/qtlogo.png");
|
||||
Q_ASSERT(!img.isNull());
|
||||
delete m_texture;
|
||||
m_texture = new QOpenGLTexture(img.scaled(32, 36).mirrored());
|
||||
|
||||
delete m_program;
|
||||
m_program = new QOpenGLShaderProgram;
|
||||
// Prepend the correct version directive to the sources. The rest is the
|
||||
// same, thanks to the common GLSL syntax.
|
||||
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, versionedShaderCode(vertexShaderSource));
|
||||
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, versionedShaderCode(fragmentShaderSource));
|
||||
m_program->link();
|
||||
|
||||
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
|
||||
m_camMatrixLoc = m_program->uniformLocation("camMatrix");
|
||||
m_worldMatrixLoc = m_program->uniformLocation("worldMatrix");
|
||||
m_myMatrixLoc = m_program->uniformLocation("myMatrix");
|
||||
m_lightPosLoc = m_program->uniformLocation("lightPos");
|
||||
|
||||
// Create a VAO. Not strictly required for ES 3, but it is for plain OpenGL.
|
||||
delete m_vao;
|
||||
m_vao = new QOpenGLVertexArrayObject;
|
||||
if (m_vao->create())
|
||||
m_vao->bind();
|
||||
|
||||
m_program->bind();
|
||||
delete m_vbo;
|
||||
m_vbo = new QOpenGLBuffer;
|
||||
m_vbo->create();
|
||||
m_vbo->bind();
|
||||
m_vbo->allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));
|
||||
f->glEnableVertexAttribArray(0);
|
||||
f->glEnableVertexAttribArray(1);
|
||||
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
|
||||
nullptr);
|
||||
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat),
|
||||
reinterpret_cast<void *>(3 * sizeof(GLfloat)));
|
||||
m_vbo->release();
|
||||
|
||||
f->glEnable(GL_DEPTH_TEST);
|
||||
f->glEnable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void GLWindow::resizeGL(int w, int h)
|
||||
{
|
||||
m_proj.setToIdentity();
|
||||
m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f);
|
||||
m_uniformsDirty = true;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
f->glClearColor(0, 0, 0, 1);
|
||||
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
m_program->bind();
|
||||
m_texture->bind();
|
||||
|
||||
if (m_uniformsDirty) {
|
||||
m_uniformsDirty = false;
|
||||
QMatrix4x4 camera;
|
||||
camera.lookAt(m_eye, m_eye + m_target, QVector3D(0, 1, 0));
|
||||
m_program->setUniformValue(m_projMatrixLoc, m_proj);
|
||||
m_program->setUniformValue(m_camMatrixLoc, camera);
|
||||
QMatrix4x4 wm = m_world;
|
||||
wm.rotate(m_r, 1, 1, 0);
|
||||
m_program->setUniformValue(m_worldMatrixLoc, wm);
|
||||
QMatrix4x4 mm;
|
||||
mm.setToIdentity();
|
||||
mm.rotate(-m_r2, 1, 0, 0);
|
||||
m_program->setUniformValue(m_myMatrixLoc, mm);
|
||||
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
|
||||
}
|
||||
|
||||
// Now call a function introduced in OpenGL 3.1 / OpenGL ES 3.0. We
|
||||
// requested a 3.3 or ES 3.0 context, so we know this will work.
|
||||
f->glDrawArraysInstanced(GL_TRIANGLES, 0, m_logo.vertexCount(), 32 * 36);
|
||||
}
|
||||
|
||||
void GLWindow::cleanup()
|
||||
{
|
||||
makeCurrent();
|
||||
delete m_texture;
|
||||
delete m_program;
|
||||
delete m_vbo;
|
||||
delete m_vao;
|
||||
m_texture = nullptr;
|
||||
m_program = nullptr;
|
||||
m_vbo = nullptr;
|
||||
m_vao = nullptr;
|
||||
doneCurrent();
|
||||
QObject::disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWindow::cleanup);
|
||||
}
|
62
examples/openGL/glwindow.h
Normal file
62
examples/openGL/glwindow.h
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QOpenGLWindow>
|
||||
#include <QMatrix4x4>
|
||||
#include <QVector3D>
|
||||
#include "logo.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLTexture)
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLBuffer)
|
||||
QT_FORWARD_DECLARE_CLASS(QOpenGLVertexArrayObject)
|
||||
|
||||
class GLWindow : public QOpenGLWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float z READ z WRITE setZ)
|
||||
Q_PROPERTY(float r READ r WRITE setR)
|
||||
Q_PROPERTY(float r2 READ r2 WRITE setR2)
|
||||
|
||||
public:
|
||||
GLWindow();
|
||||
~GLWindow();
|
||||
|
||||
void initializeGL();
|
||||
void resizeGL(int w, int h);
|
||||
void paintGL();
|
||||
|
||||
float z() const { return m_eye.z(); }
|
||||
void setZ(float v);
|
||||
|
||||
float r() const { return m_r; }
|
||||
void setR(float v);
|
||||
float r2() const { return m_r2; }
|
||||
void setR2(float v);
|
||||
public slots:
|
||||
void cleanup();
|
||||
|
||||
private slots:
|
||||
void startSecondStage();
|
||||
|
||||
private:
|
||||
QOpenGLTexture *m_texture = nullptr;
|
||||
QOpenGLShaderProgram *m_program = nullptr;
|
||||
QOpenGLBuffer *m_vbo = nullptr;
|
||||
QOpenGLVertexArrayObject *m_vao = nullptr;
|
||||
Logo m_logo;
|
||||
int m_projMatrixLoc = 0;
|
||||
int m_camMatrixLoc = 0;
|
||||
int m_worldMatrixLoc = 0;
|
||||
int m_myMatrixLoc = 0;
|
||||
int m_lightPosLoc = 0;
|
||||
QMatrix4x4 m_proj;
|
||||
QMatrix4x4 m_world;
|
||||
QVector3D m_eye;
|
||||
QVector3D m_target = {0, 0, -1};
|
||||
bool m_uniformsDirty = true;
|
||||
float m_r = 0;
|
||||
float m_r2 = 0;
|
||||
};
|
103
examples/openGL/logo.cpp
Normal file
103
examples/openGL/logo.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "logo.h"
|
||||
#include <qmath.h>
|
||||
|
||||
Logo::Logo()
|
||||
{
|
||||
m_data.resize(2500 * 6);
|
||||
|
||||
const GLfloat x1 = +0.06f;
|
||||
const GLfloat y1 = -0.14f;
|
||||
const GLfloat x2 = +0.14f;
|
||||
const GLfloat y2 = -0.06f;
|
||||
const GLfloat x3 = +0.08f;
|
||||
const GLfloat y3 = +0.00f;
|
||||
const GLfloat x4 = +0.30f;
|
||||
const GLfloat 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;
|
||||
|
||||
for (int i = 0; i < NumSectors; ++i) {
|
||||
GLfloat angle = (i * 2 * M_PI) / NumSectors;
|
||||
GLfloat angleSin = qSin(angle);
|
||||
GLfloat angleCos = qCos(angle);
|
||||
const GLfloat x5 = 0.30f * angleSin;
|
||||
const GLfloat y5 = 0.30f * angleCos;
|
||||
const GLfloat x6 = 0.20f * angleSin;
|
||||
const GLfloat y6 = 0.20f * angleCos;
|
||||
|
||||
angle = ((i + 1) * 2 * M_PI) / NumSectors;
|
||||
angleSin = qSin(angle);
|
||||
angleCos = qCos(angle);
|
||||
const GLfloat x7 = 0.20f * angleSin;
|
||||
const GLfloat y7 = 0.20f * angleCos;
|
||||
const GLfloat x8 = 0.30f * angleSin;
|
||||
const GLfloat y8 = 0.30f * angleCos;
|
||||
|
||||
quad(x5, y5, x6, y6, x7, y7, x8, y8);
|
||||
|
||||
extrude(x6, y6, x7, y7);
|
||||
extrude(x8, y8, x5, y5);
|
||||
}
|
||||
}
|
||||
|
||||
void Logo::add(const QVector3D &v, const QVector3D &n)
|
||||
{
|
||||
GLfloat *p = m_data.data() + m_count;
|
||||
*p++ = v.x();
|
||||
*p++ = v.y();
|
||||
*p++ = v.z();
|
||||
*p++ = n.x();
|
||||
*p++ = n.y();
|
||||
*p++ = n.z();
|
||||
m_count += 6;
|
||||
}
|
||||
|
||||
void Logo::quad(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4)
|
||||
{
|
||||
QVector3D n = QVector3D::normal(QVector3D(x4 - x1, y4 - y1, 0.0f), QVector3D(x2 - x1, y2 - y1, 0.0f));
|
||||
|
||||
add(QVector3D(x1, y1, -0.05f), n);
|
||||
add(QVector3D(x4, y4, -0.05f), n);
|
||||
add(QVector3D(x2, y2, -0.05f), n);
|
||||
|
||||
add(QVector3D(x3, y3, -0.05f), n);
|
||||
add(QVector3D(x2, y2, -0.05f), n);
|
||||
add(QVector3D(x4, y4, -0.05f), n);
|
||||
|
||||
n = QVector3D::normal(QVector3D(x1 - x4, y1 - y4, 0.0f), QVector3D(x2 - x4, y2 - y4, 0.0f));
|
||||
|
||||
add(QVector3D(x4, y4, 0.05f), n);
|
||||
add(QVector3D(x1, y1, 0.05f), n);
|
||||
add(QVector3D(x2, y2, 0.05f), n);
|
||||
|
||||
add(QVector3D(x2, y2, 0.05f), n);
|
||||
add(QVector3D(x3, y3, 0.05f), n);
|
||||
add(QVector3D(x4, y4, 0.05f), n);
|
||||
}
|
||||
|
||||
void Logo::extrude(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
|
||||
{
|
||||
QVector3D n = QVector3D::normal(QVector3D(0.0f, 0.0f, -0.1f), QVector3D(x2 - x1, y2 - y1, 0.0f));
|
||||
|
||||
add(QVector3D(x1, y1, +0.05f), n);
|
||||
add(QVector3D(x1, y1, -0.05f), n);
|
||||
add(QVector3D(x2, y2, +0.05f), n);
|
||||
|
||||
add(QVector3D(x2, y2, -0.05f), n);
|
||||
add(QVector3D(x2, y2, +0.05f), n);
|
||||
add(QVector3D(x1, y1, -0.05f), n);
|
||||
}
|
28
examples/openGL/logo.h
Normal file
28
examples/openGL/logo.h
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef LOGO_H
|
||||
#define LOGO_H
|
||||
|
||||
#include <qopengl.h>
|
||||
#include <QList>
|
||||
#include <QVector3D>
|
||||
|
||||
class Logo
|
||||
{
|
||||
public:
|
||||
Logo();
|
||||
const GLfloat *constData() const { return m_data.constData(); }
|
||||
int count() const { return m_count; }
|
||||
int vertexCount() const { return m_count / 6; }
|
||||
|
||||
private:
|
||||
void quad(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2, GLfloat x3, GLfloat y3, GLfloat x4, GLfloat y4);
|
||||
void extrude(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
|
||||
void add(const QVector3D &v, const QVector3D &n);
|
||||
|
||||
QList<GLfloat> m_data;
|
||||
int m_count = 0;
|
||||
};
|
||||
|
||||
#endif // LOGO_H
|
36
examples/openGL/main.cpp
Normal file
36
examples/openGL/main.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include <QApplication>
|
||||
#include <QCommandLineOption>
|
||||
#include <QCommandLineParser>
|
||||
#include <QGuiApplication>
|
||||
#include <QOpenGLContext>
|
||||
#include <QScreen>
|
||||
#include <QQuickWindow>
|
||||
|
||||
#include <glwindow.h>
|
||||
#include <mainwindow.h>
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// https://doc.qt.io/qt-6/qtdatavisualization-known-issues.html
|
||||
// Use either `qputenv("QSG_RHI_BACKEND", "opengl");` or the following line
|
||||
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
|
||||
|
||||
// Disable warnings when attempts are made to convert non-convertible non-native widgets
|
||||
// to native widgets (such as QQuickWidget)
|
||||
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
|
||||
|
||||
// Enable ADS AutoHide
|
||||
ads::CDockManager::setAutoHideConfigFlags(ads::CDockManager::DefaultAutoHideConfig);
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
MainWindow* w = new MainWindow();
|
||||
|
||||
// Release memory when closing main window and quit application
|
||||
w->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
w->show();
|
||||
|
||||
return a.exec();
|
||||
}
|
169
examples/openGL/mainwindow.cpp
Normal file
169
examples/openGL/mainwindow.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QChart>
|
||||
#include <QChartView>
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QLineSeries>
|
||||
#include <QOpenGLWidget>
|
||||
#include <QPushButton>
|
||||
#include <QQuickView>
|
||||
#include <QQuickWidget>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include <glwidget.h>
|
||||
#include <glwindow.h>
|
||||
|
||||
class OpenGLChartWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
OpenGLChartWidget(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
// Create example chart using OpenGL
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QChartView* chart_view = new QChartView(this);
|
||||
QLineSeries* series = new QLineSeries(this);
|
||||
|
||||
QList<QPointF> points = {{0, 0}, {2, 0}, {2, 5},
|
||||
{4, 5}, {4, -2}, {6, -2}};
|
||||
series->setUseOpenGL(true);
|
||||
series->replace(points);
|
||||
chart_view->chart()->addSeries(series);
|
||||
chart_view->chart()->createDefaultAxes();
|
||||
chart_view->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
layout->addWidget(chart_view);
|
||||
}
|
||||
~OpenGLChartWidget() {}
|
||||
};
|
||||
|
||||
class ChartWidget : public QWidget
|
||||
{
|
||||
public:
|
||||
ChartWidget(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
// Create example chart using OpenGL
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QChartView* chart_view = new QChartView(this);
|
||||
QLineSeries* series = new QLineSeries(this);
|
||||
|
||||
QList<QPointF> points = {{0, 0}, {2, 0}, {2, -5},
|
||||
{4, -5}, {4, 2}, {6, 2}};
|
||||
series->replace(points);
|
||||
chart_view->chart()->addSeries(series);
|
||||
chart_view->chart()->createDefaultAxes();
|
||||
chart_view->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
layout->addWidget(chart_view);
|
||||
}
|
||||
~ChartWidget() {}
|
||||
};
|
||||
|
||||
class OpenGLWindowContainer : public QWidget
|
||||
{
|
||||
public:
|
||||
OpenGLWindowContainer(QWidget* parent = nullptr) : QWidget(parent)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
QWidget* widget = QWidget::createWindowContainer(new GLWindow, parent);
|
||||
layout->addWidget(widget);
|
||||
}
|
||||
|
||||
~OpenGLWindowContainer() {}
|
||||
};
|
||||
|
||||
class QuickViewContainer : public QWidget
|
||||
{
|
||||
public:
|
||||
QuickViewContainer(QWidget* parent = nullptr) : QWidget(parent)
|
||||
{
|
||||
QVBoxLayout* l = new QVBoxLayout(this);
|
||||
l->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
_format.setDepthBufferSize(16);
|
||||
_format.setStencilBufferSize(8);
|
||||
_format.setSamples(4);
|
||||
|
||||
QUrl source("qrc:/openGL/test.qml");
|
||||
|
||||
QQuickView* quick_view = new QQuickView();
|
||||
quick_view->setFormat(_format);
|
||||
quick_view->setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
quick_view->setSource(source);
|
||||
|
||||
if (quick_view->status() != QQuickView::Ready)
|
||||
{
|
||||
qWarning() << "QQuickView error:" << quick_view->errors();
|
||||
}
|
||||
|
||||
l->addWidget(QWidget::createWindowContainer(quick_view, parent));
|
||||
}
|
||||
|
||||
~QuickViewContainer() {}
|
||||
|
||||
private:
|
||||
QSurfaceFormat _format;
|
||||
};
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
|
||||
{
|
||||
resize(900, 600);
|
||||
|
||||
// Create the dock manager. Because the parent parameter is a QMainWindow
|
||||
// the dock manager registers itself as the central widget.
|
||||
_dock_manager = new ads::CDockManager(this);
|
||||
|
||||
OpenGLChartWidget* openGL_chart = new OpenGLChartWidget(this);
|
||||
ChartWidget* simple_chart = new ChartWidget(this);
|
||||
OpenGLWindowContainer* openGL_container = new OpenGLWindowContainer(this);
|
||||
GLWidget* gl_widget = new GLWidget(this);
|
||||
GLWidget* gl_widget_2 = new GLWidget(this);
|
||||
QuickViewContainer* quick_view_container = new QuickViewContainer(this);
|
||||
|
||||
QLabel* l = new QLabel();
|
||||
l->setWordWrap(true);
|
||||
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
|
||||
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
|
||||
|
||||
QUrl source("qrc:/openGL/test.qml");
|
||||
|
||||
QQuickWidget* quick_widget = new QQuickWidget(this);
|
||||
quick_widget->setSource(source);
|
||||
quick_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||
|
||||
auto* center_dock_area_widget = createDockWidget(
|
||||
openGL_chart, "Chart with OpenGL", ads::CenterDockWidgetArea);
|
||||
|
||||
createDockWidget(simple_chart, "Simple Chart", ads::CenterDockWidgetArea,
|
||||
center_dock_area_widget);
|
||||
|
||||
createDockWidget(openGL_container, "OpenGL window", ads::CenterDockWidgetArea,
|
||||
center_dock_area_widget);
|
||||
|
||||
createDockWidget(gl_widget, "OpenGL widget", ads::CenterDockWidgetArea,
|
||||
center_dock_area_widget);
|
||||
|
||||
createDockWidget(gl_widget_2, "OpenGL widget 2", ads::CenterDockWidgetArea,
|
||||
center_dock_area_widget);
|
||||
|
||||
createDockWidget(quick_view_container, "Quick View",
|
||||
ads::CenterDockWidgetArea, center_dock_area_widget);
|
||||
|
||||
createDockWidget(quick_widget, "Quick Widget", ads::CenterDockWidgetArea,
|
||||
center_dock_area_widget);
|
||||
|
||||
createDockWidget(l, "Label", ads::CenterDockWidgetArea,
|
||||
center_dock_area_widget);
|
||||
}
|
||||
|
||||
ads::CDockAreaWidget* MainWindow::createDockWidget(
|
||||
QWidget* embedded_widget, QString dock_widget_title, ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget* center_dock_area_widget)
|
||||
{
|
||||
ads::CDockWidget* dock_widget = new ads::CDockWidget(dock_widget_title);
|
||||
dock_widget->setWidget(embedded_widget);
|
||||
return _dock_manager->addDockWidget(area, dock_widget,
|
||||
center_dock_area_widget);
|
||||
}
|
24
examples/openGL/mainwindow.h
Normal file
24
examples/openGL/mainwindow.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
#include <DockManager.h>
|
||||
#include <DockAreaWidget.h>
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MainWindow(QWidget* parent = 0);
|
||||
~MainWindow() = default;
|
||||
|
||||
ads::CDockAreaWidget* createDockWidget(QWidget* embedded_widget, QString dock_widget_title, ads::DockWidgetArea area,
|
||||
ads::CDockAreaWidget* DockAreaWidget = nullptr);
|
||||
|
||||
private:
|
||||
ads::CDockManager* _dock_manager;
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
44
examples/openGL/openGL.pro
Normal file
44
examples/openGL/openGL.pro
Normal file
@ -0,0 +1,44 @@
|
||||
ADS_OUT_ROOT = $${OUT_PWD}/../..
|
||||
|
||||
QT += core gui widgets charts opengl quick quickwidgets
|
||||
|
||||
TARGET = OpenGLExample
|
||||
DESTDIR = $${ADS_OUT_ROOT}/lib
|
||||
TEMPLATE = app
|
||||
CONFIG += c++14
|
||||
CONFIG += debug
|
||||
CONFIG += qmltypes
|
||||
QML_IMPORT_NAME = fbitem
|
||||
QML_IMPORT_MAJOR_VERSION = 1
|
||||
|
||||
adsBuildStatic {
|
||||
DEFINES += ADS_STATIC
|
||||
}
|
||||
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
DEFINES += QT_DEBUG_PLUGINS
|
||||
|
||||
SOURCES += \
|
||||
glwidget.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp \
|
||||
logo.cpp \
|
||||
glwindow.cpp \
|
||||
fbitem.cpp
|
||||
|
||||
HEADERS += \
|
||||
mainwindow.h \
|
||||
glwidget.h \
|
||||
logo.h \
|
||||
glwindow.h \
|
||||
fbitem.h
|
||||
|
||||
RESOURCES += openGL.qrc
|
||||
|
||||
OTHER_FILES += test.qml
|
||||
|
||||
LIBS += -L$${ADS_OUT_ROOT}/lib
|
||||
include(../../ads.pri)
|
||||
INCLUDEPATH += ../../src
|
||||
DEPENDPATH += ../../src
|
||||
|
10
examples/openGL/openGL.qrc
Normal file
10
examples/openGL/openGL.qrc
Normal file
@ -0,0 +1,10 @@
|
||||
<RCC>
|
||||
<qresource prefix="/openGL">
|
||||
<file>test.qml</file>
|
||||
<file>wobble.frag</file>
|
||||
<file>wobble.frag.qsb</file>
|
||||
</qresource>
|
||||
<qresource>
|
||||
<file>qtlogo.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
BIN
examples/openGL/qtlogo.png
Normal file
BIN
examples/openGL/qtlogo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
171
examples/openGL/test.qml
Normal file
171
examples/openGL/test.qml
Normal file
@ -0,0 +1,171 @@
|
||||
// Copyright (C) 2017 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Particles
|
||||
import fbitem
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
property alias currentText: edit.text
|
||||
property alias multisample: fbitem.multisample
|
||||
property bool translucency: false
|
||||
|
||||
gradient: Gradient {
|
||||
id: grad
|
||||
GradientStop { position: 0; color: "steelblue" }
|
||||
GradientStop { position: 1; color: "black" }
|
||||
}
|
||||
|
||||
onTranslucencyChanged: {
|
||||
if (translucency) {
|
||||
root.color = "transparent";
|
||||
root.gradient = null;
|
||||
} else {
|
||||
root.color = "white";
|
||||
root.gradient = grad;
|
||||
}
|
||||
}
|
||||
|
||||
ParticleSystem {
|
||||
anchors.fill: parent
|
||||
running: true
|
||||
|
||||
ImageParticle {
|
||||
source: "qrc:///particleresources/glowdot.png"
|
||||
alpha: 0
|
||||
colorVariation: 1
|
||||
}
|
||||
|
||||
Emitter {
|
||||
anchors.fill: parent
|
||||
lifeSpan: 3000
|
||||
emitRate: 30
|
||||
size: 50
|
||||
sizeVariation: 10
|
||||
velocity: PointDirection { xVariation: 10; yVariation: 10; }
|
||||
acceleration: PointDirection {
|
||||
y: -10
|
||||
xVariation: 5
|
||||
yVariation: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
y: 10
|
||||
width: parent.width / 2
|
||||
height: edit.contentHeight + 4
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
border.color: "gray"
|
||||
border.width: 2
|
||||
radius: 8
|
||||
color: "lightGray"
|
||||
clip: true
|
||||
TextInput {
|
||||
id: edit
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
maximumLength: 30
|
||||
focus: true
|
||||
font.pointSize: 20
|
||||
}
|
||||
}
|
||||
|
||||
FbItem {
|
||||
id: fbitem
|
||||
anchors.fill: parent
|
||||
SequentialAnimation on eye.y {
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation {
|
||||
from: 0
|
||||
to: 0.15
|
||||
duration: 1000
|
||||
}
|
||||
NumberAnimation {
|
||||
from: 0.15
|
||||
to: 0
|
||||
duration: 2000
|
||||
}
|
||||
}
|
||||
SequentialAnimation on eye.x {
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation {
|
||||
from: 0
|
||||
to: -0.5
|
||||
duration: 3000
|
||||
}
|
||||
NumberAnimation {
|
||||
from: -0.5
|
||||
to: 0.5
|
||||
duration: 3000
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
NumberAnimation {
|
||||
from: 0.5
|
||||
to: 0
|
||||
duration: 1000
|
||||
}
|
||||
}
|
||||
SequentialAnimation on rotation.y {
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation {
|
||||
from: 0
|
||||
to: 360
|
||||
duration: 5000
|
||||
}
|
||||
NumberAnimation {
|
||||
from: 360
|
||||
to: 0
|
||||
duration: 2500
|
||||
}
|
||||
}
|
||||
SequentialAnimation on rotation.x {
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation {
|
||||
from: 0
|
||||
to: 360
|
||||
duration: 6000
|
||||
}
|
||||
NumberAnimation {
|
||||
from: 360
|
||||
to: 0
|
||||
duration: 3000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: effText
|
||||
text: edit.text
|
||||
anchors.centerIn: parent
|
||||
font.pointSize: 60
|
||||
style: Text.Outline
|
||||
styleColor: "green"
|
||||
}
|
||||
|
||||
ShaderEffectSource {
|
||||
id: effSource
|
||||
sourceItem: effText
|
||||
hideSource: true
|
||||
}
|
||||
|
||||
ShaderEffect {
|
||||
SequentialAnimation on scale {
|
||||
loops: Animation.Infinite
|
||||
NumberAnimation { from: 1.0; to: 2.0; duration: 1000; easing.type: Easing.InCirc }
|
||||
PauseAnimation { duration: 1000 }
|
||||
NumberAnimation { from: 2.0; to: 0.5; duration: 1000; easing.type: Easing.OutExpo }
|
||||
NumberAnimation { from: 0.5; to: 1.0; duration: 500 }
|
||||
PauseAnimation { duration: 1000 }
|
||||
}
|
||||
width: effText.width
|
||||
height: effText.height
|
||||
anchors.centerIn: parent
|
||||
property variant source: effSource
|
||||
property real amplitude: 0.002
|
||||
property real frequency: 10
|
||||
property real time: 0
|
||||
NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 1000 }
|
||||
fragmentShader: "wobble.frag.qsb"
|
||||
}
|
||||
}
|
23
examples/openGL/wobble.frag
Normal file
23
examples/openGL/wobble.frag
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#version 440
|
||||
|
||||
layout(location = 0) in vec2 qt_TexCoord0;
|
||||
layout(location = 0) out vec4 fragColor;
|
||||
|
||||
layout(binding = 1) uniform sampler2D source;
|
||||
|
||||
layout(std140, binding = 0) uniform buf {
|
||||
mat4 qt_Matrix;
|
||||
float qt_Opacity;
|
||||
float amplitude;
|
||||
float frequency;
|
||||
float time;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 p = sin(time + frequency * qt_TexCoord0);
|
||||
fragColor = texture(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;
|
||||
}
|
BIN
examples/openGL/wobble.frag.qsb
Normal file
BIN
examples/openGL/wobble.frag.qsb
Normal file
Binary file not shown.
@ -725,7 +725,12 @@ void CDockAreaWidget::setCurrentIndex(int index)
|
||||
Q_EMIT currentChanging(index);
|
||||
TabBar->setCurrentIndex(index);
|
||||
d->ContentsLayout->setCurrentIndex(index);
|
||||
// Force the widget to be native in order to avoid blinks with OpenGL widgets
|
||||
d->ContentsLayout->currentWidget()->winId();
|
||||
d->ContentsLayout->currentWidget()->show();
|
||||
// Force the repaint of the current widget because mix of OpenGL widgets
|
||||
// and Raster widgets could have not been entirely rendered
|
||||
d->ContentsLayout->currentWidget()->repaint();
|
||||
Q_EMIT currentChanged(index);
|
||||
}
|
||||
|
||||
|
@ -507,6 +507,10 @@ CDockManager::CDockManager(QWidget *parent) :
|
||||
CDockContainerWidget(this, parent),
|
||||
d(new DockManagerPrivate(this))
|
||||
{
|
||||
// Force the Dock Manager to be native in order to fix wrong position of overlay
|
||||
// the first time a dock container is dragged
|
||||
winId();
|
||||
|
||||
createRootSplitter();
|
||||
createSideTabBarWidgets();
|
||||
QMainWindow* MainWindow = qobject_cast<QMainWindow*>(parent);
|
||||
|
@ -376,6 +376,9 @@ CDockWidget::CDockWidget(CDockManager *manager, const QString &title, QWidget* p
|
||||
: QFrame(parent),
|
||||
d(new DockWidgetPrivate(this))
|
||||
{
|
||||
// Force the new CDockWidget to be native so OpenGL widgets are well handled
|
||||
// with non OpenGL widgets
|
||||
winId();
|
||||
d->DockManager = manager;
|
||||
d->Layout = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
d->Layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
@ -707,6 +707,9 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
|
||||
{
|
||||
setTitleBarWidget(new QWidget());
|
||||
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
|
||||
// Force the new window to be native so OpenGL widgets are well handled
|
||||
// Unfortunatly setAttribute(Qt::WA_NativeWindow) provokes weird behavior
|
||||
winId();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
9
vcpkg-configuration.json
Normal file
9
vcpkg-configuration.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json",
|
||||
"default-registry": {
|
||||
"kind": "git",
|
||||
"baseline": "2f210a9c13fcf2b0c36b1f2187366feec37e3390",
|
||||
"reference": "master",
|
||||
"repository": "https://github.com/microsoft/vcpkg"
|
||||
}
|
||||
}
|
8
vcpkg.json
Normal file
8
vcpkg.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"dependencies": [
|
||||
"qtcharts",
|
||||
"qttranslations",
|
||||
"qtdeclarative",
|
||||
"qtbase"
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user