Support for base texture blending for DDS textures.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9335 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
9d7d5a388c
commit
96cfd22510
@ -9,6 +9,8 @@ import jme3tools.converters.RGB565;
|
||||
|
||||
import com.jme3.scene.plugins.blender.BlenderContext;
|
||||
import com.jme3.scene.plugins.blender.textures.TexturePixel;
|
||||
import com.jme3.scene.plugins.blender.textures.io.PixelIOFactory;
|
||||
import com.jme3.scene.plugins.blender.textures.io.PixelInputOutput;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Image.Format;
|
||||
import com.jme3.util.BufferUtils;
|
||||
@ -29,7 +31,6 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
||||
super(flag, negateTexture, blendType, materialColor, color, blendFactor);
|
||||
}
|
||||
|
||||
//TODO: implement using base texture
|
||||
@Override
|
||||
public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
|
||||
Format format = image.getFormat();
|
||||
@ -44,27 +45,55 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
||||
}
|
||||
ByteBuffer newData = BufferUtils.createByteBuffer(data.remaining());
|
||||
|
||||
PixelInputOutput basePixelIO = null;
|
||||
float[][] compressedMaterialColor = null;
|
||||
TexturePixel[] baseTextureColors = null;
|
||||
if(baseImage != null) {
|
||||
basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat());
|
||||
compressedMaterialColor = new float[2][4];
|
||||
baseTextureColors = new TexturePixel[] { new TexturePixel(), new TexturePixel() };
|
||||
}
|
||||
|
||||
float[] resultPixel = new float[4];
|
||||
float[] pixelColor = new float[4];
|
||||
TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel() };
|
||||
int dataIndex = 0;
|
||||
int dataIndex = 0, baseXTexelIndex = 0, baseYTexelIndex = 0;
|
||||
float[] alphas = new float[] {1, 1};
|
||||
while (data.hasRemaining()) {
|
||||
switch (format) {
|
||||
case DXT3:
|
||||
case DXT5:
|
||||
newData.putLong(dataIndex, data.getLong());// just copy the 8 bytes of alphas
|
||||
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;
|
||||
case DXT1:
|
||||
} 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);
|
||||
break;
|
||||
case DXT1A:
|
||||
LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", format);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid image format type for DDS texture blender: " + format);
|
||||
|
||||
//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
|
||||
@ -73,7 +102,8 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
||||
colors[i].negate();
|
||||
}
|
||||
colors[i].toRGBA(pixelColor);
|
||||
this.blendPixel(resultPixel, materialColor, pixelColor, blenderContext);
|
||||
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);
|
||||
@ -84,6 +114,12 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
if(depth > 1) {
|
||||
|
@ -14,8 +14,11 @@ import com.jme3.texture.Image;
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
/*package*/ class DDSPixelInputOutput implements PixelInputOutput {
|
||||
/**
|
||||
* For this class the index should be considered as a pixel index in AWT image format.
|
||||
*/
|
||||
public void read(Image image, TexturePixel pixel, int index) {
|
||||
throw new UnsupportedOperationException("Cannot get the DXT pixel by index because not every index contains the pixel color!");
|
||||
this.read(image, pixel, index % image.getWidth(), index / image.getWidth());
|
||||
}
|
||||
|
||||
public void read(Image image, TexturePixel pixel, int x, int y) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user