예제 #1
0
PlugIn_ViewPort CreatePlugInViewport( const ViewPort &vp)
{
      //    Create a PlugIn Viewport
      ViewPort tvp = vp;
      PlugIn_ViewPort pivp;

      pivp.clat =                   tvp.clat;                   // center point
      pivp.clon =                   tvp.clon;
      pivp.view_scale_ppm =         tvp.view_scale_ppm;
      pivp.skew =                   tvp.skew;
      pivp.rotation =               tvp.rotation;
      pivp.chart_scale =            tvp.chart_scale;
      pivp.pix_width =              tvp.pix_width;
      pivp.pix_height =             tvp.pix_height;
      pivp.rv_rect =                tvp.rv_rect;
      pivp.b_quilt =                tvp.b_quilt;
      pivp.m_projection_type =      tvp.m_projection_type;

      pivp.lat_min =                tvp.GetBBox().GetMinY();
      pivp.lat_max =                tvp.GetBBox().GetMaxY();
      pivp.lon_min =                tvp.GetBBox().GetMinX();
      pivp.lon_max =                tvp.GetBBox().GetMaxX();

      pivp.bValid =                 tvp.IsValid();                 // This VP is valid

      return pivp;
}
예제 #2
0
void AppDelegate::initializeViewPort(CCSize viewSize, float scaleFactor)
{
    // Divide by the scale factor so that the view port remains the same for retina devices (converts to points)
    viewSize.width /= scaleFactor;
    viewSize.height /= scaleFactor;
    
    ViewPort* viewPort = ViewPort::getInstance();
    viewPort->initialize(viewSize);
}
예제 #3
0
void Frustum::init(Window * p, Camera * c)
{
	ViewPort vp = p->getViewPort(ViewPortMain);
	vp.getFrustum(nearp,farp,angle);
	this->camera = c;

	float tang = float(tan(M_PI * angle / 360.f));
	float ratio = float(p->width) / p->height;
	nh = nearp * tang;
	nw = nh * ratio; 
	fh = farp  * tang;
	fw = fh * ratio;
}
예제 #4
0
void ParallaxBackground::update(const ViewPort& viewPort) {
    for (auto& l : layers_) {
        auto& vpp = viewPort.getPosition();
        l.sprite->setPosition(Vector2Glf(vpp(0) + (l.offset(0)-vpp(0))*l.parallaxRatio,
                                         vpp(1) + (l.offset(1)-vpp(1))*l.parallaxRatio));
    }
}
예제 #5
0
void Route::DrawGL( ViewPort &vp )
{
#ifdef ocpnUSE_GL
    if( pRoutePointList->empty() || !m_bVisible ) return;

    if(!vp.GetBBox().IntersectOut(GetBBox()))
        DrawGLRouteLines(vp);

    /*  Route points  */
    for(wxRoutePointListNode *node = pRoutePointList->GetFirst(); node; node = node->GetNext()) {
        RoutePoint *prp = node->GetData();
        if ( !m_bVisible && prp->m_bKeepXRoute )
            prp->DrawGL( vp );
        else if (m_bVisible)
            prp->DrawGL( vp );
    }
#endif
}
예제 #6
0
	//! update viewports sizes
	void ShootEditor::UpdateViewPortsSizes()
	{
		if(EditorSettings::Instance()->WindowSize == EditorSettings::WS_Stretch)
		{
			ViewPort* pViewPort = GetViewPort();
			pViewPort->SetPosition(wxPoint(0, 0));
			pViewPort->SetSize(GetTabContainer()->GetViewPortContainer()->GetSize());					
		}
		else
		{
			Size size = EditorSettings::WindowSizes[EditorSettings::Instance()->WindowSize];
			ViewPort* pViewPort = GetViewPort();
			wxSize viewPortSize = pViewPort->GetSize();
			wxPoint center = wxPoint((viewPortSize.x - size.Width)/2, (viewPortSize.y - size.Height)/2);
			pViewPort->SetPosition(center);
			pViewPort->SetSize(wxSize(size.Width, size.Height));			
		}
	}
