📄 texturebin.java
字号:
} tbFlag &= ~TextureBin.ON_UPDATE_LIST; } /** * Each list of renderMoledule with the same localToVworld * is connect by rm.next and rm.prev. * At the end of the list (i.e. rm.next = null) the field * rm.nextMap is link to another list (with the same * localToVworld). So during rendering it will traverse * rm.next until this is null, then follow the .nextMap * to access another list and use rm.next to continue * until both rm.next and rm.nextMap are null. * * renderMoleculeMap is use to assist faster location of * renderMolecule List with the same localToVWorld. The * start of renderMolecule in the list with same * localToVworld is insert in renderMoleculeMap. This * map is clean up at removeRenderMolecule(). TextureBin * also use the map for quick location of renderMolecule * with the same localToVworld and attributes in * findRenderMolecule(). */ RenderMolecule addAll(HashMap renderMoleculeMap, HashMap addRMs, RenderMolecule startList, boolean opaqueList) { int i; RenderMolecule r; Collection c = addRMs.values(); Iterator listIterator = c.iterator(); RenderMolecule renderMoleculeList, head; while (listIterator.hasNext()) { boolean changed = false; ArrayList curList = (ArrayList)listIterator.next(); r = (RenderMolecule)curList.get(0); // If this is a opaque one , but has been switched to a transparentList or // vice-versa (dur to changeLists function called before this), then // do nothing! // For changedFrequent case: Consider the case when a RM is added // (so is in the addRM list) and then // a change in transparent value occurs that make it from opaque to // transparent (the switch is handled before this function is called) if (r.isOpaqueOrInOG != opaqueList) { continue; } // Get the list of renderMolecules for this transform renderMoleculeList = (RenderMolecule)renderMoleculeMap.get( r.localToVworld); if (renderMoleculeList == null) { renderMoleculeList = r; renderMoleculeMap.put(r.localToVworld, renderMoleculeList); // Add this renderMolecule at the beginning of RM list if (startList == null) { startList = r; r.nextMap = null; r.prevMap = null; startList.dirtyAttrsAcrossRms = RenderMolecule.ALL_DIRTY_BITS; } else { r.nextMap = startList; startList.prevMap = r; startList = r; startList.nextMap.checkEquivalenceWithLeftNeighbor(r, RenderMolecule.ALL_DIRTY_BITS); } } else { // Insert the renderMolecule next to a RM that has equivalent // texture unit state if ((head = insertRenderMolecule(r, renderMoleculeList)) != null) { if (renderMoleculeList.prevMap != null) { renderMoleculeList.prevMap.nextMap = head; } head.prevMap = renderMoleculeList.prevMap; renderMoleculeList.prevMap = null; renderMoleculeList = head; changed = true; } } for (i = 1; i < curList.size(); i++) { r = (RenderMolecule)curList.get(i); // If this is a opaque one , but has been switched to a transparentList or // vice-versa (dur to changeLists function called before this), then // do nothing! // For changedFrequent case: Consider the case when a RM is added // (so is in the addRM list) and then // a change in transparent value occurs that make it from opaque to // transparent (the switch is handled before this function is called) if (r.isOpaqueOrInOG != opaqueList) continue; if ((head = insertRenderMolecule(r, renderMoleculeList)) != null) { if (renderMoleculeList.prevMap != null) { renderMoleculeList.prevMap.nextMap = head; } head.prevMap = renderMoleculeList.prevMap; renderMoleculeList.prevMap = null; renderMoleculeList = head; changed = true; } } if (changed) { renderMoleculeMap.put(r.localToVworld, renderMoleculeList); if (renderMoleculeList.prevMap != null) { renderMoleculeList.checkEquivalenceWithLeftNeighbor( renderMoleculeList.prevMap, RenderMolecule.ALL_DIRTY_BITS); } else { startList = renderMoleculeList; startList.dirtyAttrsAcrossRms = RenderMolecule.ALL_DIRTY_BITS; } } } addRMs.clear(); return startList; } // XXXX: Could the analysis be done during insertRenderMolecule? // Return the head of the list, // if the insertion occurred at beginning of the list RenderMolecule insertRenderMolecule(RenderMolecule r, RenderMolecule renderMoleculeList) { RenderMolecule rm, retval; // Look for a RM that has an equivalent material rm = renderMoleculeList; while (rm != null) { if (rm.material == r.material || (rm.definingMaterial != null && rm.definingMaterial.equivalent(r.definingMaterial))) { // Put it here r.next = rm; r.prev = rm.prev; if (rm.prev == null) { renderMoleculeList = r; retval = renderMoleculeList; } else { rm.prev.next = r; retval = null; } rm.prev = r; r.checkEquivalenceWithBothNeighbors(RenderMolecule.ALL_DIRTY_BITS); return retval; } // If they are not equivalent, then skip to the first one // that has a different material using the dirty bits else { rm = rm.next; while (rm != null && ((rm.dirtyAttrsAcrossRms & RenderMolecule.MATERIAL_DIRTY) == 0)) { rm = rm.next; } } } // Just put it up front r.next = renderMoleculeList; renderMoleculeList.prev = r; renderMoleculeList = r; r.checkEquivalenceWithBothNeighbors(RenderMolecule.ALL_DIRTY_BITS); return renderMoleculeList; } /** * Adds the given RenderMolecule to this TextureBin */ void addRenderMolecule(RenderMolecule r, RenderBin rb) { RenderMolecule rm; ArrayList list; HashMap map; r.textureBin = this; if (r.isOpaqueOrInOG) map = addOpaqueRMs; else map = addTransparentRMs; if ((list = (ArrayList)map.get(r.localToVworld)) == null) { list = new ArrayList(); map.put(r.localToVworld, list); } list.add(r); if ((tbFlag & TextureBin.ON_UPDATE_LIST) == 0) { tbFlag |= TextureBin.ON_UPDATE_LIST; rb.objUpdateList.add(this); } } /** * Removes the given RenderMolecule from this TextureBin */ void removeRenderMolecule(RenderMolecule r) { ArrayList list; int index; boolean found = false; RenderMolecule renderMoleculeList, rmlist; HashMap addMap; HashMap allMap; r.textureBin = null; if (r.isOpaqueOrInOG) { rmlist = opaqueRMList; allMap = opaqueRenderMoleculeMap; addMap = addOpaqueRMs; } else { rmlist = transparentRMList; allMap = transparentRenderMoleculeMap; addMap = addTransparentRMs; } // If the renderMolecule being remove is contained in addRMs, then // remove the renderMolecule from the addList if ((list = (ArrayList) addMap.get(r.localToVworld)) != null) { if ((index = list.indexOf(r)) != -1) { list.remove(index); // If this was the last element for this localToVworld, then remove // the entry from the addRMs list if (list.isEmpty()) { addMap.remove(r.localToVworld); } r.prev = null; r.next = null; found = true; } } if (!found) { RenderMolecule head = removeOneRM(r, allMap, rmlist); r.soleUserCompDirty = 0; r.onUpdateList = 0; if (r.definingPolygonAttributes != null && (r.definingPolygonAttributes.changedFrequent != 0)) r.definingPolygonAttributes = null; if (r.definingLineAttributes != null && (r.definingLineAttributes.changedFrequent != 0)) r.definingLineAttributes = null; if (r.definingPointAttributes != null && (r.definingPointAttributes.changedFrequent != 0)) r.definingPointAttributes = null; if (r.definingMaterial != null && (r.definingMaterial.changedFrequent != 0)) r.definingMaterial = null; if (r.definingColoringAttributes != null && (r.definingColoringAttributes.changedFrequent != 0)) r.definingColoringAttributes = null; if (r.definingTransparency != null && (r.definingTransparency.changedFrequent != 0)) r.definingTransparency = null; renderBin.removeRenderMolecule(r); if (r.isOpaqueOrInOG) { opaqueRMList = head; } else { transparentRMList = head; } } // If the renderMolecule removed is not opaque then .. if (!r.isOpaqueOrInOG && transparentRMList == null && (renderBin.transpSortMode == View.TRANSPARENCY_SORT_NONE || environmentSet.lightBin.geometryBackground != null)) { renderBin.removeTransparentObject(this); } // If the rm removed is the one that is referenced in the tinfo // then change this reference else if (parentTInfo != null && parentTInfo.rm == r) { parentTInfo.rm = transparentRMList; } // Removal of this texture setting from the texCoordGenartion // is done during the removeRenderAtom routine in RenderMolecule.java // Only remove this texture bin if there are no more renderMolcules // waiting to be added if (opaqueRenderMoleculeMap.isEmpty() && addOpaqueRMs.isEmpty() && transparentRenderMoleculeMap.isEmpty() && addTransparentRMs.isEmpty()) { if ((tbFlag & TextureBin.ON_RENDER_BIN_LIST) != 0) { tbFlag &= ~TextureBin.ON_RENDER_BIN_LIST; renderBin.removeTextureBin(this); } shaderBin.removeTextureBin(this); texUnitState = null; } } /** * This method is called to update the state for this * TextureBin. This is only applicable in the single-pass case. * Multi-pass render will have to take care of its own * state update. */ void updateAttributes(Canvas3D cv) { boolean dirty = ((cv.canvasDirty & (Canvas3D.TEXTUREBIN_DIRTY| Canvas3D.TEXTUREATTRIBUTES_DIRTY)) != 0); if (cv.textureBin == this && !dirty) { return; } cv.textureBin = this; // save the current number of active texture unit so as // to be able to reset the one that is not enabled in this bin int lastActiveTexUnitIdx = -1; // Get the number of available texture units; this depends on // whether or not shaders are being used. boolean useShaders = (shaderBin.shaderProgram != null); int availableTextureUnits = useShaders ? cv.maxTextureImageUnits : cv.maxTextureUnits; // If the number of active texture units is greater than the number of // supported units, then we // need to set a flag indicating that the texture units are invalid. boolean disableTexture = false; if (numActiveTexUnit > availableTextureUnits) { disableTexture = true;// System.err.println("*** TextureBin : number of texture units exceeded"); } // set the number active texture unit in Canvas3D if (disableTexture) { cv.setNumActiveTexUnit(0); } else { cv.setNumActiveTexUnit(numActiveTexUnit); } // state update if (numActiveTexUnit <= 0 || disableTexture) { if (cv.getLastActiveTexUnit() >= 0) { // no texture units enabled // when the canvas supports multi texture units, // we'll need to reset texture for all texture units if (cv.multiTexAccelerated) { for (int i = 0; i <= cv.getLastActiveTexUnit(); i++) { cv.resetTexture(cv.ctx, i); } // set the active texture unit back to 0 cv.setNumActiveTexUnit(0); cv.activeTextureUnit(cv.ctx, 0); } else { cv.resetTexture(cv.ctx, -1); } cv.setLastActiveTexUnit(-1); } } else { int j = 0; for (int i = 0; i < texUnitState.length; i++) { if (j >= cv.texUnitState.length) { // We finish enabling the texture state. // Note that it is possible // texUnitState.length > cv.texUnitState.length break; } if ((texUnitState[i] != null) && texUnitState[i].isTextureEnabled()) { if (dirty || cv.texUnitState[j].mirror == null || cv.texUnitState[j].mirror != texUnitState[i].mirror) { // update the texture unit state texUnitState[i].updateNative(j, cv, false, false); cv.texUnitState[j].mirror = texUnitState[i].mirror; } // create a mapping that maps an active texture // unit to a texture unit state lastActiveTexUnitIdx = j; } else { if (j <= cv.getLastActiveTexUnit()) { cv.resetTexture(cv.ctx, j);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -