diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index c17b0c7641..6e8a225d93 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -40,23 +40,16 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener, const wxString& aName ) : wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName ) { - // Default values - fillColor = COLOR4D( 0, 0, 0, 1 ); - strokeColor = COLOR4D( 1, 1, 1, 1 ); - screenSize = VECTOR2D( aParent->GetSize() ); - parentWindow = aParent; mouseListener = aMouseListener; paintListener = aPaintListener; + // Initialize the flags isGrouping = false; isInitialized = false; isDeleteSavedPixels = false; - zoomFactor = 1.0; groupCounter = 0; - SetSize( aParent->GetSize() ); - // Connecting the event handlers Connect( wxEVT_PAINT, wxPaintEventHandler( CAIRO_GAL::onPaint ) ); @@ -73,17 +66,12 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); #endif - // Initialize the cursor shape - SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); - initCursor( 21 ); + SetSize( aParent->GetSize() ); + screenSize = VECTOR2D( aParent->GetSize() ); + initCursor( 20 ); - // Allocate memory + // Allocate memory for pixel storage allocateBitmaps(); - - // Set grid defaults - SetGridColor( COLOR4D( 0.5, 0.5, 0.5, 0.3 ) ); - SetCoarseGrid( 10 ); - SetGridLineWidth( 0.5 ); } @@ -107,7 +95,7 @@ void CAIRO_GAL::onPaint( wxPaintEvent& aEvent ) void CAIRO_GAL::ResizeScreen( int aWidth, int aHeight ) { - screenSize = VECTOR2D( aWidth, aHeight ); + screenSize = VECTOR2D( aWidth, aHeight ); // Recreate the bitmaps deleteBitmaps(); @@ -557,10 +545,10 @@ void CAIRO_GAL::SetLayerDepth( double aLayerDepth ) { storePath(); -// cairo_pop_group_to_source( currentContext ); -// cairo_paint_with_alpha( currentContext, fillColor.a ); -// -// cairo_push_group( currentContext ); + cairo_pop_group_to_source( currentContext ); + cairo_paint_with_alpha( currentContext, fillColor.a ); + + cairo_push_group( currentContext ); } } diff --git a/common/gal/graphics_abstraction_layer.cpp b/common/gal/graphics_abstraction_layer.cpp index 88855fa5c6..a3bd5cff0f 100644 --- a/common/gal/graphics_abstraction_layer.cpp +++ b/common/gal/graphics_abstraction_layer.cpp @@ -38,15 +38,21 @@ GAL::GAL() : // Set the default values for the internal variables SetIsFill( false ); SetIsStroke( true ); - SetIsCursorEnabled( false ); - SetZoomFactor( 1.0 ); SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) ); SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); - SetGridVisibility( true ); - SetGridColor( COLOR4D( 1, 1, 1, 0.1 ) ); - SetCoarseGrid( 5 ); - SetLineWidth( 1.0 ); + SetIsCursorEnabled( false ); + SetZoomFactor( 1.0 ); SetDepthRange( VECTOR2D( -2048, 2047 ) ); + SetLineWidth( 1.0 ); + + // Set grid defaults + SetGridVisibility( true ); + SetGridColor( COLOR4D( 0.4, 0.4, 0.4, 1.0 ) ); + SetCoarseGrid( 10 ); + SetGridLineWidth( 0.5 ); + + // Initialize the cursor shape + SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); strokeFont.LoadNewStrokeFont( newstroke_font, newstroke_font_bufsize ); } @@ -65,99 +71,95 @@ void GAL::DrawGrid() SetTarget( TARGET_NONCACHED ); // The grid consists of lines - // For the drawing the start points, end points and increments have to be calculated in world coordinates - VECTOR2D screenStartPoint( 0, 0 ); - VECTOR2D screenEndPoint( screenSize.x, screenSize.y ); + // For the drawing the start points, end points and increments have + // to be calculated in world coordinates MATRIX3x3D inverseMatrix = worldScreenMatrix.Inverse(); - VECTOR2D worldStartPoint = inverseMatrix * screenStartPoint; - VECTOR2D worldEndPoint = inverseMatrix * screenEndPoint; - - // Compute grid variables - int gridStartX = round( worldStartPoint.x / gridSize.x ); - int gridEndX = round( worldEndPoint.x / gridSize.x ); - int gridStartY = round( worldStartPoint.y / gridSize.y ); - int gridEndY = round( worldEndPoint.y / gridSize.y ); + VECTOR2D worldStartPoint = inverseMatrix * VECTOR2D( 0.0, 0.0 ); + VECTOR2D worldEndPoint = inverseMatrix * screenSize; int gridScreenSizeDense = round( gridSize.x * worldScale ); - int gridScreenSizeCoarse = round( gridSize.x * (double) gridTick * worldScale ); - - // Swap the coordinates, if they have not the right order - SWAP( gridEndX, <, gridStartX ); - SWAP( gridEndY, <, gridStartY ); - - // Correct the index, else some lines are not correctly painted - gridStartX -= 1; - gridStartY -= 1; - gridEndX += 1; - gridEndY += 1; - - double savedLineWidth = GetLineWidth(); - COLOR4D savedColor = GetStrokeColor(); + int gridScreenSizeCoarse = round( gridSize.x * static_cast( gridTick ) * worldScale ); // Compute the line width of the grid - ComputeWorldScale(); - double width = gridLineWidth / worldScale; - double doubleWidth = 2 * width; + double width = 2.0 * gridLineWidth / worldScale; + double doubleWidth = 2.0 * width; - SetLayerDepth( 0.0 ); + SetIsFill( false ); + SetIsStroke( true ); // Draw the origin marker - double origSize = (double) gridOriginMarkerSize / worldScale; + SetLayerDepth( 0.0 ); + double origSize = static_cast( gridOriginMarkerSize ) / worldScale; SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); SetLineWidth( width ); - SetIsFill( false ); - DrawLine( gridOrigin + VECTOR2D( -origSize, -origSize ), gridOrigin + VECTOR2D( origSize, origSize ) ); - DrawLine( gridOrigin + VECTOR2D( -origSize, origSize ), gridOrigin + VECTOR2D( origSize, -origSize ) ); + DrawLine( gridOrigin + VECTOR2D( -origSize, -origSize ), + gridOrigin + VECTOR2D( origSize, origSize ) ); + DrawLine( gridOrigin + VECTOR2D( -origSize, origSize ), + gridOrigin + VECTOR2D( origSize, -origSize ) ); DrawCircle( gridOrigin, origSize * 0.7 ); - SetStrokeColor( gridColor ); - - if( std::max( gridScreenSizeDense, gridScreenSizeCoarse ) < gridDrawThreshold ) - return; - - SetLayerDepth( 0.0 ); - // Now draw the grid, every coarse grid line gets the double width - for( int j = gridStartY; j < gridEndY; j += 1 ) + // Check if the grid would not be too dense + if( std::max( gridScreenSizeDense, gridScreenSizeCoarse ) > gridDrawThreshold ) { - if( j % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + // Compute grid variables + int gridStartX = round( worldStartPoint.x / gridSize.x ); + int gridEndX = round( worldEndPoint.x / gridSize.x ); + int gridStartY = round( worldStartPoint.y / gridSize.y ); + int gridEndY = round( worldEndPoint.y / gridSize.y ); + + // Swap the coordinates, if they have not the right order + SWAP( gridEndX, <, gridStartX ); + SWAP( gridEndY, <, gridStartY ); + + // Correct the index, else some lines are not correctly painted + gridStartX -= 1; + gridStartY -= 1; + gridEndX += 1; + gridEndY += 1; + + // Draw the grid behind all layers + SetLayerDepth( depthRange.y * 0.75 ); + SetStrokeColor( gridColor ); + + // Now draw the grid, every coarse grid line gets the double width + for( int j = gridStartY; j < gridEndY; j += 1 ) { - SetLineWidth( doubleWidth ); - } - else - { - SetLineWidth( width ); + if( j % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + { + SetLineWidth( doubleWidth ); + } + else + { + SetLineWidth( width ); + } + + if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) + || gridScreenSizeDense > gridDrawThreshold ) + { + DrawGridLine( VECTOR2D( gridStartX * gridSize.x, j * gridSize.y ), + VECTOR2D( gridEndX * gridSize.x, j * gridSize.y ) ); + } } - if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) - || gridScreenSizeDense > gridDrawThreshold ) + for( int i = gridStartX; i < gridEndX; i += 1 ) { - DrawGridLine( VECTOR2D( gridStartX * gridSize.x, j * gridSize.y ), - VECTOR2D( gridEndX * gridSize.x, j * gridSize.y ) ); + if( i % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + { + SetLineWidth( doubleWidth ); + } + else + { + SetLineWidth( width ); + } + + if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) + || gridScreenSizeDense > gridDrawThreshold ) + { + DrawGridLine( VECTOR2D( i * gridSize.x, gridStartY * gridSize.y ), + VECTOR2D( i * gridSize.x, gridEndY * gridSize.y ) ); + } } } - - for( int i = gridStartX; i < gridEndX; i += 1 ) - { - if( i % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) - { - SetLineWidth( doubleWidth ); - } - else - { - SetLineWidth( width ); - } - - if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) - || gridScreenSizeDense > gridDrawThreshold ) - { - DrawGridLine( VECTOR2D( i * gridSize.x, gridStartY * gridSize.y ), - VECTOR2D( i * gridSize.x, gridEndY * gridSize.y ) ); - } - } - - // Restore old values - SetLineWidth( savedLineWidth ); - SetStrokeColor( savedColor ); } diff --git a/common/gal/opengl/opengl_compositor.cpp b/common/gal/opengl/opengl_compositor.cpp index ab8eb59188..2ff733e978 100644 --- a/common/gal/opengl/opengl_compositor.cpp +++ b/common/gal/opengl/opengl_compositor.cpp @@ -143,13 +143,18 @@ void OPENGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle ) return; // Change the rendering destination to the selected attachment point - if( m_currentFbo != m_framebuffer ) + if( aBufferHandle == 0 ) + { + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); + m_currentFbo = 0; + } + else if( m_currentFbo != m_framebuffer ) { glBindFramebuffer( GL_FRAMEBUFFER, m_framebuffer ); m_currentFbo = m_framebuffer; } - if( m_current != aBufferHandle - 1 ) + if( m_currentFbo != 0 && m_current != aBufferHandle - 1 ) { m_current = aBufferHandle - 1; glDrawBuffer( m_buffers[m_current].attachmentPoint ); diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 22b5bae9b9..9acb2d7f65 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -63,29 +63,14 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, mouseListener = aMouseListener; paintListener = aPaintListener; - // Set the cursor size - initCursor( 20 ); - SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); - // Initialize the flags isGlewInitialized = false; isFramebufferInitialized = false; isShaderInitialized = false; isGrouping = false; - wxSize parentSize = aParent->GetSize(); groupCounter = 0; - SetSize( parentSize ); - - screenSize.x = parentSize.x; - screenSize.y = parentSize.y; - - // Set grid defaults - SetGridColor( COLOR4D( 0.3, 0.3, 0.3, 0.3 ) ); - SetCoarseGrid( 10 ); - SetGridLineWidth( 1.0 ); - - // Connecting the event handlers. + // Connecting the event handlers Connect( wxEVT_PAINT, wxPaintEventHandler( OPENGL_GAL::onPaint ) ); // Mouse events are skipped to the parent @@ -101,6 +86,10 @@ OPENGL_GAL::OPENGL_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener, Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( OPENGL_GAL::skipMouseEvent ) ); #endif + SetSize( aParent->GetSize() ); + screenSize = VECTOR2D( aParent->GetSize() ); + initCursor( 20 ); + // Tesselator initialization tesselator = gluNewTess(); InitTesselatorCallbacks( tesselator ); @@ -308,6 +297,12 @@ void OPENGL_GAL::BeginDrawing() SetStrokeColor( strokeColor ); // Prepare buffers for drawing + compositor.SetBuffer( mainBuffer ); + compositor.ClearBuffer(); + compositor.SetBuffer( overlayBuffer ); + compositor.ClearBuffer(); + compositor.SetBuffer( 0 ); // Unbind buffers + nonCachedManager.Clear(); overlayManager.Clear(); @@ -321,13 +316,11 @@ void OPENGL_GAL::EndDrawing() { // Cached & non-cached containers are rendered to the same buffer compositor.SetBuffer( mainBuffer ); - compositor.ClearBuffer(); nonCachedManager.EndDrawing(); cachedManager.EndDrawing(); // Overlay container is rendered to a different buffer compositor.SetBuffer( overlayBuffer ); - compositor.ClearBuffer(); overlayManager.EndDrawing(); // Draw the remaining contents, blit the rendering targets to the screen, swap the buffers @@ -349,11 +342,9 @@ inline void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2 if( lineLength <= 0.0 ) return; - VECTOR2D perpendicularVector( -startEndVector.y * scale, startEndVector.x * scale ); - glm::vec4 vector( perpendicularVector.x, perpendicularVector.y, 0.0, 0.0 ); - // The perpendicular vector also needs transformations - vector = currentManager->GetTransformation() * vector; + glm::vec4 vector = currentManager->GetTransformation() * + glm::vec4( -startEndVector.y * scale, startEndVector.x * scale, 0.0, 0.0 ); // Line width is maintained by the vertex shader currentManager->Shader( SHADER_LINE, vector.x, vector.y, lineWidth ); @@ -1151,39 +1142,26 @@ void OPENGL_GAL::DrawCursor( VECTOR2D aCursorPosition ) void OPENGL_GAL::DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) { - // TODO change to simple drawline - // We check, if we got a horizontal or a vertical grid line and compute the offset - VECTOR2D perpendicularVector; + compositor.SetBuffer( mainBuffer ); - if( aStartPoint.x == aEndPoint.x ) + // We do not need a very precise comparison here (the lineWidth is set by GAL::DrawGrid()) + if( fabs( lineWidth - 2.0 * gridLineWidth / worldScale ) < 0.1 ) { - // Vertical grid line - perpendicularVector = VECTOR2D( 0.5 * lineWidth, 0 ); + glLineWidth( 1.0 ); } else { - // Horizontal grid line - perpendicularVector = VECTOR2D( 0, 0.5 * lineWidth ); + glLineWidth( 2.0 ); } - // Now we compute the edge points of the quad - VECTOR2D point1 = aStartPoint + perpendicularVector; - VECTOR2D point2 = aStartPoint - perpendicularVector; - VECTOR2D point3 = aEndPoint + perpendicularVector; - VECTOR2D point4 = aEndPoint - perpendicularVector; + glColor4d( gridColor.r, gridColor.g, gridColor.b, gridColor.a ); - currentManager->Color( gridColor.r, gridColor.g, gridColor.b, gridColor.a ); - currentManager->Shader( SHADER_NONE ); + glBegin( GL_LINES ); + glVertex3d( aStartPoint.x, aStartPoint.y, layerDepth ); + glVertex3d( aEndPoint.x, aEndPoint.y, layerDepth ); + glEnd(); - // Draw the quad for the grid line - double gridDepth = depthRange.y * 0.75; - currentManager->Vertex( point1.x, point1.y, gridDepth ); - currentManager->Vertex( point2.x, point2.y, gridDepth ); - currentManager->Vertex( point4.x, point4.y, gridDepth ); - - currentManager->Vertex( point1.x, point1.y, gridDepth ); - currentManager->Vertex( point4.x, point4.y, gridDepth ); - currentManager->Vertex( point3.x, point3.y, gridDepth ); + glColor4d( 1.0, 1.0, 1.0, 1.0 ); } diff --git a/common/gal/opengl/shader.vert b/common/gal/opengl/shader.vert index 86f468b3c6..f22a582b6b 100644 --- a/common/gal/opengl/shader.vert +++ b/common/gal/opengl/shader.vert @@ -51,7 +51,7 @@ void main() // Make lines appear to be at least 1 pixel wide if( worldScale * lineWidth < MIN_WIDTH ) - scale = 1.0f / ( worldScale * lineWidth ); + scale = MIN_WIDTH / ( worldScale * lineWidth ); else scale = 1.0f; diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index bccf92d724..df3d977502 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -389,12 +389,8 @@ private: */ void skipMouseEvent( wxMouseEvent& aEvent ); - /** - * @brief Initialize the cursor. - * - * @param aCursorSize is the size of the cursor. - */ - void initCursor( int aCursorSize ); + /// @copydoc GAL::initCursor() + virtual void initCursor( int aCursorSize ); /// Allocate the bitmaps for drawing void allocateBitmaps(); diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index bb256f684a..0f51d607a3 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -785,6 +785,13 @@ protected: * @param aEndPoint is the end point of the line. */ virtual void DrawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) = 0; + + /** + * @brief Initialize the cursor. + * + * @param aCursorSize is the size of the cursor. + */ + virtual void initCursor( int aCursorSize ) = 0; }; } // namespace KiGfx diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index 48aaba6928..4fd7a7c375 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -422,12 +422,8 @@ private: /// Initialize GLEW. void initGlew(); - /** - * @brief Initialize the cursor. - * - * @param aCursorSize is the cursor size in pixels (screen coordinates). - */ - void initCursor( int aCursorSize ); + /// @copydoc GAL::initCursor() + virtual void initCursor( int aCursorSize ); /** * @brief Draw a quad for the line.