Browse Source

Added support for multilayered images.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9336 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl 13 years ago
parent
commit
b09e37c9d9

+ 122 - 116
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java

@@ -236,26 +236,74 @@ public class TextureHelper extends AbstractBlenderHelper {
 	 * @return the decompressed image
 	 * @return the decompressed image
 	 */
 	 */
 	public Image decompress(Image image) {
 	public Image decompress(Image image) {
-		byte[] bytes = null;
-		TexturePixel[] colors = null;
-		ByteBuffer data = image.getData(0);// TODO: support decompression of all data 'layers'
-		data.rewind();
 		Format format = image.getFormat();
 		Format format = image.getFormat();
+		int depth = image.getDepth();
+		if(depth == 0) {
+			depth = 1;
+		}
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);
+		TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel(), new TexturePixel(), new TexturePixel() };
+		
+		for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
+			ByteBuffer data = image.getData(dataLayerIndex);
+			data.rewind();
+			
+			byte[] bytes = new byte[image.getWidth() * image.getHeight() << 2];
+			DDSTexelData texelData = new DDSTexelData(data.remaining() * 8/format.getBitsPerPixel()/16/*data.remaining() / (format.getBitsPerPixel() << 1)*/, 
+					image.getWidth(), image.getHeight(), format != Format.DXT1);
+			switch (format) {
+				case DXT1:// BC1
+				case DXT1A:
+					while (data.hasRemaining()) {
+						short c0 = data.getShort();
+						short c1 = data.getShort();
+						int col0 = RGB565.RGB565_to_ARGB8(c0);
+						int col1 = RGB565.RGB565_to_ARGB8(c1);
+						colors[0].fromARGB8(col0);
+						colors[1].fromARGB8(col1);
+
+						if (col0 > col1) {
+							// creating color2 = 2/3color0 + 1/3color1
+							colors[2].fromPixel(colors[0]);
+							colors[2].mult(2);
+							colors[2].add(colors[1]);
+							colors[2].divide(3);
+
+							// creating color3 = 1/3color0 + 2/3color1;
+							colors[3].fromPixel(colors[1]);
+							colors[3].mult(2);
+							colors[3].add(colors[0]);
+							colors[3].divide(3);
+						} else {
+							// creating color2 = 1/2color0 + 1/2color1
+							colors[2].fromPixel(colors[0]);
+							colors[2].add(colors[1]);
+							colors[2].mult(0.5f);
+
+							colors[3].fromARGB8(0);
+						}
+						int indexes = data.getInt();// 4-byte table with color indexes in decompressed table
+						texelData.add(colors, indexes);
+					}
+					break;
+				case DXT3:// BC2
+					while (data.hasRemaining()) {
+						long alpha = data.getLong();
+						float[] alphas = new float[16];
+						long alphasIndex = 0;
+						for (int i = 0; i < 16; ++i) {
+							alphasIndex |= i << i * 4;
+							byte a = (byte) ((alpha >> i * 4 & 0x0F) << 4);
+							alphas[i] = a >= 0 ? a / 255.0f : 1.0f - ~a / 255.0f;
+						}
+
+						short c0 = data.getShort();
+						short c1 = data.getShort();
+						int col0 = RGB565.RGB565_to_ARGB8(c0);
+						int col1 = RGB565.RGB565_to_ARGB8(c1);
+						colors[0].fromARGB8(col0);
+						colors[1].fromARGB8(col1);
 
 
-		DDSTexelData texelData = new DDSTexelData(data.remaining() / (format.getBitsPerPixel() * 2), image.getWidth(), image.getHeight(), format != Format.DXT1);
-		switch (format) {// TODO: DXT1A
-			case DXT1:// BC1
-				bytes = new byte[image.getWidth() * image.getHeight() * 4];
-				colors = new TexturePixel[] { new TexturePixel(), new TexturePixel(), new TexturePixel(), new TexturePixel() };
-				while (data.hasRemaining()) {
-					short c0 = data.getShort();
-					short c1 = data.getShort();
-					int col0 = RGB565.RGB565_to_ARGB8(c0);
-					int col1 = RGB565.RGB565_to_ARGB8(c1);
-					colors[0].fromARGB8(col0);
-					colors[1].fromARGB8(col1);
-
-					if (col0 > col1) {
 						// creating color2 = 2/3color0 + 1/3color1
 						// creating color2 = 2/3color0 + 1/3color1
 						colors[2].fromPixel(colors[0]);
 						colors[2].fromPixel(colors[0]);
 						colors[2].mult(2);
 						colors[2].mult(2);
@@ -267,106 +315,60 @@ public class TextureHelper extends AbstractBlenderHelper {
 						colors[3].mult(2);
 						colors[3].mult(2);
 						colors[3].add(colors[0]);
 						colors[3].add(colors[0]);
 						colors[3].divide(3);
 						colors[3].divide(3);
-					} else {
-						// creating color2 = 1/2color0 + 1/2color1
+
+						int indexes = data.getInt();// 4-byte table with color indexes in decompressed table
+						texelData.add(colors, indexes, alphas, alphasIndex);
+					}
+					break;
+				case DXT5:// BC3
+					float[] alphas = new float[8];
+					while (data.hasRemaining()) {
+						alphas[0] = data.get() * 255.0f;
+						alphas[1] = data.get() * 255.0f;
+						long alphaIndices = data.get() | data.get() << 8 | data.get() << 16 | data.get() << 24 | data.get() << 32 | data.get() << 40;
+						if (alphas[0] > alphas[1]) {// 6 interpolated alpha values.
+							alphas[2] = (6 * alphas[0] + alphas[1]) / 7;
+							alphas[3] = (5 * alphas[0] + 2 * alphas[1]) / 7;
+							alphas[4] = (4 * alphas[0] + 3 * alphas[1]) / 7;
+							alphas[5] = (3 * alphas[0] + 4 * alphas[1]) / 7;
+							alphas[6] = (2 * alphas[0] + 5 * alphas[1]) / 7;
+							alphas[7] = (alphas[0] + 6 * alphas[1]) / 7;
+						} else {
+							alphas[2] = (4 * alphas[0] + alphas[1]) * 0.2f;
+							alphas[3] = (3 * alphas[0] + 2 * alphas[1]) * 0.2f;
+							alphas[4] = (2 * alphas[0] + 3 * alphas[1]) * 0.2f;
+							alphas[5] = (alphas[0] + 4 * alphas[1]) * 0.2f;
+							alphas[6] = 0;
+							alphas[7] = 1;
+						}
+
+						short c0 = data.getShort();
+						short c1 = data.getShort();
+						int col0 = RGB565.RGB565_to_ARGB8(c0);
+						int col1 = RGB565.RGB565_to_ARGB8(c1);
+						colors[0].fromARGB8(col0);
+						colors[1].fromARGB8(col1);
+
+						// creating color2 = 2/3color0 + 1/3color1
 						colors[2].fromPixel(colors[0]);
 						colors[2].fromPixel(colors[0]);
+						colors[2].mult(2);
 						colors[2].add(colors[1]);
 						colors[2].add(colors[1]);
-						colors[2].mult(0.5f);
+						colors[2].divide(3);
 
 
-						colors[3].fromARGB8(0);
-					}
-					int indexes = data.getInt();// 4-byte table with color indexes in decompressed table
-					texelData.add(colors, indexes);
-				}
-				break;
-			case DXT3:// BC2
-				bytes = new byte[image.getWidth() * image.getHeight() * 4];
-				colors = new TexturePixel[] { new TexturePixel(), new TexturePixel(), new TexturePixel(), new TexturePixel() };
-				while (data.hasRemaining()) {
-					long alpha = data.getLong();
-					float[] alphas = new float[16];
-					long alphasIndex = 0;
-					for (int i = 0; i < 16; ++i) {
-						alphasIndex |= i << i * 4;
-						byte a = (byte) ((alpha >> i * 4 & 0x0F) << 4);
-						alphas[i] = a >= 0 ? a / 255.0f : 1.0f - ~a / 255.0f;
-					}
+						// creating color3 = 1/3color0 + 2/3color1;
+						colors[3].fromPixel(colors[1]);
+						colors[3].mult(2);
+						colors[3].add(colors[0]);
+						colors[3].divide(3);
 
 
-					short c0 = data.getShort();
-					short c1 = data.getShort();
-					int col0 = RGB565.RGB565_to_ARGB8(c0);
-					int col1 = RGB565.RGB565_to_ARGB8(c1);
-					colors[0].fromARGB8(col0);
-					colors[1].fromARGB8(col1);
-
-					// creating color2 = 2/3color0 + 1/3color1
-					colors[2].fromPixel(colors[0]);
-					colors[2].mult(2);
-					colors[2].add(colors[1]);
-					colors[2].divide(3);
-
-					// creating color3 = 1/3color0 + 2/3color1;
-					colors[3].fromPixel(colors[1]);
-					colors[3].mult(2);
-					colors[3].add(colors[0]);
-					colors[3].divide(3);
-
-					int indexes = data.getInt();// 4-byte table with color indexes in decompressed table
-					texelData.add(colors, indexes, alphas, alphasIndex);
-				}
-				break;
-			case DXT5:// BC3
-				bytes = new byte[image.getWidth() * image.getHeight() * 4];
-				colors = new TexturePixel[] { new TexturePixel(), new TexturePixel(), new TexturePixel(), new TexturePixel() };
-				float[] alphas = new float[8];
-				while (data.hasRemaining()) {
-					alphas[0] = data.get() * 255.0f;
-					alphas[1] = data.get() * 255.0f;
-					long alphaIndices = data.get() | data.get() << 8 | data.get() << 16 | data.get() << 24 | data.get() << 32 | data.get() << 40;
-					if (alphas[0] > alphas[1]) {// 6 interpolated alpha values.
-						alphas[2] = (6 * alphas[0] + alphas[1]) / 7;
-						alphas[3] = (5 * alphas[0] + 2 * alphas[1]) / 7;
-						alphas[4] = (4 * alphas[0] + 3 * alphas[1]) / 7;
-						alphas[5] = (3 * alphas[0] + 4 * alphas[1]) / 7;
-						alphas[6] = (2 * alphas[0] + 5 * alphas[1]) / 7;
-						alphas[7] = (alphas[0] + 6 * alphas[1]) / 7;
-					} else {
-						alphas[2] = (4 * alphas[0] + alphas[1]) * 0.2f;
-						alphas[3] = (3 * alphas[0] + 2 * alphas[1]) * 0.2f;
-						alphas[4] = (2 * alphas[0] + 3 * alphas[1]) * 0.2f;
-						alphas[5] = (alphas[0] + 4 * alphas[1]) * 0.2f;
-						alphas[6] = 0;
-						alphas[7] = 1;
+						int indexes = data.getInt();// 4-byte table with color indexes in decompressed table
+						texelData.add(colors, indexes, alphas, alphaIndices);
 					}
 					}
+					break;
+				default:
+					throw new IllegalStateException("Unknown compressed format: " + format);
+			}
 
 
-					short c0 = data.getShort();
-					short c1 = data.getShort();
-					int col0 = RGB565.RGB565_to_ARGB8(c0);
-					int col1 = RGB565.RGB565_to_ARGB8(c1);
-					colors[0].fromARGB8(col0);
-					colors[1].fromARGB8(col1);
-
-					// creating color2 = 2/3color0 + 1/3color1
-					colors[2].fromPixel(colors[0]);
-					colors[2].mult(2);
-					colors[2].add(colors[1]);
-					colors[2].divide(3);
-
-					// creating color3 = 1/3color0 + 2/3color1;
-					colors[3].fromPixel(colors[1]);
-					colors[3].mult(2);
-					colors[3].add(colors[0]);
-					colors[3].divide(3);
-
-					int indexes = data.getInt();// 4-byte table with color indexes in decompressed table
-					texelData.add(colors, indexes, alphas, alphaIndices);
-				}
-				break;
-			default:
-				LOGGER.fine("Unsupported decompression format.");
-		}
-
-		if (bytes != null) {// writing the data to the result table
 			byte[] pixelBytes = new byte[4];
 			byte[] pixelBytes = new byte[4];
 			for (int i = 0; i < image.getWidth(); ++i) {
 			for (int i = 0; i < image.getWidth(); ++i) {
 				for (int j = 0; j < image.getHeight(); ++j) {
 				for (int j = 0; j < image.getHeight(); ++j) {
@@ -377,11 +379,15 @@ public class TextureHelper extends AbstractBlenderHelper {
 					bytes[(j * image.getWidth() + i) * 4 + 3] = pixelBytes[3];
 					bytes[(j * image.getWidth() + i) * 4 + 3] = pixelBytes[3];
 				}
 				}
 			}
 			}
-			// TODO: think of other image formats (ie. RGB if the texture has no
-			// alpha values)
-			return new Image(Format.RGBA8, image.getWidth(), image.getHeight(), BufferUtils.createByteBuffer(bytes));
+			dataArray.add(BufferUtils.createByteBuffer(bytes));
+		}
+		
+		Image result = depth > 1 ? new Image(Format.RGBA8, image.getWidth(), image.getHeight(), depth, dataArray) : 
+								   new Image(Format.RGBA8, image.getWidth(), image.getHeight(), dataArray.get(0));
+		if(image.getMipMapSizes() != null) {
+			result.setMipMapSizes(image.getMipMapSizes().clone());
 		}
 		}
-		return image;
+		return result;
 	}
 	}
 
 
 	/**
 	/**

+ 38 - 33
engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java

@@ -42,7 +42,6 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
 	public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
 	public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
 		float[] pixelColor = new float[] { color[0], color[1], color[2], 1.0f };
 		float[] pixelColor = new float[] { color[0], color[1], color[2], 1.0f };
 		Format format = image.getFormat();
 		Format format = image.getFormat();
-		ByteBuffer data = image.getData(0);
 		
 		
 		PixelInputOutput basePixelIO = null, pixelReader = PixelIOFactory.getPixelIO(format);
 		PixelInputOutput basePixelIO = null, pixelReader = PixelIOFactory.getPixelIO(format);
 		TexturePixel basePixel = null, pixel = new TexturePixel();
 		TexturePixel basePixel = null, pixel = new TexturePixel();
@@ -59,44 +58,50 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
 		if (depth == 0) {
 		if (depth == 0) {
 			depth = 1;
 			depth = 1;
 		}
 		}
-		ByteBuffer newData = BufferUtils.createByteBuffer(width * height * depth * 4);
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);
 		
 		
 		float[] resultPixel = new float[4];
 		float[] resultPixel = new float[4];
-		int dataIndex = 0, x = 0, y = 0, index = 0;
-		while (index < data.limit()) {
-			//getting the proper material color if the base texture is applied
-			if(basePixelIO != null) {
-				basePixelIO.read(baseImage, basePixel, x, y);
-				basePixel.toRGBA(materialColor);
-			}			
+		for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
+			ByteBuffer data = image.getData(dataLayerIndex);
+			data.rewind();
+			ByteBuffer newData = BufferUtils.createByteBuffer(width * height * 4);
 			
 			
-			//reading the current texture's pixel
-			pixelReader.read(image, pixel, index);
-			index += image.getFormat().getBitsPerPixel() >> 3;
-			pixel.toRGBA(pixelColor);
-			if (negateTexture) {
-				pixel.negate();
-			}
-			
-			this.blendPixel(resultPixel, materialColor, pixelColor, blenderContext);
-			newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
-			newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
-			newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
-			newData.put(dataIndex++, (byte) (pixelColor[3] * 255.0f));
-			
-			++x;
-			if(x >= width) {
-				x = 0;
-				++y;
+			int dataIndex = 0, x = 0, y = 0, index = 0;
+			while (index < data.limit()) {
+				//getting the proper material color if the base texture is applied
+				if(basePixelIO != null) {
+					basePixelIO.read(baseImage, basePixel, x, y);
+					basePixel.toRGBA(materialColor);
+				}			
+				
+				//reading the current texture's pixel
+				pixelReader.read(image, pixel, index);
+				index += image.getFormat().getBitsPerPixel() >> 3;
+				pixel.toRGBA(pixelColor);
+				if (negateTexture) {
+					pixel.negate();
+				}
+				
+				this.blendPixel(resultPixel, materialColor, pixelColor, blenderContext);
+				newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
+				newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
+				newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
+				newData.put(dataIndex++, (byte) (pixelColor[3] * 255.0f));
+				
+				++x;
+				if(x >= width) {
+					x = 0;
+					++y;
+				}
 			}
 			}
-		}
-		if(depth > 1) {
-			ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
 			dataArray.add(newData);
 			dataArray.add(newData);
-			return new Image(Format.RGBA8, width, height, depth, dataArray);
-		} else {
-			return new Image(Format.RGBA8, width, height, newData);
 		}
 		}
+		
+		Image result = depth > 1 ? new Image(Format.RGBA8, width, height, depth, dataArray) : new Image(Format.RGBA8, width, height, dataArray.get(0));
+		if(image.getMipMapSizes() != null) {
+			result.setMipMapSizes(image.getMipMapSizes().clone());
+		}
+		return result;
 	}
 	}
 
 
 	/**
 	/**

+ 66 - 74
engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderDDS.java

@@ -2,8 +2,6 @@ package com.jme3.scene.plugins.blender.textures.blending;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 
 import jme3tools.converters.RGB565;
 import jme3tools.converters.RGB565;
 
 
@@ -18,15 +16,12 @@ import com.jme3.util.BufferUtils;
 /**
 /**
  * The class that is responsible for blending the following texture types:
  * The class that is responsible for blending the following texture types:
  * <li> DXT1
  * <li> DXT1
+ * <li> DXT1A
  * <li> DXT3
  * <li> DXT3
  * <li> DXT5
  * <li> DXT5
- * Not yet supported (but will be):
- * <li> DXT1A:
  * @author Marcin Roguski (Kaelthas)
  * @author Marcin Roguski (Kaelthas)
  */
  */
 public class TextureBlenderDDS extends TextureBlenderAWT {
 public class TextureBlenderDDS extends TextureBlenderAWT {
-	private static final Logger	LOGGER	= Logger.getLogger(TextureBlenderDDS.class.getName());
-
 	public TextureBlenderDDS(int flag, boolean negateTexture, int blendType, float[] materialColor, float[] color, float blendFactor) {
 	public TextureBlenderDDS(int flag, boolean negateTexture, int blendType, float[] materialColor, float[] color, float blendFactor) {
 		super(flag, negateTexture, blendType, materialColor, color, blendFactor);
 		super(flag, negateTexture, blendType, materialColor, color, blendFactor);
 	}
 	}
@@ -34,16 +29,13 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
 	@Override
 	@Override
 	public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
 	public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
 		Format format = image.getFormat();
 		Format format = image.getFormat();
-		ByteBuffer data = image.getData(0);
-		data.rewind();
-
 		int width = image.getWidth();
 		int width = image.getWidth();
 		int height = image.getHeight();
 		int height = image.getHeight();
 		int depth = image.getDepth();
 		int depth = image.getDepth();
 		if (depth == 0) {
 		if (depth == 0) {
 			depth = 1;
 			depth = 1;
 		}
 		}
-		ByteBuffer newData = BufferUtils.createByteBuffer(data.remaining());
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);
 		
 		
 		PixelInputOutput basePixelIO = null;
 		PixelInputOutput basePixelIO = null;
 		float[][] compressedMaterialColor = null;
 		float[][] compressedMaterialColor = null;
@@ -57,77 +49,77 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
 		float[] resultPixel = new float[4];
 		float[] resultPixel = new float[4];
 		float[] pixelColor = new float[4];
 		float[] pixelColor = new float[4];
 		TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel() };
 		TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel() };
-		int dataIndex = 0, baseXTexelIndex = 0, baseYTexelIndex = 0;
+		int baseXTexelIndex = 0, baseYTexelIndex = 0;
 		float[] alphas = new float[] {1, 1};
 		float[] alphas = new float[] {1, 1};
-		while (data.hasRemaining()) {
-			if(format == Format.DXT1A) {
-				LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", format);
-				break;
-			}
-			if(format == Format.DXT3) {
-				long alpha = data.getLong();
-				//get alpha for first and last pixel that is compressed in the texel
-				byte alpha0 = (byte)(alpha << 4 & 0xFF);
-				byte alpha1 = (byte)(alpha >> 60 & 0xFF);
-				alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
-				alphas[1] = alpha1 >= 0 ? alpha1 / 255.0f : 1.0f - ~alpha1 / 255.0f;
-				dataIndex += 8;
-			} else if(format == Format.DXT5) {
-				byte alpha0 = data.get();
-				byte alpha1 = data.get();
-				alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
-				alphas[1] = alpha1 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
-				//only read the next 6 bytes (these are alpha indexes)
-				data.getInt();
-				data.getShort();
-				dataIndex += 8;
-			}
-			int col0 = RGB565.RGB565_to_ARGB8(data.getShort());
-			int col1 = RGB565.RGB565_to_ARGB8(data.getShort());
-			colors[0].fromARGB8(col0);
-			colors[1].fromARGB8(col1);
-			
-			//compressing 16 pixels from the base texture as if they belonged to a texel
-			if(baseImage != null) {
-				//reading pixels (first and last of the 16 colors array)
-				basePixelIO.read(baseImage, baseTextureColors[0], baseXTexelIndex << 2, baseYTexelIndex << 2);//first pixel
-				basePixelIO.read(baseImage, baseTextureColors[1], baseXTexelIndex << 2 + 4, baseYTexelIndex << 2 + 4);//last pixel
-				baseTextureColors[0].toRGBA(compressedMaterialColor[0]);
-				baseTextureColors[1].toRGBA(compressedMaterialColor[1]);
-			}
+		for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
+			ByteBuffer data = image.getData(dataLayerIndex);
+			data.rewind();
+			ByteBuffer newData = BufferUtils.createByteBuffer(data.remaining());
+			System.out.println(dataLayerIndex);
+			while (data.hasRemaining()) {
+				if(format == Format.DXT3) {
+					long alpha = data.getLong();
+					//get alpha for first and last pixel that is compressed in the texel
+					byte alpha0 = (byte)(alpha << 4 & 0xFF);
+					byte alpha1 = (byte)(alpha >> 60 & 0xFF);
+					alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
+					alphas[1] = alpha1 >= 0 ? alpha1 / 255.0f : 1.0f - ~alpha1 / 255.0f;
+					newData.putLong(alpha);
+				} else if(format == Format.DXT5) {
+					byte alpha0 = data.get();
+					byte alpha1 = data.get();
+					alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
+					alphas[1] = alpha1 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
+					newData.put(alpha0);
+					newData.put(alpha1);
+					//only read the next 6 bytes (these are alpha indexes)
+					newData.putInt(data.getInt());
+					newData.putShort(data.getShort());
+				}
+				int col0 = RGB565.RGB565_to_ARGB8(data.getShort());
+				int col1 = RGB565.RGB565_to_ARGB8(data.getShort());
+				colors[0].fromARGB8(col0);
+				colors[1].fromARGB8(col1);
+				
+				//compressing 16 pixels from the base texture as if they belonged to a texel
+				if(baseImage != null) {
+					//reading pixels (first and last of the 16 colors array)
+					basePixelIO.read(baseImage, baseTextureColors[0], baseXTexelIndex << 2, baseYTexelIndex << 2);//first pixel
+					basePixelIO.read(baseImage, baseTextureColors[1], baseXTexelIndex << 2 + 4, baseYTexelIndex << 2 + 4);//last pixel
+					baseTextureColors[0].toRGBA(compressedMaterialColor[0]);
+					baseTextureColors[1].toRGBA(compressedMaterialColor[1]);
+				}
 
 
-			// blending colors
-			for (int i = 0; i < colors.length; ++i) {
-				if (negateTexture) {
-					colors[i].negate();
+				// blending colors
+				for (int i = 0; i < colors.length; ++i) {
+					if (negateTexture) {
+						colors[i].negate();
+					}
+					colors[i].toRGBA(pixelColor);
+					pixelColor[3] = alphas[i];
+					this.blendPixel(resultPixel, compressedMaterialColor != null ? compressedMaterialColor[i] : materialColor, pixelColor, blenderContext);
+					colors[i].fromARGB8(1, resultPixel[0], resultPixel[1], resultPixel[2]);
+					int argb8 = colors[i].toARGB8();
+					short rgb565 = RGB565.ARGB8_to_RGB565(argb8);
+					newData.putShort(rgb565);
 				}
 				}
-				colors[i].toRGBA(pixelColor);
-				pixelColor[3] = alphas[i];
-				this.blendPixel(resultPixel, compressedMaterialColor != null ? compressedMaterialColor[i] : materialColor, pixelColor, blenderContext);
-				colors[i].fromARGB8(1, resultPixel[0], resultPixel[1], resultPixel[2]);
-				int argb8 = colors[i].toARGB8();
-				short rgb565 = RGB565.ARGB8_to_RGB565(argb8);
-				newData.putShort(dataIndex, rgb565);
-				dataIndex += 2;
-			}
 
 
-			// just copy the remaining 4 bytes of the current texel
-			newData.putInt(dataIndex, data.getInt());
-			dataIndex += 4;
-			
-			++baseXTexelIndex;
-			if(baseXTexelIndex > image.getWidth() >> 2) {
-				baseXTexelIndex = 0;
-				++baseYTexelIndex;
+				// just copy the remaining 4 bytes of the current texel
+				newData.putInt(data.getInt());
+				
+				++baseXTexelIndex;
+				if(baseXTexelIndex > image.getWidth() >> 2) {
+					baseXTexelIndex = 0;
+					++baseYTexelIndex;
+				}
 			}
 			}
+			dataArray.add(newData);
 		}
 		}
 		
 		
