Areas


Topics

j3d.org

Textures

  1. How do I do 3D Texture mapping?
  2. How do I generate/update dynamic textures?
  3. Why does Java3D use so much memory for textures?
  4. How do I make video textures with JMF?
  5. How do I use multiple textures on one object?
  6. How do I blend multiple textures together?

Return to the main FAQ page for more questions and answers.

 

1. How do I do 3D Texture mapping?
Contributor: Kelvin Chung

3D Texture mapping works for all unix implementations of Java3D if they have OpenGL 1.2 or later installed. For Windows machines, prior to Java3D 1.2.1_03, 3D texture mapping is not supported. Texture 3D is support is dependent on GL_EXT_texture3D being defined in the header file gl.h when Java3D native code is compiled. So it will cause problem if it is run on a platform without texture3D support. This problem is fixed in v1.3 beta1.

For D3D version, v1.2.1_03 and earlier use DirectX 7.0 API which did not support 3D Texture. v1.3beta and later use DirectX 8.0, which supports volume textures.

You can query Canvas3D to see if the local card supports 3D textures by calling Canvas3D.queryProperties() with the value texture3DAvailable false.

The example program, Texture3DTest.java shows how to do this. Thanks to Doug Gehringer for providing this example.

 

2. How do I generate/update dynamic textures?

I want to create a texture and then over time play with some pixels without regenerating the entire image and then telling Java 3D to use the new values.

Java3D 1.2 does not provide a mechanism to do a partial update of texture images. 1.3 introduced the ImageComponent2D.setSubImage() method to allow you to change part of a texture without needing to reconstruct the whole texture object.

If you are using 1.3 then the call for the setSubImage() method takes an image to use as the source data to be copied and the bounds to use from that image and the bounds to copy into in the texture object. This is the quickest way to update the textures.

If you need to use 1.2 then using ImageComponent with the flag byReference and yUp is one way of achieving what you want. Using byReference enables you to change a part of the image on the application side.

 

3. Why does Java3D use so much memory for textures?

Like the rest of the scene graph structure, Java3D will make internal copies of the data so that it is not effected by your application code making changes to it. You can skip this intermediate copy by using the BY_REFERENCE capabilities. The restriction here is that you are not allowed to modify the contents of the data you hand Java3D unless it is provided as certain critical times.

Using by reference with textures is subject to a number of other conditions. Although you may have marked the texture as a by referenced capability, Java3D may still make an internal copy. Currently on PCs, Java3D will not make a copy of texture image for the following combinations of BufferedImage format and ImageComponent format(ofcourse, byReference and Yup should both be set to true)

BufferedImage format ImageComponentFormat
BufferedImage.TYPE_3BYTE_BGR ImageComponent.FORMAT_RGB8
ImageComponent.FORMAT_RGB
BufferedImage.TYPE_CUSTOM of form 3BYTE_RGB ImageComponent.FORMAT_RGB8
ImageComponent.FORMAT_RGB
BufferedImage.TYPE_CUSTOM of form 4BYTE_RGBA ImageComponent.FORMAT_RGBA8
ImageComponent.FORMAT_RGBA
BufferedImage.TYPE_BYTE_GRAY ImageComponent.FORMAT_CHANNEL8
On Solaris, the combinations below will not make a Java3D copy:
BufferedImage.TYPE_4BYTE_ABGR ImageComponent.FORMAT_RGBA8
ImageComponent.FORMAT_RGBA
BufferedImage.TYPE_CUSTOM of form 3BYTE_RGB ImageComponent.FORMAT_RGB8
ImageComponent.FORMAT_RGB
BufferedImage.TYPE_CUSTOM of form 4BYTE_RGBA ImageComponent.FORMAT_RGBA8
ImageComponent.FORMAT_RGBA
BufferedImage.TYPE_BYTE_GRAY ImageComponent.FORMAT_CHANNEL8

Note that an image associated with a live scene graph cannot be changed for by reference images unless you use the ImageComponent2D.TextureUpdater interface.

 

4. How do I make video textures with JMF?

Some of this is directly related to the previous question. A video texture is just a normal dynamic texture. The JMF team came up with an example of integrating JMF video streams with a Java 3D texture. This can be found under the JMF Tutorials area

 

5. How do I use multiple textures on one object?

The answer depends on what you mean by "multiple textures". Do you mean different textures on different parts of an object (for example, a different image on each face of a cube) of using multiple images combined together in layers to form a single texture.

To place different images on different faces, you will need to break the object up into several small objects - one for each image. Apply the appropriate texture to each of the smaller objects.

Layered textures together is called - multi-texturing. There are a variety of approaches to doing this and is answered in the next question...

 

6. How do I blend multiple textures together?

Under Java3D 1.2.x you can use the TextureUnitState class to combine a number of textures together. This combines the values for each texture equally. That is, if there are 3 textures registered, each pixel has it's color determined by weighting each colour by 1/3 and adding them together.

In J3D 1.3 there are new modes to allow full blending capabilities. This email gives more details on the capabilities and we expect to have some tutorials written shortly on it. For a simple example, have a look at the Dot-3 bump mapping tutorial on this site.