[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