diff options
author | Tomaž Vajngerl <tomaz.vajngerl@collabora.co.uk> | 2016-05-19 21:35:28 +0900 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2016-05-23 08:47:04 +0000 |
commit | c8fc1f40ad8e20af32574e0aa73bdec51ae64e14 (patch) | |
tree | 7f617b7649e2a8e9207b579a22ed333c230a8c28 /vcl | |
parent | 6473093d4f6ee7d06905ddd71c90180fcffb0bef (diff) |
opengl: use line shader for all line drawing not just polylines
Change-Id: I9c2d5c5ca4761867a0a38cb3bc3c4973454ee992
Reviewed-on: https://gerrit.libreoffice.org/25157
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 6 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 214 |
2 files changed, 15 insertions, 205 deletions
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx index 2b2109bb07c6..ee8c7e205926 100644 --- a/vcl/inc/openglgdiimpl.hxx +++ b/vcl/inc/openglgdiimpl.hxx @@ -114,16 +114,12 @@ public: bool UseSolid( SalColor nColor, sal_uInt8 nTransparency ); bool UseSolid( SalColor nColor, double fTransparency ); bool UseSolid( SalColor nColor ); - bool UseSolidAA( SalColor nColor, double fTransparency ); - bool UseSolidAA( SalColor nColor ); - bool UseLine(SalColor nColor, double fTransparency, GLfloat fLineWidth); + bool UseLine(SalColor nColor, double fTransparency, GLfloat fLineWidth, bool bUseAA); bool UseInvert50(); bool UseInvert(SalInvert nFlags); void DrawPoint( long nX, long nY ); void DrawLine( double nX1, double nY1, double nX2, double nY2 ); - void DrawLineAA( double nX1, double nY1, double nX2, double nY2 ); - void DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 ); void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, bool blockAA = false ); void DrawConvexPolygon( const tools::Polygon& rPolygon, bool blockAA = false ); void DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoid, bool blockAA = false ); diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index 8dc167695ec8..a92e5b3fca5e 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -583,25 +583,6 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor ) return UseSolid( nColor, 0.0f ); } -// Like UseSolid(), but sets up for AA drawing, which uses gradients to create the AA. -bool OpenGLSalGraphicsImpl::UseSolidAA( SalColor nColor, double fTransparency ) -{ - if( nColor == SALCOLOR_NONE ) - return false; - if( !mrParent.getAntiAliasB2DDraw()) - return UseSolid( nColor ); - if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) ) - return false; - mpProgram->SetColorf( "start_color", nColor, fTransparency ); - mpProgram->SetColorf( "end_color", nColor, 1.0f ); - return true; -} - -bool OpenGLSalGraphicsImpl::UseSolidAA( SalColor nColor ) -{ - return UseSolidAA( nColor, 0.0 ); -} - bool OpenGLSalGraphicsImpl::UseInvert( SalInvert nFlags ) { OpenGLZone aZone; @@ -715,7 +696,7 @@ void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2, addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f); } - ApplyProgramMatrices(0.0f); + ApplyProgramMatrices(0.5f); mpProgram->SetExtrusionVectors(aExtrusionVectors.data()); mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aVertices); @@ -727,9 +708,6 @@ void OpenGLSalGraphicsImpl::DrawLineSegment(float x1, float y1, float x2, float glm::vec2 p1(x1, y1); glm::vec2 p2(x2, y2); - if (p1.x == p2.x && p1.y == p2.y) - return; - std::vector<GLfloat> aPoints; std::vector<GLfloat> aExtrusionVectors; @@ -741,7 +719,7 @@ void OpenGLSalGraphicsImpl::DrawLineSegment(float x1, float y1, float x2, float addVertexPair(aPoints, aExtrusionVectors, p1, normal, 1.0f); addVertexPair(aPoints, aExtrusionVectors, p2, normal, 1.0f); - ApplyProgramMatrices(0.0f); + ApplyProgramMatrices(0.5f); mpProgram->SetExtrusionVectors(aExtrusionVectors.data()); mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aPoints); @@ -935,7 +913,7 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f); } - ApplyProgramMatrices(0.0f); + ApplyProgramMatrices(0.5f); mpProgram->SetExtrusionVectors(aExtrusionVectors.data()); mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aVertices); @@ -943,7 +921,7 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl } } -bool OpenGLSalGraphicsImpl::UseLine(SalColor nColor, double fTransparency, GLfloat fLineWidth) +bool OpenGLSalGraphicsImpl::UseLine(SalColor nColor, double fTransparency, GLfloat fLineWidth, bool bUseAA) { if( nColor == SALCOLOR_NONE ) return false; @@ -953,7 +931,7 @@ bool OpenGLSalGraphicsImpl::UseLine(SalColor nColor, double fTransparency, GLflo mpProgram->SetUniform1f("line_width", fLineWidth); // The width of the feather - area we make lineary transparent in VS. // Good AA value is 0.5 - mpProgram->SetUniform1f("feather", 0.5f); + mpProgram->SetUniform1f("feather", bUseAA ? 0.5f : 0.0f); // We need blending or AA won't work correctly mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); #ifdef DBG_UTIL @@ -964,170 +942,6 @@ bool OpenGLSalGraphicsImpl::UseLine(SalColor nColor, double fTransparency, GLflo return true; } -void OpenGLSalGraphicsImpl::DrawLineAA( double nX1, double nY1, double nX2, double nY2 ) -{ - OpenGLZone aZone; - - if( !mrParent.getAntiAliasB2DDraw()) - return DrawLine( nX1, nY1, nX2, nY2 ); - - if( nX1 == nX2 || nY1 == nY2 ) - { // Horizontal/vertical, no need for AA, both points have normal color. - - // Still set up for the trivial "gradients", because presumably UseSolidAA() has been called. - GLfloat aTexCoord[4] = { 0, 1, 1, 1 }; - mpProgram->SetTextureCoord( aTexCoord ); - DrawLine(nX1, nY1, nX2, nY2); - - return; - } - ImplDrawLineAA( nX1, nY1, nX2, nY2 ); -} - -void OpenGLSalGraphicsImpl::ImplDrawLineAA( double nX1, double nY1, double nX2, double nY2, bool edge ) -{ - // Draw the line anti-aliased. Based on code with the following notice: - /* Drawing nearly perfect 2D line segments in OpenGL - * You can use this code however you want. - * I just hope you to cite my name and the page of this technique: - * http://artgrammer.blogspot.com/2011/05/drawing-nearly-perfect-2d-line-segments.html - * http://www.codeproject.com/KB/openGL/gllinedraw.aspx - * - * Enjoy. Chris Tsang.*/ - - double x1 = nX1; - double y1 = nY1; - double x2 = nX2; - double y2 = nY2; - - // A special hack for drawing lines that are in fact AA edges of a shape. Make the line somewhat - // wider, but (done further below) draw the entire width as a gradient. This would be wrong for a line - // (too wide and seemingly less straight), but it makes the edges look smoother and the width difference - // is almost unnoticeable. - const double w = edge ? 1.4 : 1.0; - - double t(0.0); - double R(0.0); - double f = w - static_cast<int>(w); - //determine parameters t,R - if ( w>=0.0 && w<1.0 ) - { - t=0.05; - R=0.48+0.32*f; - } - else if ( w>=1.0 && w<2.0 ) - { - t=0.05+f*0.33; - R=0.768+0.312*f; - } - else if ( w>=2.0 && w<3.0 ) - { - t=0.38+f*0.58; - R=1.08; - } - else if ( w>=3.0 && w<4.0 ) - { - t=0.96+f*0.48; - R=1.08; - } - else if ( w>=4.0 && w<5.0 ) - { - t=1.44+f*0.46; - R=1.08; - } - else if ( w>=5.0 && w<6.0 ) - { - t=1.9+f*0.6; - R=1.08; - } - else if ( w>=6.0 ) - { - double ff=w-6.0; - t=2.5+ff*0.50; - R=1.08; - } - - //determine angle of the line to horizontal - double tx=0,ty=0; //core thinkness of a line - double Rx=0,Ry=0; //fading edge of a line - double dx=x2-x1; - double dy=y2-y1; - if ( w < 3 ) - { //approximate to make things even faster - double m=dy/dx; - //and calculate tx,ty,Rx,Ry - if ( m>-0.4142 && m<=0.4142) - { - // -22.5< angle <= 22.5, approximate to 0 (degree) - tx=t*0.1; ty=t; - Rx=R*0.6; Ry=R; - } - else if ( m>0.4142 && m<=2.4142) - { - // 22.5< angle <= 67.5, approximate to 45 (degree) - tx=t*-0.7071; ty=t*0.7071; - Rx=R*-0.7071; Ry=R*0.7071; - } - else if ( m>2.4142 || m<=-2.4142) - { - // 67.5 < angle <=112.5, approximate to 90 (degree) - tx=t; ty=t*0.1; - Rx=R; Ry=R*0.6; - } - else if ( m>-2.4142 && m<-0.4142) - { - // 112.5 < angle < 157.5, approximate to 135 (degree) - tx=t*0.7071; ty=t*0.7071; - Rx=R*0.7071; Ry=R*0.7071; - } - else - assert( false ); - } - else - { //calculate to exact - dx=y1-y2; - dy=x2-x1; - double L=sqrt(dx*dx+dy*dy); - dx/=L; - dy/=L; - tx=t*dx; ty=t*dy; - Rx=R*dx; Ry=R*dy; - } - - if( edge ) - { // See above. - Rx += tx; - Ry += ty; - tx = ty = 0; - } - - std::vector<GLfloat> vertices - { - GLfloat(x1-tx-Rx), GLfloat(y1-ty-Ry), //fading edge1 - GLfloat(x2-tx-Rx), GLfloat(y2-ty-Ry), - GLfloat(x1-tx), GLfloat(y1-ty), //core - GLfloat(x2-tx), GLfloat(y2-ty), - GLfloat(x1+tx), GLfloat(y1+ty), - GLfloat(x2+tx), GLfloat(y2+ty), - GLfloat(x1+tx+Rx), GLfloat(y1+ty+Ry), //fading edge2 - GLfloat(x2+tx+Rx), GLfloat(y2+ty+Ry) - }; - - ApplyProgramMatrices(0.0f); - GLfloat aTexCoord[16] = { 0, 0, 1, 0, 2, 1, 3, 1, 4, 1, 5, 1, 6, 0, 7, 0 }; - mpProgram->SetTextureCoord( aTexCoord ); - mpProgram->DrawArrays(GL_TRIANGLE_STRIP, vertices); - CHECK_GL_ERROR(); -} - -void OpenGLSalGraphicsImpl::DrawEdgeAA( double nX1, double nY1, double nX2, double nY2 ) -{ - assert( mrParent.getAntiAliasB2DDraw()); - if( nX1 == nX2 || nY1 == nY2 ) - return; //horizontal/vertical, no need for AA - ImplDrawLineAA( nX1, nY1, nX2, nY2, true ); -} - void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry, bool blockAA ) { OpenGLZone aZone; @@ -1156,13 +970,13 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin #endif SalColor lastSolidColor = mProgramSolidColor; double lastSolidTransparency = mProgramSolidTransparency; - if( UseSolidAA( lastSolidColor, lastSolidTransparency )) + if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true)) { for( i = 0; i < nPoints; ++i ) { const SalPoint& rPt1 = pPtAry[ i ]; const SalPoint& rPt2 = pPtAry[ ( i + 1 ) % nPoints ]; - DrawEdgeAA( rPt1.mnX, rPt1.mnY, rPt2.mnX, rPt2.mnY ); + DrawLineSegment(rPt1.mnX, rPt1.mnY, rPt2.mnX, rPt2.mnY); } UseSolid( lastSolidColor, lastSolidTransparency ); } @@ -1199,13 +1013,13 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const tools::Polygon& rPolygon, b #endif SalColor lastSolidColor = mProgramSolidColor; double lastSolidTransparency = mProgramSolidTransparency; - if( UseSolidAA( lastSolidColor, lastSolidTransparency )) + if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true)) { for( i = 0; i < nPoints; ++i ) { const Point& rPt1 = rPolygon.GetPoint( i ); const Point& rPt2 = rPolygon.GetPoint(( i + 1 ) % nPoints ); - DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + DrawLineSegment(rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); } UseSolid( lastSolidColor, lastSolidTransparency ); } @@ -1249,13 +1063,13 @@ void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoi #endif SalColor lastSolidColor = mProgramSolidColor; double lastSolidTransparency = mProgramSolidTransparency; - if( UseSolidAA( lastSolidColor, lastSolidTransparency )) + if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true)) { for( i = 0; i < nPoints; ++i ) { const basegfx::B2DPoint& rPt1 = rPolygon.getB2DPoint( i ); const basegfx::B2DPoint& rPt2 = rPolygon.getB2DPoint(( i + 1 ) % nPoints ); - DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); + DrawLineSegment(rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY()); } UseSolid( lastSolidColor, lastSolidTransparency ); } @@ -1878,8 +1692,8 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 ) if( mnLineColor != SALCOLOR_NONE ) { PreDraw( XOROption::IMPLEMENT_XOR ); - if( UseSolidAA( mnLineColor ) ) - DrawLineAA( nX1, nY1, nX2, nY2 ); + if (UseLine(mnLineColor, 0.0, 1.0f, mrParent.getAntiAliasB2DDraw())) + DrawLineSegment(nX1, nY1, nX2, nY2); PostDraw(); } } @@ -1998,7 +1812,7 @@ bool OpenGLSalGraphicsImpl::drawPolyLine( PreDraw(XOROption::IMPLEMENT_XOR); - if (UseLine(mnLineColor, 0.0f, fLineWidth)) + if (UseLine(mnLineColor, 0.0f, fLineWidth, mrParent.getAntiAliasB2DDraw())) { basegfx::B2DPolygon aPolygon(rPolygon); |