|
|
|
@ -2,8 +2,6 @@ package com.jme3.scene.plugins.blender.textures.blending; |
|
|
|
|
|
|
|
|
|
import java.nio.ByteBuffer; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.logging.Level; |
|
|
|
|
import java.util.logging.Logger; |
|
|
|
|
|
|
|
|
|
import jme3tools.converters.RGB565; |
|
|
|
|
|
|
|
|
@ -18,15 +16,12 @@ import com.jme3.util.BufferUtils; |
|
|
|
|
/** |
|
|
|
|
* The class that is responsible for blending the following texture types: |
|
|
|
|
* <li> DXT1 |
|
|
|
|
* <li> DXT1A |
|
|
|
|
* <li> DXT3 |
|
|
|
|
* <li> DXT5 |
|
|
|
|
* Not yet supported (but will be): |
|
|
|
|
* <li> DXT1A: |
|
|
|
|
* @author Marcin Roguski (Kaelthas) |
|
|
|
|
*/ |
|
|
|
|
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) { |
|
|
|
|
super(flag, negateTexture, blendType, materialColor, color, blendFactor); |
|
|
|
|
} |
|
|
|
@ -34,16 +29,13 @@ public class TextureBlenderDDS extends TextureBlenderAWT { |
|
|
|
|
@Override |
|
|
|
|
public Image blend(Image image, Image baseImage, BlenderContext blenderContext) { |
|
|
|
|
Format format = image.getFormat(); |
|
|
|
|
ByteBuffer data = image.getData(0); |
|
|
|
|
data.rewind(); |
|
|
|
|
|
|
|
|
|
int width = image.getWidth(); |
|
|
|
|
int height = image.getHeight(); |
|
|
|
|
int depth = image.getDepth(); |
|
|
|
|
if (depth == 0) { |
|
|
|
|
depth = 1; |
|
|
|
|
} |
|
|
|
|
ByteBuffer newData = BufferUtils.createByteBuffer(data.remaining()); |
|
|
|
|
ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth); |
|
|
|
|
|
|
|
|
|
PixelInputOutput basePixelIO = null; |
|
|
|
|
float[][] compressedMaterialColor = null; |
|
|
|
@ -57,13 +49,14 @@ public class TextureBlenderDDS extends TextureBlenderAWT { |
|
|
|
|
float[] resultPixel = new float[4]; |
|
|
|
|
float[] pixelColor = new float[4]; |
|
|
|
|
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}; |
|
|
|
|
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.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
|
|
|
|
@ -71,16 +64,17 @@ public class TextureBlenderDDS extends TextureBlenderAWT { |
|
|
|
|
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; |
|
|
|
|
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)
|
|
|
|
|
data.getInt(); |
|
|
|
|
data.getShort(); |
|
|
|
|
dataIndex += 8; |
|
|
|
|
newData.putInt(data.getInt()); |
|
|
|
|
newData.putShort(data.getShort()); |
|
|
|
|
} |
|
|
|
|
int col0 = RGB565.RGB565_to_ARGB8(data.getShort()); |
|
|
|
|
int col1 = RGB565.RGB565_to_ARGB8(data.getShort()); |
|
|
|
@ -107,13 +101,11 @@ public class TextureBlenderDDS extends TextureBlenderAWT { |
|
|
|
|
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; |
|
|
|
|
newData.putShort(rgb565); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// just copy the remaining 4 bytes of the current texel
|
|
|
|
|
newData.putInt(dataIndex, data.getInt()); |
|
|
|
|
dataIndex += 4; |
|
|
|
|
newData.putInt(data.getInt()); |
|
|
|
|
|
|
|
|
|
++baseXTexelIndex; |
|
|
|
|
if(baseXTexelIndex > image.getWidth() >> 2) { |
|
|
|
@ -121,13 +113,13 @@ public class TextureBlenderDDS extends TextureBlenderAWT { |
|
|
|
|
++baseYTexelIndex; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|