1 /*
2  * To change this template, choose Tools | Templates
3  * and open the template in the editor.
4  */
5 package jme3test.texture;
6 
7 import com.jme3.app.SimpleApplication;
8 import com.jme3.bounding.BoundingBox;
9 import com.jme3.light.PointLight;
10 import com.jme3.material.Material;
11 import com.jme3.math.ColorRGBA;
12 import com.jme3.math.Vector3f;
13 import com.jme3.scene.Geometry;
14 import com.jme3.scene.VertexBuffer;
15 import com.jme3.scene.VertexBuffer.Type;
16 import com.jme3.scene.VertexBuffer.Usage;
17 import com.jme3.scene.shape.Sphere;
18 import com.jme3.texture.Image;
19 import com.jme3.texture.Image.Format;
20 import com.jme3.texture.Texture;
21 import com.jme3.texture.Texture3D;
22 import com.jme3.util.BufferUtils;
23 import java.io.IOException;
24 import java.nio.ByteBuffer;
25 import java.nio.FloatBuffer;
26 import java.util.ArrayList;
27 
28 public class TestTexture3D extends SimpleApplication {
29 
main(String[] args)30     public static void main(String[] args) {
31         TestTexture3D app = new TestTexture3D();
32         app.start();
33     }
34 
35     @Override
simpleInitApp()36     public void simpleInitApp() {
37         //mouseInput.setCursorVisible(true);
38         flyCam.setMoveSpeed(10);
39         //creating a sphere
40         Sphere sphere = new Sphere(32, 32, 1);
41         //getting the boundingbox
42         sphere.updateBound();
43         BoundingBox bb = (BoundingBox) sphere.getBound();
44         Vector3f min = bb.getMin(null);
45         float[] ext = new float[]{bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2};
46         //we need to change the UV coordinates (the sphere is assumet to be inside the 3D image box)
47         sphere.clearBuffer(Type.TexCoord);
48         VertexBuffer vb = sphere.getBuffer(Type.Position);
49         FloatBuffer fb = (FloatBuffer) vb.getData();
50         float[] uvCoordinates = BufferUtils.getFloatArray(fb);
51         //now transform the coordinates so that they are in the range of <0; 1>
52         for (int i = 0; i < uvCoordinates.length; i += 3) {
53             uvCoordinates[i] = (uvCoordinates[i] - min.x) / ext[0];
54             uvCoordinates[i + 1] = (uvCoordinates[i + 1] - min.y) / ext[1];
55             uvCoordinates[i + 2] = (uvCoordinates[i + 2] - min.z) / ext[2];
56         }
57         //apply new texture coordinates
58         VertexBuffer uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
59         uvCoordsBuffer.setupData(Usage.Static, 3, com.jme3.scene.VertexBuffer.Format.Float,
60                 BufferUtils.createFloatBuffer(uvCoordinates));
61         sphere.setBuffer(uvCoordsBuffer);
62         //create geometry, and apply material and our 3D texture
63         Geometry g = new Geometry("sphere", sphere);
64         Material material = new Material(assetManager, "jme3test/texture/tex3D.j3md");
65         try {
66             Texture texture = this.getTexture();
67             material.setTexture("Texture", texture);
68         } catch (IOException e) {
69             e.printStackTrace();
70         }
71         g.setMaterial(material);
72         rootNode.attachChild(g);
73         //add some light so that it is visible
74         PointLight light = new PointLight();
75         light.setColor(ColorRGBA.White);
76         light.setPosition(new Vector3f(5, 5, 5));
77         light.setRadius(20);
78         rootNode.addLight(light);
79         light = new PointLight();
80         light.setColor(ColorRGBA.White);
81         light.setPosition(new Vector3f(-5, -5, -5));
82         light.setRadius(20);
83         rootNode.addLight(light);
84     }
85 
86     /**
87          * This method creates a RGB8 texture with the sizes of 10x10x10 pixels.
88          */
getTexture()89     private Texture getTexture() throws IOException {
90         ArrayList<ByteBuffer> data = new ArrayList<ByteBuffer>(1);
91         ByteBuffer bb = BufferUtils.createByteBuffer(10 * 10 * 10 * 3);//all data must be inside one buffer
92         for (int i = 0; i < 10; ++i) {
93             for (int j = 0; j < 10 * 10; ++j) {
94                 bb.put((byte) (255f*i/10f));
95                 bb.put((byte) (255f*i/10f));
96                 bb.put((byte) (255f));
97             }
98         }
99         bb.rewind();
100         data.add(bb);
101         return new Texture3D(new Image(Format.RGB8, 10, 10, 10, data));
102     }
103 }