Faster circles & semicircles drawing for the shaderless OpenGL backend. Removed unnecessary variables and computations.
This commit is contained in:
parent
332a7b4bd9
commit
628c069a39
|
@ -118,17 +118,13 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
|
||||||
gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
|
gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE );
|
||||||
|
|
||||||
// Buffered semicircle & circle vertices
|
// Buffered semicircle & circle vertices
|
||||||
// (3 vertices per triangle) * (2 items [circle&semicircle]) * (number of points per item)
|
// (3 vertices per triangle) * (number of points to draw a circle)
|
||||||
precomputedContainer = new VBO_CONTAINER( 3 * 2 * CIRCLE_POINTS );
|
precomputedContainer = new VBO_CONTAINER( 3 * CIRCLE_POINTS );
|
||||||
|
|
||||||
// Compute the unit circles, used for speed up of the circle drawing
|
// Compute the unit circles, used for speed up of the circle drawing
|
||||||
verticesCircle = new VBO_ITEM( precomputedContainer );
|
verticesCircle = new VBO_ITEM( precomputedContainer );
|
||||||
computeUnitCircle();
|
computeUnitCircle();
|
||||||
verticesCircle->Finish();
|
verticesCircle->Finish();
|
||||||
|
|
||||||
verticesSemiCircle = new VBO_ITEM( precomputedContainer );
|
|
||||||
computeUnitSemiCircle();
|
|
||||||
verticesSemiCircle->Finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,7 +133,6 @@ OPENGL_GAL::~OPENGL_GAL()
|
||||||
glFlush();
|
glFlush();
|
||||||
|
|
||||||
delete verticesCircle;
|
delete verticesCircle;
|
||||||
delete verticesSemiCircle;
|
|
||||||
delete precomputedContainer;
|
delete precomputedContainer;
|
||||||
|
|
||||||
// Delete the buffers
|
// Delete the buffers
|
||||||
|
@ -1108,30 +1103,45 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||||
if( innerScale < outerScale )
|
if( innerScale < outerScale )
|
||||||
{
|
{
|
||||||
// Draw the outline
|
// Draw the outline
|
||||||
|
VBO_VERTEX* circle = verticesCircle->GetVertices();
|
||||||
|
int next;
|
||||||
|
|
||||||
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
|
|
||||||
translate3( aCenterPoint.x, aCenterPoint.y, layerDepth );
|
translate3( aCenterPoint.x, aCenterPoint.y, 0.0 );
|
||||||
Scale( VECTOR2D( aRadius, aRadius ) );
|
Scale( VECTOR2D( aRadius, aRadius ) );
|
||||||
|
|
||||||
begin( GL_TRIANGLES );
|
begin( GL_TRIANGLES );
|
||||||
|
|
||||||
for( std::deque<VECTOR2D>::const_iterator it = unitCirclePoints.begin();
|
for( int i = 0; i < 3 * CIRCLE_POINTS; ++i )
|
||||||
it != unitCirclePoints.end(); it++ )
|
|
||||||
{
|
{
|
||||||
double v0[] = { it->x * innerScale, it->y * innerScale };
|
// verticesCircle contains precomputed circle points interleaved with vertex
|
||||||
double v1[] = { it->x * outerScale, it->y * outerScale };
|
// (0,0,0), so filled circles can be drawn as consecutive triangles, ie:
|
||||||
double v2[] = { ( it + 1 )->x * innerScale, ( it + 1 )->y * innerScale };
|
// { 0,a,b, 0,c,d, 0,e,f, 0,g,h, ... }
|
||||||
double v3[] = { ( it + 1 )->x * outerScale, ( it + 1 )->y * outerScale };
|
// where letters stand for consecutive circle points and 0 for (0,0,0) vertex.
|
||||||
|
|
||||||
vertex3( v0[0], v0[1], 0.0 );
|
// We have to skip all (0,0,0) vertices (every third vertex)
|
||||||
vertex3( v1[0], v1[1], 0.0 );
|
if( i % 3 == 0)
|
||||||
vertex3( v2[0], v2[1], 0.0 );
|
{
|
||||||
|
i++;
|
||||||
|
// Depending on the vertex, next circle point may be stored in the next vertex..
|
||||||
|
next = i + 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ..or 2 vertices away (in case it is preceded by (0,0,0) vertex)
|
||||||
|
next = i + 2;
|
||||||
|
}
|
||||||
|
|
||||||
vertex3( v1[0], v1[1], 0.0 );
|
vertex3( circle[i].x * innerScale, circle[i].y * innerScale, layerDepth );
|
||||||
vertex3( v3[0], v3[1], 0.0 );
|
vertex3( circle[i].x * outerScale, circle[i].y * outerScale, layerDepth );
|
||||||
vertex3( v2[0], v2[1], 0.0 );
|
vertex3( circle[next].x * innerScale, circle[next].y * innerScale, layerDepth );
|
||||||
|
|
||||||
|
vertex3( circle[i].x * outerScale, circle[i].y * outerScale, layerDepth );
|
||||||
|
vertex3( circle[next].x * outerScale, circle[next].y * outerScale, layerDepth );
|
||||||
|
vertex3( circle[next].x * innerScale, circle[next].y * innerScale, layerDepth );
|
||||||
}
|
}
|
||||||
|
|
||||||
end();
|
end();
|
||||||
|
@ -1151,14 +1161,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||||
|
|
||||||
if( isGrouping )
|
if( isGrouping )
|
||||||
{
|
{
|
||||||
// Multiplied by 3, as this is the number of vertices in a single triangle
|
currentGroup->PushVertices( verticesCircle->GetVertices(), CIRCLE_POINTS * 3 );
|
||||||
VBO_VERTEX* circle = new VBO_VERTEX[CIRCLE_POINTS * 3];
|
|
||||||
|
|
||||||
memcpy( circle, verticesCircle->GetVertices(),
|
|
||||||
VBO_ITEM::VertByteSize * CIRCLE_POINTS * 3 );
|
|
||||||
currentGroup->PushVertices( circle, CIRCLE_POINTS * 3 );
|
|
||||||
|
|
||||||
delete[] circle;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1208,14 +1211,8 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d
|
||||||
|
|
||||||
if( isGrouping )
|
if( isGrouping )
|
||||||
{
|
{
|
||||||
// Multiplied by 3, as this is the number of vertices in a single triangle
|
// It is enough just to push just a half of the circle vertices to make a semicircle
|
||||||
VBO_VERTEX* semiCircle = new VBO_VERTEX[CIRCLE_POINTS / 2 * 3];
|
currentGroup->PushVertices( verticesCircle->GetVertices(), CIRCLE_POINTS / 2 * 3 );
|
||||||
|
|
||||||
memcpy( semiCircle, verticesSemiCircle->GetVertices(),
|
|
||||||
VBO_ITEM::VertByteSize * CIRCLE_POINTS / 2 * 3 );
|
|
||||||
currentGroup->PushVertices( semiCircle, CIRCLE_POINTS / 2 * 3 );
|
|
||||||
|
|
||||||
delete[] semiCircle;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1668,15 +1665,16 @@ void OPENGL_GAL::computeUnitCircle()
|
||||||
|
|
||||||
// Compute the circle points for a given number of segments
|
// Compute the circle points for a given number of segments
|
||||||
// Insert in a display list and a vector
|
// Insert in a display list and a vector
|
||||||
|
const VBO_VERTEX v0 = { 0.0f, 0.0f, 0.0f };
|
||||||
|
|
||||||
for( int i = 0; i < CIRCLE_POINTS; i++ )
|
for( int i = 0; i < CIRCLE_POINTS; i++ )
|
||||||
{
|
{
|
||||||
VBO_VERTEX v0 = { 0.0f, 0.0f, 0.0f };
|
const VBO_VERTEX v1 = {
|
||||||
VBO_VERTEX v1 = {
|
|
||||||
cos( 2.0 * M_PI / CIRCLE_POINTS * i ), // x
|
cos( 2.0 * M_PI / CIRCLE_POINTS * i ), // x
|
||||||
sin( 2.0 * M_PI / CIRCLE_POINTS * i ), // y
|
sin( 2.0 * M_PI / CIRCLE_POINTS * i ), // y
|
||||||
0.0f // z
|
0.0f // z
|
||||||
};
|
};
|
||||||
VBO_VERTEX v2 = {
|
const VBO_VERTEX v2 = {
|
||||||
cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ), // x
|
cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ), // x
|
||||||
sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ), // y
|
sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ), // y
|
||||||
0.0f // z
|
0.0f // z
|
||||||
|
@ -1687,11 +1685,9 @@ void OPENGL_GAL::computeUnitCircle()
|
||||||
|
|
||||||
glVertex2d( v1.x, v1.y );
|
glVertex2d( v1.x, v1.y );
|
||||||
verticesCircle->PushVertex( &v1 );
|
verticesCircle->PushVertex( &v1 );
|
||||||
unitCirclePoints.push_back( VECTOR2D( v1.x, v1.y ) ); // TODO remove
|
|
||||||
|
|
||||||
glVertex2d( v2.x, v2.y );
|
glVertex2d( v2.x, v2.y );
|
||||||
verticesCircle->PushVertex( &v2 );
|
verticesCircle->PushVertex( &v2 );
|
||||||
unitCirclePoints.push_back( VECTOR2D( v2.x, v2.y ) ); // TODO remove
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
@ -1709,26 +1705,11 @@ void OPENGL_GAL::computeUnitSemiCircle()
|
||||||
|
|
||||||
for( int i = 0; i < CIRCLE_POINTS / 2; ++i )
|
for( int i = 0; i < CIRCLE_POINTS / 2; ++i )
|
||||||
{
|
{
|
||||||
VBO_VERTEX v0 = { 0.0f, 0.0f, 0.0f };
|
glVertex2d( 0.0, 0.0 );
|
||||||
VBO_VERTEX v1 = {
|
glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * i ),
|
||||||
cos( 2.0 * M_PI / CIRCLE_POINTS * i ), // x
|
sin( 2.0 * M_PI / CIRCLE_POINTS * i ) );
|
||||||
sin( 2.0 * M_PI / CIRCLE_POINTS * i ), // y
|
glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ),
|
||||||
0.0f // z
|
sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ) );
|
||||||
};
|
|
||||||
VBO_VERTEX v2 = {
|
|
||||||
cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ), // x
|
|
||||||
sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ), // y
|
|
||||||
0.0f // z
|
|
||||||
};
|
|
||||||
|
|
||||||
glVertex2d( 0, 0 );
|
|
||||||
verticesSemiCircle->PushVertex( &v0 );
|
|
||||||
|
|
||||||
glVertex2d( v1.x, v1.y );
|
|
||||||
verticesSemiCircle->PushVertex( &v1 );
|
|
||||||
|
|
||||||
glVertex2d( v2.x, v2.y );
|
|
||||||
verticesSemiCircle->PushVertex( &v2 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
|
@ -358,7 +358,6 @@ private:
|
||||||
GLuint displayListCircle; ///< Circle display list
|
GLuint displayListCircle; ///< Circle display list
|
||||||
VBO_ITEM* verticesCircle;
|
VBO_ITEM* verticesCircle;
|
||||||
GLuint displayListSemiCircle; ///< Semi circle display list
|
GLuint displayListSemiCircle; ///< Semi circle display list
|
||||||
VBO_ITEM* verticesSemiCircle;
|
|
||||||
|
|
||||||
// Vertex buffer objects related fields
|
// Vertex buffer objects related fields
|
||||||
std::map<unsigned int, VBO_ITEM*> groups; ///< Stores informations about VBO objects (groups)
|
std::map<unsigned int, VBO_ITEM*> groups; ///< Stores informations about VBO objects (groups)
|
||||||
|
@ -374,10 +373,6 @@ private:
|
||||||
int indicesSize; ///< Number of indices to be drawn
|
int indicesSize; ///< Number of indices to be drawn
|
||||||
GLuint* indicesPtr; ///< Pointer to mapped GPU memory
|
GLuint* indicesPtr; ///< Pointer to mapped GPU memory
|
||||||
|
|
||||||
double curvePoints[12]; ///< Coefficients for curves
|
|
||||||
// FIXME to be removed:
|
|
||||||
std::deque<VECTOR2D> unitCirclePoints; ///< List of the points on a unit circle
|
|
||||||
|
|
||||||
// Polygon tesselation
|
// Polygon tesselation
|
||||||
GLUtesselator* tesselator; ///< Pointer to the tesselator
|
GLUtesselator* tesselator; ///< Pointer to the tesselator
|
||||||
std::vector<GLdouble*> tessIntersects; ///< Storage of intersecting points
|
std::vector<GLdouble*> tessIntersects; ///< Storage of intersecting points
|
||||||
|
|
Loading…
Reference in New Issue