📄 texturebin.java
字号:
/* * $RCSfile: TextureBin.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.9 $ * $Date: 2007/04/12 17:34:07 $ * $State: Exp $ */package javax.media.j3d;import javax.vecmath.*;import java.util.*;/** * The TextureBin manages a collection of TextureSetting objects. * All objects in the TextureBin share the same Texture reference. *///class TextureBin extends Object implements ObjectUpdate, NodeComponentUpdate {class TextureBin extends Object implements ObjectUpdate { TextureUnitStateRetained [] texUnitState = null; // last active texture unit private int lastActiveTexUnitIndex; // number of active texture unit private int numActiveTexUnit; /** * The RenderBin for this object */ RenderBin renderBin = null; /** * The EnvironmentSet that this TextureBin resides */ EnvironmentSet environmentSet = null; /** * The AttributeBin that this TextureBin resides */ AttributeBin attributeBin = null; /** * The ShaderBin that this TextureBin resides */ ShaderBin shaderBin = null; /** * The references to the next and previous TextureBins in the * list. */ TextureBin next = null; TextureBin prev = null; /** * Oring of the equivalence bits for all appearance attrs under * this renderBin */ int equivalent = 0; /** * If any of the texture reference in an appearance is frequently * changable, then a separate TextureBin will be created for this * appearance, and this TextureBin is marked as the sole user of * this appearance, and app will be pointing to the appearance * being referenced by this TextureBin. Otherwise, app is null */ AppearanceRetained app = null; /** * Sole user node component dirty mask. The first bit is reserved * for node component reference dirty bit. It is set if any of the * texture related node component reference in the appearance is * being modified. The second bit onwords are for the individual * TextureUnitState dirty bit. The ith bit set means the (i-1) * texture unit state is modified. Note, this mask only supports * 30 texture unit states. If the appearance uses more than 31 * texture unit states, then the modification of the 32nd texture * unit state and up will have the first bit set, that means * the TextureBin will be reset, rather than only the particular * texture unit state will be reset. */ int soleUserCompDirty; static final int SOLE_USER_DIRTY_REF = 0x1; static final int SOLE_USER_DIRTY_TA = 0x2; static final int SOLE_USER_DIRTY_TC = 0x4; static final int SOLE_USER_DIRTY_TEXTURE = 0x8; static final int SOLE_USER_DIRTY_TUS = 0x10; /** * The hashMap of RenderMolecules in this TextureBin * this is used in rendering, the key used is localToVworld */ HashMap addOpaqueRMs = new HashMap(); HashMap addTransparentRMs = new HashMap(); // A hashmap based on localToVworld for fast // insertion of new renderMolecules HashMap opaqueRenderMoleculeMap = new HashMap(); HashMap transparentRenderMoleculeMap = new HashMap(); // List of renderMolecules - used in rendering .. RenderMolecule opaqueRMList = null; RenderMolecule transparentRMList = null; TransparentRenderingInfo parentTInfo; int numRenderMolecules = 0; int numEditingRenderMolecules = 0; int tbFlag = 0; // a general bitmask for TextureBin // Following are the bits used in flag final static int ON_RENDER_BIN_LIST = 0x0001; final static int ON_UPDATE_LIST = 0x0002; final static int SOLE_USER = 0x0004; final static int CONTIGUOUS_ACTIVE_UNITS = 0x0008; final static int RESORT = 0x0010; final static int ON_UPDATE_CHECK_LIST = 0x0020; final static int USE_DISPLAYLIST = -2; final static int USE_VERTEXARRAY = -1; TextureBin(TextureUnitStateRetained[] state, AppearanceRetained app, RenderBin rb) { renderBin = rb; tbFlag = 0; reset(state, app); } /** * For now, clone everything just like the other NodeComponent */ void reset(TextureUnitStateRetained[] state, AppearanceRetained app) { prev = null; next = null; opaqueRMList = null; transparentRMList = null; numEditingRenderMolecules = 0; // Issue 249 - check for sole user only if property is set // determine if this appearance is a sole user of this // TextureBin tbFlag &= ~TextureBin.SOLE_USER; if (VirtualUniverse.mc.allowSoleUser) { if ((app != null) && (app.changedFrequent & (AppearanceRetained.TEXTURE | AppearanceRetained.TEXCOORD_GEN | AppearanceRetained.TEXTURE_ATTR | AppearanceRetained.TEXTURE_UNIT_STATE)) != 0) { tbFlag |= TextureBin.SOLE_USER; } } if ((tbFlag & TextureBin.SOLE_USER) != 0) { this.app = app; } else { this.app = null; } resetTextureState(state); if ((tbFlag & TextureBin.ON_RENDER_BIN_LIST) == 0) { renderBin.addTextureBin(this); tbFlag |= TextureBin.ON_RENDER_BIN_LIST; } } void resetTextureState(TextureUnitStateRetained[] state) { int i, j; boolean foundDisableUnit = false; numActiveTexUnit = 0; lastActiveTexUnitIndex = 0; boolean soleUser = ((tbFlag & TextureBin.SOLE_USER) != 0); TextureRetained prevFirstTexture = null; TextureRetained tex; tbFlag |= TextureBin.CONTIGUOUS_ACTIVE_UNITS; if (state != null) { foundDisableUnit = false; if (texUnitState == null || (texUnitState.length != state.length)) { texUnitState = new TextureUnitStateRetained[state.length]; } else if (texUnitState.length > 0 && texUnitState[0] != null) { prevFirstTexture = texUnitState[0].texture; } for (i = 0; i < state.length; i++) { if (state[i] == null) { texUnitState[i] = null; foundDisableUnit = true; } else { // create a clone texture unit state if (texUnitState[i] == null) { texUnitState[i] = new TextureUnitStateRetained(); } // for sole user TextureUnitState, save // the node component reference in the mirror reference // of the cloned copy for equal test, and // for native download optimization if (soleUser || state[i].changedFrequent != 0) { texUnitState[i].mirror = state[i]; } // for the lowest level of node component in // TextureBin, clone it only if it is not // changedFrequent; in other words, if the // lowest level of texture related node components // such as TextureAttributes & TexCoordGen is // changedFrequent, have the cloned texUnitState // reference the mirror of those node components // directly. For Texture, we'll always reference // the mirror. // decrement the TextureBin ref count of the previous // texture tex = texUnitState[i].texture; if (tex != null) { tex.decTextureBinRefCount(this); if (soleUser && (tex.getTextureBinRefCount(this) == 0) && (tex != state[i].texture)) { // In this case texture change but // TextureBin will not invoke clear() to reset. // So we need to free the texture resource here. renderBin.addTextureResourceFreeList(tex); } } texUnitState[i].texture = state[i].texture; // increment the TextureBin ref count of the new // texture if (texUnitState[i].texture != null) { texUnitState[i].texture.incTextureBinRefCount(this); } if (state[i].texAttrs != null) { if (state[i].texAttrs.changedFrequent != 0) { texUnitState[i].texAttrs = state[i].texAttrs; } else { // need to check for texAttrs.source because // texAttrs could be pointing to the mirror // in the last frame, so don't want to // overwrite the mirror if (texUnitState[i].texAttrs == null || texUnitState[i].texAttrs.source != null) { texUnitState[i].texAttrs = new TextureAttributesRetained(); } texUnitState[i].texAttrs.set( state[i].texAttrs); texUnitState[i].texAttrs.mirrorCompDirty = true; // for sole user TextureBin, we are saving // the mirror node component in the mirror // reference in the clone object. This // will be used in state download to // avoid redundant download if (soleUser) { texUnitState[i].texAttrs.mirror = state[i].texAttrs; } else { texUnitState[i].texAttrs.mirror = null; } } } else { texUnitState[i].texAttrs = null; } if (state[i].texGen != null) { if (state[i].texGen.changedFrequent != 0) { texUnitState[i].texGen = state[i].texGen; } else { // need to check for texGen.source because // texGen could be pointing to the mirror // in the last frame, so don't want to // overwrite the mirror if (texUnitState[i].texGen == null || texUnitState[i].texGen.source != null) { texUnitState[i].texGen = new TexCoordGenerationRetained(); } texUnitState[i].texGen.set(state[i].texGen); texUnitState[i].texGen.mirrorCompDirty = true; // for sole user TextureBin, we are saving // the mirror node component in the mirror // reference in the clone object. This // will be used in state download to // avoid redundant download if (soleUser) { texUnitState[i].texGen.mirror = state[i].texGen; } else { texUnitState[i].texGen.mirror = null; } } } else { texUnitState[i].texGen = null; } // Track the last active texture unit and the total number // of active texture units. Note that this total number // now includes disabled units so that there is always // a one-to-one mapping. We no longer remap texture units. if (texUnitState[i].isTextureEnabled()) { lastActiveTexUnitIndex = i; numActiveTexUnit = i + 1; if (foundDisableUnit) { // mark that active texture units are not // contiguous tbFlag &= ~TextureBin.CONTIGUOUS_ACTIVE_UNITS; } } else { foundDisableUnit = true; } } } // check to see if the TextureBin sorting criteria is // modified for this textureBin; if yes, mark that // resorting is needed if ((texUnitState[0] == null && prevFirstTexture != null) || (texUnitState[0] != null && texUnitState[0].texture != prevFirstTexture)) { tbFlag |= TextureBin.RESORT; } } else { // check to see if the TextureBin sorting criteria is // modified for this textureBin; if yes, mark that // resorting is needed if (texUnitState != null && texUnitState[0].texture != null) { tbFlag |= TextureBin.RESORT; } texUnitState = null; } soleUserCompDirty = 0; } /** * The TextureBin is to be removed from RenderBin, * do the proper unsetting of any references */ void clear() { // make sure there is no reference to the scenegraph app = null; // for each texture referenced in the texture units, decrement // the reference count. If the reference count == 0, tell // the renderer to free up the resource
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -