vcl/Package_opengl.mk                        |    1 
 vcl/inc/openglgdiimpl.hxx                    |    9 +-
 vcl/opengl/gdiimpl.cxx                       |  118 ++++++++++++++++++++++-----
 vcl/opengl/radialGradientFragmentShader.glsl |   23 +++++
 4 files changed, 132 insertions(+), 19 deletions(-)

New commits:
commit f0565838389b4a0495450c3aa2ff09b0ca91e143
Author: Louis-Francis Ratté-Boulianne <l...@collabora.com>
Date:   Tue Nov 11 15:54:03 2014 -0500

    vcl: Add support for radial gradients in OpenGL backend
    
    Change-Id: Ie47fb18ae7d5286fe7559c7dffbc54b0856d4d8e

diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index da40d71..18c56fc 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -16,6 +16,7 @@ $(eval $(call 
gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
        maskVertexShader.glsl \
        maskedTextureFragmentShader.glsl \
        maskedTextureVertexShader.glsl \
+       radialGradientFragmentShader.glsl \
        solidFragmentShader.glsl \
        solidVertexShader.glsl \
        textureFragmentShader.glsl \
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 535bc72..f80c969 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -63,13 +63,18 @@ protected:
     GLuint mnLinearGradientProgram;
     GLuint mnLinearGradientStartColorUniform;
     GLuint mnLinearGradientEndColorUniform;
-    GLuint mnLinearGradientTransformUniform;
+
+    GLuint mnRadialGradientProgram;
+    GLuint mnRadialGradientStartColorUniform;
+    GLuint mnRadialGradientEndColorUniform;
+    GLuint mnRadialGradientCenterUniform;
 
     bool CreateSolidProgram( void );
     bool CreateTextureProgram( void );
     bool CreateMaskedTextureProgram( void );
     bool CreateMaskProgram( void );
     bool CreateLinearGradientProgram( void );
+    bool CreateRadialGradientProgram( void );
 
     void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
     void BeginSolid( SalColor nColor, double fTransparency );
@@ -84,6 +89,7 @@ protected:
     void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
     void DrawConvexPolygon( const Polygon& rPolygon );
     void DrawRect( long nX, long nY, long nWidth, long nHeight );
+    void DrawRect( const Rectangle& rRect );
     void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
     void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
     void DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry, bool 
bInverted = false );
@@ -91,6 +97,7 @@ protected:
     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 
);
+    void DrawRadialGradient( 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 752741e..777cfa3 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -75,6 +75,13 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
     , mnMaskProgram(0)
     , mnMaskUniform(0)
     , mnMaskColorUniform(0)
+    , mnLinearGradientProgram(0)
+    , mnLinearGradientStartColorUniform(0)
+    , mnLinearGradientEndColorUniform(0)
+    , mnRadialGradientProgram(0)
+    , mnRadialGradientStartColorUniform(0)
+    , mnRadialGradientEndColorUniform(0)
+    , mnRadialGradientCenterUniform(0)
 {
 }
 
@@ -295,7 +302,20 @@ bool OpenGLSalGraphicsImpl::CreateLinearGradientProgram( 
void )
     glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
     mnLinearGradientStartColorUniform = glGetUniformLocation( 
mnLinearGradientProgram, "start_color" );
     mnLinearGradientEndColorUniform = glGetUniformLocation( 
mnLinearGradientProgram, "end_color" );
-    mnLinearGradientTransformUniform = glGetUniformLocation( 
mnLinearGradientProgram, "transform" );
+    return true;
+}
+
+bool OpenGLSalGraphicsImpl::CreateRadialGradientProgram( void )
+{
+    mnRadialGradientProgram = OpenGLHelper::LoadShaders( 
"textureVertexShader", "radialGradientFragmentShader" );
+    if( mnRadialGradientProgram == 0 )
+        return false;
+
+    glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
+    glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
+    mnRadialGradientStartColorUniform = glGetUniformLocation( 
mnRadialGradientProgram, "start_color" );
+    mnRadialGradientEndColorUniform = glGetUniformLocation( 
mnRadialGradientProgram, "end_color" );
+    mnRadialGradientCenterUniform = glGetUniformLocation( 
mnRadialGradientProgram, "center" );
     return true;
 }
 
@@ -455,6 +475,18 @@ void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, 
long nWidth, long nHeigh
     DrawConvexPolygon( 4, aPoints );
 }
 
+void OpenGLSalGraphicsImpl::DrawRect( const Rectangle& rRect )
+{
+    long nX1( rRect.Left() );
+    long nY1( GetHeight() - rRect.Top() );
+    long nX2( rRect.Right() );
+    long nY2( GetHeight() - rRect.Bottom() );
+    const SalPoint aPoints[] = { { nX1, nY2 }, { nX1, nY1 },
+                                 { nX2, nY1 }, { nX2, nY2 }};
+
+    DrawConvexPolygon( 4, aPoints );
+}
+
 void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* 
