Kaydet (Commit) c8fc1f40 authored tarafından Tomaž Vajngerl's avatar Tomaž Vajngerl Kaydeden (comit) Tomaž Vajngerl

opengl: use line shader for all line drawing not just polylines

Change-Id: I9c2d5c5ca4761867a0a38cb3bc3c4973454ee992
Reviewed-on: https://gerrit.libreoffice.org/25157Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarTomaž Vajngerl <quikee@gmail.com>
üst 6473093d
......@@ -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 );
......
......@@ -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);
......
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