Loading common/gal/opengl/opengl_gal.cpp +71 −187 Original line number Diff line number Diff line Loading @@ -76,9 +76,10 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, isVboInitialized = false; vboNeedsUpdate = false; currentGroup = NULL; currentItem = NULL; groupCounter = 0; transform = glm::mat4( 1.0f ); // Identity matrix nonCachedItem = NULL; SetSize( parentSize ); Loading Loading @@ -120,10 +121,7 @@ OPENGL_GAL::~OPENGL_GAL() { glFlush(); if( glIsList( displayListSemiCircle ) ) glDeleteLists( displayListSemiCircle, 1 ); if( glIsList( displayListCircle ) ) glDeleteLists( displayListCircle, 1 ); delete nonCachedItem; // Delete the buffers if( isFrameBufferInitialized ) Loading Loading @@ -241,8 +239,8 @@ void OPENGL_GAL::initFrameBuffers() void OPENGL_GAL::initVertexBufferObjects() { // Generate buffers for vertices and indices glGenBuffers( 1, &vboVertices ); glGenBuffers( 1, &vboIndices ); glGenBuffers( 1, &cachedVerts ); glGenBuffers( 1, &cachedInds ); isVboInitialized = true; } Loading @@ -253,8 +251,8 @@ void OPENGL_GAL::deleteVertexBufferObjects() glBindBuffer( GL_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glDeleteBuffers( 1, &vboVertices ); glDeleteBuffers( 1, &vboIndices ); glDeleteBuffers( 1, &cachedVerts ); glDeleteBuffers( 1, &cachedInds ); isVboInitialized = false; } Loading Loading @@ -323,7 +321,6 @@ void OPENGL_GAL::initGlew() } initVertexBufferObjects(); computeCircleDisplayLists(); isGlewInitialized = true; } Loading Loading @@ -425,9 +422,9 @@ void OPENGL_GAL::BeginDrawing() // Number of vertices to be drawn indicesSize = 0; glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIndices ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, cachedInds ); // Discard old buffer, so we can use it again glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::IndByteSize, glBufferData( GL_ELEMENT_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::IndByteSize, NULL, GL_STREAM_DRAW ); // Map the GPU memory, so we can store indices that are going to be drawn Loading @@ -436,6 +433,14 @@ void OPENGL_GAL::BeginDrawing() { wxLogError( wxT( "Could not map GPU memory" ) ); } // Prepare buffer for non-cached items delete nonCachedItem; nonCachedItem = new VBO_ITEM( &nonCachedVbo ); // By default we draw non-cached objects, it changes on BeginGroup()/EndGroup() currentContainer = &nonCachedVbo; currentItem = nonCachedItem; } Loading Loading @@ -487,9 +492,6 @@ void OPENGL_GAL::blitMainTexture( bool aIsClearFrameBuffer ) void OPENGL_GAL::EndDrawing() { // TODO Checking if we are using right VBOs, in other case do the binding. // Right now there is only one VBO, so there is no problem. if( !glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER ) ) { wxLogError( wxT( "Unmapping indices buffer failed" ) ); Loading @@ -500,7 +502,7 @@ void OPENGL_GAL::EndDrawing() glEnableClientState( GL_COLOR_ARRAY ); // Bind vertices data buffers glBindBuffer( GL_ARRAY_BUFFER, vboVertices ); glBindBuffer( GL_ARRAY_BUFFER, cachedVerts ); glVertexPointer( VBO_ITEM::CoordStride, GL_FLOAT, VBO_ITEM::VertByteSize, 0 ); glColorPointer( VBO_ITEM::ColorStride, GL_UNSIGNED_BYTE, VBO_ITEM::VertByteSize, (GLvoid*) VBO_ITEM::ColorByteOffset ); Loading @@ -518,6 +520,20 @@ void OPENGL_GAL::EndDrawing() glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Draw non-cached items GLfloat* vertices = (GLfloat*)( nonCachedVbo.GetAllVertices() ); GLubyte* colors = (GLubyte*)( nonCachedVbo.GetAllVertices() ) + VBO_ITEM::ColorOffset; GLfloat* shaders = (GLfloat*)( nonCachedVbo.GetAllVertices() ) + VBO_ITEM::ShaderOffset; glVertexPointer( VBO_ITEM::CoordStride, GL_FLOAT, VBO_ITEM::VertByteSize, vertices ); glColorPointer( VBO_ITEM::ColorStride, GL_UNSIGNED_BYTE, VBO_ITEM::VertByteSize, colors ); if( isUseShader ) { glVertexAttribPointer( shaderAttrib, VBO_ITEM::ShaderStride, GL_FLOAT, GL_FALSE, VBO_ITEM::VertByteSize, shaders ); } glDrawArrays( GL_TRIANGLES, nonCachedItem->GetOffset(), nonCachedItem->GetSize() ); // Deactivate vertex array glDisableClientState( GL_COLOR_ARRAY ); glDisableClientState( GL_VERTEX_ARRAY ); Loading @@ -543,17 +559,17 @@ void OPENGL_GAL::rebuildVbo() prof_start( &totalTime, false ); #endif /* __WXDEBUG__ */ GLfloat* data = (GLfloat*) vboContainer.GetAllVertices(); GLfloat* data = (GLfloat*) cachedVbo.GetAllVertices(); // Upload vertices coordinates and shader types to GPU memory glBindBuffer( GL_ARRAY_BUFFER, vboVertices ); glBufferData( GL_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::VertByteSize, glBindBuffer( GL_ARRAY_BUFFER, cachedVerts ); glBufferData( GL_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::VertByteSize, data, GL_DYNAMIC_DRAW ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Allocate the biggest possible buffer for indices glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIndices ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::IndByteSize, glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, cachedInds ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::IndByteSize, NULL, GL_STREAM_DRAW ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); Loading @@ -563,7 +579,7 @@ void OPENGL_GAL::rebuildVbo() prof_end( &totalTime ); wxLogDebug( wxT( "Rebuilding VBO::%d vertices / %.1f ms" ), vboContainer.GetSize(), (double) totalTime.value / 1000.0 ); cachedVbo.GetSize(), (double) totalTime.value / 1000.0 ); #endif /* __WXDEBUG__ */ } Loading @@ -577,27 +593,16 @@ inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2 if( lineLength <= 0.0 ) return; if( lineWidth * worldScale < 1.0002 && !isGrouping && !isUseShader ) { // Limit the width of the line to a minimum of one pixel // this looks best without anti-aliasing scale = 0.5001 / worldScale / lineLength; } VECTOR2D perpendicularVector( -startEndVector.y * scale, startEndVector.x * scale ); begin( GL_TRIANGLES ); if( isUseShader && isGrouping ) if( isUseShader ) { glm::vec4 vector( perpendicularVector.x, perpendicularVector.y, 0.0, 0.0 ); // If transform stack is not empty, then it means that // there is a transformation matrix that has to be applied if( !transformStack.empty() ) { vector = transform * vector; } // Line width is maintained by the vertex shader setShader( SHADER_LINE, vector.x, vector.y, lineWidth ); Loading Loading @@ -634,8 +639,6 @@ inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2 vertex3( v3.x, v3.y, layerDepth ); vertex3( v2.x, v2.y, layerDepth ); } end(); } Loading Loading @@ -760,7 +763,6 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn setShader( SHADER_NONE ); color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); begin( GL_TRIANGLES ); vertex3( aStartPoint.x, aStartPoint.y, layerDepth ); vertex3( diagonalPointA.x, diagonalPointA.y, layerDepth ); vertex3( aEndPoint.x, aEndPoint.y, layerDepth ); Loading @@ -768,14 +770,13 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn vertex3( aStartPoint.x, aStartPoint.y, layerDepth ); vertex3( aEndPoint.x, aEndPoint.y, layerDepth ); vertex3( diagonalPointB.x, diagonalPointB.y, layerDepth ); end(); } } void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) { if( isUseShader && isGrouping ) if( isUseShader ) { if( isFillEnabled ) { Loading Loading @@ -856,8 +857,6 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) translate3( aCenterPoint.x, aCenterPoint.y, 0.0 ); Scale( VECTOR2D( aRadius, aRadius ) ); begin( GL_TRIANGLES ); for( int i = 0; i < 3 * CIRCLE_POINTS; ++i ) { // verticesCircle contains precomputed circle points interleaved with vertex Loading Loading @@ -887,8 +886,6 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) vertex3( circle[next].x * innerScale, circle[next].y * innerScale, layerDepth ); } end(); Restore(); } } Loading @@ -902,14 +899,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) translate3( aCenterPoint.x, aCenterPoint.y, layerDepth ); Scale( VECTOR2D( aRadius, aRadius ) ); if( isGrouping ) { currentGroup->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS * 3 ); } else { glCallList( displayListCircle ); } currentItem->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS * 3 ); Restore(); } Loading @@ -934,7 +924,7 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle ) { if( isUseShader && isGrouping ) if( isUseShader ) { Save(); Translate( aCenterPoint ); Loading Loading @@ -966,15 +956,8 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad Scale( VECTOR2D( aRadius, aRadius ) ); Rotate( aAngle ); if( isGrouping ) { // It is enough just to push just a half of the circle vertices to make a semicircle currentGroup->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS / 2 * 3 ); } else { glCallList( displayListSemiCircle ); } currentItem->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS / 2 * 3 ); Restore(); } Loading @@ -983,7 +966,7 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle ) { if( isUseShader && isGrouping ) if( isUseShader ) { Save(); Translate( aCenterPoint ); Loading Loading @@ -1028,8 +1011,6 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa VBO_VERTEX* circle = verticesCircle.GetVertices(); int next; begin( GL_TRIANGLES ); for( int i = 0; i < ( 3 * CIRCLE_POINTS ) / 2; ++i ) { // verticesCircle contains precomputed circle points interleaved with vertex Loading Loading @@ -1059,8 +1040,6 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa vertex3( circle[next].x * innerScale, circle[next].y * innerScale, 0.0 ); } end(); Restore(); } } Loading Loading @@ -1123,8 +1102,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a double alphaIncrement = 2 * M_PI / CIRCLE_POINTS; color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a ); begin( GL_TRIANGLES ); for( double alpha = aStartAngle; alpha < aEndAngle; ) { double v0[] = { cos( alpha ) * innerScale, sin( alpha ) * innerScale }; Loading @@ -1147,8 +1124,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a vertex3( v2[0], v2[1], 0.0 ); } end(); // Draw line caps drawFilledSemiCircle( startPoint, lineWidth / aRadius / 2.0, aStartAngle + M_PI ); drawFilledSemiCircle( endPoint, lineWidth / aRadius / 2.0, aEndAngle ); Loading @@ -1161,8 +1136,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a double alpha; color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); begin( GL_TRIANGLES ); for( alpha = aStartAngle; ( alpha + alphaIncrement ) < aEndAngle; ) { vertex3( middlePoint.x, middlePoint.y, 0.0 ); Loading @@ -1174,7 +1147,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a vertex3( middlePoint.x, middlePoint.y, 0.0 ); vertex3( cos( alpha ), sin( alpha ), 0.0 ); vertex3( endPoint.x, endPoint.y, 0.0 ); end(); } Restore(); Loading Loading @@ -1228,7 +1200,7 @@ void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList ) glShadeModel( GL_FLAT ); TessParams params = { currentGroup, tessIntersects }; TessParams params = { currentItem, tessIntersects }; gluTessBeginPolygon( tesselator, ¶ms ); gluTessBeginContour( tesselator ); Loading Loading @@ -1347,42 +1319,21 @@ void OPENGL_GAL::Transform( MATRIX3x3D aTransformation ) void OPENGL_GAL::Rotate( double aAngle ) { if( isGrouping ) { transform = glm::rotate( transform, (float) aAngle, glm::vec3( 0, 0, 1 ) ); } else { glRotated( aAngle * ( 360 / ( 2 * M_PI ) ), 0, 0, 1 ); } } void OPENGL_GAL::Translate( const VECTOR2D& aVector ) { if( isGrouping ) { transform = glm::translate( transform, glm::vec3( aVector.x, aVector.y, 0 ) ); } else { glTranslated( aVector.x, aVector.y, 0 ); } } void OPENGL_GAL::Scale( const VECTOR2D& aScale ) { if( isGrouping ) { transform = glm::scale( transform, glm::vec3( aScale.x, aScale.y, 0 ) ); } else { glScaled( aScale.x, aScale.y, 0 ); } } void OPENGL_GAL::Flush() Loading @@ -1392,22 +1343,13 @@ void OPENGL_GAL::Flush() void OPENGL_GAL::Save() { if( isGrouping ) { transformStack.push( transform ); vboContainer.SetTransformMatrix( &transform ); } else { glPushMatrix(); } currentContainer->SetTransformMatrix( &transform ); } void OPENGL_GAL::Restore() { if( isGrouping ) { transform = transformStack.top(); transformStack.pop(); Loading @@ -1415,12 +1357,7 @@ void OPENGL_GAL::Restore() if( transformStack.empty() ) { // Disable transforming, as the selected matrix is identity vboContainer.SetTransformMatrix( NULL ); } } else { glPopMatrix(); currentContainer->SetTransformMatrix( NULL ); } } Loading @@ -1433,9 +1370,10 @@ int OPENGL_GAL::BeginGroup() vboNeedsUpdate = true; // Save the pointer for caching the current item currentGroup = new VBO_ITEM( &vboContainer ); currentItem = new VBO_ITEM( &cachedVbo ); currentContainer = &cachedVbo; int groupNumber = getGroupNumber(); groups.insert( std::make_pair( groupNumber, currentGroup ) ); groups.insert( std::make_pair( groupNumber, currentItem ) ); return groupNumber; } Loading @@ -1443,7 +1381,9 @@ int OPENGL_GAL::BeginGroup() void OPENGL_GAL::EndGroup() { currentGroup->Finish(); currentItem->Finish(); currentItem = nonCachedItem; currentContainer = &nonCachedVbo; isGrouping = false; } Loading Loading @@ -1523,42 +1463,6 @@ void OPENGL_GAL::computeCircleVbo() } 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 ); 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(); } void OPENGL_GAL::ComputeWorldScreenMatrix() { ComputeWorldScale(); Loading Loading @@ -1603,10 +1507,6 @@ void CALLBACK VertexCallback( GLvoid* aVertexPtr, void* aData ) VBO_VERTEX newVertex = { vertex[0], vertex[1], vertex[2] }; vboItem->PushVertex( &newVertex ); } else { glVertex3dv( vertex ); } } Loading @@ -1633,20 +1533,6 @@ void CALLBACK EdgeCallback(void) } void CALLBACK BeginCallback( GLenum aWhich, void* aData ) { if( !aData ) glBegin( aWhich ); } void CALLBACK EndCallback( void* aData ) { if( !aData ) glEnd(); } void CALLBACK ErrorCallback( GLenum aErrorCode ) { const GLubyte* estring; Loading @@ -1661,8 +1547,6 @@ void InitTesselatorCallbacks( GLUtesselator* aTesselator ) gluTessCallback( aTesselator, GLU_TESS_VERTEX_DATA, ( void (CALLBACK*)() )VertexCallback ); gluTessCallback( aTesselator, GLU_TESS_COMBINE_DATA, ( void (CALLBACK*)() )CombineCallback ); gluTessCallback( aTesselator, GLU_TESS_EDGE_FLAG, ( void (CALLBACK*)() )EdgeCallback ); gluTessCallback( aTesselator, GLU_TESS_BEGIN_DATA, ( void (CALLBACK*)() )BeginCallback ); gluTessCallback( aTesselator, GLU_TESS_END_DATA, ( void (CALLBACK*)() )EndCallback ); gluTessCallback( aTesselator, GLU_TESS_ERROR_DATA, ( void (CALLBACK*)() )ErrorCallback ); } Loading Loading @@ -1771,19 +1655,19 @@ void OPENGL_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd VECTOR2D point4 = aEndPoint - perpendicularVector; // Set color glColor4d( gridColor.r, gridColor.g, gridColor.b, gridColor.a ); color4( gridColor.r, gridColor.g, gridColor.b, gridColor.a ); setShader( SHADER_NONE ); // Draw the quad for the grid line glBegin( GL_TRIANGLES ); double gridDepth = depthRange.y * 0.75; glVertex3d( point1.x, point1.y, gridDepth ); glVertex3d( point2.x, point2.y, gridDepth ); glVertex3d( point4.x, point4.y, gridDepth ); vertex3( point1.x, point1.y, gridDepth ); vertex3( point2.x, point2.y, gridDepth ); vertex3( point4.x, point4.y, gridDepth ); glVertex3d( point1.x, point1.y, gridDepth ); glVertex3d( point4.x, point4.y, gridDepth ); glVertex3d( point3.x, point3.y, gridDepth ); glEnd(); vertex3( point1.x, point1.y, gridDepth ); vertex3( point4.x, point4.y, gridDepth ); vertex3( point3.x, point3.y, gridDepth ); } Loading common/gal/opengl/vbo_container.cpp +25 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ using namespace KiGfx; VBO_CONTAINER::VBO_CONTAINER( int aSize ) : VBO_CONTAINER::VBO_CONTAINER( unsigned int aSize ) : m_freeSpace( aSize ), m_currentSize( aSize ), itemStarted( false ), m_transform( NULL ), m_failed( false ) { Loading Loading @@ -202,6 +202,30 @@ void VBO_CONTAINER::Add( VBO_ITEM* aVboItem, const VBO_VERTEX* aVertex, unsigned } void VBO_CONTAINER::Clear() { // Change size to the default one m_vertices = static_cast<VBO_VERTEX*>( realloc( m_vertices, defaultInitSize * sizeof( VBO_VERTEX ) ) ); // Reset state variables m_freeSpace = defaultInitSize; m_currentSize = defaultInitSize; itemStarted = false; m_transform = NULL; m_failed = false; // By default no shader is used m_shader[0] = 0; m_freeChunks.clear(); m_reservedChunks.clear(); // In the beginning there is only free space m_freeChunks.insert( Chunk( m_freeSpace, 0 ) ); } VBO_VERTEX* VBO_CONTAINER::GetAllVertices() const { return m_vertices; Loading include/gal/opengl/opengl_gal.h +19 −77 Original line number Diff line number Diff line Loading @@ -337,21 +337,22 @@ private: wxEvtHandler* mouseListener; wxEvtHandler* paintListener; // VBO buffers & display lists (used in immediate mode) // VBO buffered vertices for faster circle & semicircle drawing VBO_CONTAINER precomputedContainer; ///< Container for storing display lists VBO_ITEM verticesCircle; ///< Buffer for circle & semicircle vertices GLuint displayListCircle; ///< Circle display list GLuint displayListSemiCircle; ///< Semi circle display list // Vertex buffer objects related fields typedef boost::unordered_map<unsigned int, VBO_ITEM*> GroupsMap; GroupsMap 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 VBO_ITEM* currentItem; ///< Currently used VBO_ITEM (for grouping) VBO_CONTAINER* currentContainer; ///< Currently used VBO_CONTAINER (for storing VBO_ITEMs) VBO_CONTAINER cachedVbo; ///< Container for storing VBO_ITEMs GLuint cachedVerts; ///< Currently used vertices VBO handle GLuint cachedInds; ///< Currently used indices VBO handle bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt VBO_CONTAINER nonCachedVbo; ///< Container for storing non-cached VBO_ITEMs VBO_ITEM* nonCachedItem; ///< Item that is gathering non-cached vertices glm::mat4 transform; ///< Current transformation matrix std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices Loading Loading @@ -432,10 +433,6 @@ private: /// Compute the points of an unit circle & semicircle and store them in VBO. void computeCircleVbo(); /// Compute the points of an unit circle & semicircle and store them in display lists /// for drawing in immediate mode. void computeCircleDisplayLists(); // Event handling /** * @brief This is the window creation event handler. Loading Loading @@ -527,26 +524,6 @@ private: */ 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. * @param aMode specifies the primitive or primitives that will be created. */ inline void begin( GLenum aMode ) { if( !isGrouping ) glBegin( aMode ); } /** * @brief Ends drawing in immediate mode or does nothing if an item's caching has started. */ inline void end() { if( !isGrouping ) glEnd(); } /** * @brief Adds vertex to the current item or draws it in immediate mode. * @param aX is X coordinate. Loading @@ -554,44 +531,26 @@ private: * @param aZ is Z coordinate. */ inline void vertex3( double aX, double aY, double aZ ) { if( isGrouping ) { // New vertex coordinates for VBO const VBO_VERTEX vertex = { aX, aY, aZ }; currentGroup->PushVertex( &vertex ); } else { glVertex3d( aX, aY, aZ ); } currentItem->PushVertex( &vertex ); } /** * @brief Function that replaces glTranslate and behaves according to isGrouping variable. * In case isGrouping==false, it is simply glTranslate, in other case it * modifies transformation matrix. * @brief Function that replaces glTranslate. It modifies transformation matrix. * * @param aX is translation in X axis direction. * @param aY is translation in Y axis direction. * @param aZ is translation in Z axis direction. */ inline void translate3( double aX, double aY, double aZ ) { if( isGrouping ) { transform = glm::translate( transform, glm::vec3( aX, aY, aZ ) ); } else { glTranslated( aX, aY, aZ ); } } /** * @brief Function that replaces glColor and behaves according to isGrouping variable. * In case isGrouping==false, it is simply glColor, in other case it * modifies color used by current VBO_ITEM. * @brief Function that replaces glColor. It modifies color used by current VBO_ITEM. * * @param aR is red component. * @param aG is green component. Loading @@ -600,33 +559,17 @@ private: */ inline void color4( double aRed, double aGreen, double aBlue, double aAlpha ) { if( isGrouping ) { vboContainer.UseColor( aRed, aGreen, aBlue, aAlpha ); } else { glColor4d( aRed, aGreen, aBlue, aAlpha ); } currentContainer->UseColor( aRed, aGreen, aBlue, aAlpha ); } /** * @brief Function that replaces glColor and behaves according to isGrouping variable. * In case isGrouping==false, it is simply glColor, in other case it * modifies color used by current VBO_ITEM. * @brief Function that replaces glColor. It modifies color used by current VBO_ITEM. * * @param aColor is the new color. */ inline void color4( const COLOR4D& aColor ) { if( isGrouping ) { vboContainer.UseColor( aColor ); } else { glColor4d( aColor.r, aColor.g, aColor.b, aColor.a); } currentContainer->UseColor( aColor ); } /** Loading @@ -639,11 +582,10 @@ private: inline void setShader( SHADER_TYPE aShader, GLfloat aParam1 = 0.0f, GLfloat aParam2 = 0.0f, GLfloat aParam3 = 0.0f ) { if( isUseShader && isGrouping ) if( isUseShader ) { const GLfloat shader[] = { aShader, aParam1, aParam2, aParam3 }; vboContainer.UseShader( shader ); currentContainer->UseShader( shader ); } } }; Loading include/gal/opengl/vbo_container.h +10 −1 Original line number Diff line number Diff line Loading @@ -46,7 +46,7 @@ typedef struct VBO_VERTEX VBO_VERTEX; class VBO_CONTAINER { public: VBO_CONTAINER( int aSize = 1048576 ); VBO_CONTAINER( unsigned int aSize = defaultInitSize ); ~VBO_CONTAINER(); ///< Maps size of free memory chunks to their offsets Loading Loading @@ -99,6 +99,12 @@ public: } } /** * Function Clear() * Removes all the data stored in the container. */ void Clear(); /** * Function GetAllVertices() * Returns all vertices stored in the container. It is especially useful for transferring Loading Loading @@ -344,6 +350,9 @@ private: return power; } ///< Default initial size of a container (expressed in vertices) static const unsigned int defaultInitSize = 1048576; }; } // namespace KiGfx Loading include/gal/opengl/vbo_item.h +1 −1 Original line number Diff line number Diff line Loading @@ -126,7 +126,7 @@ public: ///< Informs the container that there will be no more vertices for the current VBO_ITEM void Finish(); ///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX). ///< Data structure for vertices {X,Y,Z,R,G,B,A,shader¶m} (@see VBO_VERTEX). static const unsigned int VertByteSize = sizeof(VBO_VERTEX); static const unsigned int VertStride = VertByteSize / sizeof(GLfloat); Loading Loading
common/gal/opengl/opengl_gal.cpp +71 −187 Original line number Diff line number Diff line Loading @@ -76,9 +76,10 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, isVboInitialized = false; vboNeedsUpdate = false; currentGroup = NULL; currentItem = NULL; groupCounter = 0; transform = glm::mat4( 1.0f ); // Identity matrix nonCachedItem = NULL; SetSize( parentSize ); Loading Loading @@ -120,10 +121,7 @@ OPENGL_GAL::~OPENGL_GAL() { glFlush(); if( glIsList( displayListSemiCircle ) ) glDeleteLists( displayListSemiCircle, 1 ); if( glIsList( displayListCircle ) ) glDeleteLists( displayListCircle, 1 ); delete nonCachedItem; // Delete the buffers if( isFrameBufferInitialized ) Loading Loading @@ -241,8 +239,8 @@ void OPENGL_GAL::initFrameBuffers() void OPENGL_GAL::initVertexBufferObjects() { // Generate buffers for vertices and indices glGenBuffers( 1, &vboVertices ); glGenBuffers( 1, &vboIndices ); glGenBuffers( 1, &cachedVerts ); glGenBuffers( 1, &cachedInds ); isVboInitialized = true; } Loading @@ -253,8 +251,8 @@ void OPENGL_GAL::deleteVertexBufferObjects() glBindBuffer( GL_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glDeleteBuffers( 1, &vboVertices ); glDeleteBuffers( 1, &vboIndices ); glDeleteBuffers( 1, &cachedVerts ); glDeleteBuffers( 1, &cachedInds ); isVboInitialized = false; } Loading Loading @@ -323,7 +321,6 @@ void OPENGL_GAL::initGlew() } initVertexBufferObjects(); computeCircleDisplayLists(); isGlewInitialized = true; } Loading Loading @@ -425,9 +422,9 @@ void OPENGL_GAL::BeginDrawing() // Number of vertices to be drawn indicesSize = 0; glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIndices ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, cachedInds ); // Discard old buffer, so we can use it again glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::IndByteSize, glBufferData( GL_ELEMENT_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::IndByteSize, NULL, GL_STREAM_DRAW ); // Map the GPU memory, so we can store indices that are going to be drawn Loading @@ -436,6 +433,14 @@ void OPENGL_GAL::BeginDrawing() { wxLogError( wxT( "Could not map GPU memory" ) ); } // Prepare buffer for non-cached items delete nonCachedItem; nonCachedItem = new VBO_ITEM( &nonCachedVbo ); // By default we draw non-cached objects, it changes on BeginGroup()/EndGroup() currentContainer = &nonCachedVbo; currentItem = nonCachedItem; } Loading Loading @@ -487,9 +492,6 @@ void OPENGL_GAL::blitMainTexture( bool aIsClearFrameBuffer ) void OPENGL_GAL::EndDrawing() { // TODO Checking if we are using right VBOs, in other case do the binding. // Right now there is only one VBO, so there is no problem. if( !glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER ) ) { wxLogError( wxT( "Unmapping indices buffer failed" ) ); Loading @@ -500,7 +502,7 @@ void OPENGL_GAL::EndDrawing() glEnableClientState( GL_COLOR_ARRAY ); // Bind vertices data buffers glBindBuffer( GL_ARRAY_BUFFER, vboVertices ); glBindBuffer( GL_ARRAY_BUFFER, cachedVerts ); glVertexPointer( VBO_ITEM::CoordStride, GL_FLOAT, VBO_ITEM::VertByteSize, 0 ); glColorPointer( VBO_ITEM::ColorStride, GL_UNSIGNED_BYTE, VBO_ITEM::VertByteSize, (GLvoid*) VBO_ITEM::ColorByteOffset ); Loading @@ -518,6 +520,20 @@ void OPENGL_GAL::EndDrawing() glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Draw non-cached items GLfloat* vertices = (GLfloat*)( nonCachedVbo.GetAllVertices() ); GLubyte* colors = (GLubyte*)( nonCachedVbo.GetAllVertices() ) + VBO_ITEM::ColorOffset; GLfloat* shaders = (GLfloat*)( nonCachedVbo.GetAllVertices() ) + VBO_ITEM::ShaderOffset; glVertexPointer( VBO_ITEM::CoordStride, GL_FLOAT, VBO_ITEM::VertByteSize, vertices ); glColorPointer( VBO_ITEM::ColorStride, GL_UNSIGNED_BYTE, VBO_ITEM::VertByteSize, colors ); if( isUseShader ) { glVertexAttribPointer( shaderAttrib, VBO_ITEM::ShaderStride, GL_FLOAT, GL_FALSE, VBO_ITEM::VertByteSize, shaders ); } glDrawArrays( GL_TRIANGLES, nonCachedItem->GetOffset(), nonCachedItem->GetSize() ); // Deactivate vertex array glDisableClientState( GL_COLOR_ARRAY ); glDisableClientState( GL_VERTEX_ARRAY ); Loading @@ -543,17 +559,17 @@ void OPENGL_GAL::rebuildVbo() prof_start( &totalTime, false ); #endif /* __WXDEBUG__ */ GLfloat* data = (GLfloat*) vboContainer.GetAllVertices(); GLfloat* data = (GLfloat*) cachedVbo.GetAllVertices(); // Upload vertices coordinates and shader types to GPU memory glBindBuffer( GL_ARRAY_BUFFER, vboVertices ); glBufferData( GL_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::VertByteSize, glBindBuffer( GL_ARRAY_BUFFER, cachedVerts ); glBufferData( GL_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::VertByteSize, data, GL_DYNAMIC_DRAW ); glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Allocate the biggest possible buffer for indices glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vboIndices ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, vboContainer.GetSize() * VBO_ITEM::IndByteSize, glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, cachedInds ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, cachedVbo.GetSize() * VBO_ITEM::IndByteSize, NULL, GL_STREAM_DRAW ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 ); Loading @@ -563,7 +579,7 @@ void OPENGL_GAL::rebuildVbo() prof_end( &totalTime ); wxLogDebug( wxT( "Rebuilding VBO::%d vertices / %.1f ms" ), vboContainer.GetSize(), (double) totalTime.value / 1000.0 ); cachedVbo.GetSize(), (double) totalTime.value / 1000.0 ); #endif /* __WXDEBUG__ */ } Loading @@ -577,27 +593,16 @@ inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2 if( lineLength <= 0.0 ) return; if( lineWidth * worldScale < 1.0002 && !isGrouping && !isUseShader ) { // Limit the width of the line to a minimum of one pixel // this looks best without anti-aliasing scale = 0.5001 / worldScale / lineLength; } VECTOR2D perpendicularVector( -startEndVector.y * scale, startEndVector.x * scale ); begin( GL_TRIANGLES ); if( isUseShader && isGrouping ) if( isUseShader ) { glm::vec4 vector( perpendicularVector.x, perpendicularVector.y, 0.0, 0.0 ); // If transform stack is not empty, then it means that // there is a transformation matrix that has to be applied if( !transformStack.empty() ) { vector = transform * vector; } // Line width is maintained by the vertex shader setShader( SHADER_LINE, vector.x, vector.y, lineWidth ); Loading Loading @@ -634,8 +639,6 @@ inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2 vertex3( v3.x, v3.y, layerDepth ); vertex3( v2.x, v2.y, layerDepth ); } end(); } Loading Loading @@ -760,7 +763,6 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn setShader( SHADER_NONE ); color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); begin( GL_TRIANGLES ); vertex3( aStartPoint.x, aStartPoint.y, layerDepth ); vertex3( diagonalPointA.x, diagonalPointA.y, layerDepth ); vertex3( aEndPoint.x, aEndPoint.y, layerDepth ); Loading @@ -768,14 +770,13 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn vertex3( aStartPoint.x, aStartPoint.y, layerDepth ); vertex3( aEndPoint.x, aEndPoint.y, layerDepth ); vertex3( diagonalPointB.x, diagonalPointB.y, layerDepth ); end(); } } void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) { if( isUseShader && isGrouping ) if( isUseShader ) { if( isFillEnabled ) { Loading Loading @@ -856,8 +857,6 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) translate3( aCenterPoint.x, aCenterPoint.y, 0.0 ); Scale( VECTOR2D( aRadius, aRadius ) ); begin( GL_TRIANGLES ); for( int i = 0; i < 3 * CIRCLE_POINTS; ++i ) { // verticesCircle contains precomputed circle points interleaved with vertex Loading Loading @@ -887,8 +886,6 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) vertex3( circle[next].x * innerScale, circle[next].y * innerScale, layerDepth ); } end(); Restore(); } } Loading @@ -902,14 +899,7 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius ) translate3( aCenterPoint.x, aCenterPoint.y, layerDepth ); Scale( VECTOR2D( aRadius, aRadius ) ); if( isGrouping ) { currentGroup->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS * 3 ); } else { glCallList( displayListCircle ); } currentItem->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS * 3 ); Restore(); } Loading @@ -934,7 +924,7 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle ) { if( isUseShader && isGrouping ) if( isUseShader ) { Save(); Translate( aCenterPoint ); Loading Loading @@ -966,15 +956,8 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad Scale( VECTOR2D( aRadius, aRadius ) ); Rotate( aAngle ); if( isGrouping ) { // It is enough just to push just a half of the circle vertices to make a semicircle currentGroup->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS / 2 * 3 ); } else { glCallList( displayListSemiCircle ); } currentItem->PushVertices( verticesCircle.GetVertices(), CIRCLE_POINTS / 2 * 3 ); Restore(); } Loading @@ -983,7 +966,7 @@ void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRad void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle ) { if( isUseShader && isGrouping ) if( isUseShader ) { Save(); Translate( aCenterPoint ); Loading Loading @@ -1028,8 +1011,6 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa VBO_VERTEX* circle = verticesCircle.GetVertices(); int next; begin( GL_TRIANGLES ); for( int i = 0; i < ( 3 * CIRCLE_POINTS ) / 2; ++i ) { // verticesCircle contains precomputed circle points interleaved with vertex Loading Loading @@ -1059,8 +1040,6 @@ void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRa vertex3( circle[next].x * innerScale, circle[next].y * innerScale, 0.0 ); } end(); Restore(); } } Loading Loading @@ -1123,8 +1102,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a double alphaIncrement = 2 * M_PI / CIRCLE_POINTS; color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a ); begin( GL_TRIANGLES ); for( double alpha = aStartAngle; alpha < aEndAngle; ) { double v0[] = { cos( alpha ) * innerScale, sin( alpha ) * innerScale }; Loading @@ -1147,8 +1124,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a vertex3( v2[0], v2[1], 0.0 ); } end(); // Draw line caps drawFilledSemiCircle( startPoint, lineWidth / aRadius / 2.0, aStartAngle + M_PI ); drawFilledSemiCircle( endPoint, lineWidth / aRadius / 2.0, aEndAngle ); Loading @@ -1161,8 +1136,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a double alpha; color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); begin( GL_TRIANGLES ); for( alpha = aStartAngle; ( alpha + alphaIncrement ) < aEndAngle; ) { vertex3( middlePoint.x, middlePoint.y, 0.0 ); Loading @@ -1174,7 +1147,6 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a vertex3( middlePoint.x, middlePoint.y, 0.0 ); vertex3( cos( alpha ), sin( alpha ), 0.0 ); vertex3( endPoint.x, endPoint.y, 0.0 ); end(); } Restore(); Loading Loading @@ -1228,7 +1200,7 @@ void OPENGL_GAL::DrawPolygon( const std::deque<VECTOR2D>& aPointList ) glShadeModel( GL_FLAT ); TessParams params = { currentGroup, tessIntersects }; TessParams params = { currentItem, tessIntersects }; gluTessBeginPolygon( tesselator, ¶ms ); gluTessBeginContour( tesselator ); Loading Loading @@ -1347,42 +1319,21 @@ void OPENGL_GAL::Transform( MATRIX3x3D aTransformation ) void OPENGL_GAL::Rotate( double aAngle ) { if( isGrouping ) { transform = glm::rotate( transform, (float) aAngle, glm::vec3( 0, 0, 1 ) ); } else { glRotated( aAngle * ( 360 / ( 2 * M_PI ) ), 0, 0, 1 ); } } void OPENGL_GAL::Translate( const VECTOR2D& aVector ) { if( isGrouping ) { transform = glm::translate( transform, glm::vec3( aVector.x, aVector.y, 0 ) ); } else { glTranslated( aVector.x, aVector.y, 0 ); } } void OPENGL_GAL::Scale( const VECTOR2D& aScale ) { if( isGrouping ) { transform = glm::scale( transform, glm::vec3( aScale.x, aScale.y, 0 ) ); } else { glScaled( aScale.x, aScale.y, 0 ); } } void OPENGL_GAL::Flush() Loading @@ -1392,22 +1343,13 @@ void OPENGL_GAL::Flush() void OPENGL_GAL::Save() { if( isGrouping ) { transformStack.push( transform ); vboContainer.SetTransformMatrix( &transform ); } else { glPushMatrix(); } currentContainer->SetTransformMatrix( &transform ); } void OPENGL_GAL::Restore() { if( isGrouping ) { transform = transformStack.top(); transformStack.pop(); Loading @@ -1415,12 +1357,7 @@ void OPENGL_GAL::Restore() if( transformStack.empty() ) { // Disable transforming, as the selected matrix is identity vboContainer.SetTransformMatrix( NULL ); } } else { glPopMatrix(); currentContainer->SetTransformMatrix( NULL ); } } Loading @@ -1433,9 +1370,10 @@ int OPENGL_GAL::BeginGroup() vboNeedsUpdate = true; // Save the pointer for caching the current item currentGroup = new VBO_ITEM( &vboContainer ); currentItem = new VBO_ITEM( &cachedVbo ); currentContainer = &cachedVbo; int groupNumber = getGroupNumber(); groups.insert( std::make_pair( groupNumber, currentGroup ) ); groups.insert( std::make_pair( groupNumber, currentItem ) ); return groupNumber; } Loading @@ -1443,7 +1381,9 @@ int OPENGL_GAL::BeginGroup() void OPENGL_GAL::EndGroup() { currentGroup->Finish(); currentItem->Finish(); currentItem = nonCachedItem; currentContainer = &nonCachedVbo; isGrouping = false; } Loading Loading @@ -1523,42 +1463,6 @@ void OPENGL_GAL::computeCircleVbo() } 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 ); 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(); } void OPENGL_GAL::ComputeWorldScreenMatrix() { ComputeWorldScale(); Loading Loading @@ -1603,10 +1507,6 @@ void CALLBACK VertexCallback( GLvoid* aVertexPtr, void* aData ) VBO_VERTEX newVertex = { vertex[0], vertex[1], vertex[2] }; vboItem->PushVertex( &newVertex ); } else { glVertex3dv( vertex ); } } Loading @@ -1633,20 +1533,6 @@ void CALLBACK EdgeCallback(void) } void CALLBACK BeginCallback( GLenum aWhich, void* aData ) { if( !aData ) glBegin( aWhich ); } void CALLBACK EndCallback( void* aData ) { if( !aData ) glEnd(); } void CALLBACK ErrorCallback( GLenum aErrorCode ) { const GLubyte* estring; Loading @@ -1661,8 +1547,6 @@ void InitTesselatorCallbacks( GLUtesselator* aTesselator ) gluTessCallback( aTesselator, GLU_TESS_VERTEX_DATA, ( void (CALLBACK*)() )VertexCallback ); gluTessCallback( aTesselator, GLU_TESS_COMBINE_DATA, ( void (CALLBACK*)() )CombineCallback ); gluTessCallback( aTesselator, GLU_TESS_EDGE_FLAG, ( void (CALLBACK*)() )EdgeCallback ); gluTessCallback( aTesselator, GLU_TESS_BEGIN_DATA, ( void (CALLBACK*)() )BeginCallback ); gluTessCallback( aTesselator, GLU_TESS_END_DATA, ( void (CALLBACK*)() )EndCallback ); gluTessCallback( aTesselator, GLU_TESS_ERROR_DATA, ( void (CALLBACK*)() )ErrorCallback ); } Loading Loading @@ -1771,19 +1655,19 @@ void OPENGL_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd VECTOR2D point4 = aEndPoint - perpendicularVector; // Set color glColor4d( gridColor.r, gridColor.g, gridColor.b, gridColor.a ); color4( gridColor.r, gridColor.g, gridColor.b, gridColor.a ); setShader( SHADER_NONE ); // Draw the quad for the grid line glBegin( GL_TRIANGLES ); double gridDepth = depthRange.y * 0.75; glVertex3d( point1.x, point1.y, gridDepth ); glVertex3d( point2.x, point2.y, gridDepth ); glVertex3d( point4.x, point4.y, gridDepth ); vertex3( point1.x, point1.y, gridDepth ); vertex3( point2.x, point2.y, gridDepth ); vertex3( point4.x, point4.y, gridDepth ); glVertex3d( point1.x, point1.y, gridDepth ); glVertex3d( point4.x, point4.y, gridDepth ); glVertex3d( point3.x, point3.y, gridDepth ); glEnd(); vertex3( point1.x, point1.y, gridDepth ); vertex3( point4.x, point4.y, gridDepth ); vertex3( point3.x, point3.y, gridDepth ); } Loading
common/gal/opengl/vbo_container.cpp +25 −1 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ using namespace KiGfx; VBO_CONTAINER::VBO_CONTAINER( int aSize ) : VBO_CONTAINER::VBO_CONTAINER( unsigned int aSize ) : m_freeSpace( aSize ), m_currentSize( aSize ), itemStarted( false ), m_transform( NULL ), m_failed( false ) { Loading Loading @@ -202,6 +202,30 @@ void VBO_CONTAINER::Add( VBO_ITEM* aVboItem, const VBO_VERTEX* aVertex, unsigned } void VBO_CONTAINER::Clear() { // Change size to the default one m_vertices = static_cast<VBO_VERTEX*>( realloc( m_vertices, defaultInitSize * sizeof( VBO_VERTEX ) ) ); // Reset state variables m_freeSpace = defaultInitSize; m_currentSize = defaultInitSize; itemStarted = false; m_transform = NULL; m_failed = false; // By default no shader is used m_shader[0] = 0; m_freeChunks.clear(); m_reservedChunks.clear(); // In the beginning there is only free space m_freeChunks.insert( Chunk( m_freeSpace, 0 ) ); } VBO_VERTEX* VBO_CONTAINER::GetAllVertices() const { return m_vertices; Loading
include/gal/opengl/opengl_gal.h +19 −77 Original line number Diff line number Diff line Loading @@ -337,21 +337,22 @@ private: wxEvtHandler* mouseListener; wxEvtHandler* paintListener; // VBO buffers & display lists (used in immediate mode) // VBO buffered vertices for faster circle & semicircle drawing VBO_CONTAINER precomputedContainer; ///< Container for storing display lists VBO_ITEM verticesCircle; ///< Buffer for circle & semicircle vertices GLuint displayListCircle; ///< Circle display list GLuint displayListSemiCircle; ///< Semi circle display list // Vertex buffer objects related fields typedef boost::unordered_map<unsigned int, VBO_ITEM*> GroupsMap; GroupsMap 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 VBO_ITEM* currentItem; ///< Currently used VBO_ITEM (for grouping) VBO_CONTAINER* currentContainer; ///< Currently used VBO_CONTAINER (for storing VBO_ITEMs) VBO_CONTAINER cachedVbo; ///< Container for storing VBO_ITEMs GLuint cachedVerts; ///< Currently used vertices VBO handle GLuint cachedInds; ///< Currently used indices VBO handle bool vboNeedsUpdate; ///< Flag indicating if VBO should be rebuilt VBO_CONTAINER nonCachedVbo; ///< Container for storing non-cached VBO_ITEMs VBO_ITEM* nonCachedItem; ///< Item that is gathering non-cached vertices glm::mat4 transform; ///< Current transformation matrix std::stack<glm::mat4> transformStack; ///< Stack of transformation matrices Loading Loading @@ -432,10 +433,6 @@ private: /// Compute the points of an unit circle & semicircle and store them in VBO. void computeCircleVbo(); /// Compute the points of an unit circle & semicircle and store them in display lists /// for drawing in immediate mode. void computeCircleDisplayLists(); // Event handling /** * @brief This is the window creation event handler. Loading Loading @@ -527,26 +524,6 @@ private: */ 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. * @param aMode specifies the primitive or primitives that will be created. */ inline void begin( GLenum aMode ) { if( !isGrouping ) glBegin( aMode ); } /** * @brief Ends drawing in immediate mode or does nothing if an item's caching has started. */ inline void end() { if( !isGrouping ) glEnd(); } /** * @brief Adds vertex to the current item or draws it in immediate mode. * @param aX is X coordinate. Loading @@ -554,44 +531,26 @@ private: * @param aZ is Z coordinate. */ inline void vertex3( double aX, double aY, double aZ ) { if( isGrouping ) { // New vertex coordinates for VBO const VBO_VERTEX vertex = { aX, aY, aZ }; currentGroup->PushVertex( &vertex ); } else { glVertex3d( aX, aY, aZ ); } currentItem->PushVertex( &vertex ); } /** * @brief Function that replaces glTranslate and behaves according to isGrouping variable. * In case isGrouping==false, it is simply glTranslate, in other case it * modifies transformation matrix. * @brief Function that replaces glTranslate. It modifies transformation matrix. * * @param aX is translation in X axis direction. * @param aY is translation in Y axis direction. * @param aZ is translation in Z axis direction. */ inline void translate3( double aX, double aY, double aZ ) { if( isGrouping ) { transform = glm::translate( transform, glm::vec3( aX, aY, aZ ) ); } else { glTranslated( aX, aY, aZ ); } } /** * @brief Function that replaces glColor and behaves according to isGrouping variable. * In case isGrouping==false, it is simply glColor, in other case it * modifies color used by current VBO_ITEM. * @brief Function that replaces glColor. It modifies color used by current VBO_ITEM. * * @param aR is red component. * @param aG is green component. Loading @@ -600,33 +559,17 @@ private: */ inline void color4( double aRed, double aGreen, double aBlue, double aAlpha ) { if( isGrouping ) { vboContainer.UseColor( aRed, aGreen, aBlue, aAlpha ); } else { glColor4d( aRed, aGreen, aBlue, aAlpha ); } currentContainer->UseColor( aRed, aGreen, aBlue, aAlpha ); } /** * @brief Function that replaces glColor and behaves according to isGrouping variable. * In case isGrouping==false, it is simply glColor, in other case it * modifies color used by current VBO_ITEM. * @brief Function that replaces glColor. It modifies color used by current VBO_ITEM. * * @param aColor is the new color. */ inline void color4( const COLOR4D& aColor ) { if( isGrouping ) { vboContainer.UseColor( aColor ); } else { glColor4d( aColor.r, aColor.g, aColor.b, aColor.a); } currentContainer->UseColor( aColor ); } /** Loading @@ -639,11 +582,10 @@ private: inline void setShader( SHADER_TYPE aShader, GLfloat aParam1 = 0.0f, GLfloat aParam2 = 0.0f, GLfloat aParam3 = 0.0f ) { if( isUseShader && isGrouping ) if( isUseShader ) { const GLfloat shader[] = { aShader, aParam1, aParam2, aParam3 }; vboContainer.UseShader( shader ); currentContainer->UseShader( shader ); } } }; Loading
include/gal/opengl/vbo_container.h +10 −1 Original line number Diff line number Diff line Loading @@ -46,7 +46,7 @@ typedef struct VBO_VERTEX VBO_VERTEX; class VBO_CONTAINER { public: VBO_CONTAINER( int aSize = 1048576 ); VBO_CONTAINER( unsigned int aSize = defaultInitSize ); ~VBO_CONTAINER(); ///< Maps size of free memory chunks to their offsets Loading Loading @@ -99,6 +99,12 @@ public: } } /** * Function Clear() * Removes all the data stored in the container. */ void Clear(); /** * Function GetAllVertices() * Returns all vertices stored in the container. It is especially useful for transferring Loading Loading @@ -344,6 +350,9 @@ private: return power; } ///< Default initial size of a container (expressed in vertices) static const unsigned int defaultInitSize = 1048576; }; } // namespace KiGfx Loading
include/gal/opengl/vbo_item.h +1 −1 Original line number Diff line number Diff line Loading @@ -126,7 +126,7 @@ public: ///< Informs the container that there will be no more vertices for the current VBO_ITEM void Finish(); ///< Data organization information for vertices {X,Y,Z,R,G,B,A} (@see VBO_VERTEX). ///< Data structure for vertices {X,Y,Z,R,G,B,A,shader¶m} (@see VBO_VERTEX). static const unsigned int VertByteSize = sizeof(VBO_VERTEX); static const unsigned int VertStride = VertByteSize / sizeof(GLfloat); Loading