-		if(depth > 1) {
-			ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-			dataArray.add(newData);
-			return new Image(format, width, height, depth, dataArray);
-		} else {
-			return new Image(format, width, height, newData);
+		Image result = dataArray.size() > 1 ? new Image(format, width, height, depth, dataArray) : new Image(format, width, height, dataArray.get(0));
+		if(image.getMipMapSizes() != null) {
+			result.setMipMapSizes(image.getMipMapSizes().clone());
 		}
 		}
+		return result;
 	}
 	}
 }
 }

+ 30 - 27
engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderLuminance.java

@@ -35,8 +35,6 @@ public class TextureBlenderLuminance extends AbstractTextureBlender {
 	
 	
 	public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
 	public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
 		Format format = image.getFormat();
 		Format format = image.getFormat();
-		ByteBuffer data = image.getData(0);
-		data.rewind();
 
 
 		PixelInputOutput basePixelIO = null;
 		PixelInputOutput basePixelIO = null;
 		TexturePixel basePixel = null;
 		TexturePixel basePixel = null;
@@ -53,39 +51,44 @@ public class TextureBlenderLuminance extends AbstractTextureBlender {
 		if (depth == 0) {
 		if (depth == 0) {
 			depth = 1;
 			depth = 1;
 		}
 		}
-		ByteBuffer newData = BufferUtils.createByteBuffer(width * height * depth * 4);
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);
 
 
 		float[] resultPixel = new float[4];
 		float[] resultPixel = new float[4];
 		float[] tinAndAlpha = new float[2];
 		float[] tinAndAlpha = new float[2];
-		int dataIndex = 0, x = 0, y = 0;
-		while (data.hasRemaining()) {
-			//getting the proper material color if the base texture is applied
-			if(basePixelIO != null) {
-				basePixelIO.read(baseImage, basePixel, x, y);
-				basePixel.toRGBA(materialColor);
-			}
-			
-			this.getTinAndAlpha(data, format, negateTexture, tinAndAlpha);
-			this.blendPixel(resultPixel, materialColor, color, tinAndAlpha[0], blendFactor, blendType, blenderContext);
-			newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
-			newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
-			newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
-			newData.put(dataIndex++, (byte) (tinAndAlpha[1] * 255.0f));
+		for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
+			ByteBuffer data = image.getData(dataLayerIndex);
+			data.rewind();
+			ByteBuffer newData = BufferUtils.createByteBuffer(width * height * 4);
 			
 			
-			++x;
-			if(x >= width) {
-				x = 0;
-				++y;
+			int dataIndex = 0, x = 0, y = 0;
+			while (data.hasRemaining()) {
+				//getting the proper material color if the base texture is applied
+				if(basePixelIO != null) {
+					basePixelIO.read(baseImage, basePixel, x, y);
+					basePixel.toRGBA(materialColor);
+				}
+				
+				this.getTinAndAlpha(data, format, negateTexture, tinAndAlpha);
+				this.blendPixel(resultPixel, materialColor, color, tinAndAlpha[0], blendFactor, blendType, blenderContext);
+				newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
+				newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
+				newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
+				newData.put(dataIndex++, (byte) (tinAndAlpha[1] * 255.0f));
+				
+				++x;
+				if(x >= width) {
+					x = 0;
+					++y;
+				}
 			}
 			}
+			dataArray.add(newData);
 		}
 		}
 		
 		
