这个教程展示了如何实现一个自定义的渲染类,该渲染类的主要功能是在某个地理位置的中心画出一个立方体,完整代码在 src-> gov.nasa.worldwindx.example.tutorial 中的Cube.java 。这篇教程针对那些对OpenGL熟悉的开发人员。
一、WorldWind
WorldWind是一个在 Java applications或者 Java applets 中可交互的展示3D地理信息的组件集。WorldWind的组件是可扩展的。The API 首先通过一些接口来定义,所以组件可以被一些另一些可选的组件所替代,同样的,一些具体的类也可以被替代或者是被扩展。
Applications和Applets通过建立一个或多个WorldWindow来使用WorldWind。WorldWindow提供了获取3D地理信息及应用行为操作的方法。
除了WorldWindow之外,还有几个主要的WorldWind接口。我们通过下图来具体看下:
Globe描述了一个行星的形状和地形,globe中有一个Tessellator,目的便是为了产生地形。
Layer 可以使用影像,形状或者其他的 globe信息。Layer中也提供了一些基于Screen的形状接口,这些并不会随球体的移动而有所改变。
Model整合了这个球体(globe)及他的一些图层(layer),包括一些展示在屏幕上的图层(in-screen layers)。
View 决定用户看到这个模型的视野。并且它被用户通过Input Handler发出的输入事件所控制。
Scene Controller控制着模型(model)的渲染以及渲染时间方面的事件。
在通常的用法中,应用程序为了他们所有的数据来创建一个Globe和一些Layer,并且将他们整合进一个Model。然后创建一个WorldWindow并将Model传递进去。随后,WorldWindow的scene controller球体和图层的显示,连同着视野的交互操作。
二、How World Wind Draws a Scene
当WorldWind渲染一个frame时,scene controller会建立一个球体绘画的声明,然后要求Model中的每一个图层区渲染他们自己。大多数的WorldWind shapes继承 Renderable 接口。Renderables可以被加载在RenderableLayer中,从而当layer被加载时,就实现了该Renderable。
渲染一个scene包括几个阶段:
1、The SceneController画出一个拾取模式(picking mode)的scene。“Picking”是决定在3D场景中哪一个物体被选中的过程。在拾取的时候,每一个被画的物体都有一个特有的颜色。The SceneController通过光标下的颜色来判断某一个物体是否被选中。
2、正常渲染模式下的The SceneControoler画取scene。每一个渲染类都将画自己本身。
3、当我们需要通过眼睛观察的距离来绘出从后向前显示的物体时,OrderedRenderables就要被选择了。在之后的教程中我们会讲解到。
三、Implementing Renderable
为了去画一个cube,我们需要写一个类实现Renderable接口。然后就可以直接被RenderableLayer加载。
class Cube implements Renderable
{
protected Position position;
protected double size;
public Cube(Position position, double sizeInMeters)
{
this.position = position;
this.size = sizeInMeters;
}
public void render(DrawContext dc)
{
// 1) Set up drawing state
// 2) Apply transform to position cube
// 3) Draw the cube
// 4) Restore drawing state to default
}
}
四、Managing Drawing State
在画立方体之前,我们需要建立OpenGL绘画声明。此时我们需要构造两个方法,即 beginDrawing() 和endDrawing()。在渲染cube之后,我们从WorldWind默认状态下改变的任何情况都必须被恢复,否则它将导致其他要加载的物体渲染不正确。
protected void beginDrawing(DrawContext dc)
{
GL2 gl = dc.getGL().getGL2();
int attrMask = GL2.GL_CURRENT_BIT | GL.GL_COLOR_BUFFER_BIT;
gl.glPushAttrib(attrMask);
if (!dc.isPickingMode())
dc.beginStandardLighting();
}
protected void endDrawing(DrawContext dc)
{
GL2 gl = dc.getGL().getGL2();
if (!dc.isPickingMode())
dc.endStandardLighting()