18.2 Threads running a Java 3D application
By now I hope you are curious to know how Java 3D achieves what it does. In this chapter we gallop through some of the implementation details behind the Java 3D API gaining insight into getting the most from Java 3D and maximizing the performance of your applications. This chapter gives you some clues for implementing your own 3D graphics API in Java.
Sun’s Java 3D internal implementation details are all subject to change at any time. The version described here is Java 3D 1.2 running on the Win32 platform.
The implementation of the Java 3D API has undergone considerable revision between the 1.1 and 1.2 versions of the API. About 70 percent of the Java code was rewritten between these two versions! The Java 3D 1.1 architecture was fairly simplistic and could be considered a proof-of-concept implementation of the API.
Version 1.2 moved to a message-based architecture and took tighter control of the various worker threads created by the API implementation. The collision detection thread was removed in 1.2, and collision detection is carried out by the new TimerThread functionality. By explicitly activating the threads in the system, the 1.2 API has removed the free-running threads (behaviors and collision detection) that caused 100 percent CPU utilization in Java 3D 1.1.
As you can see from tables 18.1 through 18.3, a typical Java 3D application contains many threads, some concerned with system behavior, some running the GUI event processing, and some (13) controlling the Java 3D runtime environment. The two ThreadGroups, “main” and “Java 3D,” are subgroups of the top-level “system” ThreadGroup.
The Java 3D threads have the default thread priority of 5, although this can be controlled using the VirtualUniverse.setJ3DThreadPriority method. The priority must fall between Thread.MAX_PRIORITY and Thread.MIN_PRIORITY. The default is Thread.NORM_PRIORITY. The priority of the parent ThreadGroup (Java 3D) cannot be exceeded. Note that unlike nondaemon threads, daemon threads do not have to exit their Runnable’s run method for the JVM to exit.
| Name | Priority | Daemon |
|---|---|---|
| Reference Handler | 10 | Yes |
| Finalizer | 8 | Yes |
| Signal Dispatcher | 10 | Yes |
| Name | Priority | Daemon |
|---|---|---|
| Main | 5 | No |
| AWT-EventQueue-0 | 6 | No |
| SunToolkit.PostEventQueue-0 | 5 | No |
| AWT-Windows | 5 | No |
| Image Fetcher 1 | 8 | No |
| Image Fetcher 0 | 8 | No |
| Name | Priority | Daemon |
|---|---|---|
| J3D-MasterControl | 5 | No |
| J3D-RenderingAttributesStructureUpdateThread | 5 | No |
| J3D-TimerThread | 5 | No |
| J3D-BehaviorStructureUpdateThread-1 | 5 | No |
| J3D-GeometryStructureUpdateThread-1 | 5 | No |
| J3D-SoundStructureUpdateThread-1 | 5 | No |
| J3D-RenderingEnvironmentStructureUpdateThread-1 | 5 | No |
| J3D-TransformStructureUpdateThread-1 | 5 | No |
| J3D-BehaviorScheduler-1 | 5 | No |
| J3D-RenderStructureUpdateThread-1 | 5 | No |
| J3D-SoundSchedulerUpdateThread-1 | 5 | No |
| J3D-InputDeviceScheduler-1 | 5 | No |
| J3D-Renderer-1 | 5 | No |
The Java 3D implementation is heavily multithreaded. Typically each thread controls access to a particular data structure. The threads use the MasterControl thread to periodically synchronize and exchange notifications and messages across threads. Each thread maintains a subclass of the J3dStructure member, which contains the messages to be processed by the thread. The
Once a message is posted to a thread by the MasterControl thread, the receiving thread is marked as having work to do and scheduled for activation. See the discussion of the MasterControl class for details of the message dispatch and processing mechanism.
Most threads are associated with an instance of a VirtualUniverse (threads with the -1 suffix), while the MasterControl, RenderingAttributesStructureUpdateThread, and TimerThread are systemwide and maintain data structures that apply across all VirtualUniverse instances.
The multithreaded nature of Java 3D allows it to leverage multiple CPUs if available; however, it does make synchronizing certain operations difficult or impossible.
As illustrated in figure 18.1 a Windows Java 3D application creates five threads above normal priority and three Time Critical threads. This will cause other applications running simultaneously to experience a dramatic slowdown when the Java 3D application is in the foreground.
The MasterControl class is Java 3D’s central message dispatch and thread scheduling mechanism. The MasterControl object is a static member of the VirtualUniverse class, and is initialized by a static initializer on the VirtualUniverse class. All instances of the VirtualUniverse class therefore share the same MasterControl instance.
The first time a message is posted to the MasterControl class, it creates the MasterControlThread. The MasterControlThread runs the main message-processing loop for the MasterControl class.

