use of com.jme3.scene.plugins.blender.textures.io.PixelInputOutput in project jmonkeyengine by jMonkeyEngine.
the class CombinedTexture method isWithoutAlpha.
/**
* This method determines if the given texture has no alpha channel.
*
* @param texture
* the texture to check for alpha channel
* @return <b>true</b> if the texture has no alpha channel and <b>false</b>
* otherwise
*/
private boolean isWithoutAlpha(TextureData textureData, BlenderContext blenderContext) {
ColorBand colorBand = new ColorBand(textureData.textureStructure, blenderContext);
if (!colorBand.hasTransparencies()) {
int type = ((Number) textureData.textureStructure.getFieldValue("type")).intValue();
if (type == TextureHelper.TEX_MAGIC) {
return true;
}
if (type == TextureHelper.TEX_VORONOI) {
int voronoiColorType = ((Number) textureData.textureStructure.getFieldValue("vn_coltype")).intValue();
// voronoiColorType == 0:
return voronoiColorType != 0;
// intensity, voronoiColorType
// != 0: col1, col2 or col3
}
if (type == TextureHelper.TEX_CLOUDS) {
int sType = ((Number) textureData.textureStructure.getFieldValue("stype")).intValue();
// sType==0: without colors, sType==1: with
return sType == 1;
// colors
}
// checking the flat textures for alpha values presence
if (type == TextureHelper.TEX_IMAGE) {
Image image = textureData.texture.getImage();
switch(image.getFormat()) {
case BGR8:
case DXT1:
case Luminance16F:
case Luminance32F:
case Luminance8:
case RGB111110F:
case RGB16F:
case RGB32F:
case RGB565:
case RGB8:
// these types have no alpha by definition
return true;
case ABGR8:
case DXT1A:
case DXT3:
case DXT5:
case Luminance16FAlpha16F:
case Luminance8Alpha8:
case RGBA16F:
case RGBA32F:
case RGBA8:
case ARGB8:
case BGRA8:
case // with these types it is better to make sure if the texture is or is not transparent
RGB5A1:
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, layerIndex, pixel, x, y);
if (pixel.alpha < 1.0f) {
return false;
}
}
}
}
return true;
default:
throw new IllegalStateException("Unknown image format: " + image.getFormat());
}
}
}
return false;
}
use of com.jme3.scene.plugins.blender.textures.io.PixelInputOutput in project jmonkeyengine by jMonkeyEngine.
the class CombinedTexture method generateSkyTexture.
/**
* Generates a texture that will be used by the sky spatial.
* The result texture has 6 layers. Every image in each layer has equal size and its shape is a square.
* The size of each image is the maximum size (width or height) of the textures given.
* The default sky generated texture size is used (this value is set in the BlenderKey) if no picture textures
* are present or their sizes is lower than the generated texture size.
* The textures of lower sizes are properly scaled.
* All the textures are mixed into one and put as layers in the result texture.
*
* @param horizontalColor
* the horizon color
* @param zenithColor
* the zenith color
* @param blenderContext
* the blender context
* @return texture for the sky
*/
public TextureCubeMap generateSkyTexture(ColorRGBA horizontalColor, ColorRGBA zenithColor, BlenderContext blenderContext) {
LOGGER.log(Level.FINE, "Preparing sky texture from {0} applied textures.", textureDatas.size());
LOGGER.fine("Computing the texture size.");
int size = -1;
for (TextureData textureData : textureDatas) {
if (textureData.texture instanceof Texture2D) {
size = Math.max(textureData.texture.getImage().getWidth(), size);
size = Math.max(textureData.texture.getImage().getHeight(), size);
}
}
if (size < 0) {
size = blenderContext.getBlenderKey().getSkyGeneratedTextureSize();
}
LOGGER.log(Level.FINE, "The sky texture size will be: {0}x{0}.", size);
TextureCubeMap result = null;
for (TextureData textureData : textureDatas) {
TextureCubeMap texture = null;
if (textureData.texture instanceof GeneratedTexture) {
texture = ((GeneratedTexture) textureData.texture).generateSkyTexture(size, horizontalColor, zenithColor, blenderContext);
} else {
// first create a grayscale version of the image
Image image = textureData.texture.getImage();
if (image.getWidth() != image.getHeight() || image.getWidth() != size) {
image = ImageUtils.resizeTo(image, size, size);
}
Image grayscaleImage = ImageUtils.convertToGrayscaleTexture(image);
// add the sky colors to the image
PixelInputOutput sourcePixelIO = PixelIOFactory.getPixelIO(grayscaleImage.getFormat());
PixelInputOutput targetPixelIO = PixelIOFactory.getPixelIO(image.getFormat());
TexturePixel texturePixel = new TexturePixel();
for (int x = 0; x < image.getWidth(); ++x) {
for (int y = 0; y < image.getHeight(); ++y) {
sourcePixelIO.read(grayscaleImage, 0, texturePixel, x, y);
// no matter which factor we use here, in grayscale they are all equal
texturePixel.intensity = texturePixel.red;
ImageUtils.color(texturePixel, horizontalColor, zenithColor);
targetPixelIO.write(image, 0, texturePixel, x, y);
}
}
// create the cubemap texture from the coloured image
ByteBuffer sourceData = image.getData(0);
ArrayList<ByteBuffer> data = new ArrayList<ByteBuffer>(6);
for (int i = 0; i < 6; ++i) {
data.add(BufferUtils.clone(sourceData));
}
texture = new TextureCubeMap(new Image(image.getFormat(), image.getWidth(), image.getHeight(), 6, data, ColorSpace.Linear));
}
if (result == null) {
result = texture;
} else {
ImageUtils.mix(result.getImage(), texture.getImage());
}
}
return result;
}
use of com.jme3.scene.plugins.blender.textures.io.PixelInputOutput in project jmonkeyengine by jMonkeyEngine.
the class GeneratedTexture method generateSkyTexture.
/**
* Creates a texture for the sky. The result texture has 6 layers.
* @param size
* the size of the texture (width and height are equal)
* @param horizontalColor
* the horizon color
* @param zenithColor
* the zenith color
* @param blenderContext
* the blender context
* @return the sky texture
*/
public TextureCubeMap generateSkyTexture(int size, ColorRGBA horizontalColor, ColorRGBA zenithColor, BlenderContext blenderContext) {
Image image = ImageUtils.createEmptyImage(Format.RGB8, size, size, 6);
PixelInputOutput pixelIO = PixelIOFactory.getPixelIO(image.getFormat());
TexturePixel pixel = new TexturePixel();
float delta = 1 / (float) (size - 1);
float sideV, sideS = 1, forwardU = 1, forwardV, upS;
TempVars tempVars = TempVars.get();
CastFunction castFunction = CAST_FUNCTIONS[blenderContext.getBlenderKey().getSkyGeneratedTextureShape().ordinal()];
float castRadius = blenderContext.getBlenderKey().getSkyGeneratedTextureRadius();
for (int x = 0; x < size; ++x) {
sideV = 1;
forwardV = 1;
upS = 0;
for (int y = 0; y < size; ++y) {
castFunction.cast(tempVars.vect1.set(1, sideV, sideS), castRadius);
textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
// right
pixelIO.write(image, NEGATIVE_X, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);
castFunction.cast(tempVars.vect1.set(0, sideV, 1 - sideS), castRadius);
textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
// left
pixelIO.write(image, POSITIVE_X, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);
castFunction.cast(tempVars.vect1.set(forwardU, forwardV, 0), castRadius);
textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
// front
pixelIO.write(image, POSITIVE_Z, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);
castFunction.cast(tempVars.vect1.set(1 - forwardU, forwardV, 1), castRadius);
textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
// back
pixelIO.write(image, NEGATIVE_Z, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);
castFunction.cast(tempVars.vect1.set(forwardU, 0, upS), castRadius);
textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
// top
pixelIO.write(image, NEGATIVE_Y, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);
castFunction.cast(tempVars.vect1.set(forwardU, 1, 1 - upS), castRadius);
textureGenerator.getPixel(pixel, tempVars.vect1.x, tempVars.vect1.y, tempVars.vect1.z);
// bottom
pixelIO.write(image, POSITIVE_Y, ImageUtils.color(pixel, horizontalColor, zenithColor), x, y);
sideV = FastMath.clamp(sideV - delta, 0, 1);
forwardV = FastMath.clamp(forwardV - delta, 0, 1);
upS = FastMath.clamp(upS + delta, 0, 1);
}
sideS = FastMath.clamp(sideS - delta, 0, 1);
forwardU = FastMath.clamp(forwardU - delta, 0, 1);
}
tempVars.release();
return new TextureCubeMap(image);
}
use of com.jme3.scene.plugins.blender.textures.io.PixelInputOutput in project jmonkeyengine by jMonkeyEngine.
the class ImageUtils method merge.
/**
* This method merges two given images. The result is stored in the
* 'target' image.
*
* @param targetImage
* the target image
* @param sourceImage
* the source image
*/
public static void merge(Image targetImage, Image sourceImage) {
if (sourceImage.getDepth() != targetImage.getDepth()) {
throw new IllegalArgumentException("The given images should have the same depth to merge them!");
}
if (sourceImage.getWidth() != targetImage.getWidth()) {
throw new IllegalArgumentException("The given images should have the same width to merge them!");
}
if (sourceImage.getHeight() != targetImage.getHeight()) {
throw new IllegalArgumentException("The given images should have the same height to merge them!");
}
PixelInputOutput sourceIO = PixelIOFactory.getPixelIO(sourceImage.getFormat());
PixelInputOutput targetIO = PixelIOFactory.getPixelIO(targetImage.getFormat());
TexturePixel sourcePixel = new TexturePixel();
TexturePixel targetPixel = new TexturePixel();
int depth = targetImage.getDepth() == 0 ? 1 : targetImage.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, layerIndex, sourcePixel, x, y);
targetIO.read(targetImage, layerIndex, targetPixel, x, y);
targetPixel.merge(sourcePixel);
targetIO.write(targetImage, layerIndex, targetPixel, x, y);
}
}
}
}
use of com.jme3.scene.plugins.blender.textures.io.PixelInputOutput in project jmonkeyengine by jMonkeyEngine.
the class TextureHelper method getSubimage.
/**
* This method returns subimage of the give image. The subimage is
* constrained by the rectangle coordinates. The source image is unchanged.
*
* @param image
* the image to be subimaged
* @param minX
* minimum X position
* @param minY
* minimum Y position
* @param maxX
* maximum X position
* @param maxY
* maximum Y position
* @return a part of the given image
*/
public Image getSubimage(Image image, int minX, int minY, int maxX, int maxY) {
if (minY > maxY) {
throw new IllegalArgumentException("Minimum Y value is higher than maximum Y value!");
}
if (minX > maxX) {
throw new IllegalArgumentException("Minimum Y value is higher than maximum Y value!");
}
if (image.getData().size() > 1) {
throw new IllegalArgumentException("Only flat images are allowed for subimage operation!");
}
if (image.getMipMapSizes() != null) {
LOGGER.warning("Subimaging image with mipmaps is not yet supported!");
}
int width = maxX - minX;
int height = maxY - minY;
ByteBuffer data = BufferUtils.createByteBuffer(width * height * (image.getFormat().getBitsPerPixel() >> 3));
Image result = new Image(image.getFormat(), width, height, data, ColorSpace.sRGB);
PixelInputOutput pixelIO = PixelIOFactory.getPixelIO(image.getFormat());
TexturePixel pixel = new TexturePixel();
for (int x = minX; x < maxX; ++x) {
for (int y = minY; y < maxY; ++y) {
pixelIO.read(image, 0, pixel, x, y);
pixelIO.write(result, 0, pixel, x - minX, y - minY);
}
}
return result;
}
Aggregations