summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/Package_opengl.mk1
-rw-r--r--vcl/inc/openglgdiimpl.hxx9
-rw-r--r--vcl/opengl/gdiimpl.cxx118
-rw-r--r--vcl/opengl/radialGradientFragmentShader.glsl23
4 files changed, 132 insertions, 19 deletions
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index da40d7130939..18c56fcd07b8 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 535bc722a364..f80c9699a403 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 65c4f3089017..744aa7fa541b 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 000000000000..94a86eb9510f
--- /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: */