diff options
Diffstat (limited to 'src/javax/media/j3d/AttributeBin.java')
-rw-r--r-- | src/javax/media/j3d/AttributeBin.java | 418 |
1 files changed, 418 insertions, 0 deletions
diff --git a/src/javax/media/j3d/AttributeBin.java b/src/javax/media/j3d/AttributeBin.java new file mode 100644 index 0000000..95ce52a --- /dev/null +++ b/src/javax/media/j3d/AttributeBin.java @@ -0,0 +1,418 @@ +/* + * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +package javax.media.j3d; + +import java.util.ArrayList; + +/** + * The AttributeBin manages a collection of TextureBin objects. + * All objects in the AttributeBin share the same RenderingAttributes + */ + +class AttributeBin extends Object implements ObjectUpdate { + + /** + * The RenderingAttributes for this AttributeBin + */ + RenderingAttributesRetained definingRenderingAttributes = null; + + /** + * The RenderBin for this object + */ + RenderBin renderBin = null; + + /** + * The EnvirionmentSet that this AttributeBin resides + */ + EnvironmentSet environmentSet = null; + + /** + * The references to the next and previous AttributeBins in the + * list. + */ + AttributeBin next = null; + AttributeBin prev = null; + + /** + * The list of ShaderBins in this AttributeBin + */ + ShaderBin shaderBinList = null; + +/** + * List of shaderBins to be added next frame + */ +ArrayList<ShaderBin> addShaderBins = new ArrayList<ShaderBin>(); + + /** + * If the RenderingAttribute component of the appearance will be changed + * frequently, then confine it to a separate bin + */ + boolean soleUser = false; + AppearanceRetained app = null; + + int onUpdateList = 0; + static int ON_OBJ_UPDATE_LIST = 0x1; + static int ON_CHANGED_FREQUENT_UPDATE_LIST = 0x2; + + // Cache it outside, to avoid the "if" check in renderMethod + // for whether the definingRendering attrs is non-null; + boolean ignoreVertexColors = false; + + // XXXX: use definingMaterial etc. instead of these + // when sole user is completely implement + RenderingAttributesRetained renderingAttrs; + + int numEditingShaderBins = 0; + + AttributeBin(AppearanceRetained app, RenderingAttributesRetained renderingAttributes, RenderBin rBin) { + + reset(app, renderingAttributes, rBin); + } + + void reset(AppearanceRetained app, RenderingAttributesRetained renderingAttributes, RenderBin rBin) { + prev = null; + next = null; + shaderBinList = null; + onUpdateList = 0; + numEditingShaderBins = 0; + renderingAttrs = renderingAttributes; + + renderBin = rBin; + + // Issue 249 - check for sole user only if property is set + soleUser = false; + if (VirtualUniverse.mc.allowSoleUser) { + if (app != null) { + soleUser = ((app.changedFrequent & AppearanceRetained.RENDERING) != 0); + } + } + + //System.err.println("soleUser = "+soleUser+" renderingAttributes ="+renderingAttributes); + // Set the appearance only for soleUser case + if (soleUser) + this.app = app; + else + app = null; + + if (renderingAttributes != null) { + if (renderingAttributes.changedFrequent != 0) { + definingRenderingAttributes = renderingAttributes; + if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0 ) { + renderBin.aBinUpdateList.add(this); + onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST; + } + } + else { + if (definingRenderingAttributes != null) { + definingRenderingAttributes.set(renderingAttributes); + } + else { + definingRenderingAttributes = (RenderingAttributesRetained)renderingAttributes.clone(); + } + } + ignoreVertexColors = definingRenderingAttributes.ignoreVertexColors; + } else { + definingRenderingAttributes = null; + ignoreVertexColors = false; + } + } + + + /** + * This tests if the given attributes match this AttributeBin + */ + boolean equals(RenderingAttributesRetained renderingAttributes, RenderAtom ra) { + + // If the any reference to the appearance components that is cached renderMolecule + // can change frequently, make a separate bin + if (soleUser || (ra.geometryAtom.source.appearance != null && + ((ra.geometryAtom.source.appearance.changedFrequent & + AppearanceRetained.RENDERING) != 0))) { + if (app == ra.geometryAtom.source.appearance) { + + // if this AttributeBin is currently on a zombie state, + // we'll need to put it on the update list to reevaluate + // the state, because while it is on a zombie state, + // rendering attributes reference could have been changed. + // Example, application could have detached an appearance, + // made changes to the reference, and then + // reattached the appearance. In this case, the rendering + // attributes reference change would not have reflected to + // the AttributeBin + + if (numEditingShaderBins == 0) { + if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0) { + renderBin.aBinUpdateList.add(this); + onUpdateList |= + AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST; + } + } + return true; + } + else { + return false; + } + + } + // Either a changedFrequent or a null case + // and the incoming one is not equal or null + // then return; + // This check also handles null == null case + if (definingRenderingAttributes != null) { + if ((this.definingRenderingAttributes.changedFrequent != 0) || + (renderingAttributes !=null && renderingAttributes.changedFrequent != 0)) + if (definingRenderingAttributes == renderingAttributes) { + if (definingRenderingAttributes.compChanged != 0) { + if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0 ) { + renderBin.aBinUpdateList.add(this); + onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST; + } + } + } + else { + return false; + } + else if (!definingRenderingAttributes.equivalent(renderingAttributes)) { + return false; + } + } + else if (renderingAttributes != null) { + return false; + } + + return (true); + } + + @Override + public void updateObject() { + ShaderBin sb; + int i, size; + + size = addShaderBins.size(); + if (size > 0) { + sb = addShaderBins.get(0); + if (shaderBinList == null) { + shaderBinList = sb; + } + else { + sb.next = shaderBinList; + shaderBinList.prev = sb; + shaderBinList = sb; + } + + for (i = 1; i < size ; i++) { + sb = addShaderBins.get(i); + sb.next = shaderBinList; + shaderBinList.prev = sb; + shaderBinList = sb; + } + } + addShaderBins.clear(); + onUpdateList &= ~ON_OBJ_UPDATE_LIST; + } + + + /** + * Adds the given shaderBin to this AttributeBin. + */ + void addShaderBin(ShaderBin sb, RenderBin rb, ShaderAppearanceRetained sApp) { + + sb.attributeBin = this; + + if(sApp != null) { + // ShaderBin should reference to the mirror components. -- JADA. + // System.err.println("AttributeBin : sApp.isMirror = " + sApp.isMirror); + assert(sApp.isMirror); + sb.shaderProgram = sApp.shaderProgram; + sb.shaderAttributeSet = sApp.shaderAttributeSet; + } + sb.shaderAppearance = sApp; + + // TODO : JADA - sort by ShaderProgram to avoid state trashing. + addShaderBins.add(sb); + if ((onUpdateList & ON_OBJ_UPDATE_LIST) == 0) { + onUpdateList |= ON_OBJ_UPDATE_LIST; + rb.objUpdateList.add(this); + } + + } + + + /** + * Removes the given shaderBin from this AttributeBin. + */ + void removeShaderBin(ShaderBin sb) { + + // If the shaderBin being remove is contained in addShaderBins, + // then remove the shadereBin from the addList + if (addShaderBins.contains(sb)) { + addShaderBins.remove(addShaderBins.indexOf(sb)); + } + else { + if (sb.prev == null) { // At the head of the list + shaderBinList = sb.next; + if (sb.next != null) { + sb.next.prev = null; + } + } else { // In the middle or at the end. + sb.prev.next = sb.next; + if (sb.next != null) { + sb.next.prev = sb.prev; + } + } + } + + sb.clear(); + + if (shaderBinList == null && addShaderBins.size() == 0 ) { + // Note: Removal of this attributebin as a user of the rendering + // atttrs is done during removeRenderAtom() in RenderMolecule.java + environmentSet.removeAttributeBin(this); + } + } + + /** + * Renders this AttributeBin + */ + void render(Canvas3D cv) { + + ShaderBin sb; + + boolean visible = (definingRenderingAttributes == null || + definingRenderingAttributes.visible); + + if ( (renderBin.view.viewCache.visibilityPolicy + == View.VISIBILITY_DRAW_VISIBLE && !visible) || + (renderBin.view.viewCache.visibilityPolicy + == View.VISIBILITY_DRAW_INVISIBLE && visible)) { + return; + } + + + // include this AttributeBin to the to-be-updated list in Canvas + cv.setStateToUpdate(Canvas3D.ATTRIBUTEBIN_BIT, this); + + sb = shaderBinList; + while (sb != null) { + sb.render(cv); + sb = sb.next; + } + } + + + void updateAttributes(Canvas3D cv) { + + if ((cv.canvasDirty & Canvas3D.ATTRIBUTEBIN_DIRTY) != 0) { + // Update Attribute Bundles + if (definingRenderingAttributes == null) { + cv.resetRenderingAttributes(cv.ctx, + cv.depthBufferWriteEnableOverride, + cv.depthBufferEnableOverride); + } else { + definingRenderingAttributes.updateNative( + cv, + cv.depthBufferWriteEnableOverride, + cv.depthBufferEnableOverride); + } + cv.renderingAttrs = renderingAttrs; + } + + else if (cv.renderingAttrs != renderingAttrs && + cv.attributeBin != this) { + // Update Attribute Bundles + if (definingRenderingAttributes == null) { + cv.resetRenderingAttributes( + cv.ctx, + cv.depthBufferWriteEnableOverride, + cv.depthBufferEnableOverride); + } else { + definingRenderingAttributes.updateNative( + cv, + cv.depthBufferWriteEnableOverride, + cv.depthBufferEnableOverride); + } + cv.renderingAttrs = renderingAttrs; + } + cv.attributeBin = this; + cv.canvasDirty &= ~Canvas3D.ATTRIBUTEBIN_DIRTY; + } + + void updateNodeComponent() { + // May be in the freelist already (due to freq bit changing) + // if so, don't update anything + if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) != 0) { + if (soleUser) { + boolean cloned = definingRenderingAttributes != null && definingRenderingAttributes != renderingAttrs; + renderingAttrs = app.renderingAttributes; + + if (renderingAttrs == null) { + definingRenderingAttributes = null; + ignoreVertexColors = false; + } + else { + if (renderingAttrs.changedFrequent != 0) { + definingRenderingAttributes = renderingAttrs; + } + else { + if (cloned) { + definingRenderingAttributes.set(renderingAttrs); + } + else { + definingRenderingAttributes = (RenderingAttributesRetained)renderingAttrs.clone(); + } + } + ignoreVertexColors = definingRenderingAttributes.ignoreVertexColors; + } + } + else { + ignoreVertexColors = definingRenderingAttributes.ignoreVertexColors; + } + } + + onUpdateList &= ~ON_CHANGED_FREQUENT_UPDATE_LIST; + } + + void incrActiveShaderBin() { + numEditingShaderBins++; + } + + void decrActiveShaderBin() { + numEditingShaderBins--; + } + + void updateFromShaderBin(RenderAtom ra) { + + AppearanceRetained raApp = ra.geometryAtom.source.appearance; + RenderingAttributesRetained rAttrs = + (raApp == null)? null : raApp.renderingAttributes; + + if (!soleUser && renderingAttrs != rAttrs) { + // no longer sole user + renderingAttrs = definingRenderingAttributes; + } + } +} |