• WorldWind学习系列四:功能分析——Show Planet Axis、Show Position 、Show Cross Hairs功能


      今天主要看了Show Planet AxisShow Position Show Cross Hairs功能,主要是它们在菜单调用方式上都是很类似。代码如下:

    显示位置信息 
    private void menuItemShowPosition_Click(object sender, System.EventArgs e)
            {
                World.Settings.ShowPosition 
    = !World.Settings.ShowPosition;
                
    this.toolBarButtonPosition.Pushed = World.Settings.ShowPosition;
                
    this.menuItemShowPosition.Checked = World.Settings.ShowPosition;
              
      this.worldWindow.Invalidate();
            }

     

     //显示中心十字标   
     private void menuItemShowCrosshairs_Click(object sender, System.EventArgs e)
            {
           
    //控制中心十字标显示与否
                World.Settings.ShowCrosshairs = !World.Settings.ShowCrosshairs;
                
    this.menuItemShowCrosshairs.Checked = World.Settings.ShowCrosshairs;
                
    this.worldWindow.Invalidate();
            }

        从上面的代码看,我们只能惊叹代码封装的很好,同样都调用this.worldWindow.Invalidate();难道Invalidate()函数万能?!请参考我的Invalidate()方法学习(资料收集),原来该方法是界面区域失效,发送了重绘事件,将会调用WorldWindow.cs中重载了的OnPaint()。OnPaint方法里主要是调用了 Render()方法。所以我们的关键是看Render()中如何实现上面三个功能。(其实Render()中实现的功能很多,主要是控制界面绘制方面的,以后还会提到它的)

         Render()实现上面三个功能也大量使用了DirectXDirect 3D方面的知识,请网上搜索学习相关知识或参看我的Direct3D学习(资料收集)

        显示中心十字线功能

      Render()中实现代码为

          787     if (World.Settings.ShowCrosshairs)
                        this.DrawCrossHairs();

    实现显示十字标代码
    实现显示十字标代码 

            
    protected void DrawCrossHairs()
            {
                
    int crossHairSize = 10;

                
    if(this.crossHairs == null)
                {
                    crossHairs 
    = new Line(m_Device3d);//构造线对象
                }

                Vector2[] vertical 
    = new Vector2[2];
                Vector2[] horizontal 
    = new Vector2[2];
               
    // Vector2[] test = new Vector2[2];//这是我试验添加的,效果请看下面的截图
                horizontal[0].X = this.Width / 2 - crossHairSize;
                horizontal[
    0].Y = this.Height / 2;
                horizontal[
    1].X = this.Width / 2 + crossHairSize;
                horizontal[
    1].Y = this.Height / 2;

                vertical[
    0].X = this.Width / 2;
                vertical[
    0].Y = this.Height / 2 - crossHairSize;
                vertical[
    1].X = this.Width / 2;
                vertical[
    1].Y = this.Height / 2 + crossHairSize;

               
    // test[0].X = this.Width / 2;
               
    // test[0].Y = this.Height / 2 + crossHairSize;
                
    //test[1].X = this.Width / 2 + crossHairSize;
                
    //test[1].Y = this.Height / 2;

                crossHairs.Begin();
                crossHairs.Draw(horizontal, crossHairColor);
                crossHairs.Draw(vertical, crossHairColor);
               
    // crossHairs.Draw(test,Color.Red.ToArgb());
                crossHairs.End();
            }

     

        上面注销部分(我加了红线)是我试验添加的,效果请看上面的截图。其实就是划几条两点之间的线。

    显示位置信息

     

       是在Render()中调用RenderPositionInfo()方法的,请看该段实现代码。

    实现显示位置坐标信息 

             
    private const int positionAlphaStep = 20;
            
    private int positionAlpha = 255;
            
    private int positionAlphaMin = 40;
            
    private int positionAlphaMax = 205;

            
    protected void RenderPositionInfo()
            {
                
    // Render some Development information to screen
                string captionText = _caption;

                captionText 
    += "\n" + this.drawArgs.UpperLeftCornerText;

                
    if(World.Settings.ShowPosition)
                {
                    
    string alt = null;
                    
    double agl = this.drawArgs.WorldCamera.AltitudeAboveTerrain;
                    
    /*if(agl>100000)
                        alt = string.Format("{0:f2}km", agl/1000);
                    else
                        alt = string.Format("{0:f0}m", agl);
    */
                    alt 
    = ConvertUnits.GetDisplayString(agl);

                    
    string dist = null;
                    
    double dgl = this.drawArgs.WorldCamera.Distance;
                    
    /*if(dgl>100000)
                        dist = string.Format("{0:f2}km", dgl/1000);
                    else
                        dist = string.Format("{0:f0}m", dgl);
    */
                    dist 
    = ConvertUnits.GetDisplayString(dgl);
                    
                    
    // Heading from 0 - 360
                    double heading = this.drawArgs.WorldCamera.Heading.Degrees;
                    
    if(heading<0)
                        heading
    +=360;

             
    //构造显示位置坐标信息字符串
                    captionText += String.Format("Latitude: {0}\nLongitude: {1}\nHeading: {2:f2}\nTilt: {3}\nAltitude: {4}\nDistance: {5}\nFOV: {6}",
                        
    this.drawArgs.WorldCamera.Latitude,
                        
    this.drawArgs.WorldCamera.Longitude,
                        heading,
                        
    this.drawArgs.WorldCamera.Tilt,
                        alt,
                        dist,
                        
    this.drawArgs.WorldCamera.Fov );

                    
    if(agl < 300000)
                    {
                        captionText 
    += String.Format("\nTerrain Elevation: {0:n} meters\n"this.drawArgs.WorldCamera.TerrainElevation);
                    }
                }

                
    if(this.showDiagnosticInfo)
                    captionText 
    +=
                        
    "\nAvailable Texture Memory: " + (m_Device3d.AvailableTextureMemory/1024).ToString("N0"+ " kB"+
                        
    "\nBoundary Points: " + this.drawArgs.numBoundaryPointsRendered.ToString() + " / " + this.drawArgs.numBoundaryPointsTotal.ToString() + " : " + this.drawArgs.numBoundariesDrawn.ToString() +
                        
    "\nTiles Drawn: " + (this.drawArgs.numberTilesDrawn * 0.25f).ToString() +
                        
    "\n" + this.drawArgs.WorldCamera +
                        
    "\nFPS: " + this.fps.ToString("f1"+
                        
    "\nRO: " + m_World.RenderableObjects.Count.ToString("f0"+
                        
    "\nmLat: " + this.cLat.Degrees.ToString() + 
                        
    "\nmLon: " + this.cLon.Degrees.ToString() + 
                        
    "\n" + TimeKeeper.CurrentTimeUtc.ToLocalTime().ToLongTimeString();
                captionText 
    = captionText.Trim();

              
    //定义要画出文本的样式
                DrawTextFormat dtf = DrawTextFormat.NoClip | DrawTextFormat.WordBreak | DrawTextFormat.Right;
                
    int x = 7;
                
    int y = _menuBar!=null && World.Settings.ShowToolbar ? 65 : 7;

           
    //定义盛放位置文本的矩形框
                Rectangle textRect = Rectangle.FromLTRB(x,y, this.Width-8this.Height-8 );
                
    //我添加的测试用代码
                Rectangle testRect = Rectangle.FromLTRB(x, y, this.Width, this.Height);
                
    // Hide position info when toolbar is open
                if (_menuBar.IsActive) //如果上面的_menuBar处于活动状态,则更改位置文本的Alpha值
                {
                    positionAlpha 
    -= positionAlphaStep;
                    
    if (positionAlpha<positionAlphaMin)
                    {
                        positionAlpha
    =positionAlphaMin;
                    }
                }
                
    else
                {
                    positionAlpha 
    += positionAlphaStep;
                    
    if(positionAlpha>positionAlphaMax)
                        positionAlpha 
    = positionAlphaMax;
                }

                
    int positionBackColor = positionAlpha << 24;
                
    int positionForeColor = (int)((uint)(positionAlpha << 24+ 0xffffffu);

    使用Font对象defaultDrawingFont的DrawText()实现绘制位置信息
                
    this.drawArgs.defaultDrawingFont.DrawText( null, captionText, textRect, dtf, positionBackColor);
                textRect.Offset(
    -1,-1);
                
    this.drawArgs.defaultDrawingFont.DrawText( null, captionText, textRect, dtf, positionForeColor);

    //下面这行是我添加的,测试用
                this.drawArgs.defaultDrawingFont.DrawText(null"无痕客在研究WorldWind应用!", textRect, dtf,Color.Red.ToArgb());
            } 
      

        上面需要注意的知识点就是:使用Font对象(实例:defaultDrawingFont)的DrawText()实现绘制文本信息。

    地球轴线绘制

        WorldWindow.cs的Render()方法中调用了World.cs中Render()方法,该方法又调用了DrawAxis()

    法实现地球轴线绘制。

     

    453行 if (Settings.showPlanetAxis)


                  this.DrawAxis(drawArgs);
    画地球轴线

            
    private void DrawAxis(DrawArgs drawArgs)
            {
                CustomVertex.PositionColored[] axis 
    = new CustomVertex.PositionColored[2];
                Vector3 topV 
    = MathEngine.SphericalToCartesian(900this.EquatorialRadius + 0.15f * 

    this.EquatorialRadius);
                axis[
    0].X = topV.X;
                axis[
    0].Y = topV.Y;
                axis[
    0].Z = topV.Z;

                axis[
    0].Color = System.Drawing.Color.Pink.ToArgb();

                Vector3 botV 
    = MathEngine.SphericalToCartesian(-900this.EquatorialRadius + 0.15f * 

    this.EquatorialRadius);
                axis[
    1].X = botV.X;
                axis[
    1].Y = botV.Y;
                axis[
    1].Z = botV.Z;
                axis[
    1].Color = System.Drawing.Color.Pink.ToArgb();

                drawArgs.device.VertexFormat 
    = CustomVertex.PositionColored.Format;
                drawArgs.device.TextureState[
    0].ColorOperation = TextureOperation.Disable;
                drawArgs.device.Transform.World 
    = Matrix.Translation(
                    (
    float)-drawArgs.WorldCamera.ReferenceCenter.X,
                    (
    float)-drawArgs.WorldCamera.ReferenceCenter.Y,
                    (
    float)-drawArgs.WorldCamera.ReferenceCenter.Z
                    );

                drawArgs.device.DrawUserPrimitives(PrimitiveType.LineStrip, 
    1, axis);
                drawArgs.device.Transform.World 
    = drawArgs.WorldCamera.WorldMatrix;

            }

     其他部分:

    WorldWind学习系列三:简单功能分析——主窗体的键盘监听处理及拷贝和粘贴位置坐标功能

    WorldWind学习系列三:功能分析——截屏功能和“关于”窗体分析

    WorldWind学习系列二:擒贼先擒王篇2

    WorldWind学习系列二:擒贼先擒王篇1

    WorldWind学习系列一:顺利起航篇

     

  • 相关阅读:
    Windows2003 Webshell默认权限
    Windows安装Centos7双系统后Windows启动项消失
    GCC编译流程及常用编辑命令
    swoole的websockte例子
    PhpStorm 增加Swoole智能提示
    Centos7/RHEL 7 配置静态路由
    webpack介绍和使用
    Webpack中的sourcemap以及如何在生产和开发环境中合理的设置
    什么是 PWA
    php实现excel单元格合并,字体加粗居中等操作
  • 原文地址:https://www.cnblogs.com/wuhenke/p/1622752.html
Copyright © 2020-2023  润新知