summaryrefslogtreecommitdiff
path: root/chart2/source
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@collabora.co.uk>2014-01-22 05:46:32 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2014-01-29 08:09:55 +0100
commit093fa2a359a7a25644e3983e6c525296d6bfe05c (patch)
tree8861803ae33ab6db68ca9517b136c3845c4f5dae /chart2/source
parent82ed9053e7353fe784cebac4d249cad5ed4a2bf4 (diff)
use a direct method for pie segment crastion
Change-Id: I4b42ebe994b4e498acd32d08a063e4626b3c97d8
Diffstat (limited to 'chart2/source')
-rw-r--r--chart2/source/view/main/DummyXShape.cxx183
-rwxr-xr-xchart2/source/view/main/OpenGLRender.cxx54
-rwxr-xr-xchart2/source/view/main/OpenGLRender.hxx4
3 files changed, 45 insertions, 196 deletions
diff --git a/chart2/source/view/main/DummyXShape.cxx b/chart2/source/view/main/DummyXShape.cxx
index 70d94c11ffdc..4788390c114c 100644
--- a/chart2/source/view/main/DummyXShape.cxx
+++ b/chart2/source/view/main/DummyXShape.cxx
@@ -324,168 +324,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,
@@ -506,21 +344,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())
@@ -528,14 +354,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 0419a5777916..35f33e43b6b7 100755
--- 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 6f2a8d91e953..9e07c928d848 100755
--- 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