예제 #7
0
void RoutePoint::DrawGL( ViewPort &vp, bool use_cached_screen_coords )
{
    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() &&
       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;
    double platform_pen_width = wxRound(wxMax(1.0, g_Platform->GetDisplayDPmm() / 2));             // 0.5 mm nominal, but not less than 1 pixel
    
    if(use_cached_screen_coords && m_pos_on_screen)
        r.x = m_screen_pos.m_x, r.y = m_screen_pos.m_y;
    else
        cc1->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;
    
    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;
        cc1->GetCanvasPixPoint(r.x+hilitebox.x, r.y+hilitebox.y+hilitebox.height, lat1, lon1);
        cc1->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(g_bresponsive){
            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 );
        cc1->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;
        
        wxPen ppPen1( m_wxcWaypointRangeRingsColour, platform_pen_width );
        wxBrush saveBrush = dc.GetBrush();
        wxPen savePen = dc.GetPen();
        dc.SetPen( ppPen1 );
        dc.SetBrush( wxBrush( m_wxcWaypointRangeRingsColour, 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 );
    }
    
    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
}
예제 #8
0
파일: Route.cpp 프로젝트: kheyse/OpenCPN
void Route::Draw( ocpnDC& dc, ViewPort &VP )
{
    if( m_nPoints == 0 ) return;

    if( m_bVisible && m_bRtIsSelected ) {
        dc.SetPen( *g_pRouteMan->GetSelectedRoutePen() );
        dc.SetBrush( *g_pRouteMan->GetSelectedRouteBrush() );
    }
    else if ( m_bVisible )
    {
        int style = wxSOLID;
        int width = g_route_line_width;
        wxColour col;
        if( m_style != STYLE_UNDEFINED ) style = m_style;
        if( m_width != STYLE_UNDEFINED ) width = m_width;
        if( m_Colour == wxEmptyString ) {
            col = g_pRouteMan->GetRoutePen()->GetColour();
        } else {
            for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) {
                if( m_Colour == ::GpxxColorNames[i] ) {
                    col = ::GpxxColors[i];
                    break;
                }
            }
        }
        dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) );
        dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxSOLID ) );
    }

    if( m_bVisible && m_bRtIsActive )
    {
        dc.SetPen( *g_pRouteMan->GetActiveRoutePen() );
        dc.SetBrush( *g_pRouteMan->GetActiveRouteBrush() );
    }

    wxPoint rpt1, rpt2;
    if ( m_bVisible )
        DrawPointWhich( dc, 1, &rpt1 );

    wxRoutePointListNode *node = pRoutePointList->GetFirst();
    RoutePoint *prp1 = node->GetData();
    node = node->GetNext();

    if ( !m_bVisible && prp1->m_bKeepXRoute )
            prp1->Draw( dc );

    while( node ) {

        RoutePoint *prp2 = node->GetData();
        if ( !m_bVisible && prp2->m_bKeepXRoute )
            prp2->Draw( dc );
        else if (m_bVisible)
            prp2->Draw( dc, &rpt2 );

        if ( m_bVisible )
        {
            //    Handle offscreen points
            bool b_2_on = VP.GetBBox().PointInBox( prp2->m_lon, prp2->m_lat, 0 );
            bool b_1_on = VP.GetBBox().PointInBox( prp1->m_lon, prp1->m_lat, 0 );

            //TODO This logic could be simpliifed
            //Simple case
            if( b_1_on && b_2_on ) RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x, rpt2.y, VP, true ); // with arrows

            //    In the cases where one point is on, and one off
            //    we must decide which way to go in longitude
            //     Arbitrarily, we will go the shortest way

            double pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI
                * VP.view_scale_ppm;
            double dp = pow( (double) ( rpt1.x - rpt2.x ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 );
            double dtest;
            int adder;
            if( b_1_on && !b_2_on ) {
                if( rpt2.x < rpt1.x ) adder = (int) pix_full_circle;
                else
                    adder = -(int) pix_full_circle;

                dtest = pow( (double) ( rpt1.x - ( rpt2.x + adder ) ), 2 )
                    + pow( (double) ( rpt1.y - rpt2.y ), 2 );

                if( dp < dtest ) adder = 0;

                RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x + adder, rpt2.y, VP, true );
            } else
                if( !b_1_on && b_2_on ) {
                    if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle;
                    else
                        adder = -(int) pix_full_circle;

                    dtest = pow( (double) ( rpt2.x - ( rpt1.x + adder ) ), 2 )
                        + pow( (double) ( rpt1.y - rpt2.y ), 2 );

                    if( dp < dtest ) adder = 0;

                    RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, VP, true );
                }

                //Both off, need to check shortest distance
                else
                    if( !b_1_on && !b_2_on ) {
                        if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle;
                        else
                            adder = -(int) pix_full_circle;

                        dtest = pow( (double) ( rpt2.x - ( rpt1.x + adder ) ), 2 )
                            + pow( (double) ( rpt1.y - rpt2.y ), 2 );

                        if( dp < dtest ) adder = 0;

                        RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, VP, true );
                    }
        }
        rpt1 = rpt2;
        prp1 = prp2;

        node = node->GetNext();
    }
}
예제 #9
0
void Route::DrawGLLines( ViewPort &vp, ocpnDC *dc )
{
#ifdef ocpnUSE_GL
    float pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * vp.view_scale_ppm;

    bool r1valid = false;
    wxPoint2DDouble r1;
    wxPoint2DDouble lastpoint;

    wxRoutePointListNode *node = pRoutePointList->GetFirst();
    RoutePoint *prp2 = node->GetData();
    cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &lastpoint);

    if(GetnPoints() == 1 && dc) { // single point.. make sure it shows up for highlighting
        cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r1);
        dc->DrawLine(r1.m_x, r1.m_y, r1.m_x+2, r1.m_y+2);
        return;
    }

    //    Handle offscreen points
    LLBBox bbox = vp.GetBBox();

    // dc is passed for thicker highlighted lines (performance not very important)
    if( !dc )
        glBegin(GL_LINES);

    for(node = node->GetNext(); node; node = node->GetNext()) {
        RoutePoint *prp1 = prp2;
        prp2 = node->GetData();

        // Provisional, to properly set status of last point in route
        prp2->m_pos_on_screen = false;

        {

            wxPoint2DDouble r2;
            cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r2);
            if(wxIsNaN(r2.m_x)) {
                r1valid = false;
                continue;
            }

            lastpoint = r2;             // For active track segment to ownship

            // don't need to perform calculations or render segment
            // if both points are past any edge of the vp
            // TODO: use these optimizations for dc mode
            bool lat1l = prp1->m_lat < bbox.GetMinLat(), lat2l = prp2->m_lat < bbox.GetMinLat();
            bool lat1r = prp1->m_lat > bbox.GetMaxLat(), lat2r = prp2->m_lat > bbox.GetMaxLat();
            if( (lat1l && lat2l) || (lat1r && lat2r) ) {
                r1valid = false;
                prp1->m_pos_on_screen = false;
                continue;
            }

            bool lon1l, lon1r, lon2l, lon2r;
            TestLongitude(prp1->m_lon, bbox.GetMinLon(), bbox.GetMaxLon(), lon1l, lon1r);
            TestLongitude(prp2->m_lon, bbox.GetMinLon(), bbox.GetMaxLon(), lon2l, lon2r);
            if( (lon1l && lon2l) || (lon1r && lon2r) ) {
                r1valid = false;
                prp1->m_pos_on_screen = false;
                continue;
            }

            if(!r1valid) {
                cc1->GetDoubleCanvasPointPix( prp1->m_lat, prp1->m_lon, &r1);
                if(wxIsNaN(r1.m_x))
                    continue;
            }

            //  we must decide which way to go in longitude
            //  for projections which wrap, in this case, we will render two lines
            //  (one may often be off screen which would be nice to fix but complicate things here
            //  anyway, in some cases both points are on screen, but the route wraps to either side
            //  so two lines are needed to draw this properly

            double adder = 0;
            if( (vp.m_projection_type == PROJECTION_MERCATOR ||
                    vp.m_projection_type == PROJECTION_EQUIRECTANGULAR) ) {
                float olon = vp.clon > 0 ? vp.clon - 180 : vp.clon + 180;

                if(prp1->m_lon < prp2->m_lon) {
                    if(prp2->m_lon - prp1->m_lon < 180) {
                        if(olon > prp1->m_lon && olon < prp2->m_lon)
                            adder = pix_full_circle;
                    } else if(olon < prp1->m_lon || olon > prp2->m_lon)
                        adder = -pix_full_circle;
                } else if(prp1->m_lon - prp2->m_lon < 180) {
                    if(olon < prp1->m_lon && olon > prp2->m_lon)
                        adder = -pix_full_circle;
                } else if(olon > prp1->m_lon || olon < prp2->m_lon)
                    adder = pix_full_circle;
            }

            if( dc )
                if(adder) {
                    float adderc = cos(vp.rotation)*adder, adders = sin(vp.rotation)*adder;
                    dc->DrawLine(r1.m_x, r1.m_y, r2.m_x + adderc, r2.m_y + adders);
                    dc->DrawLine(r1.m_x - adderc, r1.m_y - adders, r2.m_x, r2.m_y);
                } else
                    dc->DrawLine(r1.m_x, r1.m_y, r2.m_x, r2.m_y);
            else {
                glVertex2f(r1.m_x, r1.m_y);
                if(adder) {
                    float adderc = cos(vp.rotation)*adder, adders = sin(vp.rotation)*adder;
                    glVertex2f(r2.m_x+adderc, r2.m_y+adders);
                    glVertex2f(r1.m_x-adderc, r1.m_y-adders);
                }
                glVertex2f(r2.m_x, r2.m_y);

                // cache screen position for arrows and points
                if(!r1valid) {
                    prp1->m_pos_on_screen = !lat1l && !lat1r && !lon1l && !lon1r;
                    prp1->m_screen_pos = r1;
                }

                prp2->m_pos_on_screen = !lat2l && !lat2r && !lon2l && !lon2r;
                prp2->m_screen_pos = r2;
            }

            r1 = r2;
            r1valid = true;
        }
    }

    if( !dc )
        glEnd();
