summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/render/renderstates/qblendstate.cpp74
-rw-r--r--src/render/renderstates/qblendstate.h11
-rw-r--r--src/render/renderstates/renderstates.cpp52
-rw-r--r--src/render/renderstates/renderstates_p.h18
-rw-r--r--src/render/renderstates/renderstateset.cpp11
-rw-r--r--tests/auto/render/renderpass/tst_renderpass.cpp4
6 files changed, 130 insertions, 40 deletions
diff --git a/src/render/renderstates/qblendstate.cpp b/src/render/renderstates/qblendstate.cpp
index 0a27c5b35..a92409118 100644
--- a/src/render/renderstates/qblendstate.cpp
+++ b/src/render/renderstates/qblendstate.cpp
@@ -53,6 +53,8 @@ public:
, m_srcAlpha(QBlendState::Zero)
, m_dstRGB(QBlendState::Zero)
, m_dstAlpha(QBlendState::Zero)
+ , m_enabled(true)
+ , m_bufferIndex(-1)
{
}
@@ -62,6 +64,8 @@ public:
QBlendState::Blending m_srcAlpha;
QBlendState::Blending m_dstRGB;
QBlendState::Blending m_dstAlpha;
+ bool m_enabled;
+ int m_bufferIndex;
};
/*!
@@ -69,6 +73,14 @@ public:
\inmodule Qt3DRender
\since 5.5
\brief Encapsulates blending information.
+
+ OpenGL pre-3.0: Set the same blend state for all draw buffers
+ (one QBlendState)
+ OpenGL 3.0-pre4.0: Set the same blend state for all draw buffers,
+ but can disable blending for particular buffers
+ (one QBlendState for setting glBlendFunc, n QBlendStates
+ for enabling/disabling Draw Buffers)
+ OpenGL 4.0+: Can set blend state individually for each draw buffer.
*/
/*!
@@ -78,6 +90,11 @@ public:
\inqmlmodule Qt3D.Render
\since 5.5
\brief Encapsulates blending information.
+
+ OpenGL pre-3.0: Set the same blend state for all draw buffers
+ OpenGL 3.0-pre4.0: Set the same blend state for all draw buffers,
+ but can disable blending for particular buffers
+ OpenGL 4.0+: Can set blend state individually for each draw buffer.
*/
/*!
@@ -105,6 +122,8 @@ void QBlendState::copy(const QNode *ref)
d_func()->m_srcAlpha = refState->d_func()->m_srcAlpha;
d_func()->m_dstAlpha = refState->d_func()->m_dstAlpha;
d_func()->m_dstRGB = refState->d_func()->m_dstRGB;
+ d_func()->m_enabled = refState->d_func()->m_enabled;
+ d_func()->m_bufferIndex = refState->d_func()->m_bufferIndex;
}
/*!
@@ -235,6 +254,61 @@ void QBlendState::setDstAlpha(QBlendState::Blending dstAlpha)
}
}
+bool QBlendState::enabled() const
+{
+ Q_D(const QBlendState);
+ return d->m_enabled;
+}
+
+void QBlendState::setEnabled(bool enabled)
+{
+ Q_D(QBlendState);
+ if (d->m_enabled != enabled) {
+ d->m_enabled = enabled;
+ emit enabledChanged(enabled);
+ }
+}
+
+/*!
+ \qmlproperty int Qt3D.Render::BlendState::bufferIndex
+
+ Specifies the index of the Draw Buffer that this BlendState applies to.
+ If negative, this will apply to all Draw Buffers.
+ */
+
+/*!
+ \property Qt3DRender::QBlendState::bufferIndex
+
+ Specifies the index of the Draw Buffer that this BlendState applies to.
+ If negative, this will apply to all Draw Buffers.
+ */
+int QBlendState::bufferIndex() const
+{
+ Q_D(const QBlendState);
+ return d->m_bufferIndex;
+}
+
+void QBlendState::setBufferIndex(int bufferIndex)
+{
+ Q_D(QBlendState);
+ if (d->m_bufferIndex != bufferIndex) {
+ bool oldAllBuffers = (d->m_bufferIndex < 0);
+ bool newAllBuffers = (bufferIndex < 0);
+
+ d->m_bufferIndex = bufferIndex;
+ emit bufferIndexChanged(bufferIndex);
+
+ if (oldAllBuffers != newAllBuffers)
+ emit specifiesAllDrawBuffersChanged(newAllBuffers);
+ }
+}
+
+bool QBlendState::specifiesAllDrawBuffers() const
+{
+ Q_D(const QBlendState);
+ return (d->m_bufferIndex < 0);
+}
+
/*!
\class Qt3DRender::QBlendStateSeparate
\inmodule Qt3DRender
diff --git a/src/render/renderstates/qblendstate.h b/src/render/renderstates/qblendstate.h
index 5d9d53787..bacb5eed5 100644
--- a/src/render/renderstates/qblendstate.h
+++ b/src/render/renderstates/qblendstate.h
@@ -53,6 +53,9 @@ class QT3DRENDERSHARED_EXPORT QBlendState : public QRenderState
Q_PROPERTY(Blending srcAlpha READ srcAlpha WRITE setSrcAlpha NOTIFY srcAlphaChanged)
Q_PROPERTY(Blending dstRGB READ dstRGB WRITE setDstRGB NOTIFY dstRGBChanged)
Q_PROPERTY(Blending dstAlpha READ dstAlpha WRITE setDstAlpha NOTIFY dstAlphaChanged)
+ Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+ Q_PROPERTY(bool specifiesAllDrawBuffers READ specifiesAllDrawBuffers NOTIFY specifiesAllDrawBuffersChanged)
+ Q_PROPERTY(int bufferIndex READ bufferIndex WRITE setBufferIndex NOTIFY bufferIndexChanged)
public:
@@ -87,18 +90,26 @@ public:
Blending dstRGB() const;
Blending srcAlpha() const;
Blending dstAlpha() const;
+ bool enabled() const;
+ int bufferIndex() const;
+ bool specifiesAllDrawBuffers() const;
public Q_SLOTS:
void setSrcRGB(Blending srcRGB);
void setDstRGB(Blending dstRGB);
void setSrcAlpha(Blending srcAlpha);
void setDstAlpha(Blending dstAlpha);
+ void setEnabled(bool isEnabled);
+ void setBufferIndex(int index);
Q_SIGNALS:
void srcRGBChanged(Blending srcRGB);
void srcAlphaChanged(Blending srcAlpha);
void dstRGBChanged(Blending dstRGB);
void dstAlphaChanged(Blending dstAlpha);
+ void enabledChanged(bool enabled);
+ void bufferIndexChanged(int index);
+ void specifiesAllDrawBuffersChanged(bool specifyAll);
protected:
void copy(const Qt3DCore::QNode *ref) Q_DECL_OVERRIDE;
diff --git a/src/render/renderstates/renderstates.cpp b/src/render/renderstates/renderstates.cpp
index 204803dc6..d9cbf28a2 100644
--- a/src/render/renderstates/renderstates.cpp
+++ b/src/render/renderstates/renderstates.cpp
@@ -60,18 +60,42 @@ State* getOrCreateImpl(const State& data)
void BlendState::apply(GraphicsContext* gc) const
{
- gc->openGLContext()->functions()->glEnable(GL_BLEND);
- gc->openGLContext()->functions()->glBlendFunc( m_1, m_2 );
+ // Un-indexed BlendState -> Use normal GL1.0 functions
+ if (m_6 < 0) {
+ if (m_5) {
+ gc->openGLContext()->functions()->glEnable(GL_BLEND);
+ gc->openGLContext()->functions()->glBlendFuncSeparate(m_1, m_2, m_3, m_4);
+ } else {
+ gc->openGLContext()->functions()->glDisable(GL_BLEND);
+ }
+ }
+ // BlendState 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 (m_5) {
+ gc->enablei(GL_BLEND, m_6);
+ if (gc->supportsDrawBuffersBlend()) {
+ gc->blendFuncSeparatei(m_6, m_1, m_2, m_3, m_4);
+ }
+ } else {
+ gc->disablei(GL_BLEND, m_6);
+ }
+ }
}
-BlendState *BlendState::getOrCreate(GLenum src, GLenum dst)
+BlendState *BlendState::getOrCreate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha, bool enabled, int buf)
{
- BlendState bs(src, dst);
+ BlendState bs(srcRGB, dstRGB, srcAlpha, dstAlpha, enabled, buf);
return getOrCreateImpl(bs);
}
-BlendState::BlendState(GLenum src, GLenum dst) :
- GenericState2<BlendState, GLenum, GLenum>(src, dst)
+BlendState::BlendState(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha, bool enabled, int buf) :
+ GenericState6<BlendState, GLenum, GLenum, GLenum, GLenum, bool, int>(
+ srcRGB, dstRGB, srcAlpha, dstAlpha, enabled, buf
+ )
{
}
@@ -279,22 +303,6 @@ ColorMask *ColorMask::getOrCreate(GLboolean red, GLboolean green, GLboolean blue
return getOrCreateImpl(ColorMask(red, green, blue, alpha));
}
-void BlendStateSeparate::apply(GraphicsContext *gc) const
-{
- gc->openGLContext()->functions()->glEnable(GL_BLEND);
- gc->openGLContext()->functions()->glBlendFuncSeparate(m_1, m_2, m_3, m_4);
-}
-
-BlendStateSeparate *BlendStateSeparate::getOrCreate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-{
- return getOrCreateImpl(BlendStateSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha));
-}
-
-BlendStateSeparate::BlendStateSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
- : GenericState4<BlendStateSeparate, GLenum, GLenum, GLenum, GLenum>(srcRGB, dstRGB, srcAlpha, dstAlpha)
-{
-}
-
void ClipPlane::apply(GraphicsContext *gc) const
{
gc->enableClipPlane(m_1);
diff --git a/src/render/renderstates/renderstates_p.h b/src/render/renderstates/renderstates_p.h
index e2fada4ea..0951fa4fb 100644
--- a/src/render/renderstates/renderstates_p.h
+++ b/src/render/renderstates/renderstates_p.h
@@ -58,28 +58,16 @@ QT_BEGIN_NAMESPACE
namespace Qt3DRender {
namespace Render {
-class Q_AUTOTEST_EXPORT BlendState : public GenericState2<BlendState, GLenum, GLenum>
+class Q_AUTOTEST_EXPORT BlendState : public GenericState6<BlendState, GLenum, GLenum, GLenum, GLenum, bool, int>
{
public:
virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
virtual StateMaskSet mask() const Q_DECL_OVERRIDE
{ return BlendStateMask; }
- static BlendState *getOrCreate(GLenum src, GLenum dst);
+ static BlendState *getOrCreate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha, bool enabled, int buf);
private:
- BlendState(GLenum src, GLenum dst);
-};
-
-class Q_AUTOTEST_EXPORT BlendStateSeparate : public GenericState4<BlendStateSeparate, GLenum, GLenum, GLenum, GLenum>
-{
-public:
- virtual void apply(GraphicsContext *gc) const Q_DECL_OVERRIDE;
- virtual StateMaskSet mask() const Q_DECL_OVERRIDE
- { return BlendStateMask; }
-
- static BlendStateSeparate *getOrCreate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
-private:
- BlendStateSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+ BlendState(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha, bool enabled, int buf);
};
class Q_AUTOTEST_EXPORT BlendEquation : public GenericState1<BlendEquation, GLenum>
diff --git a/src/render/renderstates/renderstateset.cpp b/src/render/renderstates/renderstateset.cpp
index 1d2520177..608719daf 100644
--- a/src/render/renderstates/renderstateset.cpp
+++ b/src/render/renderstates/renderstateset.cpp
@@ -256,11 +256,18 @@ RenderState *RenderState::getOrCreateBackendState(QRenderState *renderState)
}
case QRenderState::BlendState: {
QBlendState *blendState = static_cast<QBlendState *>(renderState);
- return BlendState::getOrCreate(blendState->srcRGB(), blendState->dstRGB());
+ // just use the same values for RGB and Alpha
+ return BlendState::getOrCreate(blendState->srcRGB(), blendState->dstRGB(),
+ blendState->srcRGB(), blendState->dstRGB(),
+ blendState->enabled(),
+ blendState->bufferIndex());
}
case QRenderState::BlendStateSeparate: {
QBlendState *blendState = static_cast<QBlendState *>(renderState);
- return BlendStateSeparate::getOrCreate(blendState->srcRGB(), blendState->dstRGB(), blendState->srcAlpha(), blendState->dstAlpha());
+ return BlendState::getOrCreate(blendState->srcRGB(), blendState->dstRGB(),
+ blendState->srcAlpha(), blendState->dstAlpha(),
+ blendState->enabled(),
+ blendState->bufferIndex());
}
case QRenderState::CullFace: {
QCullFace *cullFace = static_cast<QCullFace *>(renderState);
diff --git a/tests/auto/render/renderpass/tst_renderpass.cpp b/tests/auto/render/renderpass/tst_renderpass.cpp
index 56123ad25..bddd6a790 100644
--- a/tests/auto/render/renderpass/tst_renderpass.cpp
+++ b/tests/auto/render/renderpass/tst_renderpass.cpp
@@ -118,7 +118,9 @@ private slots:
QBlendState *blendState = new QBlendState;
frontendState = blendState;
- backendState = BlendState::getOrCreate(blendState->srcRGB(), blendState->dstRGB());
+ backendState = BlendState::getOrCreate(blendState->srcRGB(), blendState->dstRGB(),
+ blendState->srcRGB(), blendState->dstRGB(),
+ blendState->enabled(), blendState->bufferIndex());
QTest::newRow("blendstate") << frontendState << backendState;
QColorMask *colorMask = new QColorMask;