WorldWind系列六 渲染过程解析篇.docx
- 文档编号:8282315
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:10
- 大小:54.39KB
WorldWind系列六 渲染过程解析篇.docx
《WorldWind系列六 渲染过程解析篇.docx》由会员分享,可在线阅读,更多相关《WorldWind系列六 渲染过程解析篇.docx(10页珍藏版)》请在冰豆网上搜索。
WorldWind系列六渲染过程解析篇
WorldWind系列六:
渲染过程解析篇
来源:
博客园 作者:
无痕客
今天主要是分析学习了Render问题,搞明白了WorldWind中整个Render绘制处理过程。
其中关键类是:
RenderableObject.cs,RenderobjectList.cs.
WW中所有需要绘制的对象都RenderableObject,WW的各功能的执行显示都是不断地调用相应的Render方法。
1.RenderableObject整个绘制对象继承图
WW绘制都是通过RenderableObject类,将所有的要绘制对象都看做是RenderableObject,从而统一了整个系统WW的绘制对象的绘制过程。
2.RenderableObjectList也继承自RenderableObject,先看看它的继承图
摘录内容:
“实际的点线,平面纹理等渲染对象都是从RenderableObject继承,最终的渲染实现也是在从它继续下来的类中,RenderableObjectList的成员m_children(protectedArrayListm_children=newArrayList();)包含WW中所有的渲染对象,绘制过程中按如下的优先级进行:
publicenumRenderPriority
{
SurfaceImages=0,
TerrainMappedImages=100,
AtmosphericImages=200,
LinePaths=300,
Icons=400,
Placenames=500,
Custom=600
}
这里对WW调试过程中的m_children的成员做个截图,需要注意的是m_children的成员大部分还是RenderableObjectList对象,向下包含的层次很多,但只有最底层的从RenderableObject继续的对象才是渲染的最终实现。
”摘自:
RenderableObjectList可以简单看作RenderableObject对象的集合,但实质上存储RenderableObject对象集合的仅仅是其中的属性m_children,它有很多特有的针对m_children管理的方法,如:
Add(RenderableObjectro)、Remove(RenderableObjectlayer)。
RenderableObjectList里通过该Timer.Elapsed事件实现了自动刷新渲染的功能。
这里还有个知识点,我们可以学习一下,就是Timer.Elapsed事件使用,请参考MS的
3.下面让我们一起看看WW实现渲染绘制的整个代码调用流程,主要分为两部分:
一、获取到所有的要绘制对象集合,二、绘制所有要绘制的对象。
分析入口还是从WorldWind.cs的MainAppliaction()方法开始的。
3.1获取到所有的要绘制对象集合,存放到World.cs中的RenderableObjects属性里
MainAppliaction()中调用OpenStartupWorld()
——》2974行OpenWorld(curWorldFile);调用了privatevoidOpenWorld(stringworldXmlFile)方法
——》3049行worldWindow.CurrentWorld=WorldWind.ConfigurationLoader.Load(worldXmlFile,worldWindow.Cache);调用了CongfigurationLoader.cs的publicstaticWorldLoad(stringfilename,Cachecache)方法
——》CongfigurationLoader.cs的110行newWorld.RenderableObjects=getRenderablesFromLayerDirectory(layerDirectory,newWorld,cache);看代码
加载渲染对象代码
public static World Load(string filename, Cache cache)
{
Log.Write(Log.Levels.Debug, "CONF", "Loading " + filename);
// get the World Wind Settings through reflection to avoid changing the signature of Load().
Assembly a = Assembly.GetEntryAssembly();
Type appType = a.GetType("WorldWind.MainApplication");
System.Reflection.FieldInfo finfo = appType.GetField("Settings", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetField);
WorldWindSettings settings = finfo.GetValue(null) as WorldWindSettings;
XmlReaderSettings readerSettings = new XmlReaderSettings();
if (settings.ValidateXML)
{
Log.Write(Log.Levels.Debug, "CONF", "validating " + filename + " against WorldXmlDescriptor.xsd and LayerSet.xsd");
readerSettings.ValidationType = ValidationType.Schema;
/* load the schema to validate against instead of hoping for an inline schema reference */
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(null, settings.ConfigPath + "/WorldXmlDescriptor.xsd");
schemas.Add(null, settings.ConfigPath + "/Earth/LayerSet.xsd");
readerSettings.Schemas = schemas;
readerSettings.ValidationEventHandler += new ValidationEventHandler(XMLValidationCallback);
readerSettings.ValidationFlags |= System.Xml.Schema.XmlSchemaValidationFlags.ReportValidationWarnings;
}
else
{
Log.Write(Log.Levels.Debug, "CONF", "loading " + filename + " without validation");
readerSettings.ValidationType = ValidationType.None;
}
try
{
XmlReader docReader = XmlReader.Create(filename, readerSettings);
XPathDocument docNav = new XPathDocument(docReader);
XPathNavigator nav = docNav.CreateNavigator();
XPathNodeIterator worldIter = nav.Select("/World[@Name]");
if (worldIter.Count > 0)
{
worldIter.MoveNext();
string worldName = worldIter.Current.GetAttribute("Name", "");
double equatorialRadius = ParseDouble(worldIter.Current.GetAttribute("EquatorialRadius", ""));
string layerDirectory = worldIter.Current.GetAttribute("LayerDirectory", "");
if (layerDirectory.IndexOf(":
") < 0)
{
layerDirectory = Path.Combine(Path.GetDirectoryName(filename), layerDirectory);
}
TerrainAccessor[] terrainAccessor = getTerrainAccessorsFromXPathNodeIterator(worldIter.Current.Select("TerrainAccessor"),
System.IO.Path.Combine(cache.CacheDirectory, worldName));
World newWorld = new World(
worldName,
new Microsoft.DirectX.Vector3(0, 0, 0),
new Microsoft.DirectX.Quaternion(0, 0, 0, 0),
equatorialRadius,
cache.CacheDirectory,
(terrainAccessor !
= null ?
terrainAccessor[0] :
null)//TODO:
Oops, World should be able to handle an array of terrainAccessors
);
//加载所有要渲染绘制的对象
newWorld.RenderableObjects = getRenderablesFromLayerDirectory(layerDirectory, newWorld, cache);
return newWorld;
}
}
catch (XmlSchemaException ex)
{
Log.Write(Log.Levels.Error, "CONF", "Exception caught during XML parsing:
" + ex.Message);
Log.Write(Log.Levels.Error, "CONF", "File " + filename + " was not read successfully.");
// TODO:
should pop up a message box or something.
return null;
}
return null;
}
——》170publicstaticRenderableObjectListgetRenderableFromLayerFile(stringlayerFile,WorldparentWorld,Cachecache,boolenableRefresh)方法,真正加载绘制对象集合的函数。
3.2绘制所有要绘制的对象
WorldWind.cs中MainAppliaction()中
——》675worldWindow.Render();调用了WorldWindow.cs的Render()方法
——》785m_World.Render(this.drawArgs);调用World.cs的publicoverridevoidRender(DrawArgsdrawArgs)方法
分类分层次地调用渲染代码
public override void Render(DrawArgs drawArgs)
{
try
{
if (m_WorldSurfaceRenderer !
= null && World.Settings.UseWorldSurfaceRenderer)
{
m_WorldSurfaceRenderer.RenderSurfaceImages(drawArgs);
}
// Old method -- problems with RenderPriority sorting
// RenderableObjects.Render(drawArgs);
RenderStars(drawArgs, RenderableObjects);
if (drawArgs.CurrentWorld.IsEarth && World.Settings.EnableAtmosphericScattering)
{
float aspectRatio = (float)drawArgs.WorldCamera.Viewport.Width / drawArgs.WorldCamera.Viewport.Height;
float zNear = (float)drawArgs.WorldCamera.Altitude * 0.1f;
double distToCenterOfPlanet = (drawArgs.WorldCamera.Altitude + equatorialRadius);
double tangentalDistance = Math.Sqrt(distToCenterOfPlanet * distToCenterOfPlanet - equatorialRadius * equatorialRadius);
double amosphereThickness = Math.Sqrt(m_outerSphere.m_radius * m_outerSphere.m_radius + equatorialRadius * equatorialRadius);
Matrix proj = drawArgs.device.Transform.Projection;
drawArgs.device.Transform.Projection = Matrix.PerspectiveFovRH((float)drawArgs.WorldCamera.Fov.Radians, aspectRatio, zNear, (float)(tangentalDistance + amosphereThickness));
drawArgs.device.RenderState.ZBufferEnable = false;
drawArgs.device.RenderState.CullMode = Cull.CounterClockwise;
m_outerSphere.Render(drawArgs);
drawArgs.device.RenderState.CullMode = Cull.Clockwise;
drawArgs.device.RenderState.ZBufferEnable = true;
drawArgs.device.Transform.Projection = proj;
}
if (World.Settings.EnableSunShading)
RenderSun(drawArgs);
//分类、分层次地调用渲染方法
//render SurfaceImages
Render(RenderableObjects, WorldWind.Renderable.RenderPriority.TerrainMappedImages, drawArgs);
if (m_projectedVectorRenderer !
= null)
m_projectedVectorRenderer.Render(drawArgs);
//render AtmosphericImages
Render(RenderableObjects, WorldWind.Renderable.RenderPriority.AtmosphericImages, drawArgs);
//render LinePaths
Render(RenderableObjects, WorldWind.Renderable.RenderPriority.LinePaths, drawArgs);
//render Placenames
Render(RenderableObjects, WorldWind.Renderable.RenderPriority.Placenames, drawArgs);
//render Icons
Render(RenderableObjects, WorldWind.Renderable.RenderPriority.Icons, drawArgs);
//render Custom
Render(RenderableObjects, WorldWind.Renderable.RenderPriority.Custom, drawArgs);
if (Settings.showPlanetAxis)
this.DrawAxis(drawArgs);
}
catch (Exception ex)
{
Log.Write(ex);
}
}
——》分类绘制过程中是调用485行的privatevoidRender(WorldWind.Renderable.RenderableObjectrenderable,WorldWind.Renderable.RenderPrioritypriority,DrawArgsdrawArgs)方法。
被各类对象调用的渲染方法
private void
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WorldWind系列六 渲染过程解析篇 WorldWind 系列 渲染 过程 解析
![提示](https://static.bdocx.com/images/bang_tan.gif)