diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-18 12:34:53 -0500 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2014-12-02 15:47:17 +0100 |
commit | cce7c7ffd5e71417a1661f0a59af7a1bc6992a4c (patch) | |
tree | d2ed66d304e92b647544225334de813916ae4729 /vcl/opengl | |
parent | 995848cb75977659ea500f4493e5894800da5870 (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.glsl | 27 | ||||
-rw-r--r-- | vcl/opengl/blendedTextureVertexShader.glsl | 22 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 107 |
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 |