Source Code Cross Referenced for GraphicsContext3D.java in  » 6.0-JDK-Modules » java-3d » javax » media » j3d » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » javax.media.j3d 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: GraphicsContext3D.java,v $
0003:         *
0004:         * Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006:         *
0007:         * This code is free software; you can redistribute it and/or modify it
0008:         * under the terms of the GNU General Public License version 2 only, as
0009:         * published by the Free Software Foundation.  Sun designates this
0010:         * particular file as subject to the "Classpath" exception as provided
0011:         * by Sun in the LICENSE file that accompanied this code.
0012:         *
0013:         * This code is distributed in the hope that it will be useful, but WITHOUT
0014:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0016:         * version 2 for more details (a copy is included in the LICENSE file that
0017:         * accompanied this code).
0018:         *
0019:         * You should have received a copy of the GNU General Public License version
0020:         * 2 along with this work; if not, write to the Free Software Foundation,
0021:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022:         *
0023:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024:         * CA 95054 USA or visit www.sun.com if you need additional information or
0025:         * have any questions.
0026:         *
0027:         * $Revision: 1.15 $
0028:         * $Date: 2008/02/28 20:17:22 $
0029:         * $State: Exp $
0030:         */
0031:
0032:        package javax.media.j3d;
0033:
0034:        import java.awt.Point;
0035:        import java.awt.image.BufferedImage;
0036:        import javax.vecmath.*;
0037:        import java.util.Vector;
0038:        import java.util.Enumeration;
0039:        import java.awt.Dimension;
0040:
0041:        /**
0042:         * A GraphicsContext3D object is used for immediate mode rendering into
0043:         * a 3D canvas.  It is created by, and associated with, a specific
0044:         * Canvas3D object.  A GraphicsContext3D defines methods to set 3D graphics
0045:         * state and draw 3D geometric primitives.  There are no public
0046:         * constructors of GraphicsContext3D. An application obtains a 3D graphics
0047:         * context object from the Canvas3D object that the application wishes
0048:         * to render into by using the getGraphicsContext3D method. A new graphics
0049:         * context is created if one does not already exist.  A new GraphicsContext3D
0050:         * initializes its state variables to the following defaults:
0051:         * <UL>
0052:         * <LI> Background object: null </LI>
0053:         * <LI> Fog object: null </LI>
0054:         * <LI> ModelClip object: null </LI>
0055:         * <LI> Appearance object: null </LI>
0056:         * <LI> List of Light objects: empty </LI>
0057:         * <LI> high-res coordinate: (0, 0, 0) </LI>
0058:         * <LI> modelTransform: identity </LI>
0059:         * <LI> AuralAttributes object: null </LI>
0060:         * <LI> List of Sound objects: empty </LI>
0061:         * <LI> buffer override: false </LI>
0062:         * <LI> front buffer rendering: false </LI>
0063:         * <LI> stereo mode: <code>STEREO_BOTH</code> </LI>
0064:         * </UL>
0065:         *
0066:         * <p>
0067:         * Note that the drawing methods in this class are not necessarily
0068:         * executed immediately.  They may be buffered up for future
0069:         * execution.  Applications must call the
0070:         * <code><a href="#flush(boolean)">flush</a>(boolean)</code>
0071:         * method to ensure that the rendering actually happens. The flush
0072:         * method is implicitly called in the following cases:
0073:         *
0074:         * <ul>
0075:         * <li>The <code>readRaster</code> method calls
0076:         * <code>flush(true)</code></li>
0077:         * <li>The <code>Canvas3D.swap</code> method calls
0078:         * <code>flush(true)</code></li>
0079:         * <li>The Java 3D renderer calls <code>flush(true)</code> prior to
0080:         * swapping the buffer for a double buffered on-screen Canvas3D</li>
0081:         * <li>The Java 3D renderer calls <code>flush(true)</code> prior to
0082:         * copying into the off-screen buffer of an off-screen Canvas3D</li>
0083:         * <li>The Java 3D renderer calls <code>flush(false)</code> after
0084:         * calling the preRender, renderField, postRender, and postSwap
0085:         * Canvas3D callback methods.</li>
0086:         * </ul>
0087:         *
0088:         * <p>
0089:         * A single-buffered, pure-immediate mode application must explicitly
0090:         * call flush to ensure that the graphics will be rendered to the
0091:         * Canvas3D.
0092:         *
0093:         * @see Canvas3D#getGraphicsContext3D
0094:         */
0095:        public class GraphicsContext3D extends Object {
0096:            /**
0097:             * Specifies that rendering is done to the left eye.
0098:             * @see #setStereoMode
0099:             * @since Java 3D 1.2
0100:             */
0101:            public static final int STEREO_LEFT = 0;
0102:
0103:            /**
0104:             * Specifies that rendering is done to the right eye.
0105:             * @see #setStereoMode
0106:             * @since Java 3D 1.2
0107:             */
0108:            public static final int STEREO_RIGHT = 1;
0109:
0110:            /**
0111:             * Specifies that rendering is done to both eyes.  This is the
0112:             * default.
0113:             * @see #setStereoMode
0114:             * @since Java 3D 1.2
0115:             */
0116:            public static final int STEREO_BOTH = 2;
0117:
0118:            /**
0119:             * Canvas3D in which this GraphicsContext3D will render.
0120:             */
0121:            Canvas3D canvas3d = null;
0122:
0123:            //
0124:            // Graphics state
0125:            //
0126:            // current user specified graphics state
0127:            private Background uBackground = null;
0128:            private Fog uFog = null;
0129:            private Appearance uAppearance = null;
0130:            private Vector uLights = new Vector();
0131:            private HiResCoord uHiRes = new HiResCoord();
0132:            private Vector uSounds = new Vector();
0133:            private AuralAttributes uAuralAttributes = null;
0134:            private boolean uBufferOverride = false;
0135:            private boolean uFrontBufferRendering = false;
0136:            private int uStereoMode = STEREO_BOTH;
0137:            private ModelClip uModelClip = null;
0138:
0139:            // Current rendering graphics state
0140:            // Current background
0141:            Background background = null;
0142:
0143:            // Background to use if background is null;
0144:            BackgroundRetained black = new BackgroundRetained();
0145:
0146:            // Current fog
0147:            Fog fog = null;
0148:
0149:            // Current modelClip
0150:            ModelClip modelClip = null;
0151:
0152:            // Current appearance object
0153:            Appearance appearance = null;
0154:
0155:            // default appearance retained object
0156:            AppearanceRetained defaultAppearanceRetained = new AppearanceRetained();
0157:
0158:            // The vector of lights
0159:            Vector lights = new Vector();
0160:
0161:            // Current High resolution coordinate
0162:            HiResCoord hiRes = new HiResCoord();
0163:
0164:            // Current modeling transform
0165:            Transform3D modelTransform = new Transform3D();
0166:            Transform3D identityTransform = new Transform3D();
0167:
0168:            Transform3D modelClipTransform = null;
0169:            Transform3D normalTransform = null;
0170:            boolean normalTransformNeedToUpdate = true;
0171:
0172:            // The vector of sounds
0173:            Vector sounds = new Vector();
0174:
0175:            // Current AuralAttributes state parameters
0176:            AuralAttributes auralAttributes = null;
0177:
0178:            // The render object associated with this context
0179:            LightSet ls = null;
0180:
0181:            // The current list of lights
0182:            LightRetained[] lightlist = null;
0183:
0184:            // Ambient lights
0185:            Color3f sceneAmbient = new Color3f(0.0f, 0.0f, 0.0f);
0186:
0187:            // The current number of lights, may be less than lightlist.length
0188:            int numLights = 0;
0189:
0190:            // Current composite transform: hi-res + modelTransform
0191:            Transform3D compTransform = new Transform3D();
0192:
0193:            // Draw transform: hi-res + modelTransform + view
0194:            Transform3D drawTransform = new Transform3D();
0195:
0196:            // The view transform (VPC to EC).
0197:            // NOTE that this is *read-only*
0198:            Transform3D vpcToEc;
0199:
0200:            // A boolean that indicates the lights have changed
0201:            boolean lightsChanged = false;
0202:
0203:            // A boolean that indicates the sounds have changed
0204:            // XXXX: the soundsChanged flag are set like lights methods set 
0205:            //       lightsChanged? but where is this supposed to be check???
0206:            //       lightsChanged tested in 'draw'; but Sound are not processed
0207:            //       in draw.
0208:            boolean soundsChanged = false;
0209:
0210:            // Buffer override flag; enables frontBufferRendering and stereoMode
0211:            // attributes.
0212:            boolean bufferOverride = false;
0213:
0214:            // Forces rendering to the front buffer (if bufferOverride is true)
0215:            boolean frontBufferRendering = false;
0216:
0217:            // Stereo mode for this buffer (if bufferOverride is true)
0218:            int stereoMode = STEREO_BOTH;
0219:
0220:            // Read Buffer for reading raster of color image
0221:            byte[] byteBuffer = new byte[1];
0222:
0223:            // Read Buffer for reading floating depth image
0224:            float[] floatBuffer = new float[1];
0225:
0226:            // Read Buffer for reading integer depth image
0227:            int[] intBuffer = new int[1];
0228:
0229:            /** 
0230:             * The cached ColoringAttributes color value.  It is
0231:             * 1.0, 1.0, 1.0 if there is no ColoringAttributes.
0232:             */
0233:            float red = 1.0f;
0234:            float green = 1.0f;
0235:            float blue = 1.0f;
0236:
0237:            /**
0238:             * Cached diffuse color value
0239:             */
0240:            float dRed = 1.0f;
0241:            float dGreen = 1.0f;
0242:            float dBlue = 1.0f;
0243:
0244:            /** 
0245:             * The cached TransparencyAttributes transparency value.  It is
0246:             * 0.0 if there is no TransparencyAttributes.
0247:             */
0248:            float alpha = 0.0f;
0249:
0250:            /** 
0251:             * The cached visible flag for geometry.
0252:             */
0253:            boolean visible = true;
0254:
0255:            /** 
0256:             * Cached values for polygonMode, line antialiasing, and point antialiasing
0257:             */
0258:            int polygonMode = PolygonAttributes.POLYGON_FILL;
0259:            boolean lineAA = false;
0260:            boolean pointAA = false;
0261:
0262:            /**
0263:            /** 
0264:             * A boolean indicating whether or not lighting should be on.
0265:             */
0266:            boolean enableLighting = false;
0267:
0268:            private Appearance defaultAppearance = null;
0269:
0270:            private boolean geometryIsLocked = false;
0271:
0272:            private boolean ignoreVertexColors = false;
0273:
0274:            static final int CLEAR = 0;
0275:            static final int DRAW = 1;
0276:            static final int SWAP = 2;
0277:            static final int READ_RASTER = 3;
0278:            static final int SET_APPEARANCE = 4;
0279:            static final int SET_BACKGROUND = 5;
0280:            static final int SET_FOG = 6;
0281:            static final int SET_LIGHT = 7;
0282:            static final int INSERT_LIGHT = 8;
0283:            static final int REMOVE_LIGHT = 9;
0284:            static final int ADD_LIGHT = 10;
0285:            static final int SET_HI_RES = 11;
0286:            static final int SET_MODEL_TRANSFORM = 12;
0287:            static final int MULTIPLY_MODEL_TRANSFORM = 13;
0288:            static final int SET_SOUND = 14;
0289:            static final int INSERT_SOUND = 15;
0290:            static final int REMOVE_SOUND = 16;
0291:            static final int ADD_SOUND = 17;
0292:            static final int SET_AURAL_ATTRIBUTES = 18;
0293:            static final int SET_BUFFER_OVERRIDE = 19;
0294:            static final int SET_FRONT_BUFFER_RENDERING = 20;
0295:            static final int SET_STEREO_MODE = 21;
0296:            static final int FLUSH = 22;
0297:            static final int FLUSH2D = 23;
0298:            static final int DRAWANDFLUSH2D = 24;
0299:            static final int SET_MODELCLIP = 25;
0300:            static final int DISPOSE2D = 26;
0301:            static final int NCOMMANDS = 27; // needs to be incremented
0302:            // when a new command is to be
0303:            // added to the list
0304:
0305:            private static Integer[] commands = new Integer[NCOMMANDS];
0306:            private static Integer[] stereoModes = { new Integer(STEREO_LEFT),
0307:                    new Integer(STEREO_RIGHT), new Integer(STEREO_BOTH) };
0308:
0309:            // dirty bits
0310:            private static final int BUFFER_MODE = 0x1;
0311:            private int dirtyMask = 0;
0312:
0313:            // multi-texture
0314:            private int numActiveTexUnit = 0;
0315:            private int lastActiveTexUnitIndex = 0;
0316:
0317:            // for read raster
0318:            private volatile boolean readRasterReady = false;
0319:
0320:            // for runMonitor
0321:            private boolean gcReady = false;
0322:            private int waiting = 0;
0323:
0324:            /**
0325:             * Constructs and creates a GraphicsContext3D object with default
0326:             * values.  Users do not call this directly, rather they get a
0327:             * graphics context from a Canvas3D.
0328:             */
0329:            GraphicsContext3D(Canvas3D canvas3d) {
0330:                this .canvas3d = canvas3d;
0331:            }
0332:
0333:            /**
0334:             * Gets the Canvas3D that created this GraphicsContext3D.
0335:             * @return the Canvas3D that created this GraphicsContext3D
0336:             */
0337:            public Canvas3D getCanvas3D() {
0338:                return this .canvas3d;
0339:            }
0340:
0341:            //
0342:            // Methods to set/get graphics state
0343:            //
0344:
0345:            /**
0346:             * Sets the current Appearance object to the specified
0347:             * Appearance component object.
0348:             * The graphics context stores a reference to the specified 
0349:             * Appearance object. This means that the application may modify 
0350:             * individual appearance attributes by using the appropriate 
0351:             * methods on the Appearance object.
0352:             * If the Appearance object is null, default values will be used 
0353:             * for all appearance attributes - it is as if an
0354:             * Appearance node were created using the default constructor.
0355:             *
0356:             * @param appearance the new Appearance object
0357:             *
0358:             * @exception IllegalSharingException if the specified appearance refers
0359:             * to an ImageComponent2D that is being used by a Canvas3D as
0360:             * an off-screen buffer.
0361:             */
0362:            public void setAppearance(Appearance appearance) {
0363:
0364:                if (appearance == null) {
0365:                    if (defaultAppearance == null) {
0366:                        defaultAppearance = new Appearance();
0367:                    }
0368:                    appearance = defaultAppearance;
0369:                } else {
0370:                    // Check whether any ImageComponent2D referred to by
0371:                    // the new appearance is being used as an off-screen buffer and throw
0372:                    // IllegalSharingException if it is.
0373:                    TextureRetained texRetained;
0374:                    ImageComponent[] images;
0375:                    AppearanceRetained appRetained = (AppearanceRetained) appearance.retained;
0376:                    if (appRetained.texture != null) {
0377:                        assert (appRetained.texUnitState == null);
0378:                        texRetained = appRetained.texture;
0379:                        images = texRetained.getImages();
0380:                        if (images != null) {
0381:                            for (int i = 0; i < images.length; i++) {
0382:                                if (images[i] != null) {
0383:                                    ImageComponentRetained imageRetained = (ImageComponentRetained) images[i].retained;
0384:                                    // Do illegal sharing check
0385:                                    if (imageRetained.getUsedByOffScreen()) {
0386:                                        throw new IllegalSharingException(
0387:                                                J3dI18N
0388:                                                        .getString("GraphicsContext3D30"));
0389:                                    }
0390:                                }
0391:                            }
0392:                        }
0393:                    } else if (appRetained.texUnitState != null) {
0394:                        for (int j = 0; j < appRetained.texUnitState.length; j++) {
0395:                            texRetained = appRetained.texUnitState[j].texture;
0396:                            images = texRetained.getImages();
0397:                            if (images != null) {
0398:                                for (int i = 0; i < images.length; i++) {
0399:                                    if (images[i] != null) {
0400:                                        ImageComponentRetained imageRetained = (ImageComponentRetained) images[i].retained;
0401:                                        // Do illegal sharing check
0402:                                        if (imageRetained.getUsedByOffScreen()) {
0403:                                            throw new IllegalSharingException(
0404:                                                    J3dI18N
0405:                                                            .getString("GraphicsContext3D30"));
0406:                                        }
0407:                                    }
0408:                                }
0409:                            }
0410:                        }
0411:                    }
0412:                }
0413:
0414:                uAppearance = appearance;
0415:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
0416:                        || (!canvas3d.view.active)
0417:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
0418:                    doSetAppearance(appearance);
0419:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
0420:                    sendRenderMessage(false, GraphicsContext3D.SET_APPEARANCE,
0421:                            appearance, null);
0422:                } else {
0423:                    sendRenderMessage(true, GraphicsContext3D.SET_APPEARANCE,
0424:                            appearance, null);
0425:                }
0426:            }
0427:
0428:            void doSetAppearance(Appearance appearance) {
0429:                // Appearance can't be null. See setAppearance().
0430:                assert (appearance != null);
0431:
0432:                NodeComponentRetained nc;
0433:                nc = ((AppearanceRetained) appearance.retained).material;
0434:                if (nc != null) {
0435:                    nc.setInImmCtx(true);
0436:                    enableLighting = ((MaterialRetained) nc).lightingEnable;
0437:                    dRed = ((MaterialRetained) nc).diffuseColor.x;
0438:                    dGreen = ((MaterialRetained) nc).diffuseColor.y;
0439:                    dBlue = ((MaterialRetained) nc).diffuseColor.z;
0440:                } else {
0441:                    enableLighting = false;
0442:                }
0443:
0444:                if (appearance instanceof  ShaderAppearance) {
0445:                    // Handle ShaderProgramRetained.
0446:                    ShaderProgramRetained spR = ((ShaderAppearanceRetained) appearance.retained).shaderProgram;
0447:                    if (spR != null) {
0448:                        spR.setInImmCtx(true);
0449:                        Shader[] sArray = spR.getShaders();
0450:                        if (sArray != null) {
0451:                            for (int i = 0; i < sArray.length; i++) {
0452:                                if (sArray[i] != null) {
0453:                                    ((ShaderRetained) sArray[i].retained)
0454:                                            .setInImmCtx(true);
0455:                                }
0456:                            }
0457:                        }
0458:                    }
0459:
0460:                    //Handle ShaderAttributeSetRetained.
0461:                    ShaderAttributeSetRetained sasR = ((ShaderAppearanceRetained) appearance.retained).shaderAttributeSet;
0462:                    if (sasR != null) {
0463:                        sasR.setInImmCtx(true);
0464:                        ShaderAttribute[] saArray = sasR.getAll();
0465:                        if (saArray != null) {
0466:                            for (int i = 0; i < saArray.length; i++) {
0467:                                if (saArray[i] != null) {
0468:                                    ((ShaderAttributeRetained) saArray[i].retained)
0469:                                            .setInImmCtx(true);
0470:                                }
0471:                            }
0472:                        }
0473:                    }
0474:                }
0475:
0476:                if (((AppearanceRetained) appearance.retained).texUnitState != null) {
0477:                    TextureUnitStateRetained[] texUnitState = ((AppearanceRetained) appearance.retained).texUnitState;
0478:
0479:                    for (int i = 0; i < texUnitState.length; i++) {
0480:                        if (texUnitState[i] != null) {
0481:                            texUnitState[i].setInImmCtx(true);
0482:                        }
0483:                    }
0484:                }
0485:
0486:                nc = ((AppearanceRetained) appearance.retained).texture;
0487:                if (nc != null) {
0488:                    nc.setInImmCtx(true);
0489:                }
0490:
0491:                nc = ((AppearanceRetained) appearance.retained).texCoordGeneration;
0492:                if (nc != null) {
0493:                    nc.setInImmCtx(true);
0494:                }
0495:
0496:                nc = ((AppearanceRetained) appearance.retained).textureAttributes;
0497:                if (nc != null) {
0498:                    nc.setInImmCtx(true);
0499:                }
0500:
0501:                nc = ((AppearanceRetained) appearance.retained).coloringAttributes;
0502:                if (nc != null) {
0503:                    nc.setInImmCtx(true);
0504:                    red = ((ColoringAttributesRetained) nc).color.x;
0505:                    green = ((ColoringAttributesRetained) nc).color.y;
0506:                    blue = ((ColoringAttributesRetained) nc).color.z;
0507:                } else {
0508:                    red = 1.0f;
0509:                    green = 1.0f;
0510:                    blue = 1.0f;
0511:                }
0512:
0513:                nc = ((AppearanceRetained) appearance.retained).transparencyAttributes;
0514:                if (nc != null) {
0515:                    nc.setInImmCtx(true);
0516:                    alpha = 1.0f - ((TransparencyAttributesRetained) nc).transparency;
0517:                } else {
0518:                    alpha = 1.0f;
0519:                }
0520:
0521:                nc = ((AppearanceRetained) appearance.retained).renderingAttributes;
0522:                if (nc != null) {
0523:                    nc.setInImmCtx(true);
0524:                    visible = ((RenderingAttributesRetained) nc).visible;
0525:                } else
0526:                    visible = true;
0527:
0528:                nc = ((AppearanceRetained) appearance.retained).polygonAttributes;
0529:                if (nc != null) {
0530:                    nc.setInImmCtx(true);
0531:                    polygonMode = ((PolygonAttributesRetained) nc).polygonMode;
0532:                } else {
0533:                    polygonMode = PolygonAttributes.POLYGON_FILL;
0534:                }
0535:
0536:                nc = ((AppearanceRetained) appearance.retained).lineAttributes;
0537:                if (nc != null) {
0538:                    nc.setInImmCtx(true);
0539:                    lineAA = ((LineAttributesRetained) nc).lineAntialiasing;
0540:
0541:                } else {
0542:                    lineAA = false;
0543:                }
0544:
0545:                nc = ((AppearanceRetained) appearance.retained).pointAttributes;
0546:                if (nc != null) {
0547:                    if (nc.source.isLive())
0548:                        nc.setInImmCtx(true);
0549:                    pointAA = ((PointAttributesRetained) nc).pointAntialiasing;
0550:                } else {
0551:                    pointAA = false;
0552:                }
0553:
0554:                // Reset the inImmCtx flag of this.appearance.
0555:                if (this .appearance != null) {
0556:                    AppearanceRetained app = (AppearanceRetained) this .appearance.retained;
0557:                    app.setInImmCtx(false);
0558:                    if (app.material != null) {
0559:                        app.material.setInImmCtx(false);
0560:                    }
0561:
0562:                    if (app instanceof  ShaderAppearanceRetained) {
0563:                        // Handle ShaderProgramRetained.
0564:                        ShaderProgramRetained spR = ((ShaderAppearanceRetained) app).shaderProgram;
0565:                        if (spR != null) {
0566:                            spR.setInImmCtx(false);
0567:                            Shader[] sArray = spR.getShaders();
0568:                            if (sArray != null) {
0569:                                for (int i = 0; i < sArray.length; i++) {
0570:                                    if (sArray[i] != null) {
0571:                                        ((ShaderRetained) sArray[i].retained)
0572:                                                .setInImmCtx(false);
0573:                                    }
0574:                                }
0575:                            }
0576:                        }
0577:
0578:                        //Handle ShaderAttributeSetRetained.
0579:                        ShaderAttributeSetRetained sasR = ((ShaderAppearanceRetained) app).shaderAttributeSet;
0580:                        if (sasR != null) {
0581:                            sasR.setInImmCtx(false);
0582:                            ShaderAttribute[] saArray = sasR.getAll();
0583:                            if (saArray != null) {
0584:                                for (int i = 0; i < saArray.length; i++) {
0585:                                    if (saArray[i] != null) {
0586:                                        ((ShaderAttributeRetained) saArray[i].retained)
0587:                                                .setInImmCtx(false);
0588:                                    }
0589:                                }
0590:                            }
0591:                        }
0592:                    }
0593:
0594:                    if (app.texUnitState != null) {
0595:                        for (int i = 0; i < app.texUnitState.length; i++) {
0596:                            if (app.texUnitState[0] != null)
0597:                                app.texUnitState[0].setInImmCtx(false);
0598:                        }
0599:                    }
0600:                    if (app.texture != null) {
0601:                        app.texture.setInImmCtx(false);
0602:                    }
0603:                    if (app.texCoordGeneration != null) {
0604:                        app.texCoordGeneration.setInImmCtx(false);
0605:                    }
0606:                    if (app.textureAttributes != null) {
0607:                        app.textureAttributes.setInImmCtx(false);
0608:                    }
0609:                    if (app.coloringAttributes != null) {
0610:                        app.coloringAttributes.setInImmCtx(false);
0611:                    }
0612:                    if (app.transparencyAttributes != null) {
0613:                        app.transparencyAttributes.setInImmCtx(false);
0614:                    }
0615:                    if (app.renderingAttributes != null) {
0616:                        app.renderingAttributes.setInImmCtx(false);
0617:                    }
0618:                    if (app.polygonAttributes != null) {
0619:                        app.polygonAttributes.setInImmCtx(false);
0620:                    }
0621:                    if (app.lineAttributes != null) {
0622:                        app.lineAttributes.setInImmCtx(false);
0623:                    }
0624:                    if (app.pointAttributes != null) {
0625:                        app.pointAttributes.setInImmCtx(false);
0626:                    }
0627:                }
0628:
0629:                ((AppearanceRetained) appearance.retained).setInImmCtx(true);
0630:                this .appearance = appearance;
0631:            }
0632:
0633:            /**
0634:             * Retrieves the current Appearance component object.
0635:             * @return the current Appearance object
0636:             */
0637:            public Appearance getAppearance() {
0638:                return this .uAppearance;
0639:            }
0640:
0641:            /**
0642:             * Sets the current Background to the specified Background
0643:             * leaf node object.
0644:             * The graphics context stores a reference to the specified 
0645:             * Background node. This means that the application may modify 
0646:             * the background color or image by using the appropriate 
0647:             * methods on the Background node. The Background node must 
0648:             * not be part of a live scene graph, nor may it subsequently 
0649:             * be made part of a live scene graph-an IllegalSharingException 
0650:             * is thrown in such cases. If the Background object is null, 
0651:             * the default background color of black (0,0,0) is used to clear
0652:             * the canvas prior to rendering a new frame. The Background 
0653:             * node's application region is ignored for immediate-mode 
0654:             * rendering.
0655:             *
0656:             * @param background the new Background object
0657:             *
0658:             * @exception IllegalSharingException if the Background node
0659:             * is part of or is subsequently made part of a live scene graph.
0660:             *
0661:             * @exception IllegalSharingException if the specified background node
0662:             * refers to an ImageComponent2D that is being used by a Canvas3D as
0663:             * an off-screen buffer.
0664:             */
0665:            public void setBackground(Background background) {
0666:
0667:                if (background.isLive()) {
0668:                    throw new IllegalSharingException(J3dI18N
0669:                            .getString("GraphicsContext3D11"));
0670:                }
0671:                BackgroundRetained bgRetained = (BackgroundRetained) background.retained;
0672:                ImageComponent2D image = bgRetained.getImage();
0673:                if (image != null) {
0674:                    ImageComponent2DRetained imageRetained = (ImageComponent2DRetained) image.retained;
0675:                    if (imageRetained.getUsedByOffScreen()) {
0676:                        throw new IllegalSharingException(J3dI18N
0677:                                .getString("GraphicsContext3D31"));
0678:                    }
0679:                }
0680:
0681:                if (((BackgroundRetained) background.retained).geometryBranch != null) {
0682:                    throw new IllegalSharingException(J3dI18N
0683:                            .getString("GraphicsContext3D22"));
0684:                }
0685:
0686:                uBackground = background;
0687:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
0688:                        || (!canvas3d.view.active)
0689:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
0690:                    doSetBackground(background);
0691:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
0692:                    sendRenderMessage(false, GraphicsContext3D.SET_BACKGROUND,
0693:                            background, null);
0694:                } else {
0695:                    sendRenderMessage(true, GraphicsContext3D.SET_BACKGROUND,
0696:                            background, null);
0697:                }
0698:            }
0699:
0700:            void doSetBackground(Background background) {
0701:                BackgroundRetained bg;
0702:
0703:                if (this .background != null) {
0704:                    bg = (BackgroundRetained) this .background.retained;
0705:                    bg.setInImmCtx(false);
0706:                }
0707:                bg = (BackgroundRetained) background.retained;
0708:                bg.setInImmCtx(true);
0709:
0710:                this .background = background;
0711:            }
0712:
0713:            /**
0714:             * Retrieves the current Background leaf node object.
0715:             * @return the current Background object
0716:             */
0717:            public Background getBackground() {
0718:                return this .uBackground;
0719:            }
0720:
0721:            /**
0722:             * Sets the current Fog to the specified Fog
0723:             * leaf node object.
0724:             * The graphics context stores a reference to the specified 
0725:             * Fog node. This means that the application may modify the 
0726:             * fog attributes using the appropriate methods on the Fog 
0727:             * node object. The Fog node must not be part of a live 
0728:             * scene graph, nor may it subsequently be made part of a
0729:             * live scene graph-an IllegalSharingException is thrown in 
0730:             * such cases. If the Fog object is null, fog is disabled. 
0731:             * Both the region of influence and the hierarchical scope 
0732:             * of the Fog node are ignored for immediate-mode rendering.
0733:             * @param fog the new Fog object
0734:             * @exception IllegalSharingException if the Fog node
0735:             * is part of or is subsequently made part of a live scene graph.
0736:             */
0737:            public void setFog(Fog fog) {
0738:                if (fog != null && fog.isLive()) {
0739:                    throw new IllegalSharingException(J3dI18N
0740:                            .getString("GraphicsContext3D12"));
0741:                }
0742:                uFog = fog;
0743:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
0744:                        || (!canvas3d.view.active)
0745:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
0746:                    doSetFog(fog);
0747:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
0748:                    sendRenderMessage(false, GraphicsContext3D.SET_FOG, fog,
0749:                            null);
0750:                } else {
0751:                    sendRenderMessage(true, GraphicsContext3D.SET_FOG, fog,
0752:                            null);
0753:                }
0754:            }
0755:
0756:            void doSetFog(Fog fog) {
0757:                if (this .fog != null) {
0758:                    ((FogRetained) this .fog.retained).setInImmCtx(false);
0759:                }
0760:                this .fog = fog;
0761:                if (fog != null) {
0762:                    ((FogRetained) fog.retained).setInImmCtx(true);
0763:
0764:                    // Issue 144: updateFogState now called unconditionally
0765:                    updateFogState((FogRetained) fog.retained);
0766:                }
0767:            }
0768:
0769:            /**
0770:             * Retrieves the current Fog leaf node object.
0771:             * @return the current Fog object
0772:             */
0773:            public Fog getFog() {
0774:                return this .uFog;
0775:            }
0776:
0777:            /**
0778:             * Sets the current ModelClip leaf node to the specified object.
0779:             * The graphics context stores a reference to the specified
0780:             * ModelClip node. This means that the application may modify the
0781:             * model clipping attributes using the appropriate methods on the
0782:             * ModelClip node object. The ModelClip node must not be part of a
0783:             * live scene graph, nor may it subsequently be made part of a
0784:             * live scene graph-an IllegalSharingException is thrown in such
0785:             * cases. If the ModelClip object is null, model clipping is
0786:             * disabled.  Both the region of influence and the hierarchical
0787:             * scope of the ModelClip node are ignored for immediate-mode
0788:             * rendering.
0789:             *
0790:             * @param modelClip the new ModelClip node
0791:             *
0792:             * @exception IllegalSharingException if the ModelClip node
0793:             * is part of or is subsequently made part of a live scene graph.
0794:             *
0795:             * @since Java 3D 1.2
0796:             */
0797:            public void setModelClip(ModelClip modelClip) {
0798:                if ((modelClip != null) && modelClip.isLive()) {
0799:                    throw new IllegalSharingException(J3dI18N
0800:                            .getString("GraphicsContext3D25"));
0801:                }
0802:                uModelClip = modelClip;
0803:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
0804:                        || (!canvas3d.view.active)
0805:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
0806:                    doSetModelClip(modelClip);
0807:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
0808:                    sendRenderMessage(false, GraphicsContext3D.SET_MODELCLIP,
0809:                            modelClip, null);
0810:                } else {
0811:                    sendRenderMessage(true, GraphicsContext3D.SET_MODELCLIP,
0812:                            modelClip, null);
0813:                }
0814:            }
0815:
0816:            void doSetModelClip(ModelClip modelClip) {
0817:                ModelClipRetained mc = null;
0818:
0819:                this .modelClip = modelClip;
0820:
0821:                if (this .modelClip != null) {
0822:                    mc = (ModelClipRetained) this .modelClip.retained;
0823:                    mc.setInImmCtx(true);
0824:
0825:                    if (modelClipTransform == null)
0826:                        modelClipTransform = new Transform3D();
0827:
0828:                    // save the current model Transform
0829:                    modelClipTransform.set(compTransform);
0830:                }
0831:            }
0832:
0833:            /**
0834:             * Retrieves the current ModelClip leaf node object.
0835:             * @return the current ModelClip object
0836:             *
0837:             * @since Java 3D 1.2
0838:             */
0839:            public ModelClip getModelClip() {
0840:                return this .uModelClip;
0841:            }
0842:
0843:            /**
0844:             * Replaces the specified light with the light provided.
0845:             * The graphics context stores a reference to each light 
0846:             * object in the list of lights. This means that the 
0847:             * application may modify the light attributes for
0848:             * any of the lights using the appropriate methods on that 
0849:             * Light node object. None of the Light nodes in the list 
0850:             * of lights may be part of a live scene graph, nor may 
0851:             * they subsequently be made part of a live scene graph -
0852:             * an IllegalSharingException is thrown in such cases. 
0853:             * @param light the new light
0854:             * @param index which light to replace
0855:             * @exception IllegalSharingException if the Light node
0856:             * is part of or is subsequently made part of a live scene graph.
0857:             * @exception NullPointerException if the Light object is null.
0858:             */
0859:            public void setLight(Light light, int index) {
0860:                if (light == null) {
0861:                    throw new NullPointerException(J3dI18N
0862:                            .getString("GraphicsContext3D13"));
0863:                }
0864:                if (light.isLive()) {
0865:                    throw new IllegalSharingException(J3dI18N
0866:                            .getString("GraphicsContext3D14"));
0867:                }
0868:                uLights.setElementAt(light, index);
0869:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
0870:                        || (!canvas3d.view.active)
0871:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
0872:                    doSetLight(light, index);
0873:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
0874:                    sendRenderMessage(false, GraphicsContext3D.SET_LIGHT,
0875:                            light, new Integer(index));
0876:                } else {
0877:                    sendRenderMessage(true, GraphicsContext3D.SET_LIGHT, light,
0878:                            new Integer(index));
0879:                }
0880:            }
0881:
0882:            void doSetLight(Light light, int index) {
0883:
0884:                Light oldlight;
0885:                oldlight = (Light) this .lights.elementAt(index);
0886:                if (oldlight != null) {
0887:                    ((LightRetained) oldlight.retained).setInImmCtx(false);
0888:                }
0889:                ((LightRetained) light.retained).setInImmCtx(true);
0890:                updateLightState((LightRetained) light.retained);
0891:                this .lights.setElementAt(light, index);
0892:                this .lightsChanged = true;
0893:            }
0894:
0895:            /**
0896:             * Inserts the specified light at the specified index location.
0897:             * @param light the new light
0898:             * @param index at which location to insert
0899:             * @exception IllegalSharingException if the Light node
0900:             * is part of or is subsequently made part of a live scene graph.
0901:             * @exception NullPointerException if the Light object is null.
0902:             */
0903:            public void insertLight(Light light, int index) {
0904:                if (light == null) {
0905:                    throw new NullPointerException(J3dI18N
0906:                            .getString("GraphicsContext3D13"));
0907:                }
0908:                if (light.isLive()) {
0909:                    throw new IllegalSharingException(J3dI18N
0910:                            .getString("GraphicsContext3D14"));
0911:                }
0912:                uLights.insertElementAt(light, index);
0913:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
0914:                        || (!canvas3d.view.active)
0915:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
0916:                    doInsertLight(light, index);
0917:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
0918:                    sendRenderMessage(false, GraphicsContext3D.INSERT_LIGHT,
0919:                            light, new Integer(index));
0920:                } else {
0921:                    sendRenderMessage(true, GraphicsContext3D.INSERT_LIGHT,
0922:                            light, new Integer(index));
0923:                }
0924:            }
0925:
0926:            void doInsertLight(Light light, int index) {
0927:                ((LightRetained) light.retained).setInImmCtx(true);
0928:                updateLightState((LightRetained) light.retained);
0929:                this .lights.insertElementAt(light, index);
0930:                this .lightsChanged = true;
0931:            }
0932:
0933:            /**
0934:             * Removes the light at the specified index location.
0935:             * @param index which light to remove
0936:             */
0937:            public void removeLight(int index) {
0938:                uLights.removeElementAt(index);
0939:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
0940:                        || (!canvas3d.view.active)
0941:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
0942:                    doRemoveLight(index);
0943:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
0944:                    sendRenderMessage(false, GraphicsContext3D.REMOVE_LIGHT,
0945:                            new Integer(index), null);
0946:                } else {
0947:                    sendRenderMessage(true, GraphicsContext3D.REMOVE_LIGHT,
0948:                            new Integer(index), null);
0949:                }
0950:            }
0951:
0952:            void doRemoveLight(int index) {
0953:                Light light = (Light) this .lights.elementAt(index);
0954:
0955:                ((LightRetained) light.retained).setInImmCtx(false);
0956:                this .lights.removeElementAt(index);
0957:                this .lightsChanged = true;
0958:            }
0959:
0960:            /**
0961:             * Retrieves the index selected light.
0962:             * @param index which light to return
0963:             * @return the light at location index
0964:             */
0965:            public Light getLight(int index) {
0966:                return (Light) uLights.elementAt(index);
0967:            }
0968:
0969:            /**
0970:             * Retrieves the enumeration object of all the lights.
0971:             * @return the enumeration object of all the lights
0972:             */
0973:            public Enumeration getAllLights() {
0974:                return uLights.elements();
0975:            }
0976:
0977:            /**
0978:             * Appends the specified light to this graphics context's list of lights.
0979:             * Adding a null Light object to the list will result 
0980:             * in a NullPointerException. Both the region of influence 
0981:             * and the hierarchical scope of all lights in the list 
0982:             * are ignored for immediate-mode rendering.
0983:             * @param light the light to add
0984:             * @exception IllegalSharingException if the Light node
0985:             * is part of or is subsequently made part of a live scene graph.
0986:             * @exception NullPointerException if the Light object is null.
0987:             */
0988:            public void addLight(Light light) {
0989:                if (light == null) {
0990:                    throw new NullPointerException(J3dI18N
0991:                            .getString("GraphicsContext3D13"));
0992:                }
0993:
0994:                if (light.isLive()) {
0995:                    throw new IllegalSharingException(J3dI18N
0996:                            .getString("GraphicsContext3D14"));
0997:                }
0998:                uLights.addElement(light);
0999:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1000:                        || (!canvas3d.view.active)
1001:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1002:                    doAddLight(light);
1003:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1004:                    sendRenderMessage(false, GraphicsContext3D.ADD_LIGHT,
1005:                            light, null);
1006:                } else {
1007:                    sendRenderMessage(true, GraphicsContext3D.ADD_LIGHT, light,
1008:                            null);
1009:                }
1010:            }
1011:
1012:            void doAddLight(Light light) {
1013:
1014:                ((LightRetained) light.retained).setInImmCtx(true);
1015:                updateLightState((LightRetained) light.retained);
1016:                this .lights.addElement(light);
1017:                this .lightsChanged = true;
1018:            }
1019:
1020:            /**
1021:             * Retrieves the current number of lights in this graphics context.
1022:             * @return the current number of lights
1023:             */
1024:            public int numLights() {
1025:                return this .uLights.size();
1026:            }
1027:
1028:            private Transform3D getNormalTransform() {
1029:                if (compTransform.isRigid()) {
1030:                    return compTransform;
1031:                }
1032:                if (normalTransform == null) {
1033:                    normalTransform = new Transform3D();
1034:                }
1035:
1036:                if (normalTransformNeedToUpdate) {
1037:                    normalTransform.invert(compTransform);
1038:                    normalTransform.transpose();
1039:                    normalTransformNeedToUpdate = false;
1040:                }
1041:                return normalTransform;
1042:            }
1043:
1044:            void updateFogState(FogRetained fogRet) {
1045:                // Issue 144: update localToVWorldScale for all types of Fog
1046:                fogRet.setLocalToVworldScale(modelTransform.getDistanceScale());
1047:            }
1048:
1049:            void updateLightState(LightRetained light) {
1050:
1051:                if (light instanceof  DirectionalLightRetained) {
1052:                    DirectionalLightRetained dl = (DirectionalLightRetained) light;
1053:
1054:                    Transform3D xform = getNormalTransform();
1055:                    xform.transform(dl.direction, dl.xformDirection);
1056:                    dl.xformDirection.normalize();
1057:
1058:                } else if (light instanceof  SpotLightRetained) {
1059:                    SpotLightRetained sl = (SpotLightRetained) light;
1060:
1061:                    Transform3D xform = getNormalTransform();
1062:                    xform.transform(sl.direction, sl.xformDirection);
1063:                    sl.xformDirection.normalize();
1064:                    this .modelTransform
1065:                            .transform(sl.position, sl.xformPosition);
1066:
1067:                } else if (light instanceof  PointLightRetained) {
1068:                    PointLightRetained pl = (PointLightRetained) light;
1069:
1070:                    this .modelTransform
1071:                            .transform(pl.position, pl.xformPosition);
1072:
1073:                    pl.localToVworldScale = modelTransform.getDistanceScale();
1074:
1075:                }
1076:            }
1077:
1078:            /**
1079:             * Sets the HiRes coordinate of this context to the location
1080:             * specified by the parameters provided.
1081:             * The parameters x, y, and z are arrays of eight 32-bit 
1082:             * integers that specify the high-resolution coordinates point.
1083:             * @param x an eight element array specifying the x position
1084:             * @param y an eight element array specifying the y position
1085:             * @param z an eight element array specifying the z position
1086:             * @see HiResCoord
1087:             */
1088:            public void setHiRes(int[] x, int[] y, int[] z) {
1089:                HiResCoord hiRes = new HiResCoord(x, y, z);
1090:                setHiRes(hiRes);
1091:            }
1092:
1093:            /**
1094:             * Sets the HiRes coordinate of this context
1095:             * to the location specified by the HiRes argument.
1096:             * @param hiRes the HiRes coordinate specifying the a new location
1097:             */
1098:            public void setHiRes(HiResCoord hiRes) {
1099:                uHiRes.setHiResCoord(hiRes);
1100:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1101:                        || (!canvas3d.view.active)
1102:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1103:                    doSetHiRes(hiRes);
1104:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1105:                    sendRenderMessage(false, GraphicsContext3D.SET_HI_RES,
1106:                            hiRes, null);
1107:                } else {
1108:                    sendRenderMessage(true, GraphicsContext3D.SET_HI_RES,
1109:                            hiRes, null);
1110:                }
1111:            }
1112:
1113:            void doSetHiRes(HiResCoord hiRes) {
1114:                this .hiRes.setHiResCoord(hiRes);
1115:                computeCompositeTransform();
1116:            }
1117:
1118:            /**
1119:             * Retrieves the current HiRes coordinate of this context.
1120:             * @param hiRes a HiResCoord object that will receive the
1121:             * HiRes coordinate of this context
1122:             */
1123:            public void getHiRes(HiResCoord hiRes) {
1124:                uHiRes.getHiResCoord(hiRes);
1125:            }
1126:
1127:            /**
1128:             * Sets the current model transform to a copy of the specified
1129:             * transform.
1130:             * A BadTransformException is thrown if an attempt is made 
1131:             * to specify an illegal Transform3D.
1132:             * @param t the new model transform
1133:             * @exception BadTransformException if the transform is not affine.
1134:             */
1135:            public void setModelTransform(Transform3D t) {
1136:
1137:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1138:                        || (!canvas3d.view.active)
1139:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1140:                    doSetModelTransform(t);
1141:                } else {
1142:                    Transform3D uModelTransform = new Transform3D(t);
1143:                    //Transform3D uModelTransform = t;
1144:                    if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1145:                        sendRenderMessage(false,
1146:                                GraphicsContext3D.SET_MODEL_TRANSFORM,
1147:                                uModelTransform, null);
1148:                    } else {
1149:                        sendRenderMessage(true,
1150:                                GraphicsContext3D.SET_MODEL_TRANSFORM,
1151:                                uModelTransform, null);
1152:                    }
1153:                }
1154:            }
1155:
1156:            void doSetModelTransform(Transform3D t) {
1157:                this .modelTransform.set(t);
1158:                computeCompositeTransform();
1159:                normalTransformNeedToUpdate = true;
1160:            }
1161:
1162:            /**
1163:             * Multiplies the current model transform by the specified
1164:             * transform and stores the result back into the current
1165:             * transform. The specified transformation must be affine.
1166:             * @param t the model transform to be concatenated with the
1167:             * current model transform
1168:             * @exception BadTransformException if the transform is not affine.
1169:             */
1170:            public void multiplyModelTransform(Transform3D t) {
1171:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1172:                        || (!canvas3d.view.active)
1173:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1174:                    doMultiplyModelTransform(t);
1175:                } else {
1176:                    Transform3D tt = new Transform3D(t);
1177:                    if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1178:                        sendRenderMessage(false,
1179:                                GraphicsContext3D.MULTIPLY_MODEL_TRANSFORM, tt,
1180:                                null);
1181:                    } else {
1182:                        sendRenderMessage(true,
1183:                                GraphicsContext3D.MULTIPLY_MODEL_TRANSFORM, tt,
1184:                                null);
1185:                    }
1186:                }
1187:            }
1188:
1189:            void doMultiplyModelTransform(Transform3D t) {
1190:                this .modelTransform.mul(t);
1191:                computeCompositeTransform();
1192:                normalTransformNeedToUpdate = true;
1193:            }
1194:
1195:            /**
1196:             * Retrieves the current model transform.
1197:             * @param t the model transform that will receive the current
1198:             * model transform
1199:             */
1200:            public void getModelTransform(Transform3D t) {
1201:                t.set(modelTransform);
1202:            }
1203:
1204:            /**
1205:             * Replaces the specified sound with the sound provided.
1206:             * The graphics context stores a reference to each sound 
1207:             * object in the list of sounds. This means that the 
1208:             * application may modify the sound attributes for
1209:             * any of the sounds by using the appropriate methods on 
1210:             * that Sound node object.
1211:             * @param sound the new sound
1212:             * @param index which sound to replace
1213:             * @exception IllegalSharingException if the Sound node
1214:             * is part of or is subsequently made part of a live scene graph.
1215:             * @exception NullPointerException if the Sound object is null.
1216:             */
1217:            public void setSound(Sound sound, int index) {
1218:                if (sound == null) {
1219:                    throw new NullPointerException(J3dI18N
1220:                            .getString("GraphicsContext3D17"));
1221:                }
1222:                if (sound.isLive()) {
1223:                    throw new IllegalSharingException(J3dI18N
1224:                            .getString("GraphicsContext3D23"));
1225:                }
1226:                uSounds.setElementAt(sound, index);
1227:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1228:                        || (!canvas3d.view.active)
1229:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1230:                    doSetSound(sound, index);
1231:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1232:                    sendRenderMessage(false, GraphicsContext3D.SET_SOUND,
1233:                            sound, new Integer(index));
1234:                } else {
1235:                    sendRenderMessage(true, GraphicsContext3D.SET_SOUND, sound,
1236:                            new Integer(index));
1237:                }
1238:            }
1239:
1240:            void doSetSound(Sound sound, int index) {
1241:                Sound oldSound;
1242:                oldSound = (Sound) (this .sounds.elementAt(index));
1243:                ((SoundRetained) sound.retained).setInImmCtx(true);
1244:                if (oldSound != null) {
1245:                    ((SoundRetained) oldSound.retained).setInImmCtx(false);
1246:                }
1247:                ((SoundRetained) sound.retained).setInImmCtx(true);
1248:                updateSoundState((SoundRetained) (sound.retained));
1249:                this .sounds.setElementAt(sound, index);
1250:                this .soundsChanged = true;
1251:
1252:                sendSoundMessage(GraphicsContext3D.SET_SOUND, sound, oldSound);
1253:            }
1254:
1255:            /**
1256:             * Inserts the specified sound at the specified index location.
1257:             * Inserting a sound to the list of sounds implicitly starts the
1258:             * sound playing. Once a sound is finished playing, it can be 
1259:             * restarted by setting the sound's enable flag to true. 
1260:             * The scheduling region of all sounds in the list is ignored 
1261:             * for immediate-mode rendering.
1262:             * @param sound the new sound
1263:             * @param index at which location to insert
1264:             * @exception IllegalSharingException if the Sound node
1265:             * is part or is subsequently made part of a live scene graph.
1266:             * @exception NullPointerException if the Sound object is null.
1267:             */
1268:            public void insertSound(Sound sound, int index) {
1269:                if (sound == null) {
1270:                    throw new NullPointerException(J3dI18N
1271:                            .getString("GraphicsContext3D17"));
1272:                }
1273:
1274:                if (sound.isLive()) {
1275:                    throw new IllegalSharingException(J3dI18N
1276:                            .getString("GraphicsContext3D23"));
1277:                }
1278:                uSounds.insertElementAt(sound, index);
1279:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1280:                        || (!canvas3d.view.active)
1281:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1282:                    doInsertSound(sound, index);
1283:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1284:                    sendRenderMessage(false, GraphicsContext3D.INSERT_SOUND,
1285:                            sound, new Integer(index));
1286:                } else {
1287:                    sendRenderMessage(true, GraphicsContext3D.INSERT_SOUND,
1288:                            sound, new Integer(index));
1289:                }
1290:            }
1291:
1292:            void doInsertSound(Sound sound, int index) {
1293:                updateSoundState((SoundRetained) sound.retained);
1294:                this .sounds.insertElementAt(sound, index);
1295:                this .soundsChanged = true;
1296:                sendSoundMessage(GraphicsContext3D.INSERT_SOUND, sound, null);
1297:            }
1298:
1299:            /**
1300:             * Removes the sound at the specified index location.
1301:             * @param index which sound to remove
1302:             */
1303:            public void removeSound(int index) {
1304:                uSounds.removeElementAt(index);
1305:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1306:                        || (!canvas3d.view.active)
1307:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1308:                    doRemoveSound(index);
1309:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1310:                    sendRenderMessage(false, GraphicsContext3D.REMOVE_SOUND,
1311:                            new Integer(index), null);
1312:                } else {
1313:                    sendRenderMessage(true, GraphicsContext3D.REMOVE_SOUND,
1314:                            new Integer(index), null);
1315:                }
1316:            }
1317:
1318:            void doRemoveSound(int index) {
1319:                Sound sound = (Sound) (this .sounds.elementAt(index));
1320:                SoundScheduler soundScheduler = getSoundScheduler();
1321:                ((SoundRetained) (sound.retained)).setInImmCtx(false);
1322:                this .sounds.removeElementAt(index);
1323:                this .soundsChanged = true;
1324:                // stop sound if playing on audioDevice
1325:                sendSoundMessage(GraphicsContext3D.REMOVE_SOUND, null, sound);
1326:            }
1327:
1328:            /**
1329:             * Retrieves the index selected sound.
1330:             * @param index which sound to return
1331:             * @return the sound at location index
1332:             */
1333:            public Sound getSound(int index) {
1334:                Sound sound = (Sound) (uSounds.elementAt(index));
1335:                return sound;
1336:            }
1337:
1338:            /**
1339:             * Retrieves the enumeration object of all the sounds.
1340:             * @return the enumeration object of all the sounds
1341:             */
1342:            public Enumeration getAllSounds() {
1343:                return uSounds.elements();
1344:            }
1345:
1346:            /**
1347:             * Appends the specified sound to this graphics context's list of sounds.
1348:             * Adding a sound to the list of sounds implicitly starts the
1349:             * sound playing. Once a sound is finished playing, it can be 
1350:             * restarted by setting the sound's enable flag to true. 
1351:             * The scheduling region of all sounds in the list is ignored 
1352:             * for immediate-mode rendering.
1353:             * @param sound the sound to add
1354:             * @exception IllegalSharingException if the Sound node
1355:             * is part of or is subsequently made part of a live scene graph.
1356:             * @exception NullPointerException if the Sound object is null.
1357:             */
1358:            public void addSound(Sound sound) {
1359:                if (sound == null) {
1360:                    throw new NullPointerException(J3dI18N
1361:                            .getString("GraphicsContext3D17"));
1362:                }
1363:
1364:                if (sound.isLive()) {
1365:                    throw new IllegalSharingException(J3dI18N
1366:                            .getString("GraphicsContext3D23"));
1367:
1368:                }
1369:                uSounds.addElement(sound);
1370:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1371:                        || (!canvas3d.view.active)
1372:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1373:                    doAddSound(sound);
1374:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1375:                    sendRenderMessage(false, GraphicsContext3D.ADD_SOUND,
1376:                            sound, null);
1377:                } else {
1378:                    sendRenderMessage(true, GraphicsContext3D.ADD_SOUND, sound,
1379:                            null);
1380:                }
1381:            }
1382:
1383:            void doAddSound(Sound sound) {
1384:                ((SoundRetained) (sound.retained)).setInImmCtx(true);
1385:                updateSoundState((SoundRetained) (sound.retained));
1386:                this .sounds.addElement(sound);
1387:                this .soundsChanged = true;
1388:                sendSoundMessage(GraphicsContext3D.ADD_SOUND, sound, null);
1389:            }
1390:
1391:            /**
1392:             * Retrieves the current number of sounds in this graphics context.
1393:             * @return the current number of sounds
1394:             */
1395:            public int numSounds() {
1396:                return uSounds.size();
1397:            }
1398:
1399:            SoundScheduler getSoundScheduler() {
1400:                if (canvas3d != null && canvas3d.view != null)
1401:                    return canvas3d.view.soundScheduler; // could be null as well
1402:                else
1403:                    return (SoundScheduler) null;
1404:            }
1405:
1406:            void updateSoundState(SoundRetained sound) {
1407:                View view = null;
1408:                if (canvas3d != null)
1409:                    view = canvas3d.view;
1410:                // Make sure that:
1411:                //   . Current view is not null
1412:                //   . The sound scheduler running (reference to it is not null)
1413:                if (view != null) {
1414:                    SoundScheduler soundScheduler = getSoundScheduler();
1415:                    if (soundScheduler == null) {
1416:                        // XXXX: Re-implement
1417:                        // start up SoundScheduler since it hasn't already been started
1418:                    }
1419:                }
1420:
1421:                // Update sound fields related to transforms
1422:                if (sound instanceof  ConeSoundRetained) {
1423:                    ConeSoundRetained cs = (ConeSoundRetained) sound;
1424:                    this .modelTransform.transform(cs.direction,
1425:                            cs.xformDirection);
1426:                    cs.xformDirection.normalize();
1427:                    this .modelTransform
1428:                            .transform(cs.position, cs.xformPosition);
1429:                    // XXXX (Question) Is drawTranform equivalent to Vworld-to-Local?
1430:                    cs.trans.setWithLock(drawTransform);
1431:
1432:                } else if (sound instanceof  PointSoundRetained) {
1433:                    PointSoundRetained ps = (PointSoundRetained) sound;
1434:                    this .modelTransform
1435:                            .transform(ps.position, ps.xformPosition);
1436:                    // XXXX (Question) Is drawTranform equivalent to Vworld-to-Local?
1437:                    ps.trans.setWithLock(drawTransform);
1438:                }
1439:            }
1440:
1441:            /**
1442:             * Retrieves the sound playing flag.
1443:             * @param index which sound 
1444:             * @return flag denoting if sound is currently playing
1445:             */
1446:            public boolean isSoundPlaying(int index) {
1447:                Sound sound;
1448:                // uSounds isPlaying field is NOT updated, sounds elements are used
1449:                sound = (Sound) (this .sounds.elementAt(index));
1450:                return sound.isPlaying();
1451:            }
1452:
1453:            /**
1454:             * Sets the current AuralAttributes object to the specified
1455:             * AuralAttributes component object.
1456:             * This means that the application may modify individual 
1457:             * audio attributes by using the appropriate methods in 
1458:             * the Aural-Attributes object.
1459:             * @param attributes the new AuralAttributes object
1460:             */
1461:            public void setAuralAttributes(AuralAttributes attributes) {
1462:                uAuralAttributes = attributes;
1463:
1464:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1465:                        || (!canvas3d.view.active)
1466:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1467:                    doSetAuralAttributes(attributes);
1468:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1469:                    sendRenderMessage(false,
1470:                            GraphicsContext3D.SET_AURAL_ATTRIBUTES, attributes,
1471:                            null);
1472:                } else {
1473:                    sendRenderMessage(true,
1474:                            GraphicsContext3D.SET_AURAL_ATTRIBUTES, attributes,
1475:                            null);
1476:                }
1477:            }
1478:
1479:            void doSetAuralAttributes(AuralAttributes attributes) {
1480:                this .auralAttributes = attributes;
1481:                sendSoundMessage(GraphicsContext3D.SET_AURAL_ATTRIBUTES,
1482:                        attributes, null);
1483:            }
1484:
1485:            /**
1486:             * Retrieves the current AuralAttributes component object.
1487:             * @return the current AuralAttributes object
1488:             */
1489:            public AuralAttributes getAuralAttributes() {
1490:                return uAuralAttributes;
1491:            }
1492:
1493:            /**
1494:             * Sets a flag that specifies whether the double buffering and
1495:             * stereo mode from the Canvas3D are overridden.  When set to
1496:             * true, this attribute enables the
1497:             * <code>frontBufferRendering</code> and <code>stereoMode</code>
1498:             * attributes.
1499:             *
1500:             * @param bufferOverride the new buffer override flag
1501:             *
1502:             * @see #setFrontBufferRendering
1503:             * @see #setStereoMode
1504:             *
1505:             * @since Java 3D 1.2
1506:             */
1507:            public void setBufferOverride(boolean bufferOverride) {
1508:                uBufferOverride = bufferOverride;
1509:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1510:                        || (!canvas3d.view.active)
1511:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1512:                    doSetBufferOverride(bufferOverride);
1513:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1514:                    sendRenderMessage(false,
1515:                            GraphicsContext3D.SET_BUFFER_OVERRIDE, new Boolean(
1516:                                    bufferOverride), null);
1517:                } else {
1518:                    sendRenderMessage(true,
1519:                            GraphicsContext3D.SET_BUFFER_OVERRIDE, new Boolean(
1520:                                    bufferOverride), null);
1521:                }
1522:            }
1523:
1524:            void doSetBufferOverride(boolean bufferOverride) {
1525:                if (bufferOverride != this .bufferOverride) {
1526:                    this .bufferOverride = bufferOverride;
1527:                    dirtyMask |= BUFFER_MODE;
1528:                }
1529:            }
1530:
1531:            /**
1532:             * Returns the current buffer override flag.
1533:             * @return true if buffer override is enabled; otherwise,
1534:             * false is returned
1535:             *
1536:             * @since Java 3D 1.2
1537:             */
1538:            public boolean getBufferOverride() {
1539:                return uBufferOverride;
1540:            }
1541:
1542:            /**
1543:             * Sets a flag that enables or disables immediate mode rendering
1544:             * into the front buffer of a double buffered Canvas3D.
1545:             * This attribute is only used when the
1546:             * <code>bufferOverride</code> flag is enabled.
1547:             * <p>
1548:             * Note that this attribute has no effect if double buffering
1549:             * is disabled or is not available on the Canvas3D.
1550:             *
1551:             * @param frontBufferRendering the new front buffer rendering flag
1552:             *
1553:             * @see #setBufferOverride
1554:             *
1555:             * @since Java 3D 1.2
1556:             */
1557:            public void setFrontBufferRendering(boolean frontBufferRendering) {
1558:                uFrontBufferRendering = frontBufferRendering;
1559:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1560:                        || (!canvas3d.view.active)
1561:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1562:                    doSetFrontBufferRendering(frontBufferRendering);
1563:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1564:                    sendRenderMessage(false,
1565:                            GraphicsContext3D.SET_FRONT_BUFFER_RENDERING,
1566:                            new Boolean(frontBufferRendering), null);
1567:                } else {
1568:                    sendRenderMessage(true,
1569:                            GraphicsContext3D.SET_FRONT_BUFFER_RENDERING,
1570:                            new Boolean(frontBufferRendering), null);
1571:                }
1572:            }
1573:
1574:            void doSetFrontBufferRendering(boolean frontBufferRendering) {
1575:                if (frontBufferRendering != this .frontBufferRendering) {
1576:                    this .frontBufferRendering = frontBufferRendering;
1577:                    dirtyMask |= BUFFER_MODE;
1578:                }
1579:            }
1580:
1581:            /**
1582:             * Returns the current front buffer rendering flag.
1583:             * @return true if front buffer rendering is enabled; otherwise,
1584:             * false is returned
1585:             *
1586:             * @since Java 3D 1.2
1587:             */
1588:            public boolean getFrontBufferRendering() {
1589:                return uFrontBufferRendering;
1590:            }
1591:
1592:            /**
1593:             * Sets the stereo mode for immediate mode rendering.  The
1594:             * parameter specifies which stereo buffer or buffers is rendered
1595:             * into.  This attribute is only used when the
1596:             * <code>bufferOverride</code> flag is enabled.
1597:             * <ul>
1598:             * <li>
1599:             * <code>STEREO_LEFT</code> specifies that rendering is done into
1600:             * the left eye.
1601:             * </li>
1602:             * <li>
1603:             * <code>STEREO_RIGHT</code> specifies that rendering is done into
1604:             * the right eye.
1605:             * </li>
1606:             * <li>
1607:             * <code>STEREO_BOTH</code> specifies that rendering is done into
1608:             * both eyes.  This is the default.
1609:             * </li>
1610:             * </ul>
1611:             *
1612:             * <p>
1613:             * Note that this attribute has no effect if stereo is disabled or
1614:             * is not available on the Canvas3D.
1615:             *
1616:             * @param stereoMode the new stereo mode
1617:             *
1618:             * @see #setBufferOverride
1619:             *
1620:             * @since Java 3D 1.2
1621:             */
1622:            public void setStereoMode(int stereoMode) {
1623:                uStereoMode = stereoMode;
1624:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1625:                        || (!canvas3d.view.active)
1626:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
1627:                    doSetStereoMode(stereoMode);
1628:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1629:                    sendRenderMessage(false, GraphicsContext3D.SET_STEREO_MODE,
1630:                            stereoModes[stereoMode], null);
1631:                } else {
1632:                    sendRenderMessage(true, GraphicsContext3D.SET_STEREO_MODE,
1633:                            stereoModes[stereoMode], null);
1634:                }
1635:            }
1636:
1637:            void doSetStereoMode(int stereoMode) {
1638:                if (stereoMode != this .stereoMode) {
1639:                    this .stereoMode = stereoMode;
1640:                    dirtyMask |= BUFFER_MODE;
1641:                }
1642:            }
1643:
1644:            /**
1645:             * Returns the current stereo mode.
1646:             * @return the stereo mode, one of <code>STEREO_LEFT</code>,
1647:             * <code>STEREO_RIGHT</code>, or <code>STEREO_BOTH</code>.
1648:             *
1649:             * @since Java 3D 1.2
1650:             */
1651:            public int getStereoMode() {
1652:                return uStereoMode;
1653:            }
1654:
1655:            //
1656:            // Methods to draw graphics objects
1657:            //
1658:
1659:            /**
1660:             * Clear the Canvas3D to the color or image specified by the
1661:             * current background node.
1662:             */
1663:            public void clear() {
1664:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
1665:                        || (!canvas3d.view.active)) {
1666:                    return;
1667:                } else if (Thread.currentThread() == canvas3d.screen.renderer) {
1668:                    doClear();
1669:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
1670:                    sendRenderMessage(false, GraphicsContext3D.CLEAR, null,
1671:                            null);
1672:                } else {
1673:                    sendRenderMessage(true, GraphicsContext3D.CLEAR, null, null);
1674:                }
1675:            }
1676:
1677:            void doClear() {
1678:
1679:                if (!canvas3d.firstPaintCalled)
1680:                    return;
1681:
1682:                RenderBin rb = canvas3d.view.renderBin;
1683:                BackgroundRetained back = null;
1684:
1685:                if (this .background != null)
1686:                    back = (BackgroundRetained) this .background.retained;
1687:                else
1688:                    back = this .black;
1689:
1690:                // XXXX: This should ideally be done by the renderer (or by the
1691:                // canvas itself) when the canvas is first added to a view.
1692:                /*
1693:                if ((canvas3d.screen.renderer != null) &&
1694:                    (canvas3d.screen.renderer.renderBin == null))
1695:                    canvas3d.screen.renderer.renderBin = rb;
1696:                 */
1697:                // If we are in pure immediate mode, update the view cache
1698:                if (!canvas3d.isRunning)
1699:                    updateViewCache(rb);
1700:
1701:                // We need to catch NullPointerException when the dsi
1702:                // gets yanked from us during a remove.
1703:
1704:                try {
1705:                    // Issue 78 - need to get the drawingSurface info every
1706:                    // frame; this is necessary since the HDC (window ID)
1707:                    // on Windows can become invalidated without our
1708:                    // being notified!
1709:                    if (!canvas3d.offScreen) {
1710:                        canvas3d.drawingSurfaceObject
1711:                                .getDrawingSurfaceObjectInfo();
1712:                    }
1713:
1714:                    if (canvas3d.drawingSurfaceObject.renderLock()) {
1715:                        // XXXX : Fix texture
1716:                        /*
1717:                        if (canvas3d.useSharedCtx) {
1718:                            if (canvas3d.screen.renderer.sharedCtx == 0) {
1719:                                synchronized (VirtualUniverse.mc.contextCreationLock) {
1720:                                    canvas3d.screen.renderer.sharedCtx = canvas3d.createNewContext(
1721:                                                canvas3d.screen.display,
1722:                                                canvas3d.window, 0, true,
1723:                                                canvas3d.offScreen);
1724:                                    canvas3d.screen.renderer.sharedCtxTimeStamp =
1725:                                        VirtualUniverse.mc.getContextTimeStamp();
1726:                                    canvas3d.screen.renderer.needToRebuildDisplayList = true;
1727:                                }
1728:                            }
1729:                        }
1730:                         */
1731:
1732:                        if (canvas3d.ctx == null) {
1733:                            synchronized (VirtualUniverse.mc.contextCreationLock) {
1734:                                canvas3d.ctx = canvas3d.createNewContext(null,
1735:                                        false);
1736:                                if (canvas3d.ctx == null) {
1737:                                    canvas3d.drawingSurfaceObject.unLock();
1738:                                    return;
1739:                                }
1740:
1741:                                canvas3d.ctxTimeStamp = VirtualUniverse.mc
1742:                                        .getContextTimeStamp();
1743:                                canvas3d.screen.renderer.listOfCtxs
1744:                                        .add(canvas3d.ctx);
1745:                                canvas3d.screen.renderer.listOfCanvases
1746:                                        .add(canvas3d);
1747:
1748:                                canvas3d.beginScene();
1749:
1750:                                if (canvas3d.graphics2D != null) {
1751:                                    canvas3d.graphics2D.init();
1752:                                }
1753:
1754:                                // enable separate specular color
1755:                                canvas3d.enableSeparateSpecularColor();
1756:                            }
1757:
1758:                            // create the cache texture state in canvas
1759:                            // for state download checking purpose
1760:                            if (canvas3d.texUnitState == null) {
1761:                                canvas3d.createTexUnitState();
1762:                            }
1763:
1764:                            canvas3d.drawingSurfaceObject.contextValidated();
1765:                            canvas3d.screen.renderer.currentCtx = canvas3d.ctx;
1766:                            canvas3d.screen.renderer.currentDrawable = canvas3d.drawable;
1767:                            initializeState();
1768:                            canvas3d.ctxChanged = true;
1769:                            canvas3d.canvasDirty = 0xffff;
1770:                            // Update Appearance
1771:                            updateState(rb, RenderMolecule.SURFACE);
1772:
1773:                            canvas3d.currentLights = new LightRetained[canvas3d
1774:                                    .getNumCtxLights(canvas3d.ctx)];
1775:
1776:                            for (int j = 0; j < canvas3d.currentLights.length; j++) {
1777:                                canvas3d.currentLights[j] = null;
1778:                            }
1779:                        }
1780:
1781:                        canvas3d.makeCtxCurrent();
1782:
1783:                        if ((dirtyMask & BUFFER_MODE) != 0) {
1784:                            if (bufferOverride) {
1785:                                canvas3d.setRenderMode(canvas3d.ctx,
1786:                                        stereoMode, canvas3d.useDoubleBuffer
1787:                                                && !frontBufferRendering);
1788:                            } else {
1789:                                if (!canvas3d.isRunning) {
1790:                                    canvas3d.setRenderMode(canvas3d.ctx,
1791:                                            Canvas3D.FIELD_ALL,
1792:                                            canvas3d.useDoubleBuffer);
1793:                                }
1794:                            }
1795:                            dirtyMask &= ~BUFFER_MODE;
1796:                        }
1797:
1798:                        Dimension size = canvas3d.getSize();
1799:                        int winWidth = size.width;
1800:                        int winHeight = size.height;
1801:                        boolean isByRefBackgroundImage = false;
1802:                        if (back.image != null) {
1803:                            if (back.image.isByReference()) {
1804:                                back.image.geomLock.getLock();
1805:                                isByRefBackgroundImage = true;
1806:                            }
1807:
1808:                            back.image.evaluateExtensions(canvas3d);
1809:                        }
1810:
1811:                        canvas3d.clear(back, winWidth, winHeight);
1812:
1813:                        if (isByRefBackgroundImage) {
1814:                            back.image.geomLock.unLock();
1815:                        }
1816:
1817:                        // Set the viewport and view matrices
1818:                        if (!canvas3d.isRunning) {
1819:                            CanvasViewCache cvCache = canvas3d.canvasViewCache;
1820:                            canvas3d.setViewport(canvas3d.ctx, 0, 0, cvCache
1821:                                    .getCanvasWidth(), cvCache
1822:                                    .getCanvasHeight());
1823:                            if (bufferOverride && (stereoMode == STEREO_RIGHT)) {
1824:                                canvas3d.setProjectionMatrix(canvas3d.ctx,
1825:                                        cvCache.getRightProjection());
1826:                                canvas3d.setModelViewMatrix(canvas3d.ctx,
1827:                                        cvCache.getRightVpcToEc().mat,
1828:                                        rb.vworldToVpc);
1829:                            } else {
1830:                                canvas3d.setProjectionMatrix(canvas3d.ctx,
1831:                                        cvCache.getLeftProjection());
1832:                                canvas3d.setModelViewMatrix(canvas3d.ctx,
1833:                                        cvCache.getLeftVpcToEc().mat,
1834:                                        rb.vworldToVpc);
1835:                            }
1836:                        }
1837:
1838:                        canvas3d.drawingSurfaceObject.unLock();
1839:                    }
1840:                } catch (NullPointerException ne) {
1841:                    canvas3d.drawingSurfaceObject.unLock();
1842:                    throw ne;
1843:                }
1844:            }
1845:
1846:            // Method to update compTransform.
1847:            private void computeCompositeTransform() {
1848:                ViewPlatform vp;
1849:
1850:                if ((canvas3d == null) || (canvas3d.view == null)
1851:                        || (((vp = canvas3d.view.getViewPlatform()) == null))
1852:                        || (((ViewPlatformRetained) (vp.retained)) == null)) {
1853:                    compTransform.set(modelTransform);
1854:                    return;
1855:                }
1856:
1857:                ViewPlatformRetained vpR = (ViewPlatformRetained) vp.retained;
1858:                if ((vpR == null) || (vpR.locale == null)) {
1859:                    compTransform.set(modelTransform);
1860:                    return;
1861:                }
1862:
1863:                HiResCoord localeHiRes = vpR.locale.hiRes;
1864:
1865:                if (localeHiRes.equals(hiRes)) {
1866:                    compTransform.set(modelTransform);
1867:                } else {
1868:                    Transform3D trans = new Transform3D();
1869:                    Vector3d localeTrans = new Vector3d();
1870:                    localeHiRes.difference(hiRes, localeTrans);
1871:                    trans.setTranslation(localeTrans);
1872:                    compTransform.mul(trans, modelTransform);
1873:                }
1874:            }
1875:
1876:            // Method to update the view cache in pure immediate mode
1877:            private void updateViewCache(RenderBin rb) {
1878:
1879:                ViewPlatform vp = canvas3d.view.getViewPlatform();
1880:
1881:                if (vp == null)
1882:                    return;
1883:
1884:                ViewPlatformRetained vpR = (ViewPlatformRetained) vp.retained;
1885:
1886:                if (!canvas3d.isRunning) {
1887:                    // in pure immediate mode, notify platform transform change
1888:                    vpR.evaluateInitViewPlatformTransform();
1889:                }
1890:
1891:                //	rb.setVworldToVpc(vp.getVworldToVpc());
1892:                //	rb.setVpcToVworld(vp.getVpcToVworld());
1893:
1894:                // XXXX: Fix this
1895:                rb.vpcToVworld = vpR.getVpcToVworld();
1896:                rb.vworldToVpc = vpR.getVworldToVpc();
1897:
1898:                canvas3d.updateViewCache(true, null, null, false);
1899:            }
1900:
1901:            void doDraw(Geometry geometry) {
1902:
1903:                boolean useAlpha;
1904:                GeometryRetained drawGeo;
1905:                GeometryArrayRetained geoRetained = null;
1906:
1907:                if (!canvas3d.firstPaintCalled || !visible) {
1908:                    return;
1909:                }
1910:
1911:                RenderBin rb = canvas3d.view.renderBin;
1912:                int i, nlights, activeLights;
1913:                LightRetained light;
1914:                boolean lightingOn = true;
1915:
1916:                if (canvas3d.ctx == null) {
1917:                    // Force an initial clear if one has not yet been done
1918:                    doClear();
1919:                }
1920:
1921:                if (J3dDebug.devPhase && J3dDebug.debug) {
1922:                    J3dDebug.doAssert(canvas3d.ctx != null,
1923:                            "canvas3d.ctx != null");
1924:                }
1925:
1926:                // We need to catch NullPointerException when the dsi 
1927:                // gets yanked from us during a remove.
1928:                try {
1929:                    if (canvas3d.drawingSurfaceObject.renderLock()) {
1930:
1931:                        // Make the context current
1932:                        canvas3d.makeCtxCurrent();
1933:
1934:                        if ((dirtyMask & BUFFER_MODE) != 0) {
1935:                            if (bufferOverride) {
1936:                                canvas3d.setRenderMode(canvas3d.ctx,
1937:                                        stereoMode, canvas3d.useDoubleBuffer
1938:                                                && !frontBufferRendering);
1939:                            } else {
1940:                                canvas3d.setRenderMode(canvas3d.ctx,
1941:                                        Canvas3D.FIELD_ALL,
1942:                                        canvas3d.useDoubleBuffer);
1943:                            }
1944:                            dirtyMask &= ~BUFFER_MODE;
1945:                        }
1946:
1947:                        CanvasViewCache cvCache = canvas3d.canvasViewCache;
1948:                        Transform3D proj;
1949:
1950:                        //  	    vpcToEc = cvCache.getLeftVpcToEc(); 
1951:                        if (bufferOverride) {
1952:                            switch (stereoMode) {
1953:                            case STEREO_RIGHT:
1954:                                vpcToEc = cvCache.getRightVpcToEc();
1955:                                // XXXX: move this under check for 
1956:                                // (dirtyMask & BUFFER_MODE) above after testing
1957:                                // PureImmediate mode
1958:                                canvas3d.setProjectionMatrix(canvas3d.ctx,
1959:                                        cvCache.getRightProjection());
1960:                                break;
1961:                            case STEREO_LEFT:
1962:                            case STEREO_BOTH:
1963:                            default:
1964:                                vpcToEc = cvCache.getLeftVpcToEc();
1965:                                // XXXX: move this under check for 
1966:                                // (dirtyMask & BUFFER_MODE) above after testing
1967:                                // PureImmediate mode
1968:                                canvas3d.setProjectionMatrix(canvas3d.ctx,
1969:                                        cvCache.getLeftProjection());
1970:                            }
1971:                        } else if (!canvas3d.isRunning ||
1972:                        // vpcToEc is not set in the first frame
1973:                                // of preRender() callback
1974:                                (canvas3d.vpcToEc == null)) {
1975:                            vpcToEc = cvCache.getLeftVpcToEc();
1976:                        } else {
1977:                            vpcToEc = canvas3d.vpcToEc;
1978:                        }
1979:
1980:                        // referred by RenderQueue.updateState
1981:                        //	    canvas3d.screen.renderer.vpcToEc = vpcToEc;
1982:                        //	    rb.updateState(canvas3d.screen.renderer.rId, ro, canvas3d, true);
1983:
1984:                        //	    this.drawTransform.mul(rb.vworldToVpc,
1985:                        //	    this.compTransform); 
1986:
1987:                        boolean isNonUniformScale = !drawTransform
1988:                                .isCongruent();
1989:
1990:                        int geometryType = 0;
1991:                        switch (((GeometryRetained) geometry.retained).geoType) {
1992:                        case GeometryRetained.GEO_TYPE_POINT_SET:
1993:                        case GeometryRetained.GEO_TYPE_INDEXED_POINT_SET:
1994:                            geometryType = RenderMolecule.POINT;
1995:                            break;
1996:                        case GeometryRetained.GEO_TYPE_LINE_SET:
1997:                        case GeometryRetained.GEO_TYPE_LINE_STRIP_SET:
1998:                        case GeometryRetained.GEO_TYPE_INDEXED_LINE_SET:
1999:                        case GeometryRetained.GEO_TYPE_INDEXED_LINE_STRIP_SET:
2000:                            geometryType = RenderMolecule.LINE;
2001:                            break;
2002:                        case GeometryRetained.GEO_TYPE_RASTER:
2003:                            geometryType = RenderMolecule.RASTER;
2004:                            break;
2005:                        case GeometryRetained.GEO_TYPE_COMPRESSED:
2006:                            geometryType = RenderMolecule.COMPRESSED;
2007:
2008:                            switch (((CompressedGeometryRetained) geometry.retained)
2009:                                    .getBufferType()) {
2010:                            case CompressedGeometryHeader.POINT_BUFFER:
2011:                                geometryType |= RenderMolecule.POINT;
2012:                                break;
2013:                            case CompressedGeometryHeader.LINE_BUFFER:
2014:                                geometryType |= RenderMolecule.LINE;
2015:                                break;
2016:                            default:
2017:                            case CompressedGeometryHeader.TRIANGLE_BUFFER:
2018:                                geometryType |= RenderMolecule.SURFACE;
2019:                                break;
2020:                            }
2021:                            break;
2022:                        default:
2023:                            geometryType = RenderMolecule.SURFACE;
2024:                            break;
2025:                        }
2026:
2027:                        useAlpha = updateState(rb, geometryType);
2028:
2029:                        canvas3d.setModelViewMatrix(canvas3d.ctx, vpcToEc.mat,
2030:                                rb.vworldToVpc);
2031:                        updateLightAndFog();
2032:
2033:                        updateModelClip(rb.vworldToVpc);
2034:
2035:                        this .drawTransform.mul(rb.vworldToVpc,
2036:                                this .compTransform);
2037:                        canvas3d.setModelViewMatrix(canvas3d.ctx, vpcToEc.mat,
2038:                                this .drawTransform);
2039:
2040:                        if (geometry.retained instanceof  GeometryArrayRetained) {
2041:                            geoRetained = (GeometryArrayRetained) geometry.retained;
2042:
2043:                            geoRetained.geomLock.getLock();
2044:                            // If the geometry is by refernence, then see if we are using alpha
2045:                            // and that there is no global alpha sun extension defined ..
2046:                            if (((geoRetained.vertexFormat & GeometryArray.BY_REFERENCE) != 0)
2047:                                    && (geoRetained.c4fAllocated == 0)
2048:                                    && ((geoRetained.vertexFormat & GeometryArray.COLOR) != 0)
2049:                                    && useAlpha
2050:                                    && (canvas3d.extensionsSupported & Canvas3D.SUN_GLOBAL_ALPHA) == 0) {
2051:
2052:                                if ((geoRetained.vertexFormat & GeometryArray.INTERLEAVED) != 0) {
2053:                                    geoRetained
2054:                                            .setupMirrorInterleavedColorPointer(true);
2055:                                } else {
2056:                                    geoRetained
2057:                                            .setupMirrorColorPointer(
2058:                                                    (geoRetained.vertexType & GeometryArrayRetained.COLOR_DEFINED),
2059:                                                    true);
2060:                                }
2061:                            }
2062:
2063:                            if ((geometry.retained instanceof  IndexedGeometryArrayRetained)
2064:                                    && ((((GeometryArrayRetained) geometry.retained).vertexFormat & GeometryArray.USE_COORD_INDEX_ONLY) == 0)) {
2065:                                if (geoRetained.dirtyFlag != 0) {
2066:                                    geoRetained.mirrorGeometry = ((IndexedGeometryArrayRetained) geoRetained)
2067:                                            .cloneNonIndexedGeometry();
2068:                                    // Change the source geometry dirtyFlag
2069:                                    // drawGeo.execute() will change the
2070:                                    // destination geometry dirtyFlag only.
2071:                                    geoRetained.dirtyFlag = 0;
2072:                                }
2073:                                drawGeo = (GeometryRetained) geoRetained.mirrorGeometry;
2074:                            } else {
2075:                                drawGeo = geoRetained;
2076:                            }
2077:
2078:                            geoRetained.setVertexFormat(false,
2079:                                    ignoreVertexColors, canvas3d.ctx);
2080:
2081:                        } else if (geometry.retained instanceof  Text3DRetained) {
2082:                            ((Text3DRetained) geometry.retained)
2083:                                    .setModelViewMatrix(vpcToEc,
2084:                                            this .drawTransform);
2085:                            drawGeo = (GeometryRetained) geometry.retained;
2086:                        } else if (geometry.retained instanceof  RasterRetained) {
2087:                            ImageComponent2DRetained img = ((RasterRetained) geometry.retained).image;
2088:                            if (img != null) {
2089:                                if (img.isByReference()) {
2090:                                    img.geomLock.getLock();
2091:                                    img.evaluateExtensions(canvas3d);
2092:                                    img.geomLock.unLock();
2093:                                } else {
2094:                                    img.evaluateExtensions(canvas3d);
2095:                                }
2096:                            }
2097:                            drawGeo = (GeometryRetained) geometry.retained;
2098:                        } else {
2099:                            drawGeo = (GeometryRetained) geometry.retained;
2100:                        }
2101:
2102:                        drawGeo.execute(canvas3d, null, isNonUniformScale,
2103:                                false, alpha, canvas3d.screen.screen,
2104:                                ignoreVertexColors);
2105:
2106:                        if (geoRetained != null) {
2107:                            if (geoRetained.pVertexBuffers != 0) {
2108:                                // Issue 121: always free D3D vertex buffer memory
2109:                                // after immediate mode rendering
2110:                                geoRetained.freeD3DArray(true);
2111:                            }
2112:
2113:                            geoRetained.geomLock.unLock();
2114:                        }
2115:
2116:                        canvas3d.drawingSurfaceObject.unLock();
2117:                    }
2118:                } catch (NullPointerException ne) {
2119:                    canvas3d.drawingSurfaceObject.unLock();
2120:                    throw ne;
2121:                }
2122:            }
2123:
2124:            /**
2125:             * Draw the specified Geometry component object.
2126:             * @param geometry the Geometry object to draw.
2127:             *
2128:             * @exception IllegalSharingException if the specified geometry is a 
2129:             * Raster that refers to an ImageComponent2D that is being used by a 
2130:             * Canvas3D as an off-screen buffer.
2131:             */
2132:            public void draw(Geometry geometry) {
2133:                // do illegalSharing check
2134:                if ((geometry != null) && (geometry instanceof  Raster)) {
2135:                    RasterRetained rasRetained = (RasterRetained) geometry.retained;
2136:                    ImageComponent2D image = rasRetained.getImage();
2137:                    if (image != null) {
2138:                        ImageComponentRetained imageRetained = (ImageComponentRetained) image.retained;
2139:                        // Do illegal sharing check
2140:                        if (imageRetained.getUsedByOffScreen()) {
2141:                            throw new IllegalSharingException(J3dI18N
2142:                                    .getString("GraphicsContext3D32"));
2143:                        }
2144:                    }
2145:                }
2146:
2147:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
2148:                        || (!canvas3d.view.active)) {
2149:                    return;
2150:                } else if (Thread.currentThread() == canvas3d.screen.renderer) {
2151:                    doDraw(geometry);
2152:                } else {
2153:                    if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
2154:                        sendRenderMessage(false, GraphicsContext3D.DRAW,
2155:                                geometry, null);
2156:                    } else {
2157:                        sendRenderMessage(true, GraphicsContext3D.DRAW,
2158:                                geometry, null);
2159:                    }
2160:                }
2161:            }
2162:
2163:            /**
2164:             * Draw the specified Shape3D leaf node object.  This is
2165:             * a convenience method that is identical to calling the
2166:             * setAppearance(Appearance) and draw(Geometry) methods
2167:             * passing the appearance and geometry component objects of
2168:             * the specified shape node as arguments.
2169:             *
2170:             * @param shape the Shape3D node containing the Appearance component
2171:             * object to set and Geometry component object to draw
2172:             *
2173:             * @exception IllegalSharingException if the Shape3D node
2174:             * is part of or is subsequently made part of a live scene graph.
2175:             *
2176:             * @exception IllegalSharingException if the Shape3D node's Appearance
2177:             * refers to an ImageComponent2D that is being used by a
2178:             * Canvas3D as an off-screen buffer.
2179:             */
2180:            public void draw(Shape3D shape) {
2181:                if (shape.isLive()) {
2182:                    throw new IllegalSharingException(J3dI18N
2183:                            .getString("GraphicsContext3D26"));
2184:                }
2185:                ((Shape3DRetained) shape.retained).setInImmCtx(true);
2186:                setAppearance(shape.getAppearance());
2187:                draw(shape.getGeometry());
2188:            }
2189:
2190:            /**
2191:             * Read an image from the frame buffer and copy it into the
2192:             * ImageComponent and/or DepthComponent
2193:             * objects referenced by the specified Raster object.
2194:             * All parameters of the Raster object and the component ImageComponent
2195:             * and/or DepthComponentImage objects must be set to the desired values
2196:             * prior to calling this method.  These values determine the location,
2197:             * size, and format of the pixel data that is read.
2198:             * This method calls <code>flush(true)</code> prior to reading the
2199:             * frame buffer.
2200:             *
2201:             * @param raster the Raster object used to read the
2202:             * contents of the frame buffer
2203:             *
2204:             * @exception IllegalArgumentException if the image class of the specified
2205:             * Raster's ImageComponent2D is <i>not</i> ImageClass.BUFFERED_IMAGE.
2206:             *
2207:             * @exception IllegalArgumentException if the specified Raster's
2208:             * ImageComponent2D is in by-reference mode and its
2209:             * RenderedImage is null.
2210:             *
2211:             * @exception IllegalArgumentException if the the Raster's
2212:             * ImageComponent2D format
2213:             * is <i>not</i> a 3-component format (e.g., FORMAT_RGB)
2214:             * or a 4-component format (e.g., FORMAT_RGBA).
2215:             *
2216:             * @exception IllegalSharingException if the Raster object is
2217:             * part of a live scene graph, or if the Raster's ImageComponent2D is
2218:             * part of a live scene graph.
2219:             *
2220:             * @exception IllegalSharingException if the Raster's ImageComponent2D is
2221:             * being used by an immediate mode context, or by a Canvas3D as
2222:             * an off-screen buffer.
2223:             *
2224:             * @see #flush
2225:             * @see ImageComponent
2226:             * @see DepthComponent
2227:             */
2228:            public void readRaster(Raster raster) {
2229:                if ((raster != null) && raster.isLive()) {
2230:                    ImageComponent2D image = raster.getImage();
2231:                    if (image != null) {
2232:                        ImageComponent2DRetained imageRetained = (ImageComponent2DRetained) image.retained;
2233:                        if (image.getImageClass() != ImageComponent.ImageClass.BUFFERED_IMAGE) {
2234:                            throw new IllegalArgumentException(J3dI18N
2235:                                    .getString("GraphicsContext3D33"));
2236:                        }
2237:                        if (image.isByReference() && (image.getImage() == null)) {
2238:                            throw new IllegalArgumentException(J3dI18N
2239:                                    .getString("GraphicsContext3D34"));
2240:                        }
2241:                        if (imageRetained.getNumberOfComponents() < 3) {
2242:                            throw new IllegalArgumentException(J3dI18N
2243:                                    .getString("GraphicsContext3D35"));
2244:                        }
2245:                        if (image.isLive()) {
2246:                            throw new IllegalSharingException(J3dI18N
2247:                                    .getString("GraphicsContext3D36"));
2248:                        }
2249:                        if (imageRetained.getInImmCtx()
2250:                                || imageRetained.getUsedByOffScreen()) {
2251:                            throw new IllegalSharingException(J3dI18N
2252:                                    .getString("GraphicsContext3D37"));
2253:                        }
2254:                    }
2255:                }
2256:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
2257:                        || (!canvas3d.view.active)) {
2258:                    return;
2259:                } else if (Thread.currentThread() == canvas3d.screen.renderer) {
2260:                    doReadRaster(raster);
2261:                } else if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
2262:                    readRasterReady = false;
2263:                    sendRenderMessage(false, GraphicsContext3D.READ_RASTER,
2264:                            raster, null);
2265:                    while (!readRasterReady) {
2266:                        MasterControl.threadYield();
2267:                    }
2268:                } else {
2269:                    // call from user thread
2270:                    readRasterReady = false;
2271:                    sendRenderMessage(true, GraphicsContext3D.READ_RASTER,
2272:                            raster, null);
2273:                    while (!readRasterReady) {
2274:                        MasterControl.threadYield();
2275:                    }
2276:                }
2277:            }
2278:
2279:            void doReadRaster(Raster raster) {
2280:                if (!canvas3d.firstPaintCalled) {
2281:                    readRasterReady = true;
2282:                    return;
2283:                }
2284:
2285:                RasterRetained ras = (RasterRetained) raster.retained;
2286:                Dimension canvasSize = canvas3d.getSize();
2287:                Dimension rasterSize = new Dimension();
2288:                ImageComponent2DRetained image = ras.image;
2289:
2290:                int format = 0; // Not use in case of DepthComponent read
2291:
2292:                if (canvas3d.ctx == null) {
2293:                    // Force an initial clear if one has not yet been done
2294:                    doClear();
2295:                }
2296:
2297:                if (J3dDebug.devPhase && J3dDebug.debug) {
2298:                    J3dDebug.doAssert(canvas3d.ctx != null,
2299:                            "canvas3d.ctx != null");
2300:                }
2301:
2302:                ras.getSize(rasterSize);
2303:                // allocate read buffer space
2304:                if ((ras.type & Raster.RASTER_COLOR) != 0) {
2305:                    if ((rasterSize.width > ras.image.width)
2306:                            || (rasterSize.height > ras.image.height)) {
2307:                        throw new RuntimeException(J3dI18N
2308:                                .getString("GraphicsContext3D27"));
2309:                    }
2310:                }
2311:
2312:                if ((ras.type & Raster.RASTER_DEPTH) != 0) {
2313:                    int size = ras.depthComponent.height
2314:                            * ras.depthComponent.width;
2315:                    if (ras.depthComponent.type == DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT) {
2316:                        if (floatBuffer.length < size)
2317:                            floatBuffer = new float[size];
2318:                    } else { // type INT or NATIVE
2319:                        if (intBuffer.length < size)
2320:                            intBuffer = new int[size];
2321:                    }
2322:                    if ((rasterSize.width > ras.depthComponent.width)
2323:                            || (rasterSize.height > ras.depthComponent.height)) {
2324:                        throw new RuntimeException(J3dI18N
2325:                                .getString("GraphicsContext3D28"));
2326:                    }
2327:                }
2328:
2329:                if ((ras.type & Raster.RASTER_COLOR) != 0) {
2330:
2331:                    // If by reference, check if a copy needs to be made
2332:                    // and also evaluate the storedFormat ..
2333:                    if (image.isByReference()) {
2334:                        image.geomLock.getLock();
2335:                        image.evaluateExtensions(canvas3d);
2336:                        image.geomLock.unLock();
2337:                    } else {
2338:                        // If image has a null buffer ( BufferedImage)
2339:                        if (image.imageData == null) {
2340:                            image.createBlankImageData();
2341:                        }
2342:                        // Check for possible format conversion in imageData
2343:                        else {
2344:                            // Format convert imageData if format is unsupported.
2345:                            image.evaluateExtensions(canvas3d);
2346:                        }
2347:                    }
2348:                }
2349:
2350:                // We need to catch NullPointerException when the dsi
2351:                // gets yanked from us during a remove.
2352:                try {
2353:                    if (canvas3d.drawingSurfaceObject.renderLock()) {
2354:                        // Make the context current and read the raster information
2355:                        canvas3d.makeCtxCurrent();
2356:                        canvas3d.syncRender(canvas3d.ctx, true);
2357:                        Point rasterSrcOffset = new Point();
2358:                        ras.getDstOffset(rasterSrcOffset);
2359:
2360:                        DepthComponentRetained depthComp = ras.depthComponent;
2361:                        int depthType = 0;
2362:                        if (depthComp != null) {
2363:                            depthType = depthComp.type;
2364:                        }
2365:                        Pipeline.getPipeline().readRaster(canvas3d.ctx,
2366:                                ras.type, rasterSrcOffset.x, rasterSrcOffset.y,
2367:                                rasterSize.width, rasterSize.height,
2368:                                canvasSize.height,
2369:                                image.getImageDataTypeIntValue(),
2370:                                image.getImageFormatTypeIntValue(false),
2371:                                image.imageData.get(), depthType, depthComp);
2372:
2373:                        canvas3d.drawingSurfaceObject.unLock();
2374:                    }
2375:                } catch (NullPointerException ne) {
2376:                    canvas3d.drawingSurfaceObject.unLock();
2377:                    throw ne;
2378:                }
2379:
2380:                if ((ras.type & Raster.RASTER_DEPTH) != 0) {
2381:                    if (ras.depthComponent.type == DepthComponentRetained.DEPTH_COMPONENT_TYPE_FLOAT)
2382:                        ((DepthComponentFloatRetained) ras.depthComponent)
2383:                                .retrieveDepth(floatBuffer, rasterSize.width,
2384:                                        rasterSize.height);
2385:                    else if (ras.depthComponent.type == DepthComponentRetained.DEPTH_COMPONENT_TYPE_INT)
2386:                        ((DepthComponentIntRetained) ras.depthComponent)
2387:                                .retrieveDepth(intBuffer, rasterSize.width,
2388:                                        rasterSize.height);
2389:                    else if (ras.depthComponent.type == DepthComponentRetained.DEPTH_COMPONENT_TYPE_NATIVE)
2390:                        ((DepthComponentNativeRetained) ras.depthComponent)
2391:                                .retrieveDepth(intBuffer, rasterSize.width,
2392:                                        rasterSize.height);
2393:                }
2394:                readRasterReady = true;
2395:            }
2396:
2397:            /**
2398:             * Flushes all previously executed rendering operations to the
2399:             * drawing buffer for this 3D graphics context.
2400:             *
2401:             * @param wait flag indicating whether or not to wait for the
2402:             * rendering to be complete before returning from this call.
2403:             *
2404:             * @since Java 3D 1.2
2405:             */
2406:            public void flush(boolean wait) {
2407:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)
2408:                        || (!canvas3d.view.active)
2409:                        || (Thread.currentThread() == canvas3d.screen.renderer)) {
2410:                    doFlush(wait);
2411:                } else {
2412:                    Boolean waitArg = (wait ? Boolean.TRUE : Boolean.FALSE);
2413:
2414:                    if (Thread.currentThread() == canvas3d.view.universe.behaviorScheduler) {
2415:                        sendRenderMessage(false, GraphicsContext3D.FLUSH,
2416:                                waitArg, null);
2417:                    } else {
2418:                        sendRenderMessage(true, GraphicsContext3D.FLUSH,
2419:                                waitArg, null);
2420:                    }
2421:                    // Issue 131: AutomaticOffscreen canvases must be treated as onscreen ones.
2422:                    if (wait && canvas3d.active && canvas3d.isRunningStatus
2423:                            && !canvas3d.manualRendering) {
2424:                        // No need to wait if renderer thread is not schedule
2425:                        runMonitor(J3dThread.WAIT);
2426:                    }
2427:                }
2428:            }
2429:
2430:            void doFlush(boolean wait) {
2431:                try {
2432:                    if (canvas3d.drawingSurfaceObject.renderLock()) {
2433:                        canvas3d.syncRender(canvas3d.ctx, wait);
2434:                        canvas3d.drawingSurfaceObject.unLock();
2435:                        if (wait) {
2436:                            runMonitor(J3dThread.NOTIFY);
2437:                        }
2438:                    }
2439:                } catch (NullPointerException ne) {
2440:                    canvas3d.drawingSurfaceObject.unLock();
2441:                    throw ne;
2442:                }
2443:            }
2444:
2445:            void updateLightAndFog() {
2446:                int enableMask = 0;
2447:                int i;
2448:                sceneAmbient.x = 0.0f;
2449:                sceneAmbient.y = 0.0f;
2450:                sceneAmbient.z = 0.0f;
2451:
2452:                int n = 0;
2453:                int nLight = lights.size();
2454:                ;
2455:                for (i = 0; i < nLight; i++) {
2456:                    LightRetained lt = (LightRetained) ((Light) lights.get(i)).retained;
2457:                    if (lt instanceof  AmbientLightRetained) {
2458:                        sceneAmbient.x += lt.color.x;
2459:                        sceneAmbient.y += lt.color.y;
2460:                        sceneAmbient.z += lt.color.z;
2461:                        continue;
2462:                    }
2463:
2464:                    lt.update(canvas3d.ctx, n, canvas3d.canvasViewCache
2465:                            .getVworldToCoexistenceScale());
2466:                    if (lt.lightOn)
2467:                        enableMask |= (1 << n);
2468:                    n++;
2469:                }
2470:                if (sceneAmbient.x > 1.0f) {
2471:                    sceneAmbient.x = 1.0f;
2472:                }
2473:                if (sceneAmbient.y > 1.0f) {
2474:                    sceneAmbient.y = 1.0f;
2475:                }
2476:                if (sceneAmbient.z > 1.0f) {
2477:                    sceneAmbient.z = 1.0f;
2478:                }
2479:
2480:                canvas3d.setSceneAmbient(canvas3d.ctx, sceneAmbient.x,
2481:                        sceneAmbient.y, sceneAmbient.z);
2482:
2483:                canvas3d.canvasDirty |= Canvas3D.AMBIENTLIGHT_DIRTY;
2484:                canvas3d.sceneAmbient.set(sceneAmbient);
2485:
2486:                if (canvas3d.enableMask != enableMask) {
2487:                    canvas3d.canvasDirty |= Canvas3D.LIGHTENABLES_DIRTY;
2488:                    // XXXX: 32 => renderBin.maxLights
2489:                    canvas3d.setLightEnables(canvas3d.ctx, enableMask, 32);
2490:                    canvas3d.enableMask = enableMask;
2491:                }
2492:
2493:                // Force LightBin.updateAttributes and EnvironmentSet.updateAttributes 
2494:                // to use the within frame case.
2495:                canvas3d.lightBin = null;
2496:                canvas3d.environmentSet = null;
2497:
2498:                if (fog != null) {
2499:                    if (fog.retained != canvas3d.fog) {
2500:                        ((FogRetained) fog.retained).update(canvas3d.ctx,
2501:                                canvas3d.canvasViewCache
2502:                                        .getVworldToCoexistenceScale());
2503:                        canvas3d.fog = (FogRetained) fog.retained;
2504:                        canvas3d.canvasDirty |= Canvas3D.FOG_DIRTY;
2505:                    }
2506:                } else { // Turn off fog
2507:                    if (canvas3d.fog != null) {
2508:                        canvas3d.setFogEnableFlag(canvas3d.ctx, false);
2509:                        canvas3d.fog = null;
2510:                        canvas3d.canvasDirty |= Canvas3D.FOG_DIRTY;
2511:                    }
2512:                }
2513:            }
2514:
2515:            void updateModelClip(Transform3D vworldToVpc) {
2516:                if (modelClip != null) {
2517:                    int enableMask = 0;
2518:                    for (int i = 0; i < 6; i++) {
2519:                        if (((ModelClipRetained) modelClip.retained).enables[i])
2520:                            enableMask |= 1 << i;
2521:                    }
2522:                    // planes are already transformed to eye coordinates
2523:                    // in immediate mode
2524:                    if (enableMask != 0) {
2525:                        this .drawTransform.mul(vworldToVpc,
2526:                                this .modelClipTransform);
2527:                        canvas3d.setModelViewMatrix(canvas3d.ctx, vpcToEc.mat,
2528:                                this .drawTransform);
2529:                    }
2530:                    ((ModelClipRetained) modelClip.retained).update(
2531:                            canvas3d.ctx, enableMask, this .drawTransform);
2532:                    canvas3d.canvasDirty |= Canvas3D.MODELCLIP_DIRTY;
2533:                    canvas3d.modelClip = (ModelClipRetained) modelClip.retained;
2534:                } else {
2535:                    if (canvas3d.modelClip != null) {
2536:                        canvas3d.disableModelClip(canvas3d.ctx);
2537:                        canvas3d.modelClip = null;
2538:                        canvas3d.canvasDirty |= Canvas3D.MODELCLIP_DIRTY;
2539:                    }
2540:                }
2541:
2542:                // Force EnvironmentSet.updateAttributes to  use the within frame case.
2543:                canvas3d.environmentSet = null;
2544:
2545:            }
2546:
2547:            boolean updateState(RenderBin rb, int geometryType) {
2548:
2549:                boolean useAlpha = false;
2550:                numActiveTexUnit = 0;
2551:                lastActiveTexUnitIndex = 0;
2552:
2553:                // Update Appearance
2554:                if (appearance != null) {
2555:                    AppearanceRetained app = (AppearanceRetained) appearance.retained;
2556:
2557:                    // If the material is not null then check if the one in the canvas
2558:                    // is equivalent to the one being sent down. If Yes, do nothing
2559:                    // Otherwise, cache the sent down material and mark the canvas
2560:                    // dirty flag so that the compiled/compiled-retained rendering
2561:                    // catches the change
2562:                    // if material != null, we will need to load the material
2563:                    // parameter again, because the apps could have changed
2564:                    // the material parameter
2565:
2566:                    if (app.material != null) {
2567:                        app.material.updateNative(canvas3d.ctx, red, green,
2568:                                blue, alpha, enableLighting);
2569:                        canvas3d.material = app.material;
2570:                        canvas3d.canvasDirty |= Canvas3D.MATERIAL_DIRTY;
2571:                    } else {
2572:                        if (canvas3d.material != null) {
2573:                            canvas3d.updateMaterial(canvas3d.ctx, red, green,
2574:                                    blue, alpha);
2575:                            canvas3d.material = null;
2576:                            canvas3d.canvasDirty |= Canvas3D.MATERIAL_DIRTY;
2577:                        }
2578:                    }
2579:
2580:                    // Set flag indicating whether we are using shaders
2581:                    boolean useShaders = false;
2582:                    if (app instanceof  ShaderAppearanceRetained) {
2583:                        ShaderProgramRetained spR = ((ShaderAppearanceRetained) app).shaderProgram;
2584:                        if (spR != null) {
2585:                            spR.updateNative(canvas3d, true);
2586:
2587:                            ShaderAttributeSetRetained sasR = ((ShaderAppearanceRetained) app).shaderAttributeSet;
2588:
2589:                            if (sasR != null) {
2590:                                sasR.updateNative(canvas3d, spR);
2591:                            }
2592:
2593:                            canvas3d.shaderProgram = spR;
2594:                            useShaders = true;
2595:                        }
2596:                    } else if (canvas3d.shaderProgram != null) {
2597:                        canvas3d.shaderProgram.updateNative(canvas3d, false);
2598:                        canvas3d.shaderProgram = null;
2599:                        useShaders = false;
2600:                    }
2601:
2602:                    // Set the number of available texture units; this depends on
2603:                    // whether or not shaders are being used.
2604:                    int availableTextureUnits = useShaders ? canvas3d.maxTextureImageUnits
2605:                            : canvas3d.maxTextureUnits;
2606:
2607:                    int prevNumActiveTexUnit = canvas3d.getNumActiveTexUnit();
2608:
2609:                    // Get the number of active texture units.
2610:                    // Note that this total number now includes disabled units.
2611:                    if (app.texUnitState != null) {
2612:                        TextureUnitStateRetained tus;
2613:
2614:                        for (int i = 0; i < app.texUnitState.length; i++) {
2615:                            tus = app.texUnitState[i];
2616:                            if (tus != null && tus.isTextureEnabled()) {
2617:                                lastActiveTexUnitIndex = i;
2618:                                numActiveTexUnit = i + 1;
2619:                                if (tus.texAttrs != null) {
2620:                                    useAlpha = useAlpha
2621:                                            || (tus.texAttrs.textureMode == TextureAttributes.BLEND);
2622:                                }
2623:                            }
2624:                        }
2625:
2626:                        if (numActiveTexUnit <= availableTextureUnits) {
2627:                            // Normal, single-pass rendering case
2628:
2629:                            // update all active texture unit states
2630:                            for (int i = 0; i < app.texUnitState.length; i++) {
2631:                                if (i >= availableTextureUnits) {
2632:                                    // This can happen if there are disabled units at
2633:                                    // the end of the array
2634:                                    break;
2635:                                }
2636:
2637:                                if ((app.texUnitState[i] != null)
2638:                                        && app.texUnitState[i]
2639:                                                .isTextureEnabled()) {
2640:                                    app.texUnitState[i].updateNative(i,
2641:                                            canvas3d, false, false);
2642:                                } else {
2643:                                    canvas3d.resetTexture(canvas3d.ctx, i);
2644:                                }
2645:                            }
2646:
2647:                            // reset the remaining texture units
2648:                            for (int i = app.texUnitState.length; i < prevNumActiveTexUnit; i++) {
2649:                                canvas3d.resetTexture(canvas3d.ctx, i);
2650:                            }
2651:
2652:                            // set the number active texture unit in Canvas3D
2653:                            canvas3d.setNumActiveTexUnit(numActiveTexUnit);
2654:
2655:                        } else {
2656:                            // Exceeded limit, disable all the texture units
2657:                            for (int i = 0; i < prevNumActiveTexUnit; i++) {
2658:                                canvas3d.resetTexture(canvas3d.ctx, i);
2659:                            }
2660:                            canvas3d.setNumActiveTexUnit(0);
2661:                        }
2662:
2663:                        // set the active texture unit back to 0
2664:                        canvas3d.activeTextureUnit(canvas3d.ctx, 0);
2665:                    } else {
2666:                        // if texUnitState is null, let's disable
2667:                        // all texture units first
2668:                        if (canvas3d.multiTexAccelerated) {
2669:                            if (canvas3d.texUnitState != null) {
2670:                                for (int i = 0; i < prevNumActiveTexUnit; i++) {
2671:                                    TextureUnitStateRetained tur = canvas3d.texUnitState[i];
2672:                                    if ((tur != null) && (tur.texture != null)) {
2673:                                        canvas3d.resetTexture(canvas3d.ctx, i);
2674:                                        canvas3d.texUnitState[i].texture = null;
2675:                                    }
2676:                                }
2677:                            }
2678:
2679:                            // set the active texture unit back to 0
2680:                            canvas3d.activeTextureUnit(canvas3d.ctx, 0);
2681:                        }
2682:
2683:                        if ((canvas3d.texUnitState != null)
2684:                                && (canvas3d.texUnitState[0] != null)
2685:                                && (canvas3d.texUnitState[0].texture != app.texture)) {
2686:
2687:                            // If the image is by reference, check if the image
2688:                            // should be processed
2689:                            if (app.texture != null) {
2690:                                app.texture.updateNative(canvas3d);
2691:                                canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY
2692:                                        | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2693:                                numActiveTexUnit = 1;
2694:                                lastActiveTexUnitIndex = 0;
2695:                            } else {
2696:                                numActiveTexUnit = 0;
2697:                                canvas3d.resetTexture(canvas3d.ctx, -1);
2698:                                canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY
2699:                                        | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2700:                            }
2701:
2702:                            canvas3d.texUnitState[0].texture = app.texture;
2703:                        }
2704:
2705:                        // set the number active texture unit in Canvas3D
2706:                        canvas3d.setNumActiveTexUnit(numActiveTexUnit);
2707:
2708:                        if (app.texCoordGeneration != null) {
2709:                            app.texCoordGeneration.updateNative(canvas3d);
2710:                            canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY
2711:                                    | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2712:                            if ((canvas3d.texUnitState != null)
2713:                                    && (canvas3d.texUnitState[0] != null)) {
2714:                                canvas3d.texUnitState[0].texGen = app.texCoordGeneration;
2715:                            }
2716:                        } else {
2717:                            // If the canvas does not alreadt have a null texCoordGeneration
2718:                            // load the default
2719:                            if ((canvas3d.texUnitState != null)
2720:                                    && (canvas3d.texUnitState[0] != null)
2721:                                    && (canvas3d.texUnitState[0].texGen != null)) {
2722:                                canvas3d.resetTexCoordGeneration(canvas3d.ctx);
2723:                                canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY
2724:                                        | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2725:                                canvas3d.texUnitState[0].texGen = app.texCoordGeneration;
2726:                            }
2727:                        }
2728:
2729:                        if (app.textureAttributes != null) {
2730:                            if ((canvas3d.texUnitState != null)
2731:                                    && (canvas3d.texUnitState[0] != null)) {
2732:
2733:                                if (canvas3d.texUnitState[0].texture != null) {
2734:                                    app.textureAttributes
2735:                                            .updateNative(
2736:                                                    canvas3d,
2737:                                                    false,
2738:                                                    canvas3d.texUnitState[0].texture.format);
2739:                                } else {
2740:                                    app.textureAttributes.updateNative(
2741:                                            canvas3d, false, Texture.RGBA);
2742:                                }
2743:                                canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY
2744:                                        | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2745:                                canvas3d.texUnitState[0].texAttrs = app.textureAttributes;
2746:                            }
2747:                        } else {
2748:                            // If the canvas does not already have a null texAttribute
2749:                            // load the default if necessary
2750:                            if ((canvas3d.texUnitState != null)
2751:                                    && (canvas3d.texUnitState[0] != null)
2752:                                    && (canvas3d.texUnitState[0].texAttrs != null)) {
2753:                                canvas3d.resetTextureAttributes(canvas3d.ctx);
2754:                                canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY
2755:                                        | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2756:                                canvas3d.texUnitState[0].texAttrs = null;
2757:                            }
2758:                        }
2759:                    }
2760:
2761:                    if (app.coloringAttributes != null) {
2762:                        app.coloringAttributes.updateNative(canvas3d.ctx, dRed,
2763:                                dBlue, dGreen, alpha, enableLighting);
2764:                        canvas3d.canvasDirty |= Canvas3D.COLORINGATTRS_DIRTY;
2765:                        canvas3d.coloringAttributes = app.coloringAttributes;
2766:                    } else {
2767:                        if (canvas3d.coloringAttributes != null) {
2768:                            canvas3d.resetColoringAttributes(canvas3d.ctx, red,
2769:                                    green, blue, alpha, enableLighting);
2770:                            canvas3d.canvasDirty |= Canvas3D.COLORINGATTRS_DIRTY;
2771:                            canvas3d.coloringAttributes = null;
2772:                        }
2773:                    }
2774:
2775:                    if (app.transparencyAttributes != null) {
2776:                        app.transparencyAttributes.updateNative(canvas3d.ctx,
2777:                                alpha, geometryType, polygonMode, lineAA,
2778:                                pointAA);
2779:                        canvas3d.canvasDirty |= Canvas3D.TRANSPARENCYATTRS_DIRTY;
2780:                        canvas3d.transparency = app.transparencyAttributes;
2781:
2782:                        useAlpha = useAlpha
2783:                                || ((app.transparencyAttributes.transparencyMode != TransparencyAttributes.NONE) && (VirtualUniverse.mc
2784:                                        .isD3D() || (!VirtualUniverse.mc
2785:                                        .isD3D() && (app.transparencyAttributes.transparencyMode != TransparencyAttributes.SCREEN_DOOR))));
2786:                    } else {
2787:                        canvas3d.resetTransparency(canvas3d.ctx, geometryType,
2788:                                polygonMode, lineAA, pointAA);
2789:                        canvas3d.canvasDirty |= Canvas3D.TRANSPARENCYATTRS_DIRTY;
2790:                        canvas3d.transparency = null;
2791:                    }
2792:
2793:                    if (app.renderingAttributes != null) {
2794:                        ignoreVertexColors = app.renderingAttributes.ignoreVertexColors;
2795:                        app.renderingAttributes.updateNative(canvas3d,
2796:                                canvas3d.depthBufferWriteEnableOverride,
2797:                                canvas3d.depthBufferEnableOverride);
2798:                        canvas3d.canvasDirty |= Canvas3D.ATTRIBUTEBIN_DIRTY
2799:                                | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2800:                        canvas3d.renderingAttrs = app.renderingAttributes;
2801:
2802:                        useAlpha = useAlpha
2803:                                || (app.renderingAttributes.alphaTestFunction != RenderingAttributes.ALWAYS);
2804:                    } else {
2805:                        // If the canvas does not alreadt have a null renderingAttrs
2806:                        // load the default
2807:                        ignoreVertexColors = false;
2808:                        if (canvas3d.renderingAttrs != null) {
2809:                            canvas3d.resetRenderingAttributes(canvas3d.ctx,
2810:                                    canvas3d.depthBufferWriteEnableOverride,
2811:                                    canvas3d.depthBufferEnableOverride);
2812:                            canvas3d.canvasDirty |= Canvas3D.ATTRIBUTEBIN_DIRTY
2813:                                    | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2814:                            canvas3d.renderingAttrs = null;
2815:                        }
2816:                    }
2817:
2818:                    if (app.polygonAttributes != null) {
2819:                        app.polygonAttributes.updateNative(canvas3d.ctx);
2820:                        canvas3d.canvasDirty |= Canvas3D.POLYGONATTRS_DIRTY;
2821:                        canvas3d.polygonAttributes = app.polygonAttributes;
2822:                    } else {
2823:                        // If the canvas does not alreadt have a null polygonAttr
2824:                        // load the default
2825:                        if (canvas3d.polygonAttributes != null) {
2826:                            canvas3d.resetPolygonAttributes(canvas3d.ctx);
2827:                            canvas3d.canvasDirty |= Canvas3D.POLYGONATTRS_DIRTY;
2828:                            canvas3d.polygonAttributes = null;
2829:                        }
2830:                    }
2831:
2832:                    if (app.lineAttributes != null) {
2833:                        app.lineAttributes.updateNative(canvas3d.ctx);
2834:                        canvas3d.canvasDirty |= Canvas3D.LINEATTRS_DIRTY;
2835:                        canvas3d.lineAttributes = app.lineAttributes;
2836:                    } else {
2837:                        // If the canvas does not already have a null lineAttr
2838:                        // load the default
2839:                        if (canvas3d.lineAttributes != null) {
2840:                            canvas3d.resetLineAttributes(canvas3d.ctx);
2841:                            canvas3d.canvasDirty |= Canvas3D.LINEATTRS_DIRTY;
2842:                            canvas3d.lineAttributes = null;
2843:                        }
2844:                    }
2845:
2846:                    if (app.pointAttributes != null) {
2847:                        app.pointAttributes.updateNative(canvas3d.ctx);
2848:                        canvas3d.canvasDirty |= Canvas3D.POINTATTRS_DIRTY;
2849:                        canvas3d.pointAttributes = app.pointAttributes;
2850:                    } else {
2851:                        // If the canvas does not already have a null pointAttr
2852:                        // load the default
2853:                        if (canvas3d.pointAttributes != null) {
2854:                            canvas3d.resetPointAttributes(canvas3d.ctx);
2855:                            canvas3d.canvasDirty |= Canvas3D.POINTATTRS_DIRTY;
2856:                            canvas3d.pointAttributes = null;
2857:                        }
2858:                    }
2859:
2860:                    canvas3d.appearance = app;
2861:
2862:                } else {
2863:                    if (canvas3d.appearance != null) {
2864:                        resetAppearance();
2865:                        canvas3d.appearance = null;
2866:                    }
2867:                }
2868:
2869:                return (useAlpha);
2870:            }
2871:
2872:            void initializeState() {
2873:
2874:                canvas3d.setSceneAmbient(canvas3d.ctx, 0.0f, 0.0f, 0.0f);
2875:                canvas3d.disableFog(canvas3d.ctx);
2876:                canvas3d.resetRenderingAttributes(canvas3d.ctx, false, false);
2877:
2878:                if (canvas3d.shaderProgram != null) {
2879:                    canvas3d.shaderProgram.updateNative(canvas3d, false);
2880:                    canvas3d.shaderProgram = null;
2881:                }
2882:
2883:                // reset the previously enabled texture units
2884:
2885:                int prevNumActiveTexUnit = canvas3d.getNumActiveTexUnit();
2886:
2887:                if (prevNumActiveTexUnit > 0) {
2888:                    for (int i = 0; i < prevNumActiveTexUnit; i++) {
2889:                        if (canvas3d.texUnitState[i].texture != null) {
2890:                            canvas3d.resetTexture(canvas3d.ctx, i);
2891:                            canvas3d.texUnitState[i].texture = null;
2892:                        }
2893:                        if (canvas3d.texUnitState[i].texAttrs != null) {
2894:                            canvas3d.resetTextureAttributes(canvas3d.ctx);
2895:                            canvas3d.texUnitState[i].texAttrs = null;
2896:                        }
2897:                        if (canvas3d.texUnitState[i].texGen != null) {
2898:                            canvas3d.resetTexCoordGeneration(canvas3d.ctx);
2899:                            canvas3d.texUnitState[i].texGen = null;
2900:                        }
2901:                        canvas3d.texUnitState[i].mirror = null;
2902:                    }
2903:                    canvas3d.setNumActiveTexUnit(0);
2904:                }
2905:
2906:                canvas3d.resetPolygonAttributes(canvas3d.ctx);
2907:                canvas3d.resetLineAttributes(canvas3d.ctx);
2908:                canvas3d.resetPointAttributes(canvas3d.ctx);
2909:                canvas3d.resetTransparency(canvas3d.ctx,
2910:                        RenderMolecule.SURFACE, PolygonAttributes.POLYGON_FILL,
2911:                        false, false);
2912:                canvas3d.resetColoringAttributes(canvas3d.ctx, 1.0f, 1.0f,
2913:                        1.0f, 1.0f, false);
2914:                canvas3d.updateMaterial(canvas3d.ctx, 1.0f, 1.0f, 1.0f, 1.0f);
2915:            }
2916:
2917:            void resetAppearance() {
2918:                //System.err.println("GC3D.resetAppearance ....");
2919:
2920:                if (canvas3d.material != null) {
2921:                    canvas3d.updateMaterial(canvas3d.ctx, red, green, blue,
2922:                            alpha);
2923:                    canvas3d.material = null;
2924:                    canvas3d.canvasDirty |= Canvas3D.MATERIAL_DIRTY;
2925:                }
2926:
2927:                if (canvas3d.shaderProgram != null) {
2928:                    canvas3d.shaderProgram.updateNative(canvas3d, false);
2929:                    canvas3d.shaderProgram = null;
2930:                    // ShaderBin doesn't use dirty bit.
2931:                }
2932:
2933:                // reset the previously enabled texture units
2934:                int prevNumActiveTexUnit = canvas3d.getNumActiveTexUnit();
2935:
2936:                if (prevNumActiveTexUnit > 0) {
2937:                    for (int i = 0; i < prevNumActiveTexUnit; i++) {
2938:                        if (canvas3d.texUnitState[i].texture != null) {
2939:                            canvas3d.resetTexture(canvas3d.ctx, i);
2940:                            canvas3d.texUnitState[i].texture = null;
2941:                        }
2942:                        if (canvas3d.texUnitState[i].texAttrs != null) {
2943:                            canvas3d.resetTextureAttributes(canvas3d.ctx);
2944:                            canvas3d.texUnitState[i].texAttrs = null;
2945:                        }
2946:                        if (canvas3d.texUnitState[i].texGen != null) {
2947:                            canvas3d.resetTexCoordGeneration(canvas3d.ctx);
2948:                            canvas3d.texUnitState[i].texGen = null;
2949:                        }
2950:                        canvas3d.texUnitState[i].mirror = null;
2951:                    }
2952:                    canvas3d.canvasDirty |= Canvas3D.TEXTUREBIN_DIRTY
2953:                            | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2954:                    canvas3d.setNumActiveTexUnit(0);
2955:                }
2956:
2957:                if (canvas3d.coloringAttributes != null) {
2958:                    canvas3d.resetColoringAttributes(canvas3d.ctx, red, green,
2959:                            blue, alpha, enableLighting);
2960:                    canvas3d.coloringAttributes = null;
2961:                    canvas3d.canvasDirty |= Canvas3D.COLORINGATTRS_DIRTY;
2962:                }
2963:
2964:                if (canvas3d.transparency != null) {
2965:                    canvas3d.resetTransparency(canvas3d.ctx,
2966:                            RenderMolecule.SURFACE,
2967:                            PolygonAttributes.POLYGON_FILL, lineAA, pointAA);
2968:                    canvas3d.transparency = null;
2969:                    canvas3d.canvasDirty |= Canvas3D.TRANSPARENCYATTRS_DIRTY;
2970:                }
2971:
2972:                if (canvas3d.renderingAttrs != null) {
2973:                    ignoreVertexColors = false;
2974:                    canvas3d.resetRenderingAttributes(canvas3d.ctx,
2975:                            canvas3d.depthBufferWriteEnableOverride,
2976:                            canvas3d.depthBufferEnableOverride);
2977:                    canvas3d.renderingAttrs = null;
2978:                    canvas3d.canvasDirty |= Canvas3D.ATTRIBUTEBIN_DIRTY
2979:                            | Canvas3D.TEXTUREATTRIBUTES_DIRTY;
2980:                }
2981:
2982:                if (canvas3d.polygonAttributes != null) {
2983:                    canvas3d.resetPolygonAttributes(canvas3d.ctx);
2984:                    canvas3d.polygonAttributes = null;
2985:                    canvas3d.canvasDirty |= Canvas3D.POLYGONATTRS_DIRTY;
2986:                }
2987:
2988:                if (canvas3d.lineAttributes != null) {
2989:                    canvas3d.resetLineAttributes(canvas3d.ctx);
2990:                    canvas3d.lineAttributes = null;
2991:                    canvas3d.canvasDirty |= Canvas3D.LINEATTRS_DIRTY;
2992:                }
2993:
2994:                if (canvas3d.pointAttributes != null) {
2995:                    canvas3d.resetPointAttributes(canvas3d.ctx);
2996:                    canvas3d.pointAttributes = null;
2997:                    canvas3d.canvasDirty |= Canvas3D.POINTATTRS_DIRTY;
2998:                }
2999:            }
3000:
3001:            void sendRenderMessage(boolean renderRun, int command, Object arg1,
3002:                    Object arg2) {
3003:
3004:                // send a message to the request renderer
3005:
3006:                J3dMessage renderMessage = new J3dMessage();
3007:                renderMessage.threads = J3dThread.RENDER_THREAD;
3008:                renderMessage.type = J3dMessage.RENDER_IMMEDIATE;
3009:                renderMessage.universe = null;
3010:                renderMessage.view = null;
3011:                renderMessage.args[0] = canvas3d;
3012:                renderMessage.args[1] = getImmCommand(command);
3013:                renderMessage.args[2] = arg1;
3014:                renderMessage.args[3] = arg2;
3015:
3016:                while (!canvas3d.view.inRenderThreadData) {
3017:                    // wait until the renderer thread data in added in
3018:                    // MC:RenderThreadData array ready to receive message
3019:                    MasterControl.threadYield();
3020:                }
3021:
3022:                canvas3d.screen.renderer.rendererStructure
3023:                        .addMessage(renderMessage);
3024:
3025:                if (renderRun) {
3026:                    // notify mc that there is work to do
3027:                    VirtualUniverse.mc.sendRunMessage(canvas3d.view,
3028:                            J3dThread.RENDER_THREAD);
3029:                } else {
3030:                    // notify mc that there is work for the request renderer
3031:                    VirtualUniverse.mc.setWorkForRequestRenderer();
3032:                }
3033:            }
3034:
3035:            void sendSoundMessage(int command, Object arg1, Object arg2) {
3036:                if ((canvas3d.view == null) || (canvas3d.view.universe == null)) {
3037:                    return;
3038:                }
3039:                // send a message to the request sound scheduling
3040:                J3dMessage soundMessage = new J3dMessage();
3041:                soundMessage.threads = J3dThread.SOUND_SCHEDULER;
3042:                soundMessage.type = J3dMessage.RENDER_IMMEDIATE;
3043:                soundMessage.universe = canvas3d.view.universe;
3044:                soundMessage.view = canvas3d.view;
3045:                soundMessage.args[0] = getImmCommand(command);
3046:                soundMessage.args[1] = arg1;
3047:                soundMessage.args[2] = arg2;
3048:                // notify mc that there is work to do
3049:                VirtualUniverse.mc.processMessage(soundMessage);
3050:            }
3051:
3052:            static Integer getImmCommand(int command) {
3053:                if (commands[command] == null) {
3054:                    commands[command] = new Integer(command);
3055:                }
3056:                return commands[command];
3057:            }
3058:
3059:            synchronized void runMonitor(int action) {
3060:                if (action == J3dThread.WAIT) {
3061:                    while (!gcReady) {
3062:                        waiting++;
3063:                        try {
3064:                            wait();
3065:                        } catch (InterruptedException e) {
3066:                        }
3067:                        waiting--;
3068:                    }
3069:                    gcReady = false;
3070:                } else {
3071:                    gcReady = true;
3072:                    if (waiting > 0) {
3073:                        notify();
3074:                    }
3075:                }
3076:            }
3077:
3078:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.