#endif
}
예제 #10
0
void Route::Draw( ocpnDC& dc, ViewPort &vp, const LLBBox &box )
{
    if( pRoutePointList->empty() )
        return;

    LLBBox test_box = GetBBox();
    if( box.IntersectOut( test_box ) ) // Route is wholly outside window
        return;

    int width = g_route_line_width;
    if( m_width != WIDTH_UNDEFINED ) width = m_width;

    if( m_bVisible && m_bRtIsSelected ) {
        wxPen spen = *g_pRouteMan->GetSelectedRoutePen();
        spen.SetWidth( width );
        dc.SetPen( spen );
        dc.SetBrush( *g_pRouteMan->GetSelectedRouteBrush() );
    }
    else if ( m_bVisible )
    {
        wxPenStyle style = wxPENSTYLE_SOLID;
        wxColour col;
        if( m_style != wxPENSTYLE_INVALID ) style = m_style;
        if( m_Colour == wxEmptyString ) {
            col = g_pRouteMan->GetRoutePen()->GetColour();
        } else {
            for( unsigned int i = 0; i < sizeof( ::GpxxColorNames ) / sizeof(wxString); i++ ) {
                if( m_Colour == ::GpxxColorNames[i] ) {
                    col = ::GpxxColors[i];
                    break;
                }
            }
        }
        dc.SetPen( *wxThePenList->FindOrCreatePen( col, width, style ) );
        dc.SetBrush( *wxTheBrushList->FindOrCreateBrush( col, wxBRUSHSTYLE_SOLID ) );
    }

    if( m_bVisible && m_bRtIsActive )
    {
        wxPen spen = *g_pRouteMan->GetActiveRoutePen();
        spen.SetWidth( width );
        dc.SetPen( spen );
        dc.SetBrush( *g_pRouteMan->GetActiveRouteBrush() );
    }

    wxPoint rpt1, rpt2;
    if ( m_bVisible )
        DrawPointWhich( dc, 1, &rpt1 );

    wxRoutePointListNode *node = pRoutePointList->GetFirst();
    RoutePoint *prp1 = node->GetData();
    node = node->GetNext();

    if ( !m_bVisible && prp1->m_bKeepXRoute )
        prp1->Draw( dc );

    while( node ) {

        RoutePoint *prp2 = node->GetData();
        if ( !m_bVisible && prp2->m_bKeepXRoute )
            prp2->Draw( dc );
        else if (m_bVisible)
            prp2->Draw( dc, &rpt2 );

        if ( m_bVisible )
        {
            //    Handle offscreen points
            bool b_2_on = vp.GetBBox().Contains( prp2->m_lat,  prp2->m_lon );
            bool b_1_on = vp.GetBBox().Contains( prp1->m_lat,  prp1->m_lon );

            //Simple case
            if( b_1_on && b_2_on ) RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x, rpt2.y, vp, true, m_hiliteWidth ); // with arrows

            //    In the cases where one point is on, and one off
            //    we must decide which way to go in longitude
            //     Arbitrarily, we will go the shortest way

            double pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI
                                     * vp.view_scale_ppm;
            double dp = pow( (double) ( rpt1.x - rpt2.x ), 2 ) + pow( (double) ( rpt1.y - rpt2.y ), 2 );
            double dtest;
            int adder;
            if( b_1_on && !b_2_on ) {
                if( rpt2.x < rpt1.x ) adder = (int) pix_full_circle;
                else
                    adder = -(int) pix_full_circle;

                dtest = pow( (double) ( rpt1.x - ( rpt2.x + adder ) ), 2 )
                        + pow( (double) ( rpt1.y - rpt2.y ), 2 );

                if( dp < dtest ) adder = 0;

                RenderSegment( dc, rpt1.x, rpt1.y, rpt2.x + adder, rpt2.y, vp, true, m_hiliteWidth );
            } else if( !b_1_on ) {
                if( rpt1.x < rpt2.x ) adder = (int) pix_full_circle;
                else
                    adder = -(int) pix_full_circle;

                float rxd = rpt2.x - ( rpt1.x + adder );
                float ryd = rpt1.y - rpt2.y;
                dtest = rxd*rxd + ryd*ryd;

                if( dp < dtest ) adder = 0;

                RenderSegment( dc, rpt1.x + adder, rpt1.y, rpt2.x, rpt2.y, vp, true, m_hiliteWidth );
            }
        }

        rpt1 = rpt2;
        prp1 = prp2;

        node = node->GetNext();
    }
}
예제 #11
0
파일: Route.cpp 프로젝트: jieter/OpenCPN
void Route::DrawGLLines( ViewPort &VP, ocpnDC *dc )
{
#ifdef ocpnUSE_GL    
    float pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * VP.view_scale_ppm;

    bool r1valid = false;
    wxPoint2DDouble r1;
    wxPoint2DDouble lastpoint;
    
    wxRoutePointListNode *node = pRoutePointList->GetFirst();
    RoutePoint *prp2 = node->GetData();
    cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &lastpoint);
    
    if(m_nPoints == 1 && dc) { // single point.. make sure it shows up for highlighting
        cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r1);
        dc->DrawLine(r1.m_x, r1.m_y, r1.m_x+2, r1.m_y+2);
        return;
    }

    // dc is passed for thicker highlighted lines (performance not very important)
    if( !dc )
        glBegin(GL_LINES);

    unsigned short int FromSegNo = prp2->m_GPXTrkSegNo;
    for(node = node->GetNext(); node; node = node->GetNext()) {
        RoutePoint *prp1 = prp2;
        prp2 = node->GetData();
        unsigned short int ToSegNo = prp2->m_GPXTrkSegNo;

        // Provisional, to properly set status of last point in route
        prp2->m_pos_on_screen = false;
        
        if (FromSegNo != ToSegNo) {
            FromSegNo = ToSegNo;
            r1valid = false;
        } else {
            
            wxPoint2DDouble r2;
            cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r2);
            lastpoint = r2;             // For active track segment to ownship
            
            //    Handle offscreen points
            LLBBox bbox = VP.GetBBox();

            // don't need to perform calculations or render segment
            // if both points are past any edge of the vp
            // TODO: use these optimizations for dc mode
            bool lat1l = prp1->m_lat < bbox.GetMinY(), lat2l = prp2->m_lat < bbox.GetMinY();
            bool lat1r = prp1->m_lat > bbox.GetMaxY(), lat2r = prp2->m_lat > bbox.GetMaxY();
            if( (lat1l && lat2l) || (lat1r && lat2r) ) {
                r1valid = false;
                prp1->m_pos_on_screen = false;
                continue;
            }

            bool lon1l, lon1r, lon2l, lon2r;
            TestLongitude(prp1->m_lon, bbox.GetMinX(), bbox.GetMaxX(), lon1l, lon1r);
            TestLongitude(prp2->m_lon, bbox.GetMinX(), bbox.GetMaxX(), lon2l, lon2r);
            if( (lon1l && lon2l) || (lon1r && lon2r) ) {
                r1valid = false;
                prp1->m_pos_on_screen = false;
                continue;
            }

            if(!r1valid)
                cc1->GetDoubleCanvasPointPix( prp1->m_lat, prp1->m_lon, &r1);

            //    In the cases where one point is on, and one off
            //    we must decide which way to go in longitude

            double adder1 = 0, adder2 = 0;
            if(!(lon1l || lon1r) && (lon2l || lon2r) ) { // first point is on screen, second not
                if( r2.m_x < r1.m_x )
                    adder2 = pix_full_circle;
                else
                    adder2 = -pix_full_circle;

                if( fabs(r1.m_x - r2.m_x) < fabs(r1.m_x - ( r2.m_x + adder2 )) )
                    adder2 = 0;
            } else if(lon1l || lon1r) { // first point is off screen
                if( r1.m_x < r2.m_x )
                    adder1 = pix_full_circle;
                else
                    adder1 = -pix_full_circle;

                if( fabs(r1.m_x - r2.m_x) < fabs(r2.m_x - (r1.m_x + adder1)) )
                    adder1 = 0;
            }

            if( dc )
                dc->DrawLine(r1.m_x + adder1, r1.m_y, r2.m_x + adder2, r2.m_y);
            else {
                glVertex2f(r1.m_x + adder1, r1.m_y);
                glVertex2f(r2.m_x + adder2, r2.m_y);

                // cache screen position for arrows and points
                if(!r1valid) {
                    prp1->m_pos_on_screen = !lat1l && !lat1r && !lon1l && !lon1r;
                    prp1->m_screen_pos = r1;
                }

                prp2->m_pos_on_screen = !lat2l && !lat2r && !lon2l && !lon2r;
                prp2->m_screen_pos = r2;
            }

            r1 = r2;
            r1valid = true;
        }
    }

    //  Draw tentative segment from last point to Ownship, if running.
    if( IsTrack() ) {
        /* Active tracks */
        if( dynamic_cast<Track *>(this)->IsRunning() ){
            wxPoint2DDouble rs;
            cc1->GetDoubleCanvasPointPix( gLat, gLon, &rs);
            if( dc )
                dc->DrawLine(lastpoint.m_x, lastpoint.m_y, rs.m_x, rs.m_y);
            else {
                glVertex2f(lastpoint.m_x, lastpoint.m_y);
                glVertex2f(rs.m_x, rs.m_y);
             }
        }
    }
                
                
        
    if( !dc )
        glEnd();
