aboutsummaryrefslogtreecommitdiffstats
path: root/src/javax/media/j3d/Canvas3D.java
diff options
context:
space:
mode:
authorJulien Gouesse <[email protected]>2015-11-28 15:11:48 +0100
committerJulien Gouesse <[email protected]>2015-11-28 15:11:48 +0100
commitdbc98deea1884e44da2c74d6ea807253cdefa693 (patch)
tree29c3ee7dea82d7dd773d81f33f645dde67e43a17 /src/javax/media/j3d/Canvas3D.java
parent2c99f1329dc55bd496bce91b9aba956ecba3c67e (diff)
Relocate package prefix to org.jogamp.java3d
Diffstat (limited to 'src/javax/media/j3d/Canvas3D.java')
-rw-r--r--src/javax/media/j3d/Canvas3D.java4951
1 files changed, 0 insertions, 4951 deletions
diff --git a/src/javax/media/j3d/Canvas3D.java b/src/javax/media/j3d/Canvas3D.java
deleted file mode 100644
index 080bd18..0000000
--- a/src/javax/media/j3d/Canvas3D.java
+++ /dev/null
@@ -1,4951 +0,0 @@
-/*
- * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-package javax.media.j3d;
-
-import java.awt.AWTEvent;
-import java.awt.Canvas;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.Frame;
-import java.awt.Graphics;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.GraphicsEnvironment;
-import java.awt.IllegalComponentStateException;
-import java.awt.Point;
-import java.awt.Window;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.Map;
-
-import javax.vecmath.Color3f;
-import javax.vecmath.Point2d;
-import javax.vecmath.Point3d;
-import javax.vecmath.Vector4d;
-
-
-/**
- * The Canvas3D class provides a drawing canvas for 3D rendering. It
- * is used either for on-screen rendering or off-screen rendering.
- * Canvas3D is an extension of the AWT Canvas class that users may
- * further subclass to implement additional functionality.
- * <p>
- * The Canvas3D object extends the Canvas object to include
- * 3D-related information such as the size of the canvas in pixels,
- * the Canvas3D's location, also in pixels, within a Screen3D object,
- * and whether or not the canvas has stereo enabled.
- * <p>
- * Because all Canvas3D objects contain a
- * reference to a Screen3D object and because Screen3D objects define
- * the size of a pixel in physical units, Java 3D can convert a Canvas3D
- * size in pixels to a physical world size in meters. It can also
- * determine the Canvas3D's position and orientation in the
- * physical world.
- * <p>
- * <b>On-screen Rendering vs. Off-screen Rendering</b>
- * <p>
- * The Canvas3D class is used either for on-screen rendering or
- * off-screen rendering.
- * On-screen Canvas3Ds are added to AWT or Swing Container objects
- * like any other canvas. Java 3D automatically and continuously
- * renders to all on-screen canvases that are attached to an active
- * View object. On-screen Canvas3Ds can be either single or double
- * buffered and they can be either stereo or monoscopic.
- * <p>
- * Off-screen Canvas3Ds must not be added to any Container. Java 3D
- * renders to off-screen canvases in response to the
- * <code>renderOffScreenBuffer</code> method. Off-screen Canvas3Ds
- * are single buffered. However, on many systems, the actual
- * rendering is done to an off-screen hardware buffer or to a 3D
- * library-specific buffer and only copied to the off-screen buffer of
- * the Canvas when the rendering is complete, at "buffer swap" time.
- * Off-screen Canvas3Ds are monoscopic.
- * <p>
- * The setOffScreenBuffer method sets the off-screen buffer for this
- * Canvas3D. The specified image is written into by the Java 3D renderer.
- * The size of the specified ImageComponent determines the size, in
- * pixels, of this Canvas3D - the size inherited from Component is
- * ignored. Note that the size, physical width, and physical height of the
- * associated Screen3D must be set
- * explicitly prior to rendering. Failure to do so will result in an
- * exception.
- * <p>
- * The getOffScreenBuffer method retrieves the off-screen
- * buffer for this Canvas3D.
- * <p>
- * The renderOffScreenBuffer method schedules the rendering of a frame
- * into this Canvas3D's off-screen buffer. The rendering is done from
- * the point of view of the View object to which this Canvas3D has been
- * added. No rendering is performed if this Canvas3D object has not been
- * added to an active View. This method does not wait for the rendering
- * to actually happen. An application that wishes to know when the
- * rendering is complete must either subclass Canvas3D and
- * override the postSwap method, or call waitForOffScreenRendering.
- * <p>
- * The setOfScreenLocation methods set the location of this off-screen
- * Canvas3D. The location is the upper-left corner of the Canvas3D
- * relative to the upper-left corner of the corresponding off-screen
- * Screen3D. The function of these methods is similar to that of
- * Component.setLocation for on-screen Canvas3D objects. The default
- * location is (0,0).
- * <p>
- * <b>Accessing and Modifying an Eye's Image Plate Position</b>
- * <p>
- * A Canvas3D object provides sophisticated applications with access
- * to the eye's position information in head-tracked, room-mounted
- * runtime environments. It also allows applications to manipulate
- * the position of an eye relative to an image plate in non-head-tracked
- * runtime environments.
- * <p>
- * The setLeftManualEyeInImagePlate and setRightManualEyeInImagePlate
- * methods set the position of the manual left and right eyes in image
- * plate coordinates. These values determine eye placement when a head
- * tracker is not in use and the application is directly controlling the
- * eye position in image plate coordinates. In head-tracked mode or
- * when the windowEyepointPolicy is RELATIVE_TO_FIELD_OF_VIEW or
- * RELATIVE_TO_COEXISTENCE, this
- * value is ignored. When the windowEyepointPolicy is RELATIVE_TO_WINDOW,
- * only the Z value is used.
- * <p>
- * The getLeftEyeInImagePlate, getRightEyeInImagePlate, and
- * getCenterEyeInImagePlate methods retrieve the actual position of the
- * left eye, right eye, and center eye in image plate coordinates and
- * copy that value into the object provided. The center eye is the
- * fictional eye half-way between the left and right eye. These three
- * values are a function of the windowEyepointPolicy, the tracking
- * enable flag, and the manual left, right, and center eye positions.
- * <p>
- * <b>Monoscopic View Policy</b>
- * <p>
- * The setMonoscopicViewPolicy and getMonoscopicViewPolicy methods
- * set and retrieve the policy regarding how Java 3D generates monoscopic
- * view. If the policy is set to View.LEFT_EYE_VIEW, the view generated
- * corresponds to the view as seen from the left eye. If set to
- * View.RIGHT_EYE_VIEW, the view generated corresponds to the view as
- * seen from the right eye. If set to View.CYCLOPEAN_EYE_VIEW, the view
- * generated corresponds to the view as seen from the "center eye," the
- * fictional eye half-way between the left and right eye. The default
- * monoscopic view policy is View.CYCLOPEAN_EYE_VIEW.
- * <p>
- * <b>Immediate Mode Rendering</b>
- * <p>
- * Pure immediate-mode rendering provides for those applications and
- * applets that do not want Java 3D to do any automatic rendering of
- * the scene graph. Such applications may not even wish to build a
- * scene graph to represent their graphical data. However, they use
- * Java 3D's attribute objects to set graphics state and Java 3D's
- * geometric objects to render geometry.
- * <p>
- * A pure immediate mode application must create a minimal set of
- * Java 3D objects before rendering. In addition to a Canvas3D object,
- * the application must create a View object, with its associated
- * PhysicalBody and PhysicalEnvironment objects, and the following
- * scene graph elements: a VirtualUniverse object, a high-resolution
- * Locale object, a BranchGroup node object, a TransformGroup node
- * object with associated transform, and a ViewPlatform
- * leaf node object that defines the position and orientation within
- * the virtual universe that generates the view.
- * <p>
- * In immediate mode, all rendering is done completely under user
- * control. It is necessary for the user to clear the 3D canvas,
- * render all geometry, and swap the buffers. Additionally,
- * rendering the right and left eye for stereo viewing becomes the
- * sole responsibility of the application. In pure immediate mode,
- * the user must stop the Java 3D renderer, via the
- * Canvas3D object <code>stopRenderer</code> method, prior to adding the
- * Canvas3D object to an active View object (that is, one that is
- * attached to a live ViewPlatform object).
- * <p>
- * Other Canvas3D methods related to immediate mode rendering are:
- * <p>
- * <ul>
- * <code>getGraphicsContext3D</code> retrieves the immediate-mode
- * 3D graphics context associated with this Canvas3D. It creates a
- * new graphics context if one does not already exist.
- * <p>
- * <code>getGraphics2D</code> retrieves the
- * 2D graphics object associated with this Canvas3D. It creates a
- * new 2D graphics object if one does not already exist.
- * <p>
- * <code>swap</code> synchronizes and swaps buffers on a
- * double-buffered canvas for this Canvas3D object. This method
- * should only be called if the Java 3D renderer has been stopped.
- * In the normal case, the renderer automatically swaps
- * the buffer.
- * </ul>
- *
- * <p>
- * <b>Mixed Mode Rendering</b>
- * <p>
- * Mixing immediate mode and retained or compiled-retained mode
- * requires more structure than pure immediate mode. In mixed mode,
- * the Java 3D renderer is running continuously, rendering the scene
- * graph into the canvas.
- *
- * <p>
- * Canvas3D methods related to mixed mode rendering are:
- *
- * <p>
- * <ul>
- * <code>preRender</code> called by the Java 3D rendering loop after
- * clearing the canvas and before any rendering has been done for
- * this frame.
- * <p>
- * <code>postRender</code> called by the Java 3D rendering loop after
- * completing all rendering to the canvas for this frame and before
- * the buffer swap.
- * <p>
- * <code>postSwap</code> called by the Java 3D rendering loop after
- * completing all rendering to the canvas, and all other canvases
- * associated with this view, for this frame following the
- * buffer swap.
- * <p>
- * <code>renderField</code> called by the Java 3D rendering loop
- * during the execution of the rendering loop. It is called once
- * for each field (i.e., once per frame on a mono system or once
- * each for the right eye and left eye on a two-pass stereo system.
- * </ul>
- * <p>
- * The above callback methods are called by the Java 3D rendering system
- * and should <i>not</i> be called by an application directly.
- *
- * <p>
- * The basic Java 3D <i>stereo</i> rendering loop,
- * executed for each Canvas3D, is as follows:
- * <ul><pre>
- * clear canvas (both eyes)
- * call preRender() // user-supplied method
- * set left eye view
- * render opaque scene graph objects
- * call renderField(FIELD_LEFT) // user-supplied method
- * render transparent scene graph objects
- * set right eye view
- * render opaque scene graph objects again
- * call renderField(FIELD_RIGHT) // user-supplied method
- * render transparent scene graph objects again
- * call postRender() // user-supplied method
- * synchronize and swap buffers
- * call postSwap() // user-supplied method
- * </pre></ul>
- * <p>
- * The basic Java 3D <i>monoscopic</i> rendering loop is as follows:
- * <ul><pre>
- * clear canvas
- * call preRender() // user-supplied method
- * set view
- * render opaque scene graph objects
- * call renderField(FIELD_ALL) // user-supplied method
- * render transparent scene graph objects
- * call postRender() // user-supplied method
- * synchronize and swap buffers
- * call postSwap() // user-supplied method
- * </pre></ul>
- * <p>
- * In both cases, the entire loop, beginning with clearing the canvas
- * and ending with swapping the buffers, defines a frame. The application
- * is given the opportunity to render immediate-mode geometry at any of
- * the clearly identified spots in the rendering loop. A user specifies
- * his or her own rendering methods by extending the Canvas3D class and
- * overriding the preRender, postRender, postSwap, and/or renderField
- * methods.
- * Updates to live Geometry, Texture, and ImageComponent objects
- * in the scene graph are not allowed from any of these callback
- * methods.
- *
- * <p>
- * <b>Serialization</b>
- * <p>
- * Canvas3D does <i>not</i> support serialization. An attempt to
- * serialize a Canvas3D object will result in an
- * UnsupportedOperationException being thrown.
- *
- * <p>
- * <b>Additional Information</b>
- * <p>
- * For more information, see the
- * <a href="doc-files/intro.html">Introduction to the Java 3D API</a> and
- * <a href="doc-files/ViewModel.html">View Model</a>
- * documents.
- *
- * @see Screen3D
- * @see View
- * @see GraphicsContext3D
- */
-public class Canvas3D extends Canvas {
- /**
- * Specifies the left field of a field-sequential stereo rendering loop.
- * A left field always precedes a right field.
- */
- public static final int FIELD_LEFT = 0;
-
- /**
- * Specifies the right field of a field-sequential stereo rendering loop.
- * A right field always follows a left field.
- */
- public static final int FIELD_RIGHT = 1;
-
- /**
- * Specifies a single-field rendering loop.
- */
- public static final int FIELD_ALL = 2;
-
- //
- // The following constants are bit masks to specify which of the node
- // components are dirty and need updates.
- //
- // Values for the geometryType field.
- static final int POLYGONATTRS_DIRTY = 0x01;
- static final int LINEATTRS_DIRTY = 0x02;
- static final int POINTATTRS_DIRTY = 0x04;
- static final int MATERIAL_DIRTY = 0x08;
- static final int TRANSPARENCYATTRS_DIRTY = 0x10;
- static final int COLORINGATTRS_DIRTY = 0x20;
-
- // Values for lightbin, env set, texture, texture setting etc.
- static final int LIGHTBIN_DIRTY = 0x40;
- static final int LIGHTENABLES_DIRTY = 0x80;
- static final int AMBIENTLIGHT_DIRTY = 0x100;
- static final int ATTRIBUTEBIN_DIRTY = 0x200;
- static final int TEXTUREBIN_DIRTY = 0x400;
- static final int TEXTUREATTRIBUTES_DIRTY = 0x800;
- static final int RENDERMOLECULE_DIRTY = 0x1000;
- static final int FOG_DIRTY = 0x2000;
- static final int MODELCLIP_DIRTY = 0x4000;
- static final int VIEW_MATRIX_DIRTY = 0x8000;
- // static final int SHADER_DIRTY = 0x10000; Not ready for this yet -- JADA
-
- //
- // Flag that indicates whether this Canvas3D is an off-screen Canvas3D
- //
- boolean offScreen = false;
-
- //
- // Issue 131: Flag that indicates whether this Canvas3D is a manually
- // rendered Canvas3D (versus an automatically rendered Canvas3D).
- //
- // NOTE: manualRendering only applies to off-screen Canvas3Ds at this time.
- // We have no plans to ever change this, but if we do, it might be necessary
- // to determine which, if any, of the uses of "manualRendering" should be
- // changed to "manualRendering&&offScreen"
- //
- boolean manualRendering = false;
-
- // user specified offScreen Canvas location
- Point offScreenCanvasLoc;
-
- // user specified offScreen Canvas dimension
- Dimension offScreenCanvasSize;
-
- //
- // Flag that indicates whether off-screen rendering is in progress or not
- //
- volatile boolean offScreenRendering = false;
-
- //
- // Flag that indicates we are waiting for an off-screen buffer to be
- // created or destroyed by the Renderer.
- //
- volatile boolean offScreenBufferPending = false;
-
- //
- // ImageComponent used for off-screen rendering
- //
- ImageComponent2D offScreenBuffer = null;
-
- // flag that indicates whether this canvas will use shared context
- boolean useSharedCtx = true;
-
- //
- // Read-only flag that indicates whether stereo is supported for this
- // canvas. This is always false for off-screen canvases.
- //
- boolean stereoAvailable;
-
- //
- // Flag to enable stereo rendering, if allowed by the
- // stereoAvailable flag.
- //
- boolean stereoEnable = true;
-
- //
- // This flag is set when stereo mode is both enabled and
- // available. Code that looks at stereo mode should use this
- // flag.
- //
- boolean useStereo;
-
- // Indicate whether it is left or right stereo pass currently
- boolean rightStereoPass = false;
-
- //
- // Specifies how Java 3D generates monoscopic view
- // (LEFT_EYE_VIEW, RIGHT_EYE_VIEW, or CYCLOPEAN_EYE_VIEW).
- //
- int monoscopicViewPolicy = View.CYCLOPEAN_EYE_VIEW;
-
- // User requested stencil size
- int requestedStencilSize;
-
- // Actual stencil size return for this canvas
- int actualStencilSize;
-
- // True if stencil buffer is available for user
- boolean userStencilAvailable;
-
- // True if stencil buffer is available for system ( decal )
- boolean systemStencilAvailable;
-
- //
- // Read-only flag that indicates whether double buffering is supported
- // for this canvas. This is always false for off-screen canvases.
- //
- boolean doubleBufferAvailable;
-
- //
- // Flag to enable double buffered rendering, if allowed by the
- // doubleBufferAvailable flag.
- //
- boolean doubleBufferEnable = true;
-
- //
- // This flag is set when doubleBuffering is both enabled and
- // available Code that enables or disables double buffering should
- // use this flag.
- //
- boolean useDoubleBuffer;
-
- //
- // Read-only flag that indicates whether scene antialiasing
- // is supported for this canvas.
- //
- boolean sceneAntialiasingAvailable;
- boolean sceneAntialiasingMultiSamplesAvailable;
-
- // Use to see whether antialiasing is already set
- private boolean antialiasingSet = false;
-
- //
- // Read-only flag that indicates the size of the texture color
- // table for this canvas. A value of 0 indicates that the texture
- // color table is not supported.
- //
- int textureColorTableSize;
-
- // number of active/enabled texture unit
- int numActiveTexUnit = 0;
-
- // index iof last enabled texture unit
- int lastActiveTexUnit = -1;
-
- // True if shadingLanguage is supported, otherwise false.
- boolean shadingLanguageGLSL = false;
-
- // Query properties
- J3dQueryProps queryProps;
-
- // Flag indicating a fatal rendering error of some sort
- private boolean fatalError = false;
-
- //
- // The positions of the manual left and right eyes in image-plate
- // coordinates.
- // By default, we will use the center of the screen for X and Y values
- // (X values are adjusted for default eye separation), and
- // 0.4572 meters (18 inches) for the Z value.
- // These match defaults elsewhere in the system.
- //
- Point3d leftManualEyeInImagePlate = new Point3d(0.142, 0.135, 0.4572);
- Point3d rightManualEyeInImagePlate = new Point3d(0.208, 0.135, 0.4572);
-
- //
- // View that is attached to this Canvas3D.
- //
- View view = null;
-
- // View waiting to be set
- View pendingView;
-
- //
- // View cache for this canvas and its associated view.
- //
- CanvasViewCache canvasViewCache = null;
-
- // Issue 109: View cache for this canvas, for computing view frustum planes
- CanvasViewCache canvasViewCacheFrustum = null;
-
- // Since multiple renderAtomListInfo, share the same vecBounds
- // we want to do the intersection test only once per renderAtom
- // this flag is set to true after the first intersect and set to
- // false during checkForCompaction in renderBin
- boolean raIsVisible = false;
-
- RenderAtom ra = null;
-
- // Stereo related field has changed.
- static final int STEREO_DIRTY = 0x01;
- // MonoscopicViewPolicy field has changed.
- static final int MONOSCOPIC_VIEW_POLICY_DIRTY = 0x02;
- // Left/right eye in image plate field has changed.
- static final int EYE_IN_IMAGE_PLATE_DIRTY = 0x04;
- // Canvas has moved/resized.
- static final int MOVED_OR_RESIZED_DIRTY = 0x08;
-
- // Canvas Background changed (this may affect doInfinite flag)
- static final int BACKGROUND_DIRTY = 0x10;
-
- // Canvas Background Image changed
- static final int BACKGROUND_IMAGE_DIRTY = 0x20;
-
-
- // Mask that indicates this Canvas view dependence info. has changed,
- // and CanvasViewCache may need to recompute the final view matries.
- static final int VIEW_INFO_DIRTY = (STEREO_DIRTY |
- MONOSCOPIC_VIEW_POLICY_DIRTY |
- EYE_IN_IMAGE_PLATE_DIRTY |
- MOVED_OR_RESIZED_DIRTY |
- BACKGROUND_DIRTY |
- BACKGROUND_IMAGE_DIRTY);
-
- // Issue 163: Array of dirty bits is used because the Renderer and
- // RenderBin run asynchronously. Now that they each have a separate
- // instance of CanvasViewCache (due to the fix for Issue 109), they
- // need separate dirty bits. Array element 0 is used for the Renderer and
- // element 1 is used for the RenderBin.
- static final int RENDERER_DIRTY_IDX = 0;
- static final int RENDER_BIN_DIRTY_IDX = 1;
- int[] cvDirtyMask = new int[2];
-
- // This boolean informs the J3DGraphics2DImpl that the window is resized
- boolean resizeGraphics2D = true;
- //
- // This boolean allows an application to start and stop the render
- // loop on this canvas.
- //
- volatile boolean isRunning = true;
-
- // This is used by MasterControl only. MC relay on this in a
- // single loop to set renderer thread. During this time,
- // the isRunningStatus can't change by user thread.
- volatile boolean isRunningStatus = true;
-
- // This is true when the canvas is ready to be rendered into
- boolean active = false;
-
- // This is true when the canvas is visible
- boolean visible = false;
-
- // This is true if context need to recreate
- boolean ctxReset = true;
-
- // The Screen3D that corresponds to this Canvas3D
- Screen3D screen = null;
-
- // Flag to indicate that image is render completely
- // so swap is valid.
- boolean imageReady = false;
-
- // The 3D Graphics context used for immediate mode rendering
- // into this canvas.
- GraphicsContext3D graphicsContext3D = null;
- boolean waiting = false;
- boolean swapDone = false;
-
- GraphicsConfiguration graphicsConfiguration;
-
- // The Java 3D Graphics2D object used for Java2D/AWT rendering
- // into this Canvas3D
- J3DGraphics2DImpl graphics2D = null;
-
- // Lock used to synchronize the creation of the 2D and 3D
- // graphics context objects
- Object gfxCreationLock = new Object();
-
- // The source of the currently loaded localToVWorld for this Canvas3D
- // (used to only update the model matrix when it changes)
- // Transform3D localToVWorldSrc = null;
-
- // The current vworldToEc Transform
- Transform3D vworldToEc = new Transform3D();
-
- // The view transform (VPC to EC) for the current eye.
- // NOTE that this is *read-only*
- Transform3D vpcToEc;
-
- // Opaque object representing the underlying drawable (window). This
- // is defined by the Pipeline.
- Drawable drawable = null;
-
- // graphicsConfigTable is a static hashtable which allows getBestConfiguration()
- // in NativeConfigTemplate3D to map a GraphicsConfiguration to the pointer
- // to the actual GLXFBConfig that glXChooseFBConfig() returns. The Canvas3D
- // doesn't exist at the time getBestConfiguration() is called, and
- // X11GraphicsConfig neither maintains this pointer nor provides a public
- // constructor to allow Java 3D to extend it.
- static Hashtable<GraphicsConfiguration,GraphicsConfigInfo> graphicsConfigTable =
- new Hashtable<GraphicsConfiguration,GraphicsConfigInfo>();
-
- // The native graphics version, vendor, and renderer information
- String nativeGraphicsVersion = "<UNKNOWN>";
- String nativeGraphicsVendor = "<UNKNOWN>";
- String nativeGraphicsRenderer = "<UNKNOWN>";
-
- boolean firstPaintCalled = false;
-
- // This reflects whether or not this canvas has seen an addNotify. It is
- // forced to true for off-screen canvases
- boolean added = false;
-
- // Flag indicating whether addNotify has been called (so we don't process it twice).
- private boolean addNotifyCalled = false;
-
- // This is the id for the underlying graphics context structure.
- Context ctx = null;
-
- // since the ctx id can be the same as the previous one,
- // we need to keep a time stamp to differentiate the contexts with the
- // same id
- volatile long ctxTimeStamp = 0;
-
- // The current context setting for local eye lighting
- boolean ctxEyeLightingEnable = false;
-
- // This AppearanceRetained Object refelects the current state of this
- // canvas. It is used to optimize setting of attributes at render time.
- AppearanceRetained currentAppear = new AppearanceRetained();
-
- // This MaterialRetained Object refelects the current state of this canvas.
- // It is used to optimize setting of attributes at render time.
- MaterialRetained currentMaterial = new MaterialRetained();
-
- /**
- * The object used for View Frustum Culling
- */
- CachedFrustum viewFrustum = new CachedFrustum();
-
- /**
- * The RenderBin bundle references used to decide what the underlying
- * context contains.
- */
- LightBin lightBin = null;
- EnvironmentSet environmentSet = null;
- AttributeBin attributeBin = null;
- ShaderBin shaderBin = null;
- RenderMolecule renderMolecule = null;
- PolygonAttributesRetained polygonAttributes = null;
- LineAttributesRetained lineAttributes = null;
- PointAttributesRetained pointAttributes = null;
- MaterialRetained material = null;
- boolean enableLighting = false;
- TransparencyAttributesRetained transparency = null;
- ColoringAttributesRetained coloringAttributes = null;
- Transform3D modelMatrix = null;
- Transform3D projTrans = null;
- TextureBin textureBin = null;
-
-
- /**
- * cached RenderBin states for lazy native states update
- */
- LightRetained lights[] = null;
- int frameCount[] = null;
- long enableMask = -1;
- FogRetained fog = null;
- ModelClipRetained modelClip = null;
- Color3f sceneAmbient = new Color3f();
- TextureUnitStateRetained[] texUnitState = null;
-
- /**
- * These cached values are only used in Pure Immediate and Mixed Mode rendering
- */
- TextureRetained texture = null;
- TextureAttributesRetained texAttrs = null;
- TexCoordGenerationRetained texCoordGeneration = null;
- RenderingAttributesRetained renderingAttrs = null;
- AppearanceRetained appearance = null;
-
- ShaderProgramRetained shaderProgram = null;
-
- // only used in Mixed Mode rendering
- Object appHandle = null;
-
- /**
- * Dirty bit to determine if the NodeComponent needs to be re-sent
- * down to the underlying API
- */
- int canvasDirty = 0xffff;
-
- // True when either one of dirtyRenderMoleculeList,
- // dirtyDlistPerRinfoList, dirtyRenderAtomList size > 0
- boolean dirtyDisplayList = false;
-
-ArrayList<RenderMolecule> dirtyRenderMoleculeList = new ArrayList<RenderMolecule>();
-ArrayList<RenderAtomListInfo> dirtyRenderAtomList = new ArrayList<RenderAtomListInfo>();
-// List of (Rm, rInfo) pair of individual dlists that need to be rebuilt
-ArrayList<Object[]> dirtyDlistPerRinfoList = new ArrayList<Object[]>();
-
-ArrayList<Integer> displayListResourceFreeList = new ArrayList<Integer>();
-ArrayList<Integer> textureIdResourceFreeList = new ArrayList<Integer>();
-
- // an unique bit to identify this canvas
- int canvasBit = 0;
- // an unique number to identify this canvas : ( canvasBit = 1 << canvasId)
- int canvasId = 0;
- // Indicates whether the canvasId has been allocated
- private boolean canvasIdAlloc = false;
-
- // Avoid using this as lock, it cause deadlock
- Object cvLock = new Object();
- Object evaluateLock = new Object();
- Object dirtyMaskLock = new Object();
-
- // For D3D, instead of using the same variable in Renderer,
- // each canvas has to build its own displayList.
- boolean needToRebuildDisplayList = false;
-
- // Read-only flag that indicates whether the following texture features
- // are supported for this canvas.
-
- static final int TEXTURE_3D = 0x0001;
- static final int TEXTURE_COLOR_TABLE = 0x0002;
- static final int TEXTURE_MULTI_TEXTURE = 0x0004;
- static final int TEXTURE_COMBINE = 0x0008;
- static final int TEXTURE_COMBINE_DOT3 = 0x0010;
- static final int TEXTURE_COMBINE_SUBTRACT = 0x0020;
- static final int TEXTURE_REGISTER_COMBINERS = 0x0040;
- static final int TEXTURE_CUBE_MAP = 0x0080;
- static final int TEXTURE_SHARPEN = 0x0100;
- static final int TEXTURE_DETAIL = 0x0200;
- static final int TEXTURE_FILTER4 = 0x0400;
- static final int TEXTURE_ANISOTROPIC_FILTER = 0x0800;
- static final int TEXTURE_LOD_RANGE = 0x1000;
- static final int TEXTURE_LOD_OFFSET = 0x2000;
- // Use by D3D to indicate using one pass Blend mode
- // if Texture interpolation mode is support.
- static final int TEXTURE_LERP = 0x4000;
- static final int TEXTURE_NON_POWER_OF_TWO = 0x8000;
- static final int TEXTURE_AUTO_MIPMAP_GENERATION = 0x10000;
-
- int textureExtendedFeatures = 0;
-
- // Extensions supported by the underlying canvas
- //
- // NOTE: we should remove EXT_BGR and EXT_ABGR when the imaging code is
- // rewritten
- // killed global alpha
- //static final int SUN_GLOBAL_ALPHA = 0x1;
- static final int EXT_ABGR = 0x2;
- static final int EXT_BGR = 0x4;
- static final int MULTISAMPLE = 0x8;
-
- // The following 10 variables are set by the native
- // createNewContext()/createQueryContext() methods
-
- // Supported Extensions
- int extensionsSupported = 0;
-
- // Anisotropic Filter degree
- float anisotropicDegreeMax = 1.0f;
-
- // Texture Boundary Width Max
- int textureBoundaryWidthMax = 0;
-
- boolean multiTexAccelerated = false;
-
- // Max number of texture coordinate sets
- int maxTexCoordSets = 1;
-
- // Max number of fixed-function texture units
- int maxTextureUnits = 1;
-
- // Max number of fragment shader texture units
- int maxTextureImageUnits = 0;
-
- // Max number of vertex shader texture units
- int maxVertexTextureImageUnits = 0;
-
- // Max number of combined shader texture units
- int maxCombinedTextureImageUnits = 0;
-
- // Max number of vertex attrs (not counting coord, etc.)
- int maxVertexAttrs = 0;
-
- // End of variables set by createNewContext()/createQueryContext()
-
- // The total available number of texture units used by either the
- // fixed-function or programmable shader pipeline.
- // This is computed as: max(maxTextureUnits, maxTextureImageUnits)
- int maxAvailableTextureUnits;
-
- // Texture Width, Height Max
- int textureWidthMax = 0;
- int textureHeightMax = 0;
-
- // Texture3D Width, Heigh, Depth Max
- int texture3DWidthMax = -1;
- int texture3DHeightMax = -1;
- int texture3DDepthMax = -1;
-
- // Cached position & size for CanvasViewCache.
- // We don't want to call canvas.getxx method in Renderer
- // since it will cause deadlock as removeNotify() need to get
- // component lock of Canvas also and need to wait Renderer to
- // finish before continue. So we invoke the method now in
- // CanvasViewEventCatcher.
- Point newPosition = new Point();
- Dimension newSize = new Dimension();
-
-// Remember OGL context resources to free
-// before context is destroy.
-// It is used when sharedCtx = false;
-ArrayList<TextureRetained> textureIDResourceTable = new ArrayList<TextureRetained>(5);
-
- // The following variables are used by the lazy download of
- // states code to keep track of the set of current to be update bins
-
- static final int LIGHTBIN_BIT = 0x0;
- static final int ENVIRONMENTSET_BIT = 0x1;
- static final int ATTRIBUTEBIN_BIT = 0x2;
- static final int TEXTUREBIN_BIT = 0x3;
- static final int RENDERMOLECULE_BIT = 0x4;
- static final int TRANSPARENCY_BIT = 0x5;
- static final int SHADERBIN_BIT = 0x6;
-
- // bitmask to specify if the corresponding "bin" needs to be updated
- int stateUpdateMask = 0;
-
- // the set of current "bins" that is to be updated, the stateUpdateMask
- // specifies if each bin in this set is updated or not.
- Object curStateToUpdate[] = new Object[7];
-
- /**
- * The list of lights that are currently being represented in the native
- * graphics context.
- */
- LightRetained[] currentLights = null;
-
- /**
- * Flag to override RenderAttributes.depthBufferWriteEnable
- */
- boolean depthBufferWriteEnableOverride = false;
-
- /**
- * Flag to override RenderAttributes.depthBufferEnable
- */
- boolean depthBufferEnableOverride = false;
-
- // current state of depthBufferWriteEnable
- boolean depthBufferWriteEnable = true;
-
- boolean vfPlanesValid = false;
-
- // The event catcher for this canvas.
- EventCatcher eventCatcher;
-
- // The view event catcher for this canvas.
- private CanvasViewEventCatcher canvasViewEventCatcher;
-
- // The top-level parent window for this canvas.
- private Window windowParent;
-
- // Issue 458 - list of all parent containers for this canvas
- // (includes top-level parent window)
- private LinkedList<Container> containerParentList = new LinkedList<Container>();
-
- // flag that indicates if light has changed
- boolean lightChanged = false;
-
- // resource control object
- DrawingSurfaceObject drawingSurfaceObject;
-
- // true if context is valid for rendering
- boolean validCtx = false;
-
- // true if canvas is valid for rendering
- boolean validCanvas = false;
-
- // true if ctx changed between render and swap. In this case
- // cv.canvasDirty flag will not reset in Renderer.
- // This case happen when GraphicsContext3D invoked doClear()
- // and canvas removeNotify() called while Renderer is running
- boolean ctxChanged = false;
-
- // Default graphics configuration
- private static GraphicsConfiguration defaultGcfg = null;
-
- // Returns default graphics configuration if user passes null
- // into the Canvas3D constructor
- private static synchronized GraphicsConfiguration defaultGraphicsConfiguration() {
- if (defaultGcfg == null) {
- GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D();
- defaultGcfg = GraphicsEnvironment.getLocalGraphicsEnvironment().
- getDefaultScreenDevice().getBestConfiguration(template);
- }
- return defaultGcfg;
- }
-
- // Returns true if this is a valid graphics configuration, obtained
- // via a GraphicsConfigTemplate3D.
- private static boolean isValidConfig(GraphicsConfiguration gconfig) {
- // If this is a valid GraphicsConfiguration object, then it will
- // be in the graphicsConfigTable
- return graphicsConfigTable.containsKey(gconfig);
- }
-
- // Checks the given graphics configuration, and throws an exception if
- // the config is null or invalid.
- private static synchronized GraphicsConfiguration
- checkForValidGraphicsConfig(GraphicsConfiguration gconfig, boolean offScreen) {
-
- // Issue 266 - for backwards compatibility with legacy applications,
- // we will accept a null GraphicsConfiguration for an on-screen Canvas3D
- // only if the "allowNullGraphicsConfig" system property is set to true.
- if (!offScreen && VirtualUniverse.mc.allowNullGraphicsConfig) {
- if (gconfig == null) {
- // Print out warning if Canvas3D is called with a
- // null GraphicsConfiguration
- System.err.println(J3dI18N.getString("Canvas3D7"));
- System.err.println(" " + J3dI18N.getString("Canvas3D18"));
-
- // Use a default graphics config
- gconfig = defaultGraphicsConfiguration();
- }
- }
-
- // Validate input graphics config
- if (gconfig == null) {
- throw new NullPointerException(J3dI18N.getString("Canvas3D19"));
- } else if (!isValidConfig(gconfig)) {
- throw new IllegalArgumentException(J3dI18N.getString("Canvas3D17"));
- }
-
- return gconfig;
- }
-
- // Return the actual graphics config that will be used to construct
- // the AWT Canvas. This is permitted to be non-unique or null.
- private static GraphicsConfiguration getGraphicsConfig(GraphicsConfiguration gconfig) {
- return Pipeline.getPipeline().getGraphicsConfig(gconfig);
- }
-
- /**
- * Constructs and initializes a new Canvas3D object that Java 3D
- * can render into. The following Canvas3D attributes are initialized
- * to default values as shown:
- * <ul>
- * left manual eye in image plate : (0.142, 0.135, 0.4572)<br>
- * right manual eye in image plate : (0.208, 0.135, 0.4572)<br>
- * stereo enable : true<br>
- * double buffer enable : true<br>
- * monoscopic view policy : View.CYCLOPEAN_EYE_VIEW<br>
- * off-screen mode : false<br>
- * off-screen buffer : null<br>
- * off-screen location : (0,0)<br>
- * </ul>
- *
- * @param graphicsConfiguration a valid GraphicsConfiguration object that
- * will be used to create the canvas. This object should not be null and
- * should be created using a GraphicsConfigTemplate3D or the
- * getPreferredConfiguration() method of the SimpleUniverse utility. For
- * backward compatibility with earlier versions of Java 3D, a null or
- * default GraphicsConfiguration will still work when used to create a
- * Canvas3D on the default screen, but an error message will be printed.
- * A NullPointerException or IllegalArgumentException will be thrown in a
- * subsequent release.
- *
- * @exception IllegalArgumentException if the specified
- * GraphicsConfiguration does not support 3D rendering
- */
- public Canvas3D(GraphicsConfiguration graphicsConfiguration) {
- this(null, checkForValidGraphicsConfig(graphicsConfiguration, false), false);
- }
-
- /**
- * Constructs and initializes a new Canvas3D object that Java 3D
- * can render into.
- *
- * @param graphicsConfiguration a valid GraphicsConfiguration object
- * that will be used to create the canvas. This must be created either
- * with a GraphicsConfigTemplate3D or by using the
- * getPreferredConfiguration() method of the SimpleUniverse utility.
- *
- * @param offScreen a flag that indicates whether this canvas is
- * an off-screen 3D rendering canvas. Note that if offScreen
- * is set to true, this Canvas3D object cannot be used for normal
- * rendering; it should not be added to any Container object.
- *
- * @exception NullPointerException if the GraphicsConfiguration
- * is null.
- *
- * @exception IllegalArgumentException if the specified
- * GraphicsConfiguration does not support 3D rendering
- *
- * @since Java 3D 1.2
- */
- public Canvas3D(GraphicsConfiguration graphicsConfiguration, boolean offScreen) {
- this(null, checkForValidGraphicsConfig(graphicsConfiguration, offScreen), offScreen);
- }
-
- // Private constructor only called by the two public constructors after
- // they have validated the graphics config (and possibly constructed a new
- // default config).
- // The graphics config must be valid, unique, and non-null.
- private Canvas3D(Object dummyObj1,
- GraphicsConfiguration graphicsConfiguration,
- boolean offScreen) {
- this(dummyObj1,
- graphicsConfiguration,
- getGraphicsConfig(graphicsConfiguration),
- offScreen);
- }
-
- // Private constructor only called by the previous private constructor.
- // The graphicsConfiguration parameter is used by Canvas3D to lookup the
- // graphics device and graphics template. The graphicsConfiguration2
- // parameter is generated by the Pipeline from graphicsConfiguration and
- // is only used to initialize the java.awt.Canvas.
- private Canvas3D(Object dummyObj1,
- GraphicsConfiguration graphicsConfiguration,
- GraphicsConfiguration graphicsConfiguration2,
- boolean offScreen) {
-
- super(graphicsConfiguration2);
-
- this.offScreen = offScreen;
- this.graphicsConfiguration = graphicsConfiguration;
-
- // Issue 131: Set the autoOffScreen variable based on whether this
- // canvas3d implements the AutoOffScreenCanvas3D tagging interface.
- // Eventually, we may replace this with an actual API.
- boolean autoOffScreenCanvas3D = false;
- if (this instanceof AutoOffScreenCanvas3D) {
- autoOffScreenCanvas3D = true;
- }
-
- // Throw an illegal argument exception if an on-screen canvas is tagged
- // as an auto-off-screen canvas
- if (autoOffScreenCanvas3D && !offScreen) {
- throw new IllegalArgumentException(J3dI18N.getString("Canvas3D25"));
- }
-
- // Issue 163 : Set dirty bits for both Renderer and RenderBin
- cvDirtyMask[0] = VIEW_INFO_DIRTY;
- cvDirtyMask[1] = VIEW_INFO_DIRTY;
-
- GraphicsConfigInfo gcInfo = graphicsConfigTable.get(graphicsConfiguration);
- requestedStencilSize = gcInfo.getGraphicsConfigTemplate3D().getStencilSize();
-
- if (offScreen) {
-
- // Issue 131: set manual rendering flag based on whether this is
- // an auto-off-screen Canvas3D.
- manualRendering = !autoOffScreenCanvas3D;
-
- screen = new Screen3D(graphicsConfiguration, offScreen);
-
- // QUESTION: keep a list of off-screen Screen3D objects?
- // Does this list need to be grouped by GraphicsDevice?
-
- synchronized(dirtyMaskLock) {
- cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY;
- cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY;
- }
-
- // this canvas will not receive the paint callback,
- // so we need to set the necessary flags here
- firstPaintCalled = true;
-
- if (manualRendering) {
- // since this canvas will not receive the addNotify
- // callback from AWT, set the added flag here for
- // evaluateActive to work correctly
- added = true;
- }
-
- evaluateActive();
-
- // create the rendererStructure object
- //rendererStructure = new RendererStructure();
- offScreenCanvasLoc = new Point(0, 0);
- offScreenCanvasSize = new Dimension(0, 0);
-
- this.setLocation(offScreenCanvasLoc);
- this.setSize(offScreenCanvasSize);
- newSize = offScreenCanvasSize;
- newPosition = offScreenCanvasLoc;
-
- // Issue 131: create event catchers for auto-offScreen
- if (!manualRendering) {
- eventCatcher = new EventCatcher(this);
- canvasViewEventCatcher = new CanvasViewEventCatcher(this);
- }
- } else {
-
- GraphicsDevice graphicsDevice;
- graphicsDevice = graphicsConfiguration.getDevice();
-
- eventCatcher = new EventCatcher(this);
- canvasViewEventCatcher = new CanvasViewEventCatcher(this);
-
- synchronized(VirtualUniverse.mc.deviceScreenMap) {
- screen = VirtualUniverse.mc.deviceScreenMap.get(graphicsDevice);
-
- if (screen == null) {
- screen = new Screen3D(graphicsConfiguration, offScreen);
- VirtualUniverse.mc.deviceScreenMap.put(graphicsDevice, screen);
- }
- }
-
- }
-
- lights = new LightRetained[VirtualUniverse.mc.maxLights];
- frameCount = new int[VirtualUniverse.mc.maxLights];
- for (int i=0; i<frameCount.length;i++) {
- frameCount[i] = -1;
- }
-
- // Construct the drawing surface object for this Canvas3D
- drawingSurfaceObject =
- Pipeline.getPipeline().createDrawingSurfaceObject(this);
-
- // Get double buffer, stereo available, scene antialiasing
- // flags from graphics config
- GraphicsConfigTemplate3D.getGraphicsConfigFeatures(this);
-
- useDoubleBuffer = doubleBufferEnable && doubleBufferAvailable;
- useStereo = stereoEnable && stereoAvailable;
- useSharedCtx = VirtualUniverse.mc.isSharedCtx;
-
- // Issue 131: assert that only an off-screen canvas can be demand-driven
- assert (!offScreen && manualRendering) == false;
-
- // Assert that offScreen is *not* stereo
- assert (offScreen && useStereo) == false;
- }
-
- /**
- * This method overrides AWT's handleEvent class...
- */
- void sendEventToBehaviorScheduler(AWTEvent evt) {
-
- ViewPlatform vp;
-
-
- if ((view != null) && ((vp = view.getViewPlatform()) != null)) {
- VirtualUniverse univ =
- ((ViewPlatformRetained)(vp.retained)).universe;
- if (univ != null) {
- univ.behaviorStructure.handleAWTEvent(evt);
- }
- }
- }
-
- /**
- * Method to return whether or not the Canvas3D is recursively visible;
- * that is, whether the Canas3D is currently visible on the screen. Note
- * that we don't directly use isShowing() because that won't work for an
- * auto-offScreen Canvas3D.
- */
- private boolean isRecursivelyVisible() {
- Container parent = getParent();
- return isVisible() && parent != null && parent.isShowing();
- }
-
- /**
- * Method to return whether the top-level Window parent is iconified
- */
- private boolean isIconified() {
- if (windowParent instanceof Frame) {
- return (((Frame)windowParent).getExtendedState() & Frame.ICONIFIED) != 0;
- }
-
- return false;
- }
-
- // Issue 458 - evaluate this Canvas3D's visibility whenever we get a
- // Window or Component Event that could change it.
- void evaluateVisiblilty() {
- boolean nowVisible = isRecursivelyVisible() && !isIconified();
-
- // Only need to reevaluate and repaint if visibility has changed
- if (this.visible != nowVisible) {
- this.visible = nowVisible;
- evaluateActive();
- if (nowVisible) {
- if (view != null) {
- view.repaint();
- }
- }
- }
- }
-
- /**
- * This version looks for the view and notifies it.
- */
- void redraw() {
- if ((view != null) && active && isRunning) {
- view.repaint();
- }
- }
-
- /**
- * Canvas3D uses the paint callback to track when it is possible to
- * render into the canvas. Subclasses of Canvas3D that override this
- * method need to call super.paint() in their paint method for Java 3D
- * to function properly.
- * @param g the graphics context
- */
- @Override
- public void paint(Graphics g) {
-
- if (!firstPaintCalled && added && validCanvas &&
- validGraphicsMode()) {
-
- try {
- newSize = getSize();
- newPosition = getLocationOnScreen();
- } catch (IllegalComponentStateException e) {
- return;
- }
-
- synchronized (drawingSurfaceObject) {
- drawingSurfaceObject.getDrawingSurfaceObjectInfo();
- }
-
- firstPaintCalled = true;
- visible = true;
- evaluateActive();
- }
- redraw();
- }
-
- // When this canvas is added to a frame, this notification gets called. We
- // can get drawing surface information at this time. Note: we cannot get
- // the X11 window id yet, unless it is a reset condition.
- /**
- * Canvas3D uses the addNotify callback to track when it is added
- * to a container. Subclasses of Canvas3D that override this
- * method need to call super.addNotify() in their addNotify() method for Java 3D
- * to function properly.
- */
- @Override
- public void addNotify() {
- // Return immediately if addNotify called twice with no removeNotify
- if (addNotifyCalled) {
- return;
- }
- addNotifyCalled = true;
-
- // Issue 131: This method is now being called by JCanvas3D for its
- // off-screen Canvas3D, so we need to handle off-screen properly here.
- // Do nothing for manually-rendered off-screen canvases
- if (manualRendering) {
- return;
- }
-
- Renderer rdr = null;
-
- if (isRunning && (screen != null)) {
- // If there is other Canvas3D in the same screen
- // rendering, stop it before JDK create new Canvas
-
- rdr = screen.renderer;
- if (rdr != null) {
- VirtualUniverse.mc.postRequest(MasterControl.STOP_RENDERER, rdr);
- while (!rdr.userStop) {
- MasterControl.threadYield();
- }
- }
- }
-
- // Issue 131: Don't call super for off-screen Canvas3D
- if (!offScreen) {
- super.addNotify();
- }
- screen.addUser(this);
-
- // Issue 458 - Add the eventCatcher as a component listener for each
- // parent container in the window hierarchy
- assert containerParentList.isEmpty();
-
- windowParent = null;
- Container container = this.getParent();
- while (container != null) {
- if (container instanceof Window) {
- windowParent = (Window)container;
- }
- container.addComponentListener(eventCatcher);
- container.addComponentListener(canvasViewEventCatcher);
- containerParentList.add(container);
- container = container.getParent();
- }
-
- this.addComponentListener(eventCatcher);
- this.addComponentListener(canvasViewEventCatcher);
-
- if (windowParent != null) {
- windowParent.addWindowListener(eventCatcher);
- }
-
- synchronized(dirtyMaskLock) {
- cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY;
- cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY;
- }
-
- allocateCanvasId();
-
- validCanvas = true;
- added = true;
-
- // Since we won't get a paint call for off-screen canvases, we need
- // to set the first paint and visible flags here. We also need to
- // call evaluateActive for the same reason.
- if (offScreen) {
- firstPaintCalled = true;
- visible = true;
- evaluateActive();
- }
-
- // In case the same canvas is removed and add back,
- // we have to change isRunningStatus back to true;
- if (isRunning && !fatalError) {
- isRunningStatus = true;
- }
-
- ctxTimeStamp = 0;
- if ((view != null) && (view.universe != null)) {
- view.universe.checkForEnableEvents();
- }
-
- if (rdr != null) {
- // Issue 84: Send a message to MC to restart renderer
- // Note that this also obviates the need for the earlier fix to
- // issue 131 which called redraw() for auto-off-screen Canvas3Ds
- // (and this is a more robust fix)
- VirtualUniverse.mc.postRequest(MasterControl.START_RENDERER, rdr);
- while (rdr.userStop) {
- MasterControl.threadYield();
- }
- }
- }
-
- // When this canvas is removed a frame, this notification gets called. We
- // need to release the native context at this time. The underlying window
- // is about to go away.
- /**
- * Canvas3D uses the removeNotify callback to track when it is removed
- * from a container. Subclasses of Canvas3D that override this
- * method need to call super.removeNotify() in their removeNotify()
- * method for Java 3D to function properly.
- */
- @Override
- public void removeNotify() {
- // Return immediately if addNotify not called first
- if (!addNotifyCalled) {
- return;
- }
- addNotifyCalled = false;
-
- // Do nothing for manually-rendered off-screen canvases
- if (manualRendering) {
- return;
- }
-
- Renderer rdr = null;
-
- if (isRunning && (screen != null)) {
- // If there is other Canvas3D in the same screen
- // rendering, stop it before JDK create new Canvas
-
- rdr = screen.renderer;
- if (rdr != null) {
- VirtualUniverse.mc.postRequest(MasterControl.STOP_RENDERER, rdr);
- while (!rdr.userStop) {
- MasterControl.threadYield();
- }
- }
- }
-
- // Note that although renderer userStop is true,
- // MasterControl can still schedule renderer to run through
- // runMonotor(RUN_RENDERER_CLEANUP) which skip userStop
- // thread checking.
- // For non-offscreen rendering the following call will
- // block waiting until all resources is free before
- // continue
-
- synchronized (drawingSurfaceObject) {
- validCtx = false;
- validCanvas = false;
- }
-
- removeCtx();
-
- Pipeline.getPipeline().freeDrawingSurface(this, drawingSurfaceObject);
-
- // Clear first paint and visible flags
- firstPaintCalled = false;
- visible = false;
-
- screen.removeUser(this);
- evaluateActive();
-
- freeCanvasId();
-
- ra = null;
- graphicsContext3D = null;
-
- ctx = null;
- // must be after removeCtx() because
- // it will free graphics2D textureID
- graphics2D = null;
-
- super.removeNotify();
-
- // Release and clear.
- for (Container container : containerParentList) {
- container.removeComponentListener(eventCatcher);
- container.removeComponentListener(canvasViewEventCatcher);
- }
- containerParentList.clear();
- this.removeComponentListener(eventCatcher);
- this.removeComponentListener(canvasViewEventCatcher);
-
- if (eventCatcher != null) {
- this.removeFocusListener(eventCatcher);
- this.removeKeyListener(eventCatcher);
- this.removeMouseListener(eventCatcher);
- this.removeMouseMotionListener(eventCatcher);
- this.removeMouseWheelListener(eventCatcher);
- eventCatcher.reset();
- }
-
- if (windowParent != null) {
- windowParent.removeWindowListener(eventCatcher);
- windowParent.requestFocus();
- }
-
- added = false;
-
- if (rdr != null) {
- // Issue 84: Send a message to MC to restart renderer
- VirtualUniverse.mc.postRequest(MasterControl.START_RENDERER, rdr);
- while (rdr.userStop) {
- MasterControl.threadYield();
- }
- }
-
- // Fix for issue 102 removing strong reference and avoiding memory leak
- // due retention of parent container
- this.windowParent = null;
- }
-
- void allocateCanvasId() {
- if (!canvasIdAlloc) {
- canvasId = VirtualUniverse.mc.getCanvasId();
- canvasBit = 1 << canvasId;
- canvasIdAlloc = true;
- }
- }
-
- void freeCanvasId() {
- if (canvasIdAlloc) {
- VirtualUniverse.mc.freeCanvasId(canvasId);
- canvasBit = 0;
- canvasId = 0;
- canvasIdAlloc = false;
- }
- }
-
- // This decides if the canvas is active
- void evaluateActive() {
- // Note that no need to check for isRunning, we want
- // view register in order to create scheduler in pure immedite mode
- // Also we can't use this as lock, otherwise there is a
- // deadlock where updateViewCache get a lock of this and
- // get a lock of this component. But Container
- // remove will get a lock of this component follows by evaluateActive.
-
- synchronized (evaluateLock) {
- if ((visible || manualRendering) && firstPaintCalled) {
-
- if (!active) {
- active = true;
- if (pendingView != null) {
- pendingView.evaluateActive();
- }
- } else {
- if ((pendingView != null) &&
- !pendingView.activeStatus) {
- pendingView.evaluateActive();
- }
- }
- } else {
- if (active) {
- active = false;
- if (view != null) {
- view.evaluateActive();
- }
- }
- }
- }
-
- if ((view != null) && (!active)) {
- VirtualUniverse u = view.universe;
- if ((u != null) && !u.isSceneGraphLock) {
- u.waitForMC();
- }
- }
- }
-
- void setFrustumPlanes(Vector4d[] planes) {
-
- if(VirtualUniverse.mc.viewFrustumCulling) {
- /* System.err.println("Canvas3D.setFrustumPlanes()"); */
- viewFrustum.set(planes);
- }
- }
-
-
- /**
- * Retrieve the Screen3D object that this Canvas3D is attached to.
- * If this Canvas3D is an off-screen buffer, a new Screen3D object
- * is created corresponding to the off-screen buffer.
- * @return the 3D screen object that this Canvas3D is attached to
- */
- public Screen3D getScreen3D() {
- return screen;
- }
-
- /**
- * Get the immediate mode 3D graphics context associated with
- * this Canvas3D. A new graphics context object is created if one does
- * not already exist.
- * @return a GraphicsContext3D object that can be used for immediate
- * mode rendering to this Canvas3D.
- */
- public GraphicsContext3D getGraphicsContext3D() {
-
- synchronized(gfxCreationLock) {
- if (graphicsContext3D == null)
- graphicsContext3D = new GraphicsContext3D(this);
- }
-
- return graphicsContext3D;
- }
-
- /**
- * Get the 2D graphics object associated with
- * this Canvas3D. A new 2D graphics object is created if one does
- * not already exist.
- *
- * @return a Graphics2D object that can be used for Java 2D
- * rendering into this Canvas3D.
- *
- * @since Java 3D 1.2
- */
- public J3DGraphics2D getGraphics2D() {
- synchronized(gfxCreationLock) {
- if (graphics2D == null)
- graphics2D = new J3DGraphics2DImpl(this);
- }
-
- return graphics2D;
- }
-
- /**
- * This routine is called by the Java 3D rendering loop after clearing
- * the canvas and before any rendering has been done for this frame.
- * Applications that wish to perform operations in the rendering loop,
- * prior to any actual rendering may override this function.
- *
- * <p>
- * Updates to live Geometry, Texture, and ImageComponent objects
- * in the scene graph are not allowed from this method.
- *
- * <p>
- * NOTE: Applications should <i>not</i> call this method.
- */
- public void preRender() {
- // Do nothing; the user overrides this to cause some action
- }
-
- /**
- * This routine is called by the Java 3D rendering loop after completing
- * all rendering to the canvas for this frame and before the buffer swap.
- * Applications that wish to perform operations in the rendering loop,
- * following any actual rendering may override this function.
- *
- * <p>
- * Updates to live Geometry, Texture, and ImageComponent objects
- * in the scene graph are not allowed from this method.
- *
- * <p>
- * NOTE: Applications should <i>not</i> call this method.
- */
- public void postRender() {
- // Do nothing; the user overrides this to cause some action
- }
-
- /**
- * This routine is called by the Java 3D rendering loop after completing
- * all rendering to the canvas, and all other canvases associated with
- * this view, for this frame following the buffer swap.
- * Applications that wish to perform operations at the very
- * end of the rendering loop may override this function.
- * In off-screen mode, all rendering is copied to the off-screen
- * buffer before this method is called.
- *
- * <p>
- * Updates to live Geometry, Texture, and ImageComponent objects
- * in the scene graph are not allowed from this method.
- *
- * <p>
- * NOTE: Applications should <i>not</i> call this method.
- */
- public void postSwap() {
- // Do nothing; the user overrides this to cause some action
- }
-
- /**
- * This routine is called by the Java 3D rendering loop during the
- * execution of the rendering loop. It is called once for each
- * field (i.e., once per frame on
- * a mono system or once each for the right eye and left eye on a
- * two-pass stereo system. This is intended for use by applications that
- * want to mix retained/compiled-retained mode rendering with some
- * immediate mode rendering. Applications that wish to perform
- * operations during the rendering loop, may override this
- * function.
- *
- * <p>
- * Updates to live Geometry, Texture, and ImageComponent objects
- * in the scene graph are not allowed from this method.
- *
- * <p>
- * NOTE: Applications should <i>not</i> call this method.
- * <p>
- *
- * @param fieldDesc field description, one of: FIELD_LEFT, FIELD_RIGHT or
- * FIELD_ALL. Applications that wish to work correctly in stereo mode
- * should render the same image for both FIELD_LEFT and FIELD_RIGHT calls.
- * If Java 3D calls the renderer with FIELD_ALL then the immediate mode
- * rendering only needs to be done once.
- */
- public void renderField(int fieldDesc) {
- // Do nothing; the user overrides this to cause some action
- }
-
- /**
- * Stop the Java 3D renderer on this Canvas3D object. If the
- * Java 3D renderer is currently running, the rendering will be
- * synchronized before being stopped. No further rendering will be done
- * to this canvas by Java 3D until the renderer is started again.
- * In pure immediate mode this method should be called prior to adding
- * this canvas to an active View object.
- *
- * @exception IllegalStateException if this Canvas3D is in
- * off-screen mode.
- */
- public final void stopRenderer() {
- // Issue 131: renderer can't be stopped only if it is an offscreen,
- // manual canvas. Otherwise, it has to be seen as an onscreen canvas.
- if (manualRendering)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D14"));
-
- if (isRunning) {
- VirtualUniverse.mc.postRequest(MasterControl.STOP_RENDERER, this);
- isRunning = false;
- }
- }
-
-
- /**
- * Start the Java 3D renderer on this Canvas3D object. If the
- * Java 3D renderer is not currently running, any rendering to other
- * Canvas3D objects sharing the same View will be synchronized before this
- * Canvas3D's renderer is (re)started. When a Canvas3D is created, it is
- * initially marked as being started. This means that as soon as the
- * Canvas3D is added to an active View object, the rendering loop will
- * render the scene graph to the canvas.
- */
- public final void startRenderer() {
- // Issue 260 : ignore attempt to start renderer if fatal error
- if (fatalError) {
- return;
- }
-
- if (!isRunning) {
- VirtualUniverse.mc.postRequest(MasterControl.START_RENDERER, this);
- isRunning = true;
- redraw();
- }
- }
-
- /**
- * Retrieves the state of the renderer for this Canvas3D object.
- * @return the state of the renderer
- *
- * @since Java 3D 1.2
- */
- public final boolean isRendererRunning() {
- return isRunning;
- }
-
- // Returns the state of the fatal error flag
- boolean isFatalError() {
- return fatalError;
- }
-
- // Sets the fatal error flag to true; stop the renderer for this canvas
- void setFatalError() {
- fatalError = true;
-
- if (isRunning) {
- isRunning = false;
-
- if (!manualRendering) {
- VirtualUniverse.mc.postRequest(MasterControl.STOP_RENDERER, this);
- }
- }
- }
-
-
- /**
- * Retrieves a flag indicating whether this Canvas3D is an
- * off-screen canvas.
- *
- * @return <code>true</code> if this Canvas3D is an off-screen canvas;
- * <code>false</code> if this is an on-screen canvas.
- *
- * @since Java 3D 1.2
- */
- public boolean isOffScreen() {
- return offScreen;
- }
-
-
- /**
- * Sets the off-screen buffer for this Canvas3D. The specified
- * image is written into by the Java 3D renderer. The size of the
- * specified ImageComponent determines the size, in pixels, of
- * this Canvas3D--the size inherited from Component is ignored.
- * <p>
- * NOTE: the size, physical width, and physical height of the associated
- * Screen3D must be set explicitly prior to rendering.
- * Failure to do so will result in an exception.
- * <p>
- *
- * @param buffer the image component that will be rendered into by
- * subsequent calls to renderOffScreenBuffer. The image component must not
- * be part of a live scene graph, nor may it subsequently be made part of a
- * live scene graph while being used as an off-screen buffer; an
- * IllegalSharingException is thrown in such cases. The buffer may be null,
- * indicating that the previous off-screen buffer is released without a new
- * buffer being set.
- *
- * @exception IllegalStateException if this Canvas3D is not in
- * off-screen mode.
- *
- * @exception RestrictedAccessException if an off-screen rendering
- * is in process for this Canvas3D.
- *
- * @exception IllegalSharingException if the specified ImageComponent2D
- * is part of a live scene graph
- *
- * @exception IllegalSharingException if the specified ImageComponent2D is
- * being used by an immediate mode context, or by another Canvas3D as
- * an off-screen buffer.
- *
- * @exception IllegalArgumentException if the image class of the specified
- * ImageComponent2D is <i>not</i> ImageClass.BUFFERED_IMAGE.
- *
- * @exception IllegalArgumentException if the specified
- * ImageComponent2D is in by-reference mode and its
- * RenderedImage is null.
- *
- * @exception IllegalArgumentException if the ImageComponent2D format
- * is <i>not</i> a 3-component format (e.g., FORMAT_RGB)
- * or a 4-component format (e.g., FORMAT_RGBA).
- *
- * @see #renderOffScreenBuffer
- * @see Screen3D#setSize(int, int)
- * @see Screen3D#setSize(Dimension)
- * @see Screen3D#setPhysicalScreenWidth
- * @see Screen3D#setPhysicalScreenHeight
- *
- * @since Java 3D 1.2
- */
- public void setOffScreenBuffer(ImageComponent2D buffer) {
- int width, height;
- boolean freeCanvasId = false;
-
- if (!offScreen)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
-
- if (offScreenRendering)
- throw new RestrictedAccessException(J3dI18N.getString("Canvas3D2"));
-
- // Check that offScreenBufferPending is not already set
- J3dDebug.doAssert(!offScreenBufferPending, "!offScreenBufferPending");
-
- if (offScreenBuffer != null && offScreenBuffer != buffer) {
- ImageComponent2DRetained i2dRetained =
- (ImageComponent2DRetained)offScreenBuffer.retained;
- i2dRetained.setUsedByOffScreen(false);
- }
-
- if (buffer != null) {
- ImageComponent2DRetained bufferRetained =
- (ImageComponent2DRetained)buffer.retained;
-
- if (bufferRetained.byReference &&
- !(bufferRetained.getRefImage(0) instanceof BufferedImage)) {
-
- throw new IllegalArgumentException(J3dI18N.getString("Canvas3D15"));
- }
-
- if (bufferRetained.getNumberOfComponents() < 3 ) {
- throw new IllegalArgumentException(J3dI18N.getString("Canvas3D16"));
- }
-
- if (buffer.isLive()) {
- throw new IllegalSharingException(J3dI18N.getString("Canvas3D26"));
- }
-
- if (bufferRetained.getInImmCtx()) {
- throw new IllegalSharingException(J3dI18N.getString("Canvas3D27"));
- }
-
- if (buffer != offScreenBuffer && bufferRetained.getUsedByOffScreen()) {
- throw new IllegalSharingException(J3dI18N.getString("Canvas3D28"));
- }
-
- bufferRetained.setUsedByOffScreen(true);
-
- width = bufferRetained.width;
- height = bufferRetained.height;
-
- // Issues 347, 348 - assign a canvasId for off-screen Canvas3D
- if (manualRendering) {
- sendAllocateCanvasId();
- }
- }
- else {
- width = height = 0;
-
- // Issues 347, 348 - release canvasId for off-screen Canvas3D
- if (manualRendering) {
- freeCanvasId = true;
- }
- }
-
- if ((offScreenCanvasSize.width != width) ||
- (offScreenCanvasSize.height != height)) {
-
- if (drawable != null) {
- // Fix for Issue 18 and Issue 175
- // Will do destroyOffScreenBuffer in the Renderer thread.
- sendDestroyCtxAndOffScreenBuffer();
- drawable = null;
- }
- // Issue 396. Since context is invalid here, we should set it to null.
- ctx = null;
-
- // set the canvas dimension according to the buffer dimension
- offScreenCanvasSize.setSize(width, height);
- this.setSize(offScreenCanvasSize);
-
- if (width > 0 && height > 0) {
- sendCreateOffScreenBuffer();
- }
-
- }
- else if (ctx != null) {
- removeCtx();
- }
-
- if (freeCanvasId) {
- sendFreeCanvasId();
- }
-
- offScreenBuffer = buffer;
-
- synchronized(dirtyMaskLock) {
- cvDirtyMask[0] |= MOVED_OR_RESIZED_DIRTY;
- cvDirtyMask[1] |= MOVED_OR_RESIZED_DIRTY;
- }
- }
-
- /**
- * Retrieves the off-screen buffer for this Canvas3D.
- *
- * @return the current off-screen buffer for this Canvas3D.
- *
- * @exception IllegalStateException if this Canvas3D is not in
- * off-screen mode.
- *
- * @since Java 3D 1.2
- */
- public ImageComponent2D getOffScreenBuffer() {
-
- if (!offScreen)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
-
- return (offScreenBuffer);
- }
-
-
- /**
- * Schedules the rendering of a frame into this Canvas3D's
- * off-screen buffer. The rendering is done from the point of
- * view of the View object to which this Canvas3D has been added.
- * No rendering is performed if this Canvas3D object has not been
- * added to an active View. This method does not wait for the rendering
- * to actually happen. An application that wishes to know when
- * the rendering is complete must either subclass Canvas3D and
- * override the <code>postSwap</code> method, or call
- * <code>waitForOffScreenRendering</code>.
- *
- * @exception NullPointerException if the off-screen buffer is null.
- * @exception IllegalStateException if this Canvas3D is not in
- * off-screen mode, or if either the width or the height of
- * the associated Screen3D's size is <= 0, or if the associated
- * Screen3D's physical width or height is <= 0.
- * @exception RestrictedAccessException if an off-screen rendering
- * is already in process for this Canvas3D or if the Java 3D renderer
- * is stopped.
- *
- * @see #setOffScreenBuffer
- * @see Screen3D#setSize(int, int)
- * @see Screen3D#setSize(Dimension)
- * @see Screen3D#setPhysicalScreenWidth
- * @see Screen3D#setPhysicalScreenHeight
- * @see #waitForOffScreenRendering
- * @see #postSwap
- *
- * @since Java 3D 1.2
- */
- public void renderOffScreenBuffer() {
-
- if (!offScreen)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
-
- // Issue 131: Cannot manually render to an automatic canvas.
- if (!manualRendering)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D24"));
-
- // Issue 260 : Cannot render if we already have a fatal error
- if (fatalError) {
- throw new IllegalRenderingStateException(J3dI18N.getString("Canvas3D30"));
- }
-
- if (offScreenBuffer == null)
- throw new NullPointerException(J3dI18N.getString("Canvas3D10"));
-
- Dimension screenSize = screen.getSize();
-
- if (screenSize.width <= 0)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D8"));
-
- if (screenSize.height <= 0)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D9"));
-
- if (screen.getPhysicalScreenWidth() <= 0.0)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D12"));
-
- if (screen.getPhysicalScreenHeight() <= 0.0)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D13"));
-
- if (offScreenRendering)
- throw new RestrictedAccessException(J3dI18N.getString("Canvas3D2"));
-
- if (!isRunning)
- throw new RestrictedAccessException(J3dI18N.getString("Canvas3D11"));
-
- // Fix to issue 66
- if ((!active) || (pendingView == null)) {
- /* No rendering is performed if this Canvas3D object has not been
- added to an active View. */
- return;
- }
-
- // Issue 131: moved code that determines off-screen boundary to separate
- // method that is called from the renderer
-
- offScreenRendering = true;
-
- // Fix to issue 66.
- /* This is an attempt to do the following check in one atomic operation :
- ((view != null) && (view.inCanvasCallback)) */
-
- boolean inCanvasCallback = false;
- try {
- inCanvasCallback = view.inCanvasCallback;
-
- } catch (NullPointerException npe) {
- /* Do nothing here */
- }
-
- if (inCanvasCallback) {
- // Here we assume that view is stable if inCanvasCallback
- // is true. This assumption is valid among all j3d threads as
- // all access to view is synchronized by MasterControl.
- // Issue : user threads access to view isn't synchronize hence
- // is model will break.
- if (screen.renderer == null) {
-
- // It is possible that screen.renderer = null when this View
- // is shared by another onScreen Canvas and this callback
- // is from that Canvas. In this case it need one more
- // round before the renderer.
- screen.renderer = Screen3D.deviceRendererMap.get(screen.graphicsDevice);
- // screen.renderer may equal to null when multiple
- // screen is used and this Canvas3D is in different
- // screen sharing the same View not yet initialize.
- }
-
- // if called from render call back, send a message directly to
- // the renderer message queue, and call renderer doWork
- // to do the offscreen rendering now
- if (Thread.currentThread() == screen.renderer) {
-
- J3dMessage createMessage = new J3dMessage();
- createMessage.threads = J3dThread.RENDER_THREAD;
- createMessage.type = J3dMessage.RENDER_OFFSCREEN;
- createMessage.universe = this.view.universe;
- createMessage.view = this.view;
- createMessage.args[0] = this;
-
- screen.renderer.rendererStructure.addMessage(createMessage);
-
- // modify the args to reflect offScreen rendering
- screen.renderer.args = new Object[4];
- screen.renderer.args[0] = new Integer(Renderer.REQUESTRENDER);
- screen.renderer.args[1] = this;
- screen.renderer.args[2] = view;
- // This extra argument 3 is needed in MasterControl to
- // test whether offscreen Rendering is used or not
- screen.renderer.args[3] = null;
-
- // call renderer doWork directly since we are already in
- // the renderer thread
- screen.renderer.doWork(0);
- } else {
-
- // XXXX:
- // Now we are in trouble, this will cause deadlock if
- // waitForOffScreenRendering() is invoked
- J3dMessage createMessage = new J3dMessage();
- createMessage.threads = J3dThread.RENDER_THREAD;
- createMessage.type = J3dMessage.RENDER_OFFSCREEN;
- createMessage.universe = this.view.universe;
- createMessage.view = this.view;
- createMessage.args[0] = this;
- screen.renderer.rendererStructure.addMessage(createMessage);
- VirtualUniverse.mc.setWorkForRequestRenderer();
- }
-
- } else if (Thread.currentThread() instanceof BehaviorScheduler) {
-
- // If called from behavior scheduler, send a message directly to
- // the renderer message queue.
- // Note that we didn't use
- // currentThread() == view.universe.behaviorScheduler
- // since the caller may be another universe Behavior
- // scheduler.
- J3dMessage createMessage = new J3dMessage();
- createMessage.threads = J3dThread.RENDER_THREAD;
- createMessage.type = J3dMessage.RENDER_OFFSCREEN;
- createMessage.universe = this.view.universe;
- createMessage.view = this.view;
- createMessage.args[0] = this;
- screen.renderer.rendererStructure.addMessage(createMessage);
- VirtualUniverse.mc.setWorkForRequestRenderer();
-
- } else {
- // send a message to renderBin
- // Fix for issue 66 : Since view might not been set yet,
- // we have to use pendingView instead.
- J3dMessage createMessage = new J3dMessage();
- createMessage.threads = J3dThread.UPDATE_RENDER;
- createMessage.type = J3dMessage.RENDER_OFFSCREEN;
- createMessage.universe = this.pendingView.universe;
- createMessage.view = this.pendingView;
- createMessage.args[0] = this;
- createMessage.args[1] = offScreenBuffer;
- VirtualUniverse.mc.processMessage(createMessage);
- }
- }
-
-
- /**
- * Waits for this Canvas3D's off-screen rendering to be done.
- * This method will wait until the <code>postSwap</code> method of this
- * off-screen Canvas3D has completed. If this Canvas3D has not
- * been added to an active view or if the renderer is stopped for this
- * Canvas3D, then this method will return
- * immediately. This method must not be called from a render
- * callback method of an off-screen Canvas3D.
- *
- * @exception IllegalStateException if this Canvas3D is not in
- * off-screen mode, or if this method is called from a render
- * callback method of an off-screen Canvas3D.
- *
- * @see #renderOffScreenBuffer
- * @see #postSwap
- *
- * @since Java 3D 1.2
- */
- public void waitForOffScreenRendering() {
-
- if (!offScreen) {
- throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
- }
-
- if (Thread.currentThread() instanceof Renderer) {
- throw new IllegalStateException(J3dI18N.getString("Canvas3D31"));
- }
-
- while (offScreenRendering) {
- MasterControl.threadYield();
- }
- }
-
-
- /**
- * Sets the location of this off-screen Canvas3D. The location is
- * the upper-left corner of the Canvas3D relative to the
- * upper-left corner of the corresponding off-screen Screen3D.
- * The function of this method is similar to that of
- * <code>Component.setLocation</code> for on-screen Canvas3D
- * objects. The default location is (0,0).
- *
- * @param x the <i>x</i> coordinate of the upper-left corner of
- * the new location.
- * @param y the <i>y</i> coordinate of the upper-left corner of
- * the new location.
- *
- * @exception IllegalStateException if this Canvas3D is not in
- * off-screen mode.
- *
- * @since Java 3D 1.2
- */
- public void setOffScreenLocation(int x, int y) {
-
- if (!offScreen)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
-
- synchronized(cvLock) {
- offScreenCanvasLoc.setLocation(x, y);
- }
- }
-
-
- /**
- * Sets the location of this off-screen Canvas3D. The location is
- * the upper-left corner of the Canvas3D relative to the
- * upper-left corner of the corresponding off-screen Screen3D.
- * The function of this method is similar to that of
- * <code>Component.setLocation</code> for on-screen Canvas3D
- * objects. The default location is (0,0).
- *
- * @param p the point defining the upper-left corner of the new
- * location.
- *
- * @exception IllegalStateException if this Canvas3D is not in
- * off-screen mode.
- *
- * @since Java 3D 1.2
- */
- public void setOffScreenLocation(Point p) {
-
- if (!offScreen)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
-
- synchronized(cvLock) {
- offScreenCanvasLoc.setLocation(p);
- }
- }
-
-
- /**
- * Retrieves the location of this off-screen Canvas3D. The
- * location is the upper-left corner of the Canvas3D relative to
- * the upper-left corner of the corresponding off-screen Screen3D.
- * The function of this method is similar to that of
- * <code>Component.getLocation</code> for on-screen Canvas3D
- * objects.
- *
- * @return a new point representing the upper-left corner of the
- * location of this off-screen Canvas3D.
- *
- * @exception IllegalStateException if this Canvas3D is not in
- * off-screen mode.
- *
- * @since Java 3D 1.2
- */
- public Point getOffScreenLocation() {
- if (!offScreen)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
-
- return (new Point(offScreenCanvasLoc));
- }
-
-
- /**
- * Retrieves the location of this off-screen Canvas3D and stores
- * it in the specified Point object. The location is the
- * upper-left corner of the Canvas3D relative to the upper-left
- * corner of the corresponding off-screen Screen3D. The function
- * of this method is similar to that of
- * <code>Component.getLocation</code> for on-screen Canvas3D
- * objects. This version of <code>getOffScreenLocation</code> is
- * useful if the caller wants to avoid allocating a new Point
- * object on the heap.
- *
- * @param rv Point object into which the upper-left corner of the
- * location of this off-screen Canvas3D is copied.
- * If <code>rv</code> is null, a new Point is allocated.
- *
- * @return <code>rv</code>
- *
- * @exception IllegalStateException if this Canvas3D is not in
- * off-screen mode.
- *
- * @since Java 3D 1.2
- */
- public Point getOffScreenLocation(Point rv) {
-
- if (!offScreen)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D1"));
-
- if (rv == null)
- return (new Point(offScreenCanvasLoc));
-
- else {
- rv.setLocation(offScreenCanvasLoc);
- return rv;
- }
- }
-
- void endOffScreenRendering() {
-
- ImageComponent2DRetained icRetained = (ImageComponent2DRetained)offScreenBuffer.retained;
- boolean isByRef = icRetained.isByReference();
- ImageComponentRetained.ImageData imageData = icRetained.getImageData(false);
-
- if(!isByRef) {
- // If icRetained has a null image ( BufferedImage)
- if (imageData == null) {
- assert (!isByRef);
- icRetained.createBlankImageData();
- imageData = icRetained.getImageData(false);
- }
- // Check for possible format conversion in imageData
- else {
- // Format convert imageData if format is unsupported.
- icRetained.evaluateExtensions(this);
- }
- // read the image from the offscreen buffer
- readOffScreenBuffer(ctx, icRetained.getImageFormatTypeIntValue(false),
- icRetained.getImageDataTypeIntValue(), imageData.get(),
- offScreenCanvasSize.width, offScreenCanvasSize.height);
-
- } else {
- icRetained.geomLock.getLock();
- // Create a copy of format converted image in imageData if format is unsupported.
- icRetained.evaluateExtensions(this);
-
- // read the image from the offscreen buffer
- readOffScreenBuffer(ctx, icRetained.getImageFormatTypeIntValue(false),
- icRetained.getImageDataTypeIntValue(), imageData.get(),
- offScreenCanvasSize.width, offScreenCanvasSize.height);
-
- // For byRef, we might have to copy buffer back into
- // the user's referenced ImageComponent2D
- if(!imageData.isDataByRef()) {
- if(icRetained.isImageTypeSupported()) {
- icRetained.copyToRefImage(0);
- } else {
- // This method only handle RGBA conversion.
- icRetained.copyToRefImageWithFormatConversion(0);
- }
- }
-
- icRetained.geomLock.unLock();
- }
- }
-
- /**
- * Synchronize and swap buffers on a double buffered canvas for
- * this Canvas3D object. This method should only be called if the
- * Java 3D renderer has been stopped. In the normal case, the renderer
- * automatically swaps the buffer.
- * This method calls the <code>flush(true)</code> methods of the
- * associated 2D and 3D graphics contexts, if they have been allocated.
- *
- * @exception RestrictedAccessException if the Java 3D renderer is
- * running.
- * @exception IllegalStateException if this Canvas3D is in
- * off-screen mode.
- *
- * @see #stopRenderer
- * @see GraphicsContext3D#flush
- * @see J3DGraphics2D#flush
- */
- public void swap() {
- if (offScreen)
- throw new IllegalStateException(J3dI18N.getString("Canvas3D14"));
-
- if (isRunning)
- throw new RestrictedAccessException(J3dI18N.getString("Canvas3D0"));
-
- if (!firstPaintCalled) {
- return;
- }
-
- if (view != null && graphicsContext3D != null) {
- if ((view.universe != null) &&
- (Thread.currentThread() == view.universe.behaviorScheduler)) {
- graphicsContext3D.sendRenderMessage(false, GraphicsContext3D.SWAP, null, null);
- } else {
- graphicsContext3D.sendRenderMessage(true, GraphicsContext3D.SWAP, null, null);
- }
- graphicsContext3D.runMonitor(J3dThread.WAIT);
- }
- }
-
- void doSwap() {
-
- if (firstPaintCalled && useDoubleBuffer) {
- try {
- if (validCtx && (ctx != null) && (view != null)) {
- synchronized (drawingSurfaceObject) {
- if (validCtx) {
- if (!drawingSurfaceObject.renderLock()) {
- graphicsContext3D.runMonitor(J3dThread.NOTIFY);
- return;
- }
- this.syncRender(ctx, true);
- swapBuffers(ctx, drawable);
- drawingSurfaceObject.unLock();
- }
- }
- }
- } catch (NullPointerException ne) {
- drawingSurfaceObject.unLock();
- }
- }
- // Increment the elapsedFrame for the behavior structure
- // to trigger any interpolators
- view.universe.behaviorStructure.incElapsedFrames();
- graphicsContext3D.runMonitor(J3dThread.NOTIFY);
- }
-
- /**
- * Wrapper for native createNewContext method.
- */
- Context createNewContext(Context shareCtx, boolean isSharedCtx) {
- Context retVal = createNewContext(
- this.drawable,
- shareCtx, isSharedCtx,
- this.offScreen);
- // compute the max available texture units
- maxAvailableTextureUnits = Math.max(maxTextureUnits, maxTextureImageUnits);
- // reset 'antialiasingSet' if new context is created for an already existing Canvas3D,
- // e.g. resizing offscreen Canvas3D
- antialiasingSet = false;
-
- return retVal;
- }
-
- /**
- * Make the context associated with the specified canvas current.
- */
- final void makeCtxCurrent() {
- makeCtxCurrent(ctx, drawable);
- }
-
- /**
- * Make the specified context current.
- */
- final void makeCtxCurrent(Context ctx) {
- makeCtxCurrent(ctx, drawable);
- }
-
- final void makeCtxCurrent(Context ctx, Drawable drawable) {
- if (ctx != screen.renderer.currentCtx || drawable != screen.renderer.currentDrawable) {
- if (!drawingSurfaceObject.isLocked()) {
- drawingSurfaceObject.renderLock();
- useCtx(ctx, drawable);
- drawingSurfaceObject.unLock();
- } else {
- useCtx(ctx, drawable);
- }
- screen.renderer.currentCtx = ctx;
- screen.renderer.currentDrawable = drawable;
- }
- }
-
- // Give the pipeline a chance to release the context; the Pipeline may
- // or may not ignore this call.
- void releaseCtx() {
- if (screen.renderer.currentCtx != null) {
- boolean needLock = !drawingSurfaceObject.isLocked();
- if (needLock) {
- drawingSurfaceObject.renderLock();
- }
- if (releaseCtx(screen.renderer.currentCtx)) {
- screen.renderer.currentCtx = null;
- screen.renderer.currentDrawable = null;
- }
- if (needLock) {
- drawingSurfaceObject.unLock();
- }
- }
- }
-
-
- /**
- * Sets the position of the manual left eye in image-plate
- * coordinates. This value determines eye placement when a head
- * tracker is not in use and the application is directly controlling
- * the eye position in image-plate coordinates.
- * In head-tracked mode or when the windowEyePointPolicy is
- * RELATIVE_TO_FIELD_OF_VIEW or RELATIVE_TO_COEXISTENCE, this value
- * is ignored. When the
- * windowEyepointPolicy is RELATIVE_TO_WINDOW only the Z value is
- * used.
- * @param position the new manual left eye position
- */
- public void setLeftManualEyeInImagePlate(Point3d position) {
-
- this.leftManualEyeInImagePlate.set(position);
- synchronized(dirtyMaskLock) {
- cvDirtyMask[0] |= EYE_IN_IMAGE_PLATE_DIRTY;
- cvDirtyMask[1] |= EYE_IN_IMAGE_PLATE_DIRTY;
- }
- redraw();
- }
-
- /**
- * Sets the position of the manual right eye in image-plate
- * coordinates. This value determines eye placement when a head
- * tracker is not in use and the application is directly controlling
- * the eye position in image-plate coordinates.
- * In head-tracked mode or when the windowEyePointPolicy is
- * RELATIVE_TO_FIELD_OF_VIEW or RELATIVE_TO_COEXISTENCE, this value
- * is ignored. When the
- * windowEyepointPolicy is RELATIVE_TO_WINDOW only the Z value is
- * used.
- * @param position the new manual right eye position
- */
- public void setRightManualEyeInImagePlate(Point3d position) {
-
- this.rightManualEyeInImagePlate.set(position);
- synchronized(dirtyMaskLock) {
- cvDirtyMask[0] |= EYE_IN_IMAGE_PLATE_DIRTY;
- cvDirtyMask[1] |= EYE_IN_IMAGE_PLATE_DIRTY;
- }
- redraw();
- }
-
- /**
- * Retrieves the position of the user-specified, manual left eye
- * in image-plate
- * coordinates and copies that value into the object provided.
- * @param position the object that will receive the position
- */
- public void getLeftManualEyeInImagePlate(Point3d position) {
- position.set(this.leftManualEyeInImagePlate);
- }
-
- /**
- * Retrieves the position of the user-specified, manual right eye
- * in image-plate
- * coordinates and copies that value into the object provided.
- * @param position the object that will receive the position
- */
- public void getRightManualEyeInImagePlate(Point3d position) {
- position.set(this.rightManualEyeInImagePlate);
- }
-
- /**
- * Retrieves the actual position of the left eye
- * in image-plate
- * coordinates and copies that value into the object provided.
- * This value is a function of the windowEyepointPolicy, the tracking
- * enable flag, and the manual left eye position.
- * @param position the object that will receive the position
- */
- public void getLeftEyeInImagePlate(Point3d position) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- position.set(canvasViewCache.getLeftEyeInImagePlate());
- }
- }
- else {
- position.set(leftManualEyeInImagePlate);
- }
- }
-
- /**
- * Retrieves the actual position of the right eye
- * in image-plate
- * coordinates and copies that value into the object provided.
- * This value is a function of the windowEyepointPolicy, the tracking
- * enable flag, and the manual right eye position.
- * @param position the object that will receive the position
- */
- public void getRightEyeInImagePlate(Point3d position) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- position.set(canvasViewCache.getRightEyeInImagePlate());
- }
- }
- else {
- position.set(rightManualEyeInImagePlate);
- }
- }
-
- /**
- * Retrieves the actual position of the center eye
- * in image-plate
- * coordinates and copies that value into the object provided.
- * The center eye is the fictional eye half-way between the left and
- * right eye.
- * This value is a function of the windowEyepointPolicy, the tracking
- * enable flag, and the manual right and left eye positions.
- * @param position the object that will receive the position
- * @see #setMonoscopicViewPolicy
- */
- // XXXX: This might not make sense for field-sequential HMD.
- public void getCenterEyeInImagePlate(Point3d position) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- position.set(canvasViewCache.getCenterEyeInImagePlate());
- }
- }
- else {
- Point3d cenEye = new Point3d();
- cenEye.add(leftManualEyeInImagePlate, rightManualEyeInImagePlate);
- cenEye.scale(0.5);
- position.set(cenEye);
- }
- }
-
- /**
- * Retrieves the current ImagePlate coordinates to Virtual World
- * coordinates transform and places it into the specified object.
- * @param t the Transform3D object that will receive the
- * transform
- */
- // TODO: Document -- This will return the transform of left plate.
- public void getImagePlateToVworld(Transform3D t) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- t.set(canvasViewCache.getImagePlateToVworld());
- }
- }
- else {
- t.setIdentity();
- }
- }
-
- /**
- * Computes the position of the specified AWT pixel value
- * in image-plate
- * coordinates and copies that value into the object provided.
- * @param x the X coordinate of the pixel relative to the upper-left
- * hand corner of the window.
- * @param y the Y coordinate of the pixel relative to the upper-left
- * hand corner of the window.
- * @param imagePlatePoint the object that will receive the position in
- * physical image plate coordinates (relative to the lower-left
- * corner of the screen).
- */
- // TODO: Document -- This transform the pixel location to the left image plate.
- public void getPixelLocationInImagePlate(int x, int y,
- Point3d imagePlatePoint) {
-
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- imagePlatePoint.x =
- canvasViewCache.getWindowXInImagePlate((double)x);
- imagePlatePoint.y =
- canvasViewCache.getWindowYInImagePlate((double)y);
- imagePlatePoint.z = 0.0;
- }
- } else {
- imagePlatePoint.set(0.0, 0.0, 0.0);
- }
- }
-
-
- void getPixelLocationInImagePlate(double x, double y, double z,
- Point3d imagePlatePoint) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- canvasViewCache.getPixelLocationInImagePlate(
- x, y, z, imagePlatePoint);
- }
- } else {
- imagePlatePoint.set(0.0, 0.0, 0.0);
- }
- }
-
-
- /**
- * Computes the position of the specified AWT pixel value
- * in image-plate
- * coordinates and copies that value into the object provided.
- * @param pixelLocation the coordinates of the pixel relative to
- * the upper-left hand corner of the window.
- * @param imagePlatePoint the object that will receive the position in
- * physical image plate coordinates (relative to the lower-left
- * corner of the screen).
- *
- * @since Java 3D 1.2
- */
- // TODO: Document -- This transform the pixel location to the left image plate.
- public void getPixelLocationInImagePlate(Point2d pixelLocation,
- Point3d imagePlatePoint) {
-
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- imagePlatePoint.x =
- canvasViewCache.getWindowXInImagePlate(pixelLocation.x);
- imagePlatePoint.y =
- canvasViewCache.getWindowYInImagePlate(pixelLocation.y);
- imagePlatePoint.z = 0.0;
- }
- }
- else {
- imagePlatePoint.set(0.0, 0.0, 0.0);
- }
- }
-
-
- /**
- * Projects the specified point from image plate coordinates
- * into AWT pixel coordinates. The AWT pixel coordinates are
- * copied into the object provided.
- * @param imagePlatePoint the position in
- * physical image plate coordinates (relative to the lower-left
- * corner of the screen).
- * @param pixelLocation the object that will receive the coordinates
- * of the pixel relative to the upper-left hand corner of the window.
- *
- * @since Java 3D 1.2
- */
- // TODO: Document -- This transform the pixel location from the left image plate.
- public void getPixelLocationFromImagePlate(Point3d imagePlatePoint,
- Point2d pixelLocation) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- canvasViewCache.getPixelLocationFromImagePlate(
- imagePlatePoint, pixelLocation);
- }
- }
- else {
- pixelLocation.set(0.0, 0.0);
- }
- }
-
- /**
- * Copies the current Vworld projection transform for each eye
- * into the specified Transform3D objects. This transform takes
- * points in virtual world coordinates and projects them into
- * clipping coordinates, which are in the range [-1,1] in
- * <i>X</i>, <i>Y</i>, and <i>Z</i> after clipping and perspective
- * division.
- * In monoscopic mode, the same projection transform will be
- * copied into both the right and left eye Transform3D objects.
- *
- * @param leftProjection the Transform3D object that will receive
- * a copy of the current projection transform for the left eye.
- *
- * @param rightProjection the Transform3D object that will receive
- * a copy of the current projection transform for the right eye.
- *
- * @since Java 3D 1.3
- */
- public void getVworldProjection(Transform3D leftProjection,
- Transform3D rightProjection) {
- if (canvasViewCache != null) {
- ViewPlatformRetained viewPlatformRetained =
- (ViewPlatformRetained)view.getViewPlatform().retained;
-
- synchronized(canvasViewCache) {
- leftProjection.mul(canvasViewCache.getLeftProjection(),
- canvasViewCache.getLeftVpcToEc());
- leftProjection.mul(viewPlatformRetained.getVworldToVpc());
-
- // caluclate right eye if in stereo, otherwise
- // this is the same as the left eye.
- if (useStereo) {
- rightProjection.mul(canvasViewCache.getRightProjection(),
- canvasViewCache.getRightVpcToEc());
- rightProjection.mul(viewPlatformRetained.getVworldToVpc());
- }
- else {
- rightProjection.set(leftProjection);
- }
- }
- }
- else {
- leftProjection.setIdentity();
- rightProjection.setIdentity();
- }
- }
-
- /**
- * Copies the inverse of the current Vworld projection transform
- * for each eye into the specified Transform3D objects. This
- * transform takes points in clipping coordinates, which are in
- * the range [-1,1] in <i>X</i>, <i>Y</i>, and <i>Z</i> after
- * clipping and perspective division, and transforms them into
- * virtual world coordinates.
- * In monoscopic mode, the same inverse projection transform will
- * be copied into both the right and left eye Transform3D objects.
- *
- * @param leftInverseProjection the Transform3D object that will
- * receive a copy of the current inverse projection transform for
- * the left eye.
- * @param rightInverseProjection the Transform3D object that will
- * receive a copy of the current inverse projection transform for
- * the right eye.
- *
- * @since Java 3D 1.3
- */
- public void getInverseVworldProjection(Transform3D leftInverseProjection,
- Transform3D rightInverseProjection) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- leftInverseProjection.set(
- canvasViewCache.getLeftCcToVworld());
-
- // caluclate right eye if in stereo, otherwise
- // this is the same as the left eye.
- if (useStereo) {
- rightInverseProjection.set(
- canvasViewCache.getRightCcToVworld());
- }
- else {
- rightInverseProjection.set(leftInverseProjection);
- }
- }
-
- }
- else {
- leftInverseProjection.setIdentity();
- rightInverseProjection.setIdentity();
- }
- }
-
-
- /**
- * Retrieves the physical width of this canvas window in meters.
- * @return the physical window width in meters.
- */
- public double getPhysicalWidth() {
- double width = 0.0;
-
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- width = canvasViewCache.getPhysicalWindowWidth();
- }
- }
-
- return width;
- }
-
- /**
- * Retrieves the physical height of this canvas window in meters.
- * @return the physical window height in meters.
- */
- public double getPhysicalHeight() {
- double height = 0.0;
-
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- height = canvasViewCache.getPhysicalWindowHeight();
- }
- }
-
- return height;
- }
-
- /**
- * Retrieves the current Virtual World coordinates to ImagePlate
- * coordinates transform and places it into the specified object.
- * @param t the Transform3D object that will receive the
- * transform
- */
- // TODO: Document -- This will return the transform of left plate.
- public void getVworldToImagePlate(Transform3D t) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- t.set(canvasViewCache.getVworldToImagePlate());
- }
- }
- else {
- t.setIdentity();
- }
- }
-
- void getLastVworldToImagePlate(Transform3D t) {
- if (canvasViewCache != null) {
- synchronized(canvasViewCache) {
- t.set(canvasViewCache.getLastVworldToImagePlate());
- }
- }
- else {
- t.setIdentity();
- }
- }
-
- /**
- * Sets view that points to this Canvas3D.
- * @param view view object that points to this Canvas3D
- */
- void setView(View view) {
- pendingView = view;
-
- // We can't set View directly here in user thread since
- // other threads may using canvas.view
- // e.g. In Renderer, we use canvas3d.view.inCallBack
- // before and after postSwap(), if view change in between
- // than view.inCallBack may never reset to false.
- VirtualUniverse.mc.postRequest(MasterControl.SET_VIEW, this);
- evaluateActive();
- }
-
- void computeViewCache() {
- synchronized(cvLock) {
- if (view == null) {
- canvasViewCache = null;
- canvasViewCacheFrustum = null;
- } else {
-
- canvasViewCache = new CanvasViewCache(this,
- screen.screenViewCache,
- view.viewCache);
- // Issue 109 : construct a separate canvasViewCache for
- // computing view frustum
- canvasViewCacheFrustum = new CanvasViewCache(this,
- screen.screenViewCache,
- view.viewCache);
- synchronized (dirtyMaskLock) {
- cvDirtyMask[0] = VIEW_INFO_DIRTY;
- cvDirtyMask[1] = VIEW_INFO_DIRTY;
- }
- }
- }
- }
-
- /**
- * Gets view that points to this Canvas3D.
- * @return view object that points to this Canvas3D
- */
- public View getView() {
- return pendingView;
- }
-
- /**
- * Returns a status flag indicating whether or not stereo
- * is available.
- * This is equivalent to:
- * <ul>
- * <code>
- * ((Boolean)queryProperties().
- * get("stereoAvailable")).
- * booleanValue()
- * </code>
- * </ul>
- *
- * @return a flag indicating whether stereo is available
- */
- public boolean getStereoAvailable() {
- return ((Boolean)queryProperties().get("stereoAvailable")).
- booleanValue();
- }
-
- /**
- * Turns stereo on or off. Note that this attribute is used
- * only when stereo is available. Enabling stereo on a Canvas3D
- * that does not support stereo has no effect.
- * @param flag enables or disables the display of stereo
- *
- * @see #queryProperties
- */
- public void setStereoEnable(boolean flag) {
- stereoEnable = flag;
- useStereo = stereoEnable && stereoAvailable;
- synchronized(dirtyMaskLock) {
- cvDirtyMask[0] |= STEREO_DIRTY;
- cvDirtyMask[1] |= STEREO_DIRTY;
- }
- redraw();
- }
-
- /**
- * Returns a status flag indicating whether or not stereo
- * is enabled.
- * @return a flag indicating whether stereo is enabled
- */
- public boolean getStereoEnable() {
- return this.stereoEnable;
- }
-
-
- /**
- * Specifies how Java 3D generates monoscopic view. If set to
- * View.LEFT_EYE_VIEW, the view generated corresponds to the view as
- * seen from the left eye. If set to View.RIGHT_EYE_VIEW, the view
- * generated corresponds to the view as seen from the right
- * eye. If set to View.CYCLOPEAN_EYE_VIEW, the view generated
- * corresponds to the view as seen from the 'center eye', the
- * fictional eye half-way between the left and right eye. The
- * default monoscopic view policy is View.CYCLOPEAN_EYE_VIEW.
- * <p>
- * NOTE: for backward compatibility with Java 3D 1.1, if this
- * attribute is set to its default value of
- * View.CYCLOPEAN_EYE_VIEW, the monoscopic view policy in the
- * View object will be used. An application should not use both
- * the deprecated View method and this Canvas3D method at the same
- * time.
- * @param policy one of View.LEFT_EYE_VIEW, View.RIGHT_EYE_VIEW, or
- * View.CYCLOPEAN_EYE_VIEW.
- *
- * @exception IllegalStateException if the specified
- * policy is CYCLOPEAN_EYE_VIEW, the canvas is a stereo canvas,
- * and the viewPolicy for the associated view is HMD_VIEW
- *
- * @since Java 3D 1.2
- */
- public void setMonoscopicViewPolicy(int policy) {
-
-
- if((view !=null) && (view.viewPolicy == View.HMD_VIEW) &&
- (monoscopicViewPolicy == View.CYCLOPEAN_EYE_VIEW) &&
- (!useStereo)) {
- throw new
- IllegalStateException(J3dI18N.getString("View31"));
- }
-
- monoscopicViewPolicy = policy;
- synchronized(dirtyMaskLock) {
- cvDirtyMask[0] |= MONOSCOPIC_VIEW_POLICY_DIRTY;
- cvDirtyMask[1] |= MONOSCOPIC_VIEW_POLICY_DIRTY;
- }
- redraw();
- }
-
-
- /**
- * Returns policy on how Java 3D generates monoscopic view.
- * @return policy one of View.LEFT_EYE_VIEW, View.RIGHT_EYE_VIEW or
- * View.CYCLOPEAN_EYE_VIEW.
- *
- * @since Java 3D 1.2
- */
- public int getMonoscopicViewPolicy() {
- return this.monoscopicViewPolicy;
- }
-
-
- /**
- * Returns a status flag indicating whether or not double
- * buffering is available.
- * This is equivalent to:
- * <ul>
- * <code>
- * ((Boolean)queryProperties().
- * get("doubleBufferAvailable")).
- * booleanValue()
- * </code>
- * </ul>
- *
- * @return a flag indicating whether double buffering is available.
- */
- public boolean getDoubleBufferAvailable() {
- return ((Boolean)queryProperties().get("doubleBufferAvailable")).
- booleanValue();
- }
-
- /**
- * Turns double buffering on or off. If double buffering
- * is off, all drawing is to the front buffer and no buffer swap
- * is done between frames. It should be stressed that running
- * Java 3D with double buffering disabled is not recommended.
- * Enabling double buffering on a Canvas3D
- * that does not support double buffering has no effect.
- *
- * @param flag enables or disables double buffering.
- *
- * @see #queryProperties
- */
- public void setDoubleBufferEnable(boolean flag) {
- doubleBufferEnable = flag;
- useDoubleBuffer = doubleBufferEnable && doubleBufferAvailable;
- if (Thread.currentThread() == screen.renderer) {
- setRenderMode(ctx, FIELD_ALL, useDoubleBuffer);
- }
- redraw();
- }
-
- /**
- * Returns a status flag indicating whether or not double
- * buffering is enabled.
- * @return a flag indicating if double buffering is enabled.
- */
- public boolean getDoubleBufferEnable() {
- return doubleBufferEnable;
- }
-
- /**
- * Returns a status flag indicating whether or not scene
- * antialiasing is available.
- * This is equivalent to:
- * <ul>
- * <code>
- * ((Boolean)queryProperties().
- * get("sceneAntialiasingAvailable")).
- * booleanValue()
- * </code>
- * </ul>
- *
- * @return a flag indicating whether scene antialiasing is available.
- */
- public boolean getSceneAntialiasingAvailable() {
- return ((Boolean)queryProperties().get("sceneAntialiasingAvailable")).
- booleanValue();
- }
-
-
- /**
- * Returns a flag indicating whether or not the specified shading
- * language is supported. A ShaderError will be generated if an
- * unsupported shading language is used.
- *
- * @param shadingLanguage the shading language being queried, one of:
- * <code>Shader.SHADING_LANGUAGE_GLSL</code> or
- * <code>Shader.SHADING_LANGUAGE_CG</code>.
- *
- * @return true if the specified shading language is supported,
- * false otherwise.
- *
- * @since Java 3D 1.4
- */
- public boolean isShadingLanguageSupported(int shadingLanguage) {
- // Call queryProperties to ensure that the shading language flags are valid
- queryProperties();
-
- if (shadingLanguage == Shader.SHADING_LANGUAGE_GLSL)
- return shadingLanguageGLSL;
-
- return false;
- }
-
-
- /**
- * Returns a read-only Map object containing key-value pairs that define
- * various properties for this Canvas3D. All of the keys are
- * String objects. The values are key-specific, but most will be
- * Boolean, Integer, Float, Double, or String objects.
- *
- * <p>
- * The currently defined keys are:
- *
- * <p>
- * <ul>
- * <table BORDER=1 CELLSPACING=1 CELLPADDING=1>
- * <tr>
- * <td><b>Key (String)</b></td>
- * <td><b>Value Type</b></td>
- * </tr>
- * <tr>
- * <td><code>shadingLanguageCg</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>shadingLanguageGLSL</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>doubleBufferAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>stereoAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>sceneAntialiasingAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>sceneAntialiasingNumPasses</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>stencilSize</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>texture3DAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureColorTableSize</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureLodRangeAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureLodOffsetAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureWidthMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureHeightMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureBoundaryWidthMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureEnvCombineAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureCombineDot3Available</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureCombineSubtractAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureCoordSetsMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureUnitStateMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureImageUnitsMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureImageUnitsVertexMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureImageUnitsCombinedMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>textureCubeMapAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureDetailAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureSharpenAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureFilter4Available</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>textureAnisotropicFilterDegreeMax</code></td>
- * <td>Float</td>
- * </tr>
- * <tr>
- * <td><code>textureNonPowerOfTwoAvailable</code></td>
- * <td>Boolean</td>
- * </tr>
- * <tr>
- * <td><code>vertexAttrsMax</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>compressedGeometry.majorVersionNumber</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>compressedGeometry.minorVersionNumber</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>compressedGeometry.minorMinorVersionNumber</code></td>
- * <td>Integer</td>
- * </tr>
- * <tr>
- * <td><code>native.version</code></td>
- * <td>String</td>
- * </tr>
- * </table>
- * </ul>
- *
- * <p>
- * The descriptions of the values returned for each key are as follows:
- *
- * <p>
- * <ul>
- * <li>
- * <code>shadingLanguageCg</code>
- * <ul>
- * A Boolean indicating whether or not Cg shading Language
- * is available for this Canvas3D.
- * </ul>
- * </li>
- *
- * <li>
- * <code>shadingLanguageGLSL</code>
- * <ul>
- * A Boolean indicating whether or not GLSL shading Language
- * is available for this Canvas3D.
- * </ul>
- * </li>
- *
- * <li>
- * <code>doubleBufferAvailable</code>
- * <ul>
- * A Boolean indicating whether or not double buffering
- * is available for this Canvas3D. This is equivalent to
- * the getDoubleBufferAvailable method. If this flag is false,
- * the Canvas3D will be rendered in single buffer mode; requests
- * to enable double buffering will be ignored.
- * </ul>
- * </li>
- *
- * <li>
- * <code>stereoAvailable</code>
- * <ul>
- * A Boolean indicating whether or not stereo
- * is available for this Canvas3D. This is equivalent to
- * the getStereoAvailable method. If this flag is false,
- * the Canvas3D will be rendered in monoscopic mode; requests
- * to enable stereo will be ignored.
- * </ul>
- * </li>
- *
- * <li>
- * <code>sceneAntialiasingAvailable</code>
- * <ul>
- * A Boolean indicating whether or not scene antialiasing
- * is available for this Canvas3D. This is equivalent to
- * the getSceneAntialiasingAvailable method. If this flag is false,
- * requests to enable scene antialiasing will be ignored.
- * </ul>
- * </li>
- *
- * <li>
- * <code>sceneAntialiasingNumPasses</code>
- * <ul>
- * An Integer indicating the number of passes scene antialiasing
- * requires to render a single frame for this Canvas3D.
- * If this value is zero, scene antialiasing is not supported.
- * If this value is one, multisampling antialiasing is used.
- * Otherwise, the number indicates the number of rendering passes
- * needed.
- * </ul>
- * </li>
- *
- * <li>
- * <code>stencilSize</code>
- * <ul>
- * An Integer indicating the number of stencil bits that are available
- * for this Canvas3D.
- * </ul>
- * </li>
- *
- * <li>
- * <code>texture3DAvailable</code>
- * <ul>
- * A Boolean indicating whether or not 3D Texture mapping
- * is available for this Canvas3D. If this flag is false,
- * 3D texture mapping is either not supported by the underlying
- * rendering layer or is otherwise unavailable for this
- * particular Canvas3D. All use of 3D texture mapping will be
- * ignored in this case.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureColorTableSize</code>
- * <ul>
- * An Integer indicating the maximum size of the texture color
- * table for this Canvas3D. If the size is 0, the texture
- * color table is either not supported by the underlying rendering
- * layer or is otherwise unavailable for this particular
- * Canvas3D. An attempt to use a texture color table larger than
- * textureColorTableSize will be ignored; no color lookup will be
- * performed.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureLodRangeAvailable</code>
- * <ul>
- * A Boolean indicating whether or not setting only a subset of mipmap
- * levels and setting a range of texture LOD are available for this
- * Canvas3D.
- * If it indicates false, setting a subset of mipmap levels and
- * setting a texture LOD range are not supported by the underlying
- * rendering layer, and an attempt to set base level, or maximum level,
- * or minimum LOD, or maximum LOD will be ignored. In this case,
- * images for all mipmap levels must be defined for the texture to be
- * valid.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureLodOffsetAvailable</code>
- * <ul>
- * A Boolean indicating whether or not setting texture LOD offset is
- * available for this Canvas3D. If it indicates false, setting
- * texture LOD offset is not supported by the underlying rendering
- * layer, and an attempt to set the texture LOD offset will be ignored.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureWidthMax</code>
- * <ul>
- * An Integer indicating the maximum texture width supported by
- * this Canvas3D. If the width of a texture exceeds the maximum texture
- * width for a Canvas3D, then the texture will be effectively disabled
- * for that Canvas3D.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureHeightMax</code>
- * <ul>
- * An Integer indicating the maximum texture height supported by
- * this Canvas3D. If the height of a texture exceeds the maximum texture
- * height for a Canvas3D, then the texture will be effectively disabled
- * for that Canvas3D.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureBoundaryWidthMax</code>
- * <ul>
- * An Integer indicating the maximum texture boundary width
- * supported by the underlying rendering layer for this Canvas3D. If
- * the maximum supported texture boundary width is 0, then texture
- * boundary is not supported by the underlying rendering layer.
- * An attempt to specify a texture boundary width > the
- * textureBoundaryWidthMax will effectively disable the texture.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureEnvCombineAvailable</code>
- * <ul>
- * A Boolean indicating whether or not texture environment combine
- * operation is supported for this Canvas3D. If it indicates false,
- * then texture environment combine is not supported by the
- * underlying rendering layer, and an attempt to specify COMBINE
- * as the texture mode will be ignored. The texture mode in effect
- * will be REPLACE.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureCombineDot3Available</code>
- * <ul>
- * A Boolean indicating whether or not texture combine mode
- * COMBINE_DOT3 is
- * supported for this Canvas3D. If it indicates false, then
- * texture combine mode COMBINE_DOT3 is not supported by
- * the underlying rendering layer, and an attempt to specify
- * COMBINE_DOT3 as the texture combine mode will be ignored.
- * The texture combine mode in effect will be COMBINE_REPLACE.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureCombineSubtractAvailable</code>
- * <ul>
- * A Boolean indicating whether or not texture combine mode
- * COMBINE_SUBTRACT is
- * supported for this Canvas3D. If it indicates false, then
- * texture combine mode COMBINE_SUBTRACT is not supported by
- * the underlying rendering layer, and an attempt to specify
- * COMBINE_SUBTRACT as the texture combine mode will be ignored.
- * The texture combine mode in effect will be COMBINE_REPLACE.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureCoordSetsMax</code>
- * <ul>
- * An Integer indicating the maximum number of texture coordinate sets
- * supported by the underlying rendering layer.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureUnitStateMax</code>
- * <ul>
- * An Integer indicating the maximum number of fixed-function texture units
- * supported by the underlying rendering layer. If the number of
- * application-sepcified texture unit states exceeds the maximum number
- * for a Canvas3D, and the fixed-function rendering pipeline is used, then
- * the texture will be effectively disabled for that Canvas3D.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureImageUnitsMax</code>
- * <ul>
- * An Integer indicating the maximum number of texture image units
- * that can be accessed by the fragment shader when programmable shaders
- * are used.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureImageUnitsVertexMax</code>
- * <ul>
- * An Integer indicating the maximum number of texture image units
- * that can be accessed by the vertex shader when programmable shaders
- * are used.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureImageUnitsCombinedMax</code>
- * <ul>
- * An Integer indicating the combined maximum number of texture image units
- * that can be accessed by the vertex shader and the fragment shader when
- * programmable shaders are used.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureCubeMapAvailable</code>
- * <ul>
- * A Boolean indicating whether or not texture cube map is supported
- * for this Canvas3D. If it indicates false, then texture cube map
- * is not supported by the underlying rendering layer, and an attempt
- * to specify NORMAL_MAP or REFLECTION_MAP as the texture generation
- * mode will be ignored. The texture generation mode in effect will
- * be SPHERE_MAP.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureDetailAvailable</code>
- * <ul>
- * A Boolean indicating whether or not detail texture is supported
- * for this Canvas3D. If it indicates false, then detail texture is
- * not supported by the underlying rendering layer, and an attempt
- * to specify LINEAR_DETAIL, LINEAR_DETAIL_ALPHA or
- * LINEAR_DETAIL_RGB as the texture magnification filter mode will
- * be ignored. The texture magnification filter mode in effect will
- * be BASE_LEVEL_LINEAR.
- * As of Java 3D 1.5, this property is always false.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureSharpenAvailable</code>
- * <ul>
- * A Boolean indicating whether or not sharpen texture is supported
- * for this Canvas3D. If it indicates false, then sharpen texture
- * is not supported by the underlying rendering layer, and an attempt
- * to specify LINEAR_SHARPEN, LINEAR_SHARPEN_ALPHA or
- * LINEAR_SHARPEN_RGB as the texture magnification filter mode
- * will be ignored. The texture magnification filter mode in effect
- * will be BASE_LEVEL_LINEAR.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureFilter4Available</code>
- * <ul>
- * A Boolean indicating whether or not filter4 is supported for this
- * Canvas3D. If it indicates flase, then filter4 is not supported
- * by the underlying rendering layer, and an attempt to specify
- * FILTER_4 as the texture minification filter mode or texture
- * magnification filter mode will be ignored. The texture filter mode
- * in effect will be BASE_LEVEL_LINEAR.
- * </ul>
- * </li>
- *
- * <li>
- * <code>textureAnisotropicFilterDegreeMax</code>
- * <ul>
- * A Float indicating the maximum degree of anisotropic filter
- * available for this Canvas3D. If it indicates 1.0, setting
- * anisotropic filter is not supported by the underlying rendering
- * layer, and an attempt to set anisotropic filter degree will be ignored.
- * </ul>
- * </li>
-
- * <li>
- * <code>textureNonPowerOfTwoAvailable</code>
- * <ul>
- * A Boolean indicating whether or not texture dimensions that are
- * not powers of two are supported for
- * for this Canvas3D. If it indicates false, then textures with
- * non power of two sizes will be ignored. Set the property
- * j3d.textureEnforcePowerOfTwo to revert to the pre-1.5 behavior
- * of throwing exceptions for non power of two textures.
- * </ul>
- * </li>
- *
- * <li>
- * <code>vertexAttrsMax</code>
- * <ul>
- * An Integer indicating the maximum number of vertex attributes
- * supported by the underlying rendering layer. This is in addition to
- * the vertex coordinate (position), color, normal, and so forth.
- * </ul>
- * </li>
- *
- * <li>
- * <code>compressedGeometry.majorVersionNumber</code><br>
- * <code>compressedGeometry.minorVersionNumber</code><br>
- * <code>compressedGeometry.minorMinorVersionNumber</code>
- * <ul>
- * Integers indicating the major, minor, and minor-minor
- * version numbers, respectively, of the version of compressed
- * geometry supported by this version of Java 3D.
- * </ul>
- * </li>
- *
- * <li>
- * <code>native.version</code>
- * <ul>
- * A String indicating the version number of the native graphics
- * library. The format of this string is defined by the native
- * library.
- * </ul>
- * </li>
- * </ul>
- *
- * @return the properties of this Canavs3D
- *
- * @since Java 3D 1.2
- */
- public final Map queryProperties() {
- if (queryProps == null) {
- boolean createDummyCtx = false;
-
- synchronized (VirtualUniverse.mc.contextCreationLock) {
- if (ctx == null) {
- createDummyCtx = true;
- }
- }
-
- if (createDummyCtx) {
- GraphicsConfigTemplate3D.setQueryProps(this);
- }
-
- //create query Properties
- createQueryProps();
- }
-
- if (fatalError) {
- throw new IllegalStateException(J3dI18N.getString("Canvas3D29"));
- }
-
- return queryProps;
- }
-
- void createQueryContext() {
- // create a dummy context to query for support of certain
- // extensions, the context will destroy immediately
- // inside the native code after setting the various
- // fields in this object
- createQueryContext(drawable, offScreen, 1, 1);
- // compute the max available texture units
- maxAvailableTextureUnits = Math.max(maxTextureUnits, maxTextureImageUnits);
- }
-
- /**
- * Creates the query properties for this Canvas.
- */
- private void createQueryProps() {
- // Create lists of keys and values
- ArrayList<String> keys = new ArrayList<String>();
- ArrayList<Object> values = new ArrayList<Object>();
- int pass = 0;
-
- // properties not associated with graphics context
- keys.add("doubleBufferAvailable");
- values.add(new Boolean(doubleBufferAvailable));
-
- keys.add("stereoAvailable");
- values.add(new Boolean(stereoAvailable));
-
- keys.add("sceneAntialiasingAvailable");
- values.add(new Boolean(sceneAntialiasingAvailable));
-
- keys.add("sceneAntialiasingNumPasses");
-
- if (sceneAntialiasingAvailable) {
- pass = (sceneAntialiasingMultiSamplesAvailable ?
- 1: Renderer.NUM_ACCUMULATION_SAMPLES);
- }
- values.add(new Integer(pass));
-
- keys.add("stencilSize");
- // Return the actual stencil size if the user owns it, otherwise
- // return 0
- if (userStencilAvailable) {
- values.add(new Integer(actualStencilSize));
- } else {
- values.add(new Integer(0));
- }
-
- keys.add("compressedGeometry.majorVersionNumber");
- values.add(new Integer(GeometryDecompressor.majorVersionNumber));
- keys.add("compressedGeometry.minorVersionNumber");
- values.add(new Integer(GeometryDecompressor.minorVersionNumber));
- keys.add("compressedGeometry.minorMinorVersionNumber");
- values.add(new Integer(GeometryDecompressor.minorMinorVersionNumber));
-
- // Properties associated with graphics context
- keys.add("texture3DAvailable");
- values.add(new Boolean((textureExtendedFeatures & TEXTURE_3D) != 0));
-
- keys.add("textureColorTableSize");
- values.add(new Integer(textureColorTableSize));
-
- keys.add("textureEnvCombineAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_COMBINE) != 0));
-
- keys.add("textureCombineDot3Available");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_COMBINE_DOT3) != 0));
-
- keys.add("textureCombineSubtractAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_COMBINE_SUBTRACT) != 0));
-
- keys.add("textureCubeMapAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_CUBE_MAP) != 0));
-
- keys.add("textureSharpenAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_SHARPEN) != 0));
-
- keys.add("textureDetailAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_DETAIL) != 0));
-
- keys.add("textureFilter4Available");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_FILTER4) != 0));
-
- keys.add("textureAnisotropicFilterDegreeMax");
- values.add(new Float(anisotropicDegreeMax));
-
- keys.add("textureWidthMax");
- values.add(new Integer(textureWidthMax));
-
- keys.add("textureHeightMax");
- values.add(new Integer(textureHeightMax));
-
- keys.add("texture3DWidthMax");
- values.add(new Integer(texture3DWidthMax));
-
- keys.add("texture3DHeightMax");
- values.add(new Integer(texture3DHeightMax));
-
- keys.add("texture3DDepthMax");
- values.add(new Integer(texture3DDepthMax));
-
- keys.add("textureBoundaryWidthMax");
- values.add(new Integer(textureBoundaryWidthMax));
-
- keys.add("textureLodRangeAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_LOD_RANGE) != 0));
-
- keys.add("textureLodOffsetAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_LOD_OFFSET) != 0));
-
- keys.add("textureNonPowerOfTwoAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_NON_POWER_OF_TWO) != 0));
-
- keys.add("textureAutoMipMapGenerationAvailable");
- values.add(new Boolean(
- (textureExtendedFeatures & TEXTURE_AUTO_MIPMAP_GENERATION) != 0));
-
- keys.add("textureCoordSetsMax");
- values.add(new Integer(maxTexCoordSets));
-
- keys.add("textureUnitStateMax");
- values.add(new Integer(maxTextureUnits));
-
- keys.add("textureImageUnitsMax");
- values.add(new Integer(maxTextureImageUnits));
-
- keys.add("textureImageUnitsVertexMax");
- values.add(new Integer(maxVertexTextureImageUnits));
-
- keys.add("textureImageUnitsCombinedMax");
- values.add(new Integer(maxCombinedTextureImageUnits));
-
- keys.add("vertexAttrsMax");
- values.add(new Integer(maxVertexAttrs));
-
- keys.add("shadingLanguageGLSL");
- values.add(new Boolean(shadingLanguageGLSL));
-
- keys.add("native.version");
- values.add(nativeGraphicsVersion);
-
- keys.add("native.vendor");
- values.add(nativeGraphicsVendor);
-
- keys.add("native.renderer");
- values.add(nativeGraphicsRenderer);
-
- // Now Create read-only properties object
- queryProps = new J3dQueryProps(keys, values);
- }
-
-
- /**
- * Update the view cache associated with this canvas.
- */
- void updateViewCache(boolean flag, CanvasViewCache cvc,
- BoundingBox frustumBBox, boolean doInfinite) {
-
- assert cvc == null;
- synchronized(cvLock) {
- if (firstPaintCalled && (canvasViewCache != null)) {
- assert canvasViewCacheFrustum != null;
- // Issue 109 : choose the appropriate cvCache
- if (frustumBBox != null) {
- canvasViewCacheFrustum.snapshot(true);
- canvasViewCacheFrustum.computeDerivedData(flag, null,
- frustumBBox, doInfinite);
- } else {
- canvasViewCache.snapshot(false);
- canvasViewCache.computeDerivedData(flag, null,
- null, doInfinite);
- }
- }
- }
- }
-
- /**
- * Set depthBufferWriteEnableOverride flag
- */
- void setDepthBufferWriteEnableOverride(boolean flag) {
- depthBufferWriteEnableOverride = flag;
- }
-
- /**
- * Set depthBufferEnableOverride flag
- */
- void setDepthBufferEnableOverride(boolean flag) {
- depthBufferEnableOverride = flag;
- }
-
- // Static initializer for Canvas3D class
- static {
- VirtualUniverse.loadLibraries();
- }
-
-
- void resetTexture(Context ctx, int texUnitIndex) {
- // D3D also need to reset texture attributes
- this.resetTextureNative(ctx, texUnitIndex);
-
- if (texUnitIndex < 0) {
- texUnitIndex = 0;
- }
- texUnitState[texUnitIndex].mirror = null;
- texUnitState[texUnitIndex].texture = null;
- }
-
-// reset all attributes so that everything e.g. display list,
-// texture will recreate again in the next frame
-void resetRendering() {
- reset();
-
- synchronized (dirtyMaskLock) {
- cvDirtyMask[0] |= VIEW_INFO_DIRTY;
- cvDirtyMask[1] |= VIEW_INFO_DIRTY;
- }
-
-}
-
- void reset() {
- int i;
- currentAppear = new AppearanceRetained();
- currentMaterial = new MaterialRetained();
- viewFrustum = new CachedFrustum();
- canvasDirty = 0xffff;
- lightBin = null;
- environmentSet = null;
- attributeBin = null;
- shaderBin = null;
- textureBin = null;
- renderMolecule = null;
- polygonAttributes = null;
- lineAttributes = null;
- pointAttributes = null;
- material = null;
- enableLighting = false;
- transparency = null;
- coloringAttributes = null;
- shaderProgram = null;
- texture = null;
- texAttrs = null;
- if (texUnitState != null) {
- TextureUnitStateRetained tus;
- for (i=0; i < texUnitState.length; i++) {
- tus = texUnitState[i];
- if (tus != null) {
- tus.texAttrs = null;
- tus.texGen = null;
- }
- }
- }
- texCoordGeneration = null;
- renderingAttrs = null;
- appearance = null;
- appHandle = null;
- dirtyRenderMoleculeList.clear();
- displayListResourceFreeList.clear();
-
- dirtyDlistPerRinfoList.clear();
- textureIdResourceFreeList.clear();
-
- lightChanged = true;
- modelMatrix = null;
- modelClip = null;
- fog = null;
- sceneAmbient = new Color3f();
-
-
- for (i=0; i< frameCount.length;i++) {
- frameCount[i] = -1;
- }
-
- for (i=0; i < lights.length; i++) {
- lights[i] = null;
- }
-
- if (currentLights != null) {
- for (i=0; i < currentLights.length; i++) {
- currentLights[i] = null;
- }
- }
-
- enableMask = -1;
- stateUpdateMask = 0;
- depthBufferWriteEnableOverride = false;
- depthBufferEnableOverride = false;
- depthBufferWriteEnable = true;
- vfPlanesValid = false;
- lightChanged = false;
-
- for (i=0; i < curStateToUpdate.length; i++) {
- curStateToUpdate[i] = null;
- }
-
- // Issue 362 - need to reset display lists and ctxTimeStamp in this
- // method, so that display lists will be recreated when canvas is
- // removed from a view and then added back into a view with another
- // canvas
- needToRebuildDisplayList = true;
- ctxTimeStamp = VirtualUniverse.mc.getContextTimeStamp();
- }
-
-
-void resetImmediateRendering() {
- canvasDirty = 0xffff;
- ra = null;
-
- setSceneAmbient(ctx, 0.0f, 0.0f, 0.0f);
- disableFog(ctx);
- resetRenderingAttributes(ctx, false, false);
-
- resetTexture(ctx, -1);
- resetTexCoordGeneration(ctx);
- resetTextureAttributes(ctx);
- texUnitState[0].texAttrs = null;
- texUnitState[0].texGen = null;
-
- resetPolygonAttributes(ctx);
- resetLineAttributes(ctx);
- resetPointAttributes(ctx);
- resetTransparency(ctx,
- RenderMolecule.SURFACE,
- PolygonAttributes.POLYGON_FILL,
- false, false);
- resetColoringAttributes(ctx,
- 1.0f, 1.0f,
- 1.0f, 1.0f, false);
- updateMaterial(ctx, 1.0f, 1.0f, 1.0f, 1.0f);
- resetRendering();
- makeCtxCurrent();
- synchronized (dirtyMaskLock) {
- cvDirtyMask[0] |= VIEW_INFO_DIRTY;
- cvDirtyMask[1] |= VIEW_INFO_DIRTY;
- }
- needToRebuildDisplayList = true;
-
- ctxTimeStamp = VirtualUniverse.mc.getContextTimeStamp();
-}
-
-@Override
-public Point getLocationOnScreen() {
- try {
- return super.getLocationOnScreen();
- }
- catch (IllegalComponentStateException e) {}
-
- return new Point();
-}
-
- void setProjectionMatrix(Context ctx, Transform3D projTrans) {
- this.projTrans = projTrans;
- setProjectionMatrix(ctx, projTrans.mat);
- }
-
- void setModelViewMatrix(Context ctx, double[] viewMatrix, Transform3D mTrans) {
- setModelViewMatrix(ctx, viewMatrix, mTrans.mat);
- if (!useStereo) {
- this.modelMatrix = mTrans;
- } else {
- // TODO : This seems wrong to do only for the right eye.
- // A possible approach is to invalidate the cache at begin of
- // each eye.
- if (rightStereoPass) {
- // Only set cache in right stereo pass, otherwise
- // if the left stereo pass set the cache value,
- // setModelViewMatrix() in right stereo pass will not
- // perform in RenderMolecules.
- this.modelMatrix = mTrans;
- }
- }
- }
-
- void setDepthBufferWriteEnable(boolean mode) {
- depthBufferWriteEnable = mode;
- setDepthBufferWriteEnable(ctx, mode);
- }
-
- void setNumActiveTexUnit(int n) {
- numActiveTexUnit = n;
- }
-
- int getNumActiveTexUnit() {
- return numActiveTexUnit;
- }
-
- void setLastActiveTexUnit(int n) {
- lastActiveTexUnit = n;
- }
-
- int getLastActiveTexUnit() {
- return lastActiveTexUnit;
- }
-
- // Create the texture state array
- void createTexUnitState() {
- texUnitState = new TextureUnitStateRetained[maxAvailableTextureUnits];
- for (int t = 0; t < maxAvailableTextureUnits; t++) {
- texUnitState[t] = new TextureUnitStateRetained();
- texUnitState[t].texture = null;
- texUnitState[t].mirror = null;
- }
- }
-
- /**
- * Enable separate specular color if it is not overriden by the
- * property j3d.disableSeparateSpecular.
- */
- void enableSeparateSpecularColor() {
- boolean enable = !VirtualUniverse.mc.disableSeparateSpecularColor;
- updateSeparateSpecularColorEnable(ctx, enable);
- }
-
- // Send a createOffScreenBuffer message to Renderer (via
- // MasterControl) and wait for it to be done
- private void sendCreateOffScreenBuffer() {
- // Wait for the buffer to be created unless called from
- // a Behavior or from a Rendering thread
- if (!(Thread.currentThread() instanceof BehaviorScheduler) &&
- !(Thread.currentThread() instanceof Renderer)) {
-
- offScreenBufferPending = true;
- }
-
- // Send message to Renderer thread to perform createOffScreenBuffer.
- VirtualUniverse.mc.sendCreateOffScreenBuffer(this);
-
- // Wait for off-screen buffer to be created
- while (offScreenBufferPending) {
- // Issue 364: create master control thread if needed
- VirtualUniverse.mc.createMasterControlThread();
- MasterControl.threadYield();
- }
- }
-
- // Send a destroyOffScreenBuffer message to Renderer (via
- // MasterControl) and wait for it to be done
- private void sendDestroyCtxAndOffScreenBuffer() {
- // Wait for the buffer to be destroyed unless called from
- // a Behavior or from a Rendering thread
- Thread currentThread = Thread.currentThread();
- if (!(currentThread instanceof BehaviorScheduler) &&
- !(currentThread instanceof Renderer)) {
-
- offScreenBufferPending = true;
- }
-
- // Fix for Issue 18 and Issue 175
- // Send message to Renderer thread to perform remove Ctx and destroyOffScreenBuffer.
-
- VirtualUniverse.mc.sendDestroyCtxAndOffScreenBuffer(this);
-
- // Wait for ctx and off-screen buffer to be destroyed
- while (offScreenBufferPending) {
- // Issue 364: create master control thread if needed
- VirtualUniverse.mc.createMasterControlThread();
- MasterControl.threadYield();
- }
- }
-
- // Send a allocateCanvasId message to Renderer (via MasterControl) without
- // waiting for it to be done
- private void sendAllocateCanvasId() {
- // Send message to Renderer thread to allocate a canvasId
- VirtualUniverse.mc.sendAllocateCanvasId(this);
- }
-
- // Send a freeCanvasId message to Renderer (via MasterControl) without
- // waiting for it to be done
- private void sendFreeCanvasId() {
- // Send message to Renderer thread to free the canvasId
- VirtualUniverse.mc.sendFreeCanvasId(this);
- }
-
- private void removeCtx() {
-
- if ((screen != null) &&
- (screen.renderer != null) &&
- (ctx != null)) {
- VirtualUniverse.mc.postRequest(MasterControl.FREE_CONTEXT,
- new Object[]{this,
- Long.valueOf(0L),
- drawable,
- ctx});
- // Fix for Issue 19
- // Wait for the context to be freed unless called from
- // a Behavior or from a Rendering thread
- Thread currentThread = Thread.currentThread();
- if (!(currentThread instanceof BehaviorScheduler) &&
- !(currentThread instanceof Renderer)) {
- while (ctxTimeStamp != 0) {
- MasterControl.threadYield();
- }
- }
- ctx = null;
- }
- }
-
- /**
- * Serialization of Canvas3D objects is not supported.
- *
- * @exception UnsupportedOperationException this method is not supported
- *
- * @since Java 3D 1.3
- */
- private void writeObject(java.io.ObjectOutputStream out)
- throws java.io.IOException {
-
- throw new UnsupportedOperationException(J3dI18N.getString("Canvas3D20"));
- }
-
- /**
- * Serialization of Canvas3D objects is not supported.
- *
- * @exception UnsupportedOperationException this method is not supported
- *
- * @since Java 3D 1.3
- */
- private void readObject(java.io.ObjectInputStream in)
- throws java.io.IOException, ClassNotFoundException {
-
- throw new UnsupportedOperationException(J3dI18N.getString("Canvas3D20"));
- }
-
-
- // mark that the current bin specified by the bit is already updated
- void setStateIsUpdated(int bit) {
- stateUpdateMask &= ~(1 << bit);
- }
-
- // mark that the bin specified by the bit needs to be updated
- void setStateToUpdate(int bit, Object bin) {
- stateUpdateMask |= 1 << bit;
- curStateToUpdate[bit] = bin;
- }
-
- // update LightBin, EnvironmentSet, AttributeBin & ShaderBin if neccessary
- // according to the stateUpdateMask
-
- static int ENV_STATE_MASK = (1 << LIGHTBIN_BIT) |
- (1 << ENVIRONMENTSET_BIT) |
- (1 << ATTRIBUTEBIN_BIT) |
- (1 << SHADERBIN_BIT);
-
- void updateEnvState() {
-
- if ((stateUpdateMask & ENV_STATE_MASK) == 0)
- return;
-
- if ((stateUpdateMask & (1 << LIGHTBIN_BIT)) != 0) {
- ((LightBin)curStateToUpdate[LIGHTBIN_BIT]).updateAttributes(this);
- }
-
- if ((stateUpdateMask & (1 << ENVIRONMENTSET_BIT)) != 0) {
- ((EnvironmentSet)
- curStateToUpdate[ENVIRONMENTSET_BIT]).updateAttributes(this);
- }
-
- if ((stateUpdateMask & (1 << ATTRIBUTEBIN_BIT)) != 0) {
- ((AttributeBin)
- curStateToUpdate[ATTRIBUTEBIN_BIT]).updateAttributes(this);
- }
-
- if ((stateUpdateMask & (1 << SHADERBIN_BIT)) != 0) {
- ((ShaderBin)
- curStateToUpdate[SHADERBIN_BIT]).updateAttributes(this);
- }
-
-
- // reset the state update mask for those environment state bits
- stateUpdateMask &= ~ENV_STATE_MASK;
- }
-
- /**
- * update state if neccessary according to the stateUpdatedMask
- */
- void updateState( int dirtyBits) {
-
-
- if (stateUpdateMask == 0)
- return;
-
- updateEnvState();
-
- if ((stateUpdateMask & (1 << TEXTUREBIN_BIT)) != 0) {
- ((TextureBin)
- curStateToUpdate[TEXTUREBIN_BIT]).updateAttributes(this);
- }
-
- if ((stateUpdateMask & (1 << RENDERMOLECULE_BIT)) != 0) {
- ((RenderMolecule)
- curStateToUpdate[RENDERMOLECULE_BIT]).updateAttributes(this,
- dirtyBits);
-
- }
-
- if ((stateUpdateMask & (1 << TRANSPARENCY_BIT)) != 0) {
- ((RenderMolecule)curStateToUpdate[RENDERMOLECULE_BIT]).updateTransparencyAttributes(this);
- stateUpdateMask &= ~(1 << TRANSPARENCY_BIT);
- }
-
- // reset state update mask
- stateUpdateMask = 0;
- }
-
-
- // This method updates this Texture2D for raster.
- // Note : No multi-texture is not used.
- void updateTextureForRaster(Texture2DRetained texture) {
-
- // Setup texture and texture attributes for texture unit 0.
- Pipeline.getPipeline().updateTextureUnitState(ctx, 0, true);
- setLastActiveTexUnit(0);
- setNumActiveTexUnit(1);
-
- texture.updateNative(this);
- resetTexCoordGeneration(ctx);
- resetTextureAttributes(ctx);
-
- for(int i=1; i < maxTextureUnits; i++) {
- resetTexture(ctx, i);
- }
-
- // set the active texture unit back to 0
- activeTextureUnit(ctx, 0);
-
- // Force the next textureBin to reload.
- canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
- }
-
- void restoreTextureBin() {
-
- // Need to check TextureBin's shaderBin for null
- // TextureBin can get clear() if there isn't any RM under it.
- if((textureBin != null) && (textureBin.shaderBin != null)) {
- textureBin.updateAttributes(this);
- }
- }
-
- void textureFill(RasterRetained raster, Point2d winCoord,
- float mapZ, float alpha) {
-
- int winWidth = canvasViewCache.getCanvasWidth();
- int winHeight = canvasViewCache.getCanvasHeight();
-
- int rasterImageWidth = raster.image.width;
- int rasterImageHeight = raster.image.height;
-
- float texMinU = 0, texMinV = 0, texMaxU = 0, texMaxV = 0;
- float mapMinX = 0, mapMinY = 0, mapMaxX = 0, mapMaxY = 0;
-
- Point rasterSrcOffset = new Point();
- raster.getSrcOffset(rasterSrcOffset);
-
- Dimension rasterSize = new Dimension();
- raster.getSize(rasterSize);
-
-// System.err.println("rasterImageWidth " + rasterImageWidth + " rasterImageHeight " + rasterImageHeight);
-// System.err.println("rasterSrcOffset " + rasterSrcOffset + " rasterSize " + rasterSize);
-
- int rasterMinX = rasterSrcOffset.x;
- int rasterMaxX = rasterSrcOffset.x + rasterSize.width;
- int rasterMinY = rasterSrcOffset.y;
- int rasterMaxY = rasterSrcOffset.y + rasterSize.height;
-
- if ((rasterMinX >= rasterImageWidth) || (rasterMinY >= rasterImageHeight) ||
- (rasterMaxX <= 0) || (rasterMaxY <= 0)) {
- return;
- }
-
- if (rasterMinX < 0) {
- rasterMinX = 0;
- }
- if (rasterMinY < 0) {
- rasterMinY = 0;
- }
-
- if (rasterMaxX > rasterImageWidth) {
- rasterMaxX = rasterImageWidth;
- }
-
- if (rasterMaxY > rasterImageHeight) {
- rasterMaxY = rasterImageHeight;
- }
-
- texMinU = (float) rasterMinX / (float) rasterImageWidth;
- texMaxU = (float) rasterMaxX / (float) rasterImageWidth;
- mapMinX = (float) winCoord.x / (float) winWidth;
- mapMaxX = (float) (winCoord.x + (rasterMaxX - rasterMinX)) / (float) winWidth;
-
- if (raster.image.isYUp()) {
- texMinV = (float) rasterMinY / (float) rasterImageHeight;
- texMaxV = (float) rasterMaxY / (float) rasterImageHeight;
- } else {
- // System.err.println("In yUp is false case");
- texMinV = 1.0f - (float) rasterMaxY / (float) rasterImageHeight;
- texMaxV = 1.0f - (float) rasterMinY / (float) rasterImageHeight;
- }
-
- mapMinY = 1.0f - ((float) (winCoord.y + (rasterMaxY - rasterMinY)) / (float) winHeight);
- mapMaxY = 1.0f - ((float) winCoord.y / (float) winHeight);
-
- textureFillRaster(ctx, texMinU, texMaxU, texMinV, texMaxV,
- mapMinX, mapMaxX, mapMinY, mapMaxY, mapZ, alpha, raster.image.useBilinearFilter());
-
- }
-
- void textureFill(BackgroundRetained bg, int winWidth, int winHeight) {
-
- final int maxX = bg.image.width;
- final int maxY = bg.image.height;
-
-// System.err.println("maxX " + maxX + " maxY " + maxY);
-
- float xzoom = (float)winWidth / maxX;
- float yzoom = (float)winHeight / maxY;
- float zoom = 0;
- float texMinU = 0, texMinV = 0, texMaxU = 0, texMaxV = 0, adjustV = 0;
- float mapMinX = 0, mapMinY = 0, mapMaxX = 0, mapMaxY = 0;
- float halfWidth = 0, halfHeight = 0;
-
- switch (bg.imageScaleMode) {
- case Background.SCALE_NONE:
- texMinU = 0.0f;
- texMinV = 0.0f;
- texMaxU = 1.0f;
- texMaxV = 1.0f;
- halfWidth = (float)winWidth/2.0f;
- halfHeight = (float)winHeight/2.0f;
- mapMinX = (float) ((0 - halfWidth)/halfWidth);
- mapMinY = (float) ((0 - halfHeight)/halfHeight);
- mapMaxX = (float) ((maxX - halfWidth)/halfWidth);
- mapMaxY = (float) ((maxY - halfHeight)/halfHeight);
- adjustV = ((float)winHeight - (float)maxY)/halfHeight;
- mapMinY += adjustV;
- mapMaxY += adjustV;
- break;
- case Background.SCALE_FIT_MIN:
- zoom = Math.min(xzoom, yzoom);
- texMinU = 0.0f;
- texMinV = 0.0f;
- texMaxU = 1.0f;
- texMaxV = 1.0f;
- mapMinX = -1.0f;
- mapMaxY = 1.0f;
- if (xzoom < yzoom) {
- mapMaxX = 1.0f;
- mapMinY = -1.0f + 2.0f * ( 1.0f - zoom * (float)maxY/(float) winHeight );
- } else {
- mapMaxX = -1.0f + zoom * (float)maxX/winWidth * 2;
- mapMinY = -1.0f;
- }
- break;
- case Background.SCALE_FIT_MAX:
- zoom = Math.max(xzoom, yzoom);
- mapMinX = -1.0f;
- mapMinY = -1.0f;
- mapMaxX = 1.0f;
- mapMaxY = 1.0f;
- if (xzoom < yzoom) {
- texMinU = 0.0f;
- texMinV = 0.0f;
- texMaxU = (float)winWidth/maxX/zoom;
- texMaxV = 1.0f;
- } else {
- texMinU = 0.0f;
- texMinV = 1.0f - (float)winHeight/maxY/zoom;
- texMaxU = 1.0f;
- texMaxV = 1.0f;
- }
- break;
- case Background.SCALE_FIT_ALL:
- texMinU = 0.0f;
- texMinV = 0.0f;
- texMaxU = 1.0f;
- texMaxV = 1.0f;
- mapMinX = -1.0f;
- mapMinY = -1.0f;
- mapMaxX = 1.0f;
- mapMaxY = 1.0f;
- break;
- case Background.SCALE_REPEAT:
-
- texMinU = 0.0f;
- texMinV = - yzoom;
- texMaxU = xzoom;
- texMaxV = 0.0f;
- mapMinX = -1.0f;
- mapMinY = -1.0f;
- mapMaxX = 1.0f;
- mapMaxY = 1.0f;
- break;
- case Background.SCALE_NONE_CENTER:
- // TODO : Why is there a zoom ?
- if(xzoom >= 1.0f){
- texMinU = 0.0f;
- texMaxU = 1.0f;
- mapMinX = -(float)maxX/winWidth;
- mapMaxX = (float)maxX/winWidth;
- } else {
- texMinU = 0.5f - (float)winWidth/maxX/2;
- texMaxU = 0.5f + (float)winWidth/maxX/2;
- mapMinX = -1.0f;
- mapMaxX = 1.0f;
- }
- if (yzoom >= 1.0f) {
- texMinV = 0.0f;
- texMaxV = 1.0f;
- mapMinY = -(float)maxY/winHeight;
- mapMaxY = (float)maxY/winHeight;
- } else {
- texMinV = 0.5f - (float)winHeight/maxY/2;
- texMaxV = 0.5f + (float)winHeight/maxY/2;
- mapMinY = -1.0f;
- mapMaxY = 1.0f;
- }
- break;
- }
-
-// System.err.println("Java 3D : mapMinX " + mapMinX + " mapMinY " + mapMinY +
-// " mapMaxX " + mapMaxX + " mapMaxY " + mapMaxY);
- textureFillBackground(ctx, texMinU, texMaxU, texMinV, texMaxV,
- mapMinX, mapMaxX, mapMinY, mapMaxY, bg.image.useBilinearFilter());
-
- }
-
-
- void clear(BackgroundRetained bg, int winWidth, int winHeight) {
-
- // Issue 239 - clear stencil if requested and available
- // Note that this is a partial solution, since we eventually want an API
- // to control this.
- boolean clearStencil = VirtualUniverse.mc.stencilClear &&
- userStencilAvailable;
-
- clear(ctx, bg.color.x, bg.color.y, bg.color.z, clearStencil);
-
- // TODO : This is a bug on not mirror bg. Will fix this as a bug after 1.5 beta.
- // For now, as a workaround, we will check bg.image and bg.image.imageData not null.
- if((bg.image != null) && (bg.image.imageData != null)) {
- // setup Texture pipe.
- updateTextureForRaster(bg.texture);
-
- textureFill(bg, winWidth, winHeight);
-
- // Restore texture pipe.
- restoreTextureBin();
- }
- }
-
- /**
- * obj is either TextureRetained or DetailTextureImage
- * if obj is DetailTextureImage then we just clear
- * the resourceCreationMask of all the formats
- * no matter it is create or not since we don't
- * remember the format information for simplicity.
- * We don't need to check duplicate value of id in the
- * table since this procedure is invoke only when id
- * of texture is -1 one time only.
- * This is always call from Renderer thread.
- */
-void addTextureResource(int id, TextureRetained obj) {
- if (id <= 0) {
- return;
- }
-
- if (useSharedCtx) {
- screen.renderer.addTextureResource(id, obj);
- } else {
- // This will replace the previous key if exists
- if (textureIDResourceTable.size() <= id) {
- for (int i=textureIDResourceTable.size();
- i < id; i++) {
- textureIDResourceTable.add(null);
- }
- textureIDResourceTable.add(obj);
- } else {
- textureIDResourceTable.set(id, obj);
- }
-
- }
- }
-
- // handle free resource in the FreeList
- void freeResourcesInFreeList(Context ctx) {
- Iterator<Integer> it;
- int val;
-
- // free resource for those canvases that
- // don't use shared ctx
- if (displayListResourceFreeList.size() > 0) {
- for (it = displayListResourceFreeList.iterator(); it.hasNext();) {
- val = it.next().intValue();
- if (val <= 0) {
- continue;
- }
- Canvas3D.freeDisplayList(ctx, val);
- }
- displayListResourceFreeList.clear();
- }
-
- if (textureIdResourceFreeList.size() > 0) {
- for (it = textureIdResourceFreeList.iterator(); it.hasNext();) {
- val = it.next().intValue();
- if (val <= 0) {
- continue;
- }
- if (val >= textureIDResourceTable.size()) {
- System.err.println("Error in freeResourcesInFreeList : ResourceIDTableSize = " +
- textureIDResourceTable.size() +
- " val = " + val);
- } else {
- TextureRetained tex = textureIDResourceTable.get(val);
- if (tex != null) {
- synchronized (tex.resourceLock) {
- tex.resourceCreationMask &= ~canvasBit;
- if (tex.resourceCreationMask == 0) {
- tex.freeTextureId(val);
- }
- }
- }
-
- textureIDResourceTable.set(val, null);
- }
- Canvas3D.freeTexture(ctx, val);
- }
- textureIdResourceFreeList.clear();
- }
- }
-
- void freeContextResources(Renderer rdr, boolean freeBackground,
- Context ctx) {
- TextureRetained tex;
-
- // Just return if we don't have a valid renderer or context
- if (rdr == null || ctx == null) {
- return;
- }
-
- if (freeBackground) {
- // Dispose of Graphics2D Texture
- if (graphics2D != null) {
- graphics2D.dispose();
- }
- }
-
- for (int id = textureIDResourceTable.size()-1; id >= 0; id--) {
- tex = textureIDResourceTable.get(id);
- if (tex == null) {
- continue;
- }
-
- // Issue 403 : this assertion doesn't hold in some cases
- // TODO KCR : determine why this is the case
-// assert id == ((TextureRetained)obj).objectId;
-
- Canvas3D.freeTexture(ctx, id);
- synchronized (tex.resourceLock) {
- tex.resourceCreationMask &= ~canvasBit;
- if (tex.resourceCreationMask == 0) {
-
- tex.freeTextureId(id);
- }
- }
- }
- textureIDResourceTable.clear();
-
- freeAllDisplayListResources(ctx);
- }
-
- void freeAllDisplayListResources(Context ctx) {
- if ((view != null) && (view.renderBin != null)) {
- view.renderBin.freeAllDisplayListResources(this, ctx);
- if (useSharedCtx) {
- // We need to rebuild all other Canvas3D resource
- // shared by this Canvas3D. Since we didn't
- // remember resource in Renderer but RenderBin only.
- if ((screen != null) && (screen.renderer != null)) {
- screen.renderer.needToRebuildDisplayList = true;
- }
- }
- }
-
- }
-
-
- // *****************************************************************
- // Wrappers for native methods go below here
- // *****************************************************************
-
- // This is the native method for creating the underlying graphics context.
- private Context createNewContext(Drawable drawable,
- Context shareCtx, boolean isSharedCtx,
- boolean offScreen) {
- return Pipeline.getPipeline().createNewContext(this, drawable,
- shareCtx, isSharedCtx,
- offScreen);
- }
-
- private void createQueryContext(Drawable drawable,
- boolean offScreen, int width, int height) {
- Pipeline.getPipeline().createQueryContext(this, drawable,
- offScreen, width, height);
- }
-
- // This is the native for creating offscreen buffer
- Drawable createOffScreenBuffer(Context ctx, int width, int height) {
- return Pipeline.getPipeline().createOffScreenBuffer(this,
- ctx, width, height);
- }
-
- void destroyOffScreenBuffer(Context ctx, Drawable drawable) {
- assert drawable != null;
- Pipeline.getPipeline().destroyOffScreenBuffer(this, ctx, drawable);
- }
-
- // This is the native for reading the image from the offscreen buffer
- private void readOffScreenBuffer(Context ctx, int format, int type, Object data, int width, int height) {
- Pipeline.getPipeline().readOffScreenBuffer(this, ctx, format, type, data, width, height);
- }
-
-// The native method for swapBuffers
-void swapBuffers(Context ctx, Drawable drawable) {
- Pipeline.getPipeline().swapBuffers(this, ctx, drawable);
-}
-
- // -----------------------------------------------------------------------------
-
- // native method for setting Material when no material is present
- void updateMaterial(Context ctx, float r, float g, float b, float a) {
- Pipeline.getPipeline().updateMaterialColor(ctx, r, g, b, a);
- }
-
- static void destroyContext(Drawable drawable, Context ctx) {
- Pipeline.getPipeline().destroyContext(drawable, ctx);
- }
-
- // This is the native method for doing accumulation.
- void accum(Context ctx, float value) {
- Pipeline.getPipeline().accum(ctx, value);
- }
-
- // This is the native method for doing accumulation return.
- void accumReturn(Context ctx) {
- Pipeline.getPipeline().accumReturn(ctx);
- }
-
- // This is the native method for clearing the accumulation buffer.
- void clearAccum(Context ctx) {
- Pipeline.getPipeline().clearAccum(ctx);
- }
-
- // This is the native method for getting the number of lights the underlying
- // native library can support.
- int getNumCtxLights(Context ctx) {
- return Pipeline.getPipeline().getNumCtxLights(ctx);
- }
-
- // Native method for decal 1st child setup
- boolean decal1stChildSetup(Context ctx) {
- return Pipeline.getPipeline().decal1stChildSetup(ctx);
- }
-
- // Native method for decal nth child setup
- void decalNthChildSetup(Context ctx) {
- Pipeline.getPipeline().decalNthChildSetup(ctx);
- }
-
- // Native method for decal reset
- void decalReset(Context ctx, boolean depthBufferEnable) {
- Pipeline.getPipeline().decalReset(ctx, depthBufferEnable);
- }
-
- // Native method for decal reset
- void ctxUpdateEyeLightingEnable(Context ctx, boolean localEyeLightingEnable) {
- Pipeline.getPipeline().ctxUpdateEyeLightingEnable(ctx, localEyeLightingEnable);
- }
-
- // The following three methods are used in multi-pass case
-
- // native method for setting blend color
- void setBlendColor(Context ctx, float red, float green,
- float blue, float alpha) {
- Pipeline.getPipeline().setBlendColor(ctx, red, green,
- blue, alpha);
- }
-
- // native method for setting blend func
- void setBlendFunc(Context ctx, int src, int dst) {
- Pipeline.getPipeline().setBlendFunc(ctx, src, dst);
- }
-
- // native method for setting fog enable flag
- void setFogEnableFlag(Context ctx, boolean enableFlag) {
- Pipeline.getPipeline().setFogEnableFlag(ctx, enableFlag);
- }
-
-boolean isAntialiasingSet() {
- return antialiasingSet;
-}
-
- // Setup the full scene antialising in D3D and ogl when GL_ARB_multisamle supported
- void setFullSceneAntialiasing(Context ctx, boolean enable) {
- Pipeline.getPipeline().setFullSceneAntialiasing(ctx, enable);
- antialiasingSet = enable;
- }
-
- // Native method to update separate specular color control
- void updateSeparateSpecularColorEnable(Context ctx, boolean control) {
- Pipeline.getPipeline().updateSeparateSpecularColorEnable(ctx, control);
- }
-
- // True under Solaris,
- // False under windows when display mode <= 8 bit
- private boolean validGraphicsMode() {
- return Pipeline.getPipeline().validGraphicsMode();
- }
-
- // native method for setting light enables
- void setLightEnables(Context ctx, long enableMask, int maxLights) {
- Pipeline.getPipeline().setLightEnables(ctx, enableMask, maxLights);
- }
-
- // native method for setting scene ambient
- void setSceneAmbient(Context ctx, float red, float green, float blue) {
- Pipeline.getPipeline().setSceneAmbient(ctx, red, green, blue);
- }
-
- // native method for disabling fog
- void disableFog(Context ctx) {
- Pipeline.getPipeline().disableFog(ctx);
- }
-
- // native method for disabling modelClip
- void disableModelClip(Context ctx) {
- Pipeline.getPipeline().disableModelClip(ctx);
- }
-
- // native method for setting default RenderingAttributes
- void resetRenderingAttributes(Context ctx,
- boolean depthBufferWriteEnableOverride,
- boolean depthBufferEnableOverride) {
- Pipeline.getPipeline().resetRenderingAttributes(ctx,
- depthBufferWriteEnableOverride,
- depthBufferEnableOverride);
- }
-
- // native method for setting default texture
- void resetTextureNative(Context ctx, int texUnitIndex) {
- Pipeline.getPipeline().resetTextureNative(ctx, texUnitIndex);
- }
-
- // native method for activating a particular texture unit
- void activeTextureUnit(Context ctx, int texUnitIndex) {
- Pipeline.getPipeline().activeTextureUnit(ctx, texUnitIndex);
- }
-
- // native method for setting default TexCoordGeneration
- void resetTexCoordGeneration(Context ctx) {
- Pipeline.getPipeline().resetTexCoordGeneration(ctx);
- }
-
- // native method for setting default TextureAttributes
- void resetTextureAttributes(Context ctx) {
- Pipeline.getPipeline().resetTextureAttributes(ctx);
- }
-
- // native method for setting default PolygonAttributes
- void resetPolygonAttributes(Context ctx) {
- Pipeline.getPipeline().resetPolygonAttributes(ctx);
- }
-
- // native method for setting default LineAttributes
- void resetLineAttributes(Context ctx) {
- Pipeline.getPipeline().resetLineAttributes(ctx);
- }
-
- // native method for setting default PointAttributes
- void resetPointAttributes(Context ctx) {
- Pipeline.getPipeline().resetPointAttributes(ctx);
- }
-
- // native method for setting default TransparencyAttributes
- void resetTransparency(Context ctx, int geometryType,
- int polygonMode, boolean lineAA,
- boolean pointAA) {
- Pipeline.getPipeline().resetTransparency(ctx, geometryType,
- polygonMode, lineAA,
- pointAA);
- }
-
- // native method for setting default ColoringAttributes
- void resetColoringAttributes(Context ctx,
- float r, float g,
- float b, float a,
- boolean enableLight) {
- Pipeline.getPipeline().resetColoringAttributes(ctx,
- r, g,
- b, a,
- enableLight);
- }
-
- /**
- * This native method makes sure that the rendering for this canvas
- * gets done now.
- */
- void syncRender(Context ctx, boolean wait) {
- Pipeline.getPipeline().syncRender(ctx, wait);
- }
-
- // The native method that sets this ctx to be the current one
- static boolean useCtx(Context ctx, Drawable drawable) {
- return Pipeline.getPipeline().useCtx(ctx, drawable);
- }
-
- // Give the Pipeline a chance to release the context. The return
- // value indicates whether the context was released.
- private boolean releaseCtx(Context ctx) {
- return Pipeline.getPipeline().releaseCtx(ctx);
- }
-
- void clear(Context ctx, float r, float g, float b, boolean clearStencil) {
- Pipeline.getPipeline().clear(ctx, r, g, b, clearStencil);
- }
-
- void textureFillBackground(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
- float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, boolean useBiliearFilter) {
- Pipeline.getPipeline().textureFillBackground(ctx, texMinU, texMaxU, texMinV, texMaxV,
- mapMinX, mapMaxX, mapMinY, mapMaxY, useBiliearFilter);
- }
-
- void textureFillRaster(Context ctx, float texMinU, float texMaxU, float texMinV, float texMaxV,
- float mapMinX, float mapMaxX, float mapMinY, float mapMaxY, float mapZ, float alpha, boolean useBiliearFilter) {
- Pipeline.getPipeline().textureFillRaster(ctx, texMinU, texMaxU, texMinV, texMaxV,
- mapMinX, mapMaxX, mapMinY, mapMaxY, mapZ, alpha, useBiliearFilter);
- }
-
- void executeRasterDepth(Context ctx, float posX, float posY, float posZ,
- int srcOffsetX, int srcOffsetY, int rasterWidth, int rasterHeight,
- int depthWidth, int depthHeight, int depthType, Object depthData) {
- Pipeline.getPipeline().executeRasterDepth(ctx, posX, posY, posZ,
- srcOffsetX, srcOffsetY, rasterWidth, rasterHeight, depthWidth, depthHeight, depthType, depthData);
- }
-
- // The native method for setting the ModelView matrix.
- void setModelViewMatrix(Context ctx, double[] viewMatrix, double[] modelMatrix) {
- Pipeline.getPipeline().setModelViewMatrix(ctx, viewMatrix, modelMatrix);
- }
-
- // The native method for setting the Projection matrix.
- void setProjectionMatrix(Context ctx, double[] projMatrix) {
- Pipeline.getPipeline().setProjectionMatrix(ctx, projMatrix);
- }
-
- // The native method for setting the Viewport.
- void setViewport(Context ctx, int x, int y, int width, int height) {
- Pipeline.getPipeline().resizeOffscreenLayer(this, width, height);
- Pipeline.getPipeline().setViewport(ctx, x, y, width, height);
- }
-
- // used for display Lists
- void newDisplayList(Context ctx, int displayListId) {
- Pipeline.getPipeline().newDisplayList(ctx, displayListId);
- }
- void endDisplayList(Context ctx) {
- Pipeline.getPipeline().endDisplayList(ctx);
- }
- void callDisplayList(Context ctx, int id, boolean isNonUniformScale) {
- Pipeline.getPipeline().callDisplayList(ctx, id, isNonUniformScale);
- }
-
- static void freeDisplayList(Context ctx, int id) {
- Pipeline.getPipeline().freeDisplayList(ctx, id);
- }
- static void freeTexture(Context ctx, int id) {
- Pipeline.getPipeline().freeTexture(ctx, id);
- }
-
- static int generateTexID(Context ctx) {
- return Pipeline.getPipeline().generateTexID(ctx);
- }
-
- void texturemapping(Context ctx,
- int px, int py,
- int xmin, int ymin, int xmax, int ymax,
- int texWidth, int texHeight,
- int rasWidth,
- int format, int objectId,
- byte[] image,
- int winWidth, int winHeight) {
- Pipeline.getPipeline().texturemapping(ctx,
- px, py,
- xmin, ymin, xmax, ymax,
- texWidth, texHeight,
- rasWidth,
- format, objectId,
- image,
- winWidth, winHeight);
- }
-
- boolean initTexturemapping(Context ctx, int texWidth,
- int texHeight, int objectId) {
- return Pipeline.getPipeline().initTexturemapping(ctx, texWidth,
- texHeight, objectId);
- }
-
-
- // Set internal render mode to one of FIELD_ALL, FIELD_LEFT or
- // FIELD_RIGHT. Note that it is up to the caller to ensure that
- // stereo is available before setting the mode to FIELD_LEFT or
- // FIELD_RIGHT. The boolean isTRUE for double buffered mode, FALSE
- // foe single buffering.
- void setRenderMode(Context ctx, int mode, boolean doubleBuffer) {
- Pipeline.getPipeline().setRenderMode(ctx, mode, doubleBuffer);
- }
-
- // Set glDepthMask.
- void setDepthBufferWriteEnable(Context ctx, boolean mode) {
- Pipeline.getPipeline().setDepthBufferWriteEnable(ctx, mode);
- }
-
- // Methods to get actual capabilities from Canvas3D
-
- boolean hasDoubleBuffer() {
- return Pipeline.getPipeline().hasDoubleBuffer(this);
- }
-
- boolean hasStereo() {
- return Pipeline.getPipeline().hasStereo(this);
- }
-
- int getStencilSize() {
- return Pipeline.getPipeline().getStencilSize(this);
- }
-
- boolean hasSceneAntialiasingMultisample() {
- return Pipeline.getPipeline().hasSceneAntialiasingMultisample(this);
- }
-
- boolean hasSceneAntialiasingAccum() {
- return Pipeline.getPipeline().hasSceneAntialiasingAccum(this);
- }
-
-}