From 7c0fb33fd9ffb6474867ec4b2f2e9a71775ae1cd Mon Sep 17 00:00:00 2001 From: ouv Date: Tue, 24 Aug 2010 11:59:32 +0000 Subject: [PATCH] Grid improvement --- src/GLViewer/GLViewer_Grid.cxx | 326 +++++++++++++++++---------- src/GLViewer/GLViewer_Grid.h | 98 ++++---- src/GLViewer/GLViewer_ViewPort2d.cxx | 21 +- 3 files changed, 264 insertions(+), 181 deletions(-) diff --git a/src/GLViewer/GLViewer_Grid.cxx b/src/GLViewer/GLViewer_Grid.cxx index da470d855..56b894943 100644 --- a/src/GLViewer/GLViewer_Grid.cxx +++ b/src/GLViewer/GLViewer_Grid.cxx @@ -32,45 +32,33 @@ Default constructor */ GLViewer_Grid::GLViewer_Grid() : - myIsEnabled( GL_TRUE ), myGridList( 0 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ), - myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ), - myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ), - myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( 5 ), - myScaleFactor( 10 ), myIsUpdate( GL_FALSE ) + myIsEnabled( GL_TRUE ), + myGridList( 0 ), + myGridHeight( (GLfloat)0.0 ), + myGridWidth( (GLfloat)0.0 ), + myWinWidth( (GLfloat)0.0 ), + myWinHeight( (GLfloat)0.0 ), + myXSize( (GLfloat)0.0 ), + myYSize( (GLfloat)0.0 ), + myXPan( (GLfloat)0.0 ), + myYPan( (GLfloat)0.0 ), + myXScale( (GLfloat)1.0 ), + myYScale( (GLfloat)1.0 ), + myLineWidth( (GLfloat)0.05 ), + myLineType( Solid ), + myAxisLineWidth( (GLfloat)1.5 ), + myAxisLineType( Solid ), + myCenterRadius( 5 ), + myScaleFactor( (GLfloat)10.0 ), + myScaleRatio( (GLfloat)5.0 ), + myIsUpdate( GL_FALSE ) { - myGridColor[0] = 0.5; - myGridColor[1] = 0.5; - myGridColor[2] = 0.5; - myAxisColor[0] = 0.75; - myAxisColor[1] = 0.75; - myAxisColor[2] = 0.75; -} - -/*! - Constructor - \param width and \param height - width and height of grid - \param winW and \param winH - width and height of window - \param xSize and \param ySize - steps along x and y direction - \param xPan and \param yPan - offsets along x and y direction - \param xScale and \param yScal - scale factors along x and y direction -*/ -GLViewer_Grid::GLViewer_Grid( GLfloat width, GLfloat height, - GLfloat winW, GLfloat winH, - GLfloat xSize, GLfloat ySize, - GLfloat xPan, GLfloat yPan, - GLfloat xScale, GLfloat yScale ) : - myIsEnabled( GL_TRUE ), myGridList( 0 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ), - myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ), - myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ), - myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( 5 ), - myScaleFactor( 10 ), myIsUpdate( GL_FALSE ) -{ - myGridColor[0] = 0.5; - myGridColor[1] = 0.5; - myGridColor[2] = 0.5; - myAxisColor[0] = 0.75; - myAxisColor[1] = 0.75; - myAxisColor[2] = 0.75; + myLineColor[0] = 0.5; + myLineColor[1] = 0.5; + myLineColor[2] = 0.5; + myAxisLineColor[0] = 0.75; + myAxisLineColor[1] = 0.75; + myAxisLineColor[2] = 0.75; } /*! @@ -91,7 +79,18 @@ void GLViewer_Grid::draw() if ( myGridList == 0 || myIsUpdate ) initList(); + // disable smoothing (if enabled) + glPushAttrib( GL_ENABLE_BIT | GL_HINT_BIT ); + glDisable( GL_POINT_SMOOTH ); + glDisable( GL_LINE_SMOOTH ); + glDisable( GL_POLYGON_SMOOTH ); + glBlendFunc( GL_ONE, GL_ZERO ); + glDisable( GL_BLEND ); + glCallList( myGridList ); + + // restore previous state of smoothing + glPopAttrib(); } /*! @@ -100,36 +99,10 @@ void GLViewer_Grid::draw() */ void GLViewer_Grid::setEnabled( GLboolean state ) { - myIsEnabled = state; -} - -/*! - Changes color of grid - \param r, g, b - components of color -*/ -void GLViewer_Grid::setGridColor( GLfloat r, GLfloat g, GLfloat b ) -{ - if( myGridColor[0] == r && myGridColor[1] == g && myGridColor[2] == b ) + if( myIsEnabled == state ) return; - myGridColor[0] = r; - myGridColor[1] = g; - myGridColor[2] = b; - myIsUpdate = GL_TRUE; -} - -/*! - Changes color of axis - \param r, g, b - components of color -*/ -void GLViewer_Grid::setAxisColor( GLfloat r, GLfloat g, GLfloat b ) -{ - if( myAxisColor[0] == r && myAxisColor[1] == g && myAxisColor[2] == b ) - return; - - myAxisColor[0] = r; - myAxisColor[1] = g; - myAxisColor[2] = b; + myIsEnabled = state; myIsUpdate = GL_TRUE; } @@ -160,15 +133,21 @@ void GLViewer_Grid::setGridHeight( float h ) } /*! - Sets Radius of center point( begin coords ) - \param r - new radius + Sets parameters of grid by zoom coefficient and window size + \param w - window width + \param h - window height + \param zoom - zoom coefficient */ -void GLViewer_Grid::setCenterRadius( int r ) +void GLViewer_Grid::setResize( float w, float h, float zoom ) { - if( myCenterRadius == r ) + if( myWinWidth == w && myWinHeight == h && zoom == 1.0 ) return; - myCenterRadius = r; + myGridWidth = myGridWidth + ( w - myWinWidth ) * myXScale; + myGridHeight = myGridHeight + ( h - myWinHeight ) * myYScale; + myWinWidth = w; + myWinHeight = h; + setZoom( zoom ); myIsUpdate = GL_TRUE; } @@ -232,62 +211,105 @@ bool GLViewer_Grid::setZoom( float zoom ) } /*! - Sets parameters of grid by zoom coefficient and window size - \param WinW - window width - \param WinH - window height - \param zoom - zoom coefficient + Sets line width + \param value - new line width */ -void GLViewer_Grid::setResize( float WinW, float WinH, float zoom ) +void GLViewer_Grid::setLineWidth( float value ) { - if( myWinW == WinW && myWinH == WinH && zoom == 1.0 ) + if( myLineWidth == value ) return; - myGridWidth = myGridWidth + ( WinW - myWinW ) * myXScale; - myGridHeight = myGridHeight + ( WinH - myWinH ) * myYScale; - myWinW = WinW; - myWinH = WinH; - setZoom( zoom ); + myLineWidth = value; + myIsUpdate = GL_TRUE; +} + +/*! + Sets line type + \param type - new line type +*/ +void GLViewer_Grid::setLineType( LineType type ) +{ + if( myLineType == type ) + return; + + myLineType = type; + myIsUpdate = GL_TRUE; +} + +/*! + Changes color of grid + \param r, g, b - components of color +*/ +void GLViewer_Grid::setLineColor( GLfloat r, GLfloat g, GLfloat b ) +{ + if( myLineColor[0] == r && myLineColor[1] == g && myLineColor[2] == b ) + return; + + myLineColor[0] = r; + myLineColor[1] = g; + myLineColor[2] = b; myIsUpdate = GL_TRUE; } /*! - \return grid size along x and y axis - \param xSize - for size along x axis - \param ySize - for size along y axis + Sets axis line width + \param value - new axis line width */ -void GLViewer_Grid::getSize( float& xSize, float& ySize ) const +void GLViewer_Grid::setAxisLineWidth( float value ) { - xSize = myXSize; - ySize = myYSize; + if( myAxisLineWidth == value ) + return; + + myAxisLineWidth = value; + myIsUpdate = GL_TRUE; } /*! - \return panning along x and y axis - \param xPan - for panning along x axis - \param yPan - for panning along y axis + Sets axis line type + \param type - new axis line type */ -void GLViewer_Grid::getPan( float& xPan, float& yPan ) const +void GLViewer_Grid::setAxisLineType( LineType type ) { - xPan = myXPan; - yPan = myYPan; + if( myAxisLineType == type ) + return; + + myAxisLineType = type; + myIsUpdate = GL_TRUE; } /*! - \return scaling along x and y axis - \param xScale - for scaling along x axis - \param yScale - for scaling along y axis + Changes color of axis + \param r, g, b - components of color */ -void GLViewer_Grid::getScale( float& xScale, float& yScale ) const +void GLViewer_Grid::setAxisLineColor( GLfloat r, GLfloat g, GLfloat b ) { - xScale = myXScale; - yScale = myYScale; + if( myAxisLineColor[0] == r && myAxisLineColor[1] == g && myAxisLineColor[2] == b ) + return; + + myAxisLineColor[0] = r; + myAxisLineColor[1] = g; + myAxisLineColor[2] = b; + myIsUpdate = GL_TRUE; +} + +/*! + Sets Radius of center point( begin coords ) + \param r - new radius +*/ +void GLViewer_Grid::setCenterRadius( int r ) +{ + if( myCenterRadius == r ) + return; + + myCenterRadius = r; + myIsUpdate = GL_TRUE; } /*! Sets grid scale factor \param scaleFactor - scale factor */ -void GLViewer_Grid::setScaleFactor( int scaleFactor ) +void GLViewer_Grid::setScaleFactor( float scaleFactor ) { if( myScaleFactor == scaleFactor ) return; @@ -296,6 +318,34 @@ void GLViewer_Grid::setScaleFactor( int scaleFactor ) myIsUpdate = GL_TRUE; } +/*! + Sets grid scale ratio + \param scaleFactor - scale factor +*/ +void GLViewer_Grid::setScaleRatio( float scaleRatio ) +{ + if( myScaleRatio == scaleRatio ) + return; + + myScaleRatio = scaleRatio; + myIsUpdate = GL_TRUE; +} + +/*! + Gets dash pattern by line type + \param type - line type +*/ +GLushort GLViewer_Grid::getDashPattern( const LineType type ) +{ + switch( type ) + { + case LongDash: return 0xF0F0; + case ShortDash: return 0xCCCC; + case Dot: return 0x8888; + } + return 0; +} + /*! Initialize grid display list */ @@ -309,14 +359,15 @@ bool GLViewer_Grid::initList() myYSize = (GLfloat)0.1; label: - if( ( myXSize >= myGridWidth/5 ) && ( myYSize >= myGridHeight/5 ) ) + if( ( myXSize >= myGridWidth / myScaleRatio ) && + ( myYSize >= myGridHeight / myScaleRatio ) ) { //zoom in myXSize /= myScaleFactor; myYSize /= myScaleFactor; goto label; } - else if( ( myXSize * myScaleFactor < myGridWidth/5 ) - || ( myYSize * myScaleFactor < myGridHeight/5 ) ) + else if( ( myXSize * myScaleFactor < myGridWidth / myScaleRatio ) || + ( myYSize * myScaleFactor < myGridHeight / myScaleRatio ) ) { //zoom out myXSize *= myScaleFactor; myYSize *= myScaleFactor; @@ -331,47 +382,74 @@ label: { if ( myGridList != 0 ) { - glDeleteLists( myGridList, 1 ); - if ( glGetError() != GL_NO_ERROR ) - return FALSE; + glDeleteLists( myGridList, 1 ); + // temporarily commented (too cruel) + //if ( glGetError() != GL_NO_ERROR ) + // return FALSE; } - + float xLoc = (int)(myXPan / myXSize) * myXSize; float yLoc = (int)(myYPan / myYSize) * myYSize; myGridList = glGenLists( 1 ); glNewList( myGridList, GL_COMPILE ); - glColor3f( myGridColor[0], myGridColor[1], myGridColor[2] ); + glColor3f( myLineColor[0], myLineColor[1], myLineColor[2] ); glLineWidth( myLineWidth ); - + + GLushort aLineDashPattern = getDashPattern( myLineType ); + if( aLineDashPattern ) + { + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, aLineDashPattern ); + } + glBegin( GL_LINES ); - for( int j = 0; ( j-1 ) * myXSize <= myGridWidth / 2 ; j++ ) + for( int j = 0; ( j-1 ) * myXSize <= myGridWidth / 2; j++ ) { glVertex2d( -myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc ); - glVertex2d( -myXSize * j - xLoc, myGridHeight / 2 + myYSize - yLoc ); - glVertex2d( myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc ); - glVertex2d( myXSize * j - xLoc, myGridHeight / 2 + myYSize - yLoc ); + glVertex2d( -myXSize * j - xLoc, myGridHeight / 2 + myYSize - yLoc ); + if( j != 0 ) + { + glVertex2d( myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc ); + glVertex2d( myXSize * j - xLoc, myGridHeight / 2 + myYSize - yLoc ); + } } - for( int i = 0; ( i-1 ) * myYSize <= myGridHeight / 2 ; i++) + for( int i = 0; ( i-1 ) * myYSize <= myGridHeight / 2; i++ ) { - glVertex2d( -myGridWidth / 2 - myXSize - xLoc, -myYSize * i - yLoc ); - glVertex2d( myGridWidth / 2 + myXSize - xLoc, -myYSize * i - yLoc ); - glVertex2d( -myGridWidth / 2 - myXSize - xLoc, myYSize * i - yLoc ); - glVertex2d( myGridWidth / 2 + myXSize - xLoc, myYSize * i - yLoc ); - } + glVertex2d( -myGridWidth / 2 - myXSize - xLoc, -myYSize * i - yLoc ); + glVertex2d( myGridWidth / 2 + myXSize - xLoc, -myYSize * i - yLoc ); + if( i != 0 ) + { + glVertex2d( -myGridWidth / 2 - myXSize - xLoc, myYSize * i - yLoc ); + glVertex2d( myGridWidth / 2 + myXSize - xLoc, myYSize * i - yLoc ); + } + } glEnd(); - glColor3f( myAxisColor[0], myAxisColor[1], myAxisColor[2] ); - glLineWidth( myCenterWidth ); + if( aLineDashPattern ) + glDisable( GL_LINE_STIPPLE ); + + glColor3f( myAxisLineColor[0], myAxisLineColor[1], myAxisLineColor[2] ); + glLineWidth( myAxisLineWidth ); + + GLushort anAxisLineDashPattern = getDashPattern( myAxisLineType ); + if( anAxisLineDashPattern ) + { + glEnable( GL_LINE_STIPPLE ); + glLineStipple( 1, anAxisLineDashPattern ); + } glBegin( GL_LINES ); - glVertex2d( myGridWidth / 2 + myXSize - xLoc, 0); - glVertex2d( -myGridWidth / 2 - myXSize - xLoc, 0); + glVertex2d( myGridWidth / 2 + myXSize - xLoc, 0 ); + glVertex2d( -myGridWidth / 2 - myXSize - xLoc, 0 ); glVertex2d( 0, myGridHeight / 2 + myYSize - yLoc ); glVertex2d( 0, -myGridHeight / 2 - myYSize - yLoc ); glEnd(); + if( anAxisLineDashPattern ) + glDisable( GL_LINE_STIPPLE ); + if( myCenterRadius > 0 ) { glBegin( GL_LINE_LOOP ); diff --git a/src/GLViewer/GLViewer_Grid.h b/src/GLViewer/GLViewer_Grid.h index d6ae484e7..eaafa3518 100644 --- a/src/GLViewer/GLViewer_Grid.h +++ b/src/GLViewer/GLViewer_Grid.h @@ -42,25 +42,13 @@ 2D rectangular grid for GLViewer Grid is adapt cells for current view */ - class GLVIEWER_API GLViewer_Grid { public: - //! A default constructor + enum LineType { Solid = 0, LongDash, ShortDash, Dot }; + +public: GLViewer_Grid(); - //! A constructor - /* - * \param width and \param height - width and height of grid - * \param winW and \param winH - width and height of window - * \param xSize and \param ySize - steps along x and y direction - * \param xPan and \param yPan - offsets along x and y direction - * \param xScale and \param yScal - scale factors along x and y direction - */ - GLViewer_Grid( GLfloat width, GLfloat height, - GLfloat winW, GLfloat winH, - GLfloat xSize, GLfloat ySize, - GLfloat xPan, GLfloat yPan, - GLfloat xScale, GLfloat yScale ); ~GLViewer_Grid(); //! Draws grid @@ -72,58 +60,88 @@ public: //! Returns grid enable state GLboolean isEnabled() const { return myIsEnabled; } - //! Sets color of grid in RGB format - void setGridColor( GLfloat r, GLfloat g, GLfloat b ); - //! Sets color of grid axes in RGB format - void setAxisColor( GLfloat r, GLfloat g, GLfloat b ); //! Sets grid width void setGridWidth( float ); + //! Sets grid height void setGridHeight( float ); - //! Sets Radius of center point( begin coords ) - void setCenterRadius( int ); + + //! Recomputes grid in new size and scale of view + void setResize( float, float, float ); //! Sets steps along x and y directions - void setSize( float xs, float ys ); + void setSize( float, float ); + //! Sets offset along x and y direction - void setPan( float xp, float yp ); + void setPan( float, float ); + //! Sets common scale factor along x and y direction - bool setZoom( float zoom ); - //! Recomputes grid in new size and scale of view - void setResize( float winW, float winH, float Zoom ); + bool setZoom( float ); + + //! Sets line width + void setLineWidth( float ); + + //! Sets line type + void setLineType( LineType ); + + //! Sets line color in RGB format + void setLineColor( GLfloat, GLfloat, GLfloat ); + + //! Sets axis line width + void setAxisLineWidth( float ); + + //! Sets axis line type + void setAxisLineType( LineType ); - void getSize( float&, float& ) const; - void getPan( float&, float& ) const; - void getScale( float&, float& ) const; + //! Sets axis line color in RGB format + void setAxisLineColor( GLfloat, GLfloat, GLfloat ); - //! Sets step of scale - void setScaleFactor( int ); - int getScaleFactor() const { return myScaleFactor; } + //! Sets radius of center point + void setCenterRadius( int ); + + //! Sets grid scale factor + void setScaleFactor( float ); + + //! Sets grid scale ratio + void setScaleRatio( float ); protected: //! Initialize grid display list bool initList(); + //! Gets dash pattern by line type + static GLushort getDashPattern( const LineType ); + +protected: GLboolean myIsEnabled; GLuint myGridList; - GLfloat myGridColor[3]; - GLfloat myAxisColor[3]; - GLfloat myGridHeight; + GLboolean myIsUpdate; + GLfloat myGridWidth; - GLfloat myWinW; - GLfloat myWinH; + GLfloat myGridHeight; + GLfloat myWinWidth; + GLfloat myWinHeight; GLfloat myXSize; GLfloat myYSize; + GLfloat myXPan; GLfloat myYPan; GLfloat myXScale; GLfloat myYScale; + GLfloat myLineWidth; - GLfloat myCenterWidth; + LineType myLineType; + GLfloat myLineColor[3]; + + GLfloat myAxisLineWidth; + LineType myAxisLineType; + GLfloat myAxisLineColor[3]; + GLint myCenterRadius; - GLint myScaleFactor; - GLboolean myIsUpdate; + + GLfloat myScaleFactor; + GLfloat myScaleRatio; }; #ifdef WIN32 diff --git a/src/GLViewer/GLViewer_ViewPort2d.cxx b/src/GLViewer/GLViewer_ViewPort2d.cxx index 3b18e54b6..abb16232b 100644 --- a/src/GLViewer/GLViewer_ViewPort2d.cxx +++ b/src/GLViewer/GLViewer_ViewPort2d.cxx @@ -54,9 +54,6 @@ #define MARGIN 100 #define MARGIN_RATIO 0.2 -#define GRID_XSIZE 100 -#define GRID_YSIZE 100 - int static aLastViewPostId = 0; void rotate_point( float& theX, float& theY, float theAngle ) @@ -479,11 +476,7 @@ bool GLViewer_ViewPort2d::turnGrid( GLboolean on ) { if( !myGrid ) { - myGrid = new GLViewer_Grid( 2*WIDTH, 2*HEIGHT, - 2*WIDTH, 2*HEIGHT, - GRID_XSIZE, GRID_YSIZE, - myXPan, myYPan, - myXScale, myYScale ); + myGrid = new GLViewer_Grid(); aResult = true; } myGrid->setEnabled( GL_TRUE ); @@ -505,12 +498,8 @@ void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axi { if( myGrid ) { - myGrid->setGridColor( ( GLfloat )gridColor.red() / 255, - ( GLfloat )gridColor.green() / 255, - ( GLfloat )gridColor.blue() / 255 ); - myGrid->setAxisColor( ( GLfloat )axisColor.red() / 255, - ( GLfloat )axisColor.green() / 255, - ( GLfloat )axisColor.blue() / 255 ); + myGrid->setLineColor( gridColor.redF(), gridColor.greenF(), gridColor.blueF() ); + myGrid->setAxisLineColor( axisColor.redF(), axisColor.greenF(), axisColor.blueF() ); } } @@ -522,9 +511,7 @@ void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color ) { GLViewer_ViewPort::setBackgroundColor( color ); myGLWidget->makeCurrent(); - glClearColor( ( GLfloat )color.red() / 255, - ( GLfloat )color.green() / 255, - ( GLfloat )color.blue() / 255, 1.0 ); + glClearColor( color.redF(), color.greenF(), color.blueF(), 1.0 ); myGLWidget->repaint(); } -- 2.39.2