#endif    
}
예제 #12
0
bool ViewPort::Divisor::Divide(ViewPort &Divisor, const double &Size)
{
  // Add a new window to the split.
  return Divide(Divisor.GetFinalDivisor(), Size);
}
예제 #13
0
void WVSChart::RenderViewOnDC(wxMemoryDC& dc, ViewPort& VPoint)
{
        float *platray = NULL;
        float *plonray = NULL;
        int *psegray = NULL;
        int x,y;
        if(!m_ok)
                return;

//      Set Color
        wxPen *pthispen = wxThePenList->FindOrCreatePen(GetGlobalColor(_T("BLUE3")), 1, wxSOLID);
        dc.SetPen(*pthispen);

//      Compute the 1 degree cell boundaries

        int lat_min = (int)floor(VPoint.GetBBox().GetMinY());
        int lat_max = (int)ceil(VPoint.GetBBox().GetMaxY());
        int lon_min = (int)floor(VPoint.GetBBox().GetMinX());
        int lon_max = (int)ceil(VPoint.GetBBox().GetMaxX());

        x = lon_min;
        y = lat_min;

//        printf("%d %d\n", lon_min, lon_max);

        //  Make positive definite longitude for easier integer math
        lon_min += 720;
        lon_max += 720;

        double ref_lon = VPoint.clon;

//      Loop around the lat/lon spec to get and draw the vector segments
        for(y = lat_min ; y < lat_max ; y++)
        {
                for(x = lon_min ; x < lon_max ; x++)
                {
//      Get the arrays of lat/lon vector segments
//      Sanity Check
                      int xt = x;
                      int yt = y;
//      Check the cache first
                        int ix = xt % 360; //xt + 180;                               // bias to positive
                        int iy = yt + 90;

                        if(  (ix > 359) || (ix < 0) || (iy > 179) || (iy < 0) )
                                continue;


                        if(-1 == nseg[ix][iy])                          // no data yet
                        {
                                                                                                     // so fill cache
                                platray = NULL;
                                plonray = NULL;
                                psegray = NULL;
                                int nsegments = wvsrtv (*pwvs_file_name,
                                        y, ix, &platray, &plonray, &psegray);
                                plat_ray[ix][iy] = platray;
                                plon_ray[ix][iy] = plonray;
                                pseg_ray[ix][iy] = psegray;
                                nseg[ix][iy] = nsegments;
//                                printf("load at %d %d \n", ix, iy);

                        }
 //                       else
 //                             printf("     from cache at %d %d \n", ix, iy);

                        if(nseg[ix][iy])
                        {
                                float *plat_seg = plat_ray[ix][iy];
                                float *plon_seg = plon_ray[ix][iy];
                                int *pseg_cnt = pseg_ray[ix][iy];
                                for(int iseg = 0 ; iseg < nseg[ix][iy] ; iseg++)
                                {
                                        int seg_cnt = *pseg_cnt++;
                                        if(seg_cnt > cur_seg_cnt_max)
                                        {
                                                cur_seg_cnt_max = seg_cnt;
                                                ptp = (wxPoint *)realloc(ptp, seg_cnt * sizeof(wxPoint));
                                        }
                                        wxPoint *pr = ptp;
                                        wxPoint p;



                                        for(int ip = 0 ; ip < seg_cnt ; ip++)
                                        {
                                                float plat = *plat_seg++;
                                                float plon = *plon_seg++;

                                                if(fabs(plon - ref_lon) > 180.)
                                                {
                                                      if(plon > ref_lon)
                                                            plon -= 360.;
                                                      else
                                                            plon += 360.;
                                                }


                                                double easting, northing;
                                                toSM(plat, plon + 360., VPoint.clat, ref_lon + 360., &easting, &northing);
                                                double epix = easting  * VPoint.view_scale_ppm;
                                                double npix = northing * VPoint.view_scale_ppm;

                                                double dx = epix * cos(VPoint.skew) + npix * sin(VPoint.skew);
                                                double dy = npix * cos(VPoint.skew) - epix * sin(VPoint.skew);
                                                p.x = (int)round((VPoint.pix_width  / 2) + dx);
                                                p.y = (int)round((VPoint.pix_height / 2) - dy);

                                                *pr = p;
                                                pr++;
                                        }
                                        dc.DrawLines(seg_cnt, ptp);
                                }
                        }
                }       // for x
        }       //for y
        platray = NULL;
        plonray = NULL;
        psegray = NULL;
        wvsrtv (_T("clean"), y, x, &platray, &plonray, &psegray);
}