diff --git a/engine/src/core-plugins/com/jme3/texture/plugins/DDSLoader.java b/engine/src/core-plugins/com/jme3/texture/plugins/DDSLoader.java index 81fb858fc..d89767dc9 100644 --- a/engine/src/core-plugins/com/jme3/texture/plugins/DDSLoader.java +++ b/engine/src/core-plugins/com/jme3/texture/plugins/DDSLoader.java @@ -29,7 +29,6 @@ * 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.plugins; import com.jme3.asset.AssetInfo; @@ -62,14 +61,11 @@ public class DDSLoader implements AssetLoader { private static final Logger logger = Logger.getLogger(DDSLoader.class.getName()); private static final boolean forceRGBA = false; - private static final int DDSD_MANDATORY = 0x1007; private static final int DDSD_MANDATORY_DX10 = 0x6; - private static final int DDSD_MIPMAPCOUNT = 0x20000; private static final int DDSD_LINEARSIZE = 0x80000; private static final int DDSD_DEPTH = 0x800000; - private static final int DDPF_ALPHAPIXELS = 0x1; private static final int DDPF_FOURCC = 0x4; private static final int DDPF_RGB = 0x40; @@ -79,31 +75,24 @@ public class DDSLoader implements AssetLoader { private static final int DDPF_ALPHA = 0x2; // used by NVTextureTools to mark normal images. private static final int DDPF_NORMAL = 0x80000000; - private static final int SWIZZLE_xGxR = 0x78477852; - private static final int DDSCAPS_COMPLEX = 0x8; private static final int DDSCAPS_TEXTURE = 0x1000; private static final int DDSCAPS_MIPMAP = 0x400000; - private static final int DDSCAPS2_CUBEMAP = 0x200; private static final int DDSCAPS2_VOLUME = 0x200000; - private static final int PF_DXT1 = 0x31545844; private static final int PF_DXT3 = 0x33545844; private static final int PF_DXT5 = 0x35545844; private static final int PF_ATI1 = 0x31495441; private static final int PF_ATI2 = 0x32495441; // 0x41544932; private static final int PF_DX10 = 0x30315844; // a DX10 format - private static final int DX10DIM_BUFFER = 0x1, - DX10DIM_TEXTURE1D = 0x2, - DX10DIM_TEXTURE2D = 0x3, - DX10DIM_TEXTURE3D = 0x4; - + DX10DIM_TEXTURE1D = 0x2, + DX10DIM_TEXTURE2D = 0x3, + DX10DIM_TEXTURE3D = 0x4; private static final int DX10MISC_GENERATE_MIPS = 0x1, - DX10MISC_TEXTURECUBE = 0x4; - + DX10MISC_TEXTURECUBE = 0x4; private static final double LOG2 = Math.log(2); private int width; private int height; @@ -115,60 +104,62 @@ public class DDSLoader implements AssetLoader { private int caps2; private boolean directx10; private boolean compressed; + private boolean texture3D; private boolean grayscaleOrAlpha; private boolean normal; private Format pixelFormat; private int bpp; private int[] sizes; - private int redMask, greenMask, blueMask, alphaMask; + private int redMask, greenMask, blueMask, alphaMask; private DataInput in; public DDSLoader() { } - public Object load(AssetInfo info) throws IOException{ - if (!(info.getKey() instanceof TextureKey)) + public Object load(AssetInfo info) throws IOException { + if (!(info.getKey() instanceof TextureKey)) { throw new IllegalArgumentException("Texture assets must be loaded using a TextureKey"); + } InputStream stream = info.openStream(); in = new LittleEndien(stream); loadHeader(); - ArrayList data = readData( ((TextureKey)info.getKey()).isFlipY() ); - stream.close(); - return new Image(pixelFormat, width, height, 0, data, sizes); + ArrayList data = readData(((TextureKey) info.getKey()).isFlipY()); + stream.close(); + return new Image(pixelFormat, width, height, depth, data, sizes); } - public Image load(InputStream stream) throws IOException{ + public Image load(InputStream stream) throws IOException { in = new LittleEndien(stream); loadHeader(); ArrayList data = readData(false); - return new Image(pixelFormat, width, height, 0, data, sizes); + return new Image(pixelFormat, width, height, depth, data, sizes); } - private void loadDX10Header() throws IOException{ + private void loadDX10Header() throws IOException { int dxgiFormat = in.readInt(); - if (dxgiFormat != 83){ - throw new IOException("Only DXGI_FORMAT_BC5_UNORM " + - "is supported for DirectX10 DDS! Got: "+dxgiFormat); + if (dxgiFormat != 83) { + throw new IOException("Only DXGI_FORMAT_BC5_UNORM " + + "is supported for DirectX10 DDS! Got: " + dxgiFormat); } pixelFormat = Format.LATC; bpp = 8; compressed = true; int resDim = in.readInt(); - if (resDim == DX10DIM_TEXTURE3D){ - // mark texture as 3D + if (resDim == DX10DIM_TEXTURE3D) { + texture3D = true; } int miscFlag = in.readInt(); int arraySize = in.readInt(); - if (is(miscFlag, DX10MISC_TEXTURECUBE)){ + if (is(miscFlag, DX10MISC_TEXTURECUBE)) { // mark texture as cube - if (arraySize != 6){ + if (arraySize != 6) { throw new IOException("Cubemaps should consist of 6 images!"); } } - + in.skipBytes(4); // skip reserved value } @@ -185,7 +176,7 @@ public class DDSLoader implements AssetLoader { if (!is(flags, DDSD_MANDATORY) && !is(flags, DDSD_MANDATORY_DX10)) { throw new IOException("Mandatory flags missing"); } - + height = in.readInt(); width = in.readInt(); pitchOrSize = in.readInt(); @@ -199,17 +190,23 @@ public class DDSLoader implements AssetLoader { caps2 = in.readInt(); in.skipBytes(12); - if (!directx10){ + + if (!directx10) { if (!is(caps1, DDSCAPS_TEXTURE)) { throw new IOException("File is not a texture"); } - if (depth <= 0) + if (depth <= 0) { depth = 1; + } if (is(caps2, DDSCAPS2_CUBEMAP)) { depth = 6; // somewhat of a hack, force loading 6 textures if a cubemap } + + if (is(caps2, DDSCAPS2_VOLUME)) { + texture3D = true; + } } int expectedMipmaps = 1 + (int) Math.ceil(Math.log(Math.max(height, width)) / LOG2); @@ -220,14 +217,14 @@ public class DDSLoader implements AssetLoader { } else if (mipMapCount != expectedMipmaps) { // changed to warning- images often do not have the required amount, // or specify that they have mipmaps but include only the top level.. - logger.log(Level.WARNING, "Got {0} mipmaps, expected {1}", + logger.log(Level.WARNING, "Got {0} mipmaps, expected {1}", new Object[]{mipMapCount, expectedMipmaps}); } } else { mipMapCount = 1; } - if (directx10){ + if (directx10) { loadDX10Header(); } @@ -268,7 +265,7 @@ public class DDSLoader implements AssetLoader { case PF_DXT5: bpp = 8; pixelFormat = Image.Format.DXT5; - if (swizzle == SWIZZLE_xGxR){ + if (swizzle == SWIZZLE_xGxR) { normal = true; } break; @@ -297,7 +294,7 @@ public class DDSLoader implements AssetLoader { logger.warning("Must use linear size with fourcc"); pitchOrSize = size; } else if (pitchOrSize != size) { - logger.log(Level.WARNING, "Expected size = {0}, real = {1}", + logger.log(Level.WARNING, "Expected size = {0}, real = {1}", new Object[]{size, pitchOrSize}); } } else { @@ -321,7 +318,7 @@ public class DDSLoader implements AssetLoader { } else { pixelFormat = Format.RGB8; } - } else if (is(pfFlags, DDPF_GRAYSCALE) && is(pfFlags, DDPF_ALPHAPIXELS)){ + } else if (is(pfFlags, DDPF_GRAYSCALE) && is(pfFlags, DDPF_ALPHAPIXELS)) { switch (bpp) { case 16: pixelFormat = Format.Luminance8Alpha8; @@ -368,7 +365,7 @@ public class DDSLoader implements AssetLoader { logger.warning("Linear size said to contain valid value but does not"); pitchOrSize = size; } else if (pitchOrSize != size) { - logger.log(Level.WARNING, "Expected size = {0}, real = {1}", + logger.log(Level.WARNING, "Expected size = {0}, real = {1}", new Object[]{size, pitchOrSize}); } } else { @@ -464,9 +461,9 @@ public class DDSLoader implements AssetLoader { */ public ByteBuffer readRGB2D(boolean flip, int totalSize) throws IOException { int redCount = count(redMask), - blueCount = count(blueMask), - greenCount = count(greenMask), - alphaCount = count(alphaMask); + blueCount = count(blueMask), + greenCount = count(greenMask), + alphaCount = count(alphaMask); if (redMask == 0x00FF0000 && greenMask == 0x0000FF00 && blueMask == 0x000000FF) { if (alphaMask == 0xFF000000 && bpp == 32) { @@ -536,23 +533,20 @@ public class DDSLoader implements AssetLoader { int mipWidth = width; int mipHeight = height; - int offset = 0; for (int mip = 0; mip < mipMapCount; mip++) { - if (flip){ + if (flip) { byte[] data = new byte[sizes[mip]]; in.readFully(data); ByteBuffer wrapped = ByteBuffer.wrap(data); wrapped.rewind(); ByteBuffer flipped = DXTFlipper.flipDXT(wrapped, mipWidth, mipHeight, pixelFormat); buffer.put(flipped); - }else{ + } else { byte[] data = new byte[sizes[mip]]; in.readFully(data); buffer.put(data); } - offset += sizes[mip]; - mipWidth = Math.max(mipWidth / 2, 1); mipHeight = Math.max(mipHeight / 2, 1); } @@ -561,6 +555,153 @@ public class DDSLoader implements AssetLoader { return buffer; } + /** + * Reads a grayscale image with mipmaps from the InputStream + * @param flip Flip the loaded image by Y axis + * @param totalSize Total size of the image in bytes including the mipmaps + * @return A ByteBuffer containing the grayscale image data with mips. + * @throws java.io.IOException If an error occured while reading from InputStream + */ + public ByteBuffer readGrayscale3D(boolean flip, int totalSize) throws IOException { + ByteBuffer buffer = BufferUtils.createByteBuffer(totalSize * depth); + + if (bpp == 8) { + logger.finest("Source image format: R8"); + } + + assert bpp == pixelFormat.getBitsPerPixel(); + + + for (int i = 0; i < depth; i++) { + int mipWidth = width; + int mipHeight = height; + + for (int mip = 0; mip < mipMapCount; mip++) { + byte[] data = new byte[sizes[mip]]; + in.readFully(data); + if (flip) { + data = flipData(data, mipWidth * bpp / 8, mipHeight); + } + buffer.put(data); + + mipWidth = Math.max(mipWidth / 2, 1); + mipHeight = Math.max(mipHeight / 2, 1); + } + } + buffer.rewind(); + return buffer; + } + + /** + * Reads an uncompressed RGB or RGBA image. + * + * @param flip Flip the image on the Y axis + * @param totalSize Size of the image in bytes including mipmaps + * @return ByteBuffer containing image data with mipmaps in the format specified by pixelFormat_ + * @throws java.io.IOException If an error occured while reading from InputStream + */ + public ByteBuffer readRGB3D(boolean flip, int totalSize) throws IOException { + int redCount = count(redMask), + blueCount = count(blueMask), + greenCount = count(greenMask), + alphaCount = count(alphaMask); + + if (redMask == 0x00FF0000 && greenMask == 0x0000FF00 && blueMask == 0x000000FF) { + if (alphaMask == 0xFF000000 && bpp == 32) { + logger.finest("Data source format: BGRA8"); + } else if (bpp == 24) { + logger.finest("Data source format: BGR8"); + } + } + + int sourcebytesPP = bpp / 8; + int targetBytesPP = pixelFormat.getBitsPerPixel() / 8; + + ByteBuffer dataBuffer = BufferUtils.createByteBuffer(totalSize * depth); + + for (int k = 0; k < depth; k++) { + // ByteBuffer dataBuffer = BufferUtils.createByteBuffer(totalSize); + int mipWidth = width; + int mipHeight = height; + int offset = k * totalSize; + byte[] b = new byte[sourcebytesPP]; + for (int mip = 0; mip < mipMapCount; mip++) { + for (int y = 0; y < mipHeight; y++) { + for (int x = 0; x < mipWidth; x++) { + in.readFully(b); + + int i = byte2int(b); + + byte red = (byte) (((i & redMask) >> redCount)); + byte green = (byte) (((i & greenMask) >> greenCount)); + byte blue = (byte) (((i & blueMask) >> blueCount)); + byte alpha = (byte) (((i & alphaMask) >> alphaCount)); + + if (flip) { + dataBuffer.position(offset + ((mipHeight - y - 1) * mipWidth + x) * targetBytesPP); + } + //else + // dataBuffer.position(offset + (y * width + x) * targetBytesPP); + + if (alphaMask == 0) { + dataBuffer.put(red).put(green).put(blue); + } else { + dataBuffer.put(red).put(green).put(blue).put(alpha); + } + } + } + + offset += (mipWidth * mipHeight * targetBytesPP); + + mipWidth = Math.max(mipWidth / 2, 1); + mipHeight = Math.max(mipHeight / 2, 1); + } + } + dataBuffer.rewind(); + return dataBuffer; + } + + /** + * Reads a DXT compressed image from the InputStream + * + * @param totalSize Total size of the image in bytes, including mipmaps + * @return ByteBuffer containing compressed DXT image in the format specified by pixelFormat_ + * @throws java.io.IOException If an error occured while reading from InputStream + */ + public ByteBuffer readDXT3D(boolean flip, int totalSize) throws IOException { + logger.finest("Source image format: DXT"); + + ByteBuffer bufferAll = BufferUtils.createByteBuffer(totalSize * depth); + + for (int i = 0; i < depth; i++) { + ByteBuffer buffer = BufferUtils.createByteBuffer(totalSize); + int mipWidth = width; + int mipHeight = height; + for (int mip = 0; mip < mipMapCount; mip++) { + if (flip) { + byte[] data = new byte[sizes[mip]]; + in.readFully(data); + ByteBuffer wrapped = ByteBuffer.wrap(data); + wrapped.rewind(); + ByteBuffer flipped = DXTFlipper.flipDXT(wrapped, mipWidth, mipHeight, pixelFormat); + flipped.rewind(); + buffer.put(flipped); + } else { + byte[] data = new byte[sizes[mip]]; + in.readFully(data); + buffer.put(data); + } + + mipWidth = Math.max(mipWidth / 2, 1); + mipHeight = Math.max(mipHeight / 2, 1); + } + buffer.rewind(); + bufferAll.put(buffer); + } + + return bufferAll; + } + /** * Reads the image data from the InputStream in the required format. * If the file contains a cubemap image, it is loaded as 6 ByteBuffers @@ -583,19 +724,28 @@ public class DDSLoader implements AssetLoader { } ArrayList allMaps = new ArrayList(); - if (depth > 1){ - for (int i = 0; i < depth; i++){ + if (depth > 1 && !texture3D) { + for (int i = 0; i < depth; i++) { if (compressed) { - allMaps.add(readDXT2D(flip,totalSize)); + allMaps.add(readDXT2D(flip, totalSize)); } else if (grayscaleOrAlpha) { allMaps.add(readGrayscale2D(flip, totalSize)); } else { allMaps.add(readRGB2D(flip, totalSize)); } } + } else if (texture3D) { + if (compressed) { + allMaps.add(readDXT3D(flip, totalSize)); + } else if (grayscaleOrAlpha) { + allMaps.add(readGrayscale3D(flip, totalSize)); + } else { + allMaps.add(readRGB3D(flip, totalSize)); + } + } else { if (compressed) { - allMaps.add(readDXT2D(flip,totalSize)); + allMaps.add(readDXT2D(flip, totalSize)); } else if (grayscaleOrAlpha) { allMaps.add(readGrayscale2D(flip, totalSize)); } else { diff --git a/engine/src/core/com/jme3/asset/TextureKey.java b/engine/src/core/com/jme3/asset/TextureKey.java index 5abb52981..7dc9ee071 100644 --- a/engine/src/core/com/jme3/asset/TextureKey.java +++ b/engine/src/core/com/jme3/asset/TextureKey.java @@ -29,7 +29,6 @@ * 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.asset; import com.jme3.export.JmeExporter; @@ -39,6 +38,7 @@ import com.jme3.export.OutputCapsule; import com.jme3.texture.Image; import com.jme3.texture.Texture; import com.jme3.texture.Texture2D; +import com.jme3.texture.Texture3D; import com.jme3.texture.TextureCubeMap; import java.io.IOException; import java.nio.ByteBuffer; @@ -48,23 +48,24 @@ public class TextureKey extends AssetKey { private boolean generateMips; private boolean flipY; private boolean asCube; + private boolean asTexture3D; private int anisotropy; - public TextureKey(String name, boolean flipY){ + public TextureKey(String name, boolean flipY) { super(name); this.flipY = flipY; } - public TextureKey(String name){ + public TextureKey(String name) { super(name); this.flipY = true; } - public TextureKey(){ + public TextureKey() { } @Override - public String toString(){ + public String toString() { return name + (flipY ? " (Flipped)" : "") + (asCube ? " (Cube)" : "") + (generateMips ? " (Mipmaped)" : ""); } @@ -73,39 +74,43 @@ public class TextureKey extends AssetKey { * @return true to enable smart cache */ @Override - public boolean useSmartCache(){ + public boolean useSmartCache() { return true; } @Override - public Object createClonedInstance(Object asset){ + public Object createClonedInstance(Object asset) { Texture tex = (Texture) asset; return tex.createSimpleClone(); } @Override - public Object postProcess(Object asset){ + public Object postProcess(Object asset) { Image img = (Image) asset; - if (img == null) + if (img == null) { return null; + } Texture tex; - if (isAsCube()){ - if (isFlipY()){ + if (isAsCube()) { + if (isFlipY()) { // also flip -y and +y image in cubemap ByteBuffer pos_y = img.getData(2); img.setData(2, img.getData(3)); img.setData(3, pos_y); } tex = new TextureCubeMap(); - }else{ + } else if (isAsTexture3D()) { + tex = new Texture3D(); + } else { tex = new Texture2D(); } // enable mipmaps if image has them // or generate them if requested by user - if (img.hasMipmaps() || isGenerateMips()) + if (img.hasMipmaps() || isGenerateMips()) { tex.setMinFilter(Texture.MinFilter.Trilinear); + } tex.setAnisotropicFilter(getAnisotropy()); tex.setName(getName()); @@ -141,15 +146,23 @@ public class TextureKey extends AssetKey { this.generateMips = generateMips; } + public boolean isAsTexture3D() { + return asTexture3D; + } + + public void setAsTexture3D(boolean asTexture3D) { + this.asTexture3D = asTexture3D; + } + @Override - public boolean equals(Object other){ - if (!(other instanceof TextureKey)){ + public boolean equals(Object other) { + if (!(other instanceof TextureKey)) { return false; } - return super.equals(other) && isFlipY() == ((TextureKey)other).isFlipY(); + return super.equals(other) && isFlipY() == ((TextureKey) other).isFlipY(); } - public void write(JmeExporter ex) throws IOException{ + public void write(JmeExporter ex) throws IOException { super.write(ex); OutputCapsule oc = ex.getCapsule(this); oc.write(flipY, "flip_y", false); @@ -159,7 +172,7 @@ public class TextureKey extends AssetKey { } @Override - public void read(JmeImporter im) throws IOException{ + public void read(JmeImporter im) throws IOException { super.read(im); InputCapsule ic = im.getCapsule(this); flipY = ic.readBoolean("flip_y", false); diff --git a/engine/src/core/com/jme3/material/Material.java b/engine/src/core/com/jme3/material/Material.java index fa14f0d12..3a692efb8 100644 --- a/engine/src/core/com/jme3/material/Material.java +++ b/engine/src/core/com/jme3/material/Material.java @@ -368,9 +368,8 @@ public class Material implements Asset, Cloneable, Savable, Comparable } if (type != null && paramDef.getVarType() != type) { - logger.logp(Level.WARNING, "Material parameter being set: {0} with " - + "type {1} doesn't match definition type {2}", - name, type.name(), paramDef.getVarType()); + logger.log(Level.WARNING, "Material parameter being set: {0} with " + + "type {1} doesn't match definition type {2}", new Object[]{name, type.name(), paramDef.getVarType()} ); } return newName; @@ -497,7 +496,7 @@ public class Material implements Asset, Cloneable, Savable, Comparable return; } - VarType paramType = null; + VarType paramType = null; switch (value.getType()) { case TwoDimensional: paramType = VarType.Texture2D; diff --git a/engine/src/test-data/Textures/3D/flame.dds b/engine/src/test-data/Textures/3D/flame.dds new file mode 100644 index 000000000..2eb00f746 Binary files /dev/null and b/engine/src/test-data/Textures/3D/flame.dds differ diff --git a/engine/src/test/jme3test/texture/TestTexture3DLoading.java b/engine/src/test/jme3test/texture/TestTexture3DLoading.java new file mode 100644 index 000000000..615b58bcb --- /dev/null +++ b/engine/src/test/jme3test/texture/TestTexture3DLoading.java @@ -0,0 +1,65 @@ +/* + * 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.asset.TextureKey; +import com.jme3.material.Material; +import com.jme3.material.RenderState.BlendMode; +import com.jme3.math.ColorRGBA; +import com.jme3.math.FastMath; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +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.util.ArrayList; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class TestTexture3DLoading extends SimpleApplication { + + public static void main(String[] args) { + TestTexture3DLoading app = new TestTexture3DLoading(); + app.start(); + } + + @Override + public void simpleInitApp() { + viewPort.setBackgroundColor(ColorRGBA.DarkGray); + flyCam.setEnabled(false); + + + Quad q = new Quad(10, 10); + + Geometry geom = new Geometry("Quad", q); + Material material = new Material(assetManager, "jme3test/texture/tex3DThumb.j3md"); + TextureKey key = new TextureKey("Textures/3D/flame.dds"); + key.setGenerateMips(true); + key.setAsTexture3D(true); + + Texture t = assetManager.loadTexture(key); + + int rows = 4;//4 * 4 + + q.scaleTextureCoordinates(new Vector2f(rows, rows)); + + //The image only have 8 pictures and we have 16 thumbs, the data will be interpolated by the GPU + material.setFloat("InvDepth", 1f / 16f); + material.setInt("Rows", rows); + material.setTexture("Texture", t); + geom.setMaterial(material); + + rootNode.attachChild(geom); + + cam.setLocation(new Vector3f(4.7444625f, 5.160054f, 13.1939f)); + } +} \ No newline at end of file diff --git a/engine/src/test/jme3test/texture/tex3DThumb.frag b/engine/src/test/jme3test/texture/tex3DThumb.frag new file mode 100644 index 000000000..f6eb25a3b --- /dev/null +++ b/engine/src/test/jme3test/texture/tex3DThumb.frag @@ -0,0 +1,14 @@ +uniform sampler3D m_Texture; +uniform int m_Rows; +uniform float m_InvDepth; + +varying vec2 texCoord; + +void main(){ +float depthx=floor(texCoord.x); + float depthy=(m_Rows-1.0) - floor(texCoord.y); + //vec3 texC=vec3(texCoord.x,texCoord.y ,0.7);// + + vec3 texC=vec3(fract(texCoord.x),fract(texCoord.y),(depthy*m_Rows+depthx)*m_InvDepth);// + gl_FragColor= texture3D(m_Texture,texC); +} \ No newline at end of file diff --git a/engine/src/test/jme3test/texture/tex3DThumb.j3md b/engine/src/test/jme3test/texture/tex3DThumb.j3md new file mode 100644 index 000000000..a42bd381e --- /dev/null +++ b/engine/src/test/jme3test/texture/tex3DThumb.j3md @@ -0,0 +1,18 @@ +MaterialDef Tex3DThumb { + + MaterialParameters { + Texture3D Texture + Int Rows; + Float InvDepth; + } + + Technique { + VertexShader GLSL100: jme3test/texture/tex3DThumb.vert + FragmentShader GLSL100: jme3test/texture/tex3DThumb.frag + + WorldParameters { + WorldViewProjectionMatrix + } + } + +} diff --git a/engine/src/test/jme3test/texture/tex3DThumb.vert b/engine/src/test/jme3test/texture/tex3DThumb.vert new file mode 100644 index 000000000..6d27bc030 --- /dev/null +++ b/engine/src/test/jme3test/texture/tex3DThumb.vert @@ -0,0 +1,11 @@ +uniform mat4 g_WorldViewProjectionMatrix; + +attribute vec2 inTexCoord; +attribute vec3 inPosition; + +varying vec2 texCoord; + +void main(){ + gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition,1.0); + texCoord=inTexCoord; +} \ No newline at end of file