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