[Libreoffice-commits] core.git: Branch 'feature/fixes21' - vcl/inc vcl/opengl
László Németh
laszlo.nemeth at collabora.com
Thu May 19 18:17:50 UTC 2016
vcl/inc/openglgdiimpl.hxx | 5
vcl/opengl/gdiimpl.cxx | 304 ++++++++++++++++++++++++++++++++++++++++------
2 files changed, 272 insertions(+), 37 deletions(-)
New commits:
commit 05ac44e7e6c16bfb093c19630da67ac42ae913bf
Author: László Németh <laszlo.nemeth at collabora.com>
Date: Thu May 19 20:12:41 2016 +0200
default subset, calculate all, format change
Also revert "opengl: use line shader for all line drawing not just polylines"
This reverts commit 860f19365264aaf192dd6e2464efa02123a2cd91.
and 808a4cdc7e19823b15123f8037173a7dd43e5727
Change-Id: Ifed8f1a4f5b4880a5fb24e2db8708f7d14b0b869
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index da0fe69..6dfa73c 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -114,12 +114,17 @@ 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 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 DrawLinesAA( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
+ 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 42a62fc..2beb5fe 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -581,6 +581,25 @@ 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;
@@ -696,7 +715,7 @@ void OpenGLSalGraphicsImpl::DrawLineCap(float x1, float y1, float x2, float y2,
addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f);
}
- ApplyProgramMatrices(0.5f);
+ ApplyProgramMatrices(0.0f);
mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aVertices);
@@ -708,6 +727,9 @@ 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;
@@ -719,7 +741,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.5f);
+ ApplyProgramMatrices(0.0f);
mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aPoints);
@@ -913,7 +935,7 @@ void OpenGLSalGraphicsImpl::DrawPolyLine(const basegfx::B2DPolygon& rPolygon, fl
addVertexPair(aVertices, aExtrusionVectors, p1, normal, 1.0f);
}
- ApplyProgramMatrices(0.5f);
+ ApplyProgramMatrices(0.0f);
mpProgram->SetExtrusionVectors(aExtrusionVectors.data());
mpProgram->DrawArrays(GL_TRIANGLE_STRIP, aVertices);
@@ -942,6 +964,179 @@ 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::DrawLinesAA( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
+{
+ for( int i = 0; i < int(nPoints) - 1; ++i )
+ DrawLineAA( pPtAry[ i ].mnX, pPtAry[ i ].mnY, pPtAry[ i + 1 ].mnX, pPtAry[ i + 1 ].mnY );
+ if( bClose )
+ DrawLineAA( pPtAry[ nPoints - 1 ].mnX, pPtAry[ nPoints - 1 ].mnY, pPtAry[ 0 ].mnX, pPtAry[ 0 ].mnY );
+}
+
+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;
@@ -970,13 +1165,13 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
#endif
SalColor lastSolidColor = mProgramSolidColor;
double lastSolidTransparency = mProgramSolidTransparency;
- if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true))
+ if( UseSolidAA( lastSolidColor, lastSolidTransparency ))
{
for( i = 0; i < nPoints; ++i )
{
const SalPoint& rPt1 = pPtAry[ i ];
const SalPoint& rPt2 = pPtAry[ ( i + 1 ) % nPoints ];
- DrawLineSegment(rPt1.mnX, rPt1.mnY, rPt2.mnX, rPt2.mnY);
+ DrawEdgeAA( rPt1.mnX, rPt1.mnY, rPt2.mnX, rPt2.mnY );
}
UseSolid( lastSolidColor, lastSolidTransparency );
}
@@ -1013,13 +1208,13 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const tools::Polygon& rPolygon, b
#endif
SalColor lastSolidColor = mProgramSolidColor;
double lastSolidTransparency = mProgramSolidTransparency;
- if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true))
+ if( UseSolidAA( lastSolidColor, lastSolidTransparency ))
{
for( i = 0; i < nPoints; ++i )
{
const Point& rPt1 = rPolygon.GetPoint( i );
const Point& rPt2 = rPolygon.GetPoint(( i + 1 ) % nPoints );
- DrawLineSegment(rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+ DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
}
UseSolid( lastSolidColor, lastSolidTransparency );
}
@@ -1063,13 +1258,13 @@ void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoi
#endif
SalColor lastSolidColor = mProgramSolidColor;
double lastSolidTransparency = mProgramSolidTransparency;
- if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true))
+ if( UseSolidAA( lastSolidColor, lastSolidTransparency ))
{
for( i = 0; i < nPoints; ++i )
{
const basegfx::B2DPoint& rPt1 = rPolygon.getB2DPoint( i );
const basegfx::B2DPoint& rPt2 = rPolygon.getB2DPoint(( i + 1 ) % nPoints );
- DrawLineSegment(rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
+ DrawEdgeAA( rPt1.getX(), rPt1.getY(), rPt2.getX(), rPt2.getY());
}
UseSolid( lastSolidColor, lastSolidTransparency );
}
@@ -1691,8 +1886,8 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
if( mnLineColor != SALCOLOR_NONE )
{
PreDraw( XOROption::IMPLEMENT_XOR );
- if (UseLine(mnLineColor, 0.0, 1.0f, mrParent.getAntiAliasB2DDraw()))
- DrawLineSegment(nX1, nY1, nX2, nY2);
+ if( UseSolidAA( mnLineColor ) )
+ DrawLineAA( nX1, nY1, nX2, nY2 );
PostDraw();
}
}
@@ -1729,45 +1924,80 @@ void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeigh
void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
- basegfx::B2DPolygon aPoly;
- aPoly.append(basegfx::B2DPoint(pPtAry->mnX, pPtAry->mnY), nPoints);
- for (sal_uInt32 i = 1; i < nPoints; ++i)
- aPoly.setB2DPoint(i, basegfx::B2DPoint(pPtAry[i].mnX, pPtAry[i].mnY));
- aPoly.setClosed(false);
+ VCL_GL_INFO( "::drawPolyLine" );
- drawPolyLine(aPoly, 0.0, basegfx::B2DVector(1.0, 1.0), basegfx::B2DLineJoin::Miter,
- css::drawing::LineCap_BUTT, 15.0 * F_PI180 /*default*/);
+ if( mnLineColor != SALCOLOR_NONE && nPoints > 1 )
+ {
+ PreDraw( XOROption::IMPLEMENT_XOR );
+ if( UseSolidAA( mnLineColor ) )
+ DrawLinesAA( nPoints, pPtAry, false );
+ PostDraw();
+ }
}
void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
- basegfx::B2DPolygon aPoly;
- aPoly.append(basegfx::B2DPoint(pPtAry->mnX, pPtAry->mnY), nPoints);
- for (sal_uInt32 i = 1; i < nPoints; ++i)
- aPoly.setB2DPoint(i, basegfx::B2DPoint(pPtAry[i].mnX, pPtAry[i].mnY));
+ VCL_GL_INFO( "::drawPolygon" );
+ if( nPoints == 0 )
+ return;
+ if( nPoints == 1 )
+ {
+ drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
+ return;
+ }
+ if( nPoints == 2 )
+ {
+ drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
+ pPtAry[1].mnX, pPtAry[1].mnY );
+ return;
+ }
+
+ PreDraw( XOROption::IMPLEMENT_XOR );
- drawPolyPolygon(basegfx::B2DPolyPolygon(aPoly), 0.0);
+ if( UseSolid( mnFillColor ) )
+ DrawPolygon( nPoints, pPtAry );
+
+ if( UseSolidAA( mnLineColor ) )
+ DrawLinesAA( nPoints, pPtAry, true );
+
+ PostDraw();
}
-void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPointCounts, PCONSTSALPOINT* pPtAry )
+void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry )
{
- basegfx::B2DPolyPolygon aPolyPoly;
- for(sal_uInt32 nPolygon = 0; nPolygon < nPoly; ++nPolygon)
+ VCL_GL_INFO( "::drawPolyPolygon" );
+ if( nPoly <= 0 )
+ return;
+
+ PreDraw( XOROption::IMPLEMENT_XOR );
+
+ if( UseSolid( mnFillColor ) )
{
- sal_uInt32 nPoints = pPointCounts[nPolygon];
- if (nPoints)
+ if( nPoly == 1 )
+ DrawPolygon( pPoints[ 0 ], pPtAry[ 0 ] );
+ else
{
- PCONSTSALPOINT pPoints = pPtAry[nPolygon];
- basegfx::B2DPolygon aPoly;
- aPoly.append( basegfx::B2DPoint(pPoints->mnX, pPoints->mnY), nPoints);
- for (sal_uInt32 i = 1; i < nPoints; ++i)
- aPoly.setB2DPoint(i, basegfx::B2DPoint( pPoints[i].mnX, pPoints[i].mnY));
-
- aPolyPoly.append(aPoly);
+ basegfx::B2DPolyPolygon polyPolygon;
+ for( sal_uInt32 i = 0; i < nPoly; ++i )
+ {
+ basegfx::B2DPolygon polygon;
+ for( sal_uInt32 j = 0; j < pPoints[ i ]; ++j )
+ polygon.append( basegfx::B2DPoint( pPtAry[i][j].mnX, pPtAry[i][j].mnY ) );
+ polygon.setClosed( true );
+ polyPolygon.append( polygon );
+ }
+ DrawPolyPolygon( polyPolygon );
}
}
- drawPolyPolygon(aPolyPoly, 0.0);
+ if( mnLineColor != mnFillColor && UseSolidAA( mnLineColor ) )
+ {
+ // TODO Use glMultiDrawElements or primitive restart
+ for( sal_uInt32 i = 0; i < nPoly; i++ )
+ DrawLinesAA( pPoints[i], pPtAry[i], true );
+ }
+
+ PostDraw();
}
bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency )
@@ -1810,7 +2040,7 @@ bool OpenGLSalGraphicsImpl::drawPolyLine(
PreDraw(XOROption::IMPLEMENT_XOR);
- if (UseLine(mnLineColor, 0.0f, fLineWidth, mrParent.getAntiAliasB2DDraw()))
+ if (UseLine(mnLineColor, 0.0f, fLineWidth, true))
{
basegfx::B2DPolygon aPolygon(rPolygon);
More information about the Libreoffice-commits
mailing list