-		if(depth > 1) {
-			ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-			dataArray.add(newData);
-			return new Image(Format.RGBA8, width, height, depth, dataArray);
-		} else {
-			return new Image(Format.RGBA8, width, height, newData);
+		Image result = depth > 1 ? new Image(Format.RGBA8, width, height, depth, dataArray) : new Image(Format.RGBA8, width, height, dataArray.get(0));
+		if(image.getMipMapSizes() != null) {
+			result.setMipMapSizes(image.getMipMapSizes().clone());
 		}
 		}
+		return result;
 	}
 	}
 
 
 	/**
 	/**

+ 2 - 3
engine/src/blender/com/jme3/scene/plugins/blender/textures/io/DDSPixelInputOutput.java

@@ -34,7 +34,8 @@ import com.jme3.texture.Image;
 		ByteBuffer data = image.getData().get(0);
 		ByteBuffer data = image.getData().get(0);
 		
 		
 		switch (image.getFormat()) {
 		switch (image.getFormat()) {
-			case DXT1: {// BC1
+			case DXT1: // BC1
+			case DXT1A:{
 				data.position(texelIndex * 8);
 				data.position(texelIndex * 8);
 				short c0 = data.getShort();
 				short c0 = data.getShort();
 				short c1 = data.getShort();
 				short c1 = data.getShort();
@@ -142,8 +143,6 @@ import com.jme3.texture.Image;
 				indexes = data.getInt();// 4-byte table with color indexes in decompressed table
 				indexes = data.getInt();// 4-byte table with color indexes in decompressed table
 				break;
 				break;
 			}
 			}
-			case DXT1A://TODO: implement
-				break;
 			default:
 			default:
 				throw new IllegalStateException("Unsupported decompression format.");
 				throw new IllegalStateException("Unsupported decompression format.");
 		}
 		}