diff --git a/es-core/src/components/ComponentList.cpp b/es-core/src/components/ComponentList.cpp index 4cdaa0aaa..7aa38ed96 100644 --- a/es-core/src/components/ComponentList.cpp +++ b/es-core/src/components/ComponentList.cpp @@ -227,6 +227,7 @@ void ComponentList::render(const Transform4x4f& parentTrans) } } else { + it->component->setOpacity(mOpacity); it->component->render(trans); } } @@ -239,6 +240,8 @@ void ComponentList::render(const Transform4x4f& parentTrans) // Custom rendering. Renderer::setMatrix(trans); + float opacity = mOpacity / 255.0; + // Draw selector bar. if (mFocused) { // Inversion: src * (1 - dst) + dst * 0 = where src = 1 @@ -247,18 +250,21 @@ void ComponentList::render(const Transform4x4f& parentTrans) // (1 - dst) + 0x77 const float selectedRowHeight = getRowHeight(mEntries.at(mCursor).data); - Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, - 0xFFFFFFFF, 0xFFFFFFFF, false, Renderer::Blend::ONE_MINUS_DST_COLOR, - Renderer::Blend::ZERO); - Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, - 0x777777FF, 0x777777FF, false, Renderer::Blend::ONE, - Renderer::Blend::ONE); - // Hack to draw 2px dark on left/right of the bar. - Renderer::drawRect(0.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, - 0x878787FF, 0x878787FF); - Renderer::drawRect(mSize.x() - 2.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, - 0x878787FF, 0x878787FF); + if (opacity == 1) { + Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, + 0xFFFFFFFF, 0xFFFFFFFF, false, opacity, trans, + Renderer::Blend::ONE_MINUS_DST_COLOR, Renderer::Blend::ZERO); + + Renderer::drawRect(0.0f, mSelectorBarOffset, mSize.x(), selectedRowHeight, + 0x777777FF, 0x777777FF, false, opacity, trans, + Renderer::Blend::ONE, Renderer::Blend::ONE); + // Hack to draw 2px dark on left/right of the bar. + Renderer::drawRect(0.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, + 0x878787FF, 0x878787FF, false, opacity, trans); + Renderer::drawRect(mSize.x() - 2.0f, mSelectorBarOffset, 2.0f, selectedRowHeight, + 0x878787FF, 0x878787FF, false, opacity, trans); + } for (auto it = drawAfterCursor.cbegin(); it != drawAfterCursor.cend(); it++) (*it)->render(trans); @@ -271,11 +277,11 @@ void ComponentList::render(const Transform4x4f& parentTrans) // Draw separators. float y = 0; for (unsigned int i = 0; i < mEntries.size(); i++) { - Renderer::drawRect(0.0f, y, mSize.x(), 1.0f, 0xC6C7C6FF, 0xC6C7C6FF); + Renderer::drawRect(0.0f, y, mSize.x(), 1.0f, 0xC6C7C6FF, 0xC6C7C6FF, false, opacity, trans); y += getRowHeight(mEntries.at(i).data); } - Renderer::drawRect(0.0f, y, mSize.x(), 1.0f, 0xC6C7C6FF, 0xC6C7C6FF); + Renderer::drawRect(0.0f, y, mSize.x(), 1.0f, 0xC6C7C6FF, 0xC6C7C6FF, false, opacity, trans); Renderer::popClipRect(); } diff --git a/es-core/src/components/NinePatchComponent.cpp b/es-core/src/components/NinePatchComponent.cpp index 0a42a1d68..b4bf5cecd 100644 --- a/es-core/src/components/NinePatchComponent.cpp +++ b/es-core/src/components/NinePatchComponent.cpp @@ -112,9 +112,12 @@ void NinePatchComponent::render(const Transform4x4f& parentTrans) if (mTexture && mVertices != nullptr) { Renderer::setMatrix(trans); - + if (mOpacity < 255) { + mVertices[0].shaders = Renderer::SHADER_OPACITY; + mVertices[0].opacity = mOpacity / 255.0; + } mTexture->bind(); - Renderer::drawTriangleStrips(&mVertices[0], 6*9); + Renderer::drawTriangleStrips(&mVertices[0], 6*9, trans); } renderChildren(trans); diff --git a/es-core/src/renderers/Renderer.cpp b/es-core/src/renderers/Renderer.cpp index d098286d3..2df832bd5 100644 --- a/es-core/src/renderers/Renderer.cpp +++ b/es-core/src/renderers/Renderer.cpp @@ -169,6 +169,7 @@ namespace Renderer std::vector shaderFiles; shaderFiles.push_back(":/shaders/glsl/desaturate.glsl"); + shaderFiles.push_back(":/shaders/glsl/opacity.glsl"); shaderFiles.push_back(":/shaders/glsl/dim.glsl"); shaderFiles.push_back(":/shaders/glsl/blur_horizontal.glsl"); shaderFiles.push_back(":/shaders/glsl/blur_vertical.glsl"); @@ -344,6 +345,8 @@ namespace Renderer const unsigned int _color, const unsigned int _colorEnd, bool horizontalGradient, + const float _opacity, + const Transform4x4f& _trans, const Blend::Factor _srcBlendFactor, const Blend::Factor _dstBlendFactor) { @@ -360,8 +363,14 @@ namespace Renderer for (int i = 0; i < 4; ++i) vertices[i].pos.round(); - bindTexture(0); - drawTriangleStrips(vertices, 4, Transform4x4f::Identity(), + if (_opacity < 1.0) { + vertices[0].shaders = SHADER_OPACITY; + vertices[0].opacity = _opacity; + } + else { + bindTexture(0); + } + drawTriangleStrips(vertices, 4, _trans, _srcBlendFactor, _dstBlendFactor); } diff --git a/es-core/src/renderers/Renderer.h b/es-core/src/renderers/Renderer.h index 10754193b..39925574e 100644 --- a/es-core/src/renderers/Renderer.h +++ b/es-core/src/renderers/Renderer.h @@ -23,16 +23,18 @@ struct SDL_Window; namespace Renderer { const unsigned int SHADER_DESATURATE = 1; - const unsigned int SHADER_DIM = 2; - const unsigned int SHADER_BLUR_HORIZONTAL = 4; - const unsigned int SHADER_BLUR_VERTICAL = 8; - const unsigned int SHADER_SCANLINES = 16; + const unsigned int SHADER_OPACITY = 2; + const unsigned int SHADER_DIM = 4; + const unsigned int SHADER_BLUR_HORIZONTAL = 8; + const unsigned int SHADER_BLUR_VERTICAL = 16; + const unsigned int SHADER_SCANLINES = 32; struct shaderParameters { std::array textureSize; std::array textureCoordinates; float fragmentSaturation; float fragmentDimValue; + float fragmentOpacity; unsigned int shaderPasses; shaderParameters() @@ -40,6 +42,7 @@ namespace Renderer textureCoordinates({0.0, 0.0, 0.0, 0.0}), fragmentSaturation(1.0), fragmentDimValue(0.4), + fragmentOpacity(1.0), shaderPasses(1) {}; }; @@ -124,6 +127,7 @@ namespace Renderer Vector2f tex; unsigned int col; float saturation = 1.0; + float opacity = 1.0; unsigned int shaders = 0; }; @@ -139,6 +143,8 @@ namespace Renderer const unsigned int _color, const unsigned int _colorEnd, bool horizontalGradient = false, + const float _opacity = 1.0, + const Transform4x4f& _trans = Transform4x4f::Identity(), const Blend::Factor _srcBlendFactor = Blend::SRC_ALPHA, const Blend::Factor _dstBlendFactor = Blend::ONE_MINUS_SRC_ALPHA); SDL_Window* getSDLWindow(); diff --git a/es-core/src/renderers/Renderer_GL21.cpp b/es-core/src/renderers/Renderer_GL21.cpp index e6e915aaf..3e0318cbb 100644 --- a/es-core/src/renderers/Renderer_GL21.cpp +++ b/es-core/src/renderers/Renderer_GL21.cpp @@ -275,6 +275,19 @@ namespace Renderer } } + if (_vertices->shaders & SHADER_OPACITY) { + Shader* runShader = getShaderProgram(SHADER_OPACITY); + if (runShader) { + runShader->activateShaders(); + runShader->setModelViewProjectionMatrix(getProjectionMatrix() * _trans); + _vertices->opacity < 1.0 ? + runShader->setOpacity(_vertices->opacity) : + runShader->setOpacity(_parameters.fragmentOpacity); + GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, _numVertices)); + runShader->deactivateShaders(); + } + } + // Check if any other shaders are set to be used and if so, run them. if (_vertices->shaders & SHADER_DIM) { Shader* runShader = getShaderProgram(SHADER_DIM); diff --git a/es-core/src/renderers/Shader_GL21.cpp b/es-core/src/renderers/Shader_GL21.cpp index 75842cb85..b0f256d48 100644 --- a/es-core/src/renderers/Shader_GL21.cpp +++ b/es-core/src/renderers/Shader_GL21.cpp @@ -21,6 +21,7 @@ namespace Renderer shaderTextureCoord(-1), shaderColor(-1), shaderSaturation(-1), + shaderOpacity(-1), shaderDimValue(-1) { } @@ -106,6 +107,7 @@ namespace Renderer shaderTextureCoord = glGetAttribLocation(mProgramID, "TexCoord"); shaderColor = glGetAttribLocation(mProgramID, "COLOR"); shaderSaturation = glGetUniformLocation(mProgramID, "saturation"); + shaderOpacity = glGetUniformLocation(mProgramID, "opacity"); shaderDimValue = glGetUniformLocation(mProgramID, "dimValue"); } @@ -142,6 +144,12 @@ namespace Renderer GL_CHECK_ERROR(glUniform1f(shaderSaturation, saturation)); } + void Renderer::Shader::setOpacity(GLfloat opacity) + { + if (shaderOpacity != -1) + GL_CHECK_ERROR(glUniform1f(shaderOpacity, opacity)); + } + void Renderer::Shader::setDimValue(GLfloat dimValue) { if (shaderDimValue != -1) diff --git a/es-core/src/renderers/Shader_GL21.h b/es-core/src/renderers/Shader_GL21.h index 0c786c491..b9e199ab1 100644 --- a/es-core/src/renderers/Shader_GL21.h +++ b/es-core/src/renderers/Shader_GL21.h @@ -39,6 +39,7 @@ namespace Renderer void setTextureCoordinates(std::array shaderVec4); void setColor(std::array shaderVec4); void setSaturation(GLfloat saturation); + void setOpacity(GLfloat opacity); void setDimValue(GLfloat dimValue); // Sets the shader program to use the loaded shaders. void activateShaders(); @@ -60,6 +61,7 @@ namespace Renderer GLint shaderTextureCoord; GLint shaderColor; GLint shaderSaturation; + GLint shaderOpacity; GLint shaderDimValue; }; diff --git a/resources/shaders/glsl/opacity.glsl b/resources/shaders/glsl/opacity.glsl new file mode 100644 index 000000000..a63dda14f --- /dev/null +++ b/resources/shaders/glsl/opacity.glsl @@ -0,0 +1,36 @@ +// +// opacity.glsl +// +// Changes the opacity of textures. +// The uniform variable 'opacity' sets the opacity. +// Setting this to the value 0 results in an invisible texture. +// + +#if defined(VERTEX) +// Vertex section of code: + +uniform mat4 MVPMatrix; +varying vec2 vTexCoord; + +void main(void) +{ + vTexCoord = gl_MultiTexCoord0.xy; + gl_Position = MVPMatrix * gl_Vertex; +} + +#elif defined(FRAGMENT) +// Fragment section of code: + +uniform float opacity = 1.0; +uniform sampler2D myTexture; +varying vec2 vTexCoord; + +void main() +{ + vec4 color = texture2D(myTexture, vTexCoord); + float alpha = clamp(color.a-(1-opacity), 0.0, 1.0); + + gl_FragColor = vec4(color.rgb, alpha); +} + +#endif