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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 ); }
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
