summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2020-06-08 11:54:10 +0200
committerMike Krus <mike.krus@kdab.com>2020-06-11 20:44:03 +0100
commit50ee9444cc5c5689689de9f50941d0eb3acd83eb (patch)
tree8c20965660a8da36ead4f88a3841e083a91d255d
parentf03a1202dbb706e64ae41bde82a0d2cd044821af (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.cpp4
-rw-r--r--src/quick3d/imports/scene3d/CMakeLists.txt13
-rw-r--r--src/quick3d/imports/scene3d/importsscene3d.pro5
-rw-r--r--src/quick3d/imports/scene3d/scene3d.qrc6
-rw-r--r--src/quick3d/imports/scene3d/scene3dsgmaterial.cpp6
-rw-r--r--src/quick3d/imports/scene3d/scene3dsgmaterial_p.h2
-rw-r--r--src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp138
-rw-r--r--src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h14
-rw-r--r--src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag21
-rw-r--r--src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag.qsbbin0 -> 1776 bytes
-rw-r--r--src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert17
-rw-r--r--src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert.qsbbin0 -> 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
new file mode 100644
index 000000000..b24ef4019
--- /dev/null
+++ b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.frag.qsb
Binary files differ
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
new file mode 100644
index 000000000..6e17b49fb
--- /dev/null
+++ b/src/quick3d/imports/scene3d/shaders/scene3dmaterial.vert.qsb
Binary files differ