|
JSR-184 Public Review Draft - Apr. 30, 2003. | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--javax.microedition.m3d.Graphics3D
A singleton 3D graphics context that can be bound to a rendering target.
All rendering is done through the render
methods in this class,
including the rendering of World objects. There is no other way to draw
anything in this API.
Initialization:
create the Graphics3D instance
set rendering quality hints (optional)
Per frame:
bind a rendering target set the viewport (optional) if not using retained mode clear the color buffer (optional) clear the depth buffer (if used) set up the current camera set up the current lights endif render everything release the target
There are three different render
methods, operating at
different levels of granularity. The first method is for rendering an
entire World. When this method is used, we say that the API operates in
retained mode. The second method is for rendering scene graph
nodes, including Groups. The third method is for rendering an individual
submesh. When the latter two methods are used, the API is said to operate
in immediate mode.
There is a current camera and an array of current lights
in Graphics3D. These are used by the immediate mode rendering methods only.
The retained mode rendering method render(World)
uses the camera
and lights that are specified in the World itself, ignoring the Graphics3D
camera and lights. Instead, render(World)
replaces the
Graphics3D current camera and lights with the active camera and lights in the
rendered World. Note that the number of lights in Graphics3D has a fixed limit,
typically 4 or 8, while a World may contain an arbitrary number of lights. For
this reason, the set of lights in Graphics3D after rendering a World is
partially undefined: they can be any lights that were used in rendering
the World.
Before rendering anything or even clearing the screen, the application must
bind a rendering target to this Graphics3D, using the bindTarget
method. The rendering target can be either a Graphics object or an Image2D. The
Graphics object, in turn, can be associated with a Canvas, a mutable Image, or a
CustomItem. When finished with rendering a frame, the application must release the
rendering target by calling the releaseTarget
method. Implementations
may queue rendering commands and only execute them when the target is released.
Once a rendering target is bound to the Graphics3D, all rendering will end up in
the color buffer of its rendering target until releaseTarget
is called.
The contents of the rendering target, after releasing it, will be equal to what they
were before the target was bound, augmented with any 3D rendering performed while it
was bound.
There can be only one rendering target bound to the Graphics3D at a time. Also, a bound rendering target should not be accessed via any other interface than the host Graphics3D. This is not enforced, but the results are unpredictable otherwise. For example, the following scenarios will result in unpredictable output:
render
method.The contents of the depth buffer are unspecified after bindTarget
,
and they are discarded after releaseTarget
. In order to clear depth
buffer contents (and color buffer contents, if so desired) after binding a
rendering target, the application must call the clear
method,
either explicitly, or implicitly by rendering a World.
The viewport can be positioned freely relative to the rendering target,
without releasing and re-binding the target. The position of the viewport
is specified relative to the origin of the rendering target: for Graphics
targets, this is the origin in effect when calling bindTarget
;
for Image2D targets, the origin is always in the top left corner.
All 3D rendering is clipped to the intersection of the viewport and
the rendering target clip rectangle. That is, rendering operations
(including clear
) will not touch pixels falling outside
of either the viewport or the target clip rectangle. This is illustrated
in the figure below.
For Graphics targets, the clipping rectangle is the MIDP clipping
rectangle that is in effect when calling bindTarget
. Changes
to the clipping rectangle of a bound Graphics object have no effect. For
Image2D targets, the clipping rectangle comprises all pixels in the target
image.
2D translation and clipping are independent of the viewport and projection transformations, as well as rasterization. All other parameters being equal, rendering calls must produce the same pixels (prior to clipping) into the area bounded by the viewport regardless of the position of the viewport or the target clipping rectangle.
In some situations, image quality might be more important for an application than rendering speed or memory usage. Some applications might also want to increase or decrease the image quality based on device capabilities. Some might go so far as to dynamically adjust the quality; for instance, by displaying freeze frames or slow-motion sequences in higher quality.
There are three global options in Graphics3D that allow applications to indicate a preference for higher rendering quality at the expense of slower speed and/or extra memory usage. These are the following:
These settings are merely hints, meaning that implementations may silently ignore them. A request to enable or disable these hints can be made at any time, but implementations may choose not to effect the changes until there is no rendering target bound to the Graphics3D.
Antialiasing is especially useful on displays with relatively large pixels. Dithering and true color rendering are typically used in conjunction with each other, and they are most beneficial on displays with relatively few colors. There are no requirements for how antialiasing or dithering should be implemented, nor is it specified how many bits per pixel are required for "true color".
The reference geometry and fragment pipelines are shown below. The mapping of Appearance components to the pipeline stages is also shown.
Implementations may optimize their operation by doing things in a different order, but only if the result is exactly the same as it would be with the reference pipelines.
It is intentionally unspecified whether a separate back buffer should be allocated for colors or not. Instead, we leave the implementation to decide which mode of operation is the most efficient, or which produces the best quality, according to the dimensions and speed versus quality preferences given by the application. The decision to allocate any back buffer memory must be made upon first binding of each specific rendering target to the Graphics3D object at the latest. In other words, binding a rendering target that has already been bound to the Graphics3D object must be guaranteed not to incur the performance penalty of allocating back buffer memory, provided that the rendering quality hints remain unchanged.
In a practical implementation, it is probably more efficient to render directly to the target color buffer as a general rule. Therefore, it is strongly recommended that implementations not allocate back buffer memory unnecessarily. If a back buffer is required, it can be allocated when the target that requires it is first bound to the Graphics3D object. Note that in real-world applications, the same render target is likely to be repeatedly bound to the Graphics3D object.
As an example of when a back buffer may be desired, consider a
case where the application specifies setDitheringEnable(true)
and subsequently binds a Canvas target. If the MIDP native color format
is of low precision (such as RGB444), the implementation may wish to
render at a higher color precision to a back buffer, then dither down
to the MIDP native color format.
See the General documentation conventions for treatment of null input values, etc.
public class MyCanvas extends Canvas { Graphics3D g3d; World myWorld; int currentTime = 0; public MyCanvas() throws IOException { // Create the singleton Graphics3D instance and enable all // rendering quality enhancements. The rendering quality // hints should only be set between frames, that is, when // there is no rendering target bound to the Graphics3D. g3d = Graphics3D.createGraphics3D(); g3d.setTrueColorEnable(true); g3d.setDitheringEnable(true); g3d.setAntialiasingEnable(true); // Load an entire World. Proper exception handling is omitted // for clarity; see the class description of Loader for a more // elaborate example. Object3D[] objects = Loader.load("http://www.example.com/myscene.m3d"); myWorld = (World) objects[0]; } // The paint method is called by MIDP after the application has issued // a repaint request. We draw a new frame on this Canvas by binding the // current Graphics object as the target, then rendering, and finally // releasing the target. protected void paint(Graphics g) { // Bind our 3D graphics context to the MIDP Graphics object. The // color buffer and depth buffer will have dimensions equal to // this Canvas. The viewport will cover the whole Canvas. g3d.bindTarget(g); // Apply animations. myWorld.animate(currentTime); g3d.render(myWorld); // render a view from the active camera g3d.releaseTarget(); // flush the rendered image currentTime += 50; // assume we can handle 20 frames per second } }
Field Summary | |
static int |
BUF_COLOR
A parameter to clear , specifying that the color buffer
must be cleared according to the settings in the given Background. |
static int |
BUF_DEPTH
A parameter to clear , specifying that the depth buffer
must be cleared. |
Method Summary | |
void |
bindTarget(java.lang.Object target)
Binds the given Graphics or mutable Image2D as the rendering target of this Graphics3D. |
void |
clear(int buffers,
Background background)
Clears the color and/or depth buffer of this Graphics3D. |
static Graphics3D |
createGraphics3D()
Creates a new Graphics3D instance. |
static java.util.Hashtable |
getProperties()
Retrieves implementation specific properties. |
void |
releaseTarget()
Flushes the rendered 3D image to the currently bound target. |
void |
render(Node node,
Transform transform)
Renders the given Sprite, Mesh, or Group node with the given transformation from local coordinates to world coordinates. |
void |
render(VertexBuffer vertices,
IndexBuffer triangles,
Appearance appearance,
Transform transform)
Renders the given submesh with the given transformation from local coordinates to world coordinates. |
void |
render(World world)
Renders an image of world as viewed by the active camera
of that World. |
void |
setAmbientLight(int RGB)
Sets the ambient light intensity. |
void |
setAntialiasingEnable(boolean enable)
Turns the antialiasing hint on or off for subsequent rendering. |
void |
setCamera(Camera camera,
Transform transform)
Sets the Camera to use in subsequent immediate mode rendering. |
void |
setDepthBufferEnable(boolean enable)
Enables or disables the depth buffer for subsequent rendering. |
void |
setDitheringEnable(boolean enable)
Turns the dithering hint on or off for subsequent rendering. |
void |
setLight(int index,
Light light,
Transform transform)
Sets or removes a Light to use in subsequent immediate mode rendering. |
void |
setTrueColorEnable(boolean enable)
Turns the true color hint on or off for subsequent rendering. |
void |
setViewport(int x,
int y,
int width,
int height)
Specifies a rectangular viewport on the currently bound rendering target. |
Methods inherited from class java.lang.Object |
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
public static final int BUF_COLOR
A parameter to clear
, specifying that the color buffer
must be cleared according to the settings in the given Background. The
format and bit depth of the color buffer are implementation defined and
are not known to the application.
public static final int BUF_DEPTH
A parameter to clear
, specifying that the depth buffer
must be cleared.
Method Detail |
public static final Graphics3D createGraphics3D()
Creates a new Graphics3D instance. Since Graphics3D is a singleton, the application may only call this method once. Attempting to call it multiple times is an exception.
The new Graphics3D will be initialized with the following default values:
java.lang.IllegalStateException
- if a Graphics3D instance already existspublic void bindTarget(java.lang.Object target)
Binds the given Graphics or mutable Image2D as the rendering target of this Graphics3D. The type of the Graphics object depends on the Java profile that this specification is implemented on, as follows:
java.awt.Graphics
on profiles supporting AWT;javax.microedition.lcdui.Graphics
on profiles supporting LCDUI;The viewport is set to cover the target clipping rectangle entirely.
target
- the Image2D or Graphics object to receive the rendered image
java.lang.IllegalStateException
- if this Graphics3D already has a rendering target
java.lang.IllegalArgumentException
- if target
is not a mutable Image2D
object or a Graphics object appropriate to the underlying Java profilereleaseTarget()
public void releaseTarget()
Flushes the rendered 3D image to the currently bound target. This
ensures that the 3D image is actually made visible on the target that
was set in bindTarget
. Otherwise, the image may or may
not become visible. See the class description for discussion on the
semantics of mixing 2D rendering with 3D rendering.
java.lang.IllegalStateException
- if this Graphics3D does not have a rendering targetpublic void setViewport(int x, int y, int width, int height)
Specifies a rectangular viewport on the currently bound rendering target. The viewport is the area where the view of the current camera will appear. Any parts of the viewport that lie outside the boundaries of the target clipping rectangle are silently clipped off; however, this must simply discard the pixels without affecting projection. The viewport upper left corner (x, y) is given relative to the upper left corner of the target clipping rectangle.
After bindTarget
, the viewport is set to cover the target
clipping rectangle in full, but nothing more. That is, the upper left corner
of the viewport will be at (0, 0) and its width and height will be equal to
those of the target clipping rectangle.
The viewport mapping transforms vertices from normalized device coordinates (xd, yd, zd) to window coordinates (xw, yw, zw) as follows:
xw = 0.5 × xd × w + ox
yw = 0.5 × yd × h + oy
zw = 0.5 × zd + 0.5
where w and h are the width and height of the viewport, specified in pixels, and (ox, oy) is the center of the viewport, also in pixels. The center of the viewport is obtained from the (x, y) coordinates of the top left corner as follows:
ox = x + (w / 2)
oy = y + (h / 2)
x
- X coordinate of the viewport upper left corner, in pixelsy
- Y coordinate of the viewport upper left corner, in pixelswidth
- width of the viewport, in pixelsheight
- height of the viewport, in pixels
java.lang.IllegalArgumentException
- if width
or height
is negative or zero (note that x
and y
may
have any value)
java.lang.IllegalArgumentException
- if width
or height
exceeds the implementation defined maximumpublic void clear(int buffers, Background background)
Clears the color and/or depth buffer of this Graphics3D. The buffers
to be cleared are specified as an OR mask of BUF_COLOR
and
BUF_DEPTH
. If depth buffering is disabled, the request to
clear it will be silently ignored.
The color buffer is cleared either with a single color or a
background image, as specified in the given Background. If
background
is null, the default background color
(transparent black) is used. The depth buffer is cleared with
the maximum depth value.
buffers
- buffers to clear; an OR mask of BUF_COLOR
and
BUF_DEPTH
background
- background color or image to clear the color buffer with,
or null to clear with transparent black
java.lang.IllegalArgumentException
- if buffers
is not
one of BUF_COLOR
, BUF_DEPTH
, and
BUF_COLOR | BUF_DEPTH
java.lang.IllegalStateException
- if this Graphics3D does not have a rendering targetpublic void render(World world)
Renders an image of world
as viewed by the active camera
of that World. The current camera and lights set in this Graphics3D are
ignored. Contrary to the immediate mode render
variants, the
color and depth buffers are automatically cleared, as per the Background
object of the World. If there is no Background object, the depth buffer is
cleared as usual, but the color buffer is not cleared at all.
The given World must be be self-contained in the sense that there must not be references to nodes outside of that world. Illegal references may arise from transform references in SkinnedMesh or from node alignment. This rule is to avoid ambiguity as to what to consider the "root" coordinate system between separate worlds.
world
- the World to render
java.lang.IllegalStateException
- if this Graphics3D does not have a rendering target
java.lang.IllegalStateException
- if world
has no active camera,
or the active camera is not in world
java.lang.IllegalStateException
- if world
is not self-contained
java.lang.IllegalStateException
- if any Mesh in world
violates
the constraints defined in Mesh, MorphingMesh, SkinnedMesh, VertexBuffer,
or IndexBufferpublic void render(Node node, Transform transform)
Renders the given Sprite, Mesh, or Group node with the given transformation from local coordinates to world coordinates. The transformation of the node is ignored, as well as its alignment to anything but the current camera. Any ancestors of the node are also ignored, including their transformations and all other properties that they may have. In the case of a Group node, its renderable descendants are treated as usual. If there are any Camera or Light nodes among the descendants, they are ignored; the current camera and lights of this Graphics3D are used instead.
The set of nodes to be rendered, which includes the given node and its renderable descendants, must be self-contained in the sense that there must not be references to nodes outside of that set. Illegal references may arise from transform references in SkinnedMesh, or from alignment of any of the descendants (recall that alignment of the root node is ignored). This rule is to avoid ambiguity as to what to consider the "root" coordinate system between separate groups.
This method does not clear the color and depth buffers; the application
must explicitly clear them with the clear
method and/or draw any
background graphics beforehand.
node
- the Sprite, Mesh, or Group to rendertransform
- the transformation from the local coordinate system of
node
to world space, or null to indicate the identity matrix
java.lang.IllegalArgumentException
- if node
is not a Sprite, Mesh, or Group
java.lang.IllegalStateException
- if this Graphics3D does not have a rendering target
java.lang.IllegalStateException
- if this Graphics3D does not have a current camera
java.lang.IllegalStateException
- if node
is not self-contained
java.lang.IllegalStateException
- if any Mesh that is to be rendered violates
the constraints defined in Mesh, MorphingMesh, SkinnedMesh, VertexBuffer,
or IndexBufferpublic void render(VertexBuffer vertices, IndexBuffer triangles, Appearance appearance, Transform transform)
Renders the given submesh with the given transformation from local coordinates
to world coordinates. The composite transformation from object coordinates to
camera space (the modelview transformation) is computed internally by
left-multiplying the given transformation with the inverse of the current camera
transformation (see setCamera
).
Upon rendering the submesh, the vertex positions are transformed with the modelview transformation and the normal vectors with its inverse transpose. If the modelview matrix is not invertible, the results of lighting calculations are undefined. The scope masks of the active Lights are ignored.
vertices
- a VertexBuffer defining the vertex attributestriangles
- an IndexBuffer defining the triangle stripsappearance
- an Appearance defining the surface propertiestransform
- the transformation from the local coordinate system of
vertices
to world space, or null to indicate the identity matrix
java.lang.IllegalStateException
- if this Graphics3D does not have a rendering target
java.lang.IllegalStateException
- if this Graphics3D does not have a current camera
java.lang.IllegalStateException
- if vertices
or triangles
violates the constraints defined in VertexBuffer and IndexBuffer, respectivelypublic void setCamera(Camera camera, Transform transform)
Sets the Camera to use in subsequent immediate mode rendering. The given transformation is from the Camera's local coordinate system to the world space. The transformation is copied in, so any further changes to it will not be reflected in this Graphics3D. The node transformation of the Camera is ignored. If the Camera has any ancestors, they are also ignored.
camera
- the Camera to use in immediate mode renderingtransform
- transformation to world space for the Camera node, or
null to indicate the identity matrixpublic void setLight(int index, Light light, Transform transform)
Sets or removes a Light to use in subsequent immediate mode rendering. The given transformation is from the Light's local coordinate system to the world space. The transformation is copied in, so any further changes to it will not be reflected in this Graphics3D. The node transformation of the Light is ignored. If the Light has any ancestors, they are also ignored. The scope mask of the Light is respected when rendering Nodes. It has no effect when rendering an individual submesh, because submeshes do not have a scope ID.
The number of simultaneous lights supported by the implementation can
be queried with the getProperties
method.
index
- index of the light to set; must be [0, maxLights-1]light
- the Light to set, or null to remove the light at index
transform
- transformation for the Light node, or null to
indicate the identity matrix
java.lang.IllegalArgumentException
- if index
is not within
the range [0, maxLights-1], where maxLights is the maximum number of
simultaneous lights supported by the implementationpublic void setAntialiasingEnable(boolean enable)
Turns the antialiasing hint on or off for subsequent rendering. This method provides applications with a means to indicate a preference for higher rendering quality at the expense of rendering speed and memory usage, or vice versa.
The method of antialiasing is defined by the implementation and is not known to the application. Implementations may also disregard this hint and do antialiasing at their own discretion. For example, antialiasing might be done automatically, at no extra cost, on some devices.
The request to enable or disable antialiasing can be made at any time, but implementations may choose not to effect the change until there is no rendering target bound to the Graphics3D.
enable
- true to turn the antialiasing hint on; false to turn it offpublic void setDitheringEnable(boolean enable)
Turns the dithering hint on or off for subsequent rendering. This method provides applications with a means to indicate a preference for higher rendering quality at the expense of rendering speed and memory usage, or vice versa.
The method of dithering is defined by the implementation and is not known to the application. Implementations may also disregard this hint and do dithering at their own discretion. For example, dithering might not be necessary at all on some devices.
The request to enable or disable dithering can be made at any time, but implementations may choose not to effect the change until there is no rendering target bound to the Graphics3D.
enable
- true to turn dithering on, false to turn it offpublic void setTrueColorEnable(boolean enable)
Turns the true color hint on or off for subsequent rendering. This method provides applications with a means to indicate a preference for higher rendering quality at the expense of rendering speed, or vice versa.
The request to enable or disable true color rendering can be made at any time, but implementations may choose not to effect the change until there is no rendering target bound to the Graphics3D.
enable
- true to turn dithering on, false to turn it offpublic void setDepthBufferEnable(boolean enable)
Enables or disables the depth buffer for subsequent rendering. If the depth buffer is disabled, depth testing and depth writing are implicitly disabled for all objects, regardless of their individual settings. If the depth buffer is enabled, on the other hand, the settings of each individual submesh or sprite are respected.
The format and bit depth of the depth buffer are specific to each implementation and are not known to the application. The contents of the depth buffer are never exposed through the API, so implementations may choose not to use a conventional depth buffer at all. However, all conforming implementations are guaranteed to behave as if they were using an ordinary depth buffer.
Note that the depth buffer can not be turned on or off while a rendering target is bound to the Graphics3D.
enable
- true to enable the depth buffer; false to disable it
java.lang.IllegalStateException
- if this Graphics3D is bound to a rendering targetpublic static final java.util.Hashtable getProperties()
Retrieves implementation specific properties. The properties are stored in a Hashtable that is keyed by String values. The Hashtable will always contain the entries listed in the table below, but there may also be other entries specific to each implementation.
Key (String) Value type Possible values specVersion String "1.0" supportFSAA Boolean true/false supportTrueColor Boolean true/false supportDither Boolean true/false supportMipmap Boolean true/false supportPerspectiveCorrection Boolean true/false maxLights Integer 4 or greater maxViewportDimension Integer 64 or greater maxTextureDimension Integer 64 or greater maxSpriteCropDimension Integer 64 or greater numTextureUnits Integer 2 or greater maxTransformsPerVertex Integer 2 or greater
public void setAmbientLight(int RGB)
Sets the ambient light intensity. The high order byte of the color value is ignored.
RGB
- the new global ambient light in 0x00RRGGBB format
|
JSR-184 Public Review Draft - Apr. 30, 2003. | ||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |