From d8e45ef8663a7711d3fc5ae50d5abf5fa81cf042 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 4 Jul 2013 16:27:27 +0200 Subject: [PATCH] Fixed drawing circles and semicircles using display lists. --- common/gal/opengl/opengl_gal.cpp | 57 +++++++++++++++++--------------- include/gal/opengl/opengl_gal.h | 21 +++++------- 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 5687162c7d..162a2c85e8 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -66,7 +66,6 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); // Initialize the flags - isCreated = false; isDeleteSavedPixels = true; isGlewInitialized = false; isFrameBufferInitialized = false; @@ -114,14 +113,8 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, InitTesselatorCallbacks( tesselator ); gluTessProperty( tesselator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE ); - // Buffered semicircle & circle vertices - // (3 vertices per triangle) * (number of points to draw a circle) - precomputedContainer = new VBO_CONTAINER( 3 * CIRCLE_POINTS ); - - // Compute the unit circles, used for speed up of the circle drawing - verticesCircle = new VBO_ITEM( precomputedContainer ); - computeUnitCircle(); - verticesCircle->Finish(); + // Compute unit semicircle & circle vertices and store them in a buffer for faster drawing + computeCircleVbo(); } @@ -129,6 +122,11 @@ OPENGL_GAL::~OPENGL_GAL() { glFlush(); + if( glIsList( displayListSemiCircle ) ) + glDeleteLists( displayListSemiCircle, 1 ); + if( glIsList( displayListCircle ) ) + glDeleteLists( displayListCircle, 1 ); + delete verticesCircle; delete precomputedContainer; @@ -331,6 +329,7 @@ void OPENGL_GAL::initGlew() } initVertexBufferObjects(); + computeCircleDisplayLists(); isGlewInitialized = true; } @@ -1502,12 +1501,11 @@ void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth ) } -void OPENGL_GAL::computeUnitCircle() +void OPENGL_GAL::computeCircleVbo() { - displayListCircle = glGenLists( 1 ); - glNewList( displayListCircle, GL_COMPILE ); - - glBegin( GL_TRIANGLES ); + // (3 vertices per triangle) * (number of points to draw a circle) + precomputedContainer = new VBO_CONTAINER( 3 * CIRCLE_POINTS ); + verticesCircle = new VBO_ITEM( precomputedContainer ); // Compute the circle points for a given number of segments // Insert in a display list and a vector @@ -1526,29 +1524,38 @@ void OPENGL_GAL::computeUnitCircle() 0.0f // z }; - glVertex2d( 0, 0 ); verticesCircle->PushVertex( &v0 ); - - glVertex2d( v1.x, v1.y ); verticesCircle->PushVertex( &v1 ); - - glVertex2d( v2.x, v2.y ); verticesCircle->PushVertex( &v2 ); } - glEnd(); - - glEndList(); + verticesCircle->Finish(); } -void OPENGL_GAL::computeUnitSemiCircle() +void OPENGL_GAL::computeCircleDisplayLists() { + // Circle display list + displayListCircle = glGenLists( 1 ); + glNewList( displayListCircle, GL_COMPILE ); + + glBegin( GL_TRIANGLES ); + for( int i = 0; i < CIRCLE_POINTS; ++i ) + { + glVertex2d( 0.0, 0.0 ); + glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * i ), + sin( 2.0 * M_PI / CIRCLE_POINTS * i ) ); + glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ), + sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ) ); + } + glEnd(); + glEndList(); + + // Semicircle display list displayListSemiCircle = glGenLists( 1 ); glNewList( displayListSemiCircle, GL_COMPILE ); glBegin( GL_TRIANGLES ); - for( int i = 0; i < CIRCLE_POINTS / 2; ++i ) { glVertex2d( 0.0, 0.0 ); @@ -1557,9 +1564,7 @@ void OPENGL_GAL::computeUnitSemiCircle() glVertex2d( cos( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ), sin( 2.0 * M_PI / CIRCLE_POINTS * ( i + 1 ) ) ); } - glEnd(); - glEndList(); } diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index 5fb345f881..0304ead7e1 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -337,10 +337,10 @@ private: wxEvtHandler* mouseListener; wxEvtHandler* paintListener; - // Display lists (used in shaderless mode) + // VBO buffers & display lists (used in immediate mode) VBO_CONTAINER* precomputedContainer; ///< Container for storing display lists + VBO_ITEM* verticesCircle; ///< Buffer for circle & semicircle vertices GLuint displayListCircle; ///< Circle display list - VBO_ITEM* verticesCircle; GLuint displayListSemiCircle; ///< Semi circle display list // Vertex buffer objects related fields @@ -372,8 +372,8 @@ private: SHADER_STROKED_CIRCLE, } SHADER_TYPE; - SHADER shader; ///< There is only one shader used for different objects - int shaderAttrib; ///< Location of shader attributes (for glVertexAttribPointer) + SHADER shader; ///< There is only one shader used for different objects + int shaderAttrib; ///< Location of shader attributes (for glVertexAttribPointer) // Cursor int cursorSize; ///< Size of the cursor in pixels @@ -391,7 +391,6 @@ private: GLuint textureBackup; ///< Backup texture handle // Internal flags - bool isCreated; bool isGlewInitialized; ///< Is GLEW initialized? bool isFrameBufferInitialized; ///< Are the frame buffers initialized? bool isVboInitialized; @@ -412,14 +411,12 @@ private: void drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle ); void drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle ); - /// Compute the points of a unit circle. - void computeUnitCircle(); + /// Compute the points of an unit circle & semicircle and store them in VBO. + void computeCircleVbo(); - /// Compute the points of a unit semi circle. - void computeUnitSemiCircle(); - - /// Compute the points of a unit arc. - // void computeUnitArcs(); // TODO not used + /// Compute the points of an unit circle & semicircle and store them in display lists + /// for drawing in immediate mode. + void computeCircleDisplayLists(); // Event handling /**