001: /*
002: * $RCSfile: ImageTexture.java,v $
003: *
004: * @(#)ImageTexture.java 1.25 99/03/24 16:26:11
005: *
006: * Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
007: *
008: * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
009: * modify and redistribute this software in source and binary code form,
010: * provided that i) this copyright notice and license appear on all copies of
011: * the software; and ii) Licensee does not utilize the software in a manner
012: * which is disparaging to Sun.
013: *
014: * This software is provided "AS IS," without a warranty of any kind. ALL
015: * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
016: * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
017: * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
018: * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
019: * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
020: * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
021: * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
022: * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
023: * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
024: * POSSIBILITY OF SUCH DAMAGES.
025: *
026: * This software is not designed or intended for use in on-line control of
027: * aircraft, air traffic, aircraft navigation or aircraft communications; or in
028: * the design, construction, operation or maintenance of any nuclear
029: * facility. Licensee represents and warrants that it will not use or
030: * redistribute the Software for such purposes.
031: *
032: * $Revision: 1.7 $
033: * $Date: 2006/04/24 16:45:54 $
034: * $State: Exp $
035: */
036: /*
037: * @author Rick Goldberg
038: * @author Doug Gehringer
039: * @author Nikolai V. Chr.
040: *
041: */
042: package org.jdesktop.j3d.loaders.vrml97.impl;
043:
044: import com.sun.j3d.utils.image.TextureLoader;
045: import java.awt.*;
046: import java.awt.Canvas;
047: import java.awt.image.*;
048: import java.awt.image.BufferedImage;
049: import java.net.MalformedURLException;
050: import java.net.URL;
051: import javax.media.j3d.ImageComponent2D;
052: import javax.media.j3d.Texture;
053: import javax.media.j3d.Texture2D;
054: import java.beans.*;
055: import java.beans.PropertyChangeListener;
056: import java.beans.PropertyChangeSupport;
057: import java.io.IOException;
058:
059: /** Description of the Class */
060: public class ImageTexture extends Node implements TextureSrc {
061:
062: // exposedField
063: MFString url;
064: SFBool repeatS;
065: SFBool repeatT;
066:
067: Texture impl;
068: Canvas observer = new Canvas();// dummy component
069:
070: boolean transparency = false;
071: PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
072: this );
073: final public static String TRANSPARENCY = "transparency";
074:
075: /**
076: *Constructor for the ImageTexture object
077: *
078: *@param loader Description of the Parameter
079: */
080: public ImageTexture(Loader loader) {
081: super (loader);
082: url = new MFString();
083: repeatS = new SFBool(true);
084: repeatT = new SFBool(true);
085: initFields();
086: }
087:
088: /**
089: *Constructor for the ImageTexture object
090: *
091: *@param loader Description of the Parameter
092: *@param url Description of the Parameter
093: *@param repeatS Description of the Parameter
094: *@param repeatT Description of the Parameter
095: */
096: ImageTexture(Loader loader, MFString url, SFBool repeatS,
097: SFBool repeatT) {
098: super (loader);
099: this .url = url;
100: this .repeatS = repeatS;
101: this .repeatT = repeatT;
102: initFields();
103: }
104:
105: /** Description of the Method */
106: void initImpl() {
107: impl = null;
108: doChangeUrl();
109: implReady = true;
110: }
111:
112: /**
113: * Description of the Method
114: *
115: *@return Description of the Return Value
116: */
117: public Object clone() {
118: return new ImageTexture(loader, (MFString) url.clone(),
119: (SFBool) repeatS.clone(), (SFBool) repeatT.clone());
120: }
121:
122: /** Sets the repeatS attribute of the ImageTexture object */
123: private void setRepeatS() {
124: if (repeatS.value == true) {
125: impl.setBoundaryModeS(Texture.WRAP);
126: } else {
127: impl.setBoundaryModeS(Texture.CLAMP);
128: }
129: }
130:
131: /** Sets the repeatT attribute of the ImageTexture object */
132: private void setRepeatT() {
133: if (repeatT.value == true) {
134: impl.setBoundaryModeT(Texture.WRAP);
135: } else {
136: impl.setBoundaryModeT(Texture.CLAMP);
137: }
138: }
139:
140: /**
141: * Description of the Method
142: *
143: *@param eventInName Description of the Parameter
144: *@param time Description of the Parameter
145: */
146: public void notifyMethod(String eventInName, double time) {
147: if (eventInName.equals("url")) {
148: doChangeUrl();
149: } else if (eventInName.equals("repeatS")) {
150: if (impl != null) {
151: setRepeatS();
152: }
153: } else if (eventInName.equals("repeatT")) {
154: if (impl != null) {
155: setRepeatT();
156: }
157: }
158: }
159:
160: /** Description of the Method */
161: void doChangeUrl() {
162: if (url.strings == null) {
163: return;
164: } else if (url.strings.length > 0) {// this could be an absolute url
165: // though
166: for (int i = 0; i < url.strings.length; i++) {
167: URL urlObj = null;
168: try {
169: urlObj = loader.stringToURL(url.strings[i]);
170: } catch (MalformedURLException e) {
171: continue;
172: }
173: if (urlObj == null) {
174: continue;
175: }
176: String suffix = url.strings[i].substring(
177: url.strings[i].lastIndexOf('.') + 1)
178: .toLowerCase();
179: String format = "RGBA";
180: TextureLoader tl = null;
181: if (suffix.equals("jpg") || suffix.equals("jpeg")
182: || suffix.equals("jp2") || suffix.equals("j2c")) {
183: format = "RGB";
184: }
185: if (suffix.equals("int") || suffix.equals("inta")
186: || suffix.equals("rgb")
187: || (suffix.equals("rgba"))
188: || suffix.equals("bw") || suffix.equals("sgi")) {
189: RgbFile file = null;
190: BufferedImage bi = null;
191: try {
192: file = new RgbFile(urlObj.openStream());
193:
194: bi = file.getImage();
195: } catch (IOException e) {
196: continue;
197: }
198: boolean luminance = suffix.equals("int")
199: || suffix.equals("inta")
200: || suffix.equals("bw");
201: boolean alpha = suffix.equals("inta")
202: || suffix.equals("rgba")
203: || isTransparent(bi);
204:
205: if (luminance && alpha) {
206: format = "LUM8_ALPHA8";
207: } else if (luminance) {
208: format = "LUMINANCE";
209: } else if (!alpha) {
210: format = "RGB";
211: }
212:
213: tl = new TextureLoader(bi, format,
214: TextureLoader.BY_REFERENCE, observer);
215: } else {
216: tl = new TextureLoader(urlObj, format,
217: TextureLoader.BY_REFERENCE, observer);
218: }
219: impl = tl.getTexture();
220: if (impl == null) {
221: continue;
222: }
223: impl.setMinFilter(Texture.BASE_LEVEL_LINEAR);
224: impl.setMagFilter(Texture.BASE_LEVEL_LINEAR);
225: impl.setEnable(true);
226: }
227: }
228: updateTransparency();
229: if (impl != null) {
230: setRepeatS();
231: setRepeatT();
232: }
233: }
234:
235: boolean isTransparent(Texture texture) {
236: if (texture.getImage(0) instanceof ImageComponent2D) {
237: ImageComponent2D comp = (ImageComponent2D) texture
238: .getImage(0);
239: return isTransparent(comp.getImage());
240: }
241: return false;
242: }
243:
244: boolean isTransparent(BufferedImage image) {
245: try {
246: ColorModel cm = image.getColorModel();
247: SampleModel sm = image.getSampleModel();
248: DataBuffer db = image.getRaster().getDataBuffer();
249: if (cm.hasAlpha() && cm.getTransparency() != cm.OPAQUE) {
250: for (int w = 0; w < image.getWidth(); w++) {
251: for (int h = 0; h < image.getHeight(); h++) {
252: if (cm.getAlpha(sm.getDataElements(w, h, null,
253: db)) != 255) {
254: image.flush();
255: return true;
256: }
257: }
258: }
259: }
260: } catch (IllegalStateException e) {
261: }
262: image.flush();
263: return false;
264: }
265:
266: public boolean getTransparency() {
267: return transparency;
268: }
269:
270: void updateTransparency() {
271: boolean newValue = false;
272: if (impl != null && impl instanceof Texture2D) {
273: newValue = isTransparent(impl);
274: }
275: if (newValue != transparency) {
276: transparency = newValue;
277: propertyChangeSupport.firePropertyChange(TRANSPARENCY,
278: null, Boolean.valueOf(newValue));
279: }
280: }
281:
282: public void addPropertyChangeListener(String n,
283: PropertyChangeListener l) {
284: propertyChangeSupport.addPropertyChangeListener(n, l);
285: }
286:
287: public void removePropertyChangeListener(String n,
288: PropertyChangeListener l) {
289: propertyChangeSupport.removePropertyChangeListener(n, l);
290: }
291:
292: /**
293: * Gets the implTexture attribute of the ImageTexture object
294: *
295: *@return The implTexture value
296: */
297: public Texture getImplTexture() {
298: return impl;
299: }
300:
301: /**
302: * Gets the type attribute of the ImageTexture object
303: *
304: *@return The type value
305: */
306: public String getType() {
307: return "ImageTexture";
308: }
309:
310: /** Description of the Method */
311: void initFields() {
312: url.init(this , FieldSpec, Field.EXPOSED_FIELD, "url");
313: repeatS.init(this , FieldSpec, Field.EXPOSED_FIELD, "repeatS");
314: repeatT.init(this , FieldSpec, Field.EXPOSED_FIELD, "repeatT");
315:
316: }
317: }
|