summaryrefslogtreecommitdiff
path: root/vcl/opengl
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-18 12:34:53 -0500
committerJan Holesovsky <kendy@collabora.com>2014-12-02 15:47:17 +0100
commitcce7c7ffd5e71417a1661f0a59af7a1bc6992a4c (patch)
treed2ed66d304e92b647544225334de813916ae4729 /vcl/opengl
parent995848cb75977659ea500f4493e5894800da5870 (diff)
vcl: Add support for backend-dependent blending of bitmaps (mask and alpha)
Change-Id: Iba64eb42965c86ca5655b9a105ef3f397e033ecf
Diffstat (limited to 'vcl/opengl')
-rw-r--r--vcl/opengl/blendedTextureFragmentShader.glsl27
-rw-r--r--vcl/opengl/blendedTextureVertexShader.glsl22
-rw-r--r--vcl/opengl/gdiimpl.cxx107
3 files changed, 154 insertions, 2 deletions
diff --git a/vcl/opengl/blendedTextureFragmentShader.glsl b/vcl/opengl/blendedTextureFragmentShader.glsl
new file mode 100644
index 000000000000..b46f6ce5fb9d
--- /dev/null
+++ b/vcl/opengl/blendedTextureFragmentShader.glsl
@@ -0,0 +1,27 @@
+/* -*- 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;
+varying vec2 alpha_coord;
+uniform sampler2D sampler;
+uniform sampler2D mask;
+uniform sampler2D alpha;
+
+void main() {
+ vec4 texel0, texel1, texel2;
+ texel0 = texture2D(sampler, tex_coord);
+ texel1 = texture2D(mask, tex_coord);
+ texel2 = texture2D(alpha, alpha_coord);
+ gl_FragColor = texel0;
+
+ /* Only blend if the the alpha texture wasn't fully transparent */
+ gl_FragColor.a = 1.0 - (1.0 - floor(texel2.r)) * texel1.r;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/blendedTextureVertexShader.glsl b/vcl/opengl/blendedTextureVertexShader.glsl
new file mode 100644
index 000000000000..bc8972c271d0
--- /dev/null
+++ b/vcl/opengl/blendedTextureVertexShader.glsl
@@ -0,0 +1,22 @@
+/* -*- 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/.
+ */
+
+attribute vec4 position;
+attribute vec2 tex_coord_in;
+attribute vec2 alpha_coord_in;
+varying vec2 tex_coord;
+varying vec2 alpha_coord;
+
+void main() {
+ gl_Position = position;
+ tex_coord = tex_coord_in;
+ alpha_coord = alpha_coord_in;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 0000c4071d49..8a3ff9336a1e 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -37,8 +37,9 @@
#include <glm/gtc/type_ptr.hpp>
#include <vector>
-#define GL_ATTRIB_POS 0
-#define GL_ATTRIB_TEX 1
+#define GL_ATTRIB_POS 0
+#define GL_ATTRIB_TEX 1
+#define GL_ATTRIB_TEX2 2
#define glUniformColor(nUniform, nColor, nTransparency) \
glUniform4f( nUniform, \
@@ -86,6 +87,10 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
, mnMaskedTextureProgram(0)
, mnMaskedSamplerUniform(0)
, mnMaskSamplerUniform(0)
+ , mnBlendedTextureProgram(0)
+ , mnBlendedTextureUniform(0)
+ , mnBlendedMaskUniform(0)
+ , mnBlendedAlphaUniform(0)
, mnMaskProgram(0)
, mnMaskUniform(0)
, mnMaskColorUniform(0)
@@ -399,6 +404,23 @@ bool OpenGLSalGraphicsImpl::CreateTransformedMaskedTextureProgram( void )
return true;
}
+bool OpenGLSalGraphicsImpl::CreateBlendedTextureProgram( void )
+{
+ mnBlendedTextureProgram = OpenGLHelper::LoadShaders( "blendedTextureVertexShader", "blendedTextureFragmentShader" );
+ if( mnBlendedTextureProgram == 0 )
+ return false;
+
+ glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_POS, "position" );
+ glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+ glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX2, "alpha_coord_in" );
+ mnBlendedTextureUniform = glGetUniformLocation( mnBlendedTextureProgram, "sampler" );
+ mnBlendedMaskUniform = glGetUniformLocation( mnBlendedTextureProgram, "mask" );
+ mnBlendedAlphaUniform = glGetUniformLocation( mnBlendedTextureProgram, "alpha" );
+
+ CHECK_GL_ERROR();
+ return true;
+}
+
bool OpenGLSalGraphicsImpl::CreateMaskProgram( void )
{
mnMaskProgram = OpenGLHelper::LoadShaders( "maskVertexShader", "maskFragmentShader" );
@@ -846,6 +868,50 @@ void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGL
CHECK_GL_ERROR();
}
+void OpenGLSalGraphicsImpl::DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, OpenGLTexture& rAlpha, const SalTwoRect& rPosAry )
+{
+ GLfloat aTexCoord[8];
+
+ if( mnBlendedTextureProgram == 0 )
+ {
+ if( !CreateBlendedTextureProgram() )
+ return;
+ }
+
+ glUseProgram( mnBlendedTextureProgram );
+ glUniform1i( mnBlendedTextureUniform, 0 );
+ glUniform1i( mnBlendedMaskUniform, 1 );
+ glUniform1i( mnBlendedAlphaUniform, 2 );
+ glActiveTexture( GL_TEXTURE0 );
+ rTexture.Bind();
+ glActiveTexture( GL_TEXTURE1 );
+ rMask.Bind();
+ glActiveTexture( GL_TEXTURE2 );
+ rAlpha.Bind();
+
+ rAlpha.GetCoord( aTexCoord, rPosAry );
+ glEnableVertexAttribArray( GL_ATTRIB_TEX2 );
+ glVertexAttribPointer( GL_ATTRIB_TEX2, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
+
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ DrawTextureRect( rTexture, rPosAry );
+ glDisable( GL_BLEND );
+
+ glDisableVertexAttribArray( GL_ATTRIB_TEX2 );
+
+ glActiveTexture( GL_TEXTURE0 );
+ rTexture.Unbind();
+ glActiveTexture( GL_TEXTURE1 );
+ rMask.Unbind();
+ glActiveTexture( GL_TEXTURE2 );
+ rAlpha.Unbind();
+ glActiveTexture( GL_TEXTURE0 );
+ glUseProgram( 0 );
+
+ CHECK_GL_ERROR();
+}
+
void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, SalColor nMaskColor, const SalTwoRect& pPosAry )
{
if( mnMaskProgram == 0 )
@@ -1472,6 +1538,43 @@ bool OpenGLSalGraphicsImpl::drawEPS(
return false;
}
+bool OpenGLSalGraphicsImpl::blendBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalBitmap )
+{
+ const OpenGLSalBitmap& rBitmap = static_cast<const OpenGLSalBitmap&>(rSalBitmap);
+ OpenGLTexture& rTexture( rBitmap.GetTexture() );
+
+ SAL_INFO( "vcl.opengl", "::blendBitmap" );
+ PreDraw();
+ glEnable( GL_BLEND );
+ glBlendFunc( GL_ZERO, GL_SRC_COLOR );
+ DrawTexture( rTexture, rPosAry );
+ glDisable( GL_BLEND );
+ PostDraw();
+ return true;
+}
+
+bool OpenGLSalGraphicsImpl::blendAlphaBitmap(
+ const SalTwoRect& rPosAry,
+ const SalBitmap& rSalSrcBitmap,
+ const SalBitmap& rSalMaskBitmap,
+ const SalBitmap& rSalAlphaBitmap )
+{
+ const OpenGLSalBitmap& rSrcBitmap = static_cast<const OpenGLSalBitmap&>(rSalSrcBitmap);
+ const OpenGLSalBitmap& rMaskBitmap = static_cast<const OpenGLSalBitmap&>(rSalMaskBitmap);
+ const OpenGLSalBitmap& rAlphaBitmap = static_cast<const OpenGLSalBitmap&>(rSalAlphaBitmap);
+ OpenGLTexture& rTexture( rSrcBitmap.GetTexture() );
+ OpenGLTexture& rMask( rMaskBitmap.GetTexture() );
+ OpenGLTexture& rAlpha( rAlphaBitmap.GetTexture() );
+
+ SAL_INFO( "vcl.opengl", "::blendAlphaBitmap" );
+ PreDraw();
+ DrawBlendedTexture( rTexture, rMask, rAlpha, rPosAry );
+ PostDraw();
+ return true;
+}
+
/** Render bitmap with alpha channel
@param rSourceBitmap