From 320c08417e2ee50867f33447a892d9235e45fcda Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Mon, 15 Feb 2021 12:49:42 +0000 Subject: [PATCH] Added CullFace and blending modes support Change-Id: Id41f94fbef2798c8125dc4d1e8606cc8c3531282 --- dali/internal/graphics/gles-impl/gles-context.cpp | 76 +++++++- dali/internal/graphics/gles-impl/gles-context.h | 10 + .../graphics/gles-impl/gles-graphics-types.h | 213 +++++++++++++++++++++ 3 files changed, 298 insertions(+), 1 deletion(-) diff --git a/dali/internal/graphics/gles-impl/gles-context.cpp b/dali/internal/graphics/gles-impl/gles-context.cpp index 1522719..3d965ad 100644 --- a/dali/internal/graphics/gles-impl/gles-context.cpp +++ b/dali/internal/graphics/gles-impl/gles-context.cpp @@ -71,6 +71,12 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) mImpl->mNewPipeline = nullptr; } + // Blend state + ResolveBlendState(); + + // Resolve rasterization state + ResolveRasterizationState(); + // Bind textures for(const auto& binding : mImpl->mCurrentTextureBindings) { @@ -104,8 +110,8 @@ void Context::Flush(bool reset, const GLES::DrawCallDescriptor& drawCall) // Resolve topology const auto& ia = mImpl->mCurrentPipeline->GetCreateInfo().inputAssemblyState; - // Resolve drawcall + // Resolve draw call switch(drawCall.type) { case DrawCallDescriptor::Type::DRAW: @@ -171,4 +177,72 @@ void Context::BindPipeline(const GLES::Pipeline* newPipeline) mImpl->mNewPipeline = newPipeline; } +void Context::ResolveBlendState() +{ + const auto& state = mImpl->mCurrentPipeline->GetCreateInfo(); + const auto& bs = state.colorBlendState; + auto& gl = *mImpl->mController.GetGL(); + + // TODO: prevent leaking the state + if(!bs) + { + return; + } + + bs->blendEnable ? gl.Enable(GL_BLEND) : gl.Disable(GL_BLEND); + if(!bs->blendEnable) + { + return; + } + + gl.BlendFunc(GLBlendFunc(bs->srcColorBlendFactor), GLBlendFunc(bs->dstColorBlendFactor)); + + if((GLBlendFunc(bs->srcColorBlendFactor) == GLBlendFunc(bs->srcAlphaBlendFactor)) && + (GLBlendFunc(bs->dstColorBlendFactor) == GLBlendFunc(bs->dstAlphaBlendFactor))) + { + gl.BlendFunc(GLBlendFunc(bs->srcColorBlendFactor), GLBlendFunc(bs->dstColorBlendFactor)); + } + else + { + gl.BlendFuncSeparate(GLBlendFunc(bs->srcColorBlendFactor), + GLBlendFunc(bs->dstColorBlendFactor), + GLBlendFunc(bs->srcAlphaBlendFactor), + GLBlendFunc(bs->dstAlphaBlendFactor)); + } + if(GLBlendOp(bs->colorBlendOp) == GLBlendOp(bs->alphaBlendOp)) + { + gl.BlendEquation(GLBlendOp(bs->colorBlendOp)); + } + else + { + gl.BlendEquationSeparate(GLBlendOp(bs->colorBlendOp), GLBlendOp(bs->alphaBlendOp)); + } +} + +void Context::ResolveRasterizationState() +{ + const auto& state = mImpl->mCurrentPipeline->GetCreateInfo(); + const auto& rs = state.rasterizationState; + auto& gl = *mImpl->mController.GetGL(); + + // TODO: prevent leaking the state + if(!rs) + { + return; + } + + if(rs->cullMode == CullMode::NONE) + { + gl.Disable(GL_CULL_FACE); + } + else + { + gl.Enable(GL_CULL_FACE); + gl.CullFace(GLCullMode(rs->cullMode)); + } + + // TODO: implement polygon mode (fill, line, points) + // seems like we don't support it (no glPolygonMode()) +} + } // namespace Dali::Graphics::GLES diff --git a/dali/internal/graphics/gles-impl/gles-context.h b/dali/internal/graphics/gles-impl/gles-context.h index 9ccca2c..50de21e 100644 --- a/dali/internal/graphics/gles-impl/gles-context.h +++ b/dali/internal/graphics/gles-impl/gles-context.h @@ -93,6 +93,16 @@ public: */ void BindPipeline(const GLES::Pipeline* newPipeline); + /** + * @brief Resolves blend state on the currently attached pipeline + */ + void ResolveBlendState(); + + /** + * @brief Resolves rasterization state on the currently attached pipeline + */ + void ResolveRasterizationState(); + private: struct Impl; std::unique_ptr mImpl; diff --git a/dali/internal/graphics/gles-impl/gles-graphics-types.h b/dali/internal/graphics/gles-impl/gles-graphics-types.h index e7784c6..1ee1885 100644 --- a/dali/internal/graphics/gles-impl/gles-graphics-types.h +++ b/dali/internal/graphics/gles-impl/gles-graphics-types.h @@ -1335,6 +1335,219 @@ struct GLIndexFormat GLenum format{0}; ///< Converted format }; +/** + * @brief Conversion of blending function factor + */ +struct GLBlendFunc +{ + constexpr explicit GLBlendFunc(Graphics::BlendFactor factor) + { + switch(factor) + { + case Graphics::BlendFactor::ZERO: + { + glFactor = GL_ZERO; + break; + } + case Graphics::BlendFactor::ONE: + { + glFactor = GL_ONE; + break; + } + case Graphics::BlendFactor::SRC_COLOR: + { + glFactor = GL_SRC_COLOR; + break; + } + case Graphics::BlendFactor::ONE_MINUS_SRC_COLOR: + { + glFactor = GL_ONE_MINUS_SRC_COLOR; + break; + } + case Graphics::BlendFactor::DST_COLOR: + { + glFactor = GL_DST_COLOR; + break; + } + case Graphics::BlendFactor::ONE_MINUS_DST_COLOR: + { + glFactor = GL_ONE_MINUS_DST_COLOR; + break; + } + case Graphics::BlendFactor::SRC_ALPHA: + { + glFactor = GL_SRC_ALPHA; + break; + } + case Graphics::BlendFactor::ONE_MINUS_SRC_ALPHA: + { + glFactor = GL_ONE_MINUS_SRC_ALPHA; + break; + } + case Graphics::BlendFactor::DST_ALPHA: + { + glFactor = GL_DST_ALPHA; + break; + } + case Graphics::BlendFactor::ONE_MINUS_DST_ALPHA: + { + glFactor = GL_ONE_MINUS_DST_ALPHA; + break; + } + case Graphics::BlendFactor::CONSTANT_COLOR: + { + glFactor = GL_CONSTANT_COLOR; + break; + } + case Graphics::BlendFactor::ONE_MINUS_CONSTANT_COLOR: + { + glFactor = GL_ONE_MINUS_CONSTANT_COLOR; + break; + } + case Graphics::BlendFactor::CONSTANT_ALPHA: + { + glFactor = GL_CONSTANT_ALPHA; + break; + } + case Graphics::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: + { + glFactor = GL_ONE_MINUS_CONSTANT_ALPHA; + break; + } + case Graphics::BlendFactor::SRC_ALPHA_SATURATE: + { + glFactor = GL_SRC_ALPHA_SATURATE; + break; + } + // Below may be unsupported without extension + case Graphics::BlendFactor::SRC1_COLOR: + { + glFactor = 0u; + break; + } + case Graphics::BlendFactor::ONE_MINUS_SRC1_COLOR: + { + glFactor = 0u; + break; + } + case Graphics::BlendFactor::SRC1_ALPHA: + { + glFactor = 0u; + break; + } + case Graphics::BlendFactor::ONE_MINUS_SRC1_ALPHA: + { + glFactor = 0u; + break; + } + } + } + + /** + * @brief Explicit type conversion operator + * @return converted value + */ + constexpr inline operator GLenum() const + { + return glFactor; + } + + GLenum glFactor{0u}; +}; + +/** + * @brief Converts Blend Op to GL + */ +struct GLBlendOp +{ + constexpr explicit GLBlendOp(Graphics::BlendOp blendOp) + { + switch(blendOp) + { + case Graphics::BlendOp::ADD: + { + glBlendOp = GL_FUNC_ADD; + break; + } + case Graphics::BlendOp::SUBTRACT: + { + glBlendOp = GL_FUNC_SUBTRACT; + break; + } + case Graphics::BlendOp::REVERSE_SUBTRACT: + { + glBlendOp = GL_FUNC_REVERSE_SUBTRACT; + break; + } + case Graphics::BlendOp::MIN: + { + glBlendOp = GL_MIN; + break; + } + case Graphics::BlendOp::MAX: + { + glBlendOp = GL_MAX; + break; + } + } + } + + /** + * @brief Explicit type conversion operator + * @return converted value + */ + constexpr inline operator GLenum() const + { + return glBlendOp; + } + + GLenum glBlendOp{0u}; +}; + +/** + * @brief Converts GL cull mode + */ +struct GLCullMode +{ + constexpr explicit GLCullMode(Graphics::CullMode cullMode) + { + switch(cullMode) + { + case Graphics::CullMode::NONE: // this isn't really accepted by GL! + { + glCullMode = GL_NONE; + break; + } + case Graphics::CullMode::FRONT: + { + glCullMode = GL_FRONT; + break; + } + case Graphics::CullMode::BACK: + { + glCullMode = GL_BACK; + break; + } + case Graphics::CullMode::FRONT_AND_BACK: + { + glCullMode = GL_FRONT_AND_BACK; + break; + } + } + } + + /** + * @brief Explicit type conversion operator + * @return converted value + */ + constexpr inline operator GLenum() const + { + return glCullMode; + } + + GLenum glCullMode{0u}; +}; + } // namespace Dali::Graphics::GLES #endif //DALI_GRAPHICS_API_TYPES_H -- 2.7.4