pPtAry )
 {
     ::basegfx::B2DPolygon aPolygon;
@@ -601,18 +633,6 @@ void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, 
SalColor nMaskColor, const S
 
 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 )
     {
@@ -632,10 +652,6 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const 
Gradient& rGradient, const
     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 );
 
@@ -653,6 +669,43 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const 
Gradient& rGradient, const
     glUseProgram( 0 );
 }
 
+void OpenGLSalGraphicsImpl::DrawRadialGradient( const Gradient& rGradient, 
const Rectangle& rRect )
+{
+    if( mnRadialGradientProgram == 0 )
+    {
+        if( !CreateRadialGradientProgram() )
+            return;
+    }
+
+    glUseProgram( mnRadialGradientProgram );
+
+    Color aStartCol = rGradient.GetStartColor();
+    Color aEndCol = rGradient.GetEndColor();
+    long nFactor = rGradient.GetStartIntensity();
+    glUniformColorIntensity( mnRadialGradientStartColorUniform, aStartCol, 
nFactor );
+    nFactor = rGradient.GetEndIntensity();
+    glUniformColorIntensity( mnRadialGradientEndColorUniform, aEndCol, nFactor 
);
+
+    Rectangle aRect;
+    Point aCenter;
+    rGradient.GetBoundRect( rRect, aRect, aCenter );
+
+    // adjust coordinates so that radius has distance equals to 1.0
+    double fRadius = aRect.GetWidth() / 2.0f;
+    GLfloat fWidth = rRect.GetWidth() / fRadius;
+    GLfloat fHeight = rRect.GetHeight() / fRadius;
+    glUniform2f( mnRadialGradientCenterUniform, (aCenter.X() -rRect.Left()) / 
fRadius, (aCenter.Y() - rRect.Top()) / fRadius );
+
+    GLfloat aTexCoord[8] = { 0, 0, 0, fHeight, fWidth, fHeight, fWidth, 0 };
+    glEnableVertexAttribArray( GL_ATTRIB_TEX );
+    glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord 
);
+
+    DrawRect( rRect );
+
+    glDisableVertexAttribArray( GL_ATTRIB_TEX );
+    glUseProgram( 0 );
+}
+
 
 // draw --> LineColor and FillColor and RasterOp and ClipRegion
 void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
@@ -1189,11 +1242,33 @@ bool OpenGLSalGraphicsImpl::drawAlphaRect(
 bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
         const Gradient& rGradient)
 {
-    const Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
+    Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
+
+    SAL_INFO( "vcl.opengl", "::drawGradient" );
 
     if( aBoundRect.IsEmpty() )
         return true;
 
+    aBoundRect.Left()--;
+    aBoundRect.Top()--;
+    aBoundRect.Right()++;
+    aBoundRect.Bottom()++;
+
+    // if border >= 100%, draw solid rectangle with start color
+    if( rGradient.GetBorder() >= 100.0 )
+    {
+        Color aCol = rGradient.GetStartColor();
+        long nF = rGradient.GetStartIntensity();
+        PreDraw();
+        BeginSolid( MAKE_SALCOLOR( aCol.GetRed() * nF / 100,
+                                   aCol.GetGreen() * nF / 100,
+                                   aCol.GetBlue() * nF / 100 ) );
+        DrawRect( aBoundRect );
+        EndSolid();
+        PostDraw();
+        return true;
+    }
+
     //TODO: lfrb: some missing transformation with the polygon in outdev
     if( rGradient.GetStyle() == GradientStyle_LINEAR )
     {
@@ -1202,6 +1277,13 @@ bool OpenGLSalGraphicsImpl::drawGradient(const 
tools::PolyPolygon& rPolyPoly,
         PostDraw();
         return true;
     }
+    else if( rGradient.GetStyle() == GradientStyle_RADIAL )
+    {
+        PreDraw();
+        DrawRadialGradient( rGradient, aBoundRect );
+        PostDraw();
+        return true;
+    }
     return false;
 }
 
diff --git a/vcl/opengl/radialGradientFragmentShader.glsl 
b/vcl/opengl/radialGradientFragmentShader.glsl
new file mode 100644
index 0000000..94a86eb
--- /dev/null
+++ b/vcl/opengl/radialGradientFragmentShader.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 vec2   center;
+varying vec2   tex_coord;
+
+void main(void)
+{
+    gl_FragColor = mix(end_color, start_color,
+            clamp(distance(tex_coord, center), 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

Reply via email to