Search in sources :

Example 36 with Format

use of com.jme3.texture.Image.Format in project jmonkeyengine by jMonkeyEngine.

the class EnvMapUtils method makeCubeMap.

/**
     * Creates a cube map from 6 images
     *
     * @param leftImg the west side image, also called negative x (negX) or left
     * image
     * @param rightImg the east side image, also called positive x (posX) or
     * right image
     * @param downImg the bottom side image, also called negative y (negY) or
     * down image
     * @param upImg the up side image, also called positive y (posY) or up image
     * @param backImg the south side image, also called positive z (posZ) or
     * back image
     * @param frontImg the north side image, also called negative z (negZ) or
     * front image
     * @param format the format of the image
     * @return a cube map
     */
public static TextureCubeMap makeCubeMap(Image rightImg, Image leftImg, Image upImg, Image downImg, Image backImg, Image frontImg, Image.Format format) {
    Image cubeImage = new Image(format, leftImg.getWidth(), leftImg.getHeight(), null, ColorSpace.Linear);
    cubeImage.addData(rightImg.getData(0));
    cubeImage.addData(leftImg.getData(0));
    cubeImage.addData(upImg.getData(0));
    cubeImage.addData(downImg.getData(0));
    cubeImage.addData(backImg.getData(0));
    cubeImage.addData(frontImg.getData(0));
    if (leftImg.getEfficentData() != null) {
        // also consilidate efficient data
        ArrayList<Object> efficientData = new ArrayList<Object>(6);
        efficientData.add(rightImg.getEfficentData());
        efficientData.add(leftImg.getEfficentData());
        efficientData.add(upImg.getEfficentData());
        efficientData.add(downImg.getEfficentData());
        efficientData.add(backImg.getEfficentData());
        efficientData.add(frontImg.getEfficentData());
        cubeImage.setEfficentData(efficientData);
    }
    TextureCubeMap cubeMap = new TextureCubeMap(cubeImage);
    cubeMap.setAnisotropicFilter(0);
    cubeMap.setMagFilter(Texture.MagFilter.Bilinear);
    cubeMap.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
    cubeMap.setWrap(Texture.WrapMode.EdgeClamp);
    return cubeMap;
}
Also used : TextureCubeMap(com.jme3.texture.TextureCubeMap) ArrayList(java.util.ArrayList) Image(com.jme3.texture.Image)

Example 37 with Format

use of com.jme3.texture.Image.Format in project jmonkeyengine by jMonkeyEngine.

the class PrefilteredEnvMapFaceGenerator method generatePrefilteredEnvMap.

/**
     * Generates the prefiltered env map (used for image based specular
     * lighting) With the GGX/Shlick brdf
     * {@link EnvMapUtils#getSphericalHarmonicsCoefficents(com.jme3.texture.TextureCubeMap)}
     * Note that the output cube map is in RGBA8 format.
     *
     * @param sourceEnvMap
     * @param targetMapSize the size of the irradiance map to generate
     * @param store
     * @param fixSeamsMethod the method to fix seams
     * @return The irradiance cube map for the given coefficients
     */