| Master Root Thread Group Name: Java3D Thread Name: J3D-MasterControl |
class MasterControlThread extends Thread{ MasterControlThread(ThreadGroup threadgroup) { super(threadgroup, "J3D-MasterControl"); VirtualUniverse.mc.createMCThreads(); start(); } public void run() { do while(VirtualUniverse.mc.running) { VirtualUniverse.mc.doWork(); Thread.yield(); } while(!VirtualUniverse.mc.mcThreadDone()); }}![]()
The constructor for the MasterControl class loads the J3D.DLL native DLL and reads the Java 3D system properties (see table 18.4).
The MasterControl class is a message exchange mechanism between the various subsystems that compose the Java 3D runtime. The MasterControl thread maintains five UnorderList members, each containing Java 3D worker threads.
stateWorkThreads:RenderingAttributesStructure calls updateMirrorObject on the NodeComponentRetained passed with the message.GeometryStructure maintains a binary hash tree of GeometryAtom objects and Groups. Maintains the wakeupOnCollisionEntry, Exit, and Movement lists.BehaviorStructure maintains a list of behaviors and marks them for activation.RenderingEnvironmentStructure maintains a list of the lights, fog, alternate appearances, clipping regions, and backgrounds to be used for each RenderAtom.SoundStructure maintains a list of sounds and soundscapes and schedules them for activation with the View’s SoundScheduler.BehaviorScheduler, for all VirtualUniverse instances, maintains a list of BillBoard behaviors and behaviors in the system and calls the processStimulus method on each if marked for activation.Inputdevicescheduler maintains lists of nonblocking and blocking input devices and calls the pollAndProcessInput method on the nonblocking devices. A new thread is created to handle the input from each blocking InputDevice.RenderBin, for each View, maintains lists of RenderAtoms that describe rendering operations to be performed. The RenderBin implements methods such as renderOpaque, renderBackground, renderOrdered, renderTransparent, which are called by the Render class.SoundScheduler, for each View, maintains a list of SoundSchedulerAtoms and marks each for activation. The render method iterates the scheduled SoundSchedulerAtoms and calls the start method on each.renderWorkThreads:Renderer for each Canvas3D’s Screen3D. The Render class runs the main Java 3D rendering loop by calling methods on the Canvas3D class and processing the RenderBin for the Canvas3D’s View.requestRenderWorkThreads:Renderer for each Screen3D in the device render map.renderThreadData:Renderer for each Screen3D for each View, including offscreen Renderers.inputDeviceThreads:Inputdevicescheduler.Each UnorderList member contains an array of J3dThreadData objects, containing a J3dThread member and additional scheduling information.
The MasterControl.doWork method (invoked by the MasterControlThread.run method) runs in two phases. The first phase checks for any pending messages to be executed and returns if there is nothing to execute. The second phase runs the threads under the control of the MasterControl class.
void doWork() { runMonitor( CHECK_FOR_WORK, null, null, null, null); if(pendingRequest) handlePendingRequest(); if(!running) return; if(threadListsChanged) updateWorkThreads(); updateTimeValues(); View aview[] = (View[])views.toArray(false); for(int i = views.size() - 1; i >= 0; i--) if(aview[i].active) aview[i].updateViewCache(); runMonitor( RUN_THREADS, stateWorkThreads, renderWorkThreads, requestRenderWorkThreads, null); if(renderOnceList.size() > 0) clearRenderOnceList(); }The actual runMonitor method is fairly complex, and it seems to perform the four functions shown in table 18.4, depending on the value of the first argument.
| Identifier | Index | Purpose |
|---|---|---|
| CHECK_FOR_WORK | 0 | Evaluates each thread and set the MasterControlThread to wait if none of the threads needs to be processed. |
| SET_WORK | 1 | Calls notify() on the MasterControlThread. |
| RUN_THREADS | 2 | Iterates through all the J3dThreadData under the control of the MasterControl. The notify() method is called on each thread associated with each J3dThreadData object. |
| SET_WORK_FOR_REQUEST_RENDERER | 5 | Sets the requestRenderWorkToDo member to true and calls notify on the MasterControl thread. |
The other arguments are (in order): the array of State Work Threads, the array of Render Work Threads, and the array of Request Render Work Threads. As you can see in the following pseudocode, Java 3D has the ability to call the doWork method on each worker thread directly. This enables Java 3D to perform the work of multiple threads within a single thread.
For all Render Work Threads If the Thread needs to be run (J3dThreadData member), Check whether the View should be rendered based on its Minimum Frame Cycle Time Update the OrientatedShape3Ds in each View If specified lock the geometry from updates, If the CPU limit is 1, call the doWork method of the J3dThreadData’s J3dThread directly Otherwise call the runMonitor method (NOTIFY) to notify the thread If specified release the lock on the geometry, If specified, grab the current time and put it into the View’s RenderBinNext Rendering ThreadIf specified, wait for all Rendering threads to completeFor all State Work Threads If the CPU limit is 1, call the doWork method of the J3dThreadData’s J3dThread directly Otherwise call the runMonitor method (NOTIFY) to notify the threadNext State ThreadIf specified, wait for all State threads to completeFor all Request Render Work Threads If the CPU limit is 1, call the doWork method of the J3dThreadData’s J3dThread directly Otherwise call the runMonitor method (NOTIFY) to notify the threadNext State ThreadIf specified, wait for all State threads to completeUpdate the View Frame Timing ValuesUpdate all the Mirror Objects registered with the MasterControlWait for Request Rendering to completeUpdate the frame timestamps for each rendered ViewJava 3D communicates between its various worker threads using a message dispatch mechanism. Messages are instances of the J3dMessage class. Each message contains an identifier and a target VirtualUniverse as well as up to five parameters for the message (generic Objects). Certainly not the most OO of designs—in fact it reminds me of the WPARAM and LPARAM attributes on the MESSAGE structure used to propagate messages under Windows.
The message identifiers are defined in table 18.5.
| Message | Identifier |
|---|---|
| INSERT_NODES | 0 |
| REMOVE_NODES | 1 |
| RUN | 2 |
| TRANSFORM_CHANGED | 3 |
| UPDATE_VIEW | 4 |
| STOP_THREAD | 5 |
| COLORINGATTRIBUTES_CHANGED | 6 |
| LINEATTRIBUTES_CHANGED | 7 |
| POINTATTRIBUTES_CHANGED | 8 |
| POLYGONATTRIBUTES_CHANGED | 9 |
| RENDERINGATTRIBUTES_CHANGED | 10 |
| TEXTUREATTRIBUTES_CHANGED | 11 |
| TRANSPARENCYATTRIBUTES_CHANGED | 12 |
| MATERIAL_CHANGED | 13 |
| TEXCOORDGENERATION_CHANGED | 14 |
| TEXTURE_CHANGED | 15 |
| MORPH_CHANGED | 16 |
| GEOMETRY_CHANGED | 17 |
| APPEARANCE_CHANGED | 18 |
| LIGHT_CHANGED | 19 |
| BACKGROUND_CHANGED | 20 |
| CLIP_CHANGED | 21 |
| FOG_CHANGED | 22 |
| BOUNDINGLEAF_CHANGED | 23 |
| SHAPE3D_CHANGED | 24 |
| TEXT3D_TRANSFORM_CHANGED | 25 |
| TEXT3D_DATA_CHANGED | 26 |
| SWITCH_CHANGED | 27 |
| COND_MET | 28 |
| BEHAVIOR_ENABLE | 29 |
| BEHAVIOR_DISABLE | 30 |
| INSERT_RENDERATOMS | 31 |
| ORDERED_GROUP_INSERTED | 32 |
| ORDERED_GROUP_REMOVED | 33 |
| COLLISION_BOUND_CHANGED | 34 |
| REGION_BOUND_CHANGED | 35 |
| MODELCLIP_CHANGED | 36 |
| BOUNDS_AUTO_COMPUTE_CHANGED | 37 |
| SOUND_ATTRIB_CHANGED | 38 |
| AURALATTRIBUTES_CHANGED | 39 |
| SOUNDSCAPE_CHANGED | 40 |
| ALTERNATEAPPEARANCE_CHANGED | 41 |
| RENDER_OFFSCREEN | 42 |
| RENDER_RETAINED | 43 |
| RENDER_IMMEDIATE | 44 |
| SOUND_STATE_CHANGED | 45 |
| ORIENTEDSHAPE3D_CHANGED | 46 |
| TEXTURE_UNIT_STATE_CHANGED | 47 |
| UPDATE_VIEWPLATFORM | 48 |
| BEHAVIOR_ACTIVATE | 49 |
The type member refers to one of the predefined message types from the table.
Each J3dMessage maintains a reference count so that it can clear the references to its arguments when its reference count reaches zero. Messages with a reference count of zero are placed back into a list of free messages, for subsequent reuse. This message instance cache minimizes the number of message objects created by the Java 3D at runtime in an attempt to prevent excessive garbage collection. Interestingly this type of Object pooling is no longer favored as Sun’s HotSpot compiler performs object pooling and reuse automatically.
The MasterControl method getMessage will either return a message from the free list if one is available or allocate a new J3dMessage instance, which will get added to the free list once its reference count reaches zero. The J3dMessage also maintains a reference to a View object and contains a thread identifier (bit-field) that identifies the threads that should receive the message, as shown in table 18.6.
| Identifier | Java 3D Thread | Java 3D Thread Name |
|---|---|---|
| 0x1 | BEHAVIOR_SCHEDULER | J3D-BehaviorScheduler-INSTANCE# |
| 0x2 | SOUND_SCHEDULER | J3D-SoundSchedulerUpdateThread-INSTANCE# |
| 0x4 | INPUT_DEVICE_SCHEDULER | J3D-InputDeviceScheduler-INSTANCE# |
| 0x10 | RENDER_THREAD | J3D-Renderer-INSTANCE# |
| 0x40 | UPDATE_GEOMETRY | J3D-GeometryStructureUpdateThread-INSTANCE# |
| 0x80 | UPDATE_RENDER | J3D-RenderStructureUpdateThread-INSTANCE# |
| 0x100 | UPDATE_BEHAVIOR | J3D-BehaviorStructureUpdateThread-INSTANCE# |
| 0x200 | UPDATE_SOUND | J3D-SoundStructureUpdateThread-INSTANCE# |
| 0x400 | UPDATE_RENDERING_ATTRIBUTES | J3D-RenderingAttributesStructureUpdateThread |
| 0x1000 | UPDATE_RENDERING_ENVIRONMENT | J3D-RenderingEnvironmentStructureUpdateThread-INSTANCE# |
| 0x2000 | UPDATE_TRANSFORM | J3D-TransformStructureUpdateThread-INSTANCE# |
The sendMessage method updates appropriate message queue data structures based on the value of the thread identifier (table 18.7).
| Thread Identifier | Effect |
|---|---|
| UPDATE_RENDERING_ATTRIBUTES | Appends the message to the global (across VirtualUniverses) RenderingAttributesStructure |
| UPDATE_GEOMETRY | Appends the message to the VirtualUniverses’ GeometryStructure |
| UPDATE_TRANSFORM | Appends the message to the VirtualUniverses’ TransformStructure |
| UPDATE_BEHAVIOR | Appends the message to the VirtualUniverses’ BehaviorStructure |
| UPDATE_SOUND | Appends the message to the VirtualUniverses’ SoundStructure |
| UPDATE_RENDERING_ENVIRONMENT | Appends the message to the VirtualUniverses’ RenderingEnvironmentStructure |
| SOUND_SCHEDULER | Appends the message to the View’s SoundScheduler (if a View is not specified, the message is added to the SoundScheduler for all registered Views) |
| UPDATE_RENDER | Appends the message to the View’s RenderBin (if a View is not specified, the message is added to the RenderBin for all registered Views that are attached to the specified VirtualUniverse) |
Java 3D reads a number of system properties, some documented and some internal. A list of these properties is also maintained on the J3D.ORG site at http://www.j3d.org/implementation/properties.html.
Table 18.8 lists the system properties that are referenced in the Java code of the Java 3D distribution. Many more system properties are available which are specific to the OpenGL or DirectX versions of Java 3D. Please refer to the J3D.ORG website for the latest information on these properties.
| Name | Default | Purpose |
|---|---|---|
| java.version | None | Check to see whether Java 3D is running under SDK 1.3 |
| j3d.sharedctx | False | Use shared display contexts when rendering |
| j3d.renderLock | True | Disable the render lock |
| j3d.g2ddrawpixel | True | |
| j3d.threadLimit | Processors + 1 | Number of concurrent threads that Java 3D can use. |
| j3d.deviceSampleTime | 0 | Input device sampling time. |
| j3d.debug | False | Switch on Java 3D debug output. Currently only used by the MasterController. |
| Javax.media.j3d.compileStats | None | Output scenegraph compilation statistics |
| Javax.media.j3d.compileVerbose | None | Output verbose message when compiling scenegraph |
The BehaviorScheduler is responsible for activating all the Behaviors registered with a VirtualUniverse. For active and activated Behaviors, the processStimulus method is called on the Behavior.
The BehaviorScheduler integrates tightly with the BehaviorStructure class, which maintains lists of all the Behaviors that have been created for a VirtualUniverse instance. The BehaviorStructure also contains much of the logic to determine when a Behavior has been activated, whether due to an AWT event, Behavior ID being posted, Bounds intersection, Sensor condition, or a Transform3D change.
The InputDeviceScheduler maintains lists of nonblocking and blocking Java 3D InputDevices. It calls pollAndProcessInput on each nonblocking InputDevice.
Name: J3D-Renderer-INSTANCE#
A Renderer instance is created for each screen device that is to be rendered into. The Renderer instances are kept in a static Hashtable in the Screen3D class. The Renderer calls into the Canvas3D instances (second JThreadData argument) that are available for rendering. If a device supports swapping, there may be multiple Canvas3Ds in the second argument.
Renderer uses the first argument, which is one of the GraphicsContext3D rendering commands (see table 18.9). The Renderer extracts the messages from the RendererStructure and calls methods on the GraphicsContext3D as appropriate.
The complex Renderer doWork method implements the main Java 3D rendering loop. It sets up the projection matrices, handles stereoscopic rendering, and performs the main rendering loop; specifically, it:
preRender on the Canvas3D
renderField on the Canvas3D
postRender on the Canvas3D
Table 18.9 lists the rendering commands that are used along with a RendererStructure instance to determine which methods on the GraphicsContext3D need to be invoked to execute a given command.
| Command | Index |
|---|---|
| CLEAR | 0 |
| DRAW | 1 |
| SWAP | 2 |
| READ_RASTER | 3 |
| SET_APPEARANCE | 4 |
| SET_BACKGROUND | 5 |
| SET_FOG | 6 |
| SET_LIGHT | 7 |
| INSERT_LIGHT | 8 |
| REMOVE_LIGHT | 9 |
| ADD_LIGHT | 10 |
| SET_HI_RES | 11 |
| SET_MODEL_TRANSFORM | 12 |
| MULTIPLY_MODEL_TRANSFORM | 13 |
| SET_SOUND | 14 |
| INSERT_SOUND | 15 |
| REMOVE_SOUND | 16 |
| ADD_SOUND | 17 |
| SET_AURAL_ATTRIBUTES | 18 |
| SET_BUFFER_OVERRIDE | 19 |
| SET_FRONT_BUFFER_RENDERING | 20 |
| SET_STEREO_MODE | 21 |
| FLUSH | 22 |
| FLUSH2D | 23 |
| SET_MODELCLIP | 24 |
RenderAtoms are self-contained rendering units that can be passed to the underlying rendering engine. The RenderAtom contains lights, fog, model clipping information, an Appearance, and a model transformation matrix. RenderAtoms can be linked using double linked-list RenderAtom members within the RenderAtom class.
Higher level rendering operations are described using the RenderMolecule class. In addition to maintaining a list of RenderAtoms, RenderMolecules are able to remove redundant changes in Appearance between consecutive RenderAtoms. In this way, the number of Appearance state changes (Appearance, Material, Transparency, etc.) performed by the underlying rendering engine is minimized.
The StructureUpdateThread is a J3dThread that can be attached to a J3dStructure object to perform message processing. The StructureUpdateThread instances are:
- J3D-GeometryStructureUpdateThread
- J3D-RenderStructureUpdateThread
- J3D-BehaviorStructureUpdateThread
- J3D-SoundStructureUpdateThread
- J3D-RenderingAttributesStructureUpdateThread
- J3D-RenderingEnvironmentStructureUpdateThread
- J3D-TransformStructureUpdateThread
- J3D-SoundSchedulerUpdateThread
The StructureUpdateThread is attached to an instance of a J3dStructure object, and its doWork method calls the processMessages method on the J3dStructure. The various classes derived from J3dStructure (such as SoundStructure) implement structure specific message execution.
The J3D-TimerThread manages:
WakeupOnElapsedTime objects, stored in a WakeupOnElaspsedTimeHeap (sorted, resizable array)
InputDeviceScheduler (sampling time loaded from System property)
SoundScheduler (WakeupOnElapsedTime every 2 minutes, by default)
The TimerThread will call the setTriggered method on each WakeupOnElapsedTime as appropriate.
SceneGraphObject is the base class for all the objects that can be added to a Java 3D scenegraph. It includes a number of interesting capabilities and defines some general architectural principals for Java 3D (such as capability bits and the retained delegate class pattern). The attributes of the SceneGraphObject class are described in more detail next.
A BitSet is an object that contains the capability bits that have been set on the SceneGraphObject.
The retained field holds the private Java 3D implementation object for this SceneGraphObject. The SceneGraphObjectRetained maintains a reference to its source object and implements several setLive methods that can be overridden to respond in a Node specific manner. By having an internal delegate class separate from the public implementation class defined by the specification Sun has more leeway in modifying the implementation without breaking the API or exposing protected or package level access to methods or fields.
This field is true if this node has been compiled.
This field is true if this node has been attached to a live scenegraph.
private boolean liveOrCompiled
This field is true if this node has been attached to a live scenegraph or has been compiled.
This field holds a reference to the User Data object for this scenegraph node.
Some ScenegraphObjects have a Hashtable of NodeComponents associated with them.
Table 18.10 contains a list of Node types and their identifiers.
| Name | Identifier | Name | Identifier |
|---|---|---|---|
| BACKGROUND | 1 | LINK | 9 |
| CLIP | 2 | MORPH | 10 |
| LINEARFOG | 3 | SHAPE | 11 |
| EXPONENTIALFOG | 4 | BACKGROUNDSOUND | 12 |
| AMBIENTLIGHT | 5 | POINTSOUND | 13 |
| DIRECTIONALLIGHT | 6 | CONESOUND | 14 |
| POINTLIGHT | 7 | SOUNDSCAPE | 15 |
| SPOTLIGHT | 8 | VIEWPLATFORM | 16 |
| BEHAVIOR | 17 | GROUP | 23 |
| SWITCH | 18 | TRANSFORMGROUP | 24 |
| BRANCHGROUP | 19 | BOUNDINGLEAF | 25 |
| ORDEREDGROUP | 20 | MODELCLIP | 26 |
| DECALGROUP | 21 | ALTERNATEAPPEARANCE | 27 |
| SHAREDGROUP | 22 | ORIENTEDSHAPE3D | 28 |
Read from ExceptionStrings.properties (inside J3DCORE.JAR).
Appearance0=Appearance: no capability to set materialAppearance1=Appearance: no capability to get materialAppearance2=Appearance: no capability to set textureAppearance3=Appearance: no capability to get textureAppearance4=Appearance: no capability to set textureAttributesAppearance5=Appearance: no capability to get textureAttributesAnd so forth…
The native methods within the Java 3D implementation are packaged within J3D.DLL (for Windows) and called using JNI from the Java code. The native code implements a procedural API for both OpenGL and DirectX rendering.
There are many programming tools that can list the signatures of the methods exported from a Windows DLL. The native method listings which follow are useful in that they not only expose where Java 3D calls down into native code but they also provide a blueprint for how an ambitious programmer might patch or hook a native DLL to implement an alternative rendering scheme or produce debugging output.
The following lists are sorted by ordinal (the numeric index of an exported method within a DLL) and arranged by Java 3D class. Prepend java_javax_media_j3d to the names in the following lists. For example J3D.DLL exports a method called java_javax_media_j3d_Canvas3D_callDisplayList which implements the method callDisplayList which was declared as native within the Canvad3D class.
_Canvas3D_accum@16 _Canvas3D_accumReturn@12 _Canvas3D_callDisplayList@20 _Canvas3D_clear@28 _Canvas3D_clearAccum@28 _Canvas3D_composite@40 _Canvas3D_createContext@28 _Canvas3D_createOffScreenBuffer@28 _Canvas3D_createQueryContext@24 _Canvas3D_ctxUpdateEyeLightingEnable@16 _Canvas3D_decal1stChildSetup@12 _Canvas3D_decalNthChildSetup@12 _Canvas3D_decalReset@16 _Canvas3D_destroyContext@20 _Canvas3D_destroyOffScreenBuffer@20 _Canvas3D_disableFog@12 _Canvas3D_disableModelClip@12 _Canvas3D_endDisplayList@12 _Canvas3D_freeDisplayList@16 _Canvas3D_freeTexture@16 _Canvas3D_getNumCtxLights@12 _Canvas3D_getTextureColorTableSize@12 _Canvas3D_getTextureUnitCount@12 _Canvas3D_newDisplayList@16 _Canvas3D_readOffScreenBuffer@24 _Canvas3D_resetColoringAttributes@32 _Canvas3D_resetLineAttributes@12 _Canvas3D_resetPointAttributes@12 _Canvas3D_resetPolygonAttributes@12 _Canvas3D_resetRenderingAttributes@20 _Canvas3D_resetTexCoordGeneration@12 _Canvas3D_resetTextureAttributes@12 _Canvas3D_resetTextureNative@16 _Canvas3D_resetTransparency@24 _Canvas3D_setBlendFunc@20 _Canvas3D_setDepthBufferWriteEnable@16 _Canvas3D_setDepthFunc@16 _Canvas3D_setFogEnableFlag@16 _Canvas3D_setLightEnables@24 _Canvas3D_setLightingEnable@16 _Canvas3D_setModelViewMatrix@20 _Canvas3D_setProjectionMatrix@16 _Canvas3D_setRenderMode@20 _Canvas3D_setSceneAmbient@24 _Canvas3D_setViewport@28 _Canvas3D_swapBuffers@20 _Canvas3D_syncRender@16 _Canvas3D_texturemapping@48 _Canvas3D_updateMaterial@28 _Canvas3D_useCtx@20 _Canvas3D_useSharedCtx@8
_ColoringAttributesRetained_updateNative@48
_CompressedGeometryRetained_decompressByRef@12 _CompressedGeometryRetained_decompressHW@20 _CompressedGeometryRetained_execute@40
_DirectionalLightRetained_updateLight@40
_ExponentialFogRetained_update@28
_GeometryArrayRetained_buildGA@64 _GeometryArrayRetained_defineByteColorPointer@44 _GeometryArrayRetained_defineDoubleVertexPointer@20 _GeometryArrayRetained_defineFloatColorPointer@44 _GeometryArrayRetained_defineFloatVertexPointer@20 _GeometryArrayRetained_defineNormalPointer@20 _GeometryArrayRetained_defineTexCoordPointer@28 _GeometryArrayRetained_disableGlobalAlpha@24 _GeometryArrayRetained_execute@76 _GeometryArrayRetained_executeInterLeaved@72 _GeometryArrayRetained_executeVA@32 _GeometryArrayRetained_globalAlphaSUN@8 _GeometryArrayRetained_setVertexFormat@20
_GraphicsContext3D_readRasterNative@48
_LineAttributesRetained_updateNative@32
_LinearFogRetained_update@40
_MasterControl_getMaximumLights@8 _MasterControl_getNumberOfProcessor@8 _MasterControl_getThreadConcurrency@8 _MasterControl_initializeJ3D@8 _MasterControl_setThreadConcurrency@12
_MaterialRetained_updateNative@84
_ModelClipRetained_update@52
_NativeConfigTemplate3D_choosePixelFormat@16 _NativeConfigTemplate3D_isDoubleBufferAvailable@24 _NativeConfigTemplate3D_isSceneAntialiasingAvailable@24 _NativeConfigTemplate3D_isStereoAvailable@24
_NativeWSInfo_subclass@12
_PointAttributesRetained_updateNative@20
_PointLightRetained_updateLight@52
_PolygonAttributesRetained_updateNative@32
_RasterRetained_execute@56
_Renderer_freeContext@16
_RenderingAttributesRetained_updateNative@48
_Screen3D_getDisplayParameters@24
_SpotLightRetained_updateLight@72
_TexCoordGenerationRetained_updateNative@76
_Texture3DRetained_bindTexture@20 _Texture3DRetained_updateTextureFields@52 _Texture3DRetained_updateTextureImage@44
_TextureAttributesRetained_updateNative@44 _TextureAttributesRetained_updateTextureColorTableNative@
_TextureRetained_bindTexture@20 _TextureRetained_updateTextureFields@48 _TextureRetained_updateTextureImage@40 _TextureRetained_updateTextureSubImage@44
_TextureUnitStateRetained_updateTextureUnitState@20
_Texture_freeTexture@16
_TransparencyAttributesRetained_updateNative@40
The J3D.DLL Windows library of course also imports methods from other Windows libraries. The list that follows describes the methods that the J3D.DLL library relies upon from other Windows libraries. This information is not particularly relevant except for the imports from OPENGL32.DLL (which is the standard OpenGL library on Windows). By looking at these imports you can see exactly which OpenGL functions the Sun Java 3D requires and uses.
GetLastError GetSystemInfo LCMapStringW RtlUnwind LCMapStringA CloseHandle SetFilePointer SetStdHandle LoadLibraryA SetEnvironmentVariableA GetACP CompareStringW GetOEMCP GetCPInfo CompareStringA GetStringTypeA MultiByteToWideChar GetStringTypeW InterlockedIncrement InterlockedDecrement FlushFileBuffers GetEnvironmentStringsW GetEnvironmentStrings WriteFile FreeEnvironmentStringsA GetModuleFileNameA FreeEnvironmentStringsW GetModuleHandleA GetProcAddress WideCharToMultiByte TlsGetValue SetLastError TlsAlloc TlsSetValue TlsFree HeapReAlloc GetCurrentThreadId VirtualFree HeapCreate VirtualAlloc HeapAlloc GetStartupInfoA HeapDestroy GetStdHandle SetHandleCount GetFileType DeleteCriticalSection InitializeCriticalSection GetCommandLineA HeapFree GetVersion EnterCriticalSection GetCurrentProcess LeaveCriticalSection TerminateProces FormatMessageA ExitProcess
GetSystemMetrics CallWindowProcA SetWindowLongA
ChoosePixelFormat SwapBuffers CreateDCA DeleteObject DescribePixelFormat CreateCompatibleDC SetPixelFormat CreateDIBSection SelectObject DeleteDC
glLogicOp glAlphaFunc glPolygonMode glLightModelfv glPolygonOffset glViewport glLineWidth glMultMatrixd glPointSize glTexGenfv glTexGeni glHint glCullFace glFogfv glPopAttrib glLoadIdentity glPushAttrib glMaterialfv glPolygonStipple glShadeModel glTexParameterfv glTexSubImage2D glStencilOp glStencilFunc glClearStencil glDepthFunc glLightf glLightfv glClipPlane glFogi GlColor4fv glFogf glNormal3fv glTexCoord3fv glColor3fv glTexCoord2fv glNormalPointer glVertex3fv glInterleavedArrays glEnableClientState glColorPointer glVertexPointer glDrawArrays glTexCoordPointer glDisableClientState glDeleteTextures glReadPixels wglGetProcAddress glEndList glDeleteLists glCallList GlFlush glNewList glFinish glDrawBuffer glAccum glClearAccum glBindTexture glClearColor glPixelStorei GlOrtho glTexParameterf glTexEnvf glTexCoord2f glTexImage2D glBegin glGetBooleanv glVertex2f glEnd glBlendFunc glIsEnabled glDisable glRasterPos3f glMatrixMode glLoadMatrixd glDepthMask glPixelZoom glDrawPixels wglShareLists glClear glGetIntegerv glReadBuffer glEnable glColorMaterial wglMakeCurrent wglDeleteContext wglCreateContext glTexEnvi glGetString glTexEnvfv glLightModeli glLineStipple
I hope this quick summary of Sun’s Java 3D implementation has given you an appreciation for how it works and has piqued your interest. Poking around, using fairly simple tools and a little guesswork you can learn a lot–either purely for education or to help performance tune or debug your Java 3D applications.
One of the criticisms of Java 3D has been the lack of information on the implementation of the API. Parts of the Java 3D Specification are vague and the semantics of how changes to the scenegraph are propagated across the runtime, synchronized, and rendered are largely undocumented. I hope this chapter will spur on others at Sun, or elsewhere, to further document some of these more advanced aspects of the implementation.
Since this is the last chapter, I say well done! I’m sure it’s been a hard slog, especially if you are new to Java 3D, but I hope it has been worth it. Don’t hesitate to contact me through the Manning Authors Online forum, or we may run into each other on Sun’s Java 3D email list. May all your capability bits be set correctly!