001: /*
002: * $RCSfile: AttributeBin.java,v $
003: *
004: * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.8 $
028: * $Date: 2008/02/28 20:17:19 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.*;
035: import java.util.ArrayList;
036:
037: /**
038: * The AttributeBin manages a collection of TextureBin objects.
039: * All objects in the AttributeBin share the same RenderingAttributes
040: */
041:
042: class AttributeBin extends Object implements ObjectUpdate {
043:
044: /**
045: * The RenderingAttributes for this AttributeBin
046: */
047: RenderingAttributesRetained definingRenderingAttributes = null;
048:
049: /**
050: * The RenderBin for this object
051: */
052: RenderBin renderBin = null;
053:
054: /**
055: * The EnvirionmentSet that this AttributeBin resides
056: */
057: EnvironmentSet environmentSet = null;
058:
059: /**
060: * The references to the next and previous AttributeBins in the
061: * list.
062: */
063: AttributeBin next = null;
064: AttributeBin prev = null;
065:
066: /**
067: * The list of ShaderBins in this AttributeBin
068: */
069: ShaderBin shaderBinList = null;
070:
071: /**
072: * List of shaderBins to be added next frame
073: */
074: ArrayList addShaderBins = new ArrayList();
075:
076: /**
077: * If the RenderingAttribute component of the appearance will be changed
078: * frequently, then confine it to a separate bin
079: */
080: boolean soleUser = false;
081: AppearanceRetained app = null;
082:
083: int onUpdateList = 0;
084: static int ON_OBJ_UPDATE_LIST = 0x1;
085: static int ON_CHANGED_FREQUENT_UPDATE_LIST = 0x2;
086:
087: // Cache it outside, to avoid the "if" check in renderMethod
088: // for whether the definingRendering attrs is non-null;
089: boolean ignoreVertexColors = false;
090:
091: // XXXX: use definingMaterial etc. instead of these
092: // when sole user is completely implement
093: RenderingAttributesRetained renderingAttrs;
094:
095: int numEditingShaderBins = 0;
096:
097: AttributeBin(AppearanceRetained app,
098: RenderingAttributesRetained renderingAttributes,
099: RenderBin rBin) {
100:
101: reset(app, renderingAttributes, rBin);
102: }
103:
104: void reset(AppearanceRetained app,
105: RenderingAttributesRetained renderingAttributes,
106: RenderBin rBin) {
107: prev = null;
108: next = null;
109: shaderBinList = null;
110: onUpdateList = 0;
111: numEditingShaderBins = 0;
112: renderingAttrs = renderingAttributes;
113:
114: renderBin = rBin;
115:
116: // Issue 249 - check for sole user only if property is set
117: soleUser = false;
118: if (VirtualUniverse.mc.allowSoleUser) {
119: if (app != null) {
120: soleUser = ((app.changedFrequent & AppearanceRetained.RENDERING) != 0);
121: }
122: }
123:
124: //System.err.println("soleUser = "+soleUser+" renderingAttributes ="+renderingAttributes);
125: // Set the appearance only for soleUser case
126: if (soleUser)
127: this .app = app;
128: else
129: app = null;
130:
131: if (renderingAttributes != null) {
132: if (renderingAttributes.changedFrequent != 0) {
133: definingRenderingAttributes = renderingAttributes;
134: if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0) {
135: renderBin.aBinUpdateList.add(this );
136: onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
137: }
138: } else {
139: if (definingRenderingAttributes != null) {
140: definingRenderingAttributes
141: .set(renderingAttributes);
142: } else {
143: definingRenderingAttributes = (RenderingAttributesRetained) renderingAttributes
144: .clone();
145: }
146: }
147: ignoreVertexColors = definingRenderingAttributes.ignoreVertexColors;
148: } else {
149: definingRenderingAttributes = null;
150: ignoreVertexColors = false;
151: }
152: }
153:
154: /**
155: * This tests if the given attributes match this AttributeBin
156: */
157: boolean equals(RenderingAttributesRetained renderingAttributes,
158: RenderAtom ra) {
159:
160: // If the any reference to the appearance components that is cached renderMolecule
161: // can change frequently, make a separate bin
162: if (soleUser
163: || (ra.geometryAtom.source.appearance != null && ((ra.geometryAtom.source.appearance.changedFrequent & AppearanceRetained.RENDERING) != 0))) {
164: if (app == (Object) ra.geometryAtom.source.appearance) {
165:
166: // if this AttributeBin is currently on a zombie state,
167: // we'll need to put it on the update list to reevaluate
168: // the state, because while it is on a zombie state,
169: // rendering attributes reference could have been changed.
170: // Example, application could have detached an appearance,
171: // made changes to the reference, and then
172: // reattached the appearance. In this case, the rendering
173: // attributes reference change would not have reflected to
174: // the AttributeBin
175:
176: if (numEditingShaderBins == 0) {
177: if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0) {
178: renderBin.aBinUpdateList.add(this );
179: onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
180: }
181: }
182: return true;
183: } else {
184: return false;
185: }
186:
187: }
188: // Either a changedFrequent or a null case
189: // and the incoming one is not equal or null
190: // then return;
191: // This check also handles null == null case
192: if (definingRenderingAttributes != null) {
193: if ((this .definingRenderingAttributes.changedFrequent != 0)
194: || (renderingAttributes != null && renderingAttributes.changedFrequent != 0))
195: if (definingRenderingAttributes == renderingAttributes) {
196: if (definingRenderingAttributes.compChanged != 0) {
197: if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) == 0) {
198: renderBin.aBinUpdateList.add(this );
199: onUpdateList |= AttributeBin.ON_CHANGED_FREQUENT_UPDATE_LIST;
200: }
201: }
202: } else {
203: return false;
204: }
205: else if (!definingRenderingAttributes
206: .equivalent(renderingAttributes)) {
207: return false;
208: }
209: } else if (renderingAttributes != null) {
210: return false;
211: }
212:
213: return (true);
214: }
215:
216: public void updateObject() {
217: ShaderBin sb;
218: TextureBin t;
219: int i, size;
220:
221: size = addShaderBins.size();
222: if (size > 0) {
223: sb = (ShaderBin) addShaderBins.get(0);
224: if (shaderBinList == null) {
225: shaderBinList = sb;
226: } else {
227: sb.next = shaderBinList;
228: shaderBinList.prev = sb;
229: shaderBinList = sb;
230: }
231:
232: for (i = 1; i < size; i++) {
233: sb = (ShaderBin) addShaderBins.get(i);
234: sb.next = shaderBinList;
235: shaderBinList.prev = sb;
236: shaderBinList = sb;
237: }
238: }
239: addShaderBins.clear();
240: onUpdateList &= ~ON_OBJ_UPDATE_LIST;
241: }
242:
243: /**
244: * Adds the given shaderBin to this AttributeBin.
245: */
246: void addShaderBin(ShaderBin sb, RenderBin rb,
247: ShaderAppearanceRetained sApp) {
248:
249: sb.attributeBin = this ;
250:
251: if (sApp != null) {
252: // ShaderBin should reference to the mirror components. -- JADA.
253: // System.err.println("AttributeBin : sApp.isMirror = " + sApp.isMirror);
254: assert (sApp.isMirror);
255: sb.shaderProgram = sApp.shaderProgram;
256: sb.shaderAttributeSet = sApp.shaderAttributeSet;
257: }
258: sb.shaderAppearance = sApp;
259:
260: // TODO : JADA - sort by ShaderProgram to avoid state trashing.
261: addShaderBins.add(sb);
262: if ((onUpdateList & ON_OBJ_UPDATE_LIST) == 0) {
263: onUpdateList |= ON_OBJ_UPDATE_LIST;
264: rb.objUpdateList.add(this );
265: }
266:
267: }
268:
269: /**
270: * Removes the given shaderBin from this AttributeBin.
271: */
272: void removeShaderBin(ShaderBin sb) {
273:
274: // If the shaderBin being remove is contained in addShaderBins,
275: // then remove the shadereBin from the addList
276: if (addShaderBins.contains(sb)) {
277: addShaderBins.remove(addShaderBins.indexOf(sb));
278: } else {
279: if (sb.prev == null) { // At the head of the list
280: shaderBinList = sb.next;
281: if (sb.next != null) {
282: sb.next.prev = null;
283: }
284: } else { // In the middle or at the end.
285: sb.prev.next = sb.next;
286: if (sb.next != null) {
287: sb.next.prev = sb.prev;
288: }
289: }
290: }
291:
292: sb.clear();
293:
294: if (shaderBinList == null && addShaderBins.size() == 0) {
295: // Note: Removal of this attributebin as a user of the rendering
296: // atttrs is done during removeRenderAtom() in RenderMolecule.java
297: environmentSet.removeAttributeBin(this );
298: }
299: }
300:
301: /**
302: * Renders this AttributeBin
303: */
304: void render(Canvas3D cv) {
305:
306: ShaderBin sb;
307:
308: boolean visible = (definingRenderingAttributes == null || definingRenderingAttributes.visible);
309:
310: if ((renderBin.view.viewCache.visibilityPolicy == View.VISIBILITY_DRAW_VISIBLE && !visible)
311: || (renderBin.view.viewCache.visibilityPolicy == View.VISIBILITY_DRAW_INVISIBLE && visible)) {
312: return;
313: }
314:
315: // include this AttributeBin to the to-be-updated list in Canvas
316: cv.setStateToUpdate(Canvas3D.ATTRIBUTEBIN_BIT, this );
317:
318: sb = shaderBinList;
319: while (sb != null) {
320: sb.render(cv);
321: sb = sb.next;
322: }
323: }
324:
325: void updateAttributes(Canvas3D cv) {
326:
327: if ((cv.canvasDirty & Canvas3D.ATTRIBUTEBIN_DIRTY) != 0) {
328: // Update Attribute Bundles
329: if (definingRenderingAttributes == null) {
330: cv.resetRenderingAttributes(cv.ctx,
331: cv.depthBufferWriteEnableOverride,
332: cv.depthBufferEnableOverride);
333: } else {
334: definingRenderingAttributes.updateNative(cv,
335: cv.depthBufferWriteEnableOverride,
336: cv.depthBufferEnableOverride);
337: }
338: cv.renderingAttrs = renderingAttrs;
339: }
340:
341: else if (cv.renderingAttrs != renderingAttrs
342: && cv.attributeBin != this ) {
343: // Update Attribute Bundles
344: if (definingRenderingAttributes == null) {
345: cv.resetRenderingAttributes(cv.ctx,
346: cv.depthBufferWriteEnableOverride,
347: cv.depthBufferEnableOverride);
348: } else {
349: definingRenderingAttributes.updateNative(cv,
350: cv.depthBufferWriteEnableOverride,
351: cv.depthBufferEnableOverride);
352: }
353: cv.renderingAttrs = renderingAttrs;
354: }
355: cv.attributeBin = this ;
356: cv.canvasDirty &= ~Canvas3D.ATTRIBUTEBIN_DIRTY;
357: }
358:
359: void updateNodeComponent() {
360: // May be in the freelist already (due to freq bit changing)
361: // if so, don't update anything
362: if ((onUpdateList & ON_CHANGED_FREQUENT_UPDATE_LIST) != 0) {
363: if (soleUser) {
364: boolean cloned = definingRenderingAttributes != null
365: && definingRenderingAttributes != renderingAttrs;
366: renderingAttrs = app.renderingAttributes;
367:
368: if (renderingAttrs == null) {
369: definingRenderingAttributes = null;
370: ignoreVertexColors = false;
371: } else {
372: if (renderingAttrs.changedFrequent != 0) {
373: definingRenderingAttributes = renderingAttrs;
374: } else {
375: if (cloned) {
376: definingRenderingAttributes
377: .set(renderingAttrs);
378: } else {
379: definingRenderingAttributes = (RenderingAttributesRetained) renderingAttrs
380: .clone();
381: }
382: }
383: ignoreVertexColors = definingRenderingAttributes.ignoreVertexColors;
384: }
385: } else {
386: ignoreVertexColors = definingRenderingAttributes.ignoreVertexColors;
387: }
388: }
389:
390: onUpdateList &= ~ON_CHANGED_FREQUENT_UPDATE_LIST;
391: }
392:
393: void incrActiveShaderBin() {
394: numEditingShaderBins++;
395: }
396:
397: void decrActiveShaderBin() {
398: numEditingShaderBins--;
399: }
400:
401: void updateFromShaderBin(RenderAtom ra) {
402:
403: AppearanceRetained raApp = ra.geometryAtom.source.appearance;
404: RenderingAttributesRetained rAttrs = (raApp == null) ? null
405: : raApp.renderingAttributes;
406:
407: if (!soleUser && renderingAttrs != rAttrs) {
408: // no longer sole user
409: renderingAttrs = definingRenderingAttributes;
410: }
411: }
412: }
|