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.BlenderContext;
import com.jme3.scene.plugins.blender.textures.TexturePixel; 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;
import com.jme3.texture.Image.Format; import com.jme3.texture.Image.Format;
import com.jme3.util.BufferUtils; import com.jme3.util.BufferUtils;
@ -29,7 +31,6 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
super(flag, negateTexture, blendType, materialColor, color, blendFactor); super(flag, negateTexture, blendType, materialColor, color, blendFactor);
} }
//TODO: implement using base texture
@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();
@ -43,28 +44,56 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
depth = 1; depth = 1;
} }
ByteBuffer newData = BufferUtils.createByteBuffer(data.remaining()); 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[] 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; int dataIndex = 0, baseXTexelIndex = 0, baseYTexelIndex = 0;
float[] alphas = new float[] {1, 1};
while (data.hasRemaining()) { while (data.hasRemaining()) {
switch (format) { if(format == Format.DXT1A) {
case DXT3: LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", format);
case DXT5: break;
newData.putLong(dataIndex, data.getLong());// just copy the 8 bytes of alphas }
dataIndex += 8; if(format == Format.DXT3) {
case DXT1: long alpha = data.getLong();
int col0 = RGB565.RGB565_to_ARGB8(data.getShort()); //get alpha for first and last pixel that is compressed in the texel
int col1 = RGB565.RGB565_to_ARGB8(data.getShort()); byte alpha0 = (byte)(alpha << 4 & 0xFF);
colors[0].fromARGB8(col0); byte alpha1 = (byte)(alpha >> 60 & 0xFF);
colors[1].fromARGB8(col1); alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
break; alphas[1] = alpha1 >= 0 ? alpha1 / 255.0f : 1.0f - ~alpha1 / 255.0f;
case DXT1A: dataIndex += 8;
LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", format); } else if(format == Format.DXT5) {
break; byte alpha0 = data.get();
default: byte alpha1 = data.get();
throw new IllegalStateException("Invalid image format type for DDS texture blender: " + format); 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 // blending colors
@ -73,7 +102,8 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
colors[i].negate(); colors[i].negate();
} }
colors[i].toRGBA(pixelColor); 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]); colors[i].fromARGB8(1, resultPixel[0], resultPixel[1], resultPixel[2]);
int argb8 = colors[i].toARGB8(); int argb8 = colors[i].toARGB8();
short rgb565 = RGB565.ARGB8_to_RGB565(argb8); 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 // just copy the remaining 4 bytes of the current texel
newData.putInt(dataIndex, data.getInt()); newData.putInt(dataIndex, data.getInt());
dataIndex += 4; dataIndex += 4;
++baseXTexelIndex;
if(baseXTexelIndex > image.getWidth() >> 2) {
baseXTexelIndex = 0;
++baseYTexelIndex;
}
} }
if(depth > 1) { if(depth > 1) {

@ -14,8 +14,11 @@ import com.jme3.texture.Image;
* @author Marcin Roguski (Kaelthas) * @author Marcin Roguski (Kaelthas)
*/ */
/*package*/ class DDSPixelInputOutput implements PixelInputOutput { /*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) { 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) { public void read(Image image, TexturePixel pixel, int x, int y) {

Loading…
Cancel
Save