summaryrefslogtreecommitdiffstats
path: root/src/render
diff options
context:
space:
mode:
authorWieland Hagen <wieland.hagen@kdab.com>2016-01-14 18:18:35 +0100
committerWieland Hagen <wieland.hagen@kdab.com>2016-01-15 13:02:47 +0000
commit4a93090a7b51da4a1e9f66d9727003fac0df53ac (patch)
treef0584b66f9b83ff2ed80fec174146d4c491eac63 /src/render
parent0f50b649912d44eb75e37a3f17afcefbec40fba7 (diff)
QBlendState: Target particular Draw Buffers (glBlendFunci())
There are 3 ways blending can be configured, depending on GL version: pre-3.0: Globally 3.0-3.3: Individual GL_BLEND for each Draw Buffer, one glBlendFunc 4.0- : Individual GL_BLEND and glBlendFunci for each DrawBuffer QBlendStates now allow to specify whether the blend state should be enabled or not, and what Draw Buffer it is specifying. Defaults are global and enabled. Removed backend BlendStateSeparate, BlendState is going to handle both calls. Task-number: QTBUG-50005 Change-Id: I0059a53db0d629ef9818d933c3f14e5662c1d3df Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src/render')
-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
5 files changed, 127 insertions, 39 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);