Beispiel #1
0
//
// Draw the reachable SHADED terrain glide amoeba
// This is not the outlined perimeter
//
void MapWindow::DrawTerrainAbove(LKSurface& Surface, const RECT& rc) {

  // Lets try to make it better understandable with a goto.
  // If CAR or GA users dont want amoeba, they should disable it in config. 
  // Otherwise we should paint it, not hide it automatically!
  // Here are the conditions we print this amoeba, otherwise we return;

  // First is we are in SIM mode and we changed the altitude;
  if (SIMMODE && DerivedDrawInfo.AltitudeAGL>100) goto _doit;

  // Second, if we are flying
  if (DerivedDrawInfo.Flying) goto _doit;

  if (DerivedDrawInfo.GlideFootPrint_valid)  goto _doit;
    
  return;

_doit:

#ifndef ENABLE_OPENGL
  LKColor whitecolor = LKColor(0xff,0xff,0xff);
  LKColor graycolor = LKColor(0xf0,0xf0,0xf0);
  LKColor origcolor = TempSurface.SetTextColor(whitecolor);

  TempSurface.SetBackgroundTransparent();

  TempSurface.SetBkColor(whitecolor);

  TempSurface.SelectObject(LK_WHITE_PEN);
  TempSurface.SetTextColor(graycolor);
  TempSurface.SelectObject(hAboveTerrainBrush);
  TempSurface.Rectangle(rc.left,rc.top,rc.right,rc.bottom);
  TempSurface.SelectObject(LK_WHITE_PEN);
  TempSurface.SelectObject(LKBrush_White);
  TempSurface.Polygon(Groundline.data(),Groundline.size());

  // need to do this to prevent drawing of colored outline
  TempSurface.SelectObject(LK_WHITE_PEN);
#ifdef HAVE_HATCHED_BRUSH
  Surface.TransparentCopy(
          rc.left,rc.top,
          rc.right-rc.left,rc.bottom-rc.top,
          TempSurface,
          rc.left,rc.top);
#else
  Surface.AlphaBlendNotWhite(rc, TempSurface, rc, 255/2);
#endif


  // restore original color
  TempSurface.SetTextColor(origcolor);
  TempSurface.SetBackgroundOpaque();
#else

    Canvas& canvas = Surface;
  
    const GLEnable<GL_STENCIL_TEST> stencil;
    
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glDepthMask(GL_FALSE);
    glStencilFunc(GL_NEVER, 1, 0xFF);
    glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);  // draw 1s on test fail (always)

    // draw stencil pattern
    glStencilMask(0xFF);
    glClear(GL_STENCIL_BUFFER_BIT);  // needs mask=0xFF

    ScopeVertexPointer vp(Groundline.data());
    glDrawArrays(GL_TRIANGLE_FAN, 0, Groundline.size());

    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glDepthMask(GL_TRUE);
    glStencilMask(0x00);
    // draw where stencil's value is 0
    glStencilFunc(GL_EQUAL, 0, 0xFF);

    canvas.DrawFilledRectangle(rc.left,rc.top,rc.right,rc.bottom, AboveTerrainColor);

#endif  

}
Beispiel #2
0
void MapWindow::DrawTaskAAT(LKSurface& Surface, const RECT& rc) {
    int i;
    double tmp1 = 0.0;

    if (WayPointList.empty()) return;
    if (!AATEnabled) return;

    LockTaskData(); // protect from external task changes
    /**********************************************/
    /* Check if not Validated Waypoint is visible */
    bool bDraw = false;
    int maxTp = 1;
    rectObj rcrect = (rectObj){(double) rc.left, (double) rc.top, (double) rc.right, (double) rc.bottom};
    RECT rcDraw = (RECT){rc.right, rc.bottom, rc.left, rc.top};

    for (maxTp = std::max(1, ActiveTaskPoint); ValidTaskPoint(maxTp + 1); ++maxTp) {
        if (ValidTaskPoint(maxTp)) {
            int Type = 0;
            double Radius = 0.;
            GetTaskSectorParameter(maxTp, &Type, &Radius);
            switch (Type) {
                case CONE:
                case CIRCLE:
                    tmp1 = Task[maxTp].AATCircleRadius * zoom.ResScaleOverDistanceModify();
                    break;
                case SECTOR:
                    tmp1 = Task[maxTp].AATSectorRadius * zoom.ResScaleOverDistanceModify();
                    break;
                default:
                    tmp1 = 0.0;
                    break;
            }
        }

        PixelScalar x = WayPointList[Task[maxTp].Index].Screen.x;
        PixelScalar y = WayPointList[Task[maxTp].Index].Screen.y;
        rectObj rect = (rectObj){x - tmp1, y - tmp1, x + tmp1, y + tmp1};

        if (msRectOverlap(&rect, &rcrect) == MS_TRUE) {
            rcDraw.top = std::min((PixelScalar)rect.miny, rcDraw.top);
            rcDraw.bottom = std::max((PixelScalar) rect.maxy, rcDraw.bottom);
            rcDraw.left = std::min((PixelScalar) rect.minx, rcDraw.left);
            rcDraw.right = std::max((PixelScalar) rect.maxx, rcDraw.right);
            bDraw = true;
        }
    }
    /**********************************************/

    if (bDraw) { // Draw Only if one is Visible
#ifdef USE_GDI
        rcDraw.top = std::max(rc.top, rcDraw.top);
        rcDraw.bottom = std::min(rc.bottom, rcDraw.bottom);
        rcDraw.left = std::max(rc.left, rcDraw.left);
        rcDraw.right = std::min(rc.right, rcDraw.right);


        LKColor whitecolor = RGB_WHITE;
        LKColor origcolor = TempSurface.SetTextColor(whitecolor);

        const auto oldpen = TempSurface.SelectObject(LK_WHITE_PEN);
        const auto oldbrush = TempSurface.SelectObject(LKBrush_White);
        if(LKSurface::AlphaBlendSupported()) {
            // copy original bitmap into temp (for saving fully transparent areas)
            TempSurface.Copy(rcDraw.left, rcDraw.top,
                    rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top, 
                    Surface, rcDraw.left, rcDraw.top);
        } else {
            TempSurface.Rectangle(rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom);
        }
        
        TempSurface.SelectObject(LK_NULL_PEN);
#ifdef HAVE_HATCHED_BRUSH          
        TempSurface.SelectObject(hAirspaceBrushes[iAirspaceBrush[AATASK]]);
#else
        TempSurface.SelectObject(LKBrush_Yellow);
#endif  
        // this color is used as the black bit
        TempSurface.SetTextColor(Colours[iAirspaceColour[AATASK]]);
        // this color is the transparent bit
        TempSurface.SetBkColor(whitecolor);
        
        LKSurface & AliasSurface = TempSurface;
#else
        LKSurface & AliasSurface = Surface;
        Surface.SelectObject(LKBrush(LKColor(255U,255U,0U).WithAlpha(AlphaLevel)));
#endif
        for (i = maxTp - 1; i > std::max(0, ActiveTaskPoint - 1); i--) {
        if (ValidTaskPoint(i)) {
            int Type = 0;
            double Radius = 0.;
            GetTaskSectorParameter(i, &Type, &Radius);

            switch (Type) {
                case CONE:
                case CIRCLE:
                    tmp1 = Radius * zoom.ResScaleOverDistanceModify();
                    AliasSurface.DrawCircle(
                            WayPointList[Task[i].Index].Screen.x,
                            WayPointList[Task[i].Index].Screen.y,
                            (int) tmp1, rc, true);
                    break;
                case SECTOR:
                    tmp1 = Radius * zoom.ResScaleOverDistanceModify();
                    AliasSurface.Segment(
                            WayPointList[Task[i].Index].Screen.x,
                            WayPointList[Task[i].Index].Screen.y, (int) tmp1, rc,
                            Task[i].AATStartRadial - DisplayAngle,
                            Task[i].AATFinishRadial - DisplayAngle);
                    break;
            }
        }
        }
#ifdef USE_GDI
        // restore original color
        TempSurface.SetTextColor(origcolor);
        TempSurface.SelectObject(oldpen);
        TempSurface.SelectObject(oldbrush);
        
        if(!Surface.AlphaBlend(rcDraw, TempSurface,rcDraw, AlphaLevel)) {
            // if AlphaBlend is not supported, use TransparentBld
            Surface.TransparentCopy(
                    rcDraw.left, rcDraw.top,
                    rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top,
                    TempSurface,
                    rcDraw.left, rcDraw.top);
        }
#endif
	}
    
    {
        UnlockTaskData();
    }
}