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