[Libreoffice-commits] core.git: Branch 'libreoffice-4-4' - 3 commits - vcl/inc vcl/opengl
Luboš Luňák
l.lunak at collabora.com
Mon Dec 15 13:18:00 PST 2014
vcl/inc/openglgdiimpl.hxx | 14 ++-
vcl/opengl/gdiimpl.cxx | 197 ++++++++++++++++++++++++++++++++++++++++-----
vcl/opengl/win/gdiimpl.cxx | 2
vcl/opengl/x11/gdiimpl.cxx | 4
4 files changed, 188 insertions(+), 29 deletions(-)
New commits:
commit 5bedf7301d66c6a1473c3c807e6ed3758d6c5648
Author: Luboš Luňák <l.lunak at collabora.com>
Date: Mon Dec 15 20:00:45 2014 +0100
use AA for lines only when AA is active
Change-Id: I9965f58b8f06f1cec2c419dcf16d8aebf9cd97b8
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 03d1c23..3621aab 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -40,8 +40,9 @@ class VCL_PLUGIN_PUBLIC OpenGLSalGraphicsImpl : public SalGraphicsImpl
protected:
OpenGLContext* mpContext;
+ SalGraphics& mrParent;
/// Pointer to the SalFrame or SalVirtualDevice
- SalGeometryProvider* mpParent;
+ SalGeometryProvider* mpProvider;
OpenGLFramebuffer* mpFramebuffer;
OpenGLProgram* mpProgram;
@@ -66,11 +67,14 @@ public:
bool UseSolid( SalColor nColor, sal_uInt8 nTransparency );
bool UseSolid( SalColor nColor, double fTransparency );
bool UseSolid( SalColor nColor );
+ bool UseSolidAA( SalColor nColor );
bool UseInvert();
void DrawPoint( long nX, long nY );
void DrawLine( long nX1, long nY1, long nX2, long nY2 );
void DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
+ void DrawLineAA( long nX1, long nY1, long nX2, long nY2 );
+ void DrawLinesAA( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose );
void DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry );
void DrawConvexPolygon( const Polygon& rPolygon );
void DrawRect( long nX, long nY, long nWidth, long nHeight );
@@ -92,13 +96,13 @@ public:
public:
// get the width of the device
- GLfloat GetWidth() const { return mpParent ? mpParent->GetWidth() : 1; }
+ GLfloat GetWidth() const { return mpProvider ? mpProvider->GetWidth() : 1; }
// get the height of the device
- GLfloat GetHeight() const { return mpParent ? mpParent->GetHeight() : 1; }
+ GLfloat GetHeight() const { return mpProvider ? mpProvider->GetHeight() : 1; }
// check whether this instance is used for offscreen rendering
- bool IsOffscreen() const { return mpParent ? mpParent->IsOffScreen() : true; }
+ bool IsOffscreen() const { return mpProvider ? mpProvider->IsOffScreen() : true; }
// operations to do before painting
virtual void PreDraw();
@@ -120,7 +124,7 @@ protected:
virtual bool UseContext( OpenGLContext* pContext ) = 0;
public:
- OpenGLSalGraphicsImpl(SalGeometryProvider* pParent);
+ OpenGLSalGraphicsImpl(SalGraphics& pParent, SalGeometryProvider *pProvider);
virtual ~OpenGLSalGraphicsImpl ();
OpenGLContext* GetOpenGLContext();
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index b8d6319..611b72d 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -36,9 +36,10 @@
#include <vector>
-OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGeometryProvider* pParent)
+OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGraphics& rParent, SalGeometryProvider *pProvider)
: mpContext(0)
- , mpParent(pParent)
+ , mrParent(rParent)
+ , mpProvider(pProvider)
, mpFramebuffer(NULL)
, mpProgram(NULL)
, mbUseScissor(false)
@@ -372,6 +373,18 @@ 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 )
+{
+ if( !mrParent.getAntiAliasB2DDraw())
+ return UseSolid( nColor );
+ if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) )
+ return false;
+ mpProgram->SetColorf( "start_color", nColor, 0.0f );
+ mpProgram->SetColorf( "end_color", nColor, 1.0f );
+ return true;
+}
+
bool OpenGLSalGraphicsImpl::UseInvert()
{
if( !UseSolid( MAKE_SALCOLOR( 255, 255, 255 ) ) )
@@ -393,8 +406,24 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
{
+ GLfloat pPoints[4];
+
+ pPoints[0] = (2 * nX1) / GetWidth() - 1.0;
+ pPoints[1] = 1.0f - 2 * nY1 / GetHeight();
+ pPoints[2] = (2 * nX2) / GetWidth() - 1.0;;
+ pPoints[3] = 1.0f - 2 * nY2 / GetHeight();
+
+ mpProgram->SetVertices( pPoints );
+ glDrawArrays( GL_LINES, 0, 2 );
+}
+
+void OpenGLSalGraphicsImpl::DrawLineAA( long nX1, long nY1, long nX2, long nY2 )
+{
+ if( !mrParent.getAntiAliasB2DDraw())
+ return DrawLine( nX1, nY1, nX2, nY2 );
+
if( nX1 == nX2 || nY1 == nY2 )
- { // horizontal/vertical, no need for AA
+ { // Horizontal/vertical, no need for AA, both points have normal color.
GLfloat pPoints[4];
pPoints[0] = (2 * nX1) / GetWidth() - 1.0;
@@ -403,6 +432,10 @@ void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
pPoints[3] = 1.0f - 2 * nY2 / GetHeight();
mpProgram->SetVertices( pPoints );
+ // Still set up for the trivial "gradients", because presumably UseSolidAA() has been called.
+ GLfloat aTexCoord[4] = { 0, 1, 1, 1 };
+ mpProgram->SetTextureCoord( aTexCoord );
+
glDrawArrays( GL_LINES, 0, 2 );
return;
}
@@ -416,11 +449,6 @@ void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
*
* Enjoy. Chris Tsang.*/
- if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) )
- return;
- mpProgram->SetColorf( "start_color", mnLineColor, 0.0f );
- mpProgram->SetColorf( "end_color", mnLineColor, 1.0f );
-
double x1 = nX1;
double y1 = nY1;
double x2 = nX2;
@@ -539,6 +567,14 @@ void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAr
DrawLine( pPtAry[ nPoints - 1 ].mnX, pPtAry[ nPoints - 1 ].mnY, pPtAry[ 0 ].mnX, pPtAry[ 0 ].mnY );
}
+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::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
{
std::vector<GLfloat> aVertices(nPoints * 2);
@@ -918,8 +954,8 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
if( mnLineColor != SALCOLOR_NONE )
{
PreDraw();
- if( UseSolid( mnLineColor ) )
- DrawLine( nX1, nY1, nX2, nY2 );
+ if( UseSolidAA( mnLineColor ) )
+ DrawLineAA( nX1, nY1, nX2, nY2 );
PostDraw();
}
}
@@ -940,7 +976,7 @@ void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeigh
const long nY2( nY + nHeight );
const SalPoint aPoints[] = { { nX1, nY1 }, { nX2, nY1 },
{ nX2, nY2 }, { nX1, nY2 } };
- DrawLines( 4, aPoints, true );
+ DrawLines( 4, aPoints, true ); // No need for AA.
}
PostDraw();
@@ -953,8 +989,8 @@ void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pP
if( mnLineColor != SALCOLOR_NONE && nPoints > 1 )
{
PreDraw();
- if( UseSolid( mnLineColor ) )
- DrawLines( nPoints, pPtAry, false );
+ if( UseSolidAA( mnLineColor ) )
+ DrawLinesAA( nPoints, pPtAry, false );
PostDraw();
}
}
@@ -981,8 +1017,8 @@ void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPt
if( UseSolid( mnFillColor ) )
DrawPolygon( nPoints, pPtAry );
- if( UseSolid( mnLineColor ) )
- DrawLines( nPoints, pPtAry, true );
+ if( UseSolidAA( mnLineColor ) )
+ DrawLinesAA( nPoints, pPtAry, true );
PostDraw();
}
@@ -1001,11 +1037,11 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32*
DrawPolygon( pPoints[i], pPtAry[i] );
}
- if( UseSolid( mnLineColor ) )
+ if( UseSolidAA( mnLineColor ) )
{
// TODO Use glMultiDrawElements or primitive restart
for( sal_uInt32 i = 0; i < nPoly; i++ )
- DrawLines( pPoints[i], pPtAry[i], true );
+ DrawLinesAA( pPoints[i], pPtAry[i], true );
}
PostDraw();
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index a56ea30..ee53c8a 100644
--- a/vcl/opengl/win/gdiimpl.cxx
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -15,7 +15,7 @@
WinOpenGLSalGraphicsImpl::WinOpenGLSalGraphicsImpl(WinSalGraphics& rGraphics,
SalGeometryProvider *mpProvider):
- OpenGLSalGraphicsImpl(mpProvider),
+ OpenGLSalGraphicsImpl(rGraphics,mpProvider),
mrParent(rGraphics)
{
}
diff --git a/vcl/opengl/x11/gdiimpl.cxx b/vcl/opengl/x11/gdiimpl.cxx
index d0d890b..bbc68b9 100644
--- a/vcl/opengl/x11/gdiimpl.cxx
+++ b/vcl/opengl/x11/gdiimpl.cxx
@@ -26,7 +26,7 @@
#include <vcl/opengl/OpenGLHelper.hxx>
X11OpenGLSalGraphicsImpl::X11OpenGLSalGraphicsImpl( X11SalGraphics& rParent ):
- OpenGLSalGraphicsImpl(rParent.GetGeometryProvider()),
+ OpenGLSalGraphicsImpl(rParent,rParent.GetGeometryProvider()),
mrParent(rParent)
{
}
@@ -38,7 +38,7 @@ X11OpenGLSalGraphicsImpl::~X11OpenGLSalGraphicsImpl()
void X11OpenGLSalGraphicsImpl::Init()
{
// The m_pFrame and m_pVDev pointers are updated late in X11
- mpParent = mrParent.GetGeometryProvider();
+ mpProvider = mrParent.GetGeometryProvider();
OpenGLSalGraphicsImpl::Init();
}
commit ad0a52716fd6cf6536b6d71941c83ee3a1fa1d13
Author: Luboš Luňák <l.lunak at collabora.com>
Date: Mon Dec 15 13:05:35 2014 +0100
draw lines anti-aliased (opengl vcl)
Change-Id: I3a67da89cedbb6a58b2556abf4553857125af5a6
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index b3a4321..b8d6319 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -393,33 +393,150 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
{
- GLfloat pPoints[4];
+ if( nX1 == nX2 || nY1 == nY2 )
+ { // horizontal/vertical, no need for AA
+ GLfloat pPoints[4];
- pPoints[0] = (2 * nX1) / GetWidth() - 1.0;
- pPoints[1] = 1.0f - 2 * nY1 / GetHeight();
- pPoints[2] = (2 * nX2) / GetWidth() - 1.0;;
- pPoints[3] = 1.0f - 2 * nY2 / GetHeight();
+ pPoints[0] = (2 * nX1) / GetWidth() - 1.0;
+ pPoints[1] = 1.0f - 2 * nY1 / GetHeight();
+ pPoints[2] = (2 * nX2) / GetWidth() - 1.0;;
+ pPoints[3] = 1.0f - 2 * nY2 / GetHeight();
- mpProgram->SetVertices( pPoints );
- glDrawArrays( GL_LINES, 0, 2 );
-}
+ mpProgram->SetVertices( pPoints );
+ glDrawArrays( GL_LINES, 0, 2 );
+ return;
+ }
-void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
-{
- std::vector<GLfloat> aPoints(nPoints * 2);
- sal_uInt32 i, j;
+ // 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.*/
- for( i = 0, j = 0; i < nPoints; i++ )
+ if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) )
+ return;
+ mpProgram->SetColorf( "start_color", mnLineColor, 0.0f );
+ mpProgram->SetColorf( "end_color", mnLineColor, 1.0f );
+
+ double x1 = nX1;
+ double y1 = nY1;
+ double x2 = nX2;
+ double y2 = nY2;
+ const int w = 1; // line width
+
+ double t;
+ double R;
+ //determine parameters t,R
+ switch( w )
{
- aPoints[j++] = (2 * pPtAry[i].mnX) / GetWidth() - 1.0f;
- aPoints[j++] = 1.0f - (2 * pPtAry[i].mnY) / GetHeight();
+ case 0:
+ return;
+ case 1:
+ t=0.05;
+ R=0.768;
+ break;
+ case 2:
+ t=0.38;
+ R=1.08;
+ break;
+ case 3:
+ t=0.96;
+ R=1.08;
+ break;
+ case 4:
+ t=1.44;
+ R=1.08;
+ break;
+ case 5:
+ t=1.9;
+ R=1.08;
+ break;
+ default:
+ t=2.5+(w-6)*0.50;
+ R=1.08;
+ break;
}
- mpProgram->SetVertices( &aPoints[0] );
- if( bClose )
- glDrawArrays( GL_LINE_LOOP, 0, nPoints );
+ //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 cx=0,cy=0; //cap 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
- glDrawArrays( GL_LINE_STRIP, 0, nPoints );
+ { //calculate to exact
+ dx=y1-y2;
+ dy=x2-x1;
+ double L=sqrt(dx*dx+dy*dy);
+ dx/=L;
+ dy/=L;
+ cx=-0.6*dy; cy=0.6*dx;
+ tx=t*dx; ty=t*dy;
+ Rx=R*dx; Ry=R*dy;
+ }
+
+ GLfloat vertices[]=
+ {
+#define convertX( x ) GLfloat( (2 * (x)) / GetWidth() - 1.0f)
+#define convertY( y ) GLfloat( 1.0f - (2 * (y)) / GetHeight())
+ convertX(x1-tx-Rx), convertY(y1-ty-Ry), //fading edge1
+ convertX(x2-tx-Rx), convertY(y2-ty-Ry),
+ convertX(x1-tx),convertY(y1-ty), //core
+ convertX(x2-tx),convertY(y2-ty),
+ convertX(x1+tx),convertY(y1+ty),
+ convertX(x2+tx),convertY(y2+ty),
+ convertX(x1+tx+Rx), convertY(y1+ty+Ry), //fading edge2
+ convertX(x2+tx+Rx), convertY(y2+ty+Ry)
+#undef convertX
+#undef convertY
+ };
+
+ GLfloat aTexCoord[16] = { 0, 0, 1, 0, 2, 1, 3, 1, 4, 1, 5, 1, 6, 0, 7, 0 };
+ mpProgram->SetTextureCoord( aTexCoord );
+ mpProgram->SetVertices( vertices );
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);
+}
+
+void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
+{
+ for( int i = 0; i < int(nPoints) - 1; ++i )
+ DrawLine( pPtAry[ i ].mnX, pPtAry[ i ].mnY, pPtAry[ i + 1 ].mnX, pPtAry[ i + 1 ].mnY );
+ if( bClose )
+ DrawLine( pPtAry[ nPoints - 1 ].mnX, pPtAry[ nPoints - 1 ].mnY, pPtAry[ 0 ].mnX, pPtAry[ 0 ].mnY );
}
void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
commit 07db92726cea995d6754fc1465a83f1a1b3cde0f
Author: Luboš Luňák <l.lunak at collabora.com>
Date: Mon Dec 15 13:05:17 2014 +0100
allow using more than one opengl program during one draw "operation"
I.e. between one PreDraw()/PostDraw() pair.
Change-Id: I358d603ff33fa7416a4033bf074fe390b1112fcc
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index f4fb17d..b3a4321 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -341,6 +341,8 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader )
{
+ if( mpProgram != NULL )
+ mpProgram->Clean();
mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader );
return ( mpProgram != NULL );
}
More information about the Libreoffice-commits
mailing list