void ocpnDC::DrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { if( dc ) dc->DrawEllipse( x, y, width, height ); else { double r1 = width / 2, r2 = height / 2; double cx = x + r1, cy = y + r2; glPushAttrib( GL_COLOR_BUFFER_BIT | GL_LINE_BIT | GL_HINT_BIT ); //Save state // Enable anti-aliased lines, at best quality glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); if( ConfigureBrush() ) { glBegin( GL_TRIANGLE_FAN ); glVertex2d( cx, cy ); for( double a = 0; a <= 2 * M_PI; a += 2 * M_PI / 20 ) glVertex2d( cx + r1 * sin( a ), cy + r2 * cos( a ) ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_STRIP ); for( double a = 0; a <= 2 * M_PI; a += 2 * M_PI / 200 ) glVertex2d( cx + r1 * sin( a ), cy + r2 * cos( a ) ); glEnd(); } glPopAttrib(); // restore state } }
void ocpnDC::DrawPolygon( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset ) { if( dc ) dc->DrawPolygon( n, points, xoffset, yoffset ); #ifdef ocpnUSE_GL else { glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT | GL_HINT_BIT | GL_POLYGON_BIT ); //Save state SetGLAttrs( true ); if( ConfigureBrush() ) { glBegin( GL_POLYGON ); for( int i = 0; i < n; i++ ) glVertex2i( points[i].x + xoffset, points[i].y + yoffset ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_LOOP ); for( int i = 0; i < n; i++ ) glVertex2i( points[i].x + xoffset, points[i].y + yoffset ); glEnd(); } glPopAttrib(); } #endif }
void ocpnDC::DrawRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h ) { if( dc ) dc->DrawRectangle( x, y, w, h ); #ifdef ocpnUSE_GL else { if( ConfigureBrush() ) { glBegin( GL_QUADS ); glVertex2i( x, y ); glVertex2i( x + w, y ); glVertex2i( x + w, y + h ); glVertex2i( x, y + h ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_LOOP ); glVertex2i( x, y ); glVertex2i( x + w, y ); glVertex2i( x + w, y + h ); glVertex2i( x, y + h ); glEnd(); } } #endif }
void ocpnDC::DrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h, wxCoord r ) { if( dc ) dc->DrawRoundedRectangle( x, y, w, h, r ); #ifdef ocpnUSE_GL else { r++; int steps = ceil(sqrt((float)r)); wxCoord x1 = x + r, x2 = x + w - r; wxCoord y1 = y + r, y2 = y + h - r; if( ConfigureBrush() ) { glBegin( GL_TRIANGLE_FAN ); drawrrhelper( x2, y1, r, 0, steps ); drawrrhelper( x1, y1, r, 1, steps ); drawrrhelper( x1, y2, r, 2, steps ); drawrrhelper( x2, y2, r, 3, steps ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_LOOP ); drawrrhelper( x2, y1, r, 0, steps ); drawrrhelper( x1, y1, r, 1, steps ); drawrrhelper( x1, y2, r, 2, steps ); drawrrhelper( x2, y2, r, 3, steps ); glEnd(); } } #endif }
void ocpnDC::DrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { if( dc ) dc->DrawEllipse( x, y, width, height ); #ifdef ocpnUSE_GL else { float r1 = width / 2, r2 = height / 2; float cx = x + r1, cy = y + r2; // Enable anti-aliased lines, at best quality glEnable( GL_BLEND ); /* formula for variable step count to produce smooth ellipse */ float steps = floorf(wxMax(sqrtf(sqrtf((float)(width*width + height*height))), 1) * M_PI); if( ConfigureBrush() ) { glBegin( GL_TRIANGLE_FAN ); glVertex2f( cx, cy ); for( float a = 0; a <= 2 * M_PI + M_PI/steps; a += 2 * M_PI / steps ) glVertex2f( cx + r1 * sinf( a ), cy + r2 * cosf( a ) ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_LOOP ); for( float a = 0; a < 2 * M_PI - M_PI/steps; a += 2 * M_PI / steps ) glVertex2f( cx + r1 * sinf( a ), cy + r2 * cosf( a ) ); glEnd(); } glDisable( GL_BLEND ); } #endif }
void ocpnDC::DrawPolygon( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, float scale ) { if( dc ) dc->DrawPolygon( n, points, xoffset, yoffset ); #ifdef ocpnUSE_GL else { #ifdef __WXQT__ SetGLAttrs( false ); // Some QT platforms (Android) have trouble with GL_BLEND / GL_LINE_SMOOTH #else SetGLAttrs( true ); #endif if( ConfigureBrush() ) { glBegin( GL_POLYGON ); for( int i = 0; i < n; i++ ) glVertex2f( (points[i].x * scale) + xoffset, (points[i].y * scale) + yoffset ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_LOOP ); for( int i = 0; i < n; i++ ) glVertex2f( (points[i].x * scale) + xoffset, (points[i].y * scale) + yoffset ); glEnd(); } SetGLAttrs( false ); } #endif }
void ODDC::DrawPolygonsTessellated( int n, int npoints[], wxPoint points[], wxCoord xoffset, wxCoord yoffset ) { if( dc ) { int prev = 0; for( int i = 0; i < n; i++ ) { dc->DrawPolygon( npoints[i], &points[i + prev], xoffset, yoffset ); prev += npoints[i]; } } #ifdef ocpnUSE_GL else { GLUtesselator *tobj = gluNewTess(); gluTessCallback( tobj, GLU_TESS_VERTEX, (_GLUfuncptr) &ODDCvertexCallback ); gluTessCallback( tobj, GLU_TESS_BEGIN, (_GLUfuncptr) &ODDCbeginCallback ); gluTessCallback( tobj, GLU_TESS_END, (_GLUfuncptr) &ODDCendCallback ); gluTessCallback( tobj, GLU_TESS_COMBINE, (_GLUfuncptr) &ODDCcombineCallback ); gluTessCallback( tobj, GLU_TESS_ERROR, (_GLUfuncptr) &ODDCerrorCallback ); gluTessNormal( tobj, 0, 0, 1); gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); gluTessProperty(tobj, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); if(glIsEnabled(GL_TEXTURE_2D)) g_bTexture2D = true; else g_bTexture2D = false; ConfigurePen(); if( ConfigureBrush() ) { gluTessBeginPolygon(tobj, NULL); int prev = 0; for( int j = 0; j < n; j++ ) { gluTessBeginContour(tobj); for( int i = 0; i < npoints[j]; i++ ) { GLvertex* vertex = new GLvertex(); gTesselatorVertices.Add( vertex ); vertex->info.x = (GLdouble) points[i + prev].x; vertex->info.y = (GLdouble) points[i + prev].y; vertex->info.z = (GLdouble) 0.0; vertex->info.r = (GLdouble) 0.0; vertex->info.g = (GLdouble) 0.0; vertex->info.b = (GLdouble) 0.0; vertex->info.a = (GLdouble) 0.0; gluTessVertex( tobj, (GLdouble*)vertex, (GLdouble*)vertex ); } gluTessEndContour( tobj ); prev += npoints[j]; } gluTessEndPolygon(tobj); } gluDeleteTess(tobj); for (unsigned int i = 0; i<gTesselatorVertices.Count(); i++) delete (GLvertex*)gTesselatorVertices.Item(i); gTesselatorVertices.Clear(); } #endif }
void ODDC::DrawPolygon( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, float scale ) { if( dc ) dc->DrawPolygon( n, points, xoffset, yoffset ); #ifdef ocpnUSE_GL else { SetGLAttrs( true ); if( ConfigureBrush() ) { glBegin( GL_POLYGON ); for( int i = 0; i < n; i++ ) glVertex2f( (points[i].x * scale) + xoffset, (points[i].y * scale) + yoffset ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_LOOP ); for( int i = 0; i < n; i++ ) glVertex2f( (points[i].x * scale) + xoffset, (points[i].y * scale) + yoffset ); glEnd(); } SetGLAttrs( false ); } #endif }
void ocpnDC::DrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, bool b_hiqual ) { if( dc ) dc->DrawLines( n, points, xoffset, yoffset ); #ifdef ocpnUSE_GL else if( ConfigurePen() ) { SetGLAttrs( b_hiqual ); bool b_draw_thick = false; glDisable( GL_LINE_STIPPLE ); SetGLStipple(); // Enable anti-aliased lines, at best quality if( b_hiqual ) { glEnable( GL_BLEND ); if( m_pen.GetWidth() > 1 ) { GLint parms[2]; glGetIntegerv( GL_SMOOTH_LINE_WIDTH_RANGE, &parms[0] ); if( m_pen.GetWidth() > parms[1] ) b_draw_thick = true; else glLineWidth( wxMax(g_GLMinSymbolLineWidth, m_pen.GetWidth()) ); } else glLineWidth( wxMax(g_GLMinSymbolLineWidth, 1) ); } else { if( m_pen.GetWidth() > 1 ) { GLint parms[2]; glGetIntegerv( GL_ALIASED_LINE_WIDTH_RANGE, &parms[0] ); if( m_pen.GetWidth() > parms[1] ) b_draw_thick = true; else glLineWidth( wxMax(g_GLMinSymbolLineWidth, m_pen.GetWidth()) ); } else glLineWidth( wxMax(g_GLMinSymbolLineWidth, 1) ); } if( b_draw_thick) { DrawGLThickLines( n, points, xoffset, yoffset, m_pen, b_hiqual ); } else { if( b_hiqual ) { glEnable( GL_LINE_SMOOTH ); ;// SetGLStipple(m_pen.GetStyle()); } glBegin( GL_LINE_STRIP ); for( int i = 0; i < n; i++ ) glVertex2i( points[i].x + xoffset, points[i].y + yoffset ); glEnd(); } if( b_hiqual ) { glDisable( GL_LINE_STIPPLE ); glDisable( GL_POLYGON_SMOOTH ); glDisable( GL_BLEND ); } } #endif }
void ocpnDC::DrawRoundedRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h, wxCoord r ) { if( dc ) dc->DrawRoundedRectangle( x, y, w, h, r ); else { wxCoord x0 = x, x1 = x + r, x2 = x + w - r, x3 = x + h; wxCoord y0 = y, y1 = y + r, y2 = y + h - r, y3 = y + h; if( ConfigureBrush() ) { glBegin( GL_QUADS ); glVertex2i( x0, y1 ); glVertex2i( x1, y1 ); glVertex2i( x1, y2 ); glVertex2i( x0, y2 ); glVertex2i( x1, y0 ); glVertex2i( x2, y0 ); glVertex2i( x2, y3 ); glVertex2i( x0, y3 ); glVertex2i( x2, y1 ); glVertex2i( x3, y1 ); glVertex2i( x3, y2 ); glVertex2i( x2, y2 ); glEnd(); glBegin( GL_TRIANGLE_FAN ); glVertex2i( x1, y2 ); drawrrhelper( x1, y2, r, -M_PI, -M_PI / 2 ); glEnd(); glBegin( GL_TRIANGLE_FAN ); glVertex2i( x2, y2 ); drawrrhelper( x2, y2, r, -M_PI / 2, 0 ); glEnd(); glBegin( GL_TRIANGLE_FAN ); glVertex2i( x2, y1 ); drawrrhelper( x2, y1, r, 0, M_PI / 2 ); glEnd(); glBegin( GL_TRIANGLE_FAN ); glVertex2i( x1, y1 ); drawrrhelper( x1, y1, r, M_PI / 2, M_PI ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_LOOP ); drawrrhelper( x1, y2, r, -M_PI, -M_PI / 2 ); drawrrhelper( x2, y2, r, -M_PI / 2, 0 ); drawrrhelper( x2, y1, r, 0, M_PI / 2 ); drawrrhelper( x1, y1, r, M_PI / 2, M_PI ); glEnd(); } } }
void ocpnDC::DrawLines( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, bool b_hiqual ) { if( dc ) dc->DrawLines( n, points, xoffset, yoffset ); else if( ConfigurePen() ) { glPushAttrib( GL_COLOR_BUFFER_BIT | GL_LINE_BIT | GL_HINT_BIT ); //Save state SetGLAttrs( b_hiqual ); bool b_draw_thick = false; SetGLStipple(); // Enable anti-aliased lines, at best quality if( b_hiqual ) { if( m_pen.GetWidth() > 1 ) { GLint parms[2]; glGetIntegerv( GL_SMOOTH_LINE_WIDTH_RANGE, &parms[0] ); if( m_pen.GetWidth() > parms[1] ) b_draw_thick = true; else glLineWidth( wxMax(g_GLMinLineWidth, m_pen.GetWidth()) ); } else glLineWidth( wxMax(g_GLMinLineWidth, 1) ); } else { if( m_pen.GetWidth() > 1 ) { GLint parms[2]; glGetIntegerv( GL_ALIASED_LINE_WIDTH_RANGE, &parms[0] ); if( m_pen.GetWidth() > parms[1] ) b_draw_thick = true; else glLineWidth( wxMax(g_GLMinLineWidth, m_pen.GetWidth()) ); } else glLineWidth( wxMax(g_GLMinLineWidth, 1) ); } if( b_draw_thick/*m_pen.GetWidth() > 1*/) { wxPoint p0 = points[0]; for( int i = 1; i < n; i++ ) { DrawThickLine( p0.x + xoffset, p0.y + yoffset, points[i].x + xoffset, points[i].y + yoffset, m_pen, b_hiqual ); p0 = points[i]; } } else { glBegin( GL_LINE_STRIP ); for( int i = 0; i < n; i++ ) glVertex2i( points[i].x + xoffset, points[i].y + yoffset ); glEnd(); } glPopAttrib(); // restore state } }
//------------------------------------------------------hitwh wht void ocpnDC::DrawEllipse( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) { if( dc ) dc->DrawEllipse( x, y, width, height ); #ifdef ocpnUSE_GL else { float r1 = width / 2, r2 = height / 2; float cx = x + r1, cy = y + r2; glPushAttrib( GL_COLOR_BUFFER_BIT | GL_LINE_BIT | GL_HINT_BIT ); //Save state // Enable anti-aliased lines, at best quality glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); /* formula for variable step count to produce smooth ellipse */ float steps = floorf(wxMax(sqrtf(sqrtf((float)(width*width + height*height))), 1) * M_PI); if( ConfigureBrush() ) { glBegin( GL_TRIANGLE_FAN ); glVertex2f( cx, cy ); for( float a = 0; a <= 2 * M_PI + M_PI/steps; a += 2 * M_PI / steps ) glVertex2f( cx + r1 * sinf( a ), cy + r2 * cosf( a ) ); glEnd(); } if( ConfigurePen() ) { glBegin( GL_LINE_LOOP ); for( float a = 0; a < 2 * M_PI - M_PI/steps; a += 2 * M_PI / steps ) glVertex2f( cx + r1 * sinf( a ), cy + r2 * cosf( a ) ); glEnd(); } glPopAttrib(); // restore state } #endif }
void ocpnDC::DrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, bool b_hiqual ) { if( dc ) dc->DrawLine( x1, y1, x2, y2 ); else { glPushAttrib( GL_COLOR_BUFFER_BIT | GL_LINE_BIT | GL_ENABLE_BIT | GL_HINT_BIT ); //Save state if( ConfigurePen() ) { glDisable( GL_MULTISAMPLE ); bool b_draw_thick = false; float pen_width = wxMax(g_GLMinLineWidth, m_pen.GetWidth()); // Enable anti-aliased lines, at best quality if( b_hiqual ) { SetGLStipple(); glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); if( pen_width > 1.0 ) { GLint parms[2]; glGetIntegerv( GL_SMOOTH_LINE_WIDTH_RANGE, &parms[0] ); if( pen_width > parms[1] ) b_draw_thick = true; else glLineWidth( pen_width ); } else glLineWidth( pen_width ); } else { glDisable( GL_LINE_SMOOTH ); glDisable( GL_BLEND ); if( pen_width > 1 ) { GLint parms[2]; glGetIntegerv( GL_ALIASED_LINE_WIDTH_RANGE, &parms[0] ); if( pen_width > parms[1] ) b_draw_thick = true; else glLineWidth( pen_width ); } else glLineWidth( pen_width ); } if( b_draw_thick ) DrawThickLine( x1, y1, x2, y2, m_pen, b_hiqual ); else { wxDash *dashes; int n_dashes = m_pen.GetDashes( &dashes ); if( n_dashes ) { double angle = atan2( (double) ( y2 - y1 ), (double) ( x2 - x1 ) ); double cosa = cos( angle ); double sina = sin( angle ); double t1 = m_pen.GetWidth(); double lpix = sqrt( (double) ( x1 - x2 ) * ( x1 - x2 ) + (double) ( y1 - y2 ) * ( y1 - y2 ) ); double lrun = 0.; double xa = x1; double ya = y1; double ldraw = t1 * dashes[0]; double lspace = t1 * dashes[1]; while( lrun < lpix ) { // Dash double xb = xa + ldraw * cosa; double yb = ya + ldraw * sina; if( ( lrun + ldraw ) >= lpix ) // last segment is partial draw { xb = x2; yb = y2; } glBegin( GL_LINES ); glVertex2f( xa, ya ); glVertex2f( xb, yb ); glEnd(); xa = xa + ( lspace + ldraw ) * cosa; ya = ya + ( lspace + ldraw ) * sina; lrun += lspace + ldraw; } } else // not dashed { glBegin( GL_LINES ); glVertex2i( x1, y1 ); glVertex2i( x2, y2 ); glEnd(); } } } glPopAttrib(); } }
void ocpnDC::DrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, bool b_hiqual ) { if( dc ) dc->DrawLine( x1, y1, x2, y2 ); #ifdef ocpnUSE_GL else if( ConfigurePen() ) { bool b_draw_thick = false; float pen_width = wxMax(g_GLMinSymbolLineWidth, m_pen.GetWidth()); // Enable anti-aliased lines, at best quality if( b_hiqual ) { SetGLStipple(); #ifndef __WXQT__ glEnable( GL_BLEND ); glEnable( GL_LINE_SMOOTH ); #endif if( pen_width > 1.0 ) { GLint parms[2]; glGetIntegerv( GL_SMOOTH_LINE_WIDTH_RANGE, &parms[0] ); if( pen_width > parms[1] ) b_draw_thick = true; else glLineWidth( pen_width ); } else glLineWidth( pen_width ); } else { if( pen_width > 1 ) { GLint parms[2]; glGetIntegerv( GL_ALIASED_LINE_WIDTH_RANGE, &parms[0] ); if( pen_width > parms[1] ) b_draw_thick = true; else glLineWidth( pen_width ); } else glLineWidth( pen_width ); } if( b_draw_thick ) DrawGLThickLine( x1, y1, x2, y2, m_pen, b_hiqual ); else { wxDash *dashes; int n_dashes = m_pen.GetDashes( &dashes ); if( n_dashes ) { float angle = atan2f( (float) ( y2 - y1 ), (float) ( x2 - x1 ) ); float cosa = cosf( angle ); float sina = sinf( angle ); float t1 = m_pen.GetWidth(); float lpix = sqrtf( powf(x1 - x2, 2) + powf(y1 - y2, 2) ); float lrun = 0.; float xa = x1; float ya = y1; float ldraw = t1 * dashes[0]; float lspace = t1 * dashes[1]; ldraw = wxMax(ldraw, 4.0); lspace = wxMax(lspace, 4.0); lpix = wxMin(lpix, 2000.0); glBegin( GL_LINES ); while( lrun < lpix ) { // Dash float xb = xa + ldraw * cosa; float yb = ya + ldraw * sina; if( ( lrun + ldraw ) >= lpix ) // last segment is partial draw { xb = x2; yb = y2; } glVertex2f( xa, ya ); glVertex2f( xb, yb ); xa = xa + ( lspace + ldraw ) * cosa; ya = ya + ( lspace + ldraw ) * sina; lrun += lspace + ldraw; } glEnd(); } else // not dashed { glBegin( GL_LINES ); glVertex2i( x1, y1 ); glVertex2i( x2, y2 ); glEnd(); } } glDisable( GL_LINE_STIPPLE ); if( b_hiqual ) { glDisable( GL_LINE_SMOOTH ); glDisable( GL_BLEND ); } } #endif }