From e34ee157384a5a6cce583b4426e923477071bef2 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 11 Jun 2016 16:46:24 +0100 Subject: [PATCH] implement overlay transparency for FillRect --- data/shaders/fillrect.frag | 43 ++++++++++++++++--- src/drawing/engines/opengl/FillRectShader.cpp | 11 +++++ src/drawing/engines/opengl/FillRectShader.h | 4 ++ .../engines/opengl/OpenGLDrawingEngine.cpp | 26 +++++++++-- 4 files changed, 75 insertions(+), 9 deletions(-) diff --git a/data/shaders/fillrect.frag b/data/shaders/fillrect.frag index c233dfb009..7860eaba2f 100644 --- a/data/shaders/fillrect.frag +++ b/data/shaders/fillrect.frag @@ -1,13 +1,23 @@ #version 330 -uniform ivec4 uClip; -uniform int uFlags; -uniform vec4 uColour[2]; +uniform ivec2 uScreenSize; +uniform ivec4 uClip; +uniform int uFlags; +uniform vec4 uColour[2]; +uniform sampler2D uSourceFramebuffer; +uniform ivec4 uBounds; in vec2 fPosition; layout (location = 0) out vec4 oColour; +float getluma(vec3 colour) +{ + return (colour.r * 0.2126) + + (colour.g * 0.7152) + + (colour.b * 0.0722); +} + void main() { if (fPosition.x < uClip.x || fPosition.x > uClip.z || @@ -16,13 +26,36 @@ void main() discard; } + vec4 targetColour; int posSum = int(fPosition.x) + int(fPosition.y); if ((posSum % 2) == 0) { - oColour = uColour[0]; + targetColour = uColour[0]; } else { - oColour = uColour[1]; + targetColour = uColour[1]; + } + + if ((uFlags & 1) != 0) + { + vec2 textureCoordinates = (fPosition / vec2(uScreenSize)) * vec2(1, -1); + vec4 sourceColour = texture(uSourceFramebuffer, textureCoordinates); + + float luma = getluma(sourceColour.rgb); + sourceColour = vec4(vec3(luma), 1); + + if (luma < 0.5) + { + oColour = 2.0 * sourceColour * targetColour; + } + else + { + oColour = 1.0 - 2.0 * (1.0 - sourceColour) * (1.0 - targetColour); + } + } + else + { + oColour = targetColour; } } diff --git a/src/drawing/engines/opengl/FillRectShader.cpp b/src/drawing/engines/opengl/FillRectShader.cpp index 417a35cb2e..7e8cd654a9 100644 --- a/src/drawing/engines/opengl/FillRectShader.cpp +++ b/src/drawing/engines/opengl/FillRectShader.cpp @@ -17,6 +17,7 @@ #ifndef DISABLE_OPENGL #include "FillRectShader.h" +#include "OpenGLFramebuffer.h" FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") { @@ -32,6 +33,9 @@ FillRectShader::FillRectShader() : OpenGLShaderProgram("fillrect") glBindVertexArray(_vao); glEnableVertexAttribArray(vIndex); glVertexAttribIPointer(vIndex, 1, GL_INT, 0, 0); + + Use(); + SetFlags(0); } FillRectShader::~FillRectShader() @@ -79,6 +83,13 @@ void FillRectShader::SetColour(int index, vec4f colour) glUniform4f(uColour[index], colour.r, colour.g, colour.b, colour.a); } +void FillRectShader::SetSourceFramebuffer(GLuint texture) +{ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + glUniform1i(uSourceFramebuffer, 0); +} + void FillRectShader::Draw(sint32 left, sint32 top, sint32 right, sint32 bottom) { SetBounds(left, top, right, bottom); diff --git a/src/drawing/engines/opengl/FillRectShader.h b/src/drawing/engines/opengl/FillRectShader.h index c47e9a9315..d96c33c705 100644 --- a/src/drawing/engines/opengl/FillRectShader.h +++ b/src/drawing/engines/opengl/FillRectShader.h @@ -19,6 +19,8 @@ #include "GLSLTypes.h" #include "OpenGLShaderProgram.h" +class OpenGLFramebuffer; + class FillRectShader : public OpenGLShaderProgram { private: @@ -27,6 +29,7 @@ private: GLuint uBounds; GLuint uFlags; GLuint uColour[2]; + GLuint uSourceFramebuffer; GLuint vIndex; @@ -42,6 +45,7 @@ public: void SetBounds(sint32 left, sint32 top, sint32 right, sint32 bottom); void SetFlags(uint32 flags); void SetColour(int index, vec4f colour); + void SetSourceFramebuffer(GLuint texture); void Draw(sint32 left, sint32 top, sint32 right, sint32 bottom); diff --git a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp index 6f03fa3f07..7059dac76a 100644 --- a/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp +++ b/src/drawing/engines/opengl/OpenGLDrawingEngine.cpp @@ -281,7 +281,7 @@ public: for (int i = 0; i < 256; i++) { SDL_Color colour = palette[i]; - colour.a = 255; + colour.a = i == 0 ? 0 : 255; Palette[i] = colour; GLPalette[i] = { colour.r / 255.0f, @@ -371,6 +371,12 @@ public: return &_bitsDPI; } + GLuint SwapCopyReturningSourceTexture() + { + _swapFramebuffer->SwapCopy(); + return _swapFramebuffer->GetSourceTexture(); + } + private: void ConfigureBits(uint32 width, uint32 height, uint32 pitch) { @@ -486,6 +492,9 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint if (colour & 0x1000000) { paletteColour[1].a = 0; + + _fillRectShader->Use(); + _fillRectShader->SetFlags(0); } else if (colour & 0x2000000) { @@ -498,11 +507,20 @@ void OpenGLDrawingContext::FillRect(uint32 colour, sint32 left, sint32 top, sint paletteColour[0].r = transformColour.r; paletteColour[0].g = transformColour.g; paletteColour[0].b = transformColour.b; - paletteColour[0].a = 0.5f; + paletteColour[0].a = 1; paletteColour[1] = paletteColour[0]; + + GLuint srcTexture = _engine->SwapCopyReturningSourceTexture(); + _fillRectShader->Use(); + _fillRectShader->SetFlags(1); + _fillRectShader->SetSourceFramebuffer(srcTexture); + } + else + { + _fillRectShader->Use(); + _fillRectShader->SetFlags(0); } - _fillRectShader->Use(); _fillRectShader->SetScreenSize(gScreenWidth, gScreenHeight); _fillRectShader->SetColour(0, paletteColour[0]); _fillRectShader->SetColour(1, paletteColour[1]); @@ -726,7 +744,7 @@ void * OpenGLDrawingContext::GetImageAsARGB(uint32 image, uint32 tertiaryColour, *dst++ = colour.r; *dst++ = colour.g; *dst++ = colour.b; - *dst++ = 255; + *dst++ = colour.a; } }