The code below demonstrates what may be a bug in immediate-mode rendering of
a texture with image data set by reference. I tested this on:

Java3D 1.2 Maintenance Release Implementation
JDK 1.3
Windows NT 4.0
PentiumIII laptop (Dell Inspiron 7500) with ATI Rage Mobility P OpenGL

Also, despite statements in Java3D demos (and this mailing list) that a
BufferedImage of TYPE_3BYTE_BGR enables images by reference, I have not
found this to be true. Therefore, the code below uses a BufferedImage of
TYPE_CUSTOM, which is the only way I know of (on Windows) to avoid copying
from a BufferedImage to an ImageComponent2D.

Finally, if someone can point me to a better place to submit a Java3D bug,
I'd appreciate it. I noticed that I can view Java3D bugs in the Developer
Connection Bug Database, but I could not find a category for Java3D in the
"submit bug" form.

Regards,
Dave

---

import java.applet.Applet;
import java.awt.*;
import java.awt.color.*;
import java.awt.image.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;

/**
 * Demonstrates a bug in Java3D 1.2.
 *
 * Immediate-mode rendering of texture with image data set by reference
 * yields an (incorrect) all-white image. When by reference is not
specified,
 * the displayed image is (correct) shades of gray. Search for byReference
 * below.
 *
 * @author Dave Hale, Landmark Graphics
 * @version 06/14/2000
 */
public class ImmTexByRefBug extends Applet implements Runnable {

  public ImmTexByRefBug() {
    setLayout(new BorderLayout());
    GraphicsConfiguration config =
SimpleUniverse.getPreferredConfiguration();
    canvas = new Canvas3D(config);
    canvas.stopRenderer();
    add("Center",canvas);
    SimpleUniverse u = new SimpleUniverse(canvas);
    u.getViewingPlatform().setNominalViewingTransform();
    new Thread(this).start();
  }

  public void render() {
    if (gc == null) {
      gc = canvas.getGraphicsContext3D();
      gc.setAppearance(new Appearance());
      tc = new TexturedQuad();
    }
    gc.clear();
    gc.draw(tc);
    canvas.swap();
  }

  public void run() {
    while (true) {
      render();
      Thread.yield();
    }
  }

  public static void main(String[] args) {
    new MainFrame(new ImmTexByRefBug(),256,256);
  }

  private Canvas3D canvas;
  private GraphicsContext3D gc = null;
  private TexturedQuad tc = null;

  private class TexturedQuad extends Shape3D {

    public TexturedQuad() {

      QuadArray qa = new QuadArray(
        4,QuadArray.COORDINATES|QuadArray.TEXTURE_COORDINATE_2);
      this.setGeometry(qa);
      float[] coords = {
        -0.5f, -0.5f,  0.0f,
         0.5f, -0.5f,  0.0f,
         0.5f,  0.5f,  0.0f,
        -0.5f,  0.5f,  0.0f,
      };
      qa.setCoordinates(0,coords);
      int w = 256;
      int h = 256;
      float dw = 0.5f/(float)w;
      float dh = 0.5f/(float)h;
      float[] txcoords = {
             dw,      dh,
        1.0f-dw,      dh,
        1.0f-dw, 1.0f-dh,
             dw, 1.0f-dh,
      };
      qa.setTextureCoordinates(0,0,txcoords);

      Appearance a = new Appearance();
      this.setAppearance(a);

      // If byReference==true, then textured quad is white (WRONG!).
      // If byReference==false, then textured quad is shades of gray
(RIGHT).
      boolean byReference = true;
      boolean yUp = true;

      // This is the only way I've found to avoid the copy for RGB images.
      // Documentation says TYPE_3BYTE_BGR will also avoid the copy, but
      // it does not (another bug?).
      ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
      int[] nbits = {8,8,8};
      ColorModel cm = new ComponentColorModel(
        cs,nbits,false,false,Transparency.OPAQUE,0);
      int[] bandoffset = {0,1,2};
      WritableRaster wr = java.awt.image.Raster.createInterleavedRaster(
        DataBuffer.TYPE_BYTE,w,h,w*3,3,bandoffset,null);
      BufferedImage bi = new BufferedImage(cm,wr,false,null);
      byte[] data =
((DataBufferByte)bi.getRaster().getDataBuffer()).getData();
      for (int i=0,k=0; i<h; ++i) {
        for (int j=0; j<w; ++j) {
          byte c = (byte)((i+j)*255/(w+h-2));
          data[k++] = c;
          data[k++] = c;
          data[k++] = c;
        }
      }
      ImageComponent2D ic = new ImageComponent2D(
        ImageComponent.FORMAT_RGB8,w,h,byReference,yUp);
      ic.set(bi);
      Texture2D tx = new Texture2D(Texture.BASE_LEVEL,Texture.RGB,w,h);
      tx.setMagFilter(Texture.BASE_LEVEL_LINEAR);
      tx.setMinFilter(Texture.BASE_LEVEL_LINEAR);
      tx.setImage(0,ic);
      tx.setEnable(true);
      a.setTexture(tx);
    }
  }
}

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to