|
Layers and ViewportsOne of the major changes in the move to Aviatrix3D 2.0 was the introduction of a full layering and compositing capability to the API. This changed the root of the scene graph structure to always use this capability, regardless of whether you need it or not. In the previous tutorials you have seen a basic setup using just a single layer and viewport. Aviatrix3D is capable of far more than that. If you would like to see the complete version of these examples, they can be found in the examples/layers directory. Organising the Root of the Scene GraphAt the root of the scene graph you have layers. Each layer represents an independent set of geometry that can be rendered. Layers present a logical rendering order of how content should be placed on the screen or surface. Each layer has its own viewpoint, background, global fog etc, which act independently of all the other layers. A layer logically covers the entire drawable component. The layer is a bucket for this global rendering order. Within each layer you need to describe how much of the drawable component you want to make your active drawing area. This active drawing area is called a viewport. Depending on which layer type you select, you could have more than one viewport in a single layer. Each viewport represents a single, fixed-size amount of screen that your geometry will be rendered in. Size is always measured in pixels and described in the surface coordinate system (bottom, left, width and height). With multiple viewports in a layer, you can then have a collection of different sets of geometry all being rendered at once, without needing to get into using multiple window components. To add a little further complexity, we also allow each viewport to potentially have layers. In this case the layers are all restricted to the viewport and always take that viewport's size. Why would we allow this? Well a lot of cases where you want multiple viewports, you also want to have per-viewport user interface capabilities. Think of your typical 4-view graphical editor application such as AutoCAD or Maya. Each view of the model (viewport in our terminology) has a small UI toolbar that indicates various local per-view options. These are rendered as layers within that viewport. Thus, we set up our scene graph structures to allow this sort of application environment as well. One minor departure that layers take from the rest of the scene graph is that we do not allow you to share them. All layers and viewports have a single parent object. Defining Multiple LayersIn the hello world example, you saw code that set up a single viewport and layer to render the geometry in. The code looked like this: SimpleViewport view = new SimpleViewport(); view.setDimensions(0, 0, 500, 500); view.setScene(scene); SimpleLayer layer = new SimpleLayer(); layer.setViewport(view); Layer[] layers = { layer }; sceneManager.setLayers(layers, 1); The last line is the interesting part. Notice that the second parameter says how many layers are being passed in from the array. Having multiple layers is as simple as replicating the above code for as many layers as you want. Layers are defined in rendering order, so index 0 is the first layer to be rendered, up to layer n, which is the last rendered.
A simple example of this is the SimpleViewport view1 = new SimpleViewport(); view1.setDimensions(0, 0, 800, 800); view1.setScene(scene1); SimpleViewport view2 = new SimpleViewport(); view2.setDimensions(0, 0, 800, 800); view2.setScene(scene2); SimpleViewport view3 = new SimpleViewport(); view3.setDimensions(0, 0, 800, 800); view3.setScene(scene3); SimpleLayer layer1 = new SimpleLayer(); layer1.setViewport(view1); SimpleLayer layer2 = new SimpleLayer(); layer2.setViewport(view2); SimpleLayer layer3 = new SimpleLayer(); layer3.setViewport(view3); Layer[] layers = { layer1, layer2, layer3 }; sceneManager.setLayers(layers, 3); ObjectLayerAnimation anim = new ObjectLayerAnimation(layer2_group); sceneManager.setApplicationObserver(anim); Each layer is created with a viewport and the geometry is placed as part of it. These are all then collected into an array and passed to the rendering manager. Multiple Viewports in a Layer
For applications that want to have more than a single viewport within a layer,
you make use of a different class. The A composite layer holds onto a collection of viewports. As the layer itself does not have any particular intelligence, all it needs to do is hold viewports. In the composite case, that means just a collection of them, so you have the corresponding add and remove methods. Becuase it is the viewport itself that describes screen location, the order that you add them to the containing layer is inconsequential. The following code creates 4 viewports and adds then to a single layer that is rendered by the application. // Then the viewports. Divide the screen up into 4 viewports SimpleViewport view1 = new SimpleViewport(); view1.setDimensions(0, 0, 400, 400); view1.setScene(scene1); SimpleViewport view2 = new SimpleViewport(); view2.setDimensions(400, 0, 400, 400); view2.setScene(scene2); SimpleViewport view3 = new SimpleViewport(); view3.setDimensions(0, 400, 400, 400); view3.setScene(scene3); SimpleViewport view4 = new SimpleViewport(); view4.setDimensions(400, 400, 400, 400); view4.setScene(scene4); CompositeLayer layer = new CompositeLayer(); layer.addViewport(view1); layer.addViewport(view2); layer.addViewport(view3); layer.addViewport(view4); Layer[] layers = { layer }; sceneManager.setLayers(layers, 1); Note how the pixel sizes all appear to have nice round numbers. Pixels are zero based, so a width of 400 goes from pixel 0 to 399. Pixel 400 is the start of the next area. We don't do any sanity checking of the viewport bounds, so it is perfectly legal to have one viewport overlap another. The rendering order is not guaranteed, so it's best not to do this. If you need those sort of effects, you're better off having several layers, each with their own viewport.
Just because you have multiple viewports, does not mean you are required to have
separate scene graphs for each viewport. The Scene object itself cannot be
shared, but you can share the contents of the scene graph by simply placing a
Layers in a ViewportIf you are running multiple viewports, it may be useful to have individual layers within a viewport. As it has been mentioned before, this allows you to get creative within a single viewport for providing effects such as local user interfaces etc.
In the previous examples we have used a viewport that doesn't have any layers
- it directly takes the scene to be rendered. To allow for multiple layers in
a viewport, the
Setting up a viewport with layers is mostly just a reorganisation of the
techniques you've already seen. The main difference is that there is no need to
specify an addition viewport inside each layer that is rendered in the
viewport. All layers take up the full size of the viewport that they are
contained in. The following code snippet is taken from the
SimpleViewportLayer layer1 = new SimpleViewportLayer(); layer1.setScene(scene1); SimpleViewportLayer layer2 = new SimpleViewportLayer(); layer2.setScene(scene2); SimpleViewportLayer layer3 = new SimpleViewportLayer(); layer3.setScene(scene3); CompositeViewport view = new CompositeViewport(); view.setDimensions(0, 0, 800, 800); view.addViewportLayer(layer1); view.addViewportLayer(layer2); view.addViewportLayer(layer3); SimpleLayer main_layer = new SimpleLayer(); main_layer.setViewport(view); Layer[] layers = { main_layer }; sceneManager.setLayers(layers, 1); Like the main layers, viewport layers use the order that they are added to define the rendering order. The first one added is the rear-most layer, and the last added is at the front. Changing Viewport sizesIf you have played with any of the examples so far, you may have noticed that any time you change the window size, the drawn area did not change. Resizing the window to be bigger left a black section on the right and bottom (we're using grey backgrounds for all of them). The reason for this is that we don't automatically resize the viewport as the containing component changes size. There are many reasons for this design decision, but the principle one is that we wanted to leave as much flexibility to the end user as possible about how they may want to resize the views - especially in applications that want to have multiple viewports in a single layer. However, we do realise that resizing the viewport in response to the canvas size changes is an extremely important capability, so we also designed an abstract system and some convenience classes that take care of most of the behaviour for you. One of the design goals of these convenience classes (and Aviatrix3D in
general) was to separate your code from the underlying window toolkits as much
as possible. Moving from AWT to Swing to SWT should mean absolute minimal
changes for you. To enable this, there is a listener that can be registerd
with your
For further convenience, we also provide a class that will do the viewport
size management for you as well. The class SimpleLayer layer1 = new SimpleLayer(); layer1.setViewport(view1); SimpleLayer layer2 = new SimpleLayer(); layer2.setViewport(view2); SimpleLayer layer3 = new SimpleLayer(); layer3.setViewport(view3); Layer[] layers = { layer1, layer2, layer3 }; sceneManager.setLayers(layers, 3); ViewportResizeManager resize_manager = new ViewportResizeManager(); resize_manager.addManagedViewport(view1); resize_manager.addManagedViewport(view2); resize_manager.addManagedViewport(view3); surface.addGraphicsResizeListener(resize_manager); ResizeLayerUpdater anim = new ResizeLayerUpdater(resize_manager); sceneManager.setApplicationObserver(anim); Inside the layer updater, you have the following code - which should look like a fairly familiar pattern: public class ResizeLayerUpdater implements ApplicationUpdateObserver, NodeUpdateListener { private ViewportResizeManager resizeManager; public ResizeLayerUpdater(ViewportResizeManager resizer) { resizeManager = resizer; } public void updateSceneGraph() { resizeManager.sendResizeUpdates(); } public void appShutdown() { // do nothing } }
You can see this class in action in the
That's all there is to layers. If you want to see all of them running together,
take a look at the example
|
[ Home ]
[ License ]
[ javadoc ]
[ Online Examples ]
[ Download ]
[ j3d.org ] [ Aviatrix3D ] [ Code Repository ] [ Java3D ] [ OpenGL ] [ Books ] [ Contact Us ] Last Updated: $Date: 2010-05-01 04:20:35 -0700 (Sat, 01 May 2010) $ |