C H A P T E R 13 |
M3G is a Scene Graph or Immediate Mode 3D API that supports optional hardware acceleration on mobile devices. Some applications and demos might choose to leverage its 3D abilities in order to deliver a more compelling user experience by integrating 3D special effects with the 2D user interface (for example, a cube transition effect). The main use case revolves around drawing 3D elements within LWUIT applications or using LWUIT drawn widgets in 3D worlds (such as LWUIT Image objects).
Normally M3G is bound directly to the graphics or image object during the standard rendering (painting) process, however, since LWUIT abstracts this process by supplying its own graphics object type, this doesn’t work.
M3G integration into LWUIT is built around a callback mechanism that allows the developer to bind a LWUIT Graphics object to a M3G Graphics3D object. M3G support is designed to work only on devices that support M3G. If your device does not support M3G the LWUIT implementation avoids activating M3G code.
The LWUIT com.sun.lwuit.M3G class provides support for JSR 184. Within this class LWUIT offers an internal interface (M3G.Callback) that must be implemented in order to render the 3D scene. A LWUIT paint method M3G.bind(Graphics) should be invoked in order to bind to M3G (instead of Graphics3D.bind) resulting in a callback invocation containing the appropriate 3D object similar to the example shown below:
class MyComponent extends Component { private M3G.Callback myCallbackInstance = new MyCallback(); .... public void paint(Graphics g) { M3G.getInstance().renderM3G(g, true, 0, myCallbackInstance); // draw some stuff in 2D ... } .... } class MyCallback implements M3G.Callback { .... public void paintM3G(Graphics3D g3d) { g3d.clear(background); g3d.render(world); } ... }
Due to the way in which device 3D rendering is implemented and constraints of hardware acceleration, it is important to render 2D and 3D on their own. LWUIT handles this seamlessly (flushing the 3D/2D pipelines as necessary), however, you must not keep instances of Graphics or Graphics3D and invoke them on a separate thread. Furthermore, the Graphics object must NEVER be used in the paintM3G method and the Graphics3D object must never be used outside of that method. This applies to the existence of the paintM3G method in the stack. For example:
public void paint(Graphics g) { // not allowed to use Graphics3D invokeFromPaint(); } public void invokeFromPaint() { // not allowed to use Graphics3D } public void paintM3G(Graphics3D g3d) { // not allowed to use Graphics invokeFromPaintM3G(); } public void invokeFromPaintM3G() { // not allowed to use Graphics }
The M3G API makes heavy use of an Image2D object which is constructed using the platform native Image object. However, since this image type is encapsulated by LWUIT you must construct M3G Image2D objects using the createImage2D method within M3G.
The normal method of instantiating Image2D objects doesn’t accept LWUIT image objects because they are unrecognized by the M3G implementation.
Notice that currently only standard LWUIT images are supported by M3G. IndexedImage and RGBImage are unsupported in the M3G binding. This might change in future iterations of the API.
Copyright © 2009, Sun Microsystems, Inc. All rights reserved.