summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2017-06-02 16:19:17 +0200
committerPaul Lemire <paul.lemire@kdab.com>2018-03-19 09:06:35 +0000
commit4b83e2ee155c9ebf71e2fc46ab9abdb40bbb1061 (patch)
treef6d9074e336cce1ded818cdecd14e46c847053c3 /src
parentab046302d593be2bfc368a321417a208d88f53ca (diff)
RenderStates: rework to split node and rendering part
The apply method was removed from GenericState and its subclasses. This allows to keep the GenericStates in the aspect part and let the renderer perform the right calls based on the state class it is provided with. Change-Id: I9c3ac04b4eb489e7443e67615e35e850c0aba07f Task-number: QTBUG-61151 Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp382
-rw-r--r--src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h5
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp6
-rw-r--r--src/render/renderers/opengl/renderstates/renderstateset.cpp266
-rw-r--r--src/render/renderers/opengl/renderstates/renderstateset_p.h17
-rw-r--r--src/render/renderstates/genericstate_p.h6
-rw-r--r--src/render/renderstates/renderstatenode.cpp191
-rw-r--r--src/render/renderstates/renderstates.cpp144
-rw-r--r--src/render/renderstates/renderstates_p.h25
-rw-r--r--src/render/renderstates/statevariant.cpp68
-rw-r--r--src/render/renderstates/statevariant_p.h8
11 files changed, 591 insertions, 527 deletions
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
index df7d61902..2279aeacb 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext.cpp
@@ -41,6 +41,7 @@
#include <Qt3DRender/qgraphicsapifilter.h>
#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qcullface.h>
#include <Qt3DRender/private/renderlogging_p.h>
#include <Qt3DRender/private/shader_p.h>
#include <Qt3DRender/private/material_p.h>
@@ -139,6 +140,192 @@ void copyGLFramebufferDataToImage(QImage &img, const uchar *srcData, uint stride
}
}
+// Render States Helpers
+template<typename GenericState>
+void applyStateHelper(const GenericState *state, SubmissionContext *gc)
+{
+}
+
+template<>
+void applyStateHelper<AlphaFunc>(const AlphaFunc *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->alphaTest(std::get<0>(values), std::get<1>(values));
+}
+
+template<>
+void applyStateHelper<BlendEquationArguments>(const BlendEquationArguments *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ // Un-indexed BlendEquationArguments -> Use normal GL1.0 functions
+ if (std::get<5>(values) < 0) {
+ if (std::get<4>(values)) {
+ gc->openGLContext()->functions()->glEnable(GL_BLEND);
+ gc->openGLContext()->functions()->glBlendFuncSeparate(std::get<0>(values), std::get<1>(values), std::get<2>(values), std::get<3>(values));
+ } else {
+ gc->openGLContext()->functions()->glDisable(GL_BLEND);
+ }
+ }
+ // BlendEquationArguments for a particular Draw Buffer. Different behaviours for
+ // (1) 3.0-3.3: only enablei/disablei supported.
+ // (2) 4.0+: all operations supported.
+ // We just ignore blend func parameter for (1), so no warnings get
+ // printed.
+ else {
+ if (std::get<4>(values)) {
+ gc->enablei(GL_BLEND, std::get<5>(values));
+ if (gc->supportsDrawBuffersBlend()) {
+ gc->blendFuncSeparatei(std::get<5>(values), std::get<0>(values), std::get<1>(values), std::get<2>(values), std::get<3>(values));
+ }
+ } else {
+ gc->disablei(GL_BLEND, std::get<5>(values));
+ }
+ }
+}
+
+template<>
+void applyStateHelper<BlendEquation>(const BlendEquation *state, SubmissionContext *gc)
+{
+ gc->blendEquation(std::get<0>(state->values()));
+}
+
+template<>
+void applyStateHelper<MSAAEnabled>(const MSAAEnabled *state, SubmissionContext *gc)
+{
+ gc->setMSAAEnabled(std::get<0>(state->values()));
+}
+
+
+template<>
+void applyStateHelper<DepthTest>(const DepthTest *state, SubmissionContext *gc)
+{
+ gc->depthTest(std::get<0>(state->values()));
+}
+
+
+template<>
+void applyStateHelper<NoDepthMask>(const NoDepthMask *state, SubmissionContext *gc)
+{
+ gc->depthMask(std::get<0>(state->values()));
+}
+
+
+template<>
+void applyStateHelper<CullFace>(const CullFace *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ if (std::get<0>(values) == QCullFace::NoCulling) {
+ gc->openGLContext()->functions()->glDisable(GL_CULL_FACE);
+ } else {
+ gc->openGLContext()->functions()->glEnable(GL_CULL_FACE);
+ gc->openGLContext()->functions()->glCullFace(std::get<0>(values));
+ }
+}
+
+template<>
+void applyStateHelper<FrontFace>(const FrontFace *state, SubmissionContext *gc)
+{
+ gc->frontFace(std::get<0>(state->values()));
+}
+
+template<>
+void applyStateHelper<ScissorTest>(const ScissorTest *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->openGLContext()->functions()->glEnable(GL_SCISSOR_TEST);
+ gc->openGLContext()->functions()->glScissor(std::get<0>(values), std::get<1>(values), std::get<2>(values), std::get<3>(values));
+}
+
+template<>
+void applyStateHelper<StencilTest>(const StencilTest *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->openGLContext()->functions()->glEnable(GL_STENCIL_TEST);
+ gc->openGLContext()->functions()->glStencilFuncSeparate(GL_FRONT, std::get<0>(values), std::get<1>(values), std::get<2>(values));
+ gc->openGLContext()->functions()->glStencilFuncSeparate(GL_BACK, std::get<3>(values), std::get<4>(values), std::get<5>(values));
+}
+
+template<>
+void applyStateHelper<AlphaCoverage>(const AlphaCoverage *, SubmissionContext *gc)
+{
+ gc->setAlphaCoverageEnabled(true);
+}
+
+template<>
+void applyStateHelper<PointSize>(const PointSize *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->pointSize(std::get<0>(values), std::get<1>(values));
+}
+
+
+template<>
+void applyStateHelper<PolygonOffset>(const PolygonOffset *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->openGLContext()->functions()->glEnable(GL_POLYGON_OFFSET_FILL);
+ gc->openGLContext()->functions()->glPolygonOffset(std::get<0>(values), std::get<1>(values));
+}
+
+template<>
+void applyStateHelper<ColorMask>(const ColorMask *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->openGLContext()->functions()->glColorMask(std::get<0>(values), std::get<1>(values), std::get<2>(values), std::get<3>(values));
+}
+
+template<>
+void applyStateHelper<ClipPlane>(const ClipPlane *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->enableClipPlane(std::get<0>(values));
+ gc->setClipPlane(std::get<0>(values), std::get<1>(values), std::get<2>(values));
+}
+
+template<>
+void applyStateHelper<SeamlessCubemap>(const SeamlessCubemap *, SubmissionContext *gc)
+{
+ gc->setSeamlessCubemap(true);
+}
+
+template<>
+void applyStateHelper<StencilOp>(const StencilOp *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->openGLContext()->functions()->glStencilOpSeparate(GL_FRONT, std::get<0>(values), std::get<1>(values), std::get<2>(values));
+ gc->openGLContext()->functions()->glStencilOpSeparate(GL_BACK, std::get<3>(values), std::get<4>(values), std::get<5>(values));
+}
+
+template<>
+void applyStateHelper<StencilMask>(const StencilMask *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ gc->openGLContext()->functions()->glStencilMaskSeparate(GL_FRONT, std::get<0>(values));
+ gc->openGLContext()->functions()->glStencilMaskSeparate(GL_BACK, std::get<1>(values));
+}
+
+template<>
+void applyStateHelper<Dithering>(const Dithering *, SubmissionContext *gc)
+{
+ gc->openGLContext()->functions()->glEnable(GL_DITHER);
+}
+
+#ifndef GL_LINE_SMOOTH
+#define GL_LINE_SMOOTH 0x0B20
+#endif
+
+template<>
+void applyStateHelper<LineWidth>(const LineWidth *state, SubmissionContext *gc)
+{
+ const auto values = state->values();
+ if (std::get<1>(values))
+ gc->openGLContext()->functions()->glEnable(GL_LINE_SMOOTH);
+ else
+ gc->openGLContext()->functions()->glDisable(GL_LINE_SMOOTH);
+
+ gc->openGLContext()->functions()->glLineWidth(std::get<0>(values));
+}
+
} // anonymous
unsigned int nextFreeContextId()
@@ -789,7 +976,7 @@ void SubmissionContext::setCurrentStateSet(RenderStateSet *ss)
if (ss == m_stateSet)
return;
if (ss)
- ss->apply(this);
+ applyStateSet(ss);
m_stateSet = ss;
}
@@ -798,6 +985,199 @@ RenderStateSet *SubmissionContext::currentStateSet() const
return m_stateSet;
}
+void SubmissionContext::applyState(const StateVariant &stateVariant)
+{
+ switch (stateVariant.type) {
+
+ case AlphaCoverageStateMask: {
+ applyStateHelper<AlphaCoverage>(static_cast<const AlphaCoverage *>(stateVariant.constState()), this);
+ break;
+ }
+ case AlphaTestMask: {
+ applyStateHelper<AlphaFunc>(static_cast<const AlphaFunc *>(stateVariant.constState()), this);
+ break;
+ }
+ case BlendStateMask: {
+ applyStateHelper<BlendEquation>(static_cast<const BlendEquation *>(stateVariant.constState()), this);
+ break;
+ }
+ case BlendEquationArgumentsMask: {
+ applyStateHelper<BlendEquationArguments>(static_cast<const BlendEquationArguments *>(stateVariant.constState()), this);
+ break;
+ }
+ case MSAAEnabledStateMask: {
+ applyStateHelper<MSAAEnabled>(static_cast<const MSAAEnabled *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case CullFaceStateMask: {
+ applyStateHelper<CullFace>(static_cast<const CullFace *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case DepthWriteStateMask: {
+ applyStateHelper<NoDepthMask>(static_cast<const NoDepthMask *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case DepthTestStateMask: {
+ applyStateHelper<DepthTest>(static_cast<const DepthTest *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case FrontFaceStateMask: {
+ applyStateHelper<FrontFace>(static_cast<const FrontFace *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case ScissorStateMask: {
+ applyStateHelper<ScissorTest>(static_cast<const ScissorTest *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case StencilTestStateMask: {
+ applyStateHelper<StencilTest>(static_cast<const StencilTest *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case PointSizeMask: {
+ applyStateHelper<PointSize>(static_cast<const PointSize *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case PolygonOffsetStateMask: {
+ applyStateHelper<PolygonOffset>(static_cast<const PolygonOffset *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case ColorStateMask: {
+ applyStateHelper<ColorMask>(static_cast<const ColorMask *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case ClipPlaneMask: {
+ applyStateHelper<ClipPlane>(static_cast<const ClipPlane *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case SeamlessCubemapMask: {
+ applyStateHelper<SeamlessCubemap>(static_cast<const SeamlessCubemap *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case StencilOpMask: {
+ applyStateHelper<StencilOp>(static_cast<const StencilOp *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case StencilWriteStateMask: {
+ applyStateHelper<StencilMask>(static_cast<const StencilMask *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case DitheringStateMask: {
+ applyStateHelper<Dithering>(static_cast<const Dithering *>(stateVariant.constState()), this);
+ break;
+ }
+
+ case LineWidthMask: {
+ applyStateHelper<LineWidth>(static_cast<const LineWidth *>(stateVariant.constState()), this);
+ break;
+ }
+ default:
+ Q_UNREACHABLE();
+ }
+}
+
+void SubmissionContext::resetMasked(qint64 maskOfStatesToReset)
+{
+ // TO DO -> Call gcHelper methods instead of raw GL
+ // QOpenGLFunctions shouldn't be used here directly
+ QOpenGLFunctions *funcs = m_gl->functions();
+
+ if (maskOfStatesToReset & ScissorStateMask)
+ funcs->glDisable(GL_SCISSOR_TEST);
+
+ if (maskOfStatesToReset & BlendStateMask)
+ funcs->glDisable(GL_BLEND);
+
+ if (maskOfStatesToReset & StencilWriteStateMask)
+ funcs->glStencilMask(0);
+
+ if (maskOfStatesToReset & StencilTestStateMask)
+ funcs->glDisable(GL_STENCIL_TEST);
+
+ if (maskOfStatesToReset & DepthTestStateMask)
+ funcs->glDisable(GL_DEPTH_TEST);
+
+ if (maskOfStatesToReset & DepthWriteStateMask)
+ funcs->glDepthMask(GL_TRUE); // reset to default
+
+ if (maskOfStatesToReset & FrontFaceStateMask)
+ funcs->glFrontFace(GL_CCW); // reset to default
+
+ if (maskOfStatesToReset & CullFaceStateMask)
+ funcs->glDisable(GL_CULL_FACE);
+
+ if (maskOfStatesToReset & DitheringStateMask)
+ funcs->glDisable(GL_DITHER);
+
+ if (maskOfStatesToReset & AlphaCoverageStateMask)
+ setAlphaCoverageEnabled(false);
+
+ if (maskOfStatesToReset & PointSizeMask)
+ pointSize(false, 1.0f); // reset to default
+
+ if (maskOfStatesToReset & PolygonOffsetStateMask)
+ funcs->glDisable(GL_POLYGON_OFFSET_FILL);
+
+ if (maskOfStatesToReset & ColorStateMask)
+ funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+
+ if (maskOfStatesToReset & ClipPlaneMask) {
+ GLint max = maxClipPlaneCount();
+ for (GLint i = 0; i < max; ++i)
+ disableClipPlane(i);
+ }
+
+ if (maskOfStatesToReset & SeamlessCubemapMask)
+ setSeamlessCubemap(false);
+
+ if (maskOfStatesToReset & StencilOpMask)
+ funcs->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ if (maskOfStatesToReset & LineWidthMask)
+ funcs->glLineWidth(1.0f);
+}
+
+void SubmissionContext::applyStateSet(RenderStateSet *ss)
+{
+ RenderStateSet* previousStates = currentStateSet();
+
+ const StateMaskSet invOurState = ~ss->stateMask();
+ // generate a mask for each set bit in previous, where we do not have
+ // the corresponding bit set.
+
+ StateMaskSet stateToReset = 0;
+ if (previousStates) {
+ stateToReset = previousStates->stateMask() & invOurState;
+ qCDebug(RenderStates) << "previous states " << QString::number(previousStates->stateMask(), 2);
+ }
+ qCDebug(RenderStates) << " current states " << QString::number(ss->stateMask(), 2) << "inverse " << QString::number(invOurState, 2) << " -> states to change: " << QString::number(stateToReset, 2);
+
+ // Reset states that aren't active in the current state set
+ resetMasked(stateToReset);
+
+ // Apply states that weren't in the previous state or that have
+ // different values
+ const QVector<StateVariant> statesToSet = ss->states();
+ for (const StateVariant &ds : statesToSet) {
+ if (previousStates && previousStates->contains(ds))
+ continue;
+ applyState(ds);
+ }
+}
+
void SubmissionContext::clearColor(const QColor &color)
{
if (m_currClearColorValue != color) {
diff --git a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
index 8efdcbc63..2881812e5 100644
--- a/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
+++ b/src/render/renderers/opengl/graphicshelpers/submissioncontext_p.h
@@ -79,6 +79,7 @@ class AttachmentPack;
class Attribute;
class Buffer;
class ShaderManager;
+struct StateVariant;
enum TextureScope
{
@@ -152,6 +153,10 @@ public:
// RenderState
void setCurrentStateSet(RenderStateSet* ss);
RenderStateSet *currentStateSet() const;
+ void applyState(const StateVariant &state);
+
+ void resetMasked(qint64 maskOfStatesToReset);
+ void applyStateSet(RenderStateSet *ss);
// Wrappers
void clearColor(const QColor &color);
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index 2611fb6cc..85ac4d2ec 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -229,9 +229,9 @@ Renderer::Renderer(QRenderAspect::RenderType type)
m_filterCompatibleTechniqueJob->setRenderer(this);
m_defaultRenderStateSet = new RenderStateSet;
- m_defaultRenderStateSet->addState(RenderStateSet::createState<DepthTest>(GL_LESS));
- m_defaultRenderStateSet->addState(RenderStateSet::createState<CullFace>(GL_BACK));
- m_defaultRenderStateSet->addState(RenderStateSet::createState<ColorMask>(true, true, true, true));
+ m_defaultRenderStateSet->addState(StateVariant::createState<DepthTest>(GL_LESS));
+ m_defaultRenderStateSet->addState(StateVariant::createState<CullFace>(GL_BACK));
+ m_defaultRenderStateSet->addState(StateVariant::createState<ColorMask>(true, true, true, true));
}
Renderer::~Renderer()
diff --git a/src/render/renderers/opengl/renderstates/renderstateset.cpp b/src/render/renderers/opengl/renderstates/renderstateset.cpp
index bf84b0e1c..f7fc279a1 100644
--- a/src/render/renderers/opengl/renderstates/renderstateset.cpp
+++ b/src/render/renderers/opengl/renderstates/renderstateset.cpp
@@ -45,50 +45,9 @@
#include <QDebug>
#include <QOpenGLContext>
-#include <Qt3DRender/private/submissioncontext_p.h>
#include <Qt3DRender/private/renderstates_p.h>
#include <Qt3DRender/private/qrenderstate_p.h>
-#include <Qt3DRender/qalphacoverage.h>
-#include <Qt3DRender/qalphatest.h>
-#include <Qt3DRender/private/qalphatest_p.h>
-#include <Qt3DRender/qblendequation.h>
-#include <Qt3DRender/private/qblendequation_p.h>
-#include <Qt3DRender/qblendequationarguments.h>
-#include <Qt3DRender/private/qblendequationarguments_p.h>
-#include <Qt3DRender/qcolormask.h>
-#include <Qt3DRender/private/qcolormask_p.h>
-#include <Qt3DRender/qcullface.h>
-#include <Qt3DRender/private/qcullface_p.h>
-#include <Qt3DRender/qnodepthmask.h>
-#include <Qt3DRender/qdepthtest.h>
-#include <Qt3DRender/private/qdepthtest_p.h>
-#include <Qt3DRender/qdithering.h>
-#include <Qt3DRender/qfrontface.h>
-#include <Qt3DRender/private/qfrontface_p.h>
-#include <Qt3DRender/qpointsize.h>
-#include <Qt3DRender/private/qpointsize_p.h>
-#include <Qt3DRender/qpolygonoffset.h>
-#include <Qt3DRender/private/qpolygonoffset_p.h>
-#include <Qt3DRender/qscissortest.h>
-#include <Qt3DRender/private/qscissortest_p.h>
-#include <Qt3DRender/qstenciltest.h>
-#include <Qt3DRender/private/qstenciltest_p.h>
-#include <Qt3DRender/qstenciltestarguments.h>
-#include <Qt3DRender/private/qstenciltestarguments_p.h>
-#include <Qt3DRender/qclipplane.h>
-#include <Qt3DRender/private/qclipplane_p.h>
-#include <Qt3DRender/qmultisampleantialiasing.h>
-#include <Qt3DRender/qseamlesscubemap.h>
-#include <Qt3DRender/qstenciloperation.h>
-#include <Qt3DRender/private/qstenciloperation_p.h>
-#include <Qt3DRender/qstenciloperationarguments.h>
-#include <Qt3DRender/private/qstenciloperationarguments_p.h>
-#include <Qt3DRender/qstencilmask.h>
-#include <Qt3DRender/private/qstencilmask_p.h>
-#include <Qt3DRender/qlinewidth.h>
-#include <Qt3DRender/private/qlinewidth_p.h>
-
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
@@ -139,33 +98,6 @@ int RenderStateSet::changeCost(RenderStateSet *previousState)
return cost;
}
-void RenderStateSet::apply(SubmissionContext *gc)
-{
- RenderStateSet* previousStates = gc->currentStateSet();
-
- const StateMaskSet invOurState = ~stateMask();
- // generate a mask for each set bit in previous, where we do not have
- // the corresponding bit set.
-
- StateMaskSet stateToReset = 0;
- if (previousStates) {
- stateToReset = previousStates->stateMask() & invOurState;
- qCDebug(RenderStates) << "previous states " << QString::number(previousStates->stateMask(), 2);
- }
- qCDebug(RenderStates) << " current states " << QString::number(stateMask(), 2) << "inverse " << QString::number(invOurState, 2) << " -> states to change: " << QString::number(stateToReset, 2);
-
- // Reset states that aren't active in the current state set
- resetMasked(stateToReset, gc);
-
- // Apply states that weren't in the previous state or that have
- // different values
- for (const StateVariant &ds : qAsConst(m_states)) {
- if (previousStates && previousStates->contains(ds))
- continue;
- ds.apply(gc);
- }
-}
-
StateMaskSet RenderStateSet::stateMask() const
{
return m_stateMask;
@@ -176,67 +108,6 @@ void RenderStateSet::merge(RenderStateSet *other)
m_stateMask |= other->stateMask();
}
-void RenderStateSet::resetMasked(StateMaskSet maskOfStatesToReset, SubmissionContext *gc)
-{
- // TO DO -> Call gcHelper methods instead of raw GL
- // QOpenGLFunctions shouldn't be used here directly
- QOpenGLFunctions *funcs = gc->openGLContext()->functions();
-
- if (maskOfStatesToReset & ScissorStateMask)
- funcs->glDisable(GL_SCISSOR_TEST);
-
- if (maskOfStatesToReset & BlendStateMask)
- funcs->glDisable(GL_BLEND);
-
- if (maskOfStatesToReset & StencilWriteStateMask)
- funcs->glStencilMask(0);
-
- if (maskOfStatesToReset & StencilTestStateMask)
- funcs->glDisable(GL_STENCIL_TEST);
-
- if (maskOfStatesToReset & DepthTestStateMask)
- funcs->glDisable(GL_DEPTH_TEST);
-
- if (maskOfStatesToReset & DepthWriteStateMask)
- funcs->glDepthMask(GL_TRUE); // reset to default
-
- if (maskOfStatesToReset & FrontFaceStateMask)
- funcs->glFrontFace(GL_CCW); // reset to default
-
- if (maskOfStatesToReset & CullFaceStateMask)
- funcs->glDisable(GL_CULL_FACE);
-
- if (maskOfStatesToReset & DitheringStateMask)
- funcs->glDisable(GL_DITHER);
-
- if (maskOfStatesToReset & AlphaCoverageStateMask)
- gc->setAlphaCoverageEnabled(false);
-
- if (maskOfStatesToReset & PointSizeMask)
- gc->pointSize(false, 1.0f); // reset to default
-
- if (maskOfStatesToReset & PolygonOffsetStateMask)
- funcs->glDisable(GL_POLYGON_OFFSET_FILL);
-
- if (maskOfStatesToReset & ColorStateMask)
- funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
- if (maskOfStatesToReset & ClipPlaneMask) {
- GLint max = gc->maxClipPlaneCount();
- for (GLint i = 0; i < max; ++i)
- gc->disableClipPlane(i);
- }
-
- if (maskOfStatesToReset & SeamlessCubemapMask)
- gc->setSeamlessCubemap(false);
-
- if (maskOfStatesToReset & StencilOpMask)
- funcs->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
- if (maskOfStatesToReset & LineWidthMask)
- funcs->glLineWidth(1.0f);
-}
-
bool RenderStateSet::contains(const StateVariant &ds) const
{
// trivial reject using the state mask bits
@@ -250,143 +121,6 @@ bool RenderStateSet::contains(const StateVariant &ds) const
return false;
}
-StateVariant RenderStateSet::initializeStateFromPeer(const Qt3DRender::QRenderStateCreatedChangeBasePtr change)
-{
- switch (change->renderStateType()) {
- case AlphaCoverageStateMask: {
- return RenderStateSet::createState<AlphaCoverage>();
- }
-
- case AlphaTestMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QAlphaTestData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<AlphaFunc>(data.alphaFunction, data.referenceValue);
- }
-
- case BlendStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QBlendEquationData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<BlendEquation>(data.blendFunction);
- }
-
- case BlendEquationArgumentsMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QBlendEquationArgumentsData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<BlendEquationArguments>(
- data.sourceRgb, data.destinationRgb,
- data.sourceAlpha, data.destinationAlpha,
- change->isNodeEnabled(),
- data.bufferIndex);
- }
-
- case MSAAEnabledStateMask: {
- return RenderStateSet::createState<MSAAEnabled>(change->isNodeEnabled());
- }
-
- case CullFaceStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QCullFaceData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<CullFace>(data.mode);
- }
-
- case DepthWriteStateMask: {
- return RenderStateSet::createState<NoDepthMask>(false);
- }
-
- case DepthTestStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QDepthTestData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<DepthTest>(data.depthFunction);
- }
-
- case FrontFaceStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QFrontFaceData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<FrontFace>(data.direction);
- }
-
- case ScissorStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QScissorTestData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<ScissorTest>(data.left, data.bottom,
- data.width, data.height);
- }
-
- case StencilTestStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilTestData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<StencilTest>(data.front.stencilFunction,
- data.front.referenceValue,
- data.front.comparisonMask,
- data.back.stencilFunction,
- data.back.referenceValue,
- data.back.comparisonMask);
- }
-
- case PointSizeMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QPointSizeData>>(change);
- const auto &data = typedChange->data;
- const bool isProgrammable = (data.sizeMode == QPointSize::Programmable);
- return RenderStateSet::createState<PointSize>(isProgrammable, data.value);
- }
-
- case PolygonOffsetStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QPolygonOffsetData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<PolygonOffset>(data.scaleFactor, data.depthSteps);
- }
-
- case ColorStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QColorMaskData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<ColorMask>(data.redMasked, data.greenMasked,
- data.blueMasked, data.alphaMasked);
- }
-
- case ClipPlaneMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QClipPlaneData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<ClipPlane>(data.planeIndex,
- data.normal,
- data.distance);
- }
-
- case SeamlessCubemapMask: {
- return RenderStateSet::createState<SeamlessCubemap>();
- }
-
- case StencilOpMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilOperationData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<StencilOp>(data.front.stencilTestFailureOperation,
- data.front.depthTestFailureOperation,
- data.front.allTestsPassOperation,
- data.back.stencilTestFailureOperation,
- data.back.depthTestFailureOperation,
- data.back.allTestsPassOperation);
- }
-
- case StencilWriteStateMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilMaskData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<StencilMask>(data.frontOutputMask,
- data.backOutputMask);
- }
-
- case LineWidthMask: {
- const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QLineWidthData>>(change);
- const auto &data = typedChange->data;
- return RenderStateSet::createState<LineWidth>(data.value, data.smooth);
- }
-
- // TODO: Fix Dithering state
- case DitheringStateMask:
- default:
- Q_UNREACHABLE();
- return StateVariant();
- }
-}
-
} // namespace Render
} // namespace Qt3DRender
diff --git a/src/render/renderers/opengl/renderstates/renderstateset_p.h b/src/render/renderers/opengl/renderstates/renderstateset_p.h
index 58d46c7a6..09b58b859 100644
--- a/src/render/renderers/opengl/renderstates/renderstateset_p.h
+++ b/src/render/renderers/opengl/renderstates/renderstateset_p.h
@@ -65,7 +65,6 @@ class QRenderState;
namespace Render {
-class SubmissionContext;
class RenderState;
class RenderStateSet
@@ -89,30 +88,18 @@ public:
*/
int changeCost(RenderStateSet* previousState);
- void apply(SubmissionContext *gc);
-
StateMaskSet stateMask() const;
void merge(RenderStateSet *other);
- void resetMasked(StateMaskSet maskOfStatesToReset, SubmissionContext* gc);
-
- template<class State, typename ... Args>
- static StateVariant createState(Args... values)
- {
- State state;
- state.set(values...);
- return StateVariant::fromValue(state);
- }
- static StateVariant initializeStateFromPeer(const Qt3DRender::QRenderStateCreatedChangeBasePtr change);
+ QVector<StateVariant> states() const { return m_states; }
-private:
/**
* @brief contains - check if this set contains a matching piece of state
* @param ds
* @return
*/
bool contains(const StateVariant &ds) const;
-
+private:
StateMaskSet m_stateMask;
QVector<StateVariant> m_states;
};
diff --git a/src/render/renderstates/genericstate_p.h b/src/render/renderstates/genericstate_p.h
index 236d36690..69c3dee15 100644
--- a/src/render/renderstates/genericstate_p.h
+++ b/src/render/renderstates/genericstate_p.h
@@ -78,7 +78,6 @@ class RenderStateImpl
public:
virtual ~RenderStateImpl() {}
- virtual void apply(GraphicsContext* gc) const = 0;
virtual StateMask mask() const = 0;
virtual bool equalTo(const RenderStateImpl &renderState) const = 0;
virtual void updateProperty(const char *name, const QVariant &value);
@@ -110,6 +109,11 @@ public:
return stateMask;
}
+ std::tuple<T ...> values() const
+ {
+ return m_values;
+ }
+
protected:
std::tuple<T ...> m_values;
};
diff --git a/src/render/renderstates/renderstatenode.cpp b/src/render/renderstates/renderstatenode.cpp
index d1698e4b6..52d5e20ce 100644
--- a/src/render/renderstates/renderstatenode.cpp
+++ b/src/render/renderstates/renderstatenode.cpp
@@ -38,13 +38,196 @@
#include <Qt3DRender/qrenderstate.h>
#include <Qt3DRender/private/qrenderstatecreatedchange_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
-#include <Qt3DRender/private/renderstateset_p.h>
+
+#include <Qt3DRender/qalphacoverage.h>
+#include <Qt3DRender/qalphatest.h>
+#include <Qt3DRender/private/qalphatest_p.h>
+#include <Qt3DRender/qblendequation.h>
+#include <Qt3DRender/private/qblendequation_p.h>
+#include <Qt3DRender/qblendequationarguments.h>
+#include <Qt3DRender/private/qblendequationarguments_p.h>
+#include <Qt3DRender/qcolormask.h>
+#include <Qt3DRender/private/qcolormask_p.h>
+#include <Qt3DRender/qcullface.h>
+#include <Qt3DRender/private/qcullface_p.h>
+#include <Qt3DRender/qnodepthmask.h>
+#include <Qt3DRender/qdepthtest.h>
+#include <Qt3DRender/private/qdepthtest_p.h>
+#include <Qt3DRender/qdithering.h>
+#include <Qt3DRender/qfrontface.h>
+#include <Qt3DRender/private/qfrontface_p.h>
+#include <Qt3DRender/qpointsize.h>
+#include <Qt3DRender/private/qpointsize_p.h>
+#include <Qt3DRender/qpolygonoffset.h>
+#include <Qt3DRender/private/qpolygonoffset_p.h>
+#include <Qt3DRender/qscissortest.h>
+#include <Qt3DRender/private/qscissortest_p.h>
+#include <Qt3DRender/qstenciltest.h>
+#include <Qt3DRender/private/qstenciltest_p.h>
+#include <Qt3DRender/qstenciltestarguments.h>
+#include <Qt3DRender/private/qstenciltestarguments_p.h>
+#include <Qt3DRender/qclipplane.h>
+#include <Qt3DRender/private/qclipplane_p.h>
+#include <Qt3DRender/qmultisampleantialiasing.h>
+#include <Qt3DRender/qseamlesscubemap.h>
+#include <Qt3DRender/qstenciloperation.h>
+#include <Qt3DRender/private/qstenciloperation_p.h>
+#include <Qt3DRender/qstenciloperationarguments.h>
+#include <Qt3DRender/private/qstenciloperationarguments_p.h>
+#include <Qt3DRender/qstencilmask.h>
+#include <Qt3DRender/private/qstencilmask_p.h>
+#include <Qt3DRender/qlinewidth.h>
+#include <Qt3DRender/private/qlinewidth_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Render {
+namespace {
+
+StateVariant createStateImplementation(const Qt3DRender::QRenderStateCreatedChangeBasePtr renderStateChange)
+{
+ switch (renderStateChange->renderStateType()) {
+
+ case AlphaCoverageStateMask: {
+ return StateVariant::createState<AlphaCoverage>();
+ }
+
+ case AlphaTestMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QAlphaTestData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<AlphaFunc>(data.alphaFunction, data.referenceValue);
+ }
+
+ case BlendStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QBlendEquationData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<BlendEquation>(data.blendFunction);
+ }
+
+ case BlendEquationArgumentsMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QBlendEquationArgumentsData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<BlendEquationArguments>(
+ data.sourceRgb, data.destinationRgb,
+ data.sourceAlpha, data.destinationAlpha,
+ renderStateChange->isNodeEnabled(),
+ data.bufferIndex);
+ }
+
+ case MSAAEnabledStateMask: {
+ return StateVariant::createState<MSAAEnabled>(renderStateChange->isNodeEnabled());
+ }
+
+ case CullFaceStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QCullFaceData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<CullFace>(data.mode);
+ }
+
+ case DepthWriteStateMask: {
+ return StateVariant::createState<NoDepthMask>(false);
+ }
+
+ case DepthTestStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QDepthTestData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<DepthTest>(data.depthFunction);
+ }
+
+ case FrontFaceStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QFrontFaceData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<FrontFace>(data.direction);
+ }
+
+ case ScissorStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QScissorTestData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<ScissorTest>(data.left, data.bottom,
+ data.width, data.height);
+ }
+
+ case StencilTestStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilTestData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<StencilTest>(data.front.stencilFunction,
+ data.front.referenceValue,
+ data.front.comparisonMask,
+ data.back.stencilFunction,
+ data.back.referenceValue,
+ data.back.comparisonMask);
+ }
+
+ case PointSizeMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QPointSizeData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ const bool isProgrammable = (data.sizeMode == QPointSize::Programmable);
+ return StateVariant::createState<PointSize>(isProgrammable, data.value);
+ }
+
+ case PolygonOffsetStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QPolygonOffsetData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<PolygonOffset>(data.scaleFactor, data.depthSteps);
+ }
+
+ case ColorStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QColorMaskData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<ColorMask>(data.redMasked, data.greenMasked,
+ data.blueMasked, data.alphaMasked);
+ }
+
+ case ClipPlaneMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QClipPlaneData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<ClipPlane>(data.planeIndex,
+ data.normal,
+ data.distance);
+ }
+
+ case SeamlessCubemapMask: {
+ return StateVariant::createState<SeamlessCubemap>();
+ }
+
+ case StencilOpMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilOperationData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<StencilOp>(data.front.stencilTestFailureOperation,
+ data.front.depthTestFailureOperation,
+ data.front.allTestsPassOperation,
+ data.back.stencilTestFailureOperation,
+ data.back.depthTestFailureOperation,
+ data.back.allTestsPassOperation);
+ }
+
+ case StencilWriteStateMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QStencilMaskData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<StencilMask>(data.frontOutputMask,
+ data.backOutputMask);
+ }
+
+ case DitheringStateMask: {
+ return StateVariant::createState<Dithering>();
+ }
+
+ case LineWidthMask: {
+ const auto typedChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChange<QLineWidthData>>(renderStateChange);
+ const auto &data = typedChange->data;
+ return StateVariant::createState<LineWidth>(data.value, data.smooth);
+ }
+
+ default:
+ Q_UNREACHABLE();
+ return StateVariant();
+ }
+}
+
+} // anonymous
+
RenderStateNode::RenderStateNode()
: BackendNode()
{
@@ -59,11 +242,11 @@ void RenderStateNode::cleanup()
{
}
-void RenderStateNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change)
+void RenderStateNode::initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &chang3)
{
cleanup();
- const auto renderStateChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChangeBase>(change);
- m_impl = RenderStateSet::initializeStateFromPeer(renderStateChange);
+ const auto renderStateChange = qSharedPointerCast<Qt3DRender::QRenderStateCreatedChangeBase>(chang3);
+ m_impl = createStateImplementation(renderStateChange);
}
void RenderStateNode::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
diff --git a/src/render/renderstates/renderstates.cpp b/src/render/renderstates/renderstates.cpp
index 4a2ec69b0..d6be80b1c 100644
--- a/src/render/renderstates/renderstates.cpp
+++ b/src/render/renderstates/renderstates.cpp
@@ -60,34 +60,6 @@ void RenderStateImpl::updateProperty(const char *name, const QVariant &value)
Q_UNUSED(value);
}
-void BlendEquationArguments::apply(GraphicsContext* gc) const
-{
- // Un-indexed BlendEquationArguments -> Use normal GL1.0 functions
- if (std::get<5>(m_values) < 0) {
- if (std::get<4>(m_values)) {
- gc->openGLContext()->functions()->glEnable(GL_BLEND);
- gc->openGLContext()->functions()->glBlendFuncSeparate(std::get<0>(m_values), std::get<1>(m_values), std::get<2>(m_values), std::get<3>(m_values));
- } else {
- gc->openGLContext()->functions()->glDisable(GL_BLEND);
- }
- }
- // BlendEquationArguments for a particular Draw Buffer. Different behaviours for
- // (1) 3.0-3.3: only enablei/disablei supported.
- // (2) 4.0+: all operations supported.
- // We just ignore blend func parameter for (1), so no warnings get
- // printed.
- else {
- if (std::get<4>(m_values)) {
- gc->enablei(GL_BLEND, std::get<5>(m_values));
- if (gc->supportsDrawBuffersBlend()) {
- gc->blendFuncSeparatei(std::get<5>(m_values), std::get<0>(m_values), std::get<1>(m_values), std::get<2>(m_values), std::get<3>(m_values));
- }
- } else {
- gc->disablei(GL_BLEND, std::get<5>(m_values));
- }
- }
-}
-
void BlendEquationArguments::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("sourceRgb")) std::get<0>(m_values) = value.toInt();
@@ -98,21 +70,11 @@ void BlendEquationArguments::updateProperty(const char *name, const QVariant &va
else if (name == QByteArrayLiteral("bufferIndex")) std::get<5>(m_values) = value.toInt();
}
-void BlendEquation::apply(GraphicsContext *gc) const
-{
- gc->blendEquation(std::get<0>(m_values));
-}
-
void BlendEquation::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("blendFunction")) std::get<0>(m_values) = value.toInt();
}
-void AlphaFunc::apply(GraphicsContext* gc) const
-{
- gc->alphaTest(std::get<0>(m_values), std::get<1>(m_values));
-}
-
void AlphaFunc::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("alphaFunction"))
@@ -121,73 +83,32 @@ void AlphaFunc::updateProperty(const char *name, const QVariant &value)
std::get<1>(m_values) = value.toFloat();
}
-void MSAAEnabled::apply(GraphicsContext *gc) const
-{
- gc->setMSAAEnabled(std::get<0>(m_values));
-}
-
void MSAAEnabled::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("enabled"))
std::get<0>(m_values) = value.toBool();
}
-void DepthTest::apply(GraphicsContext *gc) const
-{
- gc->depthTest(std::get<0>(m_values));
-}
-
void DepthTest::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("depthFunction")) std::get<0>(m_values) = value.toInt();
}
-void CullFace::apply(GraphicsContext *gc) const
-{
- if (std::get<0>(m_values) == QCullFace::NoCulling) {
- gc->openGLContext()->functions()->glDisable(GL_CULL_FACE);
- } else {
- gc->openGLContext()->functions()->glEnable(GL_CULL_FACE);
- gc->openGLContext()->functions()->glCullFace(std::get<0>(m_values));
- }
-}
-
void CullFace::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("mode")) std::get<0>(m_values) = value.toInt();
}
-void FrontFace::apply(GraphicsContext *gc) const
-{
- gc->frontFace(std::get<0>(m_values));
-}
-
void FrontFace::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("direction")) std::get<0>(m_values) = value.toInt();
}
-void NoDepthMask::apply(GraphicsContext *gc) const
-{
- gc->depthMask(std::get<0>(m_values));
-}
-
void NoDepthMask::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("mask")) std::get<0>(m_values) = value.toBool();
}
-void Dithering::apply(GraphicsContext *gc) const
-{
- gc->openGLContext()->functions()->glEnable(GL_DITHER);
-}
-
-void ScissorTest::apply(GraphicsContext *gc) const
-{
- gc->openGLContext()->functions()->glEnable(GL_SCISSOR_TEST);
- gc->openGLContext()->functions()->glScissor(std::get<0>(m_values), std::get<1>(m_values), std::get<2>(m_values), std::get<3>(m_values));
-}
-
void ScissorTest::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("left")) std::get<0>(m_values) = value.toInt();
@@ -196,13 +117,6 @@ void ScissorTest::updateProperty(const char *name, const QVariant &value)
else if (name == QByteArrayLiteral("height")) std::get<3>(m_values) = value.toInt();
}
-void StencilTest::apply(GraphicsContext *gc) const
-{
- gc->openGLContext()->functions()->glEnable(GL_STENCIL_TEST);
- gc->openGLContext()->functions()->glStencilFuncSeparate(GL_FRONT, std::get<0>(m_values), std::get<1>(m_values), std::get<2>(m_values));
- gc->openGLContext()->functions()->glStencilFuncSeparate(GL_BACK, std::get<3>(m_values), std::get<4>(m_values), std::get<5>(m_values));
-}
-
void StencilTest::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("arguments")) {
@@ -216,39 +130,18 @@ void StencilTest::updateProperty(const char *name, const QVariant &value)
}
}
-void AlphaCoverage::apply(GraphicsContext *gc) const
-{
- gc->setAlphaCoverageEnabled(true);
-}
-
-void PointSize::apply(GraphicsContext *gc) const
-{
- gc->pointSize(std::get<0>(m_values), std::get<1>(m_values));
-}
-
void PointSize::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("sizeMode")) std::get<0>(m_values) = (value.toInt() == QPointSize::Programmable);
else if (name == QByteArrayLiteral("value")) std::get<1>(m_values) = value.toFloat();
}
-void PolygonOffset::apply(GraphicsContext *gc) const
-{
- gc->openGLContext()->functions()->glEnable(GL_POLYGON_OFFSET_FILL);
- gc->openGLContext()->functions()->glPolygonOffset(std::get<0>(m_values), std::get<1>(m_values));
-}
-
void PolygonOffset::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("scaleFactor")) std::get<0>(m_values) = value.toFloat();
else if (name == QByteArrayLiteral("depthSteps")) std::get<1>(m_values) = value.toFloat();
}
-void ColorMask::apply(GraphicsContext *gc) const
-{
- gc->openGLContext()->functions()->glColorMask(std::get<0>(m_values), std::get<1>(m_values), std::get<2>(m_values), std::get<3>(m_values));
-}
-
void ColorMask::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("redMasked")) std::get<0>(m_values) = value.toBool();
@@ -257,12 +150,6 @@ void ColorMask::updateProperty(const char *name, const QVariant &value)
else if (name == QByteArrayLiteral("alphaMasked")) std::get<3>(m_values) = value.toBool();
}
-void ClipPlane::apply(GraphicsContext *gc) const
-{
- gc->enableClipPlane(std::get<0>(m_values));
- gc->setClipPlane(std::get<0>(m_values), std::get<1>(m_values), std::get<2>(m_values));
-}
-
void ClipPlane::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("planeIndex")) std::get<0>(m_values) = value.toInt();
@@ -270,17 +157,6 @@ void ClipPlane::updateProperty(const char *name, const QVariant &value)
else if (name == QByteArrayLiteral("distance")) std::get<2>(m_values) = value.toFloat();
}
-void SeamlessCubemap::apply(GraphicsContext *gc) const
-{
- gc->setSeamlessCubemap(true);
-}
-
-void StencilOp::apply(GraphicsContext *gc) const
-{
- gc->openGLContext()->functions()->glStencilOpSeparate(GL_FRONT, std::get<0>(m_values), std::get<1>(m_values), std::get<2>(m_values));
- gc->openGLContext()->functions()->glStencilOpSeparate(GL_BACK, std::get<3>(m_values), std::get<4>(m_values), std::get<5>(m_values));
-}
-
void StencilOp::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("arguments")) {
@@ -294,32 +170,12 @@ void StencilOp::updateProperty(const char *name, const QVariant &value)
}
}
-void StencilMask::apply(GraphicsContext *gc) const
-{
- gc->openGLContext()->functions()->glStencilMaskSeparate(GL_FRONT, std::get<0>(m_values));
- gc->openGLContext()->functions()->glStencilMaskSeparate(GL_BACK, std::get<1>(m_values));
-}
-
void StencilMask::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("frontOutputMask")) std::get<0>(m_values) = value.toInt();
else if (name == QByteArrayLiteral("backOutputMask")) std::get<1>(m_values) = value.toInt();
}
-#ifndef GL_LINE_SMOOTH
-#define GL_LINE_SMOOTH 0x0B20
-#endif
-
-void LineWidth::apply(GraphicsContext *gc) const
-{
- if (std::get<1>(m_values))
- gc->openGLContext()->functions()->glEnable(GL_LINE_SMOOTH);
- else
- gc->openGLContext()->functions()->glDisable(GL_LINE_SMOOTH);
-
- gc->openGLContext()->functions()->glLineWidth(std::get<0>(m_values));
-}
-
void LineWidth::updateProperty(const char *name, const QVariant &value)
{
if (name == QByteArrayLiteral("value"))
diff --git a/src/render/renderstates/renderstates_p.h b/src/render/renderstates/renderstates_p.h
index c85606f87..eafaeb25f 100644
--- a/src/render/renderstates/renderstates_p.h
+++ b/src/render/renderstates/renderstates_p.h
@@ -62,138 +62,115 @@ namespace Render {
class Q_AUTOTEST_EXPORT BlendEquationArguments : public GenericState<BlendEquationArguments, BlendEquationArgumentsMask, GLenum, GLenum, GLenum, GLenum, bool, int>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT BlendEquation : public GenericState<BlendEquation, BlendStateMask, GLenum>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
-
class Q_AUTOTEST_EXPORT AlphaFunc : public GenericState<AlphaFunc, AlphaTestMask, GLenum, GLclampf>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT MSAAEnabled : public GenericState<MSAAEnabled, MSAAEnabledStateMask, GLboolean>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT DepthTest : public GenericState<DepthTest, DepthTestStateMask, GLenum>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT NoDepthMask : public GenericState<NoDepthMask, DepthWriteStateMask, GLboolean>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT CullFace : public GenericState<CullFace, CullFaceStateMask, GLenum>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT FrontFace : public GenericState<FrontFace, FrontFaceStateMask, GLenum>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT Dithering : public GenericState<Dithering, DitheringStateMask>
{
-public:
- void apply(GraphicsContext *gc) const override;
};
class Q_AUTOTEST_EXPORT ScissorTest : public GenericState<ScissorTest, ScissorStateMask, int, int, int, int>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT StencilTest : public GenericState<StencilTest, StencilTestStateMask, GLenum, int, uint, GLenum, int, uint>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT AlphaCoverage : public GenericState<AlphaCoverage, AlphaCoverageStateMask>
{
-public:
- void apply(GraphicsContext *gc) const override;
};
class Q_AUTOTEST_EXPORT PointSize : public GenericState<PointSize, PointSizeMask, bool, GLfloat>
{
public:
- void apply(GraphicsContext *gc) const override;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT PolygonOffset : public GenericState<PolygonOffset, PolygonOffsetStateMask, GLfloat, GLfloat>
{
public:
- void apply(GraphicsContext *gc) const override;
+
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT ColorMask : public GenericState<ColorMask, ColorStateMask, GLboolean, GLboolean, GLboolean, GLboolean>
{
public:
- void apply(GraphicsContext *gc) const final;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT ClipPlane : public GenericState<ClipPlane, ClipPlaneMask, int, QVector3D, float>
{
public:
- void apply(GraphicsContext *gc) const final;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT SeamlessCubemap : public GenericState<SeamlessCubemap, SeamlessCubemapMask>
{
-public:
- void apply(GraphicsContext *gc) const override;
};
class Q_AUTOTEST_EXPORT StencilOp : public GenericState<StencilOp, StencilOpMask, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum>
{
public:
- void apply(GraphicsContext *gc) const final;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT StencilMask : public GenericState<StencilMask, StencilWriteStateMask, uint, uint>
{
public:
- void apply(GraphicsContext *gc) const final;
void updateProperty(const char *name, const QVariant &value) override;
};
class Q_AUTOTEST_EXPORT LineWidth : public GenericState<LineWidth, LineWidthMask, GLfloat, bool>
{
public:
- void apply(GraphicsContext *gc) const final;
void updateProperty(const char *name, const QVariant &value) override;
};
diff --git a/src/render/renderstates/statevariant.cpp b/src/render/renderstates/statevariant.cpp
index e72262825..8161cba0b 100644
--- a/src/render/renderstates/statevariant.cpp
+++ b/src/render/renderstates/statevariant.cpp
@@ -44,74 +44,6 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Render {
-void StateVariant::apply(GraphicsContext *gc) const
-{
- switch (type) {
- case BlendEquationArgumentsMask:
- data.blendEquationArguments.apply(gc);
- return;
- case BlendStateMask:
- data.blendEquation.apply(gc);
- return;
- case AlphaTestMask:
- data.alphaFunc.apply(gc);
- return;
- case MSAAEnabledStateMask:
- data.msaaEnabled.apply(gc);
- return;
- case DepthTestStateMask:
- data.depthTest.apply(gc);
- return;
- case DepthWriteStateMask:
- data.noDepthMask.apply(gc);
- return;
- case CullFaceStateMask:
- data.cullFace.apply(gc);
- return;
- case FrontFaceStateMask:
- data.frontFace.apply(gc);
- return;
- case DitheringStateMask:
- data.dithering.apply(gc);
- return;
- case ScissorStateMask:
- data.scissorTest.apply(gc);
- return;
- case StencilTestStateMask:
- data.stencilTest.apply(gc);
- return;
- case AlphaCoverageStateMask:
- data.alphaCoverage.apply(gc);
- return;
- case PointSizeMask:
- data.pointSize.apply(gc);
- return;
- case PolygonOffsetStateMask:
- data.polygonOffset.apply(gc);
- return;
- case ColorStateMask:
- data.colorMask.apply(gc);
- return;
- case ClipPlaneMask:
- data.clipPlane.apply(gc);
- return;
- case SeamlessCubemapMask:
- data.seamlessCubemap.apply(gc);
- return;
- case StencilOpMask:
- data.stencilOp.apply(gc);
- return;
- case StencilWriteStateMask:
- data.stencilMask.apply(gc);
- return;
- case LineWidthMask:
- data.lineWidth.apply(gc);
- return;
- default:
- Q_UNREACHABLE();
- }
-}
-
RenderStateImpl *StateVariant::state()
{
switch (type) {
diff --git a/src/render/renderstates/statevariant_p.h b/src/render/renderstates/statevariant_p.h
index 3fc93e7bd..ac3c12682 100644
--- a/src/render/renderstates/statevariant_p.h
+++ b/src/render/renderstates/statevariant_p.h
@@ -107,7 +107,13 @@ struct Q_AUTOTEST_EXPORT StateVariant
}
} data;
- void apply(GraphicsContext *gc) const;
+ template<class State, typename ... Args>
+ static StateVariant createState(Args... values)
+ {
+ State state;
+ state.set(values...);
+ return StateVariant::fromValue(state);
+ }
template<typename GenericState>
static StateVariant fromValue(const GenericState &state)