I'm trying to take advantage of byReference and yUp in ImageComponent2D to
create a texture that I can draw quickly onto. The texture should act like a
background picture over which I draw circles, lines, squares etc. It's
important that the texture update quickly because the drawing occurs every
frame to create an animation on the surface of a Shape3D. I have tried to
follow the instructions in the API but haven't noticed any difference in
speed whether or not byReference and yUp are true or false (Bug?). When the
background texture is large (1024 X 1024) the drawing process just takes too
long to be effective for animation.
I'm including a simple test program that illustrates the problem. Click the
button on the applet to change the color of a square drawn onto the texture.
Notice how long it takes. It seems like Java3D must be doing a whole lot
more work than necessary just to draw a square onto an image.
Does someone have a better idea for how I could implement my idea? For
instance, is there a way to avoid the calls to ImageComponent2D.set() and
Texture.setImage() and just draw to the image directly?
Java3D team: is this a functionality that you could provide?
Since byReference and yUp don't seem to make a difference, I wonder if this
is a bug with Java3D. I know that there has been discussion about this topic
but some of the messages are beyond my understanding. The discussions in
particular that deal with WritableRasters confuse me. If there is someone
out there that understands what I need and can tweak my code, please tweak
my code.
Stumped,
Raffi
Here is the program, "TextureDraw.java".
<<TextureDraw.java>>
import java.applet.Applet;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import java.awt.*;
import com.sun.j3d.utils.image.TextureLoader;
import java.awt.image.BufferedImage;
public class TextureDraw extends Applet {
MyAppearance appearance = new MyAppearance();
public BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
Box b = new Box( 0.3f, 0.3f, 0.3f,
Primitive.GENERATE_TEXTURE_COORDS, appearance );
objRoot.addChild( b );
objRoot.compile();
return objRoot;
}
public TextureDraw() {
setLayout(new BorderLayout());
Canvas3D c = new
Canvas3D(SimpleUniverse.getPreferredConfiguration());
add("Center", c);
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
Button b = new Button( "Edit" );
b.addActionListener( new ActionListener(){
public void actionPerformed( ActionEvent e ){
appearance.change();
}
});
add( "North", b );
}
public static void main(String[] args) {
new MainFrame(new TextureDraw(), 256, 256);
}
class MyAppearance extends Appearance{
Color color;
DrawingTexture tex;
int w = 1024, h = 1024;
public MyAppearance(){
BufferedImage image = new BufferedImage( w, h,
BufferedImage.TYPE_3BYTE_BGR );
Graphics g = image.getGraphics();
g.setColor( Color.gray );
g.fillRect( 0, 0, w, h );
tex = new DrawingTexture( image, w, h );
setTexture( tex );
}
public void change(){
color = color == Color.red ? Color.white : Color.red;
Graphics g = tex.getGraphics();
g.setColor( color );
g.fillRect( w/3, h/3, w/3, h/3 );
tex.swap();
}
}
class DrawingTexture extends Texture2D{
private Graphics graphics;
private Image backgroundImage;
private BufferedImage image;
private ImageComponent2D[] imcomp = new ImageComponent2D[2];
private int curImcomp = 0;
private int width, height;
final boolean byReference = true;
final boolean yUp = true;
public DrawingTexture( Image img, int w, int h ){
super( Texture.BASE_LEVEL, Texture.RGB, w, h );
setCapability( Texture.ALLOW_IMAGE_WRITE );
width = w;
height = h;
backgroundImage = img;
image = new BufferedImage( w, h, BufferedImage.TYPE_3BYTE_BGR );
graphics = image.getGraphics();
drawBackground();
imcomp[0] = new ImageComponent2D( ImageComponent.FORMAT_RGB, w,
h, byReference, yUp );
imcomp[0].set( image );
imcomp[1] = new ImageComponent2D( ImageComponent.FORMAT_RGB, w,
h, byReference, yUp );
imcomp[1].set( image );
setImage( 0, imcomp[curImcomp] );
}
public Graphics getGraphics(){
return graphics;
}
public void swap(){
curImcomp = curImcomp == 0 ? 1 : 0;
imcomp[curImcomp].set( image );
setImage( 0, imcomp[curImcomp] );
}
public void drawBackground(){
graphics.drawImage( backgroundImage, 0, 0, null );
}
}
}
TextureDraw.java