diff options
author | Julien Gouesse <[email protected]> | 2015-11-28 15:11:48 +0100 |
---|---|---|
committer | Julien Gouesse <[email protected]> | 2015-11-28 15:11:48 +0100 |
commit | dbc98deea1884e44da2c74d6ea807253cdefa693 (patch) | |
tree | 29c3ee7dea82d7dd773d81f33f645dde67e43a17 /src/javax/media/j3d/Canvas3D.java | |
parent | 2c99f1329dc55bd496bce91b9aba956ecba3c67e (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.java | 4951 |
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); - } - -} |