예제 #1
0
void iNWButton::DrawElement(iMemoryDC &ddc) const
{
	if (!IsElementEnabled()) {
		m_Dibs[0].CopyToDibXY(&ddc.m_Dib,GetElementRect().point(),BLEND_ALPHABLEND);
	} else if (IsTrack()) {
		if (m_BtnState==BtnUnpressed) m_Dibs[3].CopyToDibXY(&ddc.m_Dib,GetElementRect().point(),BLEND_ALPHABLEND);
		else if (m_BtnState==BtnFocused) m_Dibs[2].CopyToDibXY(&ddc.m_Dib,GetElementRect().point(),BLEND_ALPHABLEND);
	} else {
		if (m_BtnState==BtnUnpressed) m_Dibs[3].CopyToDibXY(&ddc.m_Dib,GetElementRect().point(),BLEND_ALPHABLEND);
		else if (m_BtnState==BtnFocused) m_Dibs[1].CopyToDibXY(&ddc.m_Dib,GetElementRect().point(),BLEND_ALPHABLEND);
	}
}
예제 #2
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(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;
    }

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

    // 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);
            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.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);
                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;
        }
    }

    //  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    
}
예제 #3
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    
}