Exemple #1
0
void Track::Draw( ocpnDC& dc, ViewPort &VP, const LLBBox &box )
{
    std::list< std::list<wxPoint> > pointlists;
    GetPointLists(pointlists, VP, box);

    if(!pointlists.size())
        return;

    unsigned short int FromSegNo = 1;

    //  Establish basic colour
    wxColour basic_colour;
    if( IsRunning() )
        basic_colour = GetGlobalColor( _T ( "URED" ) );
    else
        basic_colour = GetDimColor(g_colourTrackLineColour);

    wxPenStyle style = wxPENSTYLE_SOLID;
    int width = g_pRouteMan->GetTrackPen()->GetWidth();
    wxColour col;
    if( m_style != wxPENSTYLE_INVALID )
        style = m_style;
    if( m_width != WIDTH_UNDEFINED )
        width = m_width;
    if( m_Colour == wxEmptyString ) {
        col = basic_colour;
    } else {
        for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) {
            if( m_Colour == ::GpxxColorNames[i] ) {
                col = ::GpxxColors[i];
                break;
            }
        }
    }

    double radius = 0.;
    if( g_bHighliteTracks ) {
        double radius_meters = 20; //Current_Ch->GetNativeScale() * .0015;         // 1.5 mm at original scale
        radius = radius_meters * VP.view_scale_ppm;
        if(radius < 1.0)
            radius = 0;
    }

    if( dc.GetDC() || radius ) {
        dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) );
        dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxBRUSHSTYLE_SOLID ) );
        for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin();
        lines != pointlists.end(); lines++) {
            // convert from linked list to array
            wxPoint *points = new wxPoint[lines->size()];
            int i = 0;
            for(std::list<wxPoint>::iterator line = lines->begin();
                line != lines->end(); line++) {
                points[i] = *line;
                i++;
            }

            int hilite_width = radius;
            if( hilite_width ) {
                wxPen psave = dc.GetPen();

                dc.StrokeLines( i, points );

                wxColor trackLine_dim_colour = GetDimColor(g_colourTrackLineColour);
                wxColour hilt( trackLine_dim_colour.Red(), trackLine_dim_colour.Green(), trackLine_dim_colour.Blue(), 128 );

                wxPen HiPen( hilt, hilite_width, wxPENSTYLE_SOLID );
                dc.SetPen( HiPen );

                dc.StrokeLines( i, points );

                dc.SetPen( psave );
            } else
                dc.StrokeLines( i, points );

            delete [] points;
        }
    }
#ifdef ocpnUSE_GL    
    else { // opengl version
        glColor3ub(col.Red(), col.Green(), col.Blue());
        glLineWidth( wxMax( g_GLMinSymbolLineWidth, width ) );
        if( g_GLOptions.m_GLLineSmoothing )
            glEnable( GL_LINE_SMOOTH );
        glEnable( GL_BLEND );
        
        int size = 0;
        // convert from linked list to array, allocate array just once
        for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin();
            lines != pointlists.end(); lines++)
            size = wxMax(size, lines->size());
        int *points = new int[2*size];
        glVertexPointer(2, GL_INT, 0, points);

        glEnableClientState(GL_VERTEX_ARRAY);
        for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin();
            lines != pointlists.end(); lines++) {

            // convert from linked list to array
            int i = 0;
            for(std::list<wxPoint>::iterator line = lines->begin();
                line != lines->end(); line++) {
                points[i+0] = line->x;
                points[i+1] = line->y;
                i+=2;
            }

            glDrawArrays(GL_LINE_STRIP, 0, i >> 1);
        }
        glDisableClientState(GL_VERTEX_ARRAY);

        delete [] points;
        glDisable( GL_LINE_SMOOTH );
        glDisable( GL_BLEND );
        
    }
