Support for base texture blending for DDS textures.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9335 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Kae..pl 13 years ago
parent 9d7d5a388c
commit 96cfd22510
  1. 76
      engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderDDS.java
  2. 5
      engine/src/blender/com/jme3/scene/plugins/blender/textures/io/DDSPixelInputOutput.java

@ -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();
@ -43,28 +44,56 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
depth = 1;
}
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
dataIndex += 8;
case DXT1:
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);
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]);
}
// 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…
Cancel
Save