1 | // Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB). |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "renderstatenode_p.h" |
5 | #include <Qt3DRender/qrenderstate.h> |
6 | |
7 | #include <Qt3DRender/qalphacoverage.h> |
8 | #include <Qt3DRender/qalphatest.h> |
9 | #include <Qt3DRender/private/qalphatest_p.h> |
10 | #include <Qt3DRender/qblendequation.h> |
11 | #include <Qt3DRender/private/qblendequation_p.h> |
12 | #include <Qt3DRender/qblendequationarguments.h> |
13 | #include <Qt3DRender/private/qblendequationarguments_p.h> |
14 | #include <Qt3DRender/qcolormask.h> |
15 | #include <Qt3DRender/private/qcolormask_p.h> |
16 | #include <Qt3DRender/qcullface.h> |
17 | #include <Qt3DRender/private/qcullface_p.h> |
18 | #include <Qt3DRender/qnodepthmask.h> |
19 | #include <Qt3DRender/qdepthrange.h> |
20 | #include <Qt3DRender/private/qdepthrange_p.h> |
21 | #include <Qt3DRender/qdepthtest.h> |
22 | #include <Qt3DRender/private/qdepthtest_p.h> |
23 | #include <Qt3DRender/qrastermode.h> |
24 | #include <Qt3DRender/private/qrastermode_p.h> |
25 | #include <Qt3DRender/qdithering.h> |
26 | #include <Qt3DRender/qfrontface.h> |
27 | #include <Qt3DRender/private/qfrontface_p.h> |
28 | #include <Qt3DRender/qpointsize.h> |
29 | #include <Qt3DRender/private/qpointsize_p.h> |
30 | #include <Qt3DRender/qpolygonoffset.h> |
31 | #include <Qt3DRender/private/qpolygonoffset_p.h> |
32 | #include <Qt3DRender/qscissortest.h> |
33 | #include <Qt3DRender/private/qscissortest_p.h> |
34 | #include <Qt3DRender/qstenciltest.h> |
35 | #include <Qt3DRender/private/qstenciltest_p.h> |
36 | #include <Qt3DRender/qstenciltestarguments.h> |
37 | #include <Qt3DRender/private/qstenciltestarguments_p.h> |
38 | #include <Qt3DRender/qclipplane.h> |
39 | #include <Qt3DRender/private/qclipplane_p.h> |
40 | #include <Qt3DRender/qmultisampleantialiasing.h> |
41 | #include <Qt3DRender/qseamlesscubemap.h> |
42 | #include <Qt3DRender/qstenciloperation.h> |
43 | #include <Qt3DRender/private/qstenciloperation_p.h> |
44 | #include <Qt3DRender/qstenciloperationarguments.h> |
45 | #include <Qt3DRender/private/qstenciloperationarguments_p.h> |
46 | #include <Qt3DRender/qstencilmask.h> |
47 | #include <Qt3DRender/private/qstencilmask_p.h> |
48 | #include <Qt3DRender/qlinewidth.h> |
49 | #include <Qt3DRender/private/qlinewidth_p.h> |
50 | |
51 | QT_BEGIN_NAMESPACE |
52 | |
53 | namespace Qt3DRender { |
54 | namespace Render { |
55 | |
56 | namespace { |
57 | |
58 | StateVariant createStateImplementation(const QRenderState *node) |
59 | { |
60 | const QRenderStatePrivate *d = static_cast<const QRenderStatePrivate *>(Qt3DCore::QNodePrivate::get(q: node)); |
61 | switch (d->m_type) { |
62 | |
63 | case AlphaCoverageStateMask: { |
64 | return StateVariant::createState<AlphaCoverage>(); |
65 | } |
66 | |
67 | case AlphaTestMask: { |
68 | const QAlphaTest *alphaTest = static_cast<const QAlphaTest *>(node); |
69 | return StateVariant::createState<AlphaFunc>(values: alphaTest->alphaFunction(), values: alphaTest->referenceValue()); |
70 | } |
71 | |
72 | case BlendStateMask: { |
73 | const QBlendEquation *blendEquation = static_cast<const QBlendEquation *>(node); |
74 | return StateVariant::createState<BlendEquation>(values: blendEquation->blendFunction()); |
75 | } |
76 | |
77 | case BlendEquationArgumentsMask: { |
78 | const QBlendEquationArguments *blendArgs = static_cast<const QBlendEquationArguments *>(node); |
79 | return StateVariant::createState<BlendEquationArguments>( |
80 | values: blendArgs->sourceRgb(), values: blendArgs->destinationRgb(), |
81 | values: blendArgs->sourceAlpha(), values: blendArgs->destinationAlpha(), |
82 | values: blendArgs->isEnabled(), |
83 | values: blendArgs->bufferIndex()); |
84 | } |
85 | |
86 | case MSAAEnabledStateMask: { |
87 | return StateVariant::createState<MSAAEnabled>(values: node->isEnabled()); |
88 | } |
89 | |
90 | case CullFaceStateMask: { |
91 | const QCullFace *cullFace = static_cast<const QCullFace *>(node); |
92 | return StateVariant::createState<CullFace>(values: cullFace->mode()); |
93 | } |
94 | |
95 | case DepthRangeMask: { |
96 | const QDepthRange *depthRange = static_cast<const QDepthRange *>(node); |
97 | return StateVariant::createState<DepthRange>(values: depthRange->nearValue(), values: depthRange->farValue()); |
98 | } |
99 | |
100 | case DepthWriteStateMask: { |
101 | return StateVariant::createState<NoDepthMask>(values: !node->isEnabled()); |
102 | } |
103 | |
104 | case DepthTestStateMask: { |
105 | const QDepthTest *depthTest = static_cast<const QDepthTest *>(node); |
106 | return StateVariant::createState<DepthTest>(values: depthTest->depthFunction()); |
107 | } |
108 | |
109 | case RasterModeMask: { |
110 | const QRasterMode *rasterMode = static_cast<const QRasterMode *>(node); |
111 | return StateVariant::createState<RasterMode>(values: rasterMode->faceMode(), values: rasterMode->rasterMode()); |
112 | } |
113 | |
114 | case FrontFaceStateMask: { |
115 | const QFrontFace *frontFace = static_cast<const QFrontFace *>(node); |
116 | return StateVariant::createState<FrontFace>(values: frontFace->direction()); |
117 | } |
118 | |
119 | case ScissorStateMask: { |
120 | const QScissorTest *scissorTest = static_cast<const QScissorTest *>(node); |
121 | return StateVariant::createState<ScissorTest>(values: scissorTest->left(), values: scissorTest->bottom(), |
122 | values: scissorTest->width(), values: scissorTest->height()); |
123 | } |
124 | |
125 | case StencilTestStateMask: { |
126 | const QStencilTest *stencilTest = static_cast<const QStencilTest *>(node); |
127 | return StateVariant::createState<StencilTest>(values: stencilTest->front()->stencilFunction(), |
128 | values: stencilTest->front()->referenceValue(), |
129 | values: stencilTest->front()->comparisonMask(), |
130 | values: stencilTest->back()->stencilFunction(), |
131 | values: stencilTest->back()->referenceValue(), |
132 | values: stencilTest->back()->comparisonMask()); |
133 | } |
134 | |
135 | case PointSizeMask: { |
136 | const QPointSize *pointSize = static_cast<const QPointSize *>(node); |
137 | const bool isProgrammable = (pointSize->sizeMode() == QPointSize::Programmable); |
138 | return StateVariant::createState<PointSize>(values: isProgrammable, values: pointSize->value()); |
139 | } |
140 | |
141 | case PolygonOffsetStateMask: { |
142 | const QPolygonOffset *offset = static_cast<const QPolygonOffset *>(node); |
143 | return StateVariant::createState<PolygonOffset>(values: offset->scaleFactor(), values: offset->depthSteps()); |
144 | } |
145 | |
146 | case ColorStateMask: { |
147 | const QColorMask *colorMask = static_cast<const QColorMask *>(node); |
148 | return StateVariant::createState<ColorMask>(values: colorMask->isRedMasked(), values: colorMask->isGreenMasked(), |
149 | values: colorMask->isBlueMasked(), values: colorMask->isAlphaMasked()); |
150 | } |
151 | |
152 | case ClipPlaneMask: { |
153 | const QClipPlane *clipPlane = static_cast<const QClipPlane *>(node); |
154 | return StateVariant::createState<ClipPlane>(values: clipPlane->planeIndex(), |
155 | values: clipPlane->normal(), |
156 | values: clipPlane->distance()); |
157 | } |
158 | |
159 | case SeamlessCubemapMask: { |
160 | return StateVariant::createState<SeamlessCubemap>(); |
161 | } |
162 | |
163 | case StencilOpMask: { |
164 | const QStencilOperation *stencilOp = static_cast<const QStencilOperation *>(node); |
165 | return StateVariant::createState<StencilOp>(values: stencilOp->front()->stencilTestFailureOperation(), |
166 | values: stencilOp->front()->depthTestFailureOperation(), |
167 | values: stencilOp->front()->allTestsPassOperation(), |
168 | values: stencilOp->back()->stencilTestFailureOperation(), |
169 | values: stencilOp->back()->depthTestFailureOperation(), |
170 | values: stencilOp->back()->allTestsPassOperation()); |
171 | } |
172 | |
173 | case StencilWriteStateMask: { |
174 | const QStencilMask *stencilMask = static_cast<const QStencilMask *>(node); |
175 | return StateVariant::createState<StencilMask>(values: stencilMask->frontOutputMask(), |
176 | values: stencilMask->backOutputMask()); |
177 | } |
178 | |
179 | case DitheringStateMask: { |
180 | return StateVariant::createState<Dithering>(); |
181 | } |
182 | |
183 | case LineWidthMask: { |
184 | const QLineWidth *lineWidth = static_cast<const QLineWidth *>(node); |
185 | return StateVariant::createState<LineWidth>(values: lineWidth->value(), values: lineWidth->smooth()); |
186 | } |
187 | |
188 | default: |
189 | Q_UNREACHABLE_RETURN(StateVariant()); |
190 | } |
191 | } |
192 | |
193 | } // anonymous |
194 | |
195 | RenderStateNode::RenderStateNode() |
196 | : BackendNode() |
197 | { |
198 | } |
199 | |
200 | RenderStateNode::~RenderStateNode() |
201 | { |
202 | cleanup(); |
203 | } |
204 | |
205 | void RenderStateNode::cleanup() |
206 | { |
207 | } |
208 | |
209 | void RenderStateNode::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime) |
210 | { |
211 | const QRenderState *node = qobject_cast<const QRenderState *>(object: frontEnd); |
212 | if (!node) |
213 | return; |
214 | |
215 | BackendNode::syncFromFrontEnd(frontEnd, firstTime); |
216 | |
217 | if (firstTime) |
218 | m_impl = createStateImplementation(node); |
219 | |
220 | m_impl.state()->updateProperties(node); |
221 | markDirty(changes: AbstractRenderer::AllDirty); |
222 | } |
223 | |
224 | } // namespace Render |
225 | } // namespace Qt3DRender |
226 | |
227 | QT_END_NAMESPACE |
228 | |