[Libreoffice-commits] core.git: 2 commits - vcl/opengl

Luboš Luňák l.lunak at collabora.com
Mon Dec 15 04:06:33 PST 2014


 vcl/opengl/gdiimpl.cxx |  157 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 138 insertions(+), 19 deletions(-)

New commits:
commit f8520e299983c5b6a0ee1720218260e8e0084c7f
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 694f6d2..137a84d 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -402,33 +402,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 cbc57a99c200952816e4dd827d0a9d27beaef4bd
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 3690a6b..694f6d2 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -350,6 +350,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