001: /*
002: * $RCSfile: ShaderAttributeObjectRetained.java,v $
003: *
004: * Copyright 2005-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.9 $
028: * $Date: 2008/02/28 20:17:29 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.util.ArrayList;
035: import javax.vecmath.*;
036:
037: /**
038: * The ShaderAttributeObjectRetained class is an abstract class that
039: * encapsulates a uniform shader attribute whose value is specified
040: * explicitly.
041: */
042:
043: abstract class ShaderAttributeObjectRetained extends
044: ShaderAttributeRetained {
045:
046: private int classType;
047: private Class baseClass;
048: AttrWrapper attrWrapper;
049:
050: /**
051: * Package scope constructor
052: */
053: ShaderAttributeObjectRetained() {
054: }
055:
056: void createObjectData(Object value) {
057:
058: classType = computeClassType(value);
059: baseClass = getBaseClass(classType);
060: attrWrapper = createAttrWrapper(value, classType);
061: /*
062: System.err.println(" classType = " + classType +
063: ", baseClass = " + baseClass +
064: ", attrWrapper.get() = " + attrWrapper.get());
065: */
066: }
067:
068: void initValue(Object value) {
069: /*
070: System.err.println("ShaderAttributeObjectRetained : attrName = " + attrName +
071: ", value = " + value +
072: ", value.class = " + value.getClass());
073: */
074: attrWrapper.set(value);
075:
076: }
077:
078: /**
079: * Retrieves the value of this shader attribute.
080: * A copy of the object is returned.
081: */
082: Object getValue() {
083: return attrWrapper.get();
084: }
085:
086: /**
087: * Sets the value of this shader attribute to the specified value.
088: * A copy of the object is stored.
089: *
090: * @param value the new value of the shader attribute
091: *
092: * @exception NullPointerException if value is null
093: *
094: * @exception ClassCastException if value is not an instance of
095: * the same base class as the object used to construct this shader
096: * attribute object.
097: *
098: */
099: void setValue(Object value) {
100: initValue(value);
101: AttrWrapper valueWrapper = createAttrWrapper(value,
102: this .classType);
103: sendMessage(ShaderConstants.ATTRIBUTE_VALUE_UPDATE,
104: valueWrapper);
105: }
106:
107: /**
108: * Retrieves the base class of the value of this shader attribute.
109: * This class will always be one of the allowable classes, even if
110: * a subclass was used to construct this shader attribute object.
111: * For example, if this shader attribute object was constructed
112: * with an instance of <code>javax.vecmath.Point3f</code>, the
113: * returned class would be <code>javax.vecmath.Tuple3f</code>.
114: *
115: * @return the base class of the value of this shader attribute
116: */
117: Class getValueClass() {
118: return baseClass;
119: }
120:
121: /**
122: * Initializes a mirror object.
123: */
124: synchronized void initMirrorObject() {
125: super .initMirrorObject();
126: ((ShaderAttributeObjectRetained) mirror).initValue(getValue());
127: }
128:
129: /**
130: * Update the "component" field of the mirror object with the given "value"
131: */
132: synchronized void updateMirrorObject(int component, Object value) {
133:
134: //System.err.println("ShaderAttributeObjectRetained : updateMirrorObject");
135: ShaderAttributeObjectRetained mirrorSAV = (ShaderAttributeObjectRetained) mirror;
136: if ((component & ShaderConstants.ATTRIBUTE_VALUE_UPDATE) != 0) {
137: //System.err.println(" -- SHADER_ATTRIBUTE_VALUE_UPDATE");
138: mirrorSAV.attrWrapper = (AttrWrapper) value;
139: }
140: }
141:
142: final void sendMessage(int attrMask, Object attr) {
143:
144: ArrayList univList = new ArrayList();
145: ArrayList gaList = Shape3DRetained.getGeomAtomsList(
146: mirror.users, univList);
147:
148: // Send to rendering attribute structure, regardless of
149: // whether there are users or not (alternate appearance case ..)
150: J3dMessage createMessage = new J3dMessage();
151: createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
152: createMessage.type = J3dMessage.SHADER_ATTRIBUTE_CHANGED;
153: createMessage.universe = null;
154: createMessage.args[0] = this ;
155: createMessage.args[1] = new Integer(attrMask);
156: createMessage.args[2] = attr;
157: // System.err.println("changedFreqent1 = "+changedFrequent);
158: createMessage.args[3] = new Integer(changedFrequent);
159: VirtualUniverse.mc.processMessage(createMessage);
160:
161: // System.err.println("univList.size is " + univList.size());
162: for (int i = 0; i < univList.size(); i++) {
163: createMessage = new J3dMessage();
164: createMessage.threads = J3dThread.UPDATE_RENDER;
165: createMessage.type = J3dMessage.SHADER_ATTRIBUTE_CHANGED;
166:
167: createMessage.universe = (VirtualUniverse) univList.get(i);
168: createMessage.args[0] = this ;
169: createMessage.args[1] = new Integer(attrMask);
170: createMessage.args[2] = attr;
171:
172: ArrayList gL = (ArrayList) gaList.get(i);
173: GeometryAtom[] gaArr = new GeometryAtom[gL.size()];
174: gL.toArray(gaArr);
175: createMessage.args[3] = gaArr;
176:
177: VirtualUniverse.mc.processMessage(createMessage);
178: }
179:
180: }
181:
182: // Enumerated types representing allowed classes for shader
183: // attributes.
184: //
185: // NOTE that the values for these enums are used as an index into
186: // the tables of classes, so the values must start at 0 and
187: // increment by 1. Also, the order must be the same as the order
188: // of the entries in each of the two class tables.
189: static final int TYPE_INTEGER = 0;
190: static final int TYPE_FLOAT = 1;
191: static final int TYPE_TUPLE2I = 2;
192: static final int TYPE_TUPLE2F = 3;
193: static final int TYPE_TUPLE3I = 4;
194: static final int TYPE_TUPLE3F = 5;
195: static final int TYPE_TUPLE4I = 6;
196: static final int TYPE_TUPLE4F = 7;
197: static final int TYPE_MATRIX3F = 8;
198: static final int TYPE_MATRIX4F = 9;
199:
200: // Double-precision is not supported in the current version. Uncomment the
201: // following if future support is done.
202: // static final int TYPE_DOUBLE = 10;
203: // static final int TYPE_TUPLE2D = 11;
204: // static final int TYPE_TUPLE3D = 12;
205: // static final int TYPE_TUPLE4D = 13;
206: // static final int TYPE_MATRIX3D = 14;
207: // static final int TYPE_MATRIX4D = 15;
208:
209: static final Class classTable[] = { Integer.class, Float.class,
210: Tuple2i.class, Tuple2f.class, Tuple3i.class, Tuple3f.class,
211: Tuple4i.class, Tuple4f.class, Matrix3f.class,
212: Matrix4f.class,
213:
214: // Double-precision is not supported in the current version. Uncomment the
215: // following if future support is done.
216: // Double.class,
217: // Tuple2d.class,
218: // Tuple3d.class,
219: // Tuple4d.class,
220: // Matrix3d.class,
221: // Matrix4d.class,
222: };
223:
224: static final Class classTableArr[] = { Integer[].class,
225: Float[].class, Tuple2i[].class, Tuple2f[].class,
226: Tuple3i[].class, Tuple3f[].class, Tuple4i[].class,
227: Tuple4f[].class, Matrix3f[].class, Matrix4f[].class,
228:
229: // Double-precision is not supported in the current version. Uncomment the
230: // following if future support is done.
231: // Double[].class,
232: // Tuple2d[].class,
233: // Tuple3d[].class,
234: // Tuple4d[].class,
235: // Matrix3d[].class,
236: // Matrix4d[].class,
237: };
238:
239: /**
240: * Computes the base class from the specified object. A
241: * ClassCastException is thrown if the object is not an instance
242: * or array of one of the allowed classes.
243: */
244: abstract int computeClassType(Object value);
245:
246: /**
247: * Returns the base class represented by the specified class type.
248: */
249: abstract Class getBaseClass(int classType);
250:
251: /**
252: * Creates an attribute wrapper object of the specified class
253: * type, and stores the specified object.
254: */
255: abstract AttrWrapper createAttrWrapper(Object value, int classType);
256:
257: /**
258: * Base wrapper class for subclasses that are used to store a copy
259: * of the user-specified shader attribute value. There is a
260: * wrapper class for each supported base class in ShaderAttributeValue
261: * and ShaderAttributeArray. The value is stored in a Java primitive array.
262: */
263: static abstract class AttrWrapper {
264: /**
265: * Stores a copy of the specified object in the wrapper object
266: */
267: abstract void set(Object value);
268:
269: /**
270: * Returns a copy of the wrapped object
271: */
272: abstract Object get();
273:
274: /**
275: * Returns a reference to the internal primitive array used to
276: * wrap the object; note that the caller of this method must
277: * treat the data as read-only. It is intended only as a means
278: * to pass data down to native methods.
279: */
280: abstract Object getRef();
281: }
282:
283: int getClassType() {
284: return classType;
285: }
286:
287: void setClassType(int classType) {
288: this .classType = classType;
289: }
290:
291: // Issue 320 : Override base class method so we can force changedFrequent
292: // to be set whenever the capability is writable, regardless of whether
293: // it is frequently writable. We must do this because the ShaderBin doesn't
294: // support updating shader attributes when changedFrequent is 0.
295: void setFrequencyChangeMask(int bit, int mask) {
296: if (source.getCapability(bit)) {
297: changedFrequent |= mask;
298: } else if (!source.isLive()) {
299: // Record the freq->infreq change only for non-live node components
300: changedFrequent &= ~mask;
301: }
302: }
303:
304: void handleFrequencyChange(int bit) {
305: if (bit == ShaderAttributeObject.ALLOW_VALUE_WRITE) {
306: setFrequencyChangeMask(bit, 0x1);
307: }
308: }
309:
310: }
|