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

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

WorldWind系列四:功能分析——Show Planet Axis、Show Position、Show Cross Hairs功能
来源:博客园作者:无痕客
今天主要看了Show Planet Axis、Show Position 、Show Cross Hairs 功能,主要是它们在菜单调用方式上都是很类似。

代码如下:
显示位置信息
private void menuItemShowPosition_Click(object sender, System.EventAr gs e)
{
World.Settings.ShowPosition = !World.Settings.ShowPositio n;
this.toolBarButtonPosition.Pushed = World.Settings.ShowPo sition;
this.menuItemShowPosition.Checked = World.Settings.ShowPo sition;
this.worldWindow.Invalidate();
}
//显示中心十字标
private void menuItemShowCrosshairs_Click(object sender, System.Even tArgs e)
{
//控制中心十字标显示与否
World.Settings.ShowCrosshairs = !World.Settings.ShowCross hairs;
this.menuItemShowCrosshairs.Checked = World.Settings.Show Crosshairs;
this.worldWindow.Invalidate();
}
从上面的代码看,我们只能惊叹代码封装的很好,同样都调用
this.worldWindow.Invalidate();难道Invalidate()函数万能?!请参考我的Invalidate()方法学习(资料收集),原来该方法是界面区域失效,发送了重绘事件,将会调用WorldWindow.cs中重载了的OnPaint()。

OnPaint方法里主要是调用了 Render()方法。

所以我们的关键是看Render()中如何实现上面三个功能。

(其实Render()中实现的功能很多,主要是控制界面绘制方面的,以后还会提到它的)
Render()实现上面三个功能也大量使用了DirectX和Direct 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.AltitudeAboveT errain;
/*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.De grees;
if(heading<0)
heading+=360;
//构造显示位置坐标信息字符串
captionText += String.Format("Latitude: {0}\nLongitud e: {1}\nHeading: {2:f2}\nTilt: {3}\nAltitude: {4}\nDistance: {5}\nFO V: {6}",
titude,
this.drawArgs.WorldCamera.Longitude,
heading,
this.drawArgs.WorldCamera.Tilt,
alt,
dist,
this.drawArgs.WorldCamera.Fov );
if(agl < 300000)
{
captionText += String.Format("\nTerrain Elevatio n: {0:n} meters\n", this.drawArgs.WorldCamera.TerrainElevation);
}
if(this.showDiagnosticInfo)
captionText +=
"\nAvailable Texture Memory: " + (m_Device3d.Avai lableTextureMemory/1024).ToString("N0") + " kB"+
"\nBoundary Points: " + this.drawArgs.numBoundary PointsRendered.ToString() + " / " + this.drawArgs.numBoundaryPointsTo tal.ToString() + " : " + this.drawArgs.numBoundariesDrawn.ToString () +
"\nTiles Drawn: " + (this.drawArgs.numberTilesDra wn * 0.25f).ToString() +
"\n" + this.drawArgs.WorldCamera +
"\nFPS: " + this.fps.ToString("f1") +
"\nRO: " + m_World.RenderableObjects.Count.ToStri ng("f0") +
"\nmLat: " + this.cLat.Degrees.ToString() +
"\nmLon: " + this.cLon.Degrees.ToString() +
"\n" + TimeKeeper.CurrentTimeUtc.ToLocalTime().To LongTimeString();
captionText = captionText.Trim();
//定义要画出文本的样式
DrawTextFormat dtf = DrawTextFormat.NoClip | DrawTextForm at.WordBreak | DrawTextFormat.Right;
int x = 7;
int y = _menuBar!=null && World.Settings.ShowToolbar ? 6 5 : 7;
//定义盛放位置文本的矩形框
Rectangle textRect = Rectangle.FromLTRB(x,y, this.Width-8, this.Height-8 );
//我添加的测试用代码
Rectangle testRect = Rectangle.FromLTRB(x, y, this.Widt h, 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 << 2 4) + 0xffffffu);
使用Font对象defaultDrawingFont的DrawText()实现绘制位置信息
this.drawArgs.defaultDrawingFont.DrawText( null, captionT ext, textRect, dtf, positionBackColor);
textRect.Offset(-1,-1);
this.drawArgs.defaultDrawingFont.DrawText( null, captionT ext, 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.Po sitionColored[2];
Vector3 topV = MathEngine.SphericalToCartesian(90, 0, thi s.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(-90, 0, th is.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.PositionColor ed.Format;
drawArgs.device.TextureState[0].ColorOperation = TextureO peration.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.LineStri p, 1, axis);
drawArgs.device.Transform.World = drawArgs.WorldCamera.Wo rldMatrix;
}。

相关文档
最新文档