#endif

    if(m_HighlightedTrackPoint >= 0)
        TrackPoints[m_HighlightedTrackPoint]->Draw(dc);
}
Exemple #2
0
void RoutePoint::DrawGL( ViewPort &vp, ChartCanvas *canvas, bool use_cached_screen_coords )
{
//     if( !m_bIsVisible ) 
//         return;
//     if( !m_bIsActive)  //  An active route point must always be visible
//         if( !IsScaVisible( canvas) )          
//             return;  ;
    if ( !IsVisibleSelectable(canvas) ) return;
    
    //    Optimization, especially apparent on tracks in normal cases
    if( m_IconName == _T("empty") && !m_bShowName && !m_bPtIsSelected ) return;

    if(m_wpBBox.GetValid() &&
       vp.view_scale_ppm == m_wpBBox_view_scale_ppm &&
       vp.rotation == m_wpBBox_rotation) {
        /* see if this waypoint can intersect with bounding box */
        LLBBox vpBBox = vp.GetBBox();
        if( vpBBox.IntersectOut( m_wpBBox ) ){
            
            // Are Range Rings enabled?
            if(m_bShowWaypointRangeRings && (m_iWaypointRangeRingsNumber > 0)){
                double factor = 1.00;
                if( m_iWaypointRangeRingsStepUnits == 1 )          // convert kilometers to NMi
                    factor = 1 / 1.852;
            
                double radius = factor * m_iWaypointRangeRingsNumber * m_fWaypointRangeRingsStep  / 60.;

                LLBBox radar_box = m_wpBBox;
                radar_box.EnLarge(radius * 2 );
                if( vpBBox.IntersectOut( radar_box ) ){
                    return;
                }
            }
            else
                return;
        }
    }

    wxPoint r;
    wxRect hilitebox;
    unsigned char transparency = 150;
    
    if(use_cached_screen_coords && m_pos_on_screen)
        r.x = m_screen_pos.m_x, r.y = m_screen_pos.m_y;
    else
        canvas->GetCanvasPointPix( m_lat, m_lon, &r );

    if(r.x == INVALID_COORD)
        return;

//    Substitute icon?
    wxBitmap *pbm;
    if( ( m_bIsActive ) && ( m_IconName != _T("mob") ) )
        pbm = pWayPointMan->GetIconBitmap(  _T ( "activepoint" ) );
    else
        pbm = m_pbmIcon;

    //  If icon is corrupt, there is really nothing else to do...
    if(!pbm->IsOk())
        return;
    
    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

    wxRect r3 = r1;
    if( m_bShowName ) {
        if( !m_pMarkFont ) {
            m_pMarkFont = FontMgr::Get().GetFont( _( "Marks" ) );
            m_FontColor = FontMgr::Get().GetFontColor( _( "Marks" ) );
            CalculateNameExtents();
        }

        if( m_pMarkFont ) {
            wxRect r2( r.x + m_NameLocationOffsetX, r.y + m_NameLocationOffsetY,
                       m_NameExtents.x, m_NameExtents.y );
            r3.Union( r2 );
        }
    }

    hilitebox = r3;
    hilitebox.x -= r.x;
    hilitebox.y -= r.y;
    
    if(!m_bPreScaled){
        hilitebox.x *= g_ChartScaleFactorExp;
        hilitebox.y *= g_ChartScaleFactorExp;
        hilitebox.width  *= g_ChartScaleFactorExp;
        hilitebox.height *= g_ChartScaleFactorExp;
    }
    
    float radius;
    if( g_btouch ){
        hilitebox.Inflate( 20 );
        radius = 20.0f;
    }
    else{
        hilitebox.Inflate( 4 );
        radius = 4.0f;
    }
    
    /* update bounding box */
    if(!m_wpBBox.GetValid() || vp.view_scale_ppm != m_wpBBox_view_scale_ppm || vp.rotation != m_wpBBox_rotation) {
        double lat1, lon1, lat2, lon2;
        canvas->GetCanvasPixPoint(r.x+hilitebox.x, r.y+hilitebox.y+hilitebox.height, lat1, lon1);
        canvas->GetCanvasPixPoint(r.x+hilitebox.x+hilitebox.width, r.y+hilitebox.y, lat2, lon2);

        if(lon1 > lon2)
            m_wpBBox.Set(lat1, lon1, lat2, lon2+360);
        else
            m_wpBBox.Set(lat1, lon1, lat2, lon2);

        m_wpBBox_view_scale_ppm = vp.view_scale_ppm;
        m_wpBBox_rotation = vp.rotation;
    }

//    if(region.Contains(r3) == wxOutRegion)
//        return;
    

    ocpnDC dc;

    //  Highlite any selected point
    if( m_bPtIsSelected ) {
        wxColour hi_colour;
        if( m_bBlink ){
            wxPen *pen = g_pRouteMan->GetActiveRoutePointPen();
            hi_colour = pen->GetColour();
        }
        else{
            hi_colour = GetGlobalColor( _T ( "YELO1" ) );
        }
        
        AlphaBlending( dc, r.x + hilitebox.x, r.y + hilitebox.y, hilitebox.width, hilitebox.height, radius,
                       hi_colour, transparency );
    }
    
    bool bDrawHL = false;

    if( m_bBlink && ( gFrame->nBlinkerTick & 1 ) ) bDrawHL = true;

    if( ( !bDrawHL ) && ( NULL != m_pbmIcon ) ) {
        int glw, glh;
        unsigned int IconTexture = pWayPointMan->GetIconTexture( pbm, glw, glh );
        
        glBindTexture(GL_TEXTURE_2D, IconTexture);
        
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
        
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        
        glColor3f(1, 1, 1);
        
        int x = r1.x, y = r1.y, w = r1.width, h = r1.height;
        
        float scale = 1.0;
        if(!m_bPreScaled){
            scale =  g_ChartScaleFactorExp;
        }
            
        float ws = r1.width * scale;
        float hs = r1.height * scale;
        float xs = r.x - ws/2.;
        float ys = r.y - hs/2.;
        float u = (float)w/glw, v = (float)h/glh;
        
        glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex2f(xs, ys);
        glTexCoord2f(u, 0); glVertex2f(xs+ws, ys);
        glTexCoord2f(u, v); glVertex2f(xs+ws, ys+hs);
        glTexCoord2f(0, v); glVertex2f(xs, ys+hs);
        glEnd();
        
//         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_MarkName, 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);
        
            glColor3ub(m_FontColor.Red(), m_FontColor.Green(), m_FontColor.Blue());
            
            int x = r.x + m_NameLocationOffsetX, y = r.y + m_NameLocationOffsetY;
            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 waypoint radar rings if activated
    if( m_iWaypointRangeRingsNumber && m_bShowWaypointRangeRings ) {
        double factor = 1.00;
        if( m_iWaypointRangeRingsStepUnits == 1 )          // nautical miles
            factor = 1 / 1.852;
        
        factor *= m_fWaypointRangeRingsStep;
        
        double tlat, tlon;
        wxPoint r1;
        ll_gc_ll( m_lat, m_lon, 0, factor, &tlat, &tlon );
        canvas->GetCanvasPointPix( tlat, tlon, &r1 );
        
        double lpp = sqrt( pow( (double) (r.x - r1.x), 2) +
        pow( (double) (r.y - r1.y), 2 ) );
        int pix_radius = (int) lpp;

        extern wxColor GetDimColor(wxColor c);
        wxColor ring_dim_color = GetDimColor(m_wxcWaypointRangeRingsColour);
        
        double platform_pen_width = wxRound(wxMax(1.0, g_Platform->GetDisplayDPmm() / 2));             // 0.5 mm nominal, but not less than 1 pixel
        wxPen ppPen1( ring_dim_color, platform_pen_width );
        wxBrush saveBrush = dc.GetBrush();
        wxPen savePen = dc.GetPen();
        dc.SetPen( ppPen1 );
        dc.SetBrush( wxBrush( ring_dim_color, wxBRUSHSTYLE_TRANSPARENT ) );
        
        for( int i = 1; i <= m_iWaypointRangeRingsNumber; i++ )
            dc.StrokeCircle( r.x, r.y, i * pix_radius );
        dc.SetPen( savePen );
        dc.SetBrush( saveBrush );
    }
    
    // Render Drag handle if enabled
    if(m_bDrawDragHandle){
        
        //  A line, southeast, scaled to the size of the icon
        double platform_pen_width = wxRound(wxMax(1.0, g_Platform->GetDisplayDPmm() / 2));             // 0.5 mm nominal, but not less than 1 pixel
        
        wxColor dh_color = wxColor(0,0,0);
        wxPen ppPen1( dh_color, 3 * platform_pen_width );
        dc.SetPen( ppPen1 );
        dc.DrawLine(r.x + hilitebox.width/4, r.y + hilitebox.height/4, r.x + m_drag_line_length_man, r.y + m_drag_line_length_man);
 
        dh_color = GetGlobalColor( _T ( "YELO1" ) );
        wxPen ppPen2( dh_color, platform_pen_width );
        dc.SetPen( ppPen2 );
        dc.DrawLine(r.x + hilitebox.width/4, r.y + hilitebox.height/4, r.x + m_drag_line_length_man, r.y + m_drag_line_length_man);
        
        // The drag handle
        glBindTexture(GL_TEXTURE_2D, m_dragIconTexture);
        
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
        
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        
        glColor3f(1, 1, 1);
        
        int x = r.x + m_drag_icon_offset, y = r.y + m_drag_icon_offset, w = m_dragIcon.GetWidth(), h = m_dragIcon.GetHeight();
        
        float scale =  1.0;
            
        float ws = w * scale;
        float hs = h * scale;
        float xs = x - ws/2.;
        float ys = y - hs/2.;
        float u = (float)w/m_dragIconTextureWidth, v = (float)h/m_dragIconTextureWidth;
        
        glBegin(GL_QUADS);
        glTexCoord2f(0, 0); glVertex2f(xs, ys);
        glTexCoord2f(u, 0); glVertex2f(xs+ws, ys);
        glTexCoord2f(u, v); glVertex2f(xs+ws, ys+hs);
        glTexCoord2f(0, v); glVertex2f(xs, ys+hs);
        glEnd();
        
        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);

    }
 
 
    if( m_bBlink ) 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_bBlink ) g_blink_rect = CurrentRect_in_DC;               // also save for global blinker
}