From 332a7b4bd90fba6af92c65a48df6f1f77b237120 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Thu, 27 Jun 2013 11:54:49 +0200 Subject: [PATCH] Groups are stored in map instead of deque, so it allows easier adding & removing. --- common/gal/cairo/cairo_gal.cpp | 58 ++++++++++++++++++++----------- common/gal/opengl/opengl_gal.cpp | 59 ++++++++++++++++++++------------ include/gal/cairo/cairo_gal.h | 12 +++++-- include/gal/opengl/opengl_gal.h | 15 ++++++-- 4 files changed, 98 insertions(+), 46 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 6e30bea899..18f07f94c6 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -31,6 +31,8 @@ #include #include +#include + using namespace KiGfx; CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, @@ -50,6 +52,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, isInitialized = false; isDeleteSavedPixels = false; zoomFactor = 1.0; + groupCounter = 0; SetSize( aParent->GetSize() ); @@ -200,6 +203,20 @@ void CAIRO_GAL::deinitSurface() } +unsigned int CAIRO_GAL::getGroupNumber() +{ + wxASSERT_MSG( groups.size() < std::numeric_limits::max(), + wxT( "There are no free slots to store a group" ) ); + + while( groups.find( groupCounter ) != groups.end() ) + { + groupCounter++; + } + + return groupCounter++; +} + + void CAIRO_GAL::BeginDrawing() throw( int ) { initSurface(); @@ -429,7 +446,7 @@ void CAIRO_GAL::SetIsFill( bool aIsFillEnabled ) GroupElement groupElement; groupElement.command = CMD_SET_FILL; groupElement.boolArgument = aIsFillEnabled; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -444,7 +461,7 @@ void CAIRO_GAL::SetIsStroke( bool aIsStrokeEnabled ) GroupElement groupElement; groupElement.command = CMD_SET_STROKE; groupElement.boolArgument = aIsStrokeEnabled; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -463,7 +480,7 @@ void CAIRO_GAL::SetStrokeColor( const COLOR4D& aColor ) groupElement.arguments[1] = strokeColor.g; groupElement.arguments[2] = strokeColor.b; groupElement.arguments[3] = strokeColor.a; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -481,7 +498,7 @@ void CAIRO_GAL::SetFillColor( const COLOR4D& aColor ) groupElement.arguments[1] = fillColor.g; groupElement.arguments[2] = fillColor.b; groupElement.arguments[3] = fillColor.a; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -498,7 +515,7 @@ void CAIRO_GAL::SetLineWidth( double aLineWidth ) GroupElement groupElement; groupElement.command = CMD_SET_LINE_WIDTH; groupElement.arguments[0] = aLineWidth; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -516,7 +533,7 @@ void CAIRO_GAL::SetLineCap( LineCap aLineCap ) GroupElement groupElement; groupElement.command = CMD_SET_LINE_CAP; groupElement.intArgument = (int) aLineCap; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -534,7 +551,7 @@ void CAIRO_GAL::SetLineJoin( LineJoin aLineJoin ) GroupElement groupElement; groupElement.command = CMD_SET_LINE_JOIN; groupElement.intArgument = (int) aLineJoin; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -592,7 +609,7 @@ void CAIRO_GAL::Rotate( double aAngle ) GroupElement groupElement; groupElement.command = CMD_ROTATE; groupElement.arguments[0] = aAngle; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -609,7 +626,7 @@ void CAIRO_GAL::Translate( const VECTOR2D& aTranslation ) groupElement.command = CMD_TRANSLATE; groupElement.arguments[0] = aTranslation.x; groupElement.arguments[1] = aTranslation.y; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -626,7 +643,7 @@ void CAIRO_GAL::Scale( const VECTOR2D& aScale ) groupElement.command = CMD_SCALE; groupElement.arguments[0] = aScale.x; groupElement.arguments[1] = aScale.y; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -641,7 +658,7 @@ void CAIRO_GAL::Save() { GroupElement groupElement; groupElement.command = CMD_SAVE; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -656,7 +673,7 @@ void CAIRO_GAL::Restore() { GroupElement groupElement; groupElement.command = CMD_RESTORE; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } @@ -668,10 +685,14 @@ int CAIRO_GAL::BeginGroup() // If the grouping is started: the actual path is stored in the group, when // a attribute was changed or when grouping stops with the end group method. storePath(); + Group group; - groups.push_back( group ); + int groupNumber = getGroupNumber(); + groups.insert( std::make_pair( groupNumber, group ) ); + currentGroup = &groups[groupNumber]; isGrouping = true; - return groups.size() - 1; + + return groupNumber; } @@ -708,7 +729,7 @@ void CAIRO_GAL::DeleteGroup( int aGroupNumber ) } // Delete the group - groups.erase( groups.begin() + aGroupNumber ); + groups.erase( aGroupNumber ); } @@ -879,15 +900,12 @@ void CAIRO_GAL::storePath() // Copy the actual path, append it to the global path list // then check, if the path needs to be stroked/filled and // add this command to the group list; - - // pathList.push_back( path ); // FIXME: it's not used anywhere else? - if( isStrokeEnabled ) { GroupElement groupElement; groupElement.cairoPath = cairo_copy_path( cairoImage ); groupElement.command = CMD_STROKE_PATH; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } if( isFillEnabled ) @@ -895,7 +913,7 @@ void CAIRO_GAL::storePath() GroupElement groupElement; groupElement.cairoPath = cairo_copy_path( cairoImage ); groupElement.command = CMD_FILL_PATH; - groups.back().push_back( groupElement ); + currentGroup->push_back( groupElement ); } } diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 951f57e586..391966cc7d 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -38,6 +38,8 @@ #include #endif /* __WXDEBUG__ */ +#include + #ifndef CALLBACK #define CALLBACK #endif @@ -77,9 +79,11 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, isVboInitialized = false; vboNeedsUpdate = false; - curVboItem = NULL; + currentGroup = NULL; + groupCounter = 0; transform = glm::mat4( 1.0f ); // Identity matrix + SetSize( parentSize ); screenSize.x = parentSize.x; @@ -723,6 +727,20 @@ inline void OPENGL_GAL::drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D } +unsigned int OPENGL_GAL::getGroupNumber() +{ + wxASSERT_MSG( groups.size() < std::numeric_limits::max(), + wxT( "There are no free slots to store a group" ) ); + + while( groups.find( groupCounter ) != groups.end() ) + { + groupCounter++; + } + + return groupCounter++; +} + + void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) { if( isFillEnabled ) @@ -1138,7 +1156,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) memcpy( circle, verticesCircle->GetVertices(), VBO_ITEM::VertByteSize * CIRCLE_POINTS * 3 ); - curVboItem->PushVertices( circle, CIRCLE_POINTS * 3 ); + currentGroup->PushVertices( circle, CIRCLE_POINTS * 3 ); delete[] circle; } @@ -1195,7 +1213,7 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d memcpy( semiCircle, verticesSemiCircle->GetVertices(), VBO_ITEM::VertByteSize * CIRCLE_POINTS / 2 * 3 ); - curVboItem->PushVertices( semiCircle, CIRCLE_POINTS / 2 * 3 ); + currentGroup->PushVertices( semiCircle, CIRCLE_POINTS / 2 * 3 ); delete[] semiCircle; } @@ -1373,7 +1391,7 @@ void OPENGL_GAL::DrawPolygon( const std::deque& aPointList ) glShadeModel( GL_FLAT ); - TessParams params = { curVboItem, tessIntersects }; + TessParams params = { currentGroup, tessIntersects }; gluTessBeginPolygon( tesselator, ¶ms ); gluTessBeginContour( tesselator ); @@ -1578,39 +1596,38 @@ int OPENGL_GAL::BeginGroup() vboNeedsUpdate = true; // Save the pointer for caching the current item - curVboItem = new VBO_ITEM( vboContainer ); - vboItems.push_back( curVboItem ); + currentGroup = new VBO_ITEM( vboContainer ); + int groupNumber = getGroupNumber(); + groups.insert( std::make_pair( groupNumber, currentGroup ) ); - return vboItems.size() - 1; + return groupNumber; } void OPENGL_GAL::EndGroup() { - curVboItem->Finish(); - curVboItem = NULL; + currentGroup->Finish(); + isGrouping = false; } void OPENGL_GAL::ClearCache() { - std::deque::iterator it, end; - for( it = vboItems.begin(), end = vboItems.end(); it != end; it++ ) + std::map::iterator it, end; + for( it = groups.begin(), end = groups.end(); it != end; it++ ) { - delete *it; + delete it->second; } - vboItems.clear(); + groups.clear(); } void OPENGL_GAL::DeleteGroup( int aGroupNumber ) { - VBO_ITEM* item = vboItems[aGroupNumber]; - - vboItems[aGroupNumber] = NULL; - delete item; + delete groups[aGroupNumber]; + groups.erase( aGroupNumber ); vboNeedsUpdate = true; } @@ -1618,8 +1635,8 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber ) void OPENGL_GAL::DrawGroup( int aGroupNumber ) { - int size = vboItems[aGroupNumber]->GetSize(); - int offset = vboItems[aGroupNumber]->GetOffset(); + int size = groups[aGroupNumber]->GetSize(); + int offset = groups[aGroupNumber]->GetOffset(); // Copy indices of items that should be drawn to GPU memory for( int i = offset; i < offset + size; *indicesPtr++ = i++ ); @@ -1630,14 +1647,14 @@ void OPENGL_GAL::DrawGroup( int aGroupNumber ) void OPENGL_GAL::ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColor ) { - vboItems[aGroupNumber]->ChangeColor( aNewColor ); + groups[aGroupNumber]->ChangeColor( aNewColor ); vboNeedsUpdate = true; } void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth ) { - vboItems[aGroupNumber]->ChangeDepth( aDepth ); + groups[aGroupNumber]->ChangeDepth( aDepth ); vboNeedsUpdate = true; } diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index cd8cdf5525..610de7fef4 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -322,7 +322,6 @@ private: int actualGroupIndex; ///< The index of the actual group bool isGrouping; ///< Is grouping enabled ? bool isElementAdded; ///< Was an graphic element added ? - std::deque pathList; ///< List of stored paths /// Maximum number of arguments for one command static const int MAX_CAIRO_ARGUMENTS = 6; @@ -359,7 +358,9 @@ private: } GroupElement; typedef std::deque Group; ///< A graphic group type definition - std::deque groups; ///< List of graphic groups + std::map groups; ///< List of graphic groups + unsigned int groupCounter; ///< Counter used for generating keys for groups + Group* currentGroup; ///< Currently used group // Variables related to Cairo <-> wxWidgets cairo_matrix_t cairoWorldScreenMatrix; ///< Cairo world to screen transformation matrix @@ -410,6 +411,13 @@ private: // Destroy Cairo surfaces when are not needed anymore void deinitSurface(); + + /** + * @brief Returns a valid key that can be used as a group number. + * + * @return An unique group number that is not used by any other group. + */ + unsigned int getGroupNumber(); }; } // namespace KiGfx diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index 1dfc6f9cc8..b276b88e68 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -361,12 +361,14 @@ private: VBO_ITEM* verticesSemiCircle; // Vertex buffer objects related fields - std::deque vboItems; ///< Stores informations about VBO objects - VBO_ITEM* curVboItem; ///< Currently used VBO_ITEM (for grouping) + std::map groups; ///< Stores informations about VBO objects (groups) + unsigned int groupCounter; ///< Counter used for generating keys for groups + VBO_ITEM* currentGroup; ///< Currently used VBO_ITEM (for grouping) VBO_CONTAINER* vboContainer; ///< Container for storing VBO_ITEMs GLuint vboVertices; ///< Currently used vertices VBO handle GLuint vboIndices; ///< Currently used indices VBO handle bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt + glm::mat4 transform; ///< Current transformation matrix std::stack transformStack; ///< Stack of transformation matrices int indicesSize; ///< Number of indices to be drawn @@ -530,6 +532,13 @@ private: */ inline void drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); + /** + * @brief Returns a valid key that can be used as a group number. + * + * @return An unique group number that is not used by any other group. + */ + unsigned int getGroupNumber(); + ///< OpenGL replacement functions (that are working both in immediate and VBO modes) /** * @brief Starts drawing in immediate mode or does nothing if an item's caching has started. @@ -562,7 +571,7 @@ private: { // New vertex coordinates for VBO VBO_VERTEX vertex = { aX, aY, aZ }; - curVboItem->PushVertex( &vertex ); + currentGroup->PushVertex( &vertex ); } else {