vcl/Package_opengl.mk | 1 vcl/inc/openglgdiimpl.hxx | 9 ++ vcl/opengl/gdiimpl.cxx | 111 ++++++++++++++++++++++++++- vcl/opengl/linearGradientFragmentShader.glsl | 23 +++++ 4 files changed, 142 insertions(+), 2 deletions(-)
New commits: commit 2e9e71ca3ece1cba70b6b12d0aa0d67bb0b89caf Author: Louis-Francis Ratté-Boulianne <l...@collabora.com> Date: Tue Nov 11 05:13:40 2014 -0500 vcl: Add initial support for linear gradient with OpenGL Change-Id: Iccc12c94bfd68387dfc0161a5fde4f595edda0e1 diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk index 79dabb7..da40d71 100644 --- a/vcl/Package_opengl.mk +++ b/vcl/Package_opengl.mk @@ -11,6 +11,7 @@ $(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl)) $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\ convolutionFragmentShader.glsl \ + linearGradientFragmentShader.glsl \ maskFragmentShader.glsl \ maskVertexShader.glsl \ maskedTextureFragmentShader.glsl \ diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 6f920e5..c9e8b68 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -25,6 +25,7 @@ #include "opengl/texture.hxx" +#include <tools/poly.hxx> #include <vcl/opengl/OpenGLContext.hxx> class SalFrame; @@ -59,10 +60,16 @@ protected: GLuint mnMaskUniform; GLuint mnMaskColorUniform; + GLuint mnLinearGradientProgram; + GLuint mnLinearGradientStartColorUniform; + GLuint mnLinearGradientEndColorUniform; + GLuint mnLinearGradientTransformUniform; + bool CreateSolidProgram( void ); bool CreateTextureProgram( void ); bool CreateMaskedTextureProgram( void ); bool CreateMaskProgram( void ); + bool CreateLinearGradientProgram( void ); void BeginSolid( SalColor nColor, sal_uInt8 nTransparency ); void BeginSolid( SalColor nColor, double fTransparency ); @@ -75,6 +82,7 @@ protected: void DrawLine( long nX1, long nY1, long nX2, long nY2 ); void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose ); void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); + void DrawConvexPolygon( const Polygon& rPolygon ); void DrawRect( long nX, long nY, long nWidth, long nHeight ); void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon ); @@ -82,6 +90,7 @@ protected: void DrawTexture( GLuint nTexture, const Size& rSize, const SalTwoRect& rPosAry ); void DrawTextureWithMask( GLuint nTexture, GLuint nMask, const Size& rSize, const SalTwoRect& rPosAry ); void DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& rPosAry ); + void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ); protected: // get the width of the device diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 5856fb8..b00fa41 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -51,6 +51,13 @@ ((float) SALCOLOR_BLUE( nColor )) / 255, \ (1.0f - fTransparency) ) +#define glUniformColorIntensity(nUniform, aColor, nFactor) \ + glUniform4f( nUniform, \ + ((float) aColor.GetRed()) * nFactor / 25500.0, \ + ((float) aColor.GetGreen()) * nFactor / 25500.0, \ + ((float) aColor.GetBlue()) * nFactor / 25500.0, \ + 1.0f ) + OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl() : mpFrame(NULL) , mbOffscreen(false) @@ -278,6 +285,20 @@ bool OpenGLSalGraphicsImpl::CreateMaskProgram( void ) return true; } +bool OpenGLSalGraphicsImpl::CreateLinearGradientProgram( void ) +{ + mnLinearGradientProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "linearGradientFragmentShader" ); + if( mnLinearGradientProgram == 0 ) + return false; + + glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" ); + glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" ); + mnLinearGradientStartColorUniform = glGetUniformLocation( mnLinearGradientProgram, "start_color" ); + mnLinearGradientEndColorUniform = glGetUniformLocation( mnLinearGradientProgram, "end_color" ); + mnLinearGradientTransformUniform = glGetUniformLocation( mnLinearGradientProgram, "transform" ); + return true; +} + void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, sal_uInt8 nTransparency ) { if( mnSolidProgram == 0 ) @@ -403,6 +424,25 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin glDisableVertexAttribArray( GL_ATTRIB_POS ); } +void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon ) +{ + sal_uInt16 nPoints = rPolygon.GetSize() - 1; + std::vector<GLfloat> aVertices(nPoints * 2); + sal_uInt32 i, j; + + for( i = 0, j = 0; i < nPoints; i++, j += 2 ) + { + const Point& rPt = rPolygon.GetPoint( i ); + aVertices[j] = (2 * rPt.X()) / GetWidth() - 1.0; + aVertices[j+1] = (2 * (GetHeight() - rPt.Y())) / GetHeight() - 1.0; + } + + glEnableVertexAttribArray( GL_ATTRIB_POS ); + glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] ); + glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints ); + glDisableVertexAttribArray( GL_ATTRIB_POS ); +} + void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeight ) { long nX1( nX ); @@ -550,6 +590,60 @@ void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const S glUseProgram( 0 ); } +void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ) +{ + if( rGradient.GetBorder() >= 100.0 ) + { + // border >= 100%, draw solid rectangle + Color aCol = rGradient.GetStartColor(); + long nF = rGradient.GetStartIntensity(); + BeginSolid( MAKE_SALCOLOR( aCol.GetRed() * nF / 100, + aCol.GetGreen() * nF / 100, + aCol.GetBlue() * nF / 100 ) ); + DrawRect( rRect.Left(), rRect.Top(), rRect.GetWidth(), rRect.GetHeight() ); + EndSolid(); + return; + } + + if( mnLinearGradientProgram == 0 ) + { + if( !CreateLinearGradientProgram() ) + return; + } + + glUseProgram( mnLinearGradientProgram ); + + Color aStartCol = rGradient.GetStartColor(); + Color aEndCol = rGradient.GetEndColor(); + long nFactor = rGradient.GetStartIntensity(); + glUniformColorIntensity( mnLinearGradientStartColorUniform, aStartCol, nFactor ); + nFactor = rGradient.GetEndIntensity(); + glUniformColorIntensity( mnLinearGradientEndColorUniform, aEndCol, nFactor ); + + Rectangle aBoundRect; + Point aCenter; + rGradient.GetBoundRect( rRect, aBoundRect, aCenter ); + aBoundRect.Left()--; + aBoundRect.Top()--; + aBoundRect.Right()++; + aBoundRect.Bottom()++; + Polygon aPoly( aBoundRect ); + aPoly.Rotate( aCenter, rGradient.GetAngle() % 3600 ); + + GLfloat aTexCoord[8] = { 0, 1, 1, 1, 1, 0, 0, 0 }; + GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder()); + aTexCoord[5] = aTexCoord[7] = fMin; + glEnableVertexAttribArray( GL_ATTRIB_TEX ); + glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord ); + + DrawConvexPolygon( aPoly ); + + glDisableVertexAttribArray( GL_ATTRIB_TEX ); + CHECK_GL_ERROR(); + + glUseProgram( 0 ); +} + // draw --> LineColor and FillColor and RasterOp and ClipRegion void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY ) @@ -1080,9 +1174,22 @@ bool OpenGLSalGraphicsImpl::drawAlphaRect( return true; } -bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/, - const Gradient& /*rGradient*/) +bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, + const Gradient& rGradient) { + const Rectangle aBoundRect( rPolyPoly.GetBoundRect() ); + + if( aBoundRect.IsEmpty() ) + return true; + + //TODO: lfrb: some missing transformation with the polygon in outdev + if( rGradient.GetStyle() == GradientStyle_LINEAR ) + { + PreDraw(); + DrawLinearGradient( rGradient, aBoundRect ); + PostDraw(); + return true; + } return false; } diff --git a/vcl/opengl/linearGradientFragmentShader.glsl b/vcl/opengl/linearGradientFragmentShader.glsl new file mode 100644 index 0000000..7b84c06 --- /dev/null +++ b/vcl/opengl/linearGradientFragmentShader.glsl @@ -0,0 +1,23 @@ +/* -*- 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/. + */ + +#version 120 + +uniform vec4 start_color; +uniform vec4 end_color; +uniform mat3x3 transform; +varying vec2 tex_coord; + +void main(void) +{ + gl_FragColor = mix(start_color, end_color, + clamp(tex_coord.t, 0.0, 1.0)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits