Engine :
- Added Volume texture 3D loading support to the DDSLoader - Added a test case for texture 3D loading - fixes a minor log issue in Material.java git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8003 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
6c7082a7e3
commit
91477b73f5
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.texture.plugins;
|
package com.jme3.texture.plugins;
|
||||||
|
|
||||||
import com.jme3.asset.AssetInfo;
|
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 Logger logger = Logger.getLogger(DDSLoader.class.getName());
|
||||||
private static final boolean forceRGBA = false;
|
private static final boolean forceRGBA = false;
|
||||||
|
|
||||||
private static final int DDSD_MANDATORY = 0x1007;
|
private static final int DDSD_MANDATORY = 0x1007;
|
||||||
private static final int DDSD_MANDATORY_DX10 = 0x6;
|
private static final int DDSD_MANDATORY_DX10 = 0x6;
|
||||||
|
|
||||||
private static final int DDSD_MIPMAPCOUNT = 0x20000;
|
private static final int DDSD_MIPMAPCOUNT = 0x20000;
|
||||||
private static final int DDSD_LINEARSIZE = 0x80000;
|
private static final int DDSD_LINEARSIZE = 0x80000;
|
||||||
private static final int DDSD_DEPTH = 0x800000;
|
private static final int DDSD_DEPTH = 0x800000;
|
||||||
|
|
||||||
private static final int DDPF_ALPHAPIXELS = 0x1;
|
private static final int DDPF_ALPHAPIXELS = 0x1;
|
||||||
private static final int DDPF_FOURCC = 0x4;
|
private static final int DDPF_FOURCC = 0x4;
|
||||||
private static final int DDPF_RGB = 0x40;
|
private static final int DDPF_RGB = 0x40;
|
||||||
@ -79,31 +75,24 @@ public class DDSLoader implements AssetLoader {
|
|||||||
private static final int DDPF_ALPHA = 0x2;
|
private static final int DDPF_ALPHA = 0x2;
|
||||||
// used by NVTextureTools to mark normal images.
|
// used by NVTextureTools to mark normal images.
|
||||||
private static final int DDPF_NORMAL = 0x80000000;
|
private static final int DDPF_NORMAL = 0x80000000;
|
||||||
|
|
||||||
private static final int SWIZZLE_xGxR = 0x78477852;
|
private static final int SWIZZLE_xGxR = 0x78477852;
|
||||||
|
|
||||||
private static final int DDSCAPS_COMPLEX = 0x8;
|
private static final int DDSCAPS_COMPLEX = 0x8;
|
||||||
private static final int DDSCAPS_TEXTURE = 0x1000;
|
private static final int DDSCAPS_TEXTURE = 0x1000;
|
||||||
private static final int DDSCAPS_MIPMAP = 0x400000;
|
private static final int DDSCAPS_MIPMAP = 0x400000;
|
||||||
|
|
||||||
private static final int DDSCAPS2_CUBEMAP = 0x200;
|
private static final int DDSCAPS2_CUBEMAP = 0x200;
|
||||||
private static final int DDSCAPS2_VOLUME = 0x200000;
|
private static final int DDSCAPS2_VOLUME = 0x200000;
|
||||||
|
|
||||||
private static final int PF_DXT1 = 0x31545844;
|
private static final int PF_DXT1 = 0x31545844;
|
||||||
private static final int PF_DXT3 = 0x33545844;
|
private static final int PF_DXT3 = 0x33545844;
|
||||||
private static final int PF_DXT5 = 0x35545844;
|
private static final int PF_DXT5 = 0x35545844;
|
||||||
private static final int PF_ATI1 = 0x31495441;
|
private static final int PF_ATI1 = 0x31495441;
|
||||||
private static final int PF_ATI2 = 0x32495441; // 0x41544932;
|
private static final int PF_ATI2 = 0x32495441; // 0x41544932;
|
||||||
private static final int PF_DX10 = 0x30315844; // a DX10 format
|
private static final int PF_DX10 = 0x30315844; // a DX10 format
|
||||||
|
|
||||||
private static final int DX10DIM_BUFFER = 0x1,
|
private static final int DX10DIM_BUFFER = 0x1,
|
||||||
DX10DIM_TEXTURE1D = 0x2,
|
DX10DIM_TEXTURE1D = 0x2,
|
||||||
DX10DIM_TEXTURE2D = 0x3,
|
DX10DIM_TEXTURE2D = 0x3,
|
||||||
DX10DIM_TEXTURE3D = 0x4;
|
DX10DIM_TEXTURE3D = 0x4;
|
||||||
|
|
||||||
private static final int DX10MISC_GENERATE_MIPS = 0x1,
|
private static final int DX10MISC_GENERATE_MIPS = 0x1,
|
||||||
DX10MISC_TEXTURECUBE = 0x4;
|
DX10MISC_TEXTURECUBE = 0x4;
|
||||||
|
|
||||||
private static final double LOG2 = Math.log(2);
|
private static final double LOG2 = Math.log(2);
|
||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
@ -115,6 +104,7 @@ public class DDSLoader implements AssetLoader {
|
|||||||
private int caps2;
|
private int caps2;
|
||||||
private boolean directx10;
|
private boolean directx10;
|
||||||
private boolean compressed;
|
private boolean compressed;
|
||||||
|
private boolean texture3D;
|
||||||
private boolean grayscaleOrAlpha;
|
private boolean grayscaleOrAlpha;
|
||||||
private boolean normal;
|
private boolean normal;
|
||||||
private Format pixelFormat;
|
private Format pixelFormat;
|
||||||
@ -127,30 +117,31 @@ public class DDSLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Object load(AssetInfo info) throws IOException {
|
public Object load(AssetInfo info) throws IOException {
|
||||||
if (!(info.getKey() instanceof TextureKey))
|
if (!(info.getKey() instanceof TextureKey)) {
|
||||||
throw new IllegalArgumentException("Texture assets must be loaded using a TextureKey");
|
throw new IllegalArgumentException("Texture assets must be loaded using a TextureKey");
|
||||||
|
}
|
||||||
|
|
||||||
InputStream stream = info.openStream();
|
InputStream stream = info.openStream();
|
||||||
in = new LittleEndien(stream);
|
in = new LittleEndien(stream);
|
||||||
loadHeader();
|
loadHeader();
|
||||||
|
|
||||||
ArrayList<ByteBuffer> data = readData(((TextureKey) info.getKey()).isFlipY());
|
ArrayList<ByteBuffer> data = readData(((TextureKey) info.getKey()).isFlipY());
|
||||||
stream.close();
|
stream.close();
|
||||||
|
return new Image(pixelFormat, width, height, depth, data, sizes);
|
||||||
return new Image(pixelFormat, width, height, 0, data, sizes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image load(InputStream stream) throws IOException {
|
public Image load(InputStream stream) throws IOException {
|
||||||
in = new LittleEndien(stream);
|
in = new LittleEndien(stream);
|
||||||
loadHeader();
|
loadHeader();
|
||||||
ArrayList<ByteBuffer> data = readData(false);
|
ArrayList<ByteBuffer> 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();
|
int dxgiFormat = in.readInt();
|
||||||
if (dxgiFormat != 83) {
|
if (dxgiFormat != 83) {
|
||||||
throw new IOException("Only DXGI_FORMAT_BC5_UNORM " +
|
throw new IOException("Only DXGI_FORMAT_BC5_UNORM "
|
||||||
"is supported for DirectX10 DDS! Got: "+dxgiFormat);
|
+ "is supported for DirectX10 DDS! Got: " + dxgiFormat);
|
||||||
}
|
}
|
||||||
pixelFormat = Format.LATC;
|
pixelFormat = Format.LATC;
|
||||||
bpp = 8;
|
bpp = 8;
|
||||||
@ -158,7 +149,7 @@ public class DDSLoader implements AssetLoader {
|
|||||||
|
|
||||||
int resDim = in.readInt();
|
int resDim = in.readInt();
|
||||||
if (resDim == DX10DIM_TEXTURE3D) {
|
if (resDim == DX10DIM_TEXTURE3D) {
|
||||||
// mark texture as 3D
|
texture3D = true;
|
||||||
}
|
}
|
||||||
int miscFlag = in.readInt();
|
int miscFlag = in.readInt();
|
||||||
int arraySize = in.readInt();
|
int arraySize = in.readInt();
|
||||||
@ -199,17 +190,23 @@ public class DDSLoader implements AssetLoader {
|
|||||||
caps2 = in.readInt();
|
caps2 = in.readInt();
|
||||||
in.skipBytes(12);
|
in.skipBytes(12);
|
||||||
|
|
||||||
|
|
||||||
if (!directx10) {
|
if (!directx10) {
|
||||||
if (!is(caps1, DDSCAPS_TEXTURE)) {
|
if (!is(caps1, DDSCAPS_TEXTURE)) {
|
||||||
throw new IOException("File is not a texture");
|
throw new IOException("File is not a texture");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth <= 0)
|
if (depth <= 0) {
|
||||||
depth = 1;
|
depth = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (is(caps2, DDSCAPS2_CUBEMAP)) {
|
if (is(caps2, DDSCAPS2_CUBEMAP)) {
|
||||||
depth = 6; // somewhat of a hack, force loading 6 textures if a 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);
|
int expectedMipmaps = 1 + (int) Math.ceil(Math.log(Math.max(height, width)) / LOG2);
|
||||||
@ -536,7 +533,6 @@ public class DDSLoader implements AssetLoader {
|
|||||||
int mipWidth = width;
|
int mipWidth = width;
|
||||||
int mipHeight = height;
|
int mipHeight = height;
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (int mip = 0; mip < mipMapCount; mip++) {
|
for (int mip = 0; mip < mipMapCount; mip++) {
|
||||||
if (flip) {
|
if (flip) {
|
||||||
byte[] data = new byte[sizes[mip]];
|
byte[] data = new byte[sizes[mip]];
|
||||||
@ -551,8 +547,6 @@ public class DDSLoader implements AssetLoader {
|
|||||||
buffer.put(data);
|
buffer.put(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += sizes[mip];
|
|
||||||
|
|
||||||
mipWidth = Math.max(mipWidth / 2, 1);
|
mipWidth = Math.max(mipWidth / 2, 1);
|
||||||
mipHeight = Math.max(mipHeight / 2, 1);
|
mipHeight = Math.max(mipHeight / 2, 1);
|
||||||
}
|
}
|
||||||
@ -561,6 +555,153 @@ public class DDSLoader implements AssetLoader {
|
|||||||
return buffer;
|
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.
|
* Reads the image data from the InputStream in the required format.
|
||||||
* If the file contains a cubemap image, it is loaded as 6 ByteBuffers
|
* If the file contains a cubemap image, it is loaded as 6 ByteBuffers
|
||||||
@ -583,7 +724,7 @@ public class DDSLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<ByteBuffer> allMaps = new ArrayList<ByteBuffer>();
|
ArrayList<ByteBuffer> allMaps = new ArrayList<ByteBuffer>();
|
||||||
if (depth > 1){
|
if (depth > 1 && !texture3D) {
|
||||||
for (int i = 0; i < depth; i++) {
|
for (int i = 0; i < depth; i++) {
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
allMaps.add(readDXT2D(flip, totalSize));
|
allMaps.add(readDXT2D(flip, totalSize));
|
||||||
@ -593,6 +734,15 @@ public class DDSLoader implements AssetLoader {
|
|||||||
allMaps.add(readRGB2D(flip, totalSize));
|
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 {
|
} else {
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
allMaps.add(readDXT2D(flip, totalSize));
|
allMaps.add(readDXT2D(flip, totalSize));
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.jme3.asset;
|
package com.jme3.asset;
|
||||||
|
|
||||||
import com.jme3.export.JmeExporter;
|
import com.jme3.export.JmeExporter;
|
||||||
@ -39,6 +38,7 @@ import com.jme3.export.OutputCapsule;
|
|||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.Texture2D;
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Texture3D;
|
||||||
import com.jme3.texture.TextureCubeMap;
|
import com.jme3.texture.TextureCubeMap;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@ -48,6 +48,7 @@ public class TextureKey extends AssetKey<Texture> {
|
|||||||
private boolean generateMips;
|
private boolean generateMips;
|
||||||
private boolean flipY;
|
private boolean flipY;
|
||||||
private boolean asCube;
|
private boolean asCube;
|
||||||
|
private boolean asTexture3D;
|
||||||
private int anisotropy;
|
private int anisotropy;
|
||||||
|
|
||||||
public TextureKey(String name, boolean flipY) {
|
public TextureKey(String name, boolean flipY) {
|
||||||
@ -86,8 +87,9 @@ public class TextureKey extends AssetKey<Texture> {
|
|||||||
@Override
|
@Override
|
||||||
public Object postProcess(Object asset) {
|
public Object postProcess(Object asset) {
|
||||||
Image img = (Image) asset;
|
Image img = (Image) asset;
|
||||||
if (img == null)
|
if (img == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Texture tex;
|
Texture tex;
|
||||||
if (isAsCube()) {
|
if (isAsCube()) {
|
||||||
@ -98,14 +100,17 @@ public class TextureKey extends AssetKey<Texture> {
|
|||||||
img.setData(3, pos_y);
|
img.setData(3, pos_y);
|
||||||
}
|
}
|
||||||
tex = new TextureCubeMap();
|
tex = new TextureCubeMap();
|
||||||
|
} else if (isAsTexture3D()) {
|
||||||
|
tex = new Texture3D();
|
||||||
} else {
|
} else {
|
||||||
tex = new Texture2D();
|
tex = new Texture2D();
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable mipmaps if image has them
|
// enable mipmaps if image has them
|
||||||
// or generate them if requested by user
|
// or generate them if requested by user
|
||||||
if (img.hasMipmaps() || isGenerateMips())
|
if (img.hasMipmaps() || isGenerateMips()) {
|
||||||
tex.setMinFilter(Texture.MinFilter.Trilinear);
|
tex.setMinFilter(Texture.MinFilter.Trilinear);
|
||||||
|
}
|
||||||
|
|
||||||
tex.setAnisotropicFilter(getAnisotropy());
|
tex.setAnisotropicFilter(getAnisotropy());
|
||||||
tex.setName(getName());
|
tex.setName(getName());
|
||||||
@ -141,6 +146,14 @@ public class TextureKey extends AssetKey<Texture> {
|
|||||||
this.generateMips = generateMips;
|
this.generateMips = generateMips;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAsTexture3D() {
|
||||||
|
return asTexture3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAsTexture3D(boolean asTexture3D) {
|
||||||
|
this.asTexture3D = asTexture3D;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
if (!(other instanceof TextureKey)) {
|
if (!(other instanceof TextureKey)) {
|
||||||
|
@ -368,9 +368,8 @@ public class Material implements Asset, Cloneable, Savable, Comparable<Material>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type != null && paramDef.getVarType() != type) {
|
if (type != null && paramDef.getVarType() != type) {
|
||||||
logger.logp(Level.WARNING, "Material parameter being set: {0} with "
|
logger.log(Level.WARNING, "Material parameter being set: {0} with "
|
||||||
+ "type {1} doesn't match definition type {2}",
|
+ "type {1} doesn't match definition type {2}", new Object[]{name, type.name(), paramDef.getVarType()} );
|
||||||
name, type.name(), paramDef.getVarType());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return newName;
|
return newName;
|
||||||
|
BIN
engine/src/test-data/Textures/3D/flame.dds
Normal file
BIN
engine/src/test-data/Textures/3D/flame.dds
Normal file
Binary file not shown.
65
engine/src/test/jme3test/texture/TestTexture3DLoading.java
Normal file
65
engine/src/test/jme3test/texture/TestTexture3DLoading.java
Normal file
@ -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));
|
||||||
|
}
|
||||||
|
}
|
14
engine/src/test/jme3test/texture/tex3DThumb.frag
Normal file
14
engine/src/test/jme3test/texture/tex3DThumb.frag
Normal file
@ -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);
|
||||||
|
}
|
18
engine/src/test/jme3test/texture/tex3DThumb.j3md
Normal file
18
engine/src/test/jme3test/texture/tex3DThumb.j3md
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
engine/src/test/jme3test/texture/tex3DThumb.vert
Normal file
11
engine/src/test/jme3test/texture/tex3DThumb.vert
Normal file
@ -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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user