Source Code Cross Referenced for TextureBin.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: TextureBin.java,v $
0003:         *
0004:         * Copyright 1999-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.10 $
0028:         * $Date: 2008/02/28 20:17:31 $
0029:         * $State: Exp $
0030:         */
0031:
0032:        package javax.media.j3d;
0033:
0034:        import javax.vecmath.*;
0035:        import java.util.*;
0036:
0037:        /**
0038:         * The TextureBin manages a collection of TextureSetting objects.
0039:         * All objects in the TextureBin share the same Texture reference.
0040:         */
0041:
0042:        //class TextureBin extends Object implements ObjectUpdate, NodeComponentUpdate {
0043:        class TextureBin extends Object implements  ObjectUpdate {
0044:
0045:            TextureUnitStateRetained[] texUnitState = null;
0046:
0047:            // last active texture unit
0048:            private int lastActiveTexUnitIndex;
0049:
0050:            // number of active texture unit
0051:            private int numActiveTexUnit;
0052:
0053:            /**
0054:             * The RenderBin for this object
0055:             */
0056:            RenderBin renderBin = null;
0057:
0058:            /**
0059:             * The EnvironmentSet that this TextureBin resides
0060:             */
0061:            EnvironmentSet environmentSet = null;
0062:
0063:            /**
0064:             * The AttributeBin that this TextureBin resides
0065:             */
0066:            AttributeBin attributeBin = null;
0067:
0068:            /**
0069:             * The ShaderBin that this TextureBin resides
0070:             */
0071:            ShaderBin shaderBin = null;
0072:
0073:            /**
0074:             * The references to the next and previous TextureBins in the
0075:             * list.
0076:             */
0077:            TextureBin next = null;
0078:            TextureBin prev = null;
0079:
0080:            /**
0081:             * Oring of the equivalence bits for all appearance attrs under
0082:             * this renderBin
0083:             */
0084:            int equivalent = 0;
0085:
0086:            /**
0087:             * If any of the texture reference in an appearance is frequently
0088:             * changable, then a separate TextureBin will be created for this
0089:             * appearance, and this TextureBin is marked as the sole user of
0090:             * this appearance, and app will be pointing to the appearance
0091:             * being referenced by this TextureBin. Otherwise, app is null
0092:             */
0093:            AppearanceRetained app = null;
0094:
0095:            /**
0096:             * Sole user node component dirty mask.  The first bit is reserved
0097:             * for node component reference dirty bit. It is set if any of the
0098:             * texture related node component reference in the appearance is
0099:             * being modified. The second bit onwords are for the individual
0100:             * TextureUnitState dirty bit. The ith bit set means the (i-1)
0101:             * texture unit state is modified. Note, this mask only supports
0102:             * 30 texture unit states. If the appearance uses more than 31
0103:             * texture unit states, then the modification of the 32nd texture 
0104:             * unit state and up will have the first bit set, that means
0105:             * the TextureBin will be reset, rather than only the particular
0106:             * texture unit state will be reset. 
0107:             */
0108:            int soleUserCompDirty;
0109:
0110:            static final int SOLE_USER_DIRTY_REF = 0x1;
0111:            static final int SOLE_USER_DIRTY_TA = 0x2;
0112:            static final int SOLE_USER_DIRTY_TC = 0x4;
0113:            static final int SOLE_USER_DIRTY_TEXTURE = 0x8;
0114:            static final int SOLE_USER_DIRTY_TUS = 0x10;
0115:
0116:            /**
0117:             * The hashMap of RenderMolecules in this TextureBin
0118:             * this is used in rendering, the key used is localToVworld
0119:             */
0120:            HashMap addOpaqueRMs = new HashMap();
0121:            HashMap addTransparentRMs = new HashMap();
0122:
0123:            // A hashmap based on localToVworld for fast
0124:            // insertion of new renderMolecules
0125:            HashMap opaqueRenderMoleculeMap = new HashMap();
0126:            HashMap transparentRenderMoleculeMap = new HashMap();
0127:
0128:            // List of renderMolecules  - used in rendering ..
0129:            RenderMolecule opaqueRMList = null;
0130:
0131:            RenderMolecule transparentRMList = null;
0132:            TransparentRenderingInfo parentTInfo;
0133:
0134:            int numRenderMolecules = 0;
0135:            int numEditingRenderMolecules = 0;
0136:
0137:            int tbFlag = 0; // a general bitmask for TextureBin
0138:
0139:            // Following are the bits used in flag
0140:
0141:            final static int ON_RENDER_BIN_LIST = 0x0001;
0142:            final static int ON_UPDATE_LIST = 0x0002;
0143:            final static int SOLE_USER = 0x0004;
0144:            final static int CONTIGUOUS_ACTIVE_UNITS = 0x0008;
0145:            final static int RESORT = 0x0010;
0146:            final static int ON_UPDATE_CHECK_LIST = 0x0020;
0147:
0148:            final static int USE_DISPLAYLIST = -2;
0149:            final static int USE_VERTEXARRAY = -1;
0150:
0151:            TextureBin(TextureUnitStateRetained[] state,
0152:                    AppearanceRetained app, RenderBin rb) {
0153:                renderBin = rb;
0154:                tbFlag = 0;
0155:                reset(state, app);
0156:            }
0157:
0158:            /**
0159:             * For now, clone everything just like the other NodeComponent
0160:             */
0161:            void reset(TextureUnitStateRetained[] state, AppearanceRetained app) {
0162:
0163:                prev = null;
0164:                next = null;
0165:                opaqueRMList = null;
0166:                transparentRMList = null;
0167:                numEditingRenderMolecules = 0;
0168:
0169:                // Issue 249 - check for sole user only if property is set
0170:                // determine if this appearance is a sole user of this
0171:                // TextureBin
0172:                tbFlag &= ~TextureBin.SOLE_USER;
0173:                if (VirtualUniverse.mc.allowSoleUser) {
0174:                    if ((app != null)
0175:                            && (app.changedFrequent & (AppearanceRetained.TEXTURE
0176:                                    | AppearanceRetained.TEXCOORD_GEN
0177:                                    | AppearanceRetained.TEXTURE_ATTR | AppearanceRetained.TEXTURE_UNIT_STATE)) != 0) {
0178:                        tbFlag |= TextureBin.SOLE_USER;
0179:
0180:                    }
0181:                }
0182:
0183:                if ((tbFlag & TextureBin.SOLE_USER) != 0) {
0184:                    this .app = app;
0185:                } else {
0186:                    this .app = null;
0187:                }
0188:
0189:                resetTextureState(state);
0190:
0191:                if ((tbFlag & TextureBin.ON_RENDER_BIN_LIST) == 0) {
0192:                    renderBin.addTextureBin(this );
0193:                    tbFlag |= TextureBin.ON_RENDER_BIN_LIST;
0194:                }
0195:
0196:            }
0197:
0198:            void resetTextureState(TextureUnitStateRetained[] state) {
0199:
0200:                int i, j;
0201:                boolean foundDisableUnit = false;
0202:                numActiveTexUnit = 0;
0203:                lastActiveTexUnitIndex = 0;
0204:                boolean soleUser = ((tbFlag & TextureBin.SOLE_USER) != 0);
0205:                TextureRetained prevFirstTexture = null;
0206:                TextureRetained tex;
0207:
0208:                tbFlag |= TextureBin.CONTIGUOUS_ACTIVE_UNITS;
0209:
0210:                if (state != null) {
0211:
0212:                    foundDisableUnit = false;
0213:
0214:                    if (texUnitState == null
0215:                            || (texUnitState.length != state.length)) {
0216:                        texUnitState = new TextureUnitStateRetained[state.length];
0217:                    } else if (texUnitState.length > 0
0218:                            && texUnitState[0] != null) {
0219:                        prevFirstTexture = texUnitState[0].texture;
0220:                    }
0221:
0222:                    for (i = 0; i < state.length; i++) {
0223:                        if (state[i] == null) {
0224:                            texUnitState[i] = null;
0225:                            foundDisableUnit = true;
0226:                        } else {
0227:
0228:                            // create a clone texture unit state
0229:                            if (texUnitState[i] == null) {
0230:                                texUnitState[i] = new TextureUnitStateRetained();
0231:                            }
0232:
0233:                            // for sole user TextureUnitState, save
0234:                            // the node component reference in the mirror reference
0235:                            // of the cloned copy for equal test, and
0236:                            // for native download optimization
0237:                            if (soleUser || state[i].changedFrequent != 0) {
0238:                                texUnitState[i].mirror = state[i];
0239:                            }
0240:
0241:                            // for the lowest level of node component in 
0242:                            // TextureBin, clone it only if it is not
0243:                            // changedFrequent; in other words, if the
0244:                            // lowest level of texture related node components
0245:                            // such as TextureAttributes & TexCoordGen is
0246:                            // changedFrequent, have the cloned texUnitState
0247:                            // reference the mirror of those node components
0248:                            // directly. For Texture, we'll always reference
0249:                            // the mirror.
0250:
0251:                            // decrement the TextureBin ref count of the previous
0252:                            // texture
0253:                            tex = texUnitState[i].texture;
0254:                            if (tex != null) {
0255:                                tex.decTextureBinRefCount(this );
0256:                                if (soleUser
0257:                                        && (tex.getTextureBinRefCount(this ) == 0)
0258:                                        && (tex != state[i].texture)) {
0259:                                    // In this case texture change but 
0260:                                    // TextureBin will not invoke clear() to reset.
0261:                                    // So we need to free the texture resource here.
0262:                                    renderBin.addTextureResourceFreeList(tex);
0263:                                }
0264:                            }
0265:
0266:                            texUnitState[i].texture = state[i].texture;
0267:
0268:                            // increment the TextureBin ref count of the new
0269:                            // texture
0270:
0271:                            if (texUnitState[i].texture != null) {
0272:                                texUnitState[i].texture
0273:                                        .incTextureBinRefCount(this );
0274:                            }
0275:
0276:                            if (state[i].texAttrs != null) {
0277:
0278:                                if (state[i].texAttrs.changedFrequent != 0) {
0279:                                    texUnitState[i].texAttrs = state[i].texAttrs;
0280:
0281:                                } else {
0282:
0283:                                    // need to check for texAttrs.source because
0284:                                    // texAttrs could be pointing to the mirror
0285:                                    // in the last frame, so don't want to
0286:                                    // overwrite the mirror
0287:
0288:                                    if (texUnitState[i].texAttrs == null
0289:                                            || texUnitState[i].texAttrs.source != null) {
0290:                                        texUnitState[i].texAttrs = new TextureAttributesRetained();
0291:                                    }
0292:                                    texUnitState[i].texAttrs
0293:                                            .set(state[i].texAttrs);
0294:                                    texUnitState[i].texAttrs.mirrorCompDirty = true;
0295:
0296:                                    // for sole user TextureBin, we are saving
0297:                                    // the mirror node component in the mirror
0298:                                    // reference in the clone object. This
0299:                                    // will be used in state download to
0300:                                    // avoid redundant download 
0301:
0302:                                    if (soleUser) {
0303:                                        texUnitState[i].texAttrs.mirror = state[i].texAttrs;
0304:                                    } else {
0305:                                        texUnitState[i].texAttrs.mirror = null;
0306:                                    }
0307:
0308:                                }
0309:                            } else {
0310:                                texUnitState[i].texAttrs = null;
0311:                            }
0312:
0313:                            if (state[i].texGen != null) {
0314:                                if (state[i].texGen.changedFrequent != 0) {
0315:                                    texUnitState[i].texGen = state[i].texGen;
0316:                                } else {
0317:
0318:                                    // need to check for texGen.source because
0319:                                    // texGen could be pointing to the mirror
0320:                                    // in the last frame, so don't want to
0321:                                    // overwrite the mirror
0322:
0323:                                    if (texUnitState[i].texGen == null
0324:                                            || texUnitState[i].texGen.source != null) {
0325:                                        texUnitState[i].texGen = new TexCoordGenerationRetained();
0326:                                    }
0327:
0328:                                    texUnitState[i].texGen.set(state[i].texGen);
0329:                                    texUnitState[i].texGen.mirrorCompDirty = true;
0330:
0331:                                    // for sole user TextureBin, we are saving
0332:                                    // the mirror node component in the mirror
0333:                                    // reference in the clone object. This
0334:                                    // will be used in state download to
0335:                                    // avoid redundant download 
0336:
0337:                                    if (soleUser) {
0338:                                        texUnitState[i].texGen.mirror = state[i].texGen;
0339:                                    } else {
0340:                                        texUnitState[i].texGen.mirror = null;
0341:                                    }
0342:                                }
0343:                            } else {
0344:                                texUnitState[i].texGen = null;
0345:                            }
0346:
0347:                            // Track the last active texture unit and the total number
0348:                            // of active texture units. Note that this total number
0349:                            // now includes disabled units so that there is always
0350:                            // a one-to-one mapping. We no longer remap texture units.
0351:                            if (texUnitState[i].isTextureEnabled()) {
0352:                                lastActiveTexUnitIndex = i;
0353:                                numActiveTexUnit = i + 1;
0354:
0355:                                if (foundDisableUnit) {
0356:
0357:                                    // mark that active texture units are not
0358:                                    // contiguous
0359:                                    tbFlag &= ~TextureBin.CONTIGUOUS_ACTIVE_UNITS;
0360:                                }
0361:                            } else {
0362:                                foundDisableUnit = true;
0363:                            }
0364:                        }
0365:                    }
0366:
0367:                    // check to see if the TextureBin sorting criteria is
0368:                    // modified for this textureBin; if yes, mark that
0369:                    // resorting is needed
0370:
0371:                    if ((texUnitState[0] == null && prevFirstTexture != null)
0372:                            || (texUnitState[0] != null && texUnitState[0].texture != prevFirstTexture)) {
0373:                        tbFlag |= TextureBin.RESORT;
0374:                    }
0375:
0376:                } else {
0377:
0378:                    // check to see if the TextureBin sorting criteria is
0379:                    // modified for this textureBin; if yes, mark that
0380:                    // resorting is needed
0381:
0382:                    if (texUnitState != null && texUnitState[0].texture != null) {
0383:                        tbFlag |= TextureBin.RESORT;
0384:                    }
0385:                    texUnitState = null;
0386:                }
0387:
0388:                soleUserCompDirty = 0;
0389:            }
0390:
0391:            /**
0392:             * The TextureBin is to be removed from RenderBin,
0393:             * do the proper unsetting of any references
0394:             */
0395:            void clear() {
0396:
0397:                // make sure there is no reference to the scenegraph
0398:                app = null;
0399:
0400:                // for each texture referenced in the texture units, decrement
0401:                // the reference count. If the reference count == 0, tell
0402:                // the renderer to free up the resource
0403:                if (texUnitState != null) {
0404:
0405:                    TextureRetained tex;
0406:
0407:                    for (int i = 0; i < texUnitState.length; i++) {
0408:                        if (texUnitState[i] != null) {
0409:                            if (texUnitState[i].texture != null) {
0410:                                tex = texUnitState[i].texture;
0411:                                tex.decTextureBinRefCount(this );
0412:
0413:                                if (tex.getTextureBinRefCount(this ) == 0) {
0414:                                    renderBin.addTextureResourceFreeList(tex);
0415:                                }
0416:
0417:                                texUnitState[i].texture = null;
0418:                            }
0419:
0420:                            // make sure there is no more reference to the scenegraph
0421:
0422:                            texUnitState[i].mirror = null;
0423:                            texUnitState[i].texture = null;
0424:                            if (texUnitState[i].texAttrs != null
0425:                                    && texUnitState[i].texAttrs.source != null) {
0426:                                texUnitState[i].texAttrs = null;
0427:                            }
0428:                            if (texUnitState[i].texGen != null
0429:                                    && texUnitState[i].texGen.source != null) {
0430:                                texUnitState[i].texGen = null;
0431:                            }
0432:                        }
0433:                    }
0434:                }
0435:            }
0436:
0437:            /**
0438:             * This tests if the qiven textureUnitState matches this TextureBin
0439:             */
0440:            boolean equals(TextureUnitStateRetained state[], RenderAtom ra) {
0441:
0442:                int i, j, k = 0;
0443:                TextureRetained texture;
0444:
0445:                // if this TextureBin is a soleUser case or the incoming
0446:                // app has changedFrequent bit set for any of the texture
0447:                // related component, then either the current TextureBin
0448:                // or the incoming app requires the same app match
0449:                if (((tbFlag & TextureBin.SOLE_USER) != 0)
0450:                        || ((ra.app != null) && (ra.app.changedFrequent & (AppearanceRetained.TEXTURE
0451:                                | AppearanceRetained.TEXCOORD_GEN
0452:                                | AppearanceRetained.TEXTURE_ATTR | AppearanceRetained.TEXTURE_UNIT_STATE)) != 0)) {
0453:
0454:                    if (app == ra.app) {
0455:
0456:                        // if this textureBin is currently on a zombie state,
0457:                        // we'll need to put it on the update list to reevaluate
0458:                        // the state, because while it is on a zombie state,
0459:                        // texture state could have been changed. Example,
0460:                        // application could have detached an appearance,
0461:                        // made changes to the texture references, and then
0462:                        // reattached the appearance. In this case, the texture
0463:                        // changes would not have reflected to the textureBin
0464:
0465:                        if (numEditingRenderMolecules == 0) {
0466:
0467:                            //System.err.println("===> TB in zombie state  " + this);
0468:
0469:                            if (soleUserCompDirty == 0) {
0470:                                this .renderBin.tbUpdateList.add(this );
0471:                            }
0472:                            soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_REF;
0473:                        }
0474:                        return true;
0475:
0476:                    } else {
0477:                        return false;
0478:                    }
0479:                }
0480:
0481:                if (texUnitState == null && state == null)
0482:                    return (true);
0483:
0484:                if (texUnitState == null || state == null)
0485:                    return (false);
0486:
0487:                if (state.length != texUnitState.length)
0488:                    return (false);
0489:
0490:                for (i = 0; i < texUnitState.length; i++) {
0491:                    // If texture Unit State is null
0492:                    if (texUnitState[i] == null) {
0493:                        if (state[i] != null)
0494:                            return (false);
0495:                    } else {
0496:                        if (!texUnitState[i].equivalent(state[i])) {
0497:                            return (false);
0498:                        }
0499:                    }
0500:                }
0501:
0502:                // Check if the image component has changed(may be a clearLive texture
0503:                // change img component. setLive case)
0504:                //
0505:                if ((tbFlag & TextureBin.ON_RENDER_BIN_LIST) == 0) {
0506:                    renderBin.addTextureBin(this );
0507:                    tbFlag |= TextureBin.ON_RENDER_BIN_LIST;
0508:                }
0509:
0510:                return (true);
0511:
0512:            }
0513:
0514:            /*
0515:            // updateNodeComponentCheck is called for each soleUser TextureBin 
0516:            // into which new renderAtom has been added. This method is called before
0517:            // updateNodeComponent() to allow TextureBin to catch any node
0518:            // component changes that have been missed because the changes
0519:            // come when there is no active renderAtom associated with the
0520:            // TextureBin. See bug# 4503926 for details.
0521:            public void updateNodeComponentCheck() {
0522:
0523:            //System.err.println("TextureBin.updateNodeComponentCheck()");
0524:
0525:            tbFlag &= ~TextureBin.ON_UPDATE_CHECK_LIST;
0526:
0527:            if ((soleUserCompDirty & SOLE_USER_DIRTY_REF) != 0) {
0528:                return ;
0529:            }
0530:
0531:               	if ((app.compChanged & (AppearanceRetained.TEXTURE |
0532:                         		AppearanceRetained.TEXCOORD_GEN |
0533:                         		AppearanceRetained.TEXTURE_ATTR |
0534:                         		AppearanceRetained.TEXTURE_UNIT_STATE)) != 0) {
0535:                    if (soleUserCompDirty == 0) {
0536:                        this.renderBin.tbUpdateList.add(this);
0537:                    }
0538:                    soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_REF;
0539:
0540:                } else if (app.texUnitState != null) {
0541:
0542:                // if one texture unit state has to be reevaluated, then
0543:                // it's enough update checking because reevaluating texture unit
0544:                // state will automatically take care of its node component
0545:                // updates.
0546:
0547:                boolean done = false;
0548:
0549:                    for (int i = 0; i < app.texUnitState.length && !done; i++) {
0550:                        if (app.texUnitState[i] != null) {
0551:            	    if (app.texUnitState[i].compChanged != 0) {
0552:            	        if (soleUserCompDirty == 0) {
0553:            		    this.renderBin.tbUpdateList.add(this);
0554:            	        }
0555:            	        soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TUS;
0556:            		done = true;
0557:            	    } else {
0558:            		if (app.texUnitState[i].texAttrs != null &&
0559:            			app.texUnitState[i].texAttrs.compChanged != 0) {
0560:            		    if (soleUserCompDirty == 0) {
0561:            			this.renderBin.tbUpdateList.add(this);
0562:            		    }
0563:            		    soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TA;
0564:            		}
0565:            		if (app.texUnitState[i].texGen != null &&
0566:            			app.texUnitState[i].texGen.compChanged != 0) {
0567:            		    if (soleUserCompDirty == 0) {
0568:            			this.renderBin.tbUpdateList.add(this);
0569:            		    }
0570:            		    soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TC;
0571:            		}
0572:            		if (app.texUnitState[i].texture != null &&
0573:            			((app.texUnitState[i].texture.compChanged &
0574:            			    TextureRetained.ENABLE_CHANGED) != 0)) {
0575:            		    if (soleUserCompDirty == 0) {
0576:            			this.renderBin.tbUpdateList.add(this);
0577:            		    }
0578:            		    soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TEXTURE;
0579:            		}
0580:            	    }
0581:            	}
0582:                }
0583:            }
0584:            }
0585:             */
0586:
0587:            /**
0588:             * updateNodeComponent is called from RenderBin to update the
0589:             * clone copy of the sole user node component in TextureBin when the
0590:             * corresponding node component is being modified
0591:             */
0592:            public void updateNodeComponent() {
0593:
0594:                // don't bother to update if the TextureBin is already
0595:                // removed from RenderBin
0596:
0597:                if ((tbFlag & TextureBin.ON_RENDER_BIN_LIST) == 0)
0598:                    return;
0599:
0600:                // if any of the texture reference in the appearance referenced
0601:                // by a sole user TextureBin is being modified, just do a reset
0602:
0603:                if (((tbFlag & TextureBin.SOLE_USER) != 0)
0604:                        && ((soleUserCompDirty & TextureBin.SOLE_USER_DIRTY_REF) != 0)) {
0605:
0606:                    resetTextureState(app.texUnitState);
0607:                    return;
0608:                }
0609:
0610:                if (texUnitState == null) {
0611:                    soleUserCompDirty = 0;
0612:                    return;
0613:                }
0614:
0615:                if ((soleUserCompDirty & TextureBin.SOLE_USER_DIRTY_TUS) != 0) {
0616:
0617:                    // Now take care of the Texture Unit State changes
0618:                    TextureUnitStateRetained tus, mirrorTUS = null;
0619:                    boolean soleUser = ((tbFlag & TextureBin.SOLE_USER) != 0);
0620:
0621:                    for (int i = 0; i < texUnitState.length; i++) {
0622:                        tus = texUnitState[i];
0623:                        if (tus != null) {
0624:                            if (tus.mirror != null) {
0625:
0626:                                mirrorTUS = (TextureUnitStateRetained) tus.mirror;
0627:
0628:                                if (tus.texture != mirrorTUS.texture) {
0629:                                    if (tus.texture != null) {
0630:                                        tus.texture.decTextureBinRefCount(this );
0631:                                    }
0632:                                    tus.texture = mirrorTUS.texture;
0633:                                    if (tus.texture != null) {
0634:                                        tus.texture.incTextureBinRefCount(this );
0635:                                    }
0636:
0637:                                    // the first texture (TextureBin sorting
0638:                                    // criteria) is modified, so needs to resort
0639:
0640:                                    if (i == 0) {
0641:                                        tbFlag |= TextureBin.RESORT;
0642:                                    }
0643:                                }
0644:
0645:                                if (mirrorTUS.texAttrs != null) {
0646:                                    if (mirrorTUS.texAttrs.changedFrequent != 0) {
0647:                                        tus.texAttrs = mirrorTUS.texAttrs;
0648:                                    } else {
0649:                                        if (tus.texAttrs == null
0650:                                                || tus.texAttrs.source != null) {
0651:                                            tus.texAttrs = new TextureAttributesRetained();
0652:                                        }
0653:                                        tus.texAttrs.set(mirrorTUS.texAttrs);
0654:                                        tus.texAttrs.mirrorCompDirty = true;
0655:
0656:                                        if (soleUser) {
0657:                                            tus.texAttrs.mirror = mirrorTUS.texAttrs;
0658:                                        } else {
0659:                                            tus.texAttrs.mirror = null;
0660:                                        }
0661:                                    }
0662:                                } else {
0663:                                    tus.texAttrs = null;
0664:                                }
0665:
0666:                                if (mirrorTUS.texGen != null) {
0667:                                    if (mirrorTUS.texGen.changedFrequent != 0) {
0668:                                        tus.texGen = mirrorTUS.texGen;
0669:                                    } else {
0670:                                        if (tus.texGen == null
0671:                                                || tus.texGen.source != null) {
0672:                                            tus.texGen = new TexCoordGenerationRetained();
0673:                                        }
0674:                                        tus.texGen.set(mirrorTUS.texGen);
0675:                                        tus.texGen.mirrorCompDirty = true;
0676:
0677:                                        if (soleUser) {
0678:                                            tus.texGen.mirror = mirrorTUS.texGen;
0679:                                        } else {
0680:                                            tus.texGen.mirror = null;
0681:                                        }
0682:                                    }
0683:                                } else {
0684:                                    tus.texGen = null;
0685:                                }
0686:                            }
0687:                        }
0688:                    }
0689:
0690:                    // need to reEvaluate # of active textures after the update
0691:                    soleUserCompDirty |= TextureBin.SOLE_USER_DIRTY_TEXTURE;
0692:
0693:                    // TextureUnitState update automatically taken care of
0694:                    // TextureAttributes & TexCoordGeneration update
0695:
0696:                    soleUserCompDirty &= ~(TextureBin.SOLE_USER_DIRTY_TA | TextureBin.SOLE_USER_DIRTY_TC);
0697:                }
0698:
0699:                if ((soleUserCompDirty & TextureBin.SOLE_USER_DIRTY_TEXTURE) != 0) {
0700:
0701:                    boolean foundDisableUnit = false;
0702:
0703:                    numActiveTexUnit = 0;
0704:                    lastActiveTexUnitIndex = 0;
0705:                    tbFlag |= TextureBin.CONTIGUOUS_ACTIVE_UNITS;
0706:                    for (int i = 0; i < texUnitState.length; i++) {
0707:
0708:                        // Track the last active texture unit and the total number
0709:                        // of active texture units. Note that this total number
0710:                        // now includes disabled units so that there is always
0711:                        // a one-to-one mapping. We no longer remap texture units.
0712:                        if (texUnitState[i] != null
0713:                                && texUnitState[i].isTextureEnabled()) {
0714:                            lastActiveTexUnitIndex = i;
0715:                            numActiveTexUnit = i + 1;
0716:
0717:                            if (foundDisableUnit) {
0718:
0719:                                // mark that active texture units are not
0720:                                // contiguous
0721:                                tbFlag &= ~TextureBin.CONTIGUOUS_ACTIVE_UNITS;
0722:                            }
0723:                        } else {
0724:                            foundDisableUnit = true;
0725:                        }
0726:                    }
0727:                }
0728:
0729:                if ((soleUserCompDirty & TextureBin.SOLE_USER_DIRTY_TA) != 0) {
0730:                    for (int i = 0; i < texUnitState.length; i++) {
0731:                        if (texUnitState[i] != null
0732:                                && texUnitState[i].texAttrs != null
0733:                                && texUnitState[i].texAttrs.mirror != null
0734:                                && texUnitState[i].texAttrs.mirror.changedFrequent != 0) {
0735:                            texUnitState[i].texAttrs = (TextureAttributesRetained) texUnitState[i].texAttrs.mirror;
0736:                        }
0737:                    }
0738:                }
0739:
0740:                if ((soleUserCompDirty & TextureBin.SOLE_USER_DIRTY_TC) != 0) {
0741:                    for (int i = 0; i < texUnitState.length; i++) {
0742:                        if (texUnitState[i] != null
0743:                                && texUnitState[i].texGen != null
0744:                                && texUnitState[i].texGen.mirror != null
0745:                                && texUnitState[i].texGen.mirror.changedFrequent != 0) {
0746:                            texUnitState[i].texGen = (TexCoordGenerationRetained) texUnitState[i].texGen.mirror;
0747:                        }
0748:                    }
0749:                }
0750:
0751:                soleUserCompDirty = 0;
0752:            }
0753:
0754:            public void updateObject() {
0755:                if (!addOpaqueRMs.isEmpty()) {
0756:                    opaqueRMList = addAll(opaqueRenderMoleculeMap,
0757:                            addOpaqueRMs, opaqueRMList, true);
0758:                }
0759:                if (!addTransparentRMs.isEmpty()) {
0760:                    // If transparent and not in bg geometry and inodepth 
0761:                    // sorted transparency
0762:                    if (transparentRMList == null
0763:                            && (renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE || environmentSet.lightBin.geometryBackground != null)) {
0764:                        //		System.err.println("========> addTransparentTextureBin "+this); 
0765:                        transparentRMList = addAll(
0766:                                transparentRenderMoleculeMap,
0767:                                addTransparentRMs, transparentRMList, false);
0768:                        // Eventhough we are adding to transparentList , if all the RMS
0769:                        // have been switched already due to changeLists, then there is
0770:                        // nothing to add, and TBIN does not have any transparentRMList
0771:                        if (transparentRMList != null) {
0772:                            renderBin.addTransparentObject(this );
0773:                        }
0774:
0775:                    } else {
0776:                        transparentRMList = addAll(
0777:                                transparentRenderMoleculeMap,
0778:                                addTransparentRMs, transparentRMList, false);
0779:                    }
0780:                }
0781:                tbFlag &= ~TextureBin.ON_UPDATE_LIST;
0782:
0783:            }
0784:
0785:            /**
0786:             * Each list of renderMoledule with the same localToVworld
0787:             * is connect by rm.next and rm.prev.
0788:             * At the end of the list (i.e. rm.next = null) the field
0789:             * rm.nextMap is link to another list (with the same
0790:             * localToVworld). So during rendering it will traverse
0791:             * rm.next until this is null, then follow the .nextMap
0792:             * to access another list and use rm.next to continue
0793:             * until both rm.next and rm.nextMap are null.
0794:             *
0795:             * renderMoleculeMap is use to assist faster location of 
0796:             * renderMolecule List with the same localToVWorld. The
0797:             * start of renderMolecule in the list with same 
0798:             * localToVworld is insert in renderMoleculeMap. This
0799:             * map is clean up at removeRenderMolecule(). TextureBin
0800:             * also use the map for quick location of renderMolecule
0801:             * with the same localToVworld and attributes in
0802:             * findRenderMolecule().
0803:             */
0804:            RenderMolecule addAll(HashMap renderMoleculeMap, HashMap addRMs,
0805:                    RenderMolecule startList, boolean opaqueList) {
0806:                int i;
0807:                RenderMolecule r;
0808:                Collection c = addRMs.values();
0809:                Iterator listIterator = c.iterator();
0810:                RenderMolecule renderMoleculeList, head;
0811:
0812:                while (listIterator.hasNext()) {
0813:                    boolean changed = false;
0814:                    ArrayList curList = (ArrayList) listIterator.next();
0815:                    r = (RenderMolecule) curList.get(0);
0816:                    // If this is a opaque one , but has been switched to a transparentList or
0817:                    // vice-versa (dur to changeLists function called before this), then
0818:                    // do nothing!
0819:                    // For changedFrequent case: Consider the case when a RM is added
0820:                    // (so is in the addRM list) and then
0821:                    // a change  in transparent value occurs that make it from opaque to
0822:                    // transparent (the switch is handled before this function is called)
0823:                    if (r.isOpaqueOrInOG != opaqueList) {
0824:                        continue;
0825:                    }
0826:                    // Get the list of renderMolecules for this transform
0827:                    renderMoleculeList = (RenderMolecule) renderMoleculeMap
0828:                            .get(r.localToVworld);
0829:                    if (renderMoleculeList == null) {
0830:                        renderMoleculeList = r;
0831:                        renderMoleculeMap.put(r.localToVworld,
0832:                                renderMoleculeList);
0833:                        // Add this renderMolecule at the beginning of RM list
0834:                        if (startList == null) {
0835:                            startList = r;
0836:                            r.nextMap = null;
0837:                            r.prevMap = null;
0838:                            startList.dirtyAttrsAcrossRms = RenderMolecule.ALL_DIRTY_BITS;
0839:                        } else {
0840:                            r.nextMap = startList;
0841:                            startList.prevMap = r;
0842:                            startList = r;
0843:                            startList.nextMap.checkEquivalenceWithLeftNeighbor(
0844:                                    r, RenderMolecule.ALL_DIRTY_BITS);
0845:                        }
0846:
0847:                    } else {
0848:                        // Insert the renderMolecule next to a RM that has equivalent 
0849:                        // texture unit state
0850:                        if ((head = insertRenderMolecule(r, renderMoleculeList)) != null) {
0851:                            if (renderMoleculeList.prevMap != null) {
0852:                                renderMoleculeList.prevMap.nextMap = head;
0853:                            }
0854:                            head.prevMap = renderMoleculeList.prevMap;
0855:                            renderMoleculeList.prevMap = null;
0856:                            renderMoleculeList = head;
0857:                            changed = true;
0858:                        }
0859:                    }
0860:                    for (i = 1; i < curList.size(); i++) {
0861:                        r = (RenderMolecule) curList.get(i);
0862:                        // If this is a opaque one , but has been switched to a transparentList or
0863:                        // vice-versa (dur to changeLists function called before this), then
0864:                        // do nothing!
0865:                        // For changedFrequent case: Consider the case when a RM is added
0866:                        // (so is in the addRM list) and then
0867:                        // a change  in transparent value occurs that make it from opaque to
0868:                        // transparent (the switch is handled before this function is called)
0869:                        if (r.isOpaqueOrInOG != opaqueList)
0870:                            continue;
0871:                        if ((head = insertRenderMolecule(r, renderMoleculeList)) != null) {
0872:                            if (renderMoleculeList.prevMap != null) {
0873:                                renderMoleculeList.prevMap.nextMap = head;
0874:                            }
0875:                            head.prevMap = renderMoleculeList.prevMap;
0876:                            renderMoleculeList.prevMap = null;
0877:                            renderMoleculeList = head;
0878:                            changed = true;
0879:                        }
0880:
0881:                    }
0882:                    if (changed) {
0883:                        renderMoleculeMap.put(r.localToVworld,
0884:                                renderMoleculeList);
0885:                        if (renderMoleculeList.prevMap != null) {
0886:                            renderMoleculeList
0887:                                    .checkEquivalenceWithLeftNeighbor(
0888:                                            renderMoleculeList.prevMap,
0889:                                            RenderMolecule.ALL_DIRTY_BITS);
0890:                        } else {
0891:                            startList = renderMoleculeList;
0892:                            startList.dirtyAttrsAcrossRms = RenderMolecule.ALL_DIRTY_BITS;
0893:                        }
0894:                    }
0895:                }
0896:
0897:                addRMs.clear();
0898:                return startList;
0899:            }
0900:
0901:            // XXXX: Could the analysis be done during insertRenderMolecule?
0902:            // Return the head of the list,
0903:            // if the insertion occurred at beginning of the list
0904:            RenderMolecule insertRenderMolecule(RenderMolecule r,
0905:                    RenderMolecule renderMoleculeList) {
0906:                RenderMolecule rm, retval;
0907:
0908:                // Look for a RM that has an equivalent material
0909:                rm = renderMoleculeList;
0910:                while (rm != null) {
0911:                    if (rm.material == r.material
0912:                            || (rm.definingMaterial != null && rm.definingMaterial
0913:                                    .equivalent(r.definingMaterial))) {
0914:                        // Put it here
0915:                        r.next = rm;
0916:                        r.prev = rm.prev;
0917:                        if (rm.prev == null) {
0918:                            renderMoleculeList = r;
0919:                            retval = renderMoleculeList;
0920:                        } else {
0921:                            rm.prev.next = r;
0922:                            retval = null;
0923:                        }
0924:                        rm.prev = r;
0925:                        r
0926:                                .checkEquivalenceWithBothNeighbors(RenderMolecule.ALL_DIRTY_BITS);
0927:                        return retval;
0928:                    }
0929:                    // If they are not equivalent, then skip to the first one
0930:                    // that has a different material using the dirty bits
0931:                    else {
0932:                        rm = rm.next;
0933:                        while (rm != null
0934:                                && ((rm.dirtyAttrsAcrossRms & RenderMolecule.MATERIAL_DIRTY) == 0)) {
0935:                            rm = rm.next;
0936:                        }
0937:                    }
0938:                }
0939:                // Just put it up front
0940:                r.next = renderMoleculeList;
0941:                renderMoleculeList.prev = r;
0942:                renderMoleculeList = r;
0943:                r
0944:                        .checkEquivalenceWithBothNeighbors(RenderMolecule.ALL_DIRTY_BITS);
0945:                return renderMoleculeList;
0946:            }
0947:
0948:            /**
0949:             * Adds the given RenderMolecule to this TextureBin
0950:             */
0951:            void addRenderMolecule(RenderMolecule r, RenderBin rb) {
0952:                RenderMolecule rm;
0953:                ArrayList list;
0954:                HashMap map;
0955:                r.textureBin = this ;
0956:
0957:                if (r.isOpaqueOrInOG)
0958:                    map = addOpaqueRMs;
0959:                else
0960:                    map = addTransparentRMs;
0961:
0962:                if ((list = (ArrayList) map.get(r.localToVworld)) == null) {
0963:                    list = new ArrayList();
0964:                    map.put(r.localToVworld, list);
0965:                }
0966:                list.add(r);
0967:
0968:                if ((tbFlag & TextureBin.ON_UPDATE_LIST) == 0) {
0969:                    tbFlag |= TextureBin.ON_UPDATE_LIST;
0970:                    rb.objUpdateList.add(this );
0971:                }
0972:            }
0973:
0974:            /**
0975:             * Removes the given RenderMolecule from this TextureBin
0976:             */
0977:            void removeRenderMolecule(RenderMolecule r) {
0978:                ArrayList list;
0979:                int index;
0980:                boolean found = false;
0981:                RenderMolecule renderMoleculeList, rmlist;
0982:                HashMap addMap;
0983:                HashMap allMap;
0984:                r.textureBin = null;
0985:
0986:                if (r.isOpaqueOrInOG) {
0987:                    rmlist = opaqueRMList;
0988:                    allMap = opaqueRenderMoleculeMap;
0989:                    addMap = addOpaqueRMs;
0990:                } else {
0991:                    rmlist = transparentRMList;
0992:                    allMap = transparentRenderMoleculeMap;
0993:                    addMap = addTransparentRMs;
0994:                }
0995:                // If the renderMolecule being remove is contained in addRMs, then
0996:                // remove the renderMolecule from the addList
0997:                if ((list = (ArrayList) addMap.get(r.localToVworld)) != null) {
0998:                    if ((index = list.indexOf(r)) != -1) {
0999:                        list.remove(index);
1000:                        // If this was the last element for this localToVworld, then remove
1001:                        // the entry from the addRMs list
1002:                        if (list.isEmpty()) {
1003:                            addMap.remove(r.localToVworld);
1004:                        }
1005:
1006:                        r.prev = null;
1007:                        r.next = null;
1008:                        found = true;
1009:                    }
1010:                }
1011:                if (!found) {
1012:                    RenderMolecule head = removeOneRM(r, allMap, rmlist);
1013:
1014:                    r.soleUserCompDirty = 0;
1015:                    r.onUpdateList = 0;
1016:                    if (r.definingPolygonAttributes != null
1017:                            && (r.definingPolygonAttributes.changedFrequent != 0))
1018:                        r.definingPolygonAttributes = null;
1019:
1020:                    if (r.definingLineAttributes != null
1021:                            && (r.definingLineAttributes.changedFrequent != 0))
1022:                        r.definingLineAttributes = null;
1023:
1024:                    if (r.definingPointAttributes != null
1025:                            && (r.definingPointAttributes.changedFrequent != 0))
1026:                        r.definingPointAttributes = null;
1027:
1028:                    if (r.definingMaterial != null
1029:                            && (r.definingMaterial.changedFrequent != 0))
1030:                        r.definingMaterial = null;
1031:
1032:                    if (r.definingColoringAttributes != null
1033:                            && (r.definingColoringAttributes.changedFrequent != 0))
1034:                        r.definingColoringAttributes = null;
1035:
1036:                    if (r.definingTransparency != null
1037:                            && (r.definingTransparency.changedFrequent != 0))
1038:                        r.definingTransparency = null;
1039:
1040:                    renderBin.removeRenderMolecule(r);
1041:                    if (r.isOpaqueOrInOG) {
1042:                        opaqueRMList = head;
1043:                    } else {
1044:                        transparentRMList = head;
1045:                    }
1046:
1047:                }
1048:                // If the renderMolecule removed is not opaque then ..
1049:                if (!r.isOpaqueOrInOG
1050:                        && transparentRMList == null
1051:                        && (renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE || environmentSet.lightBin.geometryBackground != null)) {
1052:                    renderBin.removeTransparentObject(this );
1053:                }
1054:                // If the rm removed is the one that is referenced in the tinfo
1055:                // then change this reference
1056:                else if (parentTInfo != null && parentTInfo.rm == r) {
1057:                    parentTInfo.rm = transparentRMList;
1058:                }
1059:                // Removal of this texture setting from the texCoordGenartion
1060:                // is done during the removeRenderAtom routine in RenderMolecule.java
1061:                // Only remove this texture bin if there are no more renderMolcules
1062:                // waiting to be added
1063:                if (opaqueRenderMoleculeMap.isEmpty() && addOpaqueRMs.isEmpty()
1064:                        && transparentRenderMoleculeMap.isEmpty()
1065:                        && addTransparentRMs.isEmpty()) {
1066:                    if ((tbFlag & TextureBin.ON_RENDER_BIN_LIST) != 0) {
1067:                        tbFlag &= ~TextureBin.ON_RENDER_BIN_LIST;
1068:                        renderBin.removeTextureBin(this );
1069:                    }
1070:
1071:                    shaderBin.removeTextureBin(this );
1072:                    texUnitState = null;
1073:                }
1074:            }
1075:
1076:            /**
1077:             * This method is called to update the state for this
1078:             * TextureBin. This is only applicable in the single-pass case.
1079:             * Multi-pass render will have to take care of its own
1080:             * state update.
1081:             */
1082:            void updateAttributes(Canvas3D cv) {
1083:
1084:                boolean dirty = ((cv.canvasDirty & (Canvas3D.TEXTUREBIN_DIRTY | Canvas3D.TEXTUREATTRIBUTES_DIRTY)) != 0);
1085:
1086:                if (cv.textureBin == this  && !dirty) {
1087:                    return;
1088:                }
1089:
1090:                cv.textureBin = this ;
1091:
1092:                // save the current number of active texture unit so as
1093:                // to be able to reset the one that is not enabled in this bin
1094:
1095:                int lastActiveTexUnitIdx = -1;
1096:
1097:                // Get the number of available texture units; this depends on
1098:                // whether or not shaders are being used.
1099:                boolean useShaders = (shaderBin.shaderProgram != null);
1100:                int availableTextureUnits = useShaders ? cv.maxTextureImageUnits
1101:                        : cv.maxTextureUnits;
1102:
1103:                // If the number of active texture units is greater than the number of
1104:                // supported units, then we
1105:                // need to set a flag indicating that the texture units are invalid.
1106:                boolean disableTexture = false;
1107:
1108:                if (numActiveTexUnit > availableTextureUnits) {
1109:                    disableTexture = true;
1110:                    //            System.err.println("*** TextureBin : number of texture units exceeded");
1111:                }
1112:
1113:                // set the number active texture unit in Canvas3D
1114:                if (disableTexture) {
1115:                    cv.setNumActiveTexUnit(0);
1116:                } else {
1117:                    cv.setNumActiveTexUnit(numActiveTexUnit);
1118:                }
1119:
1120:                // state update
1121:                if (numActiveTexUnit <= 0 || disableTexture) {
1122:                    if (cv.getLastActiveTexUnit() >= 0) {
1123:                        // no texture units enabled
1124:
1125:                        // when the canvas supports multi texture units,
1126:                        // we'll need to reset texture for all texture units
1127:                        if (cv.multiTexAccelerated) {
1128:                            for (int i = 0; i <= cv.getLastActiveTexUnit(); i++) {
1129:                                cv.resetTexture(cv.ctx, i);
1130:                            }
1131:                            // set the active texture unit back to 0
1132:                            cv.setNumActiveTexUnit(0);
1133:                            cv.activeTextureUnit(cv.ctx, 0);
1134:                        } else {
1135:                            cv.resetTexture(cv.ctx, -1);
1136:                        }
1137:                        cv.setLastActiveTexUnit(-1);
1138:                    }
1139:                } else {
1140:
1141:                    int j = 0;
1142:
1143:                    for (int i = 0; i < texUnitState.length; i++) {
1144:
1145:                        if (j >= cv.texUnitState.length) {
1146:                            // We finish enabling the texture state.
1147:                            // Note that it is possible
1148:                            // texUnitState.length > cv.texUnitState.length 
1149:
1150:                            break;
1151:                        }
1152:
1153:                        if ((texUnitState[i] != null)
1154:                                && texUnitState[i].isTextureEnabled()) {
1155:                            if (dirty
1156:                                    || cv.texUnitState[j].mirror == null
1157:                                    || cv.texUnitState[j].mirror != texUnitState[i].mirror) {
1158:                                // update the texture unit state
1159:                                texUnitState[i].updateNative(j, cv, false,
1160:                                        false);
1161:                                cv.texUnitState[j].mirror = texUnitState[i].mirror;
1162:                            }
1163:
1164:                            // create a mapping that maps an active texture
1165:                            // unit to a texture unit state
1166:
1167:                            lastActiveTexUnitIdx = j;
1168:                        } else {
1169:                            if (j <= cv.getLastActiveTexUnit()) {
1170:                                cv.resetTexture(cv.ctx, j);
1171:                            }
1172:                        }
1173:
1174:                        j++;
1175:                    }
1176:
1177:                    // make sure to disable the remaining texture units
1178:                    // since they could have been enabled from the previous
1179:                    // texture bin
1180:
1181:                    for (int i = j; i <= cv.getLastActiveTexUnit(); i++) {
1182:                        cv.resetTexture(cv.ctx, i);
1183:                    }
1184:
1185:                    cv.setLastActiveTexUnit(lastActiveTexUnitIdx);
1186:
1187:                    // set the active texture unit back to 0
1188:                    cv.activeTextureUnit(cv.ctx, 0);
1189:
1190:                }
1191:                cv.canvasDirty &= ~Canvas3D.TEXTUREBIN_DIRTY;
1192:            }
1193:
1194:            /**
1195:             * Renders this TextureBin
1196:             */
1197:            void render(Canvas3D cv) {
1198:                render(cv, (Object) opaqueRMList);
1199:            }
1200:
1201:            void render(Canvas3D cv, Object rlist) {
1202:
1203:                cv.texLinearMode = false;
1204:
1205:                /*
1206:                System.err.println("TextureBin/render " + this +
1207:                	" numActiveTexUnit= " + numActiveTexUnit + 
1208:                	" maxTextureUnits= " + cv.maxTextureUnits);
1209:                 */
1210:
1211:                // include this TextureBin to the to-be-updated state set in canvas
1212:                cv.setStateToUpdate(Canvas3D.TEXTUREBIN_BIT, this );
1213:
1214:                // For D3D - set the texLinearMode flag in the canvas if texcoord
1215:                // generation is enabled in object_linear mode for any texture unit.
1216:                if ((texUnitState != null) && VirtualUniverse.mc.isD3D()) {
1217:                    TextureUnitStateRetained tus;
1218:                    for (int i = 0; i < texUnitState.length; i++) {
1219:                        tus = texUnitState[i];
1220:                        if ((tus != null) && tus.isTextureEnabled()) {
1221:                            if ((tus.texGen != null)
1222:                                    && (tus.texGen.genMode == TexCoordGeneration.OBJECT_LINEAR)) {
1223:                                cv.texLinearMode = true;
1224:                            }
1225:                        }
1226:                    }
1227:                }
1228:
1229:                renderList(cv, USE_DISPLAYLIST, rlist);
1230:            }
1231:
1232:            /**
1233:             * render a render list
1234:             */
1235:            void renderList(Canvas3D cv, int pass, Object rlist) {
1236:                assert pass < 0;
1237:
1238:                if (rlist instanceof  RenderMolecule) {
1239:                    renderList(cv, pass, (RenderMolecule) rlist);
1240:                } else if (rlist instanceof  TransparentRenderingInfo) {
1241:                    renderList(cv, pass, (TransparentRenderingInfo) rlist);
1242:                }
1243:            }
1244:
1245:            /**
1246:             * render list of RenderMolecule 
1247:             */
1248:            void renderList(Canvas3D cv, int pass, RenderMolecule rlist) {
1249:                assert pass < 0;
1250:
1251:                // bit mask of all attr fields that are equivalent across 
1252:                // renderMolecules thro. ORing of invisible RMs.
1253:                int combinedDirtyBits = 0;
1254:                boolean rmVisible = true;
1255:                RenderMolecule rm = rlist;
1256:
1257:                while (rm != null) {
1258:                    if (rmVisible) {
1259:                        combinedDirtyBits = rm.dirtyAttrsAcrossRms;
1260:                    } else {
1261:                        combinedDirtyBits |= rm.dirtyAttrsAcrossRms;
1262:                    }
1263:
1264:                    rmVisible = rm.render(cv, pass, combinedDirtyBits);
1265:
1266:                    // next render molecule or the nextmap
1267:                    if (rm.next == null) {
1268:                        rm = rm.nextMap;
1269:                    } else {
1270:                        rm = rm.next;
1271:                    }
1272:                }
1273:            }
1274:
1275:            /**
1276:             * render sorted transparent list 
1277:             */
1278:            void renderList(Canvas3D cv, int pass,
1279:                    TransparentRenderingInfo tinfo) {
1280:                assert pass < 0;
1281:
1282:                RenderMolecule rm = tinfo.rm;
1283:                if (rm.isSwitchOn()) {
1284:                    rm.transparentSortRender(cv, pass, tinfo);
1285:                }
1286:            }
1287:
1288:            void changeLists(RenderMolecule r) {
1289:                RenderMolecule renderMoleculeList, rmlist = null, head;
1290:                HashMap allMap = null;
1291:                ArrayList list;
1292:                int index;
1293:                boolean newRM = false;
1294:                //	System.err.println("changeLists r = "+r+" tBin = "+this);
1295:                // If its a new RM then do nothing, otherwise move lists
1296:                if (r.isOpaqueOrInOG) {
1297:                    if (opaqueRMList == null
1298:                            && (r.prev == null && r.prevMap == null
1299:                                    && r.next == null && r.nextMap == null)) {
1300:                        newRM = true;
1301:                    } else {
1302:                        rmlist = opaqueRMList;
1303:                        allMap = opaqueRenderMoleculeMap;
1304:                    }
1305:
1306:                } else {
1307:                    if (transparentRMList == null
1308:                            && (r.prev == null && r.prevMap == null
1309:                                    && r.next == null && r.nextMap == null)) {
1310:                        newRM = true;
1311:                    } else {
1312:                        rmlist = transparentRMList;
1313:                        allMap = transparentRenderMoleculeMap;
1314:                    }
1315:                }
1316:                if (!newRM) {
1317:                    head = removeOneRM(r, allMap, rmlist);
1318:
1319:                    if (r.isOpaqueOrInOG) {
1320:                        opaqueRMList = head;
1321:                    } else {
1322:                        transparentRMList = head;
1323:                        if (transparentRMList == null
1324:                                && (renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE || environmentSet.lightBin.geometryBackground != null)) {
1325:                            renderBin.removeTransparentObject(this );
1326:                        }
1327:                        // Issue 129: remove the RM's render atoms from the
1328:                        // list of transparent render atoms
1329:                        if ((renderBin.transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY)
1330:                                && (environmentSet.lightBin.geometryBackground == null)) {
1331:                            r.addRemoveTransparentObject(renderBin, false);
1332:                        }
1333:                    }
1334:                }
1335:                HashMap renderMoleculeMap;
1336:                RenderMolecule startList;
1337:
1338:                // Now insert in the other bin
1339:                r.evalAlphaUsage(
1340:                        shaderBin.attributeBin.definingRenderingAttributes,
1341:                        texUnitState);
1342:                r.isOpaqueOrInOG = r.isOpaque() || r.inOrderedGroup;
1343:                if (r.isOpaqueOrInOG) {
1344:                    startList = opaqueRMList;
1345:                    renderMoleculeMap = opaqueRenderMoleculeMap;
1346:                    markDlistAsDirty(r);
1347:                } else {
1348:                    startList = transparentRMList;
1349:                    renderMoleculeMap = transparentRenderMoleculeMap;
1350:                    if ((r.primaryMoleculeType & RenderMolecule.DLIST_MOLECULE) != 0
1351:                            && renderBin.transpSortMode != View.TRANSPARENCY_SORT_NONE) {
1352:                        renderBin.addDisplayListResourceFreeList(r);
1353:                        renderBin.removeDirtyRenderMolecule(r);
1354:
1355:                        r.vwcBounds.set(null);
1356:                        r.displayListId = 0;
1357:                        r.displayListIdObj = null;
1358:                        // Change the group type for all the rlistInfo in the primaryList
1359:                        RenderAtomListInfo rinfo = r.primaryRenderAtomList;
1360:                        while (rinfo != null) {
1361:                            rinfo.groupType = RenderAtom.SEPARATE_DLIST_PER_RINFO;
1362:                            if (rinfo.renderAtom.dlistIds == null) {
1363:                                rinfo.renderAtom.dlistIds = new int[rinfo.renderAtom.rListInfo.length];
1364:
1365:                                for (int k = 0; k < rinfo.renderAtom.dlistIds.length; k++) {
1366:                                    rinfo.renderAtom.dlistIds[k] = -1;
1367:                                }
1368:                            }
1369:                            if (rinfo.renderAtom.dlistIds[rinfo.index] == -1) {
1370:                                rinfo.renderAtom.dlistIds[rinfo.index] = VirtualUniverse.mc
1371:                                        .getDisplayListId().intValue();
1372:                                renderBin.addDlistPerRinfo.add(rinfo);
1373:                            }
1374:                            rinfo = rinfo.next;
1375:                        }
1376:                        r.primaryMoleculeType = RenderMolecule.SEPARATE_DLIST_PER_RINFO_MOLECULE;
1377:                    } else {
1378:                        markDlistAsDirty(r);
1379:                    }
1380:
1381:                }
1382:                renderMoleculeList = (RenderMolecule) renderMoleculeMap
1383:                        .get(r.localToVworld);
1384:
1385:                if (renderMoleculeList == null) {
1386:                    renderMoleculeList = r;
1387:                    renderMoleculeMap.put(r.localToVworld, renderMoleculeList);
1388:                    // Add this renderMolecule at the beginning of RM list
1389:                    if (startList == null) {
1390:                        startList = r;
1391:                        r.nextMap = null;
1392:                        r.prevMap = null;
1393:                    } else {
1394:                        r.nextMap = startList;
1395:                        startList.prevMap = r;
1396:                        startList = r;
1397:                        startList.nextMap.checkEquivalenceWithLeftNeighbor(r,
1398:                                RenderMolecule.ALL_DIRTY_BITS);
1399:                    }
1400:                    // Issue 67 : since we are adding the new RM at the head, we must
1401:                    // set all dirty bits unconditionally
1402:                    startList.dirtyAttrsAcrossRms = RenderMolecule.ALL_DIRTY_BITS;
1403:                } else {
1404:                    // Insert the renderMolecule next to a RM that has equivalent 
1405:                    // texture unit state
1406:                    if ((head = insertRenderMolecule(r, renderMoleculeList)) != null) {
1407:                        if (renderMoleculeList.prevMap != null) {
1408:                            renderMoleculeList.prevMap.nextMap = head;
1409:                        }
1410:                        head.prevMap = renderMoleculeList.prevMap;
1411:                        renderMoleculeList.prevMap = null;
1412:                        renderMoleculeList = head;
1413:                        renderMoleculeMap.put(r.localToVworld,
1414:                                renderMoleculeList);
1415:                        if (renderMoleculeList.prevMap != null) {
1416:                            renderMoleculeList
1417:                                    .checkEquivalenceWithLeftNeighbor(
1418:                                            renderMoleculeList.prevMap,
1419:                                            RenderMolecule.ALL_DIRTY_BITS);
1420:                        } else {
1421:                            startList.dirtyAttrsAcrossRms = RenderMolecule.ALL_DIRTY_BITS;
1422:                            startList = renderMoleculeList;
1423:                        }
1424:                    }
1425:
1426:                }
1427:                if (r.isOpaqueOrInOG) {
1428:                    opaqueRMList = startList;
1429:                } else {
1430:                    // If transparent and not in bg geometry and inodepth sorted transparency
1431:                    if (transparentRMList == null
1432:                            && (renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE || environmentSet.lightBin.geometryBackground != null)) {
1433:                        transparentRMList = startList;
1434:                        renderBin.addTransparentObject(this );
1435:                    } else {
1436:                        transparentRMList = startList;
1437:                    }
1438:                    // Issue 129: add the RM's render atoms to the list of
1439:                    // transparent render atoms
1440:                    // XXXX: do we need to resort the list after the add???
1441:                    if ((renderBin.transpSortMode == View.TRANSPARENCY_SORT_GEOMETRY)
1442:                            && (environmentSet.lightBin.geometryBackground == null)) {
1443:                        r.addRemoveTransparentObject(renderBin, true);
1444:                    }
1445:                }
1446:            }
1447:
1448:            RenderMolecule removeOneRM(RenderMolecule r, HashMap allMap,
1449:                    RenderMolecule list) {
1450:                RenderMolecule rmlist = list;
1451:                // In the middle, just remove and update
1452:                if (r.prev != null && r.next != null) {
1453:                    r.prev.next = r.next;
1454:                    r.next.prev = r.prev;
1455:                    r.next.checkEquivalenceWithLeftNeighbor(r.prev,
1456:                            RenderMolecule.ALL_DIRTY_BITS);
1457:                }
1458:                // If whats is removed is at the end of an entry
1459:                else if (r.prev != null && r.next == null) {
1460:                    r.prev.next = r.next;
1461:                    r.prev.nextMap = r.nextMap;
1462:                    if (r.nextMap != null) {
1463:                        r.nextMap.prevMap = r.prev;
1464:                        r.nextMap.checkEquivalenceWithLeftNeighbor(r.prev,
1465:                                RenderMolecule.ALL_DIRTY_BITS);
1466:                    }
1467:                } else if (r.prev == null && r.next != null) {
1468:                    r.next.prev = null;
1469:                    r.next.prevMap = r.prevMap;
1470:                    if (r.prevMap != null) {
1471:                        r.prevMap.nextMap = r.next;
1472:                        r.next.checkEquivalenceWithLeftNeighbor(r.prevMap,
1473:                                RenderMolecule.ALL_DIRTY_BITS);
1474:                    }
1475:                    // Head of the rmList
1476:                    else {
1477:                        rmlist = r.next;
1478:                        rmlist.dirtyAttrsAcrossRms = RenderMolecule.ALL_DIRTY_BITS;
1479:                    }
1480:                    allMap.put(r.localToVworld, r.next);
1481:                }
1482:                // Update the maps and remove this entry from the map list
1483:                else if (r.prev == null && r.next == null) {
1484:                    if (r.prevMap != null) {
1485:                        r.prevMap.nextMap = r.nextMap;
1486:
1487:                    } else {
1488:                        rmlist = r.nextMap;
1489:                        if (r.nextMap != null) {
1490:                            rmlist.dirtyAttrsAcrossRms = RenderMolecule.ALL_DIRTY_BITS;
1491:                        }
1492:                    }
1493:                    if (r.nextMap != null) {
1494:                        r.nextMap.prevMap = r.prevMap;
1495:                        if (r.prevMap != null) {
1496:                            r.nextMap.checkEquivalenceWithLeftNeighbor(
1497:                                    r.prevMap, RenderMolecule.ALL_DIRTY_BITS);
1498:                        }
1499:
1500:                    }
1501:
1502:                    allMap.remove(r.localToVworld);
1503:
1504:                }
1505:                r.prev = null;
1506:                r.next = null;
1507:                r.prevMap = null;
1508:                r.nextMap = null;
1509:                return rmlist;
1510:            }
1511:
1512:            void markDlistAsDirty(RenderMolecule r) {
1513:
1514:                if (r.primaryMoleculeType == RenderMolecule.DLIST_MOLECULE) {
1515:                    renderBin.addDirtyRenderMolecule(r);
1516:                } else if (r.primaryMoleculeType == RenderMolecule.SEPARATE_DLIST_PER_RINFO_MOLECULE) {
1517:                    RenderAtomListInfo ra = r.primaryRenderAtomList;
1518:                    while (ra != null) {
1519:                        renderBin.addDlistPerRinfo.add(ra);
1520:                        ra = ra.next;
1521:                    }
1522:                }
1523:            }
1524:
1525:            void decrActiveRenderMolecule() {
1526:                numEditingRenderMolecules--;
1527:
1528:                if (numEditingRenderMolecules == 0) {
1529:
1530:                    // if number of editing renderMolecules goes to 0,
1531:                    // inform the shaderBin that this textureBin goes to
1532:                    // zombie state
1533:
1534:                    shaderBin.decrActiveTextureBin();
1535:                }
1536:            }
1537:
1538:            void incrActiveRenderMolecule() {
1539:
1540:                if (numEditingRenderMolecules == 0) {
1541:
1542:                    // if this textureBin is in zombie state, inform
1543:                    // the shaderBin that this textureBin is activated again.
1544:
1545:                    shaderBin.incrActiveTextureBin();
1546:                }
1547:
1548:                numEditingRenderMolecules++;
1549:            }
1550:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.