git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8002 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
c26e4d8e42
commit
6c7082a7e3
@ -0,0 +1,224 @@ |
||||
/* |
||||
* Copyright (c) 2009-2010 jMonkeyEngine |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted provided that the following conditions are |
||||
* met: |
||||
* |
||||
* * Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* * Redistributions in binary form must reproduce the above copyright |
||||
* notice, this list of conditions and the following disclaimer in the |
||||
* documentation and/or other materials provided with the distribution. |
||||
* |
||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors |
||||
* may be used to endorse or promote products derived from this software |
||||
* without specific prior written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package com.jme3.texture; |
||||
|
||||
import com.jme3.export.JmeExporter; |
||||
import com.jme3.export.JmeImporter; |
||||
import com.jme3.export.InputCapsule; |
||||
import com.jme3.export.OutputCapsule; |
||||
import java.io.IOException; |
||||
|
||||
/** |
||||
* @author Maarten Steur |
||||
*/ |
||||
public class Texture3D extends Texture { |
||||
|
||||
private WrapMode wrapS = WrapMode.EdgeClamp; |
||||
private WrapMode wrapT = WrapMode.EdgeClamp; |
||||
private WrapMode wrapR = WrapMode.EdgeClamp; |
||||
|
||||
/** |
||||
* Creates a new two-dimensional texture with default attributes. |
||||
*/ |
||||
public Texture3D() { |
||||
super(); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new three-dimensional texture using the given image. |
||||
* @param img The image to use. |
||||
*/ |
||||
public Texture3D(Image img) { |
||||
super(); |
||||
setImage(img); |
||||
if (img.getFormat().isDepthFormat()) { |
||||
setMagFilter(MagFilter.Nearest); |
||||
setMinFilter(MinFilter.NearestNoMipMaps); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Creates a new three-dimensional texture for the purpose of offscreen |
||||
* rendering. |
||||
* |
||||
* @see com.jme3.texture.FrameBuffer |
||||
* |
||||
* @param width |
||||
* @param height |
||||
* @param depth |
||||
* @param format |
||||
*/ |
||||
public Texture3D(int width, int height, int depth, Image.Format format) { |
||||
this(new Image(format, width, height, depth, null)); |
||||
} |
||||
|
||||
/** |
||||
* Creates a new three-dimensional texture for the purpose of offscreen |
||||
* rendering. |
||||
* |
||||
* @see com.jme3.texture.FrameBuffer |
||||
* |
||||
* @param width |
||||
* @param height |
||||
* @param format |
||||
* @param numSamples |
||||
*/ |
||||
public Texture3D(int width, int height, int depth, int numSamples, Image.Format format) { |
||||
this(new Image(format, width, height, depth, null)); |
||||
getImage().setMultiSamples(numSamples); |
||||
} |
||||
|
||||
@Override |
||||
public Texture createSimpleClone() { |
||||
Texture3D clone = new Texture3D(); |
||||
createSimpleClone(clone); |
||||
return clone; |
||||
} |
||||
|
||||
@Override |
||||
public Texture createSimpleClone(Texture rVal) { |
||||
rVal.setWrap(WrapAxis.S, wrapS); |
||||
rVal.setWrap(WrapAxis.T, wrapT); |
||||
rVal.setWrap(WrapAxis.R, wrapR); |
||||
return super.createSimpleClone(rVal); |
||||
} |
||||
|
||||
/** |
||||
* <code>setWrap</code> sets the wrap mode of this texture for a |
||||
* particular axis. |
||||
* |
||||
* @param axis |
||||
* the texture axis to define a wrapmode on. |
||||
* @param mode |
||||
* the wrap mode for the given axis of the texture. |
||||
* @throws IllegalArgumentException |
||||
* if axis or mode are null |
||||
*/ |
||||
public void setWrap(WrapAxis axis, WrapMode mode) { |
||||
if (mode == null) { |
||||
throw new IllegalArgumentException("mode can not be null."); |
||||
} else if (axis == null) { |
||||
throw new IllegalArgumentException("axis can not be null."); |
||||
} |
||||
switch (axis) { |
||||
case S: |
||||
this.wrapS = mode; |
||||
break; |
||||
case T: |
||||
this.wrapT = mode; |
||||
break; |
||||
case R: |
||||
this.wrapR = mode; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* <code>setWrap</code> sets the wrap mode of this texture for all axis. |
||||
* |
||||
* @param mode |
||||
* the wrap mode for the given axis of the texture. |
||||
* @throws IllegalArgumentException |
||||
* if mode is null |
||||
*/ |
||||
public void setWrap(WrapMode mode) { |
||||
if (mode == null) { |
||||
throw new IllegalArgumentException("mode can not be null."); |
||||
} |
||||
this.wrapS = mode; |
||||
this.wrapT = mode; |
||||
this.wrapR = mode; |
||||
} |
||||
|
||||
/** |
||||
* <code>getWrap</code> returns the wrap mode for a given coordinate axis |
||||
* on this texture. |
||||
* |
||||
* @param axis |
||||
* the axis to return for |
||||
* @return the wrap mode of the texture. |
||||
* @throws IllegalArgumentException |
||||
* if axis is null |
||||
*/ |
||||
public WrapMode getWrap(WrapAxis axis) { |
||||
switch (axis) { |
||||
case S: |
||||
return wrapS; |
||||
case T: |
||||
return wrapT; |
||||
case R: |
||||
return wrapR; |
||||
} |
||||
throw new IllegalArgumentException("invalid WrapAxis: " + axis); |
||||
} |
||||
|
||||
@Override |
||||
public Type getType() { |
||||
return Type.ThreeDimensional; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object other) { |
||||
if (!(other instanceof Texture3D)) { |
||||
return false; |
||||
} |
||||
Texture3D that = (Texture3D) other; |
||||
if (this.getWrap(WrapAxis.S) != that.getWrap(WrapAxis.S)) { |
||||
return false; |
||||
} |
||||
if (this.getWrap(WrapAxis.T) != that.getWrap(WrapAxis.T)) { |
||||
return false; |
||||
} |
||||
if (this.getWrap(WrapAxis.R) != that.getWrap(WrapAxis.R)) { |
||||
return false; |
||||
} |
||||
return super.equals(other); |
||||
} |
||||
|
||||
@Override |
||||
public void write(JmeExporter e) throws IOException { |
||||
super.write(e); |
||||
OutputCapsule capsule = e.getCapsule(this); |
||||
capsule.write(wrapS, "wrapS", WrapMode.EdgeClamp); |
||||
capsule.write(wrapT, "wrapT", WrapMode.EdgeClamp); |
||||
capsule.write(wrapR, "wrapR", WrapMode.EdgeClamp); |
||||
} |
||||
|
||||
@Override |
||||
public void read(JmeImporter e) throws IOException { |
||||
super.read(e); |
||||
InputCapsule capsule = e.getCapsule(this); |
||||
wrapS = capsule.readEnum("wrapS", WrapMode.class, WrapMode.EdgeClamp); |
||||
wrapT = capsule.readEnum("wrapT", WrapMode.class, WrapMode.EdgeClamp); |
||||
wrapR = capsule.readEnum("wrapR", WrapMode.class, WrapMode.EdgeClamp); |
||||
} |
||||
} |
@ -0,0 +1,103 @@ |
||||
/* |
||||
* To change this template, choose Tools | Templates |
||||
* and open the template in the editor. |
||||
*/ |
||||
package jme3test.texture; |
||||
|
||||
import com.jme3.app.SimpleApplication; |
||||
import com.jme3.bounding.BoundingBox; |
||||
import com.jme3.light.PointLight; |
||||
import com.jme3.material.Material; |
||||
import com.jme3.math.ColorRGBA; |
||||
import com.jme3.math.Vector3f; |
||||
import com.jme3.scene.Geometry; |
||||
import com.jme3.scene.VertexBuffer; |
||||
import com.jme3.scene.VertexBuffer.Type; |
||||
import com.jme3.scene.VertexBuffer.Usage; |
||||
import com.jme3.scene.shape.Sphere; |
||||
import com.jme3.texture.Image; |
||||
import com.jme3.texture.Image.Format; |
||||
import com.jme3.texture.Texture; |
||||
import com.jme3.texture.Texture3D; |
||||
import com.jme3.util.BufferUtils; |
||||
import java.io.IOException; |
||||
import java.nio.ByteBuffer; |
||||
import java.nio.FloatBuffer; |
||||
import java.util.ArrayList; |
||||
|
||||
public class TestTexture3D extends SimpleApplication { |
||||
|
||||
public static void main(String[] args) { |
||||
TestTexture3D app = new TestTexture3D(); |
||||
app.start(); |
||||
} |
||||
|
||||
@Override |
||||
public void simpleInitApp() { |
||||
//mouseInput.setCursorVisible(true);
|
||||
flyCam.setMoveSpeed(10); |
||||
//creating a sphere
|
||||
Sphere sphere = new Sphere(32, 32, 1); |
||||
//getting the boundingbox
|
||||
sphere.updateBound(); |
||||
BoundingBox bb = (BoundingBox) sphere.getBound(); |
||||
Vector3f min = bb.getMin(null); |
||||
float[] ext = new float[]{bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2}; |
||||
//we need to change the UV coordinates (the sphere is assumet to be inside the 3D image box)
|
||||
sphere.clearBuffer(Type.TexCoord); |
||||
VertexBuffer vb = sphere.getBuffer(Type.Position); |
||||
FloatBuffer fb = (FloatBuffer) vb.getData(); |
||||
float[] uvCoordinates = BufferUtils.getFloatArray(fb); |
||||
//now transform the coordinates so that they are in the range of <0; 1>
|
||||
for (int i = 0; i < uvCoordinates.length; i += 3) { |
||||
uvCoordinates[i] = (uvCoordinates[i] - min.x) / ext[0]; |
||||
uvCoordinates[i + 1] = (uvCoordinates[i + 1] - min.y) / ext[1]; |
||||
uvCoordinates[i + 2] = (uvCoordinates[i + 2] - min.z) / ext[2]; |
||||
} |
||||
//apply new texture coordinates
|
||||
VertexBuffer uvCoordsBuffer = new VertexBuffer(Type.TexCoord); |
||||
uvCoordsBuffer.setupData(Usage.Static, 3, com.jme3.scene.VertexBuffer.Format.Float, |
||||
BufferUtils.createFloatBuffer(uvCoordinates)); |
||||
sphere.setBuffer(uvCoordsBuffer); |
||||
//create geometry, and apply material and our 3D texture
|
||||
Geometry g = new Geometry("sphere", sphere); |
||||
Material material = new Material(assetManager, "jme3test/texture/tex3D.j3md"); |
||||
try { |
||||
Texture texture = this.getTexture(); |
||||
material.setTexture("Texture", texture); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
g.setMaterial(material); |
||||
rootNode.attachChild(g); |
||||
//add some light so that it is visible
|
||||
PointLight light = new PointLight(); |
||||
light.setColor(ColorRGBA.White); |
||||
light.setPosition(new Vector3f(5, 5, 5)); |
||||
light.setRadius(20); |
||||
rootNode.addLight(light); |
||||
light = new PointLight(); |
||||
light.setColor(ColorRGBA.White); |
||||
light.setPosition(new Vector3f(-5, -5, -5)); |
||||
light.setRadius(20); |
||||
rootNode.addLight(light); |
||||
} |
||||
|
||||
/** |
||||
* This method creates a RGB8 texture with the sizes of 10x10x10 pixels. |
||||
*/ |
||||
private Texture getTexture() throws IOException { |
||||
ArrayList<ByteBuffer> data = new ArrayList<ByteBuffer>(1); |
||||
ByteBuffer bb = BufferUtils.createByteBuffer(10 * 10 * 10 * 3);//all data must be inside one buffer
|
||||
for (int i = 0; i < 10; ++i) { |
||||
for (int j = 0; j < 10 * 10; ++j) { |
||||
bb.put((byte) (255f*i/10f)); |
||||
bb.put((byte) (255f*i/10f)); |
||||
bb.put((byte) (255f)); |
||||
} |
||||
} |
||||
bb.rewind(); |
||||
data.add(bb); |
||||
return new Texture3D(new Image(Format.RGB8, 10, 10, 10, data)); |
||||
} |
||||
} |
@ -0,0 +1,7 @@ |
||||
uniform sampler3D m_Texture; |
||||
|
||||
varying vec3 texCoord; |
||||
|
||||
void main(){ |
||||
gl_FragColor= texture3D(m_Texture,texCoord); |
||||
} |
@ -0,0 +1,16 @@ |
||||
MaterialDef My MaterialDef { |
||||
|
||||
MaterialParameters { |
||||
Texture3D Texture |
||||
} |
||||
|
||||
Technique { |
||||
VertexShader GLSL100: jme3test/texture/tex3D.vert |
||||
FragmentShader GLSL100: jme3test/texture/tex3D.frag |
||||
|
||||
WorldParameters { |
||||
WorldViewProjectionMatrix |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,11 @@ |
||||
uniform mat4 g_WorldViewProjectionMatrix; |
||||
|
||||
attribute vec3 inTexCoord; |
||||
attribute vec3 inPosition; |
||||
|
||||
varying vec3 texCoord; |
||||
|
||||
void main(){ |
||||
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition,1.0); |
||||
texCoord=inTexCoord; |
||||
} |
Loading…
Reference in new issue