Hello,
I asked this question already roughly half a year ago, but didn’t get any answer, so I’ll try again.
I have problems with a texture combiner of mine. What is it supposed to be doing? It is supposed to combine multiple texture images into one. I use this for a paperdoll character creation system, where the user can build together his avatar from different sprite parts he can choose.
The code of the class which should combine the texture parts into one is this:
[java]
import com.jme3.texture.Image;
import com.jme3.texture.Image.Format;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.MagFilter;
import com.jme3.texture.Texture2D;
import com.jme3.util.BufferUtils;
import java.awt.Color;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
- Provides methods to combine parts of a sprite into one sprite.
/
public class SpriteCreator {
/* Holds pixel data of the texture to create. /
protected byte[] m_data;
protected Texture2D m_baseTexture;
protected Texture2D m_hairTexture;
protected Texture2D m_topTexture;
protected Texture2D m_bottomTexture;
protected Texture2D m_faceTexture;
protected Texture2D m_bagTexture;
protected byte[] m_baseImageData;
protected byte[] m_hairImageData;
protected byte[] m_topImageData;
protected byte[] m_bottomImageData;
protected byte[] m_faceImageData;
protected byte[] m_bagImageData;
/* Width of the created texture. /
int m_width;
/* Height of the created texture. */
int m_height;
public SpriteCreator(int width, int height) {
this.m_width = width;
this.m_height = height;
m_baseImageData = new byte[width * height * 4];
m_hairImageData = new byte[width * height * 4];
m_topImageData = new byte[width * height * 4];
m_bottomImageData = new byte[width * height * 4];
m_faceImageData = new byte[width * height * 4];
m_bagImageData = new byte[width * height * 4];
// create black image
m_data = new byte[width * height * 4];
setBackground (new Color(0,0,0,0));
}
/**
- Creates a texture from the pixel data this object holds and returns it.
*
-
@return The texture created from the pixel data this object holds.
*/
public Texture getTexture() {
ByteBuffer buffer = BufferUtils.createByteBuffer(m_data);
Image spriteImage = new Image(Format.RGBA8, m_width, m_height, buffer);
Texture combinedTexture = new Texture2D(spriteImage);
combinedTexture.setMagFilter(MagFilter.Nearest);
return combinedTexture;
}
/**
- Sets a specified pixel to a specified color.
*
-
@param x The x-coordinate of the pixel to set.
-
@param y The y-coordinate of the pixel to set.
-
@param color The color of the pixel to set.
*/
private void setPixel(int x, int y, Color color) {
int i = (x + y * m_width) * 4;
m_data = (byte) color.getRed(); // r
m_data = (byte) color.getGreen(); // g
m_data = (byte) color.getBlue(); // b
m_data = (byte) color.getAlpha(); // a
}
/**
- Sets the pixel data of the texture to create to a combination of all stored
- individual texture parts.
*/
public void combineSprite() {
setBackground(new Color(0,0,0,0));
drawSpritePart(SpritePart.BASE);
drawSpritePart(SpritePart.TOP);
drawSpritePart(SpritePart.BOTTOM);
drawSpritePart(SpritePart.BAG);
drawSpritePart(SpritePart.FACE);
drawSpritePart(SpritePart.HAIR);
}
private void drawSpritePart(SpritePart part) {
Texture2D partToDraw = null;
byte[] imageData;
switch(part) {
case BASE:
partToDraw = m_baseTexture;
imageData = m_baseImageData;
break;
case HAIR:
partToDraw = m_hairTexture;
imageData = m_hairImageData;
break;
case TOP:
partToDraw = m_topTexture;
imageData = m_topImageData;
break;
case BOTTOM:
partToDraw = m_bottomTexture;
imageData = m_bottomImageData;
break;
case FACE:
partToDraw = m_faceTexture;
imageData = m_faceImageData;
break;
case BAG:
partToDraw = m_bagTexture;
imageData = m_bagImageData;
break;
default:
imageData = new byte[m_width * m_height * 4];
break;
}
if(partToDraw != null) {
if(partToDraw.getImage().getData().get(0).hasRemaining()) {
partToDraw.getImage().getData().get(0).get(imageData);
switch(part) {
case BASE:
m_baseImageData = Arrays.copyOf(imageData, imageData.length);
break;
case HAIR:
m_hairImageData = Arrays.copyOf(imageData, imageData.length);
break;
case TOP:
m_topImageData = Arrays.copyOf(imageData, imageData.length);
break;
case BOTTOM:
m_bottomImageData = Arrays.copyOf(imageData, imageData.length);
break;
case FACE:
m_faceImageData = Arrays.copyOf(imageData, imageData.length);
break;
case BAG:
m_bagImageData = Arrays.copyOf(imageData, imageData.length);
break;
}
}
for(int y = 0; y < m_height; y++) {
for(int x = 0; x < m_width; x++) {
int i = (x + y * m_width) * 4;
Color pixelColor;
if(ByteToUnsignedIntCaster.byteToUnsignedInt(imageData[i+3]) != 0) {
pixelColor = new Color(ByteToUnsignedIntCaster.byteToUnsignedInt(imageData),
ByteToUnsignedIntCaster.byteToUnsignedInt(imageData[i+1]),
ByteToUnsignedIntCaster.byteToUnsignedInt(imageData[i+2]),
ByteToUnsignedIntCaster.byteToUnsignedInt(imageData[i+3]));
setPixel(x, y, pixelColor);
}
}
}
}
}
public void setBaseTexture(Texture2D baseTexture) {
m_baseTexture = baseTexture;
}
public void setHairTexture(Texture2D hairTexture) {
m_hairTexture = hairTexture;
}
public void setTopTexture(Texture2D topTexture) {
m_topTexture = topTexture;
}
public void setBottomTexture(Texture2D bottomTexture) {
m_bottomTexture = bottomTexture;
}
public void setFaceTexture(Texture2D topTexture) {
m_faceTexture = topTexture;
}
public void setBagTexture(Texture2D bottomTexture) {
m_bagTexture = bottomTexture;
}
public final void setBackground(Color color) {
for (int i = 0; i < m_width * m_height * 4; i += 4) {
m_data = (byte) color.getRed(); // r
m_data = (byte) color.getGreen(); // g
m_data = (byte) color.getBlue(); // b
m_data = (byte) color.getAlpha(); // a
}
}
public enum SpritePart {
BASE, HAIR, TOP, BOTTOM, FACE, BAG
}
}[/java]
I first call the set…Texture methods, then I call combineSprite and then getTexture to get the endresult. I get the textures which I pass to set…Texture from assetManager.loadTexture();
It used to work, but after a patch/change to jmonkey, I’m getting transparent textures only (where every pixel is transparent). Any idea where the error is?