diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index e830c38b06..c7a6a5f495 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -294,6 +294,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) { if( isFillEnabled ) { + currentManager->Reserve( 3 ); currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); /* Draw a triangle that contains the circle, then shade it leaving only the circle. @@ -320,6 +321,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) if( isStrokeEnabled ) { + currentManager->Reserve( 3 ); currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a ); /* Draw a triangle that contains the circle, then shade it leaving only the circle. @@ -394,6 +396,7 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a // Triangle fan for( alpha = aStartAngle; ( alpha + alphaIncrement ) < aEndAngle; ) { + currentManager->Reserve( 3 ); currentManager->Vertex( 0.0, 0.0, 0.0 ); currentManager->Vertex( cos( alpha ) * aRadius, sin( alpha ) * aRadius, 0.0 ); alpha += alphaIncrement; @@ -402,6 +405,8 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a // The last missing triangle const VECTOR2D endPoint( cos( aEndAngle ) * aRadius, sin( aEndAngle ) * aRadius ); + + currentManager->Reserve( 3 ); currentManager->Vertex( 0.0, 0.0, 0.0 ); currentManager->Vertex( cos( alpha ) * aRadius, sin( alpha ) * aRadius, 0.0 ); currentManager->Vertex( endPoint.x, endPoint.y, 0.0 ); @@ -434,6 +439,7 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn // Fill the rectangle if( isFillEnabled ) { + currentManager->Reserve( 6 ); currentManager->Shader( SHADER_NONE ); currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); @@ -868,6 +874,8 @@ void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd glm::vec4 vector = currentManager->GetTransformation() * glm::vec4( -startEndVector.y * scale, startEndVector.x * scale, 0.0, 0.0 ); + currentManager->Reserve( 6 ); + // Line width is maintained by the vertex shader currentManager->Shader( SHADER_LINE, vector.x, vector.y, lineWidth ); currentManager->Vertex( aStartPoint.x, aStartPoint.y, layerDepth ); // v0 @@ -909,6 +917,8 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad double aAngle ) { Save(); + + currentManager->Reserve( 3 ); currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0f ); currentManager->Rotate( aAngle, 0.0f, 0.0f, 1.0f ); @@ -940,6 +950,8 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa double outerRadius = aRadius + ( lineWidth / 2 ); Save(); + + currentManager->Reserve( 3 ); currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0f ); currentManager->Rotate( aAngle, 0.0f, 0.0f, 1.0f ); diff --git a/common/gal/opengl/vertex_manager.cpp b/common/gal/opengl/vertex_manager.cpp index d055b52169..4f65608ff9 100644 --- a/common/gal/opengl/vertex_manager.cpp +++ b/common/gal/opengl/vertex_manager.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 CERN + * Copyright (C) 2013-2016 CERN * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -38,7 +38,7 @@ using namespace KIGFX; VERTEX_MANAGER::VERTEX_MANAGER( bool aCached ) : - m_noTransform( true ), m_transform( 1.0f ) + m_noTransform( true ), m_transform( 1.0f ), m_reserved( NULL ), m_reservedSpace( 0 ) { m_container.reset( VERTEX_CONTAINER::MakeContainer( aCached ) ); m_gpu.reset( GPU_MANAGER::MakeManager( m_container.get() ) ); @@ -49,13 +49,50 @@ VERTEX_MANAGER::VERTEX_MANAGER( bool aCached ) : } -void VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ ) const +void VERTEX_MANAGER::Reserve( unsigned int aSize ) +{ + assert( m_reservedSpace == 0 && m_reserved == NULL ); + + // flag to avoid hanging by calling DisplayError too many times: + static bool show_err = true; + + m_reserved = m_container->Allocate( aSize ); + + if( m_reserved == NULL ) + { + if( show_err ) + { + DisplayError( NULL, wxT( "VERTEX_MANAGER::Reserve: Vertex allocation error" ) ); + show_err = false; + } + + return; + } + + m_reservedSpace = aSize; +} + + +void VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ ) { // flag to avoid hanging by calling DisplayError too many times: static bool show_err = true; // Obtain the pointer to the vertex in the currently used container - VERTEX* newVertex = m_container->Allocate( 1 ); + VERTEX* newVertex; + + if( m_reservedSpace > 0 ) + { + newVertex = m_reserved++; + --m_reservedSpace; + + if( m_reservedSpace == 0 ) + m_reserved = NULL; + } + else + { + newVertex = m_container->Allocate( 1 ); + } if( newVertex == NULL ) { @@ -72,7 +109,7 @@ void VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ ) const } -void VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize ) const +void VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize ) { // flag to avoid hanging by calling DisplayError too many times: static bool show_err = true; diff --git a/include/gal/opengl/vertex_manager.h b/include/gal/opengl/vertex_manager.h index fe6c5e6433..c7455aecea 100644 --- a/include/gal/opengl/vertex_manager.h +++ b/include/gal/opengl/vertex_manager.h @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2013 CERN + * Copyright (C) 2013-2016 CERN * @author Maciej Suminski * * This program is free software; you can redistribute it and/or @@ -58,6 +58,14 @@ public: */ VERTEX_MANAGER( bool aCached ); + /** + * Function Reserve() + * allocates space for vertices, so it will be used with subsequent Vertex() calls. + * + * @param aSize is the number of vertices that should be available in the reserved space. + */ + void Reserve( unsigned int aSize ); + /** * Function Vertex() * adds a vertex with the given coordinates to the currently set item. Color & shader @@ -67,7 +75,7 @@ public: * * @param aVertex contains vertex coordinates. */ - inline void Vertex( const VERTEX& aVertex ) const + inline void Vertex( const VERTEX& aVertex ) { Vertex( aVertex.x, aVertex.y, aVertex.z ); } @@ -81,7 +89,7 @@ public: * @param aY is the Y coordinate of the new vertex. * @param aZ is the Z coordinate of the new vertex. */ - void Vertex( GLfloat aX, GLfloat aY, GLfloat aZ ) const; + void Vertex( GLfloat aX, GLfloat aY, GLfloat aZ ); /** * Function Vertices() @@ -94,7 +102,7 @@ public: * @param aVertices contains vertices to be added * @param aSize is the number of vertices to be added. */ - void Vertices( const VERTEX aVertices[], unsigned int aSize ) const; + void Vertices( const VERTEX aVertices[], unsigned int aSize ); /** * Function Color() @@ -340,6 +348,12 @@ protected: GLubyte m_color[ColorStride]; /// Currently used shader and its parameters GLfloat m_shader[ShaderStride]; + + /// Currently reserved chunk to store vertices + VERTEX* m_reserved; + + /// Currently available reserved space + unsigned int m_reservedSpace; }; } // namespace KIGFX