aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quick/scenegraph
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-06-03 11:26:58 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-06-03 10:24:32 +0000
commit446661a199563b13db56aeddb7eeecf7259786d8 (patch)
tree88007ab9b4e6f9c58f188d6992266998cf98f42c /examples/quick/scenegraph
parent0e767eaa29ea0a7edb101ba87fb8367e9f056eed (diff)
Enhance rendernode example with opacity support
The opacity is already animated in the QML scene but enabling blending and using inheritedOpacity() was not done. Until now. Change-Id: Iaaf50c20302e29db85c5dfaeaab4d069cb18714e Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'examples/quick/scenegraph')
-rw-r--r--examples/quick/scenegraph/rendernode/d3d12renderer.cpp42
-rw-r--r--examples/quick/scenegraph/rendernode/main.qml4
-rw-r--r--examples/quick/scenegraph/rendernode/openglrenderer.cpp16
-rw-r--r--examples/quick/scenegraph/rendernode/openglrenderer.h2
-rw-r--r--examples/quick/scenegraph/rendernode/shader.hlsl7
5 files changed, 49 insertions, 22 deletions
diff --git a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp
index 3694c6ae75..bc03720407 100644
--- a/examples/quick/scenegraph/rendernode/d3d12renderer.cpp
+++ b/examples/quick/scenegraph/rendernode/d3d12renderer.cpp
@@ -83,7 +83,7 @@ void D3D12RenderNode::init()
D3D12_ROOT_PARAMETER rootParameter;
rootParameter.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
- rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
+ rootParameter.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;
rootParameter.Descriptor.ShaderRegister = 0; // b0
rootParameter.Descriptor.RegisterSpace = 0;
@@ -123,11 +123,19 @@ void D3D12RenderNode::init()
rastDesc.CullMode = D3D12_CULL_MODE_BACK;
rastDesc.FrontCounterClockwise = TRUE; // Vertices are given CCW
- // No blending, just enable color write.
- D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = {};
- defaultRenderTargetBlendDesc.RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
+ // Enable color write and blending (premultiplied alpha). The latter is
+ // needed because the example changes the item's opacity and we pass
+ // inheritedOpacity() into the pixel shader. If that wasn't the case,
+ // blending could have stayed disabled.
+ const D3D12_RENDER_TARGET_BLEND_DESC premulBlendDesc = {
+ TRUE, FALSE,
+ D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
+ D3D12_BLEND_ONE, D3D12_BLEND_INV_SRC_ALPHA, D3D12_BLEND_OP_ADD,
+ D3D12_LOGIC_OP_NOOP,
+ D3D12_COLOR_WRITE_ENABLE_ALL
+ };
D3D12_BLEND_DESC blendDesc = {};
- blendDesc.RenderTarget[0] = defaultRenderTargetBlendDesc;
+ blendDesc.RenderTarget[0] = premulBlendDesc;
D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {};
psoDesc.InputLayout = { inputElementDescs, _countof(inputElementDescs) };
@@ -177,7 +185,7 @@ void D3D12RenderNode::init()
}
vertexBufferView.BufferLocation = vertexBuffer->GetGPUVirtualAddress();
- vertexBufferView.StrideInBytes = (2 + 3) * sizeof(float);
+ vertexBufferView.StrideInBytes = vertexBufferSize / 3;
vertexBufferView.SizeInBytes = vertexBufferSize;
bufDesc.Width = 256;
@@ -198,6 +206,14 @@ void D3D12RenderNode::init()
qWarning("Map failed (constant buffer)");
return;
}
+
+ float *vp = reinterpret_cast<float *>(vbPtr);
+ vp += 2;
+ *vp++ = 1.0f; *vp++ = 0.0f; *vp++ = 0.0f;
+ vp += 2;
+ *vp++ = 0.0f; *vp++ = 1.0f; *vp++ = 0.0f;
+ vp += 2;
+ *vp++ = 0.0f; *vp++ = 0.0f; *vp++ = 1.0f;
}
void D3D12RenderNode::render(const RenderState *state)
@@ -212,6 +228,8 @@ void D3D12RenderNode::render(const RenderState *state)
const int msize = 16 * sizeof(float);
memcpy(cbPtr, matrix()->constData(), msize);
memcpy(cbPtr + msize, state->projectionMatrix()->constData(), msize);
+ const float opacity = inheritedOpacity();
+ memcpy(cbPtr + 2 * msize, &opacity, sizeof(float));
const QPointF p0(m_item->width() - 1, m_item->height() - 1);
const QPointF p1(0, 0);
@@ -220,15 +238,12 @@ void D3D12RenderNode::render(const RenderState *state)
float *vp = reinterpret_cast<float *>(vbPtr);
*vp++ = p0.x();
*vp++ = p0.y();
- *vp++ = 1.0f; *vp++ = 0.0f; *vp++ = 0.0f;
-
+ vp += 3;
*vp++ = p1.x();
*vp++ = p1.y();
- *vp++ = 0.0f; *vp++ = 1.0f; *vp++ = 0.0f;
-
+ vp += 3;
*vp++ = p2.x();
*vp++ = p2.y();
- *vp++ = 0.0f; *vp++ = 0.0f; *vp++ = 1.0f;
commandList->SetPipelineState(pipelineState.Get());
commandList->SetGraphicsRootSignature(rootSignature.Get());
@@ -237,8 +252,9 @@ void D3D12RenderNode::render(const RenderState *state)
commandList->IASetVertexBuffers(0, 1, &vertexBufferView);
commandList->DrawInstanced(3, 1, 0, 0);
-
- // we won't implement changedStates() since no viewport/scissor/stencil/blend related commands were added
}
+// No need to reimplement changedStates() because no relevant commands are
+// added to the command list in render().
+
#endif // HAS_D3D12
diff --git a/examples/quick/scenegraph/rendernode/main.qml b/examples/quick/scenegraph/rendernode/main.qml
index c647aab88d..a91656dfaa 100644
--- a/examples/quick/scenegraph/rendernode/main.qml
+++ b/examples/quick/scenegraph/rendernode/main.qml
@@ -71,9 +71,9 @@ Item {
NumberAnimation { target: rotation; property: "angle"; to: 80; duration: 1000; easing.type: Easing.InOutCubic }
NumberAnimation { target: rotation; property: "angle"; to: -80; duration: 1000; easing.type: Easing.InOutCubic }
NumberAnimation { target: rotation; property: "angle"; to: 0; duration: 1000; easing.type: Easing.InOutCubic }
- NumberAnimation { target: renderer; property: "opacity"; to: 0.5; duration: 1000; easing.type: Easing.InOutCubic }
+ NumberAnimation { target: renderer; property: "opacity"; to: 0.1; duration: 1000; easing.type: Easing.InOutCubic }
PauseAnimation { duration: 1000 }
- NumberAnimation { target: renderer; property: "opacity"; to: 0.8; duration: 1000; easing.type: Easing.InOutCubic }
+ NumberAnimation { target: renderer; property: "opacity"; to: 1.0; duration: 1000; easing.type: Easing.InOutCubic }
ParallelAnimation {
NumberAnimation { target: scale; property: "xScale"; to: 1; duration: 1000; easing.type: Easing.InOutBack }
NumberAnimation { target: scale; property: "yScale"; to: 1; duration: 1000; easing.type: Easing.InOutBack }
diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.cpp b/examples/quick/scenegraph/rendernode/openglrenderer.cpp
index 27712e13b2..3eff70cb42 100644
--- a/examples/quick/scenegraph/rendernode/openglrenderer.cpp
+++ b/examples/quick/scenegraph/rendernode/openglrenderer.cpp
@@ -57,9 +57,6 @@ OpenGLRenderNode::~OpenGLRenderNode()
releaseResources();
}
-// No need to reimplement changedStates() since our rendering is so simple,
-// without involving any state changes.
-
void OpenGLRenderNode::releaseResources()
{
delete m_program;
@@ -84,8 +81,9 @@ void OpenGLRenderNode::init()
static const char *fragmentShaderSource =
"varying lowp vec4 col;\n"
+ "uniform lowp float opacity;\n"
"void main() {\n"
- " gl_FragColor = col;\n"
+ " gl_FragColor = col * opacity;\n"
"}\n";
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
@@ -95,6 +93,7 @@ void OpenGLRenderNode::init()
m_program->link();
m_matrixUniform = m_program->uniformLocation("matrix");
+ m_opacityUniform = m_program->uniformLocation("opacity");
const int VERTEX_SIZE = 6 * sizeof(GLfloat);
@@ -123,6 +122,7 @@ void OpenGLRenderNode::render(const RenderState *state)
m_program->bind();
m_program->setUniformValue(m_matrixUniform, *state->projectionMatrix() * *matrix());
+ m_program->setUniformValue(m_opacityUniform, float(inheritedOpacity()));
m_vbo->bind();
@@ -140,7 +140,15 @@ void OpenGLRenderNode::render(const RenderState *state)
m_program->enableAttributeArray(0);
m_program->enableAttributeArray(1);
+ f->glEnable(GL_BLEND);
+ f->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
f->glDrawArrays(GL_TRIANGLES, 0, 3);
}
+QSGRenderNode::StateFlags OpenGLRenderNode::changedStates() const
+{
+ return BlendState;
+}
+
#endif // QT_NO_OPENGL
diff --git a/examples/quick/scenegraph/rendernode/openglrenderer.h b/examples/quick/scenegraph/rendernode/openglrenderer.h
index 3f38faf458..28d528e617 100644
--- a/examples/quick/scenegraph/rendernode/openglrenderer.h
+++ b/examples/quick/scenegraph/rendernode/openglrenderer.h
@@ -57,6 +57,7 @@ public:
void render(const RenderState *state) override;
void releaseResources() override;
+ StateFlags changedStates() const override;
private:
void init();
@@ -64,6 +65,7 @@ private:
QQuickItem *m_item;
QOpenGLShaderProgram *m_program = nullptr;
int m_matrixUniform;
+ int m_opacityUniform;
QOpenGLBuffer *m_vbo = nullptr;
};
diff --git a/examples/quick/scenegraph/rendernode/shader.hlsl b/examples/quick/scenegraph/rendernode/shader.hlsl
index 8b9b9ff9d8..f300fe7aa5 100644
--- a/examples/quick/scenegraph/rendernode/shader.hlsl
+++ b/examples/quick/scenegraph/rendernode/shader.hlsl
@@ -2,15 +2,16 @@ cbuffer ConstantBuffer : register(b0)
{
float4x4 modelview;
float4x4 projection;
+ float opacity;
};
struct PSInput
{
float4 position : SV_POSITION;
- float4 color : COLOR;
+ float3 color : COLOR;
};
-PSInput VS_Simple(float4 position : POSITION, float4 color : COLOR)
+PSInput VS_Simple(float4 position : POSITION, float3 color : COLOR)
{
PSInput result;
@@ -23,5 +24,5 @@ PSInput VS_Simple(float4 position : POSITION, float4 color : COLOR)
float4 PS_Simple(PSInput input) : SV_TARGET
{
- return input.color;
+ return float4(input.color, 1.0) * opacity;
}