Kaydet (Commit) e1e787d5 authored tarafından Louis-Francis Ratté-Boulianne's avatar Louis-Francis Ratté-Boulianne Kaydeden (comit) Markus Mohrhard

vcl: Add support for radial gradients in OpenGL backend

Change-Id: Ie47fb18ae7d5286fe7559c7dffbc54b0856d4d8e
üst 74c3dbe8
...@@ -16,6 +16,7 @@ $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\ ...@@ -16,6 +16,7 @@ $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
maskVertexShader.glsl \ maskVertexShader.glsl \
maskedTextureFragmentShader.glsl \ maskedTextureFragmentShader.glsl \
maskedTextureVertexShader.glsl \ maskedTextureVertexShader.glsl \
radialGradientFragmentShader.glsl \
solidFragmentShader.glsl \ solidFragmentShader.glsl \
solidVertexShader.glsl \ solidVertexShader.glsl \
textureFragmentShader.glsl \ textureFragmentShader.glsl \
......
...@@ -63,13 +63,18 @@ protected: ...@@ -63,13 +63,18 @@ protected:
GLuint mnLinearGradientProgram; GLuint mnLinearGradientProgram;
GLuint mnLinearGradientStartColorUniform; GLuint mnLinearGradientStartColorUniform;
GLuint mnLinearGradientEndColorUniform; GLuint mnLinearGradientEndColorUniform;
GLuint mnLinearGradientTransformUniform;
GLuint mnRadialGradientProgram;
GLuint mnRadialGradientStartColorUniform;
GLuint mnRadialGradientEndColorUniform;
GLuint mnRadialGradientCenterUniform;
bool CreateSolidProgram( void ); bool CreateSolidProgram( void );
bool CreateTextureProgram( void ); bool CreateTextureProgram( void );
bool CreateMaskedTextureProgram( void ); bool CreateMaskedTextureProgram( void );
bool CreateMaskProgram( void ); bool CreateMaskProgram( void );
bool CreateLinearGradientProgram( void ); bool CreateLinearGradientProgram( void );
bool CreateRadialGradientProgram( void );
void BeginSolid( SalColor nColor, sal_uInt8 nTransparency ); void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
void BeginSolid( SalColor nColor, double fTransparency ); void BeginSolid( SalColor nColor, double fTransparency );
...@@ -84,6 +89,7 @@ protected: ...@@ -84,6 +89,7 @@ protected:
void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
void DrawConvexPolygon( const Polygon& rPolygon ); void DrawConvexPolygon( const Polygon& rPolygon );
void DrawRect( long nX, long nY, long nWidth, long nHeight ); void DrawRect( long nX, long nY, long nWidth, long nHeight );
void DrawRect( const Rectangle& rRect );
void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ); void DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon ); void DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPolyPolygon );
void DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry, bool bInverted = false ); void DrawTextureRect( const Size& rSize, const SalTwoRect& rPosAry, bool bInverted = false );
...@@ -91,6 +97,7 @@ protected: ...@@ -91,6 +97,7 @@ protected:
void DrawTextureWithMask( GLuint nTexture, GLuint nMask, 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 DrawMask( GLuint nMask, SalColor nMaskColor, const SalTwoRect& rPosAry );
void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ); void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect );
void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect );
protected: protected:
// get the width of the device // get the width of the device
......
...@@ -75,6 +75,13 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl() ...@@ -75,6 +75,13 @@ OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl()
, mnMaskProgram(0) , mnMaskProgram(0)
, mnMaskUniform(0) , mnMaskUniform(0)
, mnMaskColorUniform(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 ) ...@@ -295,7 +302,20 @@ bool OpenGLSalGraphicsImpl::CreateLinearGradientProgram( void )
glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" ); glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
mnLinearGradientStartColorUniform = glGetUniformLocation( mnLinearGradientProgram, "start_color" ); mnLinearGradientStartColorUniform = glGetUniformLocation( mnLinearGradientProgram, "start_color" );
mnLinearGradientEndColorUniform = glGetUniformLocation( mnLinearGradientProgram, "end_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; return true;
} }
...@@ -455,6 +475,18 @@ void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeigh ...@@ -455,6 +475,18 @@ void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeigh
DrawConvexPolygon( 4, aPoints ); 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 ) void OpenGLSalGraphicsImpl::DrawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{ {
::basegfx::B2DPolygon aPolygon; ::basegfx::B2DPolygon aPolygon;
...@@ -601,18 +633,6 @@ void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const S ...@@ -601,18 +633,6 @@ void OpenGLSalGraphicsImpl::DrawMask( GLuint nMask, SalColor nMaskColor, const S
void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ) 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( mnLinearGradientProgram == 0 )
{ {
...@@ -632,10 +652,6 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const ...@@ -632,10 +652,6 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const
Rectangle aBoundRect; Rectangle aBoundRect;
Point aCenter; Point aCenter;
rGradient.GetBoundRect( rRect, aBoundRect, aCenter ); rGradient.GetBoundRect( rRect, aBoundRect, aCenter );
aBoundRect.Left()--;
aBoundRect.Top()--;
aBoundRect.Right()++;
aBoundRect.Bottom()++;
Polygon aPoly( aBoundRect ); Polygon aPoly( aBoundRect );
aPoly.Rotate( aCenter, rGradient.GetAngle() % 3600 ); aPoly.Rotate( aCenter, rGradient.GetAngle() % 3600 );
...@@ -653,6 +669,43 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const ...@@ -653,6 +669,43 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const
glUseProgram( 0 ); 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 // draw --> LineColor and FillColor and RasterOp and ClipRegion
void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY ) void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
...@@ -1189,11 +1242,33 @@ bool OpenGLSalGraphicsImpl::drawAlphaRect( ...@@ -1189,11 +1242,33 @@ bool OpenGLSalGraphicsImpl::drawAlphaRect(
bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
const Gradient& rGradient) const Gradient& rGradient)
{ {
const Rectangle aBoundRect( rPolyPoly.GetBoundRect() ); Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
SAL_INFO( "vcl.opengl", "::drawGradient" );
if( aBoundRect.IsEmpty() ) if( aBoundRect.IsEmpty() )
return true; 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 //TODO: lfrb: some missing transformation with the polygon in outdev
if( rGradient.GetStyle() == GradientStyle_LINEAR ) if( rGradient.GetStyle() == GradientStyle_LINEAR )
{ {
...@@ -1202,6 +1277,13 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, ...@@ -1202,6 +1277,13 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
PostDraw(); PostDraw();
return true; return true;
} }
else if( rGradient.GetStyle() == GradientStyle_RADIAL )
{
PreDraw();
DrawRadialGradient( rGradient, aBoundRect );
PostDraw();
return true;
}
return false; return false;
} }
......
/* -*- 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: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment