diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-14 01:16:28 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2014-11-15 12:17:43 +0100 |
commit | 32bddc7cb2fe6f3f5d9b964b28fcda864aae5c66 (patch) | |
tree | f317b586c3010b2eecc53ba62e11fb600dd37be6 | |
parent | b190ffe58796875eceaf340501a8832e222514fb (diff) |
vcl: Implement axial gradients in OpenGL backend
Change-Id: I93b8c3c076c79d992d467b01ca5f5eca1ed626d3
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 1 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 67 | ||||
-rw-r--r-- | vcl/opengl/linearGradientFragmentShader.glsl | 2 |
3 files changed, 69 insertions, 1 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 67c0c308af77..dd0b1e38712d 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -107,6 +107,7 @@ public: void DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry ); void DrawMask( OpenGLTexture& rTexture, SalColor nMaskColor, const SalTwoRect& rPosAry ); void DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect ); + void DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect ); void DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect ); public: diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index ef0c2bd03090..04237757cd80 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -772,6 +772,68 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const CHECK_GL_ERROR(); } +void OpenGLSalGraphicsImpl::DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect ) +{ + 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 ); + + /** + * Draw two rectangles with linear gradient. + * + * 1 *---* 2 + * | /| + * | / | Points 0 and 3 have start color + * 0 |/__| 3 Points 1, 2, 4 and 5 have end color + * |\ | + * | \ | + * | \| + * 5 *---* 4 + * + */ + + Rectangle aRect; + Point aCenter; + rGradient.GetBoundRect( rRect, aRect, aCenter ); + + // determine points 0 and 3 + Point aPt0( aRect.Left(), (aRect.Top() + aRect.Bottom() + 1) / 2 ); + Point aPt3( aRect.Right(), (aRect.Top() + aRect.Bottom() + 1) / 2 ); + + Polygon aPoly( 7 ); + aPoly.SetPoint( aPt0, 0 ); + aPoly.SetPoint( aRect.TopLeft(), 1 ); + aPoly.SetPoint( aRect.TopRight(), 2 ); + aPoly.SetPoint( aPt3, 3 ); + aPoly.SetPoint( aRect.BottomRight(), 4 ); + aPoly.SetPoint( aRect.BottomLeft(), 5 ); + aPoly.SetPoint( aPt0, 6 ); + aPoly.Rotate( aCenter, rGradient.GetAngle() % 3600 ); + + GLfloat aTexCoord[12] = { 0, 1, 1, 0, 2, 0, 3, 1, 4, 0, 5, 0 }; + GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder()); + aTexCoord[3] = aTexCoord[5] = aTexCoord[9] = aTexCoord[11] = fMin; + glEnableVertexAttribArray( GL_ATTRIB_TEX ); + glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord ); + + DrawConvexPolygon( aPoly ); + + glDisableVertexAttribArray( GL_ATTRIB_TEX ); + glUseProgram( 0 ); + CHECK_GL_ERROR(); +} + void OpenGLSalGraphicsImpl::DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect ) { if( mnRadialGradientProgram == 0 ) @@ -1365,6 +1427,7 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, return true; if( rGradient.GetStyle() != GradientStyle_LINEAR && + rGradient.GetStyle() != GradientStyle_AXIAL && rGradient.GetStyle() != GradientStyle_RADIAL ) return false; @@ -1402,6 +1465,10 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly, { DrawLinearGradient( rGradient, aBoundRect ); } + else if( rGradient.GetStyle() == GradientStyle_AXIAL ) + { + DrawAxialGradient( rGradient, aBoundRect ); + } else if( rGradient.GetStyle() == GradientStyle_RADIAL ) { DrawRadialGradient( rGradient, aBoundRect ); diff --git a/vcl/opengl/linearGradientFragmentShader.glsl b/vcl/opengl/linearGradientFragmentShader.glsl index 7b84c0693313..bd1137c16481 100644 --- a/vcl/opengl/linearGradientFragmentShader.glsl +++ b/vcl/opengl/linearGradientFragmentShader.glsl @@ -16,7 +16,7 @@ varying vec2 tex_coord; void main(void) { - gl_FragColor = mix(start_color, end_color, + gl_FragColor = mix(end_color, start_color, clamp(tex_coord.t, 0.0, 1.0)); } |