001: /*
002: * $RCSfile: TextureAttributesRetained.java,v $
003: *
004: * Copyright 1998-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:31 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import javax.vecmath.Color4f;
035: import java.util.ArrayList;
036:
037: /**
038: * The TextureAttributes object defines attributes that apply to
039: * to texture mapping.
040: */
041: class TextureAttributesRetained extends NodeComponentRetained {
042:
043: // A list of pre-defined bits to indicate which component
044: // in this TextureAttributes object changed.
045: static final int TRANSFORM_CHANGED = 0x0001;
046: static final int MODE_CHANGED = 0x0002;
047: static final int COLOR_CHANGED = 0x0004;
048: static final int CORRECTION_CHANGED = 0x0008;
049: static final int TEXTURE_COLOR_TABLE_CHANGED = 0x0010;
050: static final int COMBINE_RGB_MODE_CHANGED = 0x0020;
051: static final int COMBINE_ALPHA_MODE_CHANGED = 0x0040;
052: static final int COMBINE_RGB_SRC_CHANGED = 0x0080;
053: static final int COMBINE_ALPHA_SRC_CHANGED = 0x0100;
054: static final int COMBINE_RGB_FCN_CHANGED = 0x0200;
055: static final int COMBINE_ALPHA_FCN_CHANGED = 0x0400;
056: static final int COMBINE_RGB_SCALE_CHANGED = 0x0800;
057: static final int COMBINE_ALPHA_SCALE_CHANGED = 0x1000;
058:
059: // static class variable for commands used in messages
060: static Integer commandInt[] = null;
061:
062: // static class variable for enums. Currently only supports 0 - 9.
063: static Integer enums[] = null;
064:
065: // Texture transform
066: Transform3D transform = new Transform3D();
067:
068: // Texture mode
069: int textureMode = TextureAttributes.REPLACE;
070:
071: // Texture blend color
072: Color4f textureBlendColor = new Color4f(0.0f, 0.0f, 0.0f, 0.0f);
073:
074: // Texture color table
075: int textureColorTable[] = null;
076: int numTextureColorTableComponents = 0;
077: int textureColorTableSize = 0;
078:
079: // Texture Combine Mode
080:
081: int combineRgbMode = TextureAttributes.COMBINE_MODULATE;
082: int combineAlphaMode = TextureAttributes.COMBINE_MODULATE;
083:
084: // the following fields are only applicable if textureMode specifies
085: // COMBINE. If COMBINE mode is specified, then each of the following
086: // fields will be referencing an array of 3 integers, each representing
087: // an operand in the combine equation.
088: int[] combineRgbSrc = null;
089: int[] combineAlphaSrc = null;
090: int[] combineRgbFcn = null;
091: int[] combineAlphaFcn = null;
092:
093: int combineRgbScale = 1;
094: int combineAlphaScale = 1;
095:
096: //Perspective correction mode, used for color/texCoord interpolation
097: int perspCorrectionMode = TextureAttributes.NICEST;
098:
099: // true when mirror texCoord component set
100: boolean mirrorCompDirty = false;
101:
102: static final void initTextureEnums() {
103: // create some of the enums Integer to be used in the messages
104: // this can be eliminated if the message is modified to take
105: // integer itself
106: //
107: // NOTE: check with the actual enum value before using this
108: // list. This list only supports 0 - 9
109: if (enums == null) {
110: enums = new Integer[10];
111: for (int i = 0; i < 10; i++) {
112: enums[i] = new Integer(i);
113: }
114: }
115: }
116:
117: TextureAttributesRetained() {
118: initTextureEnums();
119: }
120:
121: // initCombineMode -- initializes the combine mode related fields
122: // delay the allocation of memory to minimize
123: // memory footprint
124:
125: final void initCombineMode(TextureAttributesRetained tr) {
126: tr.combineRgbSrc = new int[3];
127: tr.combineAlphaSrc = new int[3];
128: tr.combineRgbFcn = new int[3];
129: tr.combineAlphaFcn = new int[3];
130:
131: //default values
132:
133: tr.combineRgbSrc[0] = TextureAttributes.COMBINE_TEXTURE_COLOR;
134: tr.combineRgbSrc[1] = TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE;
135: tr.combineRgbSrc[2] = TextureAttributes.COMBINE_CONSTANT_COLOR;
136:
137: tr.combineAlphaSrc[0] = TextureAttributes.COMBINE_TEXTURE_COLOR;
138: tr.combineAlphaSrc[1] = TextureAttributes.COMBINE_PREVIOUS_TEXTURE_UNIT_STATE;
139: tr.combineAlphaSrc[2] = TextureAttributes.COMBINE_CONSTANT_COLOR;
140:
141: tr.combineRgbFcn[0] = TextureAttributes.COMBINE_SRC_COLOR;
142: tr.combineRgbFcn[1] = TextureAttributes.COMBINE_SRC_COLOR;
143: tr.combineRgbFcn[2] = TextureAttributes.COMBINE_SRC_COLOR;
144:
145: tr.combineAlphaFcn[0] = TextureAttributes.COMBINE_SRC_ALPHA;
146: tr.combineAlphaFcn[1] = TextureAttributes.COMBINE_SRC_ALPHA;
147: tr.combineAlphaFcn[2] = TextureAttributes.COMBINE_SRC_ALPHA;
148: }
149:
150: final void initTextureMode(int textureMode) {
151: this .textureMode = textureMode;
152:
153: if (textureMode == TextureAttributes.COMBINE) {
154: if (combineRgbSrc == null) {
155: initCombineMode(this );
156: }
157: }
158: }
159:
160: /**
161: * Sets the texture mode parameter for this
162: * appearance component object.
163: * @param textureMode the texture mode, one of: MODULATE,
164: * DECAL, BLEND, or REPLACE
165: */
166: final void setTextureMode(int textureMode) {
167: initTextureMode(textureMode);
168: sendMessage(MODE_CHANGED, enums[textureMode], null);
169: }
170:
171: /**
172: * Gets the texture mode parameter for this
173: * texture attributes object.
174: * @return textureMode the texture mode
175: */
176: final int getTextureMode() {
177: return textureMode;
178: }
179:
180: final void initTextureBlendColor(Color4f textureBlendColor) {
181: this .textureBlendColor.set(textureBlendColor);
182:
183: }
184:
185: /**
186: * Sets the texture blend color for this
187: * texture attributes object.
188: * @param textureBlendColor the texture blend color used when
189: * the mode is BLEND
190: */
191: final void setTextureBlendColor(Color4f textureBlendColor) {
192: this .textureBlendColor.set(textureBlendColor);
193: sendMessage(COLOR_CHANGED, new Color4f(textureBlendColor), null);
194: }
195:
196: final void initTextureBlendColor(float r, float g, float b, float a) {
197: this .textureBlendColor.set(r, g, b, a);
198: }
199:
200: /**
201: * Sets the texture blend color for this
202: * appearance component object. This color is used when
203: * the mode is BLEND.
204: * @param r the red component of the color
205: * @param g the green component of the color
206: * @param b the blue component of the color
207: * @param a the alpha component of the color
208: */
209: final void setTextureBlendColor(float r, float g, float b, float a) {
210: this .textureBlendColor.set(r, g, b, a);
211: sendMessage(COLOR_CHANGED, new Color4f(r, g, b, a), null);
212: }
213:
214: /**
215: * Gets the texture blend color for this
216: * appearance component object.
217: * @param textureBlendColor the vector that will receive the texture
218: * blend color used when the mode is BLEND
219: */
220: final void getTextureBlendColor(Color4f textureBlendColor) {
221: textureBlendColor.set(this .textureBlendColor);
222: }
223:
224: final void initTextureTransform(Transform3D transform) {
225: this .transform.set(transform);
226: }
227:
228: /**
229: * Sets the texture transform object used to transform texture
230: * coordinates. A copy of the specified Transform3D object is
231: * stored in this TextureAttributes object.
232: * @param transform the new transform object
233: */
234: final void setTextureTransform(Transform3D transform) {
235: this .transform.set(transform);
236: sendMessage(TRANSFORM_CHANGED, new Transform3D(transform), null);
237: }
238:
239: /**
240: * Retrieves a copy of the texture transform object.
241: * @param transform the transform object that will receive the
242: * current texture transform.
243: */
244: final void getTextureTransform(Transform3D transform) {
245: transform.set(this .transform);
246: }
247:
248: final void initPerspectiveCorrectionMode(int mode) {
249: this .perspCorrectionMode = mode;
250: }
251:
252: /**
253: * Sets perspective correction mode to be used for color
254: * and/or texture coordinate interpolation.
255: * A value of NICEST indicates that perspective correction should be
256: * performed and that the highest quality method should be used.
257: * A value of FASTEST indicates that the most efficient perspective
258: * correction method should be used.
259: * @param mode one of NICEST or FASTEST.
260: * The default value is NICEST.
261: */
262: final void setPerspectiveCorrectionMode(int mode) {
263: this .perspCorrectionMode = mode;
264: sendMessage(CORRECTION_CHANGED, enums[mode], null);
265: }
266:
267: /**
268: * Gets perspective correction mode value.
269: * @return mode the value of perspective correction mode.
270: */
271: final int getPerspectiveCorrectionMode() {
272: return perspCorrectionMode;
273: }
274:
275: final void setTextureColorTable(int[][] table) {
276: initTextureColorTable(table);
277:
278: //clone a copy of the texture for the mirror object
279: if (table == null) {
280: sendMessage(TEXTURE_COLOR_TABLE_CHANGED, null, null);
281: } else {
282: int ctable[] = new int[textureColorTableSize
283: * numTextureColorTableComponents];
284: System.arraycopy(textureColorTable, 0, ctable, 0,
285: textureColorTable.length);
286: Object args[] = new Object[3];
287:
288: args[0] = new Integer(numTextureColorTableComponents);
289: args[1] = new Integer(textureColorTableSize);
290: args[2] = ctable;
291: sendMessage(TEXTURE_COLOR_TABLE_CHANGED, args, null);
292: }
293: }
294:
295: final void initTextureColorTable(int[][] table) {
296:
297: numTextureColorTableComponents = 0;
298: textureColorTableSize = 0;
299:
300: if (table == null) {
301: textureColorTable = null;
302: return;
303: }
304:
305: if (table.length < 3 || table.length > 4) {
306: throw new IllegalArgumentException(J3dI18N
307: .getString("TextureAttributes13"));
308: }
309:
310: if (Texture.getPowerOf2(table[0].length) == -1) {
311: throw new IllegalArgumentException(J3dI18N
312: .getString("TextureAttributes14"));
313: }
314:
315: for (int i = 1; i < table.length; i++) {
316: if (table[i].length != table[0].length)
317: throw new IllegalArgumentException(J3dI18N
318: .getString("TextureAttributes15"));
319: }
320:
321: numTextureColorTableComponents = table.length;
322: textureColorTableSize = table[0].length;
323:
324: if (textureColorTable == null
325: || textureColorTable.length != numTextureColorTableComponents
326: * textureColorTableSize) {
327: textureColorTable = new int[numTextureColorTableComponents
328: * textureColorTableSize];
329: }
330:
331: int k = 0;
332: for (int i = 0; i < textureColorTableSize; i++) {
333: for (int j = 0; j < numTextureColorTableComponents; j++) {
334: textureColorTable[k++] = table[j][i];
335: }
336: }
337: }
338:
339: final void getTextureColorTable(int[][] table) {
340:
341: if (textureColorTable == null)
342: return;
343:
344: int k = 0;
345: for (int i = 0; i < textureColorTableSize; i++) {
346: for (int j = 0; j < numTextureColorTableComponents; j++) {
347: table[j][i] = textureColorTable[k++];
348: }
349: }
350: }
351:
352: final int getNumTextureColorTableComponents() {
353: return numTextureColorTableComponents;
354: }
355:
356: final int getTextureColorTableSize() {
357: return textureColorTableSize;
358: }
359:
360: final void initCombineRgbMode(int mode) {
361: combineRgbMode = mode;
362: }
363:
364: final void setCombineRgbMode(int mode) {
365: initCombineRgbMode(mode);
366: sendMessage(COMBINE_RGB_MODE_CHANGED, enums[mode], null);
367: }
368:
369: final int getCombineRgbMode() {
370: return combineRgbMode;
371: }
372:
373: final void initCombineAlphaMode(int mode) {
374: combineAlphaMode = mode;
375: }
376:
377: final void setCombineAlphaMode(int mode) {
378: initCombineAlphaMode(mode);
379: sendMessage(COMBINE_ALPHA_MODE_CHANGED, enums[mode], null);
380: }
381:
382: final int getCombineAlphaMode() {
383: return combineAlphaMode;
384: }
385:
386: final void initCombineRgbSource(int index, int src) {
387: if (combineRgbSrc == null) {
388: // it is possible to set the combineRgbSource before
389: // setting the texture mode to COMBINE, so need to initialize
390: // the combine mode related fields here
391: initCombineMode(this );
392: }
393: combineRgbSrc[index] = src;
394: }
395:
396: final void setCombineRgbSource(int index, int src) {
397: initCombineRgbSource(index, src);
398: sendMessage(COMBINE_RGB_SRC_CHANGED, enums[index], enums[src]);
399: }
400:
401: final int getCombineRgbSource(int index) {
402: if (combineRgbSrc == null) {
403: // it is possible to do a get before
404: // setting the texture mode to COMBINE, so need to initialize
405: // the combine mode related fields here
406: initCombineMode(this );
407: }
408: return combineRgbSrc[index];
409: }
410:
411: final void initCombineAlphaSource(int index, int src) {
412: if (combineRgbSrc == null) {
413: // it is possible to set the combineAlphaSource before
414: // setting the texture mode to COMBINE, so need to initialize
415: // the combine mode related fields here
416: initCombineMode(this );
417: }
418: combineAlphaSrc[index] = src;
419: }
420:
421: final void setCombineAlphaSource(int index, int src) {
422: initCombineAlphaSource(index, src);
423: sendMessage(COMBINE_ALPHA_SRC_CHANGED, enums[index], enums[src]);
424: }
425:
426: final int getCombineAlphaSource(int index) {
427: if (combineRgbSrc == null) {
428: // it is possible to do a get before
429: // setting the texture mode to COMBINE, so need to initialize
430: // the combine mode related fields here
431: initCombineMode(this );
432: }
433: return combineAlphaSrc[index];
434: }
435:
436: final void initCombineRgbFunction(int index, int fcn) {
437: if (combineRgbSrc == null) {
438: // it is possible to set the combineRgbFcn before
439: // setting the texture mode to COMBINE, so need to initialize
440: // the combine mode related fields here
441: initCombineMode(this );
442: }
443: combineRgbFcn[index] = fcn;
444: }
445:
446: final void setCombineRgbFunction(int index, int fcn) {
447: initCombineRgbFunction(index, fcn);
448: sendMessage(COMBINE_RGB_FCN_CHANGED, enums[index], enums[fcn]);
449: }
450:
451: final int getCombineRgbFunction(int index) {
452: if (combineRgbSrc == null) {
453: // it is possible to do a get before
454: // setting the texture mode to COMBINE, so need to initialize
455: // the combine mode related fields here
456: initCombineMode(this );
457: }
458: return combineRgbFcn[index];
459: }
460:
461: final void initCombineAlphaFunction(int index, int fcn) {
462: if (combineRgbSrc == null) {
463: // it is possible to set the combineAlphaFcn before
464: // setting the texture mode to COMBINE, so need to initialize
465: // the combine mode related fields here
466: initCombineMode(this );
467: }
468: combineAlphaFcn[index] = fcn;
469: }
470:
471: final void setCombineAlphaFunction(int index, int fcn) {
472: initCombineAlphaFunction(index, fcn);
473: sendMessage(COMBINE_ALPHA_FCN_CHANGED, enums[index], enums[fcn]);
474: }
475:
476: final int getCombineAlphaFunction(int index) {
477: if (combineRgbSrc == null) {
478: // it is possible to do a get before
479: // setting the texture mode to COMBINE, so need to initialize
480: // the combine mode related fields here
481: initCombineMode(this );
482: }
483: return combineAlphaFcn[index];
484: }
485:
486: final void initCombineRgbScale(int scale) {
487: combineRgbScale = scale;
488: }
489:
490: final void setCombineRgbScale(int scale) {
491: initCombineRgbScale(scale);
492: sendMessage(COMBINE_RGB_SCALE_CHANGED, enums[scale], null);
493: }
494:
495: final int getCombineRgbScale() {
496: return combineRgbScale;
497: }
498:
499: final void initCombineAlphaScale(int scale) {
500: combineAlphaScale = scale;
501: }
502:
503: final void setCombineAlphaScale(int scale) {
504: initCombineAlphaScale(scale);
505: sendMessage(COMBINE_ALPHA_SCALE_CHANGED, enums[scale], null);
506: }
507:
508: final int getCombineAlphaScale() {
509: return combineAlphaScale;
510: }
511:
512: void updateNative(Canvas3D cv, boolean simulate, int textureFormat) {
513:
514: //System.err.println("TextureAttributes/updateNative: simulate= " + simulate + " " + this);
515:
516: //if ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COLOR_TABLE)
517: // == 0) && textureColorTable != null) {
518: // System.err.println("TextureColorTable Not supported");
519: //}
520:
521: //System.err.println("textureMode= " + textureMode);
522: boolean isIdentity = ((transform.getType() & Transform3D.IDENTITY) != 0);
523:
524: if (simulate == false) {
525: if (VirtualUniverse.mc.useCombiners
526: && (cv.textureExtendedFeatures & Canvas3D.TEXTURE_REGISTER_COMBINERS) != 0) {
527: Pipeline.getPipeline().updateRegisterCombiners(cv.ctx,
528: transform.mat, isIdentity, textureMode,
529: perspCorrectionMode, textureBlendColor.x,
530: textureBlendColor.y, textureBlendColor.z,
531: textureBlendColor.w, textureFormat,
532: combineRgbMode, combineAlphaMode,
533: combineRgbSrc, combineAlphaSrc, combineRgbFcn,
534: combineAlphaFcn, combineRgbScale,
535: combineAlphaScale);
536: } else {
537: if (textureMode == TextureAttributes.COMBINE) {
538:
539: if ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COMBINE) != 0) {
540:
541: // Texture COMBINE is supported by the underlying layer
542:
543: int _combineRgbMode = combineRgbMode;
544: int _combineAlphaMode = combineAlphaMode;
545:
546: Pipeline.getPipeline().updateTextureAttributes(
547: cv.ctx, transform.mat, isIdentity,
548: textureMode, perspCorrectionMode,
549: textureBlendColor.x,
550: textureBlendColor.y,
551: textureBlendColor.z,
552: textureBlendColor.w, textureFormat);
553:
554: if (((combineRgbMode == TextureAttributes.COMBINE_DOT3) && ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COMBINE_DOT3) == 0))
555: || ((combineRgbMode == TextureAttributes.COMBINE_SUBTRACT) && ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COMBINE_SUBTRACT) == 0))) {
556:
557: // Combine DOT3/SUBTRACT is not supported by the
558: // underlying layer, fallback to COMBINE_REPLACE
559:
560: _combineRgbMode = TextureAttributes.COMBINE_REPLACE;
561: }
562:
563: if (((combineAlphaMode == TextureAttributes.COMBINE_DOT3) && ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COMBINE_DOT3) == 0))
564: || ((combineAlphaMode == TextureAttributes.COMBINE_SUBTRACT) && ((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COMBINE_SUBTRACT) == 0))) {
565:
566: // Combine DOT3/SUBTRACT is not supported by the
567: // underlying layer, fallback to COMBINE_REPLACE
568:
569: _combineAlphaMode = TextureAttributes.COMBINE_REPLACE;
570: }
571:
572: Pipeline.getPipeline().updateCombiner(cv.ctx,
573: _combineRgbMode, _combineAlphaMode,
574: combineRgbSrc, combineAlphaSrc,
575: combineRgbFcn, combineAlphaFcn,
576: combineRgbScale, combineAlphaScale);
577:
578: } else {
579:
580: // Texture COMBINE is not supported by the underlying
581: // layer, fallback to REPLACE
582:
583: Pipeline.getPipeline().updateTextureAttributes(
584: cv.ctx, transform.mat, isIdentity,
585: TextureAttributes.REPLACE,
586: perspCorrectionMode,
587: textureBlendColor.x,
588: textureBlendColor.y,
589: textureBlendColor.z,
590: textureBlendColor.w, textureFormat);
591: }
592: } else {
593: Pipeline.getPipeline().updateTextureAttributes(
594: cv.ctx, transform.mat, isIdentity,
595: textureMode, perspCorrectionMode,
596: textureBlendColor.x, textureBlendColor.y,
597: textureBlendColor.z, textureBlendColor.w,
598: textureFormat);
599: }
600: }
601:
602: if (((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COLOR_TABLE) != 0)
603: && textureColorTable != null) {
604:
605: Pipeline.getPipeline().updateTextureColorTable(cv.ctx,
606: numTextureColorTableComponents,
607: textureColorTableSize, textureColorTable);
608: }
609: } else {
610: // we are in the multi-pass mode,
611: // in this case, set the texture Mode to replace and use
612: // blending to simulate the original textureMode
613: Pipeline.getPipeline().updateTextureAttributes(cv.ctx,
614: transform.mat, isIdentity,
615: TextureAttributes.REPLACE, perspCorrectionMode,
616: textureBlendColor.x, textureBlendColor.y,
617: textureBlendColor.z, textureBlendColor.w,
618: textureFormat);
619:
620: if (((cv.textureExtendedFeatures & Canvas3D.TEXTURE_COLOR_TABLE) != 0)
621: && textureColorTable != null) {
622:
623: Pipeline.getPipeline().updateTextureColorTable(cv.ctx,
624: numTextureColorTableComponents,
625: textureColorTableSize, textureColorTable);
626: }
627:
628: switch (textureMode) {
629: case TextureAttributes.COMBINE:
630: case TextureAttributes.REPLACE:
631: cv.setBlendFunc(cv.ctx,
632: TransparencyAttributes.BLEND_ONE,
633: TransparencyAttributes.BLEND_ZERO);
634: break;
635: case TextureAttributes.MODULATE:
636: cv.setBlendFunc(cv.ctx,
637: TransparencyAttributes.BLEND_DST_COLOR,
638: TransparencyAttributes.BLEND_ZERO);
639: break;
640: case TextureAttributes.DECAL:
641: if (textureFormat == Texture.RGBA) {
642: cv
643: .setBlendFunc(
644: cv.ctx,
645: TransparencyAttributes.BLEND_SRC_ALPHA,
646: TransparencyAttributes.BLEND_ONE_MINUS_SRC_ALPHA);
647: } else {
648: cv.setBlendFunc(cv.ctx,
649: TransparencyAttributes.BLEND_ONE,
650: TransparencyAttributes.BLEND_ZERO);
651: }
652: break;
653: case TextureAttributes.BLEND:
654: cv.setBlendColor(cv.ctx, textureBlendColor.x,
655: textureBlendColor.y, textureBlendColor.z,
656: textureBlendColor.w);
657: cv
658: .setBlendFunc(
659: cv.ctx,
660: TransparencyAttributes.BLEND_CONSTANT_COLOR,
661: TransparencyAttributes.BLEND_ONE_MINUS_SRC_COLOR);
662: break;
663: }
664: }
665: }
666:
667: /**
668: * Creates and initializes a mirror object, point the mirror object
669: * to the retained object if the object is not editable
670: */
671: synchronized void createMirrorObject() {
672:
673: if (mirror == null) {
674: // Check the capability bits and let the mirror object
675: // point to itself if is not editable
676: if (isStatic()) {
677: mirror = this ;
678: } else {
679: TextureAttributesRetained mirrorTa = new TextureAttributesRetained();
680: mirrorTa.source = source;
681: mirrorTa.set(this );
682: mirror = mirrorTa;
683: }
684: } else {
685: ((TextureAttributesRetained) mirror).set(this );
686: }
687: }
688:
689: /**
690: * Initializes a mirror object
691: */
692: synchronized void initMirrorObject() {
693: ((TextureAttributesRetained) mirror).set(this );
694: }
695:
696: /**
697: * Update the "component" field of the mirror object with the
698: * given "value"
699: */
700: synchronized void updateMirrorObject(int component, Object value,
701: Object value2) {
702: TextureAttributesRetained mirrorTa = (TextureAttributesRetained) mirror;
703: mirrorTa.mirrorCompDirty = true;
704:
705: if ((component & TRANSFORM_CHANGED) != 0) {
706: mirrorTa.transform.set((Transform3D) value);
707: } else if ((component & MODE_CHANGED) != 0) {
708: mirrorTa.textureMode = ((Integer) value).intValue();
709:
710: if ((mirrorTa.textureMode == TextureAttributes.COMBINE)
711: && (mirrorTa.combineRgbSrc == null)) {
712: initCombineMode(mirrorTa);
713: }
714: } else if ((component & COLOR_CHANGED) != 0) {
715: mirrorTa.textureBlendColor.set((Color4f) value);
716: } else if ((component & CORRECTION_CHANGED) != 0) {
717: mirrorTa.perspCorrectionMode = ((Integer) value).intValue();
718: } else if ((component & TEXTURE_COLOR_TABLE_CHANGED) != 0) {
719: if (value == null) {
720: mirrorTa.textureColorTable = null;
721: mirrorTa.numTextureColorTableComponents = 0;
722: mirrorTa.textureColorTableSize = 0;
723: } else {
724: Object args[] = (Object[]) value;
725: mirrorTa.textureColorTable = (int[]) args[2];
726: mirrorTa.numTextureColorTableComponents = ((Integer) args[0])
727: .intValue();
728: mirrorTa.textureColorTableSize = ((Integer) args[1])
729: .intValue();
730: }
731: } else if ((component & COMBINE_RGB_MODE_CHANGED) != 0) {
732: mirrorTa.combineRgbMode = ((Integer) value).intValue();
733: } else if ((component & COMBINE_ALPHA_MODE_CHANGED) != 0) {
734: mirrorTa.combineAlphaMode = ((Integer) value).intValue();
735: } else if ((component & COMBINE_RGB_SRC_CHANGED) != 0) {
736: if (mirrorTa.combineRgbSrc == null) {
737: //initialize the memory for combine mode
738: initCombineMode(mirrorTa);
739: }
740: int index = ((Integer) value).intValue();
741: mirrorTa.combineRgbSrc[index] = ((Integer) value2)
742: .intValue();
743: } else if ((component & COMBINE_ALPHA_SRC_CHANGED) != 0) {
744: if (mirrorTa.combineRgbSrc == null) {
745: //initialize the memory for combine mode
746: initCombineMode(mirrorTa);
747: }
748: int index = ((Integer) value).intValue();
749: mirrorTa.combineAlphaSrc[index] = ((Integer) value2)
750: .intValue();
751: } else if ((component & COMBINE_RGB_FCN_CHANGED) != 0) {
752: if (mirrorTa.combineRgbSrc == null) {
753: //initialize the memory for combine mode
754: initCombineMode(mirrorTa);
755: }
756: int index = ((Integer) value).intValue();
757: mirrorTa.combineRgbFcn[index] = ((Integer) value2)
758: .intValue();
759: } else if ((component & COMBINE_ALPHA_FCN_CHANGED) != 0) {
760: if (mirrorTa.combineRgbSrc == null) {
761: //initialize the memory for combine mode
762: initCombineMode(mirrorTa);
763: }
764: int index = ((Integer) value).intValue();
765: mirrorTa.combineAlphaFcn[index] = ((Integer) value2)
766: .intValue();
767: } else if ((component & COMBINE_RGB_SCALE_CHANGED) != 0) {
768: mirrorTa.combineRgbScale = ((Integer) value).intValue();
769: } else if ((component & COMBINE_ALPHA_SCALE_CHANGED) != 0) {
770: mirrorTa.combineAlphaScale = ((Integer) value).intValue();
771: }
772: }
773:
774: boolean equivalent(TextureAttributesRetained tr) {
775:
776: if (tr == null) {
777: return (false);
778:
779: } else if ((this .changedFrequent != 0)
780: || (tr.changedFrequent != 0)) {
781: return (this == tr);
782: }
783:
784: if (!(tr.transform.equals(transform)
785: && tr.textureBlendColor.equals(textureBlendColor)
786: && (tr.textureMode == textureMode) && (tr.perspCorrectionMode == perspCorrectionMode))) {
787: return false;
788: }
789:
790: // now check for combine mode attributes if textureMode specifies
791: // COMBINE
792:
793: if (textureMode == TextureAttributes.COMBINE) {
794:
795: if ((tr.combineRgbMode != combineRgbMode)
796: || (tr.combineAlphaMode != combineAlphaMode)
797: || (tr.combineRgbScale != combineRgbScale)
798: || (tr.combineAlphaScale != combineAlphaScale)) {
799: return false;
800: }
801:
802: // now check if the operands for the combine equations are
803: // equivalent
804:
805: int nOpNeeded = 0;
806:
807: if (combineRgbMode == TextureAttributes.COMBINE_REPLACE) {
808: nOpNeeded = 1;
809: } else if (combineRgbMode == TextureAttributes.COMBINE_INTERPOLATE) {
810: nOpNeeded = 3;
811: } else {
812: nOpNeeded = 2;
813: }
814:
815: for (int i = 0; i < nOpNeeded; i++) {
816: if ((tr.combineRgbSrc[i] != combineRgbSrc[i])
817: || (tr.combineAlphaSrc[i] != combineAlphaSrc[i])
818: || (tr.combineRgbFcn[i] != combineRgbFcn[i])
819: || (tr.combineAlphaFcn[i] != combineAlphaFcn[i])) {
820: return false;
821: }
822: }
823: }
824:
825: // now check for texture color table
826:
827: if (tr.textureColorTable == null) {
828: if (this .textureColorTable == null)
829: return true;
830: else
831: return false;
832: } else if (this .textureColorTable == null) {
833: // tr.textureColorTable != null
834: return false;
835: } else {
836: if (tr.textureColorTable.length != this .textureColorTable.length)
837: return false;
838:
839: for (int i = 0; i < this .textureColorTable.length; i++) {
840: if (this .textureColorTable[i] != tr.textureColorTable[i])
841: return false;
842: }
843:
844: return true;
845: }
846:
847: }
848:
849: protected Object clone() {
850: TextureAttributesRetained tr = (TextureAttributesRetained) super
851: .clone();
852: tr.transform = new Transform3D(transform);
853: tr.textureBlendColor = new Color4f(textureBlendColor);
854: if (textureColorTable != null) {
855: tr.textureColorTable = new int[textureColorTable.length];
856: System.arraycopy(textureColorTable, 0,
857: tr.textureColorTable, 0, textureColorTable.length);
858: } else {
859: tr.textureColorTable = null;
860: }
861:
862: // clone the combine mode attributes
863: if (combineRgbSrc != null) {
864: tr.combineRgbSrc = new int[3];
865: tr.combineAlphaSrc = new int[3];
866: tr.combineRgbFcn = new int[3];
867: tr.combineAlphaFcn = new int[3];
868:
869: for (int i = 0; i < 3; i++) {
870: tr.combineRgbSrc[i] = combineRgbSrc[i];
871: tr.combineAlphaSrc[i] = combineAlphaSrc[i];
872: tr.combineRgbFcn[i] = combineRgbFcn[i];
873: tr.combineAlphaFcn[i] = combineAlphaFcn[i];
874: }
875: }
876:
877: // other attributes are copied in super.clone()
878: return tr;
879: }
880:
881: protected void set(TextureAttributesRetained tr) {
882: super .set(tr);
883: transform.set(tr.transform);
884: textureBlendColor.set(tr.textureBlendColor);
885: textureMode = tr.textureMode;
886: perspCorrectionMode = tr.perspCorrectionMode;
887:
888: // set texture color table
889:
890: if (tr.textureColorTable != null) {
891: if (textureColorTable == null
892: || textureColorTable.length != tr.textureColorTable.length) {
893: textureColorTable = new int[tr.textureColorTable.length];
894: }
895: System.arraycopy(tr.textureColorTable, 0,
896: textureColorTable, 0, tr.textureColorTable.length);
897: } else {
898: textureColorTable = null;
899: }
900: numTextureColorTableComponents = tr.numTextureColorTableComponents;
901: textureColorTableSize = tr.textureColorTableSize;
902:
903: // set the combine mode attributes
904:
905: combineRgbMode = tr.combineRgbMode;
906: combineAlphaMode = tr.combineAlphaMode;
907: combineRgbScale = tr.combineRgbScale;
908: combineAlphaScale = tr.combineAlphaScale;
909:
910: if (tr.combineRgbSrc != null) {
911: if (combineRgbSrc == null) {
912: combineRgbSrc = new int[3];
913: combineAlphaSrc = new int[3];
914: combineRgbFcn = new int[3];
915: combineAlphaFcn = new int[3];
916: }
917:
918: for (int i = 0; i < 3; i++) {
919: combineRgbSrc[i] = tr.combineRgbSrc[i];
920: combineAlphaSrc[i] = tr.combineAlphaSrc[i];
921: combineRgbFcn[i] = tr.combineRgbFcn[i];
922: combineAlphaFcn[i] = tr.combineAlphaFcn[i];
923: }
924: }
925: }
926:
927: final void sendMessage(int attrMask, Object attr1, Object attr2) {
928:
929: ArrayList univList = new ArrayList();
930: ArrayList gaList = Shape3DRetained.getGeomAtomsList(
931: mirror.users, univList);
932:
933: // Send to rendering attribute structure, regardless of
934: // whether there are users or not (alternate appearance case ..)
935: J3dMessage createMessage = new J3dMessage();
936: createMessage.threads = J3dThread.UPDATE_RENDERING_ATTRIBUTES;
937: createMessage.type = J3dMessage.TEXTUREATTRIBUTES_CHANGED;
938: createMessage.universe = null;
939: createMessage.args[0] = this ;
940: createMessage.args[1] = new Integer(attrMask);
941: createMessage.args[2] = attr1;
942: createMessage.args[3] = attr2;
943: createMessage.args[4] = new Integer(changedFrequent);
944: VirtualUniverse.mc.processMessage(createMessage);
945:
946: // System.err.println("univList.size is " + univList.size());
947: for (int i = 0; i < univList.size(); i++) {
948: createMessage = new J3dMessage();
949: createMessage.threads = J3dThread.UPDATE_RENDER;
950: createMessage.type = J3dMessage.TEXTUREATTRIBUTES_CHANGED;
951:
952: createMessage.universe = (VirtualUniverse) univList.get(i);
953: createMessage.args[0] = this ;
954: createMessage.args[1] = new Integer(attrMask);
955: createMessage.args[2] = attr1;
956:
957: ArrayList gL = (ArrayList) gaList.get(i);
958: GeometryAtom[] gaArr = new GeometryAtom[gL.size()];
959: gL.toArray(gaArr);
960: createMessage.args[3] = gaArr;
961:
962: VirtualUniverse.mc.processMessage(createMessage);
963: }
964: }
965:
966: void handleFrequencyChange(int bit) {
967: switch (bit) {
968: case TextureAttributes.ALLOW_MODE_WRITE:
969: case TextureAttributes.ALLOW_BLEND_COLOR_WRITE:
970: case TextureAttributes.ALLOW_TRANSFORM_WRITE:
971: case TextureAttributes.ALLOW_COLOR_TABLE_WRITE:
972: case TextureAttributes.ALLOW_COMBINE_WRITE: {
973: setFrequencyChangeMask(bit, bit);
974: }
975: default:
976: break;
977: }
978: }
979: }
|