Commit 332a7b4b authored by Maciej Suminski's avatar Maciej Suminski

Groups are stored in map instead of deque, so it allows easier adding & removing.

parent 58de62aa
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include <gal/cairo/cairo_gal.h> #include <gal/cairo/cairo_gal.h>
#include <gal/definitions.h> #include <gal/definitions.h>
#include <limits>
using namespace KiGfx; using namespace KiGfx;
CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
...@@ -50,6 +52,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, ...@@ -50,6 +52,7 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
isInitialized = false; isInitialized = false;
isDeleteSavedPixels = false; isDeleteSavedPixels = false;
zoomFactor = 1.0; zoomFactor = 1.0;
groupCounter = 0;
SetSize( aParent->GetSize() ); SetSize( aParent->GetSize() );
...@@ -200,6 +203,20 @@ void CAIRO_GAL::deinitSurface() ...@@ -200,6 +203,20 @@ void CAIRO_GAL::deinitSurface()
} }
unsigned int CAIRO_GAL::getGroupNumber()
{
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::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 ) void CAIRO_GAL::BeginDrawing() throw( int )
{ {
initSurface(); initSurface();
...@@ -429,7 +446,7 @@ void CAIRO_GAL::SetIsFill( bool aIsFillEnabled ) ...@@ -429,7 +446,7 @@ void CAIRO_GAL::SetIsFill( bool aIsFillEnabled )
GroupElement groupElement; GroupElement groupElement;
groupElement.command = CMD_SET_FILL; groupElement.command = CMD_SET_FILL;
groupElement.boolArgument = aIsFillEnabled; groupElement.boolArgument = aIsFillEnabled;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -444,7 +461,7 @@ void CAIRO_GAL::SetIsStroke( bool aIsStrokeEnabled ) ...@@ -444,7 +461,7 @@ void CAIRO_GAL::SetIsStroke( bool aIsStrokeEnabled )
GroupElement groupElement; GroupElement groupElement;
groupElement.command = CMD_SET_STROKE; groupElement.command = CMD_SET_STROKE;
groupElement.boolArgument = aIsStrokeEnabled; groupElement.boolArgument = aIsStrokeEnabled;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -463,7 +480,7 @@ void CAIRO_GAL::SetStrokeColor( const COLOR4D& aColor ) ...@@ -463,7 +480,7 @@ void CAIRO_GAL::SetStrokeColor( const COLOR4D& aColor )
groupElement.arguments[1] = strokeColor.g; groupElement.arguments[1] = strokeColor.g;
groupElement.arguments[2] = strokeColor.b; groupElement.arguments[2] = strokeColor.b;
groupElement.arguments[3] = strokeColor.a; 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 ) ...@@ -481,7 +498,7 @@ void CAIRO_GAL::SetFillColor( const COLOR4D& aColor )
groupElement.arguments[1] = fillColor.g; groupElement.arguments[1] = fillColor.g;
groupElement.arguments[2] = fillColor.b; groupElement.arguments[2] = fillColor.b;
groupElement.arguments[3] = fillColor.a; groupElement.arguments[3] = fillColor.a;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -498,7 +515,7 @@ void CAIRO_GAL::SetLineWidth( double aLineWidth ) ...@@ -498,7 +515,7 @@ void CAIRO_GAL::SetLineWidth( double aLineWidth )
GroupElement groupElement; GroupElement groupElement;
groupElement.command = CMD_SET_LINE_WIDTH; groupElement.command = CMD_SET_LINE_WIDTH;
groupElement.arguments[0] = aLineWidth; groupElement.arguments[0] = aLineWidth;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -516,7 +533,7 @@ void CAIRO_GAL::SetLineCap( LineCap aLineCap ) ...@@ -516,7 +533,7 @@ void CAIRO_GAL::SetLineCap( LineCap aLineCap )
GroupElement groupElement; GroupElement groupElement;
groupElement.command = CMD_SET_LINE_CAP; groupElement.command = CMD_SET_LINE_CAP;
groupElement.intArgument = (int) aLineCap; groupElement.intArgument = (int) aLineCap;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -534,7 +551,7 @@ void CAIRO_GAL::SetLineJoin( LineJoin aLineJoin ) ...@@ -534,7 +551,7 @@ void CAIRO_GAL::SetLineJoin( LineJoin aLineJoin )
GroupElement groupElement; GroupElement groupElement;
groupElement.command = CMD_SET_LINE_JOIN; groupElement.command = CMD_SET_LINE_JOIN;
groupElement.intArgument = (int) aLineJoin; groupElement.intArgument = (int) aLineJoin;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -592,7 +609,7 @@ void CAIRO_GAL::Rotate( double aAngle ) ...@@ -592,7 +609,7 @@ void CAIRO_GAL::Rotate( double aAngle )
GroupElement groupElement; GroupElement groupElement;
groupElement.command = CMD_ROTATE; groupElement.command = CMD_ROTATE;
groupElement.arguments[0] = aAngle; groupElement.arguments[0] = aAngle;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -609,7 +626,7 @@ void CAIRO_GAL::Translate( const VECTOR2D& aTranslation ) ...@@ -609,7 +626,7 @@ void CAIRO_GAL::Translate( const VECTOR2D& aTranslation )
groupElement.command = CMD_TRANSLATE; groupElement.command = CMD_TRANSLATE;
groupElement.arguments[0] = aTranslation.x; groupElement.arguments[0] = aTranslation.x;
groupElement.arguments[1] = aTranslation.y; 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 ) ...@@ -626,7 +643,7 @@ void CAIRO_GAL::Scale( const VECTOR2D& aScale )
groupElement.command = CMD_SCALE; groupElement.command = CMD_SCALE;
groupElement.arguments[0] = aScale.x; groupElement.arguments[0] = aScale.x;
groupElement.arguments[1] = aScale.y; groupElement.arguments[1] = aScale.y;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -641,7 +658,7 @@ void CAIRO_GAL::Save() ...@@ -641,7 +658,7 @@ void CAIRO_GAL::Save()
{ {
GroupElement groupElement; GroupElement groupElement;
groupElement.command = CMD_SAVE; groupElement.command = CMD_SAVE;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -656,7 +673,7 @@ void CAIRO_GAL::Restore() ...@@ -656,7 +673,7 @@ void CAIRO_GAL::Restore()
{ {
GroupElement groupElement; GroupElement groupElement;
groupElement.command = CMD_RESTORE; groupElement.command = CMD_RESTORE;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
...@@ -668,10 +685,14 @@ int CAIRO_GAL::BeginGroup() ...@@ -668,10 +685,14 @@ int CAIRO_GAL::BeginGroup()
// If the grouping is started: the actual path is stored in the group, when // 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. // a attribute was changed or when grouping stops with the end group method.
storePath(); storePath();
Group group; Group group;
groups.push_back( group ); int groupNumber = getGroupNumber();
groups.insert( std::make_pair( groupNumber, group ) );
currentGroup = &groups[groupNumber];
isGrouping = true; isGrouping = true;
return groups.size() - 1;
return groupNumber;
} }
...@@ -708,7 +729,7 @@ void CAIRO_GAL::DeleteGroup( int aGroupNumber ) ...@@ -708,7 +729,7 @@ void CAIRO_GAL::DeleteGroup( int aGroupNumber )
} }
// Delete the group // Delete the group
groups.erase( groups.begin() + aGroupNumber ); groups.erase( aGroupNumber );
} }
...@@ -879,15 +900,12 @@ void CAIRO_GAL::storePath() ...@@ -879,15 +900,12 @@ void CAIRO_GAL::storePath()
// Copy the actual path, append it to the global path list // Copy the actual path, append it to the global path list
// then check, if the path needs to be stroked/filled and // then check, if the path needs to be stroked/filled and
// add this command to the group list; // add this command to the group list;
// pathList.push_back( path ); // FIXME: it's not used anywhere else?
if( isStrokeEnabled ) if( isStrokeEnabled )
{ {
GroupElement groupElement; GroupElement groupElement;
groupElement.cairoPath = cairo_copy_path( cairoImage ); groupElement.cairoPath = cairo_copy_path( cairoImage );
groupElement.command = CMD_STROKE_PATH; groupElement.command = CMD_STROKE_PATH;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
if( isFillEnabled ) if( isFillEnabled )
...@@ -895,7 +913,7 @@ void CAIRO_GAL::storePath() ...@@ -895,7 +913,7 @@ void CAIRO_GAL::storePath()
GroupElement groupElement; GroupElement groupElement;
groupElement.cairoPath = cairo_copy_path( cairoImage ); groupElement.cairoPath = cairo_copy_path( cairoImage );
groupElement.command = CMD_FILL_PATH; groupElement.command = CMD_FILL_PATH;
groups.back().push_back( groupElement ); currentGroup->push_back( groupElement );
} }
} }
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
#include <profile.h> #include <profile.h>
#endif /* __WXDEBUG__ */ #endif /* __WXDEBUG__ */
#include <limits>
#ifndef CALLBACK #ifndef CALLBACK
#define CALLBACK #define CALLBACK
#endif #endif
...@@ -77,9 +79,11 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, ...@@ -77,9 +79,11 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
isVboInitialized = false; isVboInitialized = false;
vboNeedsUpdate = false; vboNeedsUpdate = false;
curVboItem = NULL; currentGroup = NULL;
groupCounter = 0;
transform = glm::mat4( 1.0f ); // Identity matrix transform = glm::mat4( 1.0f ); // Identity matrix
SetSize( parentSize ); SetSize( parentSize );
screenSize.x = parentSize.x; screenSize.x = parentSize.x;
...@@ -723,6 +727,20 @@ inline void OPENGL_GAL::drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D ...@@ -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<unsigned int>::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 ) void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
{ {
if( isFillEnabled ) if( isFillEnabled )
...@@ -1138,7 +1156,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) ...@@ -1138,7 +1156,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
memcpy( circle, verticesCircle->GetVertices(), memcpy( circle, verticesCircle->GetVertices(),
VBO_ITEM::VertByteSize * CIRCLE_POINTS * 3 ); VBO_ITEM::VertByteSize * CIRCLE_POINTS * 3 );
curVboItem->PushVertices( circle, CIRCLE_POINTS * 3 ); currentGroup->PushVertices( circle, CIRCLE_POINTS * 3 );
delete[] circle; delete[] circle;
} }
...@@ -1195,7 +1213,7 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d ...@@ -1195,7 +1213,7 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d
memcpy( semiCircle, verticesSemiCircle->GetVertices(), memcpy( semiCircle, verticesSemiCircle->GetVertices(),
VBO_ITEM::VertByteSize * CIRCLE_POINTS / 2 * 3 ); VBO_ITEM::VertByteSize * CIRCLE_POINTS / 2 * 3 );
curVboItem->PushVertices( semiCircle, CIRCLE_POINTS / 2 * 3 ); currentGroup->PushVertices( semiCircle, CIRCLE_POINTS / 2 * 3 );
delete[] semiCircle; delete[] semiCircle;
} }
...@@ -1373,7 +1391,7 @@ void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList ) ...@@ -1373,7 +1391,7 @@ void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList )
glShadeModel( GL_FLAT ); glShadeModel( GL_FLAT );
TessParams params = { curVboItem, tessIntersects }; TessParams params = { currentGroup, tessIntersects };
gluTessBeginPolygon( tesselator, &params ); gluTessBeginPolygon( tesselator, &params );
gluTessBeginContour( tesselator ); gluTessBeginContour( tesselator );
...@@ -1578,39 +1596,38 @@ int OPENGL_GAL::BeginGroup() ...@@ -1578,39 +1596,38 @@ int OPENGL_GAL::BeginGroup()
vboNeedsUpdate = true; vboNeedsUpdate = true;
// Save the pointer for caching the current item // Save the pointer for caching the current item
curVboItem = new VBO_ITEM( vboContainer ); currentGroup = new VBO_ITEM( vboContainer );
vboItems.push_back( curVboItem ); int groupNumber = getGroupNumber();
groups.insert( std::make_pair( groupNumber, currentGroup ) );
return vboItems.size() - 1; return groupNumber;
} }
void OPENGL_GAL::EndGroup() void OPENGL_GAL::EndGroup()
{ {
curVboItem->Finish(); currentGroup->Finish();
curVboItem = NULL;
isGrouping = false; isGrouping = false;
} }
void OPENGL_GAL::ClearCache() void OPENGL_GAL::ClearCache()
{ {
std::deque<VBO_ITEM*>::iterator it, end; std::map<unsigned int, VBO_ITEM*>::iterator it, end;
for( it = vboItems.begin(), end = vboItems.end(); it != end; it++ ) 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 ) void OPENGL_GAL::DeleteGroup( int aGroupNumber )
{ {
VBO_ITEM* item = vboItems[aGroupNumber]; delete groups[aGroupNumber];
groups.erase( aGroupNumber );
vboItems[aGroupNumber] = NULL;
delete item;
vboNeedsUpdate = true; vboNeedsUpdate = true;
} }
...@@ -1618,8 +1635,8 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber ) ...@@ -1618,8 +1635,8 @@ void OPENGL_GAL::DeleteGroup( int aGroupNumber )
void OPENGL_GAL::DrawGroup( int aGroupNumber ) void OPENGL_GAL::DrawGroup( int aGroupNumber )
{ {
int size = vboItems[aGroupNumber]->GetSize(); int size = groups[aGroupNumber]->GetSize();
int offset = vboItems[aGroupNumber]->GetOffset(); int offset = groups[aGroupNumber]->GetOffset();
// Copy indices of items that should be drawn to GPU memory // Copy indices of items that should be drawn to GPU memory
for( int i = offset; i < offset + size; *indicesPtr++ = i++ ); for( int i = offset; i < offset + size; *indicesPtr++ = i++ );
...@@ -1630,14 +1647,14 @@ void OPENGL_GAL::DrawGroup( int aGroupNumber ) ...@@ -1630,14 +1647,14 @@ void OPENGL_GAL::DrawGroup( int aGroupNumber )
void OPENGL_GAL::ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColor ) void OPENGL_GAL::ChangeGroupColor( int aGroupNumber, const COLOR4D& aNewColor )
{ {
vboItems[aGroupNumber]->ChangeColor( aNewColor ); groups[aGroupNumber]->ChangeColor( aNewColor );
vboNeedsUpdate = true; vboNeedsUpdate = true;
} }
void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth ) void OPENGL_GAL::ChangeGroupDepth( int aGroupNumber, int aDepth )
{ {
vboItems[aGroupNumber]->ChangeDepth( aDepth ); groups[aGroupNumber]->ChangeDepth( aDepth );
vboNeedsUpdate = true; vboNeedsUpdate = true;
} }
......
...@@ -322,7 +322,6 @@ private: ...@@ -322,7 +322,6 @@ private:
int actualGroupIndex; ///< The index of the actual group int actualGroupIndex; ///< The index of the actual group
bool isGrouping; ///< Is grouping enabled ? bool isGrouping; ///< Is grouping enabled ?
bool isElementAdded; ///< Was an graphic element added ? bool isElementAdded; ///< Was an graphic element added ?
std::deque<cairo_path_t*> pathList; ///< List of stored paths
/// Maximum number of arguments for one command /// Maximum number of arguments for one command
static const int MAX_CAIRO_ARGUMENTS = 6; static const int MAX_CAIRO_ARGUMENTS = 6;
...@@ -359,7 +358,9 @@ private: ...@@ -359,7 +358,9 @@ private:
} GroupElement; } GroupElement;
typedef std::deque<GroupElement> Group; ///< A graphic group type definition typedef std::deque<GroupElement> Group; ///< A graphic group type definition
std::deque<Group> groups; ///< List of graphic groups std::map<int, Group> 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 // Variables related to Cairo <-> wxWidgets
cairo_matrix_t cairoWorldScreenMatrix; ///< Cairo world to screen transformation matrix cairo_matrix_t cairoWorldScreenMatrix; ///< Cairo world to screen transformation matrix
...@@ -410,6 +411,13 @@ private: ...@@ -410,6 +411,13 @@ private:
// Destroy Cairo surfaces when are not needed anymore // Destroy Cairo surfaces when are not needed anymore
void deinitSurface(); 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 } // namespace KiGfx
......
...@@ -361,12 +361,14 @@ private: ...@@ -361,12 +361,14 @@ private:
VBO_ITEM* verticesSemiCircle; VBO_ITEM* verticesSemiCircle;
// Vertex buffer objects related fields // Vertex buffer objects related fields
std::deque<VBO_ITEM*> vboItems; ///< Stores informations about VBO objects std::map<unsigned int, VBO_ITEM*> groups; ///< Stores informations about VBO objects (groups)
VBO_ITEM* curVboItem; ///< Currently used VBO_ITEM (for grouping) 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 VBO_CONTAINER* vboContainer; ///< Container for storing VBO_ITEMs
GLuint vboVertices; ///< Currently used vertices VBO handle GLuint vboVertices; ///< Currently used vertices VBO handle
GLuint vboIndices; ///< Currently used indices VBO handle GLuint vboIndices; ///< Currently used indices VBO handle
bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt
glm::mat4 transform; ///< Current transformation matrix glm::mat4 transform; ///< Current transformation matrix
std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices
int indicesSize; ///< Number of indices to be drawn int indicesSize; ///< Number of indices to be drawn
...@@ -530,6 +532,13 @@ private: ...@@ -530,6 +532,13 @@ private:
*/ */
inline void drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); 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) ///< 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. * @brief Starts drawing in immediate mode or does nothing if an item's caching has started.
...@@ -562,7 +571,7 @@ private: ...@@ -562,7 +571,7 @@ private:
{ {
// New vertex coordinates for VBO // New vertex coordinates for VBO
VBO_VERTEX vertex = { aX, aY, aZ }; VBO_VERTEX vertex = { aX, aY, aZ };
curVboItem->PushVertex( &vertex ); currentGroup->PushVertex( &vertex );
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment