From 58ed0c8cce0b0e514572fda3a8546fb6b25fc465 Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Mon, 2 May 2016 16:15:24 +0200 Subject: [PATCH] Improved grid drawing routine (OpenGL). --- common/gal/opengl/opengl_compositor.cpp | 6 +- common/gal/opengl/opengl_gal.cpp | 125 ++++++++++++++++++----- include/gal/graphics_abstraction_layer.h | 2 +- include/gal/opengl/opengl_gal.h | 6 +- 4 files changed, 109 insertions(+), 30 deletions(-) diff --git a/common/gal/opengl/opengl_compositor.cpp b/common/gal/opengl/opengl_compositor.cpp index 19b61c4e3f..95f9aff2fd 100644 --- a/common/gal/opengl/opengl_compositor.cpp +++ b/common/gal/opengl/opengl_compositor.cpp @@ -68,9 +68,9 @@ void OPENGL_COMPOSITOR::Initialize() glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_depthBuffer ); checkGlError( "binding renderbuffer" ); - glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, m_width, m_height ); + glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8, m_width, m_height ); checkGlError( "creating renderbuffer storage" ); - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT, + glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER_EXT, m_depthBuffer ); checkGlError( "attaching renderbuffer" ); @@ -220,7 +220,7 @@ void OPENGL_COMPOSITOR::ClearBuffer() assert( m_initialized ); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); } diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 5122428d57..b19fb14bd2 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -802,6 +802,107 @@ void OPENGL_GAL::BitmapText( const wxString& aText, const VECTOR2D& aPosition, } +void OPENGL_GAL::DrawGrid() +{ + if( !gridVisibility ) + return; + + int gridScreenSizeDense = KiROUND( gridSize.x * worldScale ); + int gridScreenSizeCoarse = KiROUND( gridSize.x * static_cast( gridTick ) * worldScale ); + + // Check if the grid would not be too dense + if( std::max( gridScreenSizeDense, gridScreenSizeCoarse ) < gridDrawThreshold ) + return; + + SetTarget( TARGET_NONCACHED ); + compositor.SetBuffer( mainBuffer ); + + // Draw the grid + // For the drawing the start points, end points and increments have + // to be calculated in world coordinates + VECTOR2D worldStartPoint = screenWorldMatrix * VECTOR2D( 0.0, 0.0 ); + VECTOR2D worldEndPoint = screenWorldMatrix * VECTOR2D( screenSize ); + + // Compute grid variables + int gridStartX = KiROUND( worldStartPoint.x / gridSize.x ); + int gridEndX = KiROUND( worldEndPoint.x / gridSize.x ); + int gridStartY = KiROUND( worldStartPoint.y / gridSize.y ); + int gridEndY = KiROUND( worldEndPoint.y / gridSize.y ); + + assert( gridEndX >= gridStartX ); + assert( gridEndY >= gridStartY ); + + // Correct the index, else some lines are not correctly painted + gridStartX -= std::abs( gridOrigin.x / gridSize.x ) + 1; + gridStartY -= std::abs( gridOrigin.y / gridSize.y ) + 1; + gridEndX += std::abs( gridOrigin.x / gridSize.x ) + 1; + gridEndY += std::abs( gridOrigin.y / gridSize.y ) + 1; + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_TEXTURE_2D ); + + if( gridStyle == GRID_STYLE_DOTS ) + { + glEnable( GL_STENCIL_TEST ); + glStencilFunc( GL_ALWAYS, 1, 1 ); + glStencilOp( GL_KEEP, GL_KEEP, GL_INCR ); + glColor4d( 0.0, 0.0, 0.0, 0.0 ); + } + else + { + glColor4d( gridColor.r, gridColor.g, gridColor.b, 1.0 ); + } + + // Vertical lines + for( int j = gridStartY; j < gridEndY; j += 1 ) + { + if( j % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + glLineWidth( 2.0 ); + else + glLineWidth( 1.0 ); + + if( ( j % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) + || gridScreenSizeDense > gridDrawThreshold ) + { + glBegin( GL_LINES ); + glVertex2d( gridStartX * gridSize.x, j * gridSize.y + gridOrigin.y ); + glVertex2d( gridEndX * gridSize.x, j * gridSize.y + gridOrigin.y ); + glEnd(); + } + } + + if( gridStyle == GRID_STYLE_DOTS ) + { + glStencilFunc( GL_NOTEQUAL, 0, 1 ); + glColor4d( gridColor.r, gridColor.g, gridColor.b, 1.0 ); + } + + // Horizontal lines + for( int i = gridStartX; i < gridEndX; i += 1 ) + { + if( i % gridTick == 0 && gridScreenSizeDense > gridDrawThreshold ) + glLineWidth( 2.0 ); + else + glLineWidth( 1.0 ); + + if( ( i % gridTick == 0 && gridScreenSizeCoarse > gridDrawThreshold ) + || gridScreenSizeDense > gridDrawThreshold ) + { + glBegin( GL_LINES ); + glVertex2d( i * gridSize.x + gridOrigin.x, gridStartY * gridSize.y ); + glVertex2d( i * gridSize.x + gridOrigin.x, gridEndY * gridSize.y ); + glEnd(); + } + } + + if( gridStyle == GRID_STYLE_DOTS ) + glDisable( GL_STENCIL_TEST ); + + glEnable( GL_DEPTH_TEST ); + glEnable( GL_TEXTURE_2D ); +} + + void OPENGL_GAL::ResizeScreen( int aWidth, int aHeight ) { screenSize = VECTOR2I( aWidth, aHeight ); @@ -842,7 +943,7 @@ void OPENGL_GAL::ClearScreen( const COLOR4D& aColor ) // Clear screen compositor.SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING ); glClearColor( aColor.r, aColor.g, aColor.b, aColor.a ); - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); } @@ -1021,28 +1122,6 @@ void OPENGL_GAL::DrawCursor( const VECTOR2D& aCursorPosition ) } -void OPENGL_GAL::drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) -{ - compositor.SetBuffer( mainBuffer ); - - // 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 ) - glLineWidth( 1.0 ); - else - glLineWidth( 2.0 ); - - glColor4d( gridColor.r, gridColor.g, gridColor.b, gridColor.a ); - - glBegin( GL_LINES ); - glVertex3d( aStartPoint.x, aStartPoint.y, layerDepth ); - glVertex3d( aEndPoint.x, aEndPoint.y, layerDepth ); - glEnd(); - - // Restore the default color, so textures will be drawn properly - glColor4d( 1.0, 1.0, 1.0, 1.0 ); -} - - void OPENGL_GAL::drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) { /* Helper drawing: ____--- v3 ^ diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index 5246e116f3..ca7a0a43c8 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -837,7 +837,7 @@ public: } ///> @brief Draw the grid - void DrawGrid(); + virtual void DrawGrid(); /** * Function GetGridPoint() diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index be197acb82..ba0b97cd26 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -135,6 +135,9 @@ public: virtual void BitmapText( const wxString& aText, const VECTOR2D& aPosition, double aRotationAngle ); + /// @copydoc GAL::DrawGrid() + virtual void DrawGrid(); + // -------------- // Screen methods // -------------- @@ -258,9 +261,6 @@ public: std::deque< boost::shared_array >& intersectPoints; } TessParams; -protected: - virtual void drawGridLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); - private: /// Super class definition typedef GAL super;