summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/Package_opengl.mk1
-rw-r--r--vcl/inc/opengl/program.hxx2
-rw-r--r--vcl/opengl/program.cxx19
-rw-r--r--vcl/opengl/replaceColorFragmentShader.glsl25
-rw-r--r--vcl/opengl/salbmp.cxx29
5 files changed, 74 insertions, 2 deletions
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index 98ff78b5d77c..0aa324fc6db7 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -19,6 +19,7 @@ $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
maskFragmentShader.glsl \
maskedTextureFragmentShader.glsl \
radialGradientFragmentShader.glsl \
+ replaceColorFragmentShader.glsl \
solidFragmentShader.glsl \
textureFragmentShader.glsl \
textureVertexShader.glsl \
diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
index 2aeb2fde771b..96fed09ec25c 100644
--- a/vcl/inc/opengl/program.hxx
+++ b/vcl/inc/opengl/program.hxx
@@ -47,9 +47,11 @@ public:
void SetTextureCoord( const GLvoid* pData );
void SetAlphaCoord( const GLvoid* pData );
+ void SetUniform1f( const OString& rName, GLfloat v1 );
void SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 );
void SetUniform1fv( const OString& rName, GLsizei nCount, GLfloat* aValues );
void SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat* aValues );
+ void SetColor( const OString& rName, const Color& rColor );
void SetColor( const OString& rName, SalColor nColor, sal_uInt8 nTransparency );
void SetColorf( const OString& rName, SalColor nColor, double fTransparency );
void SetColorWithIntensity( const OString& rName, const Color& rColor, long nFactor );
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
index 320b06f067a4..8b92c4bebb26 100644
--- a/vcl/opengl/program.cxx
+++ b/vcl/opengl/program.cxx
@@ -126,6 +126,12 @@ GLuint OpenGLProgram::GetUniformLocation( const OString& rName )
return it->second;
}
+void OpenGLProgram::SetUniform1f( const OString& rName, GLfloat v1 )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ glUniform1f( nUniform, v1 );
+}
+
void OpenGLProgram::SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 )
{
GLuint nUniform = GetUniformLocation( rName );
@@ -170,6 +176,19 @@ void OpenGLProgram::SetColorf( const OString& rName, SalColor nColor, double fTr
SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
+void OpenGLProgram::SetColor( const OString& rName, const Color& rColor )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ glUniform4f( nUniform,
+ ((float) rColor.GetRed()) / 255,
+ ((float) rColor.GetGreen()) / 255,
+ ((float) rColor.GetBlue()) / 255,
+ 1.0f - ((float) rColor.GetTransparency()) / 255 );
+
+ if( rColor.GetTransparency() > 0 )
+ SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+}
+
void OpenGLProgram::SetColorWithIntensity( const OString& rName, const Color& rColor, long nFactor )
{
GLuint nUniform = GetUniformLocation( rName );
diff --git a/vcl/opengl/replaceColorFragmentShader.glsl b/vcl/opengl/replaceColorFragmentShader.glsl
new file mode 100644
index 000000000000..7c5b4c5bc7d0
--- /dev/null
+++ b/vcl/opengl/replaceColorFragmentShader.glsl
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+varying vec2 tex_coord;
+uniform sampler2D sampler;
+uniform vec4 search_color;
+uniform vec4 replace_color;
+uniform float epsilon;
+
+void main() {
+ vec4 texel = texture2D(sampler, tex_coord);
+ vec4 diff = clamp(abs(texel - search_color) - epsilon, 0.0, 1.0);
+ float bump = max(0.0, 1.0 - ceil(diff.x + diff.y + diff.z));
+ gl_FragColor = texel + bump * (replace_color - search_color);
+ gl_FragColor.r = 1.0;
+ gl_FragColor.g = 0.0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index 078e050df1e9..94c0c870ae76 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -27,6 +27,7 @@
#include "svdata.hxx"
#include "salgdi.hxx"
+#include "opengl/program.hxx"
#include "opengl/salbmp.hxx"
static bool isValidBitCount( sal_uInt16 nBitCount )
@@ -579,9 +580,33 @@ bool OpenGLSalBitmap::Erase( const ::Color& /*rFillColor*/ )
return false;
}
-bool OpenGLSalBitmap::Replace( const Color& /*rSearchColor*/, const Color& /*rReplaceColor*/, sal_uLong /*nTol*/ )
+bool OpenGLSalBitmap::Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol )
{
- return false;
+ OpenGLFramebuffer* pFramebuffer;
+ OpenGLProgram* pProgram;
+
+ GetTexture();
+ makeCurrent();
+ pProgram = mpContext->UseProgram( "textureVertexShader",
+ "replaceColorFragmentShader" );
+ if( !pProgram )
+ return false;
+
+ OpenGLTexture aNewTex = OpenGLTexture( mnWidth, mnHeight );
+ pFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
+
+ pProgram->SetTexture( "sampler", maTexture );
+ pProgram->SetColor( "search_color", rSearchColor );
+ pProgram->SetColor( "replace_color", rReplaceColor );
+ pProgram->SetUniform1f( "epsilon", nTol / 255.0f );
+ pProgram->DrawTexture( maTexture );
+ pProgram->Clean();
+
+ mpContext->ReleaseFramebuffer( pFramebuffer );
+ maTexture = aNewTex;
+
+ CHECK_GL_ERROR();
+ return true;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */