[Libreoffice-commits] core.git: Branch 'feature/chart-opengl2' - 3 commits - chart2/source

Markus Mohrhard markus.mohrhard at collabora.co.uk
Tue Jan 21 20:50:37 PST 2014


 chart2/source/view/inc/DummyXShape.hxx   |    2 
 chart2/source/view/main/DummyXShape.cxx  |   34 ++++++++++++
 chart2/source/view/main/OpenGLRender.cxx |   86 +++++++++++++++++++++++++++++++
 chart2/source/view/main/OpenGLRender.hxx |    5 +
 4 files changed, 126 insertions(+), 1 deletion(-)

New commits:
commit f1af6572d55ed2dde50a84905e4def52d4f3459a
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Wed Jan 22 05:48:02 2014 +0100

    remove unused variable
    
    Change-Id: I07e45a42fc24d5b9169a9d5bc3b47e9d98d7163a

diff --git a/chart2/source/view/main/OpenGLRender.hxx b/chart2/source/view/main/OpenGLRender.hxx
index 9e07c92..21a05cb 100644
--- a/chart2/source/view/main/OpenGLRender.hxx
+++ b/chart2/source/view/main/OpenGLRender.hxx
@@ -298,7 +298,6 @@ private:
     float m_BackgroundColor[16];
     glm::vec4 m_ClearColor;
 
-    PieSegment2DPointList m_PieSegment2DPointList;
     std::list <PieSegment2DPointList> m_PieSegment2DShapePointList;
 
 #if DEBUG_POSITIONING
commit 7dfd469d4f74efd87ecebd7426c2089ec641bf20
Author: Markus Mohrhard <markus.mohrhard at collabora.co.uk>
Date:   Wed Jan 22 05:46:32 2014 +0100

    use a direct method for pie segment crastion
    
    Change-Id: I4b42ebe994b4e498acd32d08a063e4626b3c97d8

diff --git a/chart2/source/view/main/DummyXShape.cxx b/chart2/source/view/main/DummyXShape.cxx
index e2aa4981..e6072c5 100644
--- a/chart2/source/view/main/DummyXShape.cxx
+++ b/chart2/source/view/main/DummyXShape.cxx
@@ -330,168 +330,6 @@ DummyCone::DummyCone(const drawing::Position3D& rPos, const drawing::Direction3D
     setPosition(Position3DToAWTPoint(rPos));
     setSize(Direction3DToAWTSize(rSize));
 }
-void appendAndCloseBezierCoords( drawing::PolyPolygonBezierCoords& rReturn, const drawing::PolyPolygonBezierCoords& rAdd, sal_Bool bAppendInverse )
-{
-    if(!rAdd.Coordinates.getLength())
-        return;
-    sal_Int32 nAddCount = rAdd.Coordinates[0].getLength();
-    if(!nAddCount)
-        return;
-
-    sal_Int32 nOldCount = rReturn.Coordinates[0].getLength();
-
-    rReturn.Coordinates[0].realloc(nOldCount+nAddCount+1);
-    rReturn.Flags[0].realloc(nOldCount+nAddCount+1);
-
-    for(sal_Int32 nN=0;nN<nAddCount; nN++ )
-    {
-        sal_Int32 nAdd = bAppendInverse ? (nAddCount-1-nN) : nN;
-        rReturn.Coordinates[0][nOldCount+nN] = rAdd.Coordinates[0][nAdd];
-        rReturn.Flags[0][nOldCount+nN] = rAdd.Flags[0][nAdd];
-    }
-
-    //close
-    rReturn.Coordinates[0][nOldCount+nAddCount] = rReturn.Coordinates[0][0];
-    rReturn.Flags[0][nOldCount+nAddCount] = rReturn.Flags[0][0];
-}
-
-drawing::PolyPolygonBezierCoords getCircularArcBezierCoords(
-        double fStartAngleRadian, double fWidthAngleRadian, double fUnitRadius
-        , const ::basegfx::B2DHomMatrix& rTransformationFromUnitCircle
-        , const double fAngleSubdivisionRadian )
-{
-    //at least one polygon is created using two normal and two control points
-    //if the angle is larger it is separated into multiple sub angles
-
-    drawing::PolyPolygonBezierCoords aReturn = drawing::PolyPolygonBezierCoords();
-    sal_Int32 nSegmentCount = static_cast< sal_Int32 >( fWidthAngleRadian/fAngleSubdivisionRadian );
-    if( fWidthAngleRadian > fAngleSubdivisionRadian*nSegmentCount )
-        nSegmentCount++;
-
-    double fFirstSegmentAngle = fAngleSubdivisionRadian;
-    double fLastSegmentAngle = fAngleSubdivisionRadian;
-    if(nSegmentCount==1)
-    {
-        fFirstSegmentAngle = fWidthAngleRadian;
-        fLastSegmentAngle = 0.0;
-    }
-    else
-    {
-        double fFirstAngleOnSubDevision = (static_cast<sal_Int32>(fStartAngleRadian/fAngleSubdivisionRadian)+1)*fAngleSubdivisionRadian;
-        if( !::rtl::math::approxEqual( fStartAngleRadian, fFirstAngleOnSubDevision ) )
-            fFirstSegmentAngle = fFirstAngleOnSubDevision-fStartAngleRadian;
-
-        if(nSegmentCount>1)
-        {
-            fLastSegmentAngle = fWidthAngleRadian-fFirstSegmentAngle-fAngleSubdivisionRadian*(nSegmentCount-2);
-            if( fLastSegmentAngle<0 )
-                nSegmentCount--;
-            if( fLastSegmentAngle>fAngleSubdivisionRadian )
-            {
-                fLastSegmentAngle-=fAngleSubdivisionRadian;
-                nSegmentCount++;
-            }
-        }
-    }
-
-    sal_Int32 nPointCount     = 1 + 3*nSegmentCount; //first point of next segment equals last point of former segment
-
-    aReturn.Coordinates = drawing::PointSequenceSequence(1);
-    aReturn.Flags       = drawing::FlagSequenceSequence(1);
-
-    drawing::PointSequence aPoints(nPointCount);
-    drawing::FlagSequence  aFlags(nPointCount);
-
-    //
-
-    //!! applying matrix to vector does ignore translation, so it is important to use a B2DPoint here instead of B2DVector
-    ::basegfx::B2DPoint P0,P1,P2,P3;
-
-    sal_Int32 nPoint=0;
-    double fCurrentRotateAngle = fStartAngleRadian;
-    for(sal_Int32 nSegment=0; nSegment<nSegmentCount; nSegment++)
-    {
-        double fCurrentSegmentAngle = fAngleSubdivisionRadian;
-        if(nSegment==0)//first segment gets only a smaller peace until the next subdevision
-            fCurrentSegmentAngle = fFirstSegmentAngle;
-        else if(nSegment==(nSegmentCount-1)) //the last segment gets the rest angle that does not fit into equal pieces
-            fCurrentSegmentAngle = fLastSegmentAngle;
-
-        //first create untransformed points for a unit circle arc:
-        const double fCos = cos(fCurrentSegmentAngle/2.0);
-        const double fSin = sin(fCurrentSegmentAngle/2.0);
-        P0.setX(fCos);
-        P3.setX(fCos);
-        P0.setY(-fSin);
-        P3.setY(-P0.getY());
-
-        P1.setX((4.0-fCos)/3.0);
-        P2.setX(P1.getX());
-        P1.setY((1.0-fCos)*(fCos-3.0)/(3.0*fSin));
-        P2.setY(-P1.getY());
-        //transform thus startangle equals NULL
-        ::basegfx::B2DHomMatrix aStart;
-        aStart.rotate(fCurrentSegmentAngle/2.0 + fCurrentRotateAngle );
-        fCurrentRotateAngle+=fCurrentSegmentAngle;
-
-        aStart.scale( fUnitRadius, fUnitRadius );
-
-        //apply given transformation to get final points
-        P0 = rTransformationFromUnitCircle*(aStart*P0);
-        P1 = rTransformationFromUnitCircle*(aStart*P1);
-        P2 = rTransformationFromUnitCircle*(aStart*P2);
-        P3 = rTransformationFromUnitCircle*(aStart*P3);
-
-        aPoints[nPoint].X = static_cast< sal_Int32 >( P0.getX());
-        aPoints[nPoint].Y = static_cast< sal_Int32 >( P0.getY());
-        aFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
-
-        aPoints[nPoint].X = static_cast< sal_Int32 >( P1.getX());
-        aPoints[nPoint].Y = static_cast< sal_Int32 >( P1.getY());
-        aFlags[nPoint++] = drawing::PolygonFlags_CONTROL;
-
-        aPoints[nPoint].X = static_cast< sal_Int32 >( P2.getX());
-        aPoints[nPoint].Y = static_cast< sal_Int32 >( P2.getY());
-        aFlags [nPoint++] = drawing::PolygonFlags_CONTROL;
-
-        if(nSegment==(nSegmentCount-1))
-        {
-            aPoints[nPoint].X = static_cast< sal_Int32 >( P3.getX());
-            aPoints[nPoint].Y = static_cast< sal_Int32 >( P3.getY());
-            aFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
-        }
-    }
-
-    aReturn.Coordinates[0] = aPoints;
-    aReturn.Flags[0] = aFlags;
-
-    return aReturn;
-}
-
-
-drawing::PolyPolygonBezierCoords getRingBezierCoords(
-            double fUnitCircleInnerRadius
-            , double fUnitCircleOuterRadius
-            , double fStartAngleRadian, double fWidthAngleRadian
-            , ::basegfx::B2DHomMatrix aTransformationFromUnitCircle
-            , const double fAngleSubdivisionRadian )
-{
-    drawing::PolyPolygonBezierCoords aReturn = drawing::PolyPolygonBezierCoords();
-
-    aReturn.Coordinates = drawing::PointSequenceSequence(1);
-    aReturn.Flags       = drawing::FlagSequenceSequence(1);
-
-    drawing::PolyPolygonBezierCoords aOuterArc = getCircularArcBezierCoords(
-        fStartAngleRadian, fWidthAngleRadian, fUnitCircleOuterRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
-    aReturn.Coordinates[0] = aOuterArc.Coordinates[0];
-    aReturn.Flags[0] = aOuterArc.Flags[0];
-
-    drawing::PolyPolygonBezierCoords aInnerArc = getCircularArcBezierCoords(
-        fStartAngleRadian, fWidthAngleRadian, fUnitCircleInnerRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
-    appendAndCloseBezierCoords( aReturn, aInnerArc, sal_True );
-
-    return aReturn;
-}
 
 DummyPieSegment2D::DummyPieSegment2D(double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree,
         double fUnitCircleInnerRadius, double fUnitCircleOuterRadius,
@@ -512,21 +350,9 @@ void DummyPieSegment2D::render()
         mfUnitCircleWidthAngleDegree -= 360.0;
     while(mfUnitCircleWidthAngleDegree<0)
         mfUnitCircleWidthAngleDegree += 360.0;
-    ::basegfx::B2DHomMatrix aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(maUnitCircleToScene) ) );
-    aTransformationFromUnitCircle.translate(maOffset.DirectionX,maOffset.DirectionY);
-    const double fAngleSubdivisionRadian = F_PI/30.0;
 
-    drawing::PolyPolygonBezierCoords aCoords = getRingBezierCoords(
-                    mfUnitCircleInnerRadius, mfUnitCircleOuterRadius
-                    , mfUnitCircleStartAngleDegree*F_PI/180.0, mfUnitCircleWidthAngleDegree*F_PI/180.0
-                    , aTransformationFromUnitCircle, fAngleSubdivisionRadian );
-
-    sal_Int32 pointCount = aCoords.Coordinates[0].getLength();
-    for (sal_Int32 i = 0; i < pointCount; i++)
-    {
-        com::sun::star::awt::Point p = aCoords.Coordinates[0][i];
-        pChart->m_GLRender.SetPieSegment2DShapePoint((float)p.X, (float)p.Y, pointCount);
-    }
+    pChart->m_GLRender.GeneratePieSegment2D(mfUnitCircleInnerRadius, mfUnitCircleOuterRadius,
+            mfUnitCircleStartAngleDegree, mfUnitCircleWidthAngleDegree);
 
     std::map<OUString, uno::Any>::const_iterator itr = maProperties.find(UNO_NAME_FILLCOLOR);
     if(itr != maProperties.end())
@@ -534,14 +360,17 @@ void DummyPieSegment2D::render()
         sal_Int32 nColor = itr->second.get<sal_Int32>();
         pChart->m_GLRender.SetColor(nColor);
     }
+    /*
     itr = maProperties.find(UNO_NAME_FILL_TRANSPARENCE);
     if(itr != maProperties.end())
     {
         sal_Int32 transparency = itr->second.get<sal_Int32>();
         pChart->m_GLRender.SetTransparency(transparency&(0xFF));
     }
+    */
 
-    pChart->m_GLRender.RenderPieSegment2DShape();
+    float nSize = std::max<float>(maUnitCircleToScene.Line1.Column1, maUnitCircleToScene.Line2.Column2);
+    pChart->m_GLRender.RenderPieSegment2DShape(nSize, maUnitCircleToScene.Line1.Column4, maUnitCircleToScene.Line2.Column4);
 
 }
 
diff --git a/chart2/source/view/main/OpenGLRender.cxx b/chart2/source/view/main/OpenGLRender.cxx
index 0419a57..35f33e4 100644
--- a/chart2/source/view/main/OpenGLRender.cxx
+++ b/chart2/source/view/main/OpenGLRender.cxx
@@ -1726,32 +1726,51 @@ void OpenGLRender::SetChartTransparencyGradient(long transparencyGradient)
         m_BackgroundColor[15] = 0.0;
     }
 }
-int OpenGLRender::SetPieSegment2DShapePoint(float x, float y, int listLength)
+
+void OpenGLRender::GeneratePieSegment2D(double fInnerRadius, double fOutterRadius, double nAngleStart, double nAngleWidth)
 {
-    if (m_PieSegment2DPointList.empty())
+    double nAngleStep = 1;
+    PieSegment2DPointList aPointList;
+    // TODO: moggi: GL_TRIANGLE_FAN seems not to work
+    bool bInnerRadiusNotZero = true; //!rtl::math::approxEqual(0.0, fInnerRadius);
+    size_t nVectorSize = 3*(nAngleWidth/nAngleStep);
+    if(bInnerRadiusNotZero)
+        nVectorSize *= 2;
+
+    aPointList.reserve(nVectorSize);
+    // if inner radius = 0 generate a normal pie segment (triangle fan)
+    // if inner radius != 0 generate a pie segment - inner pie (triangle strip)
+    if(!bInnerRadiusNotZero)
     {
-        m_PieSegment2DPointList.reserve(listLength);
+        aPointList.push_back(0);
+        aPointList.push_back(0);
+        aPointList.push_back(m_fZStep);
     }
-    float actualX = (x / OPENGL_SCALE_VALUE);
-    float actualY = (y / OPENGL_SCALE_VALUE);
-    m_PieSegment2DPointList.push_back(actualX);
-    m_PieSegment2DPointList.push_back(actualY);
-    m_PieSegment2DPointList.push_back(m_fZStep);
-
-    if (m_PieSegment2DPointList.size() == size_t(listLength * 3))
+    for(double nAngle = nAngleStart; nAngle <= nAngleStart + nAngleWidth; nAngle += nAngleStep)
     {
-        m_PieSegment2DShapePointList.push_back(m_PieSegment2DPointList);
-        m_PieSegment2DPointList.clear();
+        float xVal = sin(nAngle/360*2*GL_PI);
+        float yVal = cos(nAngle/360*2*GL_PI);
+        aPointList.push_back(fOutterRadius * xVal);
+        aPointList.push_back(fOutterRadius * yVal);
+        aPointList.push_back(m_fZStep);
+
+        if(bInnerRadiusNotZero)
+        {
+            aPointList.push_back(fInnerRadius * xVal);
+            aPointList.push_back(fInnerRadius * yVal);
+            aPointList.push_back(m_fZStep);
+        }
     }
-    return 0;
+
+    m_PieSegment2DShapePointList.push_back(aPointList);
 }
 
-int OpenGLRender::RenderPieSegment2DShape()
+int OpenGLRender::RenderPieSegment2DShape(float fSize, float fPosX, float fPosY)
 {
     int listNum = m_PieSegment2DShapePointList.size();
-    PosVecf3 trans = {0.0f, 0.0f, 0.0f};
+    PosVecf3 trans = {fPosX/OPENGL_SCALE_VALUE, fPosY/OPENGL_SCALE_VALUE, 0.0f};
     PosVecf3 angle = {0.0f, 0.0f, 0.0f};
-    PosVecf3 scale = {1.0f, 1.0f, 1.0f};
+    PosVecf3 scale = {fSize/OPENGL_SCALE_VALUE, fSize/OPENGL_SCALE_VALUE, 1.0f};
     MoveModelf(trans, angle, scale);
     m_MVP = m_Projection * m_View * m_Model;
 
@@ -1779,10 +1798,11 @@ int OpenGLRender::RenderPieSegment2DShape()
             0,                  // stride
             (void*)0            // array buffer offset
             );
-        glDrawArrays(GL_POLYGON, 0, pointList.size() / 3); // 12*3 indices starting at 0 -> 12 triangles
+        glDrawArrays(GL_TRIANGLE_STRIP, 0, pointList.size() / 3); // 12*3 indices starting at 0 -> 12 triangles
         glDisableVertexAttribArray(m_2DVertexID);
         glUseProgram(0);
         m_PieSegment2DShapePointList.pop_back();
+        CHECK_GL_ERROR();
 
     }
     glEnable(GL_MULTISAMPLE);
diff --git a/chart2/source/view/main/OpenGLRender.hxx b/chart2/source/view/main/OpenGLRender.hxx
index 6f2a8d9..9e07c92 100644
--- a/chart2/source/view/main/OpenGLRender.hxx
+++ b/chart2/source/view/main/OpenGLRender.hxx
@@ -176,8 +176,8 @@ public:
     int RenderArea2DShape();
     void SetChartTransparencyGradient(long transparencyGradient);
 
-    int SetPieSegment2DShapePoint(float x, float y, int listLength);
-    int RenderPieSegment2DShape();
+    void GeneratePieSegment2D(double, double, double, double);
+    int RenderPieSegment2DShape(float, float, float);
 #if DEBUG_POSITIONING
     void renderDebug();
 #endif
commit 4c642254e2d4e877d8fe4c3f0b07392c4588defe
Author: Peilin <peilin at multicorewareinc.com>
Date:   Mon Jan 20 14:47:19 2014 +0800

    piesegment2d gl rendering && mov coords operation to dummy shape
    
    Change-Id: Ic709fe37554cf29b4a644cabdc618c15959593d7

diff --git a/chart2/source/view/inc/DummyXShape.hxx b/chart2/source/view/inc/DummyXShape.hxx
index 7112ac7..9b3eed2 100644
--- a/chart2/source/view/inc/DummyXShape.hxx
+++ b/chart2/source/view/inc/DummyXShape.hxx
@@ -239,7 +239,7 @@ public:
     DummyPieSegment2D(double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree,
             double fUnitCircleInnerRadius, double fUnitCircleOuterRadius,
             const drawing::Direction3D& rOffset, const drawing::HomogenMatrix& rUnitCircleToScene);
-
+    void render();
 private:
     double mfUnitCircleStartAngleDegree;
     double mfUnitCircleWidthAngleDegree;
diff --git a/chart2/source/view/main/DummyXShape.cxx b/chart2/source/view/main/DummyXShape.cxx
index 77fcabd..e2aa4981 100644
--- a/chart2/source/view/main/DummyXShape.cxx
+++ b/chart2/source/view/main/DummyXShape.cxx
@@ -29,6 +29,9 @@
 
 #include <algorithm>
 
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/matrix/b3dhommatrix.hxx>
+
 #define ENABLE_DEBUG_PROPERTIES 0
 
 using namespace com::sun::star;
@@ -327,6 +330,168 @@ DummyCone::DummyCone(const drawing::Position3D& rPos, const drawing::Direction3D
     setPosition(Position3DToAWTPoint(rPos));
     setSize(Direction3DToAWTSize(rSize));
 }
+void appendAndCloseBezierCoords( drawing::PolyPolygonBezierCoords& rReturn, const drawing::PolyPolygonBezierCoords& rAdd, sal_Bool bAppendInverse )
+{
+    if(!rAdd.Coordinates.getLength())
+        return;
+    sal_Int32 nAddCount = rAdd.Coordinates[0].getLength();
+    if(!nAddCount)
+        return;
+
+    sal_Int32 nOldCount = rReturn.Coordinates[0].getLength();
+
+    rReturn.Coordinates[0].realloc(nOldCount+nAddCount+1);
+    rReturn.Flags[0].realloc(nOldCount+nAddCount+1);
+
+    for(sal_Int32 nN=0;nN<nAddCount; nN++ )
+    {
+        sal_Int32 nAdd = bAppendInverse ? (nAddCount-1-nN) : nN;
+        rReturn.Coordinates[0][nOldCount+nN] = rAdd.Coordinates[0][nAdd];
+        rReturn.Flags[0][nOldCount+nN] = rAdd.Flags[0][nAdd];
+    }
+
+    //close
+    rReturn.Coordinates[0][nOldCount+nAddCount] = rReturn.Coordinates[0][0];
+    rReturn.Flags[0][nOldCount+nAddCount] = rReturn.Flags[0][0];
+}
+
+drawing::PolyPolygonBezierCoords getCircularArcBezierCoords(
+        double fStartAngleRadian, double fWidthAngleRadian, double fUnitRadius
+        , const ::basegfx::B2DHomMatrix& rTransformationFromUnitCircle
+        , const double fAngleSubdivisionRadian )
+{
+    //at least one polygon is created using two normal and two control points
+    //if the angle is larger it is separated into multiple sub angles
+
+    drawing::PolyPolygonBezierCoords aReturn = drawing::PolyPolygonBezierCoords();
+    sal_Int32 nSegmentCount = static_cast< sal_Int32 >( fWidthAngleRadian/fAngleSubdivisionRadian );
+    if( fWidthAngleRadian > fAngleSubdivisionRadian*nSegmentCount )
+        nSegmentCount++;
+
+    double fFirstSegmentAngle = fAngleSubdivisionRadian;
+    double fLastSegmentAngle = fAngleSubdivisionRadian;
+    if(nSegmentCount==1)
+    {
+        fFirstSegmentAngle = fWidthAngleRadian;
+        fLastSegmentAngle = 0.0;
+    }
+    else
+    {
+        double fFirstAngleOnSubDevision = (static_cast<sal_Int32>(fStartAngleRadian/fAngleSubdivisionRadian)+1)*fAngleSubdivisionRadian;
+        if( !::rtl::math::approxEqual( fStartAngleRadian, fFirstAngleOnSubDevision ) )
+            fFirstSegmentAngle = fFirstAngleOnSubDevision-fStartAngleRadian;
+
+        if(nSegmentCount>1)
+        {
+            fLastSegmentAngle = fWidthAngleRadian-fFirstSegmentAngle-fAngleSubdivisionRadian*(nSegmentCount-2);
+            if( fLastSegmentAngle<0 )
+                nSegmentCount--;
+            if( fLastSegmentAngle>fAngleSubdivisionRadian )
+            {
+                fLastSegmentAngle-=fAngleSubdivisionRadian;
+                nSegmentCount++;
+            }
+        }
+    }
+
+    sal_Int32 nPointCount     = 1 + 3*nSegmentCount; //first point of next segment equals last point of former segment
+
+    aReturn.Coordinates = drawing::PointSequenceSequence(1);
+    aReturn.Flags       = drawing::FlagSequenceSequence(1);
+
+    drawing::PointSequence aPoints(nPointCount);
+    drawing::FlagSequence  aFlags(nPointCount);
+
+    //
+
+    //!! applying matrix to vector does ignore translation, so it is important to use a B2DPoint here instead of B2DVector
+    ::basegfx::B2DPoint P0,P1,P2,P3;
+
+    sal_Int32 nPoint=0;
+    double fCurrentRotateAngle = fStartAngleRadian;
+    for(sal_Int32 nSegment=0; nSegment<nSegmentCount; nSegment++)
+    {
+        double fCurrentSegmentAngle = fAngleSubdivisionRadian;
+        if(nSegment==0)//first segment gets only a smaller peace until the next subdevision
+            fCurrentSegmentAngle = fFirstSegmentAngle;
+        else if(nSegment==(nSegmentCount-1)) //the last segment gets the rest angle that does not fit into equal pieces
+            fCurrentSegmentAngle = fLastSegmentAngle;
+
+        //first create untransformed points for a unit circle arc:
+        const double fCos = cos(fCurrentSegmentAngle/2.0);
+        const double fSin = sin(fCurrentSegmentAngle/2.0);
+        P0.setX(fCos);
+        P3.setX(fCos);
+        P0.setY(-fSin);
+        P3.setY(-P0.getY());
+
+        P1.setX((4.0-fCos)/3.0);
+        P2.setX(P1.getX());
+        P1.setY((1.0-fCos)*(fCos-3.0)/(3.0*fSin));
+        P2.setY(-P1.getY());
+        //transform thus startangle equals NULL
+        ::basegfx::B2DHomMatrix aStart;
+        aStart.rotate(fCurrentSegmentAngle/2.0 + fCurrentRotateAngle );
+        fCurrentRotateAngle+=fCurrentSegmentAngle;
+
+        aStart.scale( fUnitRadius, fUnitRadius );
+
+        //apply given transformation to get final points
+        P0 = rTransformationFromUnitCircle*(aStart*P0);
+        P1 = rTransformationFromUnitCircle*(aStart*P1);
+        P2 = rTransformationFromUnitCircle*(aStart*P2);
+        P3 = rTransformationFromUnitCircle*(aStart*P3);
+
+        aPoints[nPoint].X = static_cast< sal_Int32 >( P0.getX());
+        aPoints[nPoint].Y = static_cast< sal_Int32 >( P0.getY());
+        aFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
+
+        aPoints[nPoint].X = static_cast< sal_Int32 >( P1.getX());
+        aPoints[nPoint].Y = static_cast< sal_Int32 >( P1.getY());
+        aFlags[nPoint++] = drawing::PolygonFlags_CONTROL;
+
+        aPoints[nPoint].X = static_cast< sal_Int32 >( P2.getX());
+        aPoints[nPoint].Y = static_cast< sal_Int32 >( P2.getY());
+        aFlags [nPoint++] = drawing::PolygonFlags_CONTROL;
+
+        if(nSegment==(nSegmentCount-1))
+        {
+            aPoints[nPoint].X = static_cast< sal_Int32 >( P3.getX());
+            aPoints[nPoint].Y = static_cast< sal_Int32 >( P3.getY());
+            aFlags [nPoint++] = drawing::PolygonFlags_NORMAL;
+        }
+    }
+
+    aReturn.Coordinates[0] = aPoints;
+    aReturn.Flags[0] = aFlags;
+
+    return aReturn;
+}
+
+
+drawing::PolyPolygonBezierCoords getRingBezierCoords(
+            double fUnitCircleInnerRadius
+            , double fUnitCircleOuterRadius
+            , double fStartAngleRadian, double fWidthAngleRadian
+            , ::basegfx::B2DHomMatrix aTransformationFromUnitCircle
+            , const double fAngleSubdivisionRadian )
+{
+    drawing::PolyPolygonBezierCoords aReturn = drawing::PolyPolygonBezierCoords();
+
+    aReturn.Coordinates = drawing::PointSequenceSequence(1);
+    aReturn.Flags       = drawing::FlagSequenceSequence(1);
+
+    drawing::PolyPolygonBezierCoords aOuterArc = getCircularArcBezierCoords(
+        fStartAngleRadian, fWidthAngleRadian, fUnitCircleOuterRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
+    aReturn.Coordinates[0] = aOuterArc.Coordinates[0];
+    aReturn.Flags[0] = aOuterArc.Flags[0];
+
+    drawing::PolyPolygonBezierCoords aInnerArc = getCircularArcBezierCoords(
+        fStartAngleRadian, fWidthAngleRadian, fUnitCircleInnerRadius, aTransformationFromUnitCircle, fAngleSubdivisionRadian );
+    appendAndCloseBezierCoords( aReturn, aInnerArc, sal_True );
+
+    return aReturn;
+}
 
 DummyPieSegment2D::DummyPieSegment2D(double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree,
         double fUnitCircleInnerRadius, double fUnitCircleOuterRadius,
@@ -339,6 +504,46 @@ DummyPieSegment2D::DummyPieSegment2D(double fUnitCircleStartAngleDegree, double
     maUnitCircleToScene(rUnitCircleToScene)
 {
 }
+void DummyPieSegment2D::render()
+{
+    DummyChart* pChart = getRootShape();
+
+    while(mfUnitCircleWidthAngleDegree>360)
+        mfUnitCircleWidthAngleDegree -= 360.0;
+    while(mfUnitCircleWidthAngleDegree<0)
+        mfUnitCircleWidthAngleDegree += 360.0;
+    ::basegfx::B2DHomMatrix aTransformationFromUnitCircle( IgnoreZ( HomogenMatrixToB3DHomMatrix(maUnitCircleToScene) ) );
+    aTransformationFromUnitCircle.translate(maOffset.DirectionX,maOffset.DirectionY);
+    const double fAngleSubdivisionRadian = F_PI/30.0;
+
+    drawing::PolyPolygonBezierCoords aCoords = getRingBezierCoords(
+                    mfUnitCircleInnerRadius, mfUnitCircleOuterRadius
+                    , mfUnitCircleStartAngleDegree*F_PI/180.0, mfUnitCircleWidthAngleDegree*F_PI/180.0
+                    , aTransformationFromUnitCircle, fAngleSubdivisionRadian );
+
+    sal_Int32 pointCount = aCoords.Coordinates[0].getLength();
+    for (sal_Int32 i = 0; i < pointCount; i++)
+    {
+        com::sun::star::awt::Point p = aCoords.Coordinates[0][i];
+        pChart->m_GLRender.SetPieSegment2DShapePoint((float)p.X, (float)p.Y, pointCount);
+    }
+
+    std::map<OUString, uno::Any>::const_iterator itr = maProperties.find(UNO_NAME_FILLCOLOR);
+    if(itr != maProperties.end())
+    {
+        sal_Int32 nColor = itr->second.get<sal_Int32>();
+        pChart->m_GLRender.SetColor(nColor);
+    }
+    itr = maProperties.find(UNO_NAME_FILL_TRANSPARENCE);
+    if(itr != maProperties.end())
+    {
+        sal_Int32 transparency = itr->second.get<sal_Int32>();
+        pChart->m_GLRender.SetTransparency(transparency&(0xFF));
+    }
+
+    pChart->m_GLRender.RenderPieSegment2DShape();
+
+}
 
 DummyPieSegment::DummyPieSegment(double fUnitCircleStartAngleDegree, double fUnitCircleWidthAngleDegree,
         double fUnitCircleInnerRadius, double fUnitCircleOuterRadius,
diff --git a/chart2/source/view/main/OpenGLRender.cxx b/chart2/source/view/main/OpenGLRender.cxx
index d96b219..0419a57 100644
--- a/chart2/source/view/main/OpenGLRender.cxx
+++ b/chart2/source/view/main/OpenGLRender.cxx
@@ -1726,4 +1726,70 @@ void OpenGLRender::SetChartTransparencyGradient(long transparencyGradient)
         m_BackgroundColor[15] = 0.0;
     }
 }
+int OpenGLRender::SetPieSegment2DShapePoint(float x, float y, int listLength)
+{
+    if (m_PieSegment2DPointList.empty())
+    {
+        m_PieSegment2DPointList.reserve(listLength);
+    }
+    float actualX = (x / OPENGL_SCALE_VALUE);
+    float actualY = (y / OPENGL_SCALE_VALUE);
+    m_PieSegment2DPointList.push_back(actualX);
+    m_PieSegment2DPointList.push_back(actualY);
+    m_PieSegment2DPointList.push_back(m_fZStep);
+
+    if (m_PieSegment2DPointList.size() == size_t(listLength * 3))
+    {
+        m_PieSegment2DShapePointList.push_back(m_PieSegment2DPointList);
+        m_PieSegment2DPointList.clear();
+    }
+    return 0;
+}
+
+int OpenGLRender::RenderPieSegment2DShape()
+{
+    int listNum = m_PieSegment2DShapePointList.size();
+    PosVecf3 trans = {0.0f, 0.0f, 0.0f};
+    PosVecf3 angle = {0.0f, 0.0f, 0.0f};
+    PosVecf3 scale = {1.0f, 1.0f, 1.0f};
+    MoveModelf(trans, angle, scale);
+    m_MVP = m_Projection * m_View * m_Model;
+
+    for (int i = 0; i < listNum; i++)
+    {
+        PieSegment2DPointList &pointList = m_PieSegment2DShapePointList.back();
+        //fill vertex buffer
+        glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+        glBufferData(GL_ARRAY_BUFFER, pointList.size() * sizeof(float), &pointList[0] , GL_STATIC_DRAW);
+        // Use our shader
+        glUseProgram(m_CommonProID);
+
+        glUniform4fv(m_2DColorID, 1, &m_2DColor[0]);
+
+        glUniformMatrix4fv(m_MatrixID, 1, GL_FALSE, &m_MVP[0][0]);
+
+        // 1rst attribute buffer : vertices
+        glEnableVertexAttribArray(m_2DVertexID);
+        glBindBuffer(GL_ARRAY_BUFFER, m_VertexBuffer);
+        glVertexAttribPointer(
+            m_2DVertexID,                  // attribute. No particular reason for 0, but must match the layout in the shader.
+            3,                  // size
+            GL_FLOAT,           // type
+            GL_FALSE,           // normalized?
+            0,                  // stride
+            (void*)0            // array buffer offset
+            );
+        glDrawArrays(GL_POLYGON, 0, pointList.size() / 3); // 12*3 indices starting at 0 -> 12 triangles
+        glDisableVertexAttribArray(m_2DVertexID);
+        glUseProgram(0);
+        m_PieSegment2DShapePointList.pop_back();
+
+    }
+    glEnable(GL_MULTISAMPLE);
+    m_fZStep += 0.01f;
+
+    CHECK_GL_ERROR();
+    return 0;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/chart2/source/view/main/OpenGLRender.hxx b/chart2/source/view/main/OpenGLRender.hxx
index 435e76d..6f2a8d9 100644
--- a/chart2/source/view/main/OpenGLRender.hxx
+++ b/chart2/source/view/main/OpenGLRender.hxx
@@ -100,6 +100,7 @@ typedef struct TextInfo
 }TextInfo;
 
 typedef std::vector<GLfloat> Area2DPointList;
+typedef std::vector<GLfloat> PieSegment2DPointList;
 
 /// Holds the information of our new child window
 struct GLWindow
@@ -175,6 +176,8 @@ public:
     int RenderArea2DShape();
     void SetChartTransparencyGradient(long transparencyGradient);
 
+    int SetPieSegment2DShapePoint(float x, float y, int listLength);
+    int RenderPieSegment2DShape();
 #if DEBUG_POSITIONING
     void renderDebug();
 #endif
@@ -295,6 +298,9 @@ private:
     float m_BackgroundColor[16];
     glm::vec4 m_ClearColor;
 
+    PieSegment2DPointList m_PieSegment2DPointList;
+    std::list <PieSegment2DPointList> m_PieSegment2DShapePointList;
+
 #if DEBUG_POSITIONING
     GLuint m_DebugProID;
     GLuint m_DebugVertexID;


More information about the Libreoffice-commits mailing list