summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
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)