void GZ::Draw( ODDC& dc, PlugIn_ViewPort &piVP ) { if(m_dSecondDistance == 0) return; m_bSetTransparent = true; ODPath::Draw( dc, piVP ); m_bSetTransparent = false; SetActiveColours(); wxPoint l_l1p1; wxPoint l_l1p2; wxPoint l_l2p1; wxPoint l_l2p2; wxPoint l_pCentre; GetLatLonPoints( piVP, &l_pCentre, &l_l1p1, &l_l1p2, &l_l2p1, &l_l2p2 ); wxColour tCol; tCol.Set(m_fillcol.Red(), m_fillcol.Green(), m_fillcol.Blue(), m_uiFillTransparency); dc.SetPen( *wxThePenList->FindOrCreatePen( m_col, m_width, m_style ) ); dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( tCol, wxBRUSHSTYLE_CROSSDIAG_HATCH ) ); RenderArcSegment( dc, &l_pCentre, &l_l1p1, &l_l1p2, &l_l2p2, &l_l2p1, piVP, false ); }
void TextPoint::Draw( ODDC& dc, wxPoint *rpn ) { if( !m_bIsVisible ) return; if( m_iDisplayTextWhen == ID_TEXTPOINT_DISPLAY_TEXT_SHOW_ALWAYS || ( m_iDisplayTextWhen == ID_TEXTPOINT_DISPLAY_TEXT_SHOW_ON_ROLLOVER && m_bShowDisplayTextOnRollover) ) { if( m_TextPointText.Len() > 0 ) { CalculateTextExtents(); int teX, teY; int scalefactor = round(g_ocpn_draw_pi->m_chart_scale / m_natural_scale); if(m_natural_scale > (g_ocpn_draw_pi->m_chart_scale / 2) ) { teX = m_TextExtents.x; teY = m_TextExtents.y; } else { teX = m_TextExtents.x / scalefactor; teY = m_TextExtents.y / scalefactor; } if(teX > 0 && teY > 0 && scalefactor <= 8) { switch ( m_iTextPosition ) { case ID_TEXT_TOP: m_TextLocationOffsetX = g_iTextTopOffsetX; m_TextLocationOffsetY = g_iTextTopOffsetY - teY; break; case ID_TEXT_CENTRE_TOP: m_TextLocationOffsetX = g_iTextTopOffsetX - (teX / 2); m_TextLocationOffsetY = g_iTextTopOffsetY - teY; break; case ID_TEXT_BOTTOM: m_TextLocationOffsetX = g_iTextBottomOffsetX; m_TextLocationOffsetY = g_iTextBottomOffsetY; if(m_bShowName) m_TextLocationOffsetY += g_iTextBottomNameExtraOffsetY; break; case ID_TEXT_CENTRE_BOTTOM: m_TextLocationOffsetX = g_iTextBottomOffsetX - (teX / 2); m_TextLocationOffsetY = g_iTextBottomOffsetY; break; case ID_TEXT_CENTRE: m_TextLocationOffsetX = g_iTextCentreOffsetX - (teX / 2); m_TextLocationOffsetY = g_iTextCentreOffsetY - (teY / 2); break; case ID_TEXT_RIGHT: m_TextLocationOffsetX = g_iTextRightOffsetX; m_TextLocationOffsetY = g_iTextRightOffsetY; break; case ID_TEXT_LEFT: m_TextLocationOffsetX = g_iTextLeftOffsetX - teX; m_TextLocationOffsetY = g_iTextLeftOffsetY; break; } int sx2 = m_pbmIcon->GetWidth() / 2; int sy2 = m_pbmIcon->GetHeight() / 2; // Calculate the mark drawing extents wxPoint r; GetCanvasPixLL( g_pivp, &r, m_lat, m_lon); wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 ); // the bitmap extents if( m_DisplayTextFont.IsOk() ) { // Added to help with display of text (stops end clipping) teX += 20; wxRect r2( r.x + m_TextLocationOffsetX, r.y + m_TextLocationOffsetY, teX, teY ); r1.Union( r2 ); r.x = r.x + m_TextLocationOffsetX; r.y = r.y + m_TextLocationOffsetY; dc.SetFont( m_DisplayTextFont ); dc.SetTextForeground( m_colourTextColour ); g_ocpn_draw_pi->AlphaBlending( dc, r.x, r.y, r2.width, r2.height, 6.0, m_colourTextBackgroundColour, m_iBackgroundTransparency ); if(m_natural_scale > (g_ocpn_draw_pi->m_chart_scale / 2) ) dc.DrawText( m_TextPointText, r.x + 10, r.y ); else dc.DrawText( wxT(" "), r.x + 10, r.y ); } } } } ODPoint::Draw( dc, rpn ); }
void Boundary::Draw( ODDC& dc, PlugIn_ViewPort &piVP ) { //ODPath::Draw( dc, piVP ); if ( m_bVisible && m_pODPointList->GetCount() > 2) { int l_iBoundaryPointCount = 0; m_bpts = new wxPoint[ m_pODPointList->GetCount() ]; wxPoint r; for(wxODPointListNode *node = m_pODPointList->GetFirst(); node; node = node->GetNext()) { ODPoint *pOp = node->GetData(); GetCanvasPixLL( &piVP, &r, pOp->m_lat, pOp->m_lon ); m_bpts[ l_iBoundaryPointCount++ ] = r; } if( m_bExclusionBoundary && !m_bInclusionBoundary ) { // fill boundary with hatching wxGraphicsContext *wxGC = NULL; wxMemoryDC *pmdc = wxDynamicCast(dc.GetDC(), wxMemoryDC); if( pmdc ) wxGC = wxGraphicsContext::Create( *pmdc ); else { wxClientDC *pcdc = wxDynamicCast(dc.GetDC(), wxClientDC); if( pcdc ) wxGC = wxGraphicsContext::Create( *pcdc ); } wxGC->SetPen(*wxTRANSPARENT_PEN); wxColour tCol; tCol.Set(m_fillcol.Red(), m_fillcol.Green(), m_fillcol.Blue(), m_uiFillTransparency); wxGC->SetBrush( *wxTheBrushList->FindOrCreateBrush( tCol, wxBRUSHSTYLE_CROSSDIAG_HATCH ) ); wxGraphicsPath path = wxGC->CreatePath(); path.MoveToPoint(m_bpts[0].x, m_bpts[0].y); for( size_t i = 1; i < m_pODPointList->GetCount(); i++ ) { path.AddLineToPoint(m_bpts[i].x, m_bpts[i].y); } path.CloseSubpath(); wxGC->StrokePath(path); wxGC->FillPath( path ); delete wxGC; } else if( !m_bExclusionBoundary && m_bInclusionBoundary && m_pODPointList->GetCount() > 3 ) { // surround boundary with hatching if there is more than 10 pixels different between points int l_imaxpointdiffX = 0; int l_imaxpointdiffY = 0; for( size_t i = 1; i < m_pODPointList->GetCount(); i++ ) { int l_ipointdiffX = abs(m_bpts[0].x - m_bpts[i].x); int l_ipointdiffY = abs(m_bpts[0].y - m_bpts[i].y); if(l_ipointdiffX > l_imaxpointdiffX) l_imaxpointdiffX = l_ipointdiffX; if(l_ipointdiffY > l_imaxpointdiffY) l_imaxpointdiffY = l_ipointdiffY; } if(l_imaxpointdiffX < 10 && l_imaxpointdiffY < 10 ) return; // Use ClipperLib to manage Polygon // If needed simplify polygons to make shading stay outside Paths poly(1); for( size_t i = 0; i < m_pODPointList->GetCount(); i++ ) { poly[0] << IntPoint( m_bpts[i].x, m_bpts[i].y ); } Paths polys; SimplifyPolygons( poly, polys ); ClipperOffset co; Paths ExpandedBoundaries; co.AddPaths( polys, jtSquare, etClosedPolygon ); co.Execute( ExpandedBoundaries, m_iInclusionBoundarySize ); wxPoint *l_InclusionBoundary = new wxPoint[ ExpandedBoundaries[0].size() + 1 ]; for( size_t i = 0; i < ExpandedBoundaries[0].size(); i++ ) { l_InclusionBoundary[i].x = ExpandedBoundaries[0][i].X; l_InclusionBoundary[i].y = ExpandedBoundaries[0][i].Y; } // need to add first point to end to ensure the polygon is closed l_InclusionBoundary[ ExpandedBoundaries[0].size()].x = ExpandedBoundaries[0][0].X; l_InclusionBoundary[ ExpandedBoundaries[0].size()].y = ExpandedBoundaries[0][0].Y; int *l_iPolygonPointCount = new int[2]; l_iPolygonPointCount[0] = m_pODPointList->GetCount(); l_iPolygonPointCount[1] = ExpandedBoundaries[0].size() + 1; wxGraphicsContext *wxGC = NULL; wxMemoryDC *pmdc = wxDynamicCast(dc.GetDC(), wxMemoryDC); if( pmdc ) wxGC = wxGraphicsContext::Create( *pmdc ); else { wxClientDC *pcdc = wxDynamicCast(dc.GetDC(), wxClientDC); if( pcdc ) wxGC = wxGraphicsContext::Create( *pcdc ); } wxGC->SetPen(*wxTRANSPARENT_PEN); wxColour tCol; tCol.Set(m_fillcol.Red(), m_fillcol.Green(), m_fillcol.Blue(), m_uiFillTransparency); wxGC->SetBrush( *wxTheBrushList->FindOrCreateBrush( tCol, wxBRUSHSTYLE_CROSSDIAG_HATCH ) ); wxGraphicsPath path = wxGC->CreatePath(); path.MoveToPoint(m_bpts[0].x, m_bpts[0].y); for( int i = 0; i < l_iPolygonPointCount[0]; i++ ) { path.AddLineToPoint(m_bpts[i].x, m_bpts[i].y); } path.MoveToPoint(l_InclusionBoundary[0].x, l_InclusionBoundary[0].y); for( int i = 1; i < l_iPolygonPointCount[1]; i++ ) { path.AddLineToPoint(l_InclusionBoundary[i].x, l_InclusionBoundary[i].y); } path.CloseSubpath(); wxGC->StrokePath(path); wxGC->FillPath( path ); delete wxGC; ExpandedBoundaries.clear(); polys.clear(); poly.clear(); co.Clear(); } wxDELETEA( m_bpts ); } ODPath::Draw( dc, piVP ); }
void Boundary::DrawGL( PlugIn_ViewPort &piVP ) { #ifdef ocpnUSE_GL if ( !m_bVisible ) return; ODDC dc; if(m_pODPointList->GetCount() > 2 ) { if( m_bExclusionBoundary || m_bInclusionBoundary ) { wxPoint *l_AllPoints; int l_iAllPointsSizes[2]; wxPoint *l_InclusionBoundary; int l_iBoundaryPointCount = 0; m_bpts = new wxPoint[ m_pODPointList->GetCount() ]; wxPoint r; for(wxODPointListNode *node = m_pODPointList->GetFirst(); node; node = node->GetNext()) { ODPoint *pOp = node->GetData(); GetCanvasPixLL( &piVP, &r, pOp->m_lat, pOp->m_lon ); m_bpts[ l_iBoundaryPointCount++ ] = r; } if( !m_bExclusionBoundary && m_bInclusionBoundary ) { // surround boundary with hatching if there is more than 10 pixels different between points int l_imaxpointdiffX = 0; int l_imaxpointdiffY = 0; for( size_t i = 1; i < m_pODPointList->GetCount(); i++ ) { int l_ipointdiffX = abs(m_bpts[0].x - m_bpts[i].x); int l_ipointdiffY = abs(m_bpts[0].y - m_bpts[i].y); if(l_ipointdiffX > l_imaxpointdiffX) l_imaxpointdiffX = l_ipointdiffX; if(l_ipointdiffY > l_imaxpointdiffY) l_imaxpointdiffY = l_ipointdiffY; } if(l_imaxpointdiffX < 10 && l_imaxpointdiffY < 10 ) return; // Use ClipperLib to manage Polygon // If needed simplify polygons to make shading stay outside Paths poly(1); for( int i = 0; i < l_iBoundaryPointCount; i++ ) { poly[0] << IntPoint( m_bpts[i].x, m_bpts[i].y ); } Paths simplePolys; SimplifyPolygons( poly, simplePolys ); ClipperOffset co; Paths ExpandedBoundaries; co.AddPaths( simplePolys, jtSquare, etClosedPolygon ); co.Execute( ExpandedBoundaries, m_iInclusionBoundarySize ); int l_iInclusionBoundarySize = ExpandedBoundaries[0].size(); l_InclusionBoundary = new wxPoint[ l_iInclusionBoundarySize + 1 ]; for( int i = 0; i < l_iInclusionBoundarySize; i++ ) { l_InclusionBoundary[i].x = ExpandedBoundaries[0][i].X; l_InclusionBoundary[i].y = ExpandedBoundaries[0][i].Y; } // need to add first point to end to ensure the polygon is closed l_InclusionBoundary[ l_iInclusionBoundarySize ].x = ExpandedBoundaries[0][0].X; l_InclusionBoundary[ l_iInclusionBoundarySize ].y = ExpandedBoundaries[0][0].Y; // Create one array containing the original polygon joined to the expanded polygon to allow filling l_iAllPointsSizes[0] = l_iBoundaryPointCount; l_iAllPointsSizes[1] = l_iInclusionBoundarySize; l_AllPoints = new wxPoint[ l_iBoundaryPointCount + l_iInclusionBoundarySize + 1 ]; for( int i = 0; i < l_iBoundaryPointCount; i++ ) { l_AllPoints[i] = m_bpts[ i ]; } for( int i = 0; i < l_iInclusionBoundarySize; i++ ) { l_AllPoints[ i + l_iBoundaryPointCount ] = l_InclusionBoundary[i]; } ExpandedBoundaries.clear(); } // Each byte represents a single pixel for Alpha. This provides a cross hatch in a 16x16 pixel square GLubyte slope_cross_hatch[] = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }; GLuint textureID; glGenTextures(1, &textureID); glBindTexture( GL_TEXTURE_2D, textureID ); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, 16, 16, 0, GL_ALPHA, GL_UNSIGNED_BYTE, slope_cross_hatch ); dc.SetTextureSize( 16, 16 ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); wxColour tCol; tCol.Set(m_fillcol.Red(), m_fillcol.Green(), m_fillcol.Blue(), m_uiFillTransparency); dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( tCol, wxPENSTYLE_SOLID ) ); if( m_bExclusionBoundary ) { if(m_bIsBeingCreated) dc.DrawPolygonTessellated( m_pODPointList->GetCount(), m_bpts, 0, 0); else dc.DrawPolygonTessellated( m_pODPointList->GetCount() - 1, m_bpts, 0, 0); } else if( m_bInclusionBoundary ) { dc.DrawPolygonsTessellated( 2, l_iAllPointsSizes, l_AllPoints, 0, 0); } glDisable( GL_BLEND ); glDisable( GL_TEXTURE_2D ); glDeleteTextures(1, &textureID); wxDELETEA( m_bpts ); } } ODPath::DrawGL( piVP ); #endif }
void GZ::DrawGL( PlugIn_ViewPort &piVP ) { #ifdef ocpnUSE_GL if(m_dSecondDistance == 0) return; if ( !m_bVisible ) return; wxPoint l_l1p1; wxPoint l_l1p2; wxPoint l_l2p1; wxPoint l_l2p2; wxPoint l_pCentre; GetLatLonPoints( piVP, &l_pCentre, &l_l1p1, &l_l1p2, &l_l2p1, &l_l2p2 ); ODDC dc; m_bSetTransparent = true; ODPath::DrawGL( piVP ); m_bSetTransparent = false; int style = wxPENSTYLE_SOLID; int width = g_path_line_width; if( m_style != STYLE_UNDEFINED ) style = m_style; if( m_width != STYLE_UNDEFINED ) width = m_width; SetActiveColours(); // Each byte represents a single pixel for Alpha. This provides a cross hatch in a 16x16 pixel square GLubyte slope_cross_hatch[] = { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }; GLuint textureID; glGenTextures(1, &textureID); glBindTexture( GL_TEXTURE_2D, textureID ); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, 16, 16, 0, GL_ALPHA, GL_UNSIGNED_BYTE, slope_cross_hatch ); dc.SetTextureSize( 16, 16 ); glEnable( GL_TEXTURE_2D ); glEnable( GL_BLEND ); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); wxColour tCol; tCol.Set(m_fillcol.Red(), m_fillcol.Green(), m_fillcol.Blue(), m_uiFillTransparency); dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( tCol, wxPENSTYLE_SOLID ) ); RenderArcSegment( dc, &l_pCentre, &l_l1p1, &l_l1p2, &l_l2p2, &l_l2p1, piVP, false ); glDisable( GL_LINE_STIPPLE ); glDisable( GL_BLEND ); glDisable( GL_TEXTURE_2D ); glDeleteTextures(1, &textureID); dc.SetPen( *wxThePenList->FindOrCreatePen( m_col, width, style ) ); wxPoint *points; int numpoints = ArcSectorPoints( *&points, l_pCentre.x, l_pCentre.y, l_l1p1.x, l_l1p1.y, l_l1p2.x, l_l1p2.y, l_l2p2.x, l_l2p2.y, l_l2p1.x, l_l2p1.y, true); dc.DrawLines( numpoints, points ); #ifdef __WXOSX__ delete [] points; #else wxDELETE( points ); #endif #endif }
void ODPoint::DrawGL( PlugIn_ViewPort &pivp ) { if( !m_bIsVisible ) return; // Optimization, especially apparent on tracks in normal cases if( m_IconName == _T("empty") && !m_bShowName && !m_bPtIsSelected ) return; if(m_wpBBox.GetValid() && pivp.chart_scale == m_wpBBox_chart_scale && pivp.rotation == m_wpBBox_rotation) { } wxPoint r; wxRect hilitebox; unsigned char transparency = 150; GetCanvasPixLL( &g_VP, &r, m_lat, m_lon ); // Substitue icon? wxBitmap *pbm; if( ( m_bIsActive ) && ( m_IconName != _T("mob") ) ) pbm = g_pODPointMan->GetIconBitmap( _T ( "activepoint" ) ); else pbm = m_pbmIcon; int sx2 = pbm->GetWidth() / 2; int sy2 = pbm->GetHeight() / 2; // Calculate the mark drawing extents wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 ); // the bitmap extents float l_fIconScaleFactor = GetOCPNChartScaleFactor_Plugin(); wxRect r3 = r1; if( m_bShowName ) { if( !m_pMarkFont ) { m_pMarkFont = GetOCPNScaledFont_PlugIn( wxT( "Marks" ) ); m_FontColor = GetFontColour_PlugIn( wxS( "Marks" ) ); CalculateNameExtents(); } if( m_pMarkFont ) { wxRect r2( r.x + (m_NameLocationOffsetX * l_fIconScaleFactor), r.y + (m_NameLocationOffsetY * l_fIconScaleFactor), m_NameExtents.x, m_NameExtents.y ); r3.Union( r2 ); } } hilitebox = r3; hilitebox.x -= r.x; hilitebox.y -= r.y; float radius; if( IsTouchInterface_PlugIn() ){ hilitebox.Inflate( 20 ); radius = 20.0f; } else{ hilitebox.Inflate( 4 ); radius = 4.0f; } /* update bounding box */ if(!m_wpBBox.GetValid() || pivp.chart_scale != m_wpBBox_chart_scale || pivp.rotation != m_wpBBox_rotation) { double lat1, lon1, lat2, lon2; wxPoint wxpoint; wxpoint.x = r.x+hilitebox.x; wxpoint.y = r.y + hilitebox.height; GetCanvasLLPix( &pivp, wxpoint, &lat1, &lon1 ); wxpoint.x = r.x + hilitebox.x + hilitebox.width; wxpoint.y = r.y + hilitebox.y; GetCanvasLLPix( &pivp, wxpoint, &lat2, &lon2 ); if(lon1 > lon2) m_wpBBox.Set(lat1, lon1, lat2, lon2+360); else m_wpBBox.Set(lat1, lon1, lat2, lon2); m_wpBBox_chart_scale = pivp.chart_scale; m_wpBBox_rotation = pivp.rotation; } ODDC dc; // Highlite any selected point if( m_bPtIsSelected || m_bIsBeingEdited ) { wxColour hi_colour; if( m_bPointPropertiesBlink || m_bPathManagerBlink ){ wxPen *pen = g_pPathMan->GetActiveODPointPen(); hi_colour = pen->GetColour(); } else{ GetGlobalColor( wxS( "YELO1" ), &hi_colour ); } g_ocpn_draw_pi->AlphaBlending( dc, r.x + hilitebox.x, r.y + hilitebox.y, hilitebox.width, hilitebox.height, radius, hi_colour, transparency ); } bool bDrawHL = false; if( (m_bPointPropertiesBlink || m_bPathManagerBlink) && ( g_ocpn_draw_pi->nBlinkerTick & 1 ) ) bDrawHL = true; if( ( !bDrawHL ) && ( NULL != m_pbmIcon ) ) { int glw, glh; unsigned int IconTexture = g_pODPointMan->GetIconTexture( pbm, glw, glh ); glBindTexture(GL_TEXTURE_2D, IconTexture); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); glColor3f(1, 1, 1); float l_ChartScaleFactorExp = GetOCPNChartScaleFactor_Plugin(); float w = r1.width * l_ChartScaleFactorExp; float h = r1.height * l_ChartScaleFactorExp; float x = r.x - w/2; float y = r.y - h/2; float u = (float)r1.width/glw, v = (float)r1.height/glh; glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(x, y); glTexCoord2f(u, 0); glVertex2f(x+w, y); glTexCoord2f(u, v); glVertex2f(x+w, y+h); glTexCoord2f(0, v); glVertex2f(x, y+h); glEnd(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } if( m_bShowName && m_pMarkFont ) { int w = m_NameExtents.x, h = m_NameExtents.y; if(!m_iTextTexture && w && h) { wxBitmap tbm(w, h); /* render text on dc */ wxMemoryDC dc; dc.SelectObject( tbm ); dc.SetBackground( wxBrush( *wxBLACK ) ); dc.Clear(); dc.SetFont( *m_pMarkFont ); dc.SetTextForeground( *wxWHITE ); dc.DrawText( m_ODPointName, 0, 0); dc.SelectObject( wxNullBitmap ); /* make alpha texture for text */ wxImage image = tbm.ConvertToImage(); unsigned char *d = image.GetData(); unsigned char *e = new unsigned char[w * h]; if(d && e){ for( int p = 0; p < w*h; p++) e[p] = d[3*p + 0]; } /* create texture for rendered text */ glGenTextures(1, &m_iTextTexture); glBindTexture(GL_TEXTURE_2D, m_iTextTexture); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); m_iTextTextureWidth = NextPow2(w); m_iTextTextureHeight = NextPow2(h); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, m_iTextTextureWidth, m_iTextTextureHeight, 0, GL_ALPHA, GL_UNSIGNED_BYTE, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_ALPHA, GL_UNSIGNED_BYTE, e); delete [] e; } if(m_iTextTexture) { /* draw texture with text */ glBindTexture(GL_TEXTURE_2D, m_iTextTexture); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor3ub(m_FontColor.Red(), m_FontColor.Green(), m_FontColor.Blue()); int x = r.x + (m_NameLocationOffsetX * l_fIconScaleFactor), y = r.y + (m_NameLocationOffsetY * l_fIconScaleFactor); float u = (float)w/m_iTextTextureWidth, v = (float)h/m_iTextTextureHeight; glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex2f(x, y); glTexCoord2f(u, 0); glVertex2f(x+w, y); glTexCoord2f(u, v); glVertex2f(x+w, y+h); glTexCoord2f(0, v); glVertex2f(x, y+h); glEnd(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); } } // Draw ODPoint range rings if activated if( m_iODPointRangeRingsNumber && m_bShowODPointRangeRings ) { double factor = 1.00; if( m_iODPointRangeRingsStepUnits == 1 ) // nautical miles factor = 1 / 1.852; factor *= m_fODPointRangeRingsStep; double tlat, tlon; wxPoint r1; ll_gc_ll( m_lat, m_lon, 0, factor, &tlat, &tlon ); GetCanvasPixLL( &g_VP, &r1, tlat, tlon); double lpp = sqrt( pow( (double) (r.x - r1.x), 2) + pow( (double) (r.y - r1.y), 2 ) ); int pix_radius = (int) lpp; wxPen ppPen1( m_wxcODPointRangeRingsSchemeColour, m_iRangeRingWidth, m_iRangeRingStyle ); wxBrush saveBrush = dc.GetBrush(); wxPen savePen = dc.GetPen(); dc.SetPen( ppPen1 ); dc.SetBrush( wxBrush( m_wxcODPointRangeRingsSchemeColour, wxBRUSHSTYLE_TRANSPARENT ) ); dc.SetGLStipple(); for( int i = 1; i <= m_iODPointRangeRingsNumber; i++ ) dc.StrokeCircle( r.x, r.y, i * pix_radius ); glDisable( GL_LINE_STIPPLE ); dc.SetPen( savePen ); dc.SetBrush( saveBrush ); } if( m_bPointPropertiesBlink || m_bPathManagerBlink ) g_blink_rect = CurrentRect_in_DC; // also save for global blinker // This will be useful for fast icon redraws CurrentRect_in_DC.x = r.x + hilitebox.x; CurrentRect_in_DC.y = r.y + hilitebox.y; CurrentRect_in_DC.width = hilitebox.width; CurrentRect_in_DC.height = hilitebox.height; if( m_bPointPropertiesBlink || m_bPathManagerBlink ) g_blink_rect = CurrentRect_in_DC; // also save for global blinker }
void ODPoint::Draw( ODDC& dc, wxPoint *rpn ) { wxPoint r; wxRect hilitebox; GetCanvasPixLL( &g_VP, &r, m_lat, m_lon); // return the home point in this dc to allow "connect the dots" if( NULL != rpn ) *rpn = r; if( !m_bIsVisible /*&& !m_bIsInTrack*/) // pjotrc 2010.02.13, 2011.02.24 return; // Optimization, especially apparent on tracks in normal cases if( m_IconName == _T("empty") && !m_bShowName && !m_bPtIsSelected ) return; wxPen *pen; if( m_bPointPropertiesBlink || m_bPathManagerBlink ) pen = g_pPathMan->GetActiveODPointPen(); else pen = g_pPathMan->GetODPointPen(); // Substitue icon? wxBitmap *pbm; if( ( m_bIsActive ) && ( m_IconName != _T("mob") ) ) pbm = g_pODPointMan->GetIconBitmap( _T ( "activepoint" ) ); else pbm = m_pbmIcon; float l_ChartScaleFactorExp = GetOCPNChartScaleFactor_Plugin(); if(m_fIconScaleFactor != l_ChartScaleFactorExp) { m_fIconScaleFactor = l_ChartScaleFactorExp; if(m_fIconScaleFactor != 0) { wxImage scaled_image = pbm->ConvertToImage(); int new_width = pbm->GetWidth() * m_fIconScaleFactor; int new_height = pbm->GetHeight() * m_fIconScaleFactor; m_ScaledBMP = wxBitmap(scaled_image.Scale(new_width, new_height, wxIMAGE_QUALITY_HIGH)); } } if( m_fIconScaleFactor != 0 && m_ScaledBMP.IsOk() ) pbm = &m_ScaledBMP; int sx2 = pbm->GetWidth() / 2; int sy2 = pbm->GetHeight() / 2; // Calculate the mark drawing extents wxRect r1( r.x - sx2, r.y - sy2, sx2 * 2, sy2 * 2 ); // the bitmap extents if( m_bShowName ) { if( 0 == m_pMarkFont ) { m_pMarkFont = GetOCPNScaledFont_PlugIn( wxS("Marks") ); m_FontColor = GetFontColour_PlugIn( wxS( "Marks" ) ); CalculateNameExtents(); } if( m_pMarkFont ) { wxRect r2( r.x + (m_NameLocationOffsetX * m_fIconScaleFactor), r.y + (m_NameLocationOffsetY * m_fIconScaleFactor), m_NameExtents.x, m_NameExtents.y ); r1.Union( r2 ); } } hilitebox = r1; hilitebox.x -= r.x; hilitebox.y -= r.y; float radius; if( IsTouchInterface_PlugIn() ){ hilitebox.Inflate( 20 ); radius = 20.0f; } else{ hilitebox.Inflate( 4 ); radius = 4.0f; } wxColour hi_colour; hi_colour = pen->GetColour(); unsigned char transparency = 100; if( m_bIsBeingEdited ){ GetGlobalColor( wxS( "YELO1" ), &hi_colour ); transparency = 150; } // Highlite any selected point if( m_bPtIsSelected || m_bIsBeingEdited ) { g_ocpn_draw_pi->AlphaBlending( dc, r.x + hilitebox.x, r.y + hilitebox.y, hilitebox.width, hilitebox.height, radius, hi_colour, transparency ); } bool bDrawHL = false; if( (m_bPointPropertiesBlink || m_bPathManagerBlink) && ( g_ocpn_draw_pi->nBlinkerTick & 1 ) ) bDrawHL = true; if( ( !bDrawHL ) && ( NULL != m_pbmIcon ) ) { dc.DrawBitmap( *pbm, r.x - sx2, r.y - sy2, true ); // on MSW, the dc Bounding box is not updated on DrawBitmap() method. // Do it explicitely here for all platforms. dc.CalcBoundingBox( r.x - sx2, r.y - sy2 ); dc.CalcBoundingBox( r.x + sx2, r.y + sy2 ); } if( m_bShowName ) { if( m_pMarkFont ) { dc.SetFont( *m_pMarkFont ); dc.SetTextForeground( m_FontColor ); dc.DrawText( m_ODPointName, r.x + (m_NameLocationOffsetX * m_fIconScaleFactor), r.y + (m_NameLocationOffsetY * m_fIconScaleFactor) ); } } // Draw ODPoint range rings if activated if( m_iODPointRangeRingsNumber && m_bShowODPointRangeRings ) { double factor = 1.00; if( m_iODPointRangeRingsStepUnits == 1 ) // nautical miles factor = 1 / 1.852; factor *= m_fODPointRangeRingsStep; double tlat, tlon; wxPoint r1; ll_gc_ll( m_lat, m_lon, 0, factor, &tlat, &tlon ); GetCanvasPixLL( &g_VP, &r1, tlat, tlon); double lpp = sqrt( pow( (double) (r.x - r1.x), 2) + pow( (double) (r.y - r1.y), 2 ) ); int pix_radius = (int) lpp; wxBrush saveBrush = dc.GetBrush(); wxPen savePen = dc.GetPen(); dc.SetPen( wxPen( m_wxcODPointRangeRingsSchemeColour, m_iRangeRingWidth, m_iRangeRingStyle ) ); dc.SetBrush( wxBrush( m_wxcODPointRangeRingsSchemeColour, wxBRUSHSTYLE_TRANSPARENT ) ); for( int i = 1; i <= m_iODPointRangeRingsNumber; i++ ) dc.StrokeCircle( r.x, r.y, i * pix_radius ); dc.SetPen( savePen ); dc.SetBrush( saveBrush ); } // Save the current draw rectangle in the current DC // This will be useful for fast icon redraws CurrentRect_in_DC.x = r.x + hilitebox.x; CurrentRect_in_DC.y = r.y + hilitebox.y; CurrentRect_in_DC.width = hilitebox.width; CurrentRect_in_DC.height = hilitebox.height; if( m_bPointPropertiesBlink || m_bPathManagerBlink ) g_blink_rect = CurrentRect_in_DC; // also save for global blinker }