Support for multilayered textures and textures with mipmaps.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9402 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Kae..pl 13 years ago
parent 0090d4eaad
commit 9e2f6b88ef
  1. 23
      engine/src/blender/com/jme3/scene/plugins/blender/textures/CombinedTexture.java
  2. 80
      engine/src/blender/com/jme3/scene/plugins/blender/textures/DDSTexelData.java
  3. 68
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java
  4. 14
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TriangulatedTexture.java
  5. 23
      engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/AbstractTextureBlender.java
  6. 6
      engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderAWT.java
  7. 7
      engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderDDS.java
  8. 5
      engine/src/blender/com/jme3/scene/plugins/blender/textures/blending/TextureBlenderLuminance.java
  9. 60
      engine/src/blender/com/jme3/scene/plugins/blender/textures/io/AWTPixelInputOutput.java
  10. 12
      engine/src/blender/com/jme3/scene/plugins/blender/textures/io/DDSPixelInputOutput.java
  11. 16
      engine/src/blender/com/jme3/scene/plugins/blender/textures/io/LuminancePixelInputOutput.java
  12. 8
      engine/src/blender/com/jme3/scene/plugins/blender/textures/io/PixelInputOutput.java

@ -100,8 +100,7 @@ public class CombinedTexture {
Texture previousTexture = null;
UVCoordinatesType masterUVCoordinatesType = null;
for (TextureData textureData : textureDatas) {
// decompress compressed textures (all will be merged into one
// texture anyway)
// decompress compressed textures (all will be merged into one texture anyway)
if (textureDatas.size() > 1 && textureData.texture.getImage().getFormat().isCompressed()) {
textureData.texture.setImage(textureHelper.decompress(textureData.texture.getImage()));
textureData.textureBlender = TextureBlenderFactory.alterTextureType(textureData.texture.getImage().getFormat(), textureData.textureBlender);
@ -228,19 +227,25 @@ public class CombinedTexture {
* the source texture
*/
private void merge(Texture2D target, Texture2D source) {
if(target.getImage().getDepth() != source.getImage().getDepth()) {
throw new IllegalArgumentException("Cannot merge images with different depths!");
}
Image sourceImage = source.getImage();
Image targetImage = target.getImage();
PixelInputOutput sourceIO = PixelIOFactory.getPixelIO(sourceImage.getFormat());
PixelInputOutput targetIO = PixelIOFactory.getPixelIO(targetImage.getFormat());
TexturePixel sourcePixel = new TexturePixel();
TexturePixel targetPixel = new TexturePixel();
int depth = target.getImage().getDepth() == 0 ? 1 : target.getImage().getDepth();
for (int layerIndex = 0; layerIndex < depth; ++layerIndex) {
for (int x = 0; x < sourceImage.getWidth(); ++x) {
for (int y = 0; y < sourceImage.getHeight(); ++y) {
sourceIO.read(sourceImage, sourcePixel, x, y);
targetIO.read(targetImage, targetPixel, x, y);
sourceIO.read(sourceImage, layerIndex, sourcePixel, x, y);
targetIO.read(targetImage, layerIndex, targetPixel, x, y);
targetPixel.merge(sourcePixel);
targetIO.write(targetImage, targetPixel, x, y);
targetIO.write(targetImage, layerIndex, targetPixel, x, y);
}
}
}
}
@ -299,18 +304,20 @@ public class CombinedTexture {
case RGBA16:
case RGBA16F:
case RGBA32F:
case RGBA8:// with these types it is better to make sure if
// the texture is or is not transparent
case RGBA8:// with these types it is better to make sure if the texture is or is not transparent
PixelInputOutput pixelInputOutput = PixelIOFactory.getPixelIO(image.getFormat());
TexturePixel pixel = new TexturePixel();
int depth = image.getDepth() == 0 ? 1 : image.getDepth();
for (int layerIndex = 0; layerIndex < depth; ++layerIndex) {
for (int x = 0; x < image.getWidth(); ++x) {
for (int y = 0; y < image.getHeight(); ++y) {
pixelInputOutput.read(image, pixel, x, y);
pixelInputOutput.read(image, layerIndex, pixel, x, y);
if (pixel.alpha < 1.0f) {
return false;
}
}
}
}
return true;
}
}

@ -1,13 +1,14 @@
package com.jme3.scene.plugins.blender.textures;
import com.jme3.math.FastMath;
import com.jme3.texture.Image.Format;
/**
* The data that helps in bytes calculations for the result image.
*
* @author Marcin Roguski (Kaelthas)
*/
/*package*/ class DDSTexelData {
/* package */class DDSTexelData {
/** The colors of the texes. */
private TexturePixel[][] colors;
/** The indexes of the texels. */
@ -21,36 +22,33 @@ import com.jme3.math.FastMath;
/** The counter of texel y row. */
private int yCounter;
/** The width of the image in pixels. */
private int pixelWidth;
private int widthInPixels;
/** The height of the image in pixels. */
private int pixelHeight;
private int heightInPixels;
/** The total texel count. */
private int xTexelCount;
/**
* Constructor. Allocates the required memory. Initializes variables.
* Constructor. Allocates memory for data structures.
*
* @param textelsCount
* the total count of the texels
* @param pixelWidth
* the width of the image in pixels
* @param pixelHeight
* the height of the image in pixels
* @param isAlpha
* indicates if the memory for alpha values should be
* allocated
* @param compressedSize
* the size of compressed image (or its mipmap)
* @param widthToHeightRatio
* width/height ratio for the image
* @param format
* the format of the image
*/
public DDSTexelData(int textelsCount, int pixelWidth, int pixelHeight, boolean isAlpha) {
textelsCount = pixelWidth * pixelHeight >> 4;
this.colors = new TexturePixel[textelsCount][];
this.indexes = new long[textelsCount];
this.xTexelCount = pixelWidth >> 2;
this.yCounter = (pixelHeight >> 2) - 1;// xCounter is 0 for now
this.pixelHeight = pixelHeight;
this.pixelWidth = pixelWidth;
if (isAlpha) {
this.alphas = new float[textelsCount][];
this.alphaIndexes = new long[textelsCount];
public DDSTexelData(int compressedSize, float widthToHeightRatio, Format format) {
int texelsCount = compressedSize * 8 / format.getBitsPerPixel() / 16;
this.colors = new TexturePixel[texelsCount][];
this.indexes = new long[texelsCount];
this.widthInPixels = (int) (0.5f * (float) Math.sqrt(this.getSizeInBytes() / widthToHeightRatio));
this.heightInPixels = (int) (this.widthInPixels / widthToHeightRatio);
this.xTexelCount = widthInPixels >> 2;
this.yCounter = (heightInPixels >> 2) - 1;// xCounter is 0 for now
if (format == Format.DXT3 || format == Format.DXT5) {
this.alphas = new float[texelsCount][];
this.alphaIndexes = new long[texelsCount];
}
}
@ -104,12 +102,15 @@ import com.jme3.math.FastMath;
* the y coordinate of the pixel
* @param result
* the table where the result is stored
* @return <b>true</b> if the pixel was correctly read and <b>false</b> if
* the position was outside the image sizes
*/
public void getRGBA8(int x, int y, byte[] result) {
int xTexetlIndex = x % pixelWidth / 4;
int yTexelIndex = y % pixelHeight / 4;
public boolean getRGBA8(int x, int y, byte[] result) {
int xTexetlIndex = x % widthInPixels / 4;
int yTexelIndex = y % heightInPixels / 4;
int texelIndex = yTexelIndex * xTexelCount + xTexetlIndex;
if (texelIndex < colors.length) {
TexturePixel[] colors = this.colors[texelIndex];
// coordinates of the pixel in the selected texel
@ -127,5 +128,30 @@ import com.jme3.math.FastMath;
result[1] = (byte) (colors[colorIndex].green * 255.0f);
result[2] = (byte) (colors[colorIndex].blue * 255.0f);
result[3] = (byte) (alpha * 255.0f);
return true;
}
return false;
}
/**
* @return the size of the decompressed texel (in bytes)
*/
public int getSizeInBytes() {
// indexes.length == count of texels
return indexes.length * 16 * 4;
}
/**
* @return image (mipmap) width
*/
public int getPixelWidth() {
return widthInPixels;
}
/**
* @return image (mipmap) height
*/
public int getPixelHeight() {
return heightInPixels;
}
}

@ -242,19 +242,28 @@ public class TextureHelper extends AbstractBlenderHelper {
depth = 1;
}
ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);
TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel(), new TexturePixel(), new TexturePixel() };
int[] sizes = image.getMipMapSizes() != null ? image.getMipMapSizes() : new int[1];
int[] newMipmapSizes = image.getMipMapSizes() != null ? new int[image.getMipMapSizes().length] : null;
for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
ByteBuffer data = image.getData(dataLayerIndex);
data.rewind();
if(sizes.length == 1) {
sizes[0] = data.remaining();
}
float widthToHeightRatio = image.getWidth() / image.getHeight();//this should always be constant for each mipmap
List<DDSTexelData> texelDataList = new ArrayList<DDSTexelData>(sizes.length);
int maxPosition = 0, resultSize = 0;
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);
for(int sizeIndex=0;sizeIndex<sizes.length;++sizeIndex) {
maxPosition += sizes[sizeIndex];
DDSTexelData texelData = new DDSTexelData(sizes[sizeIndex], widthToHeightRatio, format);
texelDataList.add(texelData);
switch (format) {
case DXT1:// BC1
case DXT1A:
while (data.hasRemaining()) {
while (data.position() < maxPosition) {
TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel(), new TexturePixel(), new TexturePixel() };
short c0 = data.getShort();
short c1 = data.getShort();
int col0 = RGB565.RGB565_to_ARGB8(c0);
@ -287,7 +296,8 @@ public class TextureHelper extends AbstractBlenderHelper {
}
break;
case DXT3:// BC2
while (data.hasRemaining()) {
while (data.position() < maxPosition) {
TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel(), new TexturePixel(), new TexturePixel() };
long alpha = data.getLong();
float[] alphas = new float[16];
long alphasIndex = 0;
@ -322,7 +332,8 @@ public class TextureHelper extends AbstractBlenderHelper {
break;
case DXT5:// BC3
float[] alphas = new float[8];
while (data.hasRemaining()) {
while (data.position() < maxPosition) {
TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel(), new TexturePixel(), new TexturePixel() };
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;
@ -368,24 +379,34 @@ public class TextureHelper extends AbstractBlenderHelper {
default:
throw new IllegalStateException("Unknown compressed format: " + format);
}
newMipmapSizes[sizeIndex] = texelData.getSizeInBytes();
resultSize += texelData.getSizeInBytes();
}
byte[] bytes = new byte[resultSize];
int offset = 0;
byte[] pixelBytes = new byte[4];
for (int i = 0; i < image.getWidth(); ++i) {
for (int j = 0; j < image.getHeight(); ++j) {
texelData.getRGBA8(i, j, pixelBytes);
bytes[(j * image.getWidth() + i) * 4] = pixelBytes[0];
bytes[(j * image.getWidth() + i) * 4 + 1] = pixelBytes[1];
bytes[(j * image.getWidth() + i) * 4 + 2] = pixelBytes[2];
bytes[(j * image.getWidth() + i) * 4 + 3] = pixelBytes[3];
for(DDSTexelData texelData : texelDataList) {
for (int i = 0; i < texelData.getPixelWidth(); ++i) {
for (int j = 0; j < texelData.getPixelHeight(); ++j) {
if(texelData.getRGBA8(i, j, pixelBytes)) {
bytes[offset + (j * texelData.getPixelWidth() + i) * 4] = pixelBytes[0];
bytes[offset + (j * texelData.getPixelWidth() + i) * 4 + 1] = pixelBytes[1];
bytes[offset + (j * texelData.getPixelWidth() + i) * 4 + 2] = pixelBytes[2];
bytes[offset + (j * texelData.getPixelWidth() + i) * 4 + 3] = pixelBytes[3];
} else {
break;
}
}
}
offset += texelData.getSizeInBytes();
}
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());
if(newMipmapSizes != null) {
result.setMipMapSizes(newMipmapSizes);
}
return result;
}
@ -500,13 +521,15 @@ public class TextureHelper extends AbstractBlenderHelper {
float gfac = ((Number) tex.getFieldValue("gfac")).floatValue();
float bfac = ((Number) tex.getFieldValue("bfac")).floatValue();
float[][] colorBand = new ColorBand(tex, blenderContext).computeValues();
int depth = image.getDepth() == 0 ? 1 : image.getDepth();
if (colorBand != null) {
TexturePixel pixel = new TexturePixel();
PixelInputOutput imageIO = PixelIOFactory.getPixelIO(image.getFormat());
for (int layerIndex = 0; layerIndex < depth; ++layerIndex) {
for (int x = 0; x < image.getWidth(); ++x) {
for (int y = 0; y < image.getHeight(); ++y) {
imageIO.read(image, pixel, x, y);
imageIO.read(image, layerIndex, pixel, x, y);
int colorbandIndex = (int) (pixel.alpha * 1000.0f);
pixel.red = colorBand[colorbandIndex][0] * rfac;
@ -514,21 +537,24 @@ public class TextureHelper extends AbstractBlenderHelper {
pixel.blue = colorBand[colorbandIndex][2] * bfac;
pixel.alpha = colorBand[colorbandIndex][3];
imageIO.write(image, pixel, x, y);
imageIO.write(image, layerIndex, pixel, x, y);
}
}
}
} else if (rfac != 1.0f || gfac != 1.0f || bfac != 1.0f) {
TexturePixel pixel = new TexturePixel();
PixelInputOutput imageIO = PixelIOFactory.getPixelIO(image.getFormat());
for (int layerIndex = 0; layerIndex < depth; ++layerIndex) {
for (int x = 0; x < image.getWidth(); ++x) {
for (int y = 0; y < image.getHeight(); ++y) {
imageIO.read(image, pixel, x, y);
imageIO.read(image, layerIndex, pixel, x, y);
pixel.red *= rfac;
pixel.green *= gfac;
pixel.blue *= bfac;
imageIO.write(image, pixel, x, y);
imageIO.write(image, layerIndex, pixel, x, y);
}
}
}
}

@ -184,10 +184,10 @@ import com.jme3.util.BufferUtils;
for (int x = 0; x < sourceImage.getWidth(); ++x) {
for (int y = 0; y < sourceImage.getHeight(); ++y) {
sourceIO.read(sourceImage, sourcePixel, x, y);
targetIO.read(targetImage, targetPixel, x, y);
sourceIO.read(sourceImage, 0, sourcePixel, x, y);
targetIO.read(targetImage, 0, targetPixel, x, y);
targetPixel.merge(sourcePixel);
targetIO.write(targetImage, targetPixel, x, y);
targetIO.write(targetImage, 0, targetPixel, x, y);
}
}
}
@ -331,8 +331,8 @@ import com.jme3.util.BufferUtils;
for (int x = 0; x < source.getWidth(); ++x) {
for (int y = 0; y < source.getHeight(); ++y) {
sourceIO.read(source, pixel, x, y);
targetIO.write(target, pixel, targetXPos + x, targetYPos + y);
sourceIO.read(source, 0, pixel, x, y);
targetIO.write(target, 0, pixel, targetXPos + x, targetYPos + y);
}
}
}
@ -465,7 +465,7 @@ import com.jme3.util.BufferUtils;
for (int x = minX; x < maxX; ++x) {
int xPos = x >= sourceImage.getWidth() ? x - sourceImage.getWidth() : x;
int yPos = y >= sourceImage.getHeight() ? y - sourceImage.getHeight() : y;
pixelReader.read(sourceImage, pixel, xPos, yPos);
pixelReader.read(sourceImage, 0, pixel, xPos, yPos);
data.put(pixel.getR8());
data.put(pixel.getG8());
data.put(pixel.getB8());
@ -542,7 +542,7 @@ import com.jme3.util.BufferUtils;
for (int y = 0; y < imageHeight; ++y) {
this.toTextureUV(boundingBox, point, uvs);
texture.getPixel(pixel, uvs[0], uvs[1], uvs[2]);
pixelWriter.write(image, pixel, x, y);
pixelWriter.write(image, 0, pixel, x, y);
point.addLocal(hDelta);
}

@ -2,8 +2,11 @@ package com.jme3.scene.plugins.blender.textures.blending;
import java.util.logging.Logger;
import jme3tools.converters.MipMapGenerator;
import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.materials.MaterialHelper;
import com.jme3.texture.Image;
/**
* An abstract class that contains the basic methods used by the classes that
@ -112,4 +115,24 @@ import com.jme3.scene.plugins.blender.materials.MaterialHelper;
LOGGER.warning("Cannot copy blending data from other types than " + this.getClass());
}
}
/**
* The method prepares images for blending. It generates mipmaps if one of
* the images has them defined and the other one has not.
*
* @param target
* the image where the blending result is stored
* @param source
* the image that is being read only
*/
protected void prepareImagesForBlending(Image target, Image source) {
LOGGER.fine("Generating mipmaps if needed!");
boolean targetHasMipmaps = target == null ? false : target.getMipMapSizes() != null && target.getMipMapSizes().length > 0;
boolean sourceHasMipmaps = source == null ? false : source.getMipMapSizes() != null && source.getMipMapSizes().length > 0;
if (target != null && !targetHasMipmaps && sourceHasMipmaps) {
MipMapGenerator.generateMipMaps(target);
} else if (source != null && !sourceHasMipmaps && targetHasMipmaps) {
MipMapGenerator.generateMipMaps(source);
}
}
}

@ -40,6 +40,8 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
}
public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
this.prepareImagesForBlending(image, baseImage);
float[] pixelColor = new float[] { color[0], color[1], color[2], 1.0f };
Format format = image.getFormat();
@ -70,12 +72,12 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
while (index < data.limit()) {
//getting the proper material color if the base texture is applied
if(basePixelIO != null) {
basePixelIO.read(baseImage, basePixel, x, y);
basePixelIO.read(baseImage, dataLayerIndex, basePixel, x, y);
basePixel.toRGBA(materialColor);
}
//reading the current texture's pixel
pixelReader.read(image, pixel, index);
pixelReader.read(image, dataLayerIndex, pixel, index);
index += image.getFormat().getBitsPerPixel() >> 3;
pixel.toRGBA(pixelColor);
if (negateTexture) {

@ -28,6 +28,8 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
@Override
public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
this.prepareImagesForBlending(image, baseImage);
Format format = image.getFormat();
int width = image.getWidth();
int height = image.getHeight();
@ -55,7 +57,6 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
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();
@ -84,8 +85,8 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
//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
basePixelIO.read(baseImage, dataLayerIndex, baseTextureColors[0], baseXTexelIndex << 2, baseYTexelIndex << 2);//first pixel
basePixelIO.read(baseImage, dataLayerIndex, baseTextureColors[1], baseXTexelIndex << 2 + 4, baseYTexelIndex << 2 + 4);//last pixel
baseTextureColors[0].toRGBA(compressedMaterialColor[0]);
baseTextureColors[1].toRGBA(compressedMaterialColor[1]);
}

@ -34,8 +34,9 @@ public class TextureBlenderLuminance extends AbstractTextureBlender {
}
public Image blend(Image image, Image baseImage, BlenderContext blenderContext) {
Format format = image.getFormat();
this.prepareImagesForBlending(image, baseImage);
Format format = image.getFormat();
PixelInputOutput basePixelIO = null;
TexturePixel basePixel = null;
float[] materialColor = this.materialColor;
@ -64,7 +65,7 @@ public class TextureBlenderLuminance extends AbstractTextureBlender {
while (data.hasRemaining()) {
//getting the proper material color if the base texture is applied
if(basePixelIO != null) {
basePixelIO.read(baseImage, basePixel, x, y);
basePixelIO.read(baseImage, dataLayerIndex, basePixel, x, y);
basePixel.toRGBA(materialColor);
}

@ -1,5 +1,7 @@
package com.jme3.scene.plugins.blender.textures.io;
import java.nio.ByteBuffer;
import com.jme3.scene.plugins.blender.textures.TexturePixel;
import com.jme3.texture.Image;
@ -8,25 +10,26 @@ import com.jme3.texture.Image;
* @author Marcin Roguski (Kaelthas)
*/
/*package*/ class AWTPixelInputOutput implements PixelInputOutput {
public void read(Image image, TexturePixel pixel, int index) {
public void read(Image image, int layer, TexturePixel pixel, int index) {
byte r,g,b,a;
ByteBuffer data = image.getData(layer);
switch(image.getFormat()) {//TODO: add other formats
case RGBA8:
r = image.getData(0).get(index);
g = image.getData(0).get(index + 1);
b = image.getData(0).get(index + 2);
a = image.getData(0).get(index + 3);
r = data.get(index);
g = data.get(index + 1);
b = data.get(index + 2);
a = data.get(index + 3);
break;
case ABGR8:
a = image.getData(0).get(index);
b = image.getData(0).get(index + 1);
g = image.getData(0).get(index + 2);
r = image.getData(0).get(index + 3);
a = data.get(index);
b = data.get(index + 1);
g = data.get(index + 2);
r = data.get(index + 3);
break;
case BGR8:
b = image.getData(0).get(index);
g = image.getData(0).get(index + 1);
r = image.getData(0).get(index + 2);
b = data.get(index);
g = data.get(index + 1);
r = data.get(index + 2);
a = (byte)0xFF;
break;
default:
@ -35,37 +38,38 @@ import com.jme3.texture.Image;
pixel.fromARGB8(a, r, g, b);
}
public void read(Image image, TexturePixel pixel, int x, int y) {
public void read(Image image, int layer, TexturePixel pixel, int x, int y) {
int index = (y * image.getWidth() + x) * (image.getFormat().getBitsPerPixel() >> 3);
this.read(image, pixel, index);
this.read(image, layer, pixel, index);
}
public void write(Image image, TexturePixel pixel, int index) {
public void write(Image image, int layer, TexturePixel pixel, int index) {
ByteBuffer data = image.getData(layer);
switch(image.getFormat()) {
case RGBA8:
image.getData(0).put(index, pixel.getR8());
image.getData(0).put(index + 1, pixel.getG8());
image.getData(0).put(index + 2, pixel.getB8());
image.getData(0).put(index + 3, pixel.getA8());
data.put(index, pixel.getR8());
data.put(index + 1, pixel.getG8());
data.put(index + 2, pixel.getB8());
data.put(index + 3, pixel.getA8());
break;
case ABGR8:
image.getData(0).put(index, pixel.getA8());
image.getData(0).put(index + 1, pixel.getB8());
image.getData(0).put(index + 2, pixel.getG8());
image.getData(0).put(index + 3, pixel.getR8());
data.put(index, pixel.getA8());
data.put(index + 1, pixel.getB8());
data.put(index + 2, pixel.getG8());
data.put(index + 3, pixel.getR8());
break;
case BGR8:
image.getData(0).put(index, pixel.getB8());
image.getData(0).put(index + 1, pixel.getG8());
image.getData(0).put(index + 2, pixel.getR8());
data.put(index, pixel.getB8());
data.put(index + 1, pixel.getG8());
data.put(index + 2, pixel.getR8());
break;
default:
throw new IllegalStateException("Unknown image format: " + image.getFormat());
}
}
public void write(Image image, TexturePixel pixel, int x, int y) {
public void write(Image image, int layer, TexturePixel pixel, int x, int y) {
int index = (y * image.getWidth() + x) * (image.getFormat().getBitsPerPixel() >> 3);
this.write(image, pixel, index);
this.write(image, layer, pixel, index);
}
}

@ -17,11 +17,11 @@ import com.jme3.texture.Image;
/**
* 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) {
this.read(image, pixel, index % image.getWidth(), index / image.getWidth());
public void read(Image image, int layer, TexturePixel pixel, int index) {
this.read(image, layer, pixel, index % image.getWidth(), index / image.getWidth());
}
public void read(Image image, TexturePixel pixel, int x, int y) {
public void read(Image image, int layer, TexturePixel pixel, int x, int y) {
int xTexetlIndex = x % image.getWidth() >> 2;
int yTexelIndex = y % image.getHeight() >> 2;
int xTexelCount = image.getWidth() >> 2;
@ -31,7 +31,7 @@ import com.jme3.texture.Image;
int indexes = 0;
long alphaIndexes = 0;
float[] alphas = null;
ByteBuffer data = image.getData().get(0);
ByteBuffer data = image.getData().get(layer);
switch (image.getFormat()) {
case DXT1: // BC1
@ -162,11 +162,11 @@ import com.jme3.texture.Image;
pixel.alpha = alpha;
}
public void write(Image image, TexturePixel pixel, int index) {
public void write(Image image, int layer, TexturePixel pixel, int index) {
throw new UnsupportedOperationException("Cannot put the DXT pixel by index because not every index contains the pixel color!");
}
public void write(Image image, TexturePixel pixel, int x, int y) {
public void write(Image image, int layer, TexturePixel pixel, int x, int y) {
throw new UnsupportedOperationException("Writing to DDS texture pixel by pixel is not yet supported!");
}
}

@ -8,22 +8,22 @@ import com.jme3.texture.Image;
* @author Marcin Roguski (Kaelthas)
*/
/*package*/ class LuminancePixelInputOutput implements PixelInputOutput {
public void read(Image image, TexturePixel pixel, int index) {
byte intensity = image.getData(0).get(index);
public void read(Image image, int layer, TexturePixel pixel, int index) {
byte intensity = image.getData(layer).get(index);
pixel.fromIntensity(intensity);
}
public void read(Image image, TexturePixel pixel, int x, int y) {
public void read(Image image, int layer, TexturePixel pixel, int x, int y) {
int index = y * image.getWidth() + x;
this.read(image, pixel, index);
this.read(image, layer, pixel, index);
}
public void write(Image image, TexturePixel pixel, int index) {
image.getData(0).put(index, pixel.getInt());
public void write(Image image, int layer, TexturePixel pixel, int index) {
image.getData(layer).put(index, pixel.getInt());
}
public void write(Image image, TexturePixel pixel, int x, int y) {
public void write(Image image, int layer, TexturePixel pixel, int x, int y) {
int index = y * image.getWidth() + x;
this.write(image, pixel, index);
this.write(image, layer,pixel, index);
}
}

@ -19,7 +19,7 @@ public interface PixelInputOutput {
* @param index
* the index where the pixel begins in the image data
*/
void read(Image image, TexturePixel pixel, int index);
void read(Image image, int layer, TexturePixel pixel, int index);
/**
* This method reads a pixel that is located at the given position on the
@ -34,7 +34,7 @@ public interface PixelInputOutput {
* @param y
* the Y coordinate of the pixel
*/
void read(Image image, TexturePixel pixel, int x, int y);
void read(Image image, int layer, TexturePixel pixel, int x, int y);
/**
* This method writes a pixel that starts at the given index.
@ -46,7 +46,7 @@ public interface PixelInputOutput {
* @param index
* the index where the pixel begins in the image data
*/
void write(Image image, TexturePixel pixel, int index);
void write(Image image, int layer, TexturePixel pixel, int index);
/**
* This method writes a pixel that is located at the given position on the
@ -61,5 +61,5 @@ public interface PixelInputOutput {
* @param y
* the Y coordinate of the pixel
*/
void write(Image image, TexturePixel pixel, int x, int y);
void write(Image image, int layer, TexturePixel pixel, int x, int y);
}

Loading…
Cancel
Save