private TextureCubeMap generatePrefilteredEnvMap(TextureCubeMap sourceEnvMap, int targetMapSize, EnvMapUtils.FixSeamsMethod fixSeamsMethod, TextureCubeMap store) {
    TextureCubeMap pem = store;
    int nbMipMap = (int) (Math.log(targetMapSize) / Math.log(2) - 1);
    setEnd(nbMipMap);
    CubeMapWrapper sourceWrapper = new CubeMapWrapper(sourceEnvMap);
    CubeMapWrapper targetWrapper = new CubeMapWrapper(pem);
    Vector3f texelVect = new Vector3f();
    Vector3f color = new Vector3f();
    ColorRGBA outColor = new ColorRGBA();
    for (int mipLevel = 0; mipLevel < nbMipMap; mipLevel++) {
        float roughness = getRoughnessFromMip(mipLevel, nbMipMap);
        int nbSamples = getSampleFromMip(mipLevel, nbMipMap);
        int targetMipMapSize = (int) pow(2, nbMipMap + 1 - mipLevel);
        for (int y = 0; y < targetMipMapSize; y++) {
            for (int x = 0; x < targetMipMapSize; x++) {
                color.set(0, 0, 0);
                getVectorFromCubemapFaceTexCoord(x, y, targetMipMapSize, face, texelVect, EnvMapUtils.FixSeamsMethod.Wrap);
                prefilterEnvMapTexel(sourceWrapper, roughness, texelVect, nbSamples, color);
                outColor.set(Math.max(color.x, 0.0001f), Math.max(color.y, 0.0001f), Math.max(color.z, 0.0001f), 1);
                log.log(Level.FINE, "coords {0},{1}", new Object[] { x, y });
                targetWrapper.setPixel(x, y, face, mipLevel, outColor);
            }
        }
        progress();
    }
    return pem;
}
Also used : ColorRGBA(com.jme3.math.ColorRGBA) TextureCubeMap(com.jme3.texture.TextureCubeMap) Vector3f(com.jme3.math.Vector3f) CubeMapWrapper(com.jme3.environment.util.CubeMapWrapper) EnvMapUtils.getHammersleyPoint(com.jme3.environment.util.EnvMapUtils.getHammersleyPoint)

Example 38 with Format

use of com.jme3.texture.Image.Format in project jmonkeyengine by jMonkeyEngine.

the class Image method write.

public void write(JmeExporter e) throws IOException {
    OutputCapsule capsule = e.getCapsule(this);
    capsule.write(format, "format", Format.RGBA8);
    capsule.write(width, "width", 0);
    capsule.write(height, "height", 0);
    capsule.write(depth, "depth", 0);
    capsule.write(mipMapSizes, "mipMapSizes", null);
    capsule.write(multiSamples, "multiSamples", 1);
    capsule.writeByteBufferArrayList(data, "data", null);
    capsule.write(colorSpace, "colorSpace", null);
}
Also used : OutputCapsule(com.jme3.export.OutputCapsule)

Example 39 with Format

use of com.jme3.texture.Image.Format in project jmonkeyengine by jMonkeyEngine.

the class HDRLoader method load.

