diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2020-06-08 11:54:10 +0200 |
---|---|---|
committer | Mike Krus <mike.krus@kdab.com> | 2020-06-11 20:44:03 +0100 |
commit | 50ee9444cc5c5689689de9f50941d0eb3acd83eb (patch) | |
tree | 8c20965660a8da36ead4f88a3841e083a91d255d | |
parent | f03a1202dbb706e64ae41bde82a0d2cd044821af (diff) |
Fix Scene3D to work with latest QtQuick SceneGraph RHI changes
Change-Id: If507aac8d48cc33fa7acf993ab77b76cdd70ee9a
Reviewed-by: Mike Krus <mike.krus@kdab.com>
-rw-r--r-- | examples/qt3d/scene3d/main.cpp | 4 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/CMakeLists.txt | 13 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/importsscene3d.pro | 5 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3d.qrc | 6 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgmaterial.cpp | 6 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgmaterial_p.h | 2 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp | 138 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h | 14 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag | 21 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag.qsb | bin | 0 -> 1776 bytes | |||
-rw-r--r-- | src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert | 17 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert.qsb | bin | 0 -> 1920 bytes |
12 files changed, 124 insertions, 102 deletions
diff --git a/examples/qt3d/scene3d/main.cpp b/examples/qt3d/scene3d/main.cpp index 4d22a5b68..3df6816c6 100644 --- a/examples/qt3d/scene3d/main.cpp +++ b/examples/qt3d/scene3d/main.cpp @@ -69,10 +69,14 @@ int main(int argc, char **argv) } QGuiApplication app(argc, argv); + // Force OpenGL backend + QQuickWindow::setSceneGraphBackend(QSGRendererInterface::OpenGLRhi); QQuickView view; view.resize(1024, 768); view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setPersistentOpenGLContext(true); + view.setPersistentSceneGraph(true); view.setSource(QUrl("qrc:/main.qml")); view.show(); diff --git a/src/quick3d/imports/scene3d/CMakeLists.txt b/src/quick3d/imports/scene3d/CMakeLists.txt index d5f86f563..ce4a0e51c 100644 --- a/src/quick3d/imports/scene3d/CMakeLists.txt +++ b/src/quick3d/imports/scene3d/CMakeLists.txt @@ -52,3 +52,16 @@ qt_extend_target(qtquickscene3dplugin CONDITION QT_FEATURE_qt3d_animation PUBLIC_LIBRARIES Qt::3DAnimation ) + +# Resources: +set(shader_resource_files + "shaders/scene3dmaterial.vert.qsb" + "shaders/scene3dmaterial.frag.qsb" +) + +qt6_add_resources(qtquickscene3dplugin "scene3d" + PREFIX + "/" + FILES + ${shader_resource_files} +) diff --git a/src/quick3d/imports/scene3d/importsscene3d.pro b/src/quick3d/imports/scene3d/importsscene3d.pro index 2f257399c..3b8244f19 100644 --- a/src/quick3d/imports/scene3d/importsscene3d.pro +++ b/src/quick3d/imports/scene3d/importsscene3d.pro @@ -29,6 +29,9 @@ SOURCES += \ scene3dsgmaterial.cpp \ scene3dview.cpp -OTHER_FILES += qmldir +OTHER_FILES += qmldir shaders/* load(qml_plugin) + +RESOURCES += \ + scene3d.qrc diff --git a/src/quick3d/imports/scene3d/scene3d.qrc b/src/quick3d/imports/scene3d/scene3d.qrc new file mode 100644 index 000000000..99b33df03 --- /dev/null +++ b/src/quick3d/imports/scene3d/scene3d.qrc @@ -0,0 +1,6 @@ +<RCC> + <qresource prefix="/"> + <file>shaders/scene3dmaterial.frag.qsb</file> + <file>shaders/scene3dmaterial.vert.qsb</file> + </qresource> +</RCC> diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterial.cpp b/src/quick3d/imports/scene3d/scene3dsgmaterial.cpp index 80a1c2c9c..a4de2f76d 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterial.cpp +++ b/src/quick3d/imports/scene3d/scene3dsgmaterial.cpp @@ -64,6 +64,12 @@ Scene3DSGMaterial::Scene3DSGMaterial() { } +QSGMaterialShader *Scene3DSGMaterial::createShader() const +{ + return new Scene3DSGMaterialShader(); +} + + } // namespace Qt3DRender QT_END_NAMESPACE diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h b/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h index 59724782b..cecd295df 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h +++ b/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h @@ -73,7 +73,7 @@ public: QSGTexture *texture() const Q_DECL_NOTHROW { return m_texture; } QSGMaterialType *type() const final { return &Scene3DSGMaterialShader::type; } - QSGMaterialShader *createShader() const final { return new Scene3DSGMaterialShader(); } + QSGMaterialShader *createShader() const final; void show() { m_visible = true; } bool visible() const { return m_visible; } diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp index 13e691e7f..955bcbfc3 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp +++ b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp @@ -74,100 +74,71 @@ QSGMaterialType Scene3DSGMaterialShader::type; Scene3DSGMaterialShader::Scene3DSGMaterialShader() : QSGMaterialShader() - , m_matrixId(-1) - , m_opacityId(-1) - , m_visibleId(-1) { + // Generated with qsb, we target all GL version Qt3D can handle + // qsb -b --glsl "460,450,440,430,420,410,400,330,150,120,320 es,300 es,100 es" --hlsl 50 --msl 12 -o scene3dmaterial.vert.qsb scene3dmaterial.vert + // qsb --glsl "460,450,440,430,420,410,400,330,150,120,320 es,300 es,100 es" --hlsl 50 --msl 12 -o scene3dmaterial.frag.qsb scene3dmaterial.frag + setShaderFileName(VertexStage, QLatin1String(":/shaders/scene3dmaterial.vert.qsb")); + setShaderFileName(FragmentStage, QLatin1String(":/shaders/scene3dmaterial.frag.qsb")); } -const char * const *Scene3DSGMaterialShader::attributeNames() const +bool Scene3DSGMaterialShader::updateUniformData(QSGMaterialShader::RenderState &state, + QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) { - static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 }; - return attr; -} + // layout(std140, binding = 0) uniform buf { + // mat4 qt_Matrix; // offset 0, sizeof(float) * 16 + // float qt_Opacity; // offset sizeof(float) * 16, sizeof(float) + // bool visible; // offset sizeof(float) * 17, sizeof(float) + // }; + + QByteArray *buf = state.uniformData(); + Q_ASSERT(buf->size() >= int(18 * sizeof(float))); + Scene3DSGMaterial *tx = static_cast<Scene3DSGMaterial *>(newMaterial); + Scene3DSGMaterial *oldTx = static_cast<Scene3DSGMaterial *>(oldMaterial); + + bool updateMade = false; + + if (state.isMatrixDirty()) { + const QMatrix4x4 &m = state.combinedMatrix(); + memcpy(buf->data(), m.constData(), 16 * sizeof(float)); + updateMade = true; + } -const char *Scene3DSGMaterialShader::vertexShader() const -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->format().version() >= qMakePair(3, 2) && ctx->format().profile() == QSurfaceFormat::CoreProfile) { - return "" - "#version 150 core \n" - "uniform mat4 qt_Matrix; \n" - "in vec4 qt_VertexPosition; \n" - "in vec2 qt_VertexTexCoord; \n" - "out vec2 qt_TexCoord; \n" - "void main() { \n" - " qt_TexCoord = qt_VertexTexCoord; \n" - " gl_Position = qt_Matrix * qt_VertexPosition; \n" - "}"; - } else { - return "" - "uniform highp mat4 qt_Matrix; \n" - "attribute highp vec4 qt_VertexPosition; \n" - "attribute highp vec2 qt_VertexTexCoord; \n" - "varying highp vec2 qt_TexCoord; \n" - "void main() { \n" - " qt_TexCoord = qt_VertexTexCoord; \n" - " gl_Position = qt_Matrix * qt_VertexPosition; \n" - "}"; + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 16 * sizeof(float), &opacity, sizeof(float)); + updateMade = true; } -} -const char *Scene3DSGMaterialShader::fragmentShader() const -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx->format().version() >= qMakePair(3, 2) && ctx->format().profile() == QSurfaceFormat::CoreProfile) { - return "" - "#version 150 core \n" - "uniform bool visible; \n" - "uniform sampler2D source; \n" - "uniform float qt_Opacity; \n" - "in vec2 qt_TexCoord; \n" - "out vec4 fragColor; \n" - "void main() { \n" - " if (!visible) discard; \n" - " vec4 p = texture(source, qt_TexCoord); \n" - " float a = qt_Opacity * p.a; \n" - " fragColor = vec4(p.rgb * a, a); \n" - "}"; - } else { - return "" - "uniform bool visible; \n" - "uniform highp sampler2D source; \n" - "uniform highp float qt_Opacity; \n" - "varying highp vec2 qt_TexCoord; \n" - "void main() { \n" - " if (!visible) discard; \n" - " highp vec4 p = texture2D(source, qt_TexCoord); \n" - " highp float a = qt_Opacity * p.a; \n" - " gl_FragColor = vec4(p.rgb * a, a); \n" - "}"; + if (oldTx == nullptr || oldTx->visible() != tx->visible()) { + const float value = tx->visible() ? 1.0f : -1.0f; + memcpy(buf->data() + 17 * sizeof(float), &value, sizeof(float)); + updateMade = true; } -} -void Scene3DSGMaterialShader::initialize() -{ - m_matrixId = program()->uniformLocation("qt_Matrix"); - m_opacityId = program()->uniformLocation("qt_Opacity"); - m_visibleId = program()->uniformLocation("visible"); + return updateMade; } -// TODO QT6 (this will be removed from base class) -void Scene3DSGMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) +void Scene3DSGMaterialShader::updateSampledImage(QSGMaterialShader::RenderState &state, + int binding, + QSGTexture **texture, + QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) { - Q_ASSERT(oldEffect == 0 || newEffect->type() == oldEffect->type()); - Scene3DSGMaterial *tx = static_cast<Scene3DSGMaterial *>(newEffect); - Scene3DSGMaterial *oldTx = static_cast<Scene3DSGMaterial *>(oldEffect); - + Q_UNUSED(state); + Q_UNUSED(binding); + Scene3DSGMaterial *tx = static_cast<Scene3DSGMaterial *>(newMaterial); + Scene3DSGMaterial *oldTx = static_cast<Scene3DSGMaterial *>(oldMaterial); QSGTexture *t = tx->texture(); if (t != nullptr) { // TODO QT6 FIXME -// bool npotSupported = const_cast<QOpenGLContext *>(state.context()) -// ->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat); + // bool npotSupported = const_cast<QOpenGLContext *>(state.context()) + // ->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextureRepeat); bool npotSupported = true; if (!npotSupported) { - QSize size = t->textureSize(); + const QSize size = t->textureSize(); const bool isNpot = !isPowerOfTwo(size.width()) || !isPowerOfTwo(size.height()); if (isNpot) { t->setHorizontalWrapMode(QSGTexture::ClampToEdge); @@ -175,20 +146,9 @@ void Scene3DSGMaterialShader::updateState(const RenderState &state, QSGMaterial } } - if (oldTx == 0 || oldTx->texture()->textureId() != t->textureId()) - t->bind(); - else - t->updateBindOptions(); + if (oldTx == nullptr || oldTx->texture() != t) + *texture = t; } - - if (oldTx == nullptr || oldTx->visible() != tx->visible()) - program()->setUniformValue(m_visibleId, tx->visible()); - - if (state.isMatrixDirty()) - program()->setUniformValue(m_matrixId, state.combinedMatrix()); - - if (state.isOpacityDirty()) - program()->setUniformValue(m_opacityId, state.opacity()); } } // namespace Qt3DRender diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h b/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h index 60edf6d45..c4b483625 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h +++ b/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h @@ -61,20 +61,12 @@ class Scene3DSGMaterialShader : public QSGMaterialShader { public: Scene3DSGMaterialShader(); - void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) final; - const char * const *attributeNames() const final; - static QSGMaterialType type; protected: - const char *vertexShader() const final; - const char *fragmentShader() const final; - void initialize() final; - -private: - int m_matrixId; - int m_opacityId; - int m_visibleId; + // QSGMaterialShader interface + bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) final; + void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) final; }; } // namespace Qt3DRender diff --git a/src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag new file mode 100644 index 000000000..3b8bafeb7 --- /dev/null +++ b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag @@ -0,0 +1,21 @@ +#version 450 + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float visible; +}; + +layout(binding = 1) uniform sampler2D source; + +layout(location = 0) in vec2 qt_TexCoord; +layout(location = 0) out vec4 fragColor; + +void main() +{ + if (visible < 0.0) + discard; + vec4 p = texture(source, qt_TexCoord); + float a = qt_Opacity * p.a; + fragColor = vec4(p.rgb * a, a); +} diff --git a/src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag.qsb b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag.qsb Binary files differnew file mode 100644 index 000000000..b24ef4019 --- /dev/null +++ b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag.qsb diff --git a/src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert new file mode 100644 index 000000000..5528ddeb5 --- /dev/null +++ b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert @@ -0,0 +1,17 @@ +#version 450 + +layout(location = 0) in vec4 vertexPosition; +layout(location = 1) in vec2 vertexTexCoord; +layout(location = 0) out vec2 qt_TexCoord; + +layout(std140, binding = 0) uniform buf { + mat4 qt_Matrix; + float qt_Opacity; + float visible; +}; + +void main() +{ + qt_TexCoord = vertexTexCoord; + gl_Position = qt_Matrix * vertexPosition; +} diff --git a/src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert.qsb b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert.qsb Binary files differnew file mode 100644 index 000000000..6e17b49fb --- /dev/null +++ b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert.qsb |