public Image load(InputStream in, boolean flipY) throws IOException {
    float gamma = -1f;
    float exposure = -1f;
    float[] colorcorr = new float[] { -1f, -1f, -1f };
    int width = -1, height = -1;
    boolean verifiedFormat = false;
    while (true) {
        String ln = readString(in);
        ln = ln.trim();
        if (ln.startsWith("#") || ln.equals("")) {
            if (ln.equals("#?RADIANCE") || ln.equals("#?RGBE"))
                verifiedFormat = true;
            // comment or empty statement
            continue;
        } else if (ln.startsWith("+") || ln.startsWith("-")) {
            // + or - mark image resolution and start of data
            String[] resData = ln.split("\\s");
            if (resData.length != 4) {
                throw new IOException("Invalid resolution string in HDR file");
            }
            if (!resData[0].equals("-Y") || !resData[2].equals("+X")) {
                logger.warning("Flipping/Rotating attributes ignored!");
            }
            //if (resData[0].endsWith("X")){
            // first width then height
            //    width = Integer.parseInt(resData[1]);
            //    height = Integer.parseInt(resData[3]);
            //}else{
            width = Integer.parseInt(resData[3]);
            height = Integer.parseInt(resData[1]);
            break;
        } else {
            // regular command
            int index = ln.indexOf("=");
            if (index < 1) {
                logger.log(Level.FINE, "Ignored string: {0}", ln);
                continue;
            }
            String var = ln.substring(0, index).trim().toLowerCase();
            String value = ln.substring(index + 1).trim().toLowerCase();
            if (var.equals("format")) {
                if (!value.equals("32-bit_rle_rgbe") && !value.equals("32-bit_rle_xyze")) {
                    throw new IOException("Unsupported format in HDR picture");
                }
            } else if (var.equals("exposure")) {
                exposure = Float.parseFloat(value);
            } else if (var.equals("gamma")) {
                gamma = Float.parseFloat(value);
            } else {
                logger.log(Level.WARNING, "HDR Command ignored: {0}", ln);
            }
        }
    }
    assert width != -1 && height != -1;
    if (!verifiedFormat)
        logger.warning("Unsure if specified image is Radiance HDR");
    // some HDR images can get pretty big
    System.gc();
    // each pixel times size of component times # of components
    Format pixelFormat;
    if (writeRGBE) {
        pixelFormat = Format.RGBA8;
    } else {
        pixelFormat = Format.RGB16F;
    }
    dataStore = BufferUtils.createByteBuffer(width * height * pixelFormat.getBitsPerPixel());
    int bytesPerPixel = pixelFormat.getBitsPerPixel() / 8;
    int scanLineBytes = bytesPerPixel * width;
    for (int y = height - 1; y >= 0; y--) {
        if (flipY)
            dataStore.position(scanLineBytes * y);
        decodeScanline(in, width);
    }
    in.close();
    dataStore.rewind();
    //HDR files color data is actually stored in linear space.
    return new Image(pixelFormat, width, height, dataStore, ColorSpace.Linear);
}
Also used : Format(com.jme3.texture.Image.Format) IOException(java.io.IOException) Image(com.jme3.texture.Image)

Example 40 with Format

use of com.jme3.texture.Image.Format in project jmonkeyengine by jMonkeyEngine.

the class TGALoader method load.

/**
     * <code>loadImage</code> is a manual image loader which is entirely
     * independent of AWT. OUT: RGB888 or RGBA8888 Image object
     * 
     * 
    
     * @param in
     *            InputStream of an uncompressed 24b RGB or 32b RGBA TGA
     * @param flip
     *            Flip the image vertically
     * @return <code>Image</code> object that contains the
     *         image, either as a RGB888 or RGBA8888
     * @throws java.io.IOException
     */
public static Image load(InputStream in, boolean flip) throws IOException {
    boolean flipH = false;
    // open a stream to the file
    DataInputStream dis = new DataInputStream(new BufferedInputStream(in));
    // ---------- Start Reading the TGA header ---------- //
    // length of the image id (1 byte)
    int idLength = dis.readUnsignedByte();
    // Type of color map (if any) included with the image
    // 0 - no color map data is included
    // 1 - a color map is included
    int colorMapType = dis.readUnsignedByte();
    // Type of image being read:
    int imageType = dis.readUnsignedByte();
    // Read Color Map Specification (5 bytes)
    // Index of first color map entry (if we want to use it, uncomment and remove extra read.)
    //        short cMapStart = flipEndian(dis.readShort());
    dis.readShort();
    // number of entries in the color map
    short cMapLength = flipEndian(dis.readShort());
    // number of bits per color map entry
    int cMapDepth = dis.readUnsignedByte();
    // Read Image Specification (10 bytes)
    // horizontal coordinate of lower left corner of image. (if we want to use it, uncomment and remove extra read.)
    //        int xOffset = flipEndian(dis.readShort());
    dis.readShort();
    // vertical coordinate of lower left corner of image. (if we want to use it, uncomment and remove extra read.)
    //        int yOffset = flipEndian(dis.readShort());
    dis.readShort();
    // width of image - in pixels
    int width = flipEndian(dis.readShort());
    // height of image - in pixels
    int height = flipEndian(dis.readShort());
    // bits per pixel in image.
    int pixelDepth = dis.readUnsignedByte();
    int imageDescriptor = dis.readUnsignedByte();
    if (// bit 5 : if 1, flip top/bottom ordering
    (imageDescriptor & 32) != 0) {
        flip = !flip;
    }
    if (// bit 4 : if 1, flip left/right ordering
    (imageDescriptor & 16) != 0) {
        flipH = !flipH;
    }
    // Skip image ID
    if (idLength > 0) {
        dis.skip(idLength);
    }
    ColorMapEntry[] cMapEntries = null;
    if (colorMapType != 0) {
        // read the color map.
        int bytesInColorMap = (cMapDepth * cMapLength) >> 3;
        int bitsPerColor = Math.min(cMapDepth / 3, 8);
        byte[] cMapData = new byte[bytesInColorMap];
        dis.read(cMapData);
        // table if this is declared a color mapped image.
        if (imageType == TYPE_COLORMAPPED || imageType == TYPE_COLORMAPPED_RLE) {
            cMapEntries = new ColorMapEntry[cMapLength];
            int alphaSize = cMapDepth - (3 * bitsPerColor);
            float scalar = 255f / (FastMath.pow(2, bitsPerColor) - 1);
            float alphaScalar = 255f / (FastMath.pow(2, alphaSize) - 1);
            for (int i = 0; i < cMapLength; i++) {
                ColorMapEntry entry = new ColorMapEntry();
                int offset = cMapDepth * i;
                entry.red = (byte) (int) (getBitsAsByte(cMapData, offset, bitsPerColor) * scalar);
                entry.green = (byte) (int) (getBitsAsByte(cMapData, offset + bitsPerColor, bitsPerColor) * scalar);
                entry.blue = (byte) (int) (getBitsAsByte(cMapData, offset + (2 * bitsPerColor), bitsPerColor) * scalar);
                if (alphaSize <= 0) {
                    entry.alpha = (byte) 255;
                } else {
                    entry.alpha = (byte) (int) (getBitsAsByte(cMapData, offset + (3 * bitsPerColor), alphaSize) * alphaScalar);
                }
                cMapEntries[i] = entry;
            }
        }
    }
    // Allocate image data array
    Format format;
    byte[] rawData = null;
    int dl;
    if (pixelDepth == 32) {
        rawData = new byte[width * height * 4];
        dl = 4;
    } else {
        rawData = new byte[width * height * 3];
        dl = 3;
    }
    int rawDataIndex = 0;
    if (imageType == TYPE_TRUECOLOR) {
        byte red = 0;
        byte green = 0;
        byte blue = 0;
        byte alpha = 0;
        // just make a seperate loop for each.
        if (pixelDepth == 16) {
            byte[] data = new byte[2];
            float scalar = 255f / 31f;
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    data[1] = dis.readByte();
                    data[0] = dis.readByte();
                    rawData[rawDataIndex++] = (byte) (int) (getBitsAsByte(data, 1, 5) * scalar);
                    rawData[rawDataIndex++] = (byte) (int) (getBitsAsByte(data, 6, 5) * scalar);
                    rawData[rawDataIndex++] = (byte) (int) (getBitsAsByte(data, 11, 5) * scalar);
                    if (dl == 4) {
                        // create an alpha channel
                        alpha = getBitsAsByte(data, 0, 1);
                        if (alpha == 1) {
                            alpha = (byte) 255;
                        }
                        rawData[rawDataIndex++] = alpha;
                    }
                }
            }
            format = dl == 4 ? Format.RGBA8 : Format.RGB8;
        } else if (pixelDepth == 24) {
            for (int y = 0; y < height; y++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - y) * width * dl;
                } else {
                    rawDataIndex = y * width * dl;
                }
                dis.readFully(rawData, rawDataIndex, width * dl);
            //                    for (int x = 0; x < width; x++) {
            //read scanline
            //                        blue = dis.readByte();
            //                        green = dis.readByte();
            //                        red = dis.readByte();
            //                        rawData[rawDataIndex++] = red;
            //                        rawData[rawDataIndex++] = green;
            //                        rawData[rawDataIndex++] = blue;
            //                    }
            }
            format = Format.BGR8;
        } else if (pixelDepth == 32) {
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    blue = dis.readByte();
                    green = dis.readByte();
                    red = dis.readByte();
                    alpha = dis.readByte();
                    rawData[rawDataIndex++] = red;
                    rawData[rawDataIndex++] = green;
                    rawData[rawDataIndex++] = blue;
                    rawData[rawDataIndex++] = alpha;
                }
            }
            format = Format.RGBA8;
        } else {
            throw new IOException("Unsupported TGA true color depth: " + pixelDepth);
        }
    } else if (imageType == TYPE_TRUECOLOR_RLE) {
        byte red = 0;
        byte green = 0;
        byte blue = 0;
        byte alpha = 0;
        // just make a seperate loop for each.
        if (pixelDepth == 32) {
            for (int i = 0; i <= (height - 1); ++i) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; ++j) {
                    // Get the number of pixels the next chunk covers (either packed or unpacked)
                    int count = dis.readByte();
                    if ((count & 0x80) != 0) {
                        // Its an RLE packed block - use the following 1 pixel for the next <count> pixels
                        count &= 0x07f;
                        j += count;
                        blue = dis.readByte();
                        green = dis.readByte();
                        red = dis.readByte();
                        alpha = dis.readByte();
                        while (count-- >= 0) {
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                            rawData[rawDataIndex++] = alpha;
                        }
                    } else {
                        // Its not RLE packed, but the next <count> pixels are raw.
                        j += count;
                        while (count-- >= 0) {
                            blue = dis.readByte();
                            green = dis.readByte();
                            red = dis.readByte();
                            alpha = dis.readByte();
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                            rawData[rawDataIndex++] = alpha;
                        }
                    }
                }
            }
            format = Format.RGBA8;
        } else if (pixelDepth == 24) {
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; ++j) {
                    // Get the number of pixels the next chunk covers (either packed or unpacked)
                    int count = dis.readByte();
                    if ((count & 0x80) != 0) {
                        // Its an RLE packed block - use the following 1 pixel for the next <count> pixels
                        count &= 0x07f;
                        j += count;
                        blue = dis.readByte();
                        green = dis.readByte();
                        red = dis.readByte();
                        while (count-- >= 0) {
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                        }
                    } else {
                        // Its not RLE packed, but the next <count> pixels are raw.
                        j += count;
                        while (count-- >= 0) {
                            blue = dis.readByte();
                            green = dis.readByte();
                            red = dis.readByte();
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                        }
                    }
                }
            }
            format = Format.RGB8;
        } else if (pixelDepth == 16) {
            byte[] data = new byte[2];
            float scalar = 255f / 31f;
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    // Get the number of pixels the next chunk covers (either packed or unpacked)
                    int count = dis.readByte();
                    if ((count & 0x80) != 0) {
                        // Its an RLE packed block - use the following 1 pixel for the next <count> pixels
                        count &= 0x07f;
                        j += count;
                        data[1] = dis.readByte();
                        data[0] = dis.readByte();
                        blue = (byte) (int) (getBitsAsByte(data, 1, 5) * scalar);
                        green = (byte) (int) (getBitsAsByte(data, 6, 5) * scalar);
                        red = (byte) (int) (getBitsAsByte(data, 11, 5) * scalar);
                        while (count-- >= 0) {
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                        }
                    } else {
                        // Its not RLE packed, but the next <count> pixels are raw.
                        j += count;
                        while (count-- >= 0) {
                            data[1] = dis.readByte();
                            data[0] = dis.readByte();
                            blue = (byte) (int) (getBitsAsByte(data, 1, 5) * scalar);
                            green = (byte) (int) (getBitsAsByte(data, 6, 5) * scalar);
                            red = (byte) (int) (getBitsAsByte(data, 11, 5) * scalar);
                            rawData[rawDataIndex++] = red;
                            rawData[rawDataIndex++] = green;
                            rawData[rawDataIndex++] = blue;
                        }
                    }
                }
            }
            format = Format.RGB8;
        } else {
            throw new IOException("Unsupported TGA true color depth: " + pixelDepth);
        }
    } else if (imageType == TYPE_COLORMAPPED) {
        int bytesPerIndex = pixelDepth / 8;
        if (bytesPerIndex == 1) {
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    int index = dis.readUnsignedByte();
                    if (index >= cMapEntries.length || index < 0) {
                        throw new IOException("TGA: Invalid color map entry referenced: " + index);
                    }
                    ColorMapEntry entry = cMapEntries[index];
                    rawData[rawDataIndex++] = entry.blue;
                    rawData[rawDataIndex++] = entry.green;
                    rawData[rawDataIndex++] = entry.red;
                    if (dl == 4) {
                        rawData[rawDataIndex++] = entry.alpha;
                    }
                }
            }
        } else if (bytesPerIndex == 2) {
            for (int i = 0; i <= (height - 1); i++) {
                if (!flip) {
                    rawDataIndex = (height - 1 - i) * width * dl;
                }
                for (int j = 0; j < width; j++) {
                    int index = flipEndian(dis.readShort());
                    if (index >= cMapEntries.length || index < 0) {
                        throw new IOException("TGA: Invalid color map entry referenced: " + index);
                    }
                    ColorMapEntry entry = cMapEntries[index];
                    rawData[rawDataIndex++] = entry.blue;
                    rawData[rawDataIndex++] = entry.green;
                    rawData[rawDataIndex++] = entry.red;
                    if (dl == 4) {
                        rawData[rawDataIndex++] = entry.alpha;
                    }
                }
            }
        } else {
            throw new IOException("TGA: unknown colormap indexing size used: " + bytesPerIndex);
        }
        format = dl == 4 ? Format.RGBA8 : Format.RGB8;
    } else {
        throw new IOException("Monochrome and RLE colormapped images are not supported");
    }
    in.close();
    // Get a pointer to the image memory
    ByteBuffer scratch = BufferUtils.createByteBuffer(rawData.length);
    scratch.clear();
    scratch.put(rawData);
    scratch.rewind();
    // Create the Image object
    Image textureImage = new Image();
    textureImage.setFormat(format);
    textureImage.setWidth(width);
    textureImage.setHeight(height);
    textureImage.setData(scratch);
    return textureImage;
}
Also used : IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer) Format(com.jme3.texture.Image.Format) BufferedInputStream(java.io.BufferedInputStream)

Aggregations

Image (com.jme3.texture.Image)20 ByteBuffer (java.nio.ByteBuffer)19 Format (com.jme3.texture.Image.Format)13 IOException (java.io.IOException)8 BufferedImage (java.awt.image.BufferedImage)7 ArrayList (java.util.ArrayList)7 TextureCubeMap (com.jme3.texture.TextureCubeMap)6 ColorRGBA (com.jme3.math.ColorRGBA)5 Texture2D (com.jme3.texture.Texture2D)5 TexturePixel (com.jme3.scene.plugins.blender.textures.TexturePixel)4 PixelInputOutput (com.jme3.scene.plugins.blender.textures.io.PixelInputOutput)4 DataInputStream (java.io.DataInputStream)4 AssetNotFoundException (com.jme3.asset.AssetNotFoundException)3 Vector3f (com.jme3.math.Vector3f)3 ShaderNodeVariable (com.jme3.shader.ShaderNodeVariable)3 VariableMapping (com.jme3.shader.VariableMapping)3 FrameBuffer (com.jme3.texture.FrameBuffer)3 LittleEndien (com.jme3.util.LittleEndien)3 InputStream (java.io.InputStream)3 TextureKey (com.jme3.asset.TextureKey)2