Search in sources :

Example 91 with Image

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

the class MaterialLoader method readTextureImage.

private void readTextureImage(String content) {
    // texture image def
    String path = null;
    // find extension
    int extStart = content.lastIndexOf(".");
    for (int i = extStart; i < content.length(); i++) {
        char c = content.charAt(i);
        if (Character.isWhitespace(c)) {
            // extension ends here
            path = content.substring(0, i).trim();
            content = content.substring(i + 1).trim();
            break;
        }
    }
    if (path == null) {
        path = content.trim();
        content = "";
    }
    Scanner lnScan = new Scanner(content);
    String mips = null;
    String type = null;
    if (lnScan.hasNext()) {
        // more params
        type = lnScan.next();
    //            if (!lnScan.hasNext("\n") && lnScan.hasNext()){
    //                mips = lnScan.next();
    //                if (lnScan.hasNext()){
    // even more params..
    // will have to ignore
    //                }
    //            }
    }
    boolean genMips = true;
    boolean cubic = false;
    if (type != null && type.equals("0"))
        genMips = false;
    if (type != null && type.equals("cubic")) {
        cubic = true;
    }
    TextureKey texKey = new TextureKey(folderName + path, false);
    texKey.setGenerateMips(genMips);
    if (cubic) {
        texKey.setTextureTypeHint(Texture.Type.CubeMap);
    }
    try {
        Texture loadedTexture = assetManager.loadTexture(texKey);
        textures[texUnit].setImage(loadedTexture.getImage());
        textures[texUnit].setMinFilter(loadedTexture.getMinFilter());
        textures[texUnit].setMagFilter(loadedTexture.getMagFilter());
        textures[texUnit].setAnisotropicFilter(loadedTexture.getAnisotropicFilter());
        textures[texUnit].setKey(loadedTexture.getKey());
        // XXX: Is this really neccessary?
        textures[texUnit].setWrap(WrapMode.Repeat);
        if (texName != null) {
            textures[texUnit].setName(texName);
            texName = null;
        } else {
            textures[texUnit].setName(texKey.getName());
        }
    } catch (AssetNotFoundException ex) {
        logger.log(Level.WARNING, "Cannot locate {0} for material {1}", new Object[] { texKey, matName });
        textures[texUnit].setImage(PlaceholderAssets.getPlaceholderImage(assetManager));
        textures[texUnit].setKey(texKey);
    }
}
Also used : Scanner(java.util.Scanner) Texture(com.jme3.texture.Texture)

Example 92 with Image

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

the class MaterialLoader method readTextureUnit.

private void readTextureUnit(Statement statement) {
    String[] split = statement.getLine().split(" ", 2);
    // name is optional
    if (split.length == 2) {
        texName = split[1];
    } else {
        texName = null;
    }
    textures[texUnit] = new Texture2D();
    for (Statement texUnitStat : statement.getContents()) {
        readTextureUnitStatement(texUnitStat);
    }
    if (textures[texUnit].getImage() != null) {
        texUnit++;
    } else {
        // no image was loaded, ignore
        textures[texUnit] = null;
    }
}
Also used : Texture2D(com.jme3.texture.Texture2D) Statement(com.jme3.util.blockparser.Statement)

Example 93 with Image

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

the class CombinedTexture method flatten.

/**
	 * This method flattens the texture and creates a single result of Texture2D
	 * type.
	 * 
	 * @param geometry
	 *            the geometry the texture is created for
	 * @param geometriesOMA
	 *            the old memory address of the geometries list that the given
	 *            geometry belongs to (needed for bounding box creation)
	 * @param userDefinedUVCoordinates
	 *            the UV's defined by user (null or zero length table if none
	 *            were defined)
	 * @param blenderContext
	 *            the blender context
	 * @return the name of the user UV coordinates used (null if the UV's were
	 *         generated)
	 */
public String flatten(Geometry geometry, Long geometriesOMA, Map<String, List<Vector2f>> userDefinedUVCoordinates, BlenderContext blenderContext) {
    Mesh mesh = geometry.getMesh();
    Texture previousTexture = null;
    UVCoordinatesType masterUVCoordinatesType = null;
    String masterUserUVSetName = null;
    for (TextureData textureData : textureDatas) {
        // decompress compressed textures (all will be merged into one texture anyway)
        if (textureDatas.size() > 1 && textureData.texture.getImage().getFormat().isCompressed()) {
            textureData.texture.setImage(ImageUtils.decompress(textureData.texture.getImage()));
            textureData.textureBlender = TextureBlenderFactory.alterTextureType(textureData.texture.getImage().getFormat(), textureData.textureBlender);
        }
        if (previousTexture == null) {
            // the first texture will lead the others to its shape
            if (textureData.texture instanceof GeneratedTexture) {
                resultTexture = ((GeneratedTexture) textureData.texture).triangulate(mesh, geometriesOMA, textureData.uvCoordinatesType, blenderContext);
            } else if (textureData.texture instanceof Texture2D) {
                resultTexture = textureData.texture;
                if (textureData.uvCoordinatesType == UVCoordinatesType.TEXCO_UV && userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
                    if (textureData.uvCoordinatesName == null) {
                        // get the first UV available
                        resultUVS = userDefinedUVCoordinates.values().iterator().next();
                    } else {
                        resultUVS = userDefinedUVCoordinates.get(textureData.uvCoordinatesName);
                    }
                    if (resultUVS == null && LOGGER.isLoggable(Level.WARNING)) {
                        LOGGER.warning("The texture " + textureData.texture.getName() + " has assigned non existing UV coordinates group: " + textureData.uvCoordinatesName + ".");
                    }
                    masterUserUVSetName = textureData.uvCoordinatesName;
                } else {
                    TemporalMesh temporalMesh = (TemporalMesh) blenderContext.getLoadedFeature(geometriesOMA, LoadedDataType.TEMPORAL_MESH);
                    resultUVS = UVCoordinatesGenerator.generateUVCoordinatesFor2DTexture(mesh, textureData.uvCoordinatesType, textureData.projectionType, temporalMesh);
                }
            }
            this.blend(resultTexture, textureData.textureBlender, blenderContext);
            previousTexture = resultTexture;
            masterUVCoordinatesType = textureData.uvCoordinatesType;
        } else {
            if (textureData.texture instanceof GeneratedTexture) {
                if (!(resultTexture instanceof TriangulatedTexture)) {
                    resultTexture = new TriangulatedTexture((Texture2D) resultTexture, resultUVS, blenderContext);
                    resultUVS = null;
                    previousTexture = resultTexture;
                }
                TriangulatedTexture triangulatedTexture = ((GeneratedTexture) textureData.texture).triangulate(mesh, geometriesOMA, textureData.uvCoordinatesType, blenderContext);
                triangulatedTexture.castToUVS((TriangulatedTexture) resultTexture, blenderContext);
                triangulatedTexture.blend(textureData.textureBlender, (TriangulatedTexture) resultTexture, blenderContext);
                resultTexture = previousTexture = triangulatedTexture;
            } else if (textureData.texture instanceof Texture2D) {
                if (this.isUVTypesMatch(masterUVCoordinatesType, masterUserUVSetName, textureData.uvCoordinatesType, textureData.uvCoordinatesName) && resultTexture instanceof Texture2D) {
                    this.scale((Texture2D) textureData.texture, resultTexture.getImage().getWidth(), resultTexture.getImage().getHeight());
                    ImageUtils.merge(resultTexture.getImage(), textureData.texture.getImage());
                    previousTexture = resultTexture;
                } else {
                    if (!(resultTexture instanceof TriangulatedTexture)) {
                        resultTexture = new TriangulatedTexture((Texture2D) resultTexture, resultUVS, blenderContext);
                        resultUVS = null;
                    }
                    // first triangulate the current texture
                    List<Vector2f> textureUVS = null;
                    if (textureData.uvCoordinatesType == UVCoordinatesType.TEXCO_UV && userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
                        if (textureData.uvCoordinatesName == null) {
                            // get the first UV available
                            textureUVS = userDefinedUVCoordinates.values().iterator().next();
                        } else {
                            textureUVS = userDefinedUVCoordinates.get(textureData.uvCoordinatesName);
                        }
                    } else {
                        TemporalMesh geometries = (TemporalMesh) blenderContext.getLoadedFeature(geometriesOMA, LoadedDataType.TEMPORAL_MESH);
                        textureUVS = UVCoordinatesGenerator.generateUVCoordinatesFor2DTexture(mesh, textureData.uvCoordinatesType, textureData.projectionType, geometries);
                    }
                    TriangulatedTexture triangulatedTexture = new TriangulatedTexture((Texture2D) textureData.texture, textureUVS, blenderContext);
                    // then move the texture to different UV's
                    triangulatedTexture.castToUVS((TriangulatedTexture) resultTexture, blenderContext);
                    // merge triangulated textures
                    for (int i = 0; i < ((TriangulatedTexture) resultTexture).getFaceTextureCount(); ++i) {
                        ImageUtils.merge(((TriangulatedTexture) resultTexture).getFaceTextureElement(i).image, triangulatedTexture.getFaceTextureElement(i).image);
                    }
                }
            }
        }
    }
    if (resultTexture instanceof TriangulatedTexture) {
        if (mappingType == MaterialContext.MTEX_NOR) {
            for (int i = 0; i < ((TriangulatedTexture) resultTexture).getFaceTextureCount(); ++i) {
                TriangleTextureElement triangleTextureElement = ((TriangulatedTexture) resultTexture).getFaceTextureElement(i);
                // TODO: get proper strength factor
                triangleTextureElement.image = ImageUtils.convertToNormalMapTexture(triangleTextureElement.image, 1);
            }
        }
        resultUVS = ((TriangulatedTexture) resultTexture).getResultUVS();
        resultTexture = ((TriangulatedTexture) resultTexture).getResultTexture();
        masterUserUVSetName = null;
    }
    // setting additional data
    resultTexture.setWrap(WrapMode.Repeat);
    // the filters are required if generated textures are used because
    // otherwise ugly lines appear between the mesh faces
    resultTexture.setMagFilter(MagFilter.Nearest);
    resultTexture.setMinFilter(MinFilter.NearestNoMipMaps);
    return masterUserUVSetName;
}
Also used : TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh) Texture2D(com.jme3.texture.Texture2D) TriangleTextureElement(com.jme3.scene.plugins.blender.textures.TriangulatedTexture.TriangleTextureElement) UVCoordinatesType(com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.UVCoordinatesType) TemporalMesh(com.jme3.scene.plugins.blender.meshes.TemporalMesh) Mesh(com.jme3.scene.Mesh) ArrayList(java.util.ArrayList) List(java.util.List) Texture(com.jme3.texture.Texture)

Example 94 with Image

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

the class ImageLoader method loadImage.

/**
     * This method loads the image from the blender file itself. It tries each loader to load the image.
     * 
     * @param inputStream
     *            blender input stream
     * @param startPosition
     *            position in the stream where the image data starts
     * @param flipY
     *            if the image should be flipped (does not work with DirectX image)
     * @return loaded image or null if it could not be loaded
     */
public Image loadImage(BlenderInputStream inputStream, int startPosition, boolean flipY) {
    // loading using AWT loader
    inputStream.setPosition(startPosition);
    Image result = this.loadImage(inputStream, ImageType.AWT, flipY);
    // loading using TGA loader
    if (result == null) {
        inputStream.setPosition(startPosition);
        result = this.loadImage(inputStream, ImageType.TGA, flipY);
    }
    // loading using DDS loader
    if (result == null) {
        inputStream.setPosition(startPosition);
        result = this.loadImage(inputStream, ImageType.DDS, flipY);
    }
    if (result == null) {
        LOGGER.warning("Image could not be loaded by none of available loaders!");
    }
    return result;
}
Also used : Image(com.jme3.texture.Image)

Example 95 with Image

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

the class ImageUtils method decompress.

/**
     * This method decompresses the given image. If the given image is already
     * decompressed nothing happens and it is simply returned.
     * 
     * @param image
     *            the image to decompress
     * @return the decompressed image
     */
public static Image decompress(Image image) {
    Format format = image.getFormat();
    int depth = image.getDepth();
    if (depth == 0) {
        depth = 1;
    }
    ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);
    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();
        }
        // this should always be constant for each mipmap
        float widthToHeightRatio = image.getWidth() / image.getHeight();
        List<DDSTexelData> texelDataList = new ArrayList<DDSTexelData>(sizes.length);
        int maxPosition = 0, resultSize = 0;
        for (int sizeIndex = 0; sizeIndex < sizes.length; ++sizeIndex) {
            maxPosition += sizes[sizeIndex];
            DDSTexelData texelData = new DDSTexelData(sizes[sizeIndex], widthToHeightRatio, format);
            texelDataList.add(texelData);
            switch(format) {
                // BC1
                case DXT1:
                case DXT1A:
                    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);
                        int col1 = RGB565.RGB565_to_ARGB8(c1);
                        colors[0].fromARGB8(col0);
                        colors[1].fromARGB8(col1);
                        if (col0 > col1) {
                            // creating color2 = 2/3color0 + 1/3color1
                            colors[2].fromPixel(colors[0]);
                            colors[2].mult(2);
                            colors[2].add(colors[1]);
                            colors[2].divide(3);
                            // creating color3 = 1/3color0 + 2/3color1;
                            colors[3].fromPixel(colors[1]);
                            colors[3].mult(2);
                            colors[3].add(colors[0]);
                            colors[3].divide(3);
                        } else {
                            // creating color2 = 1/2color0 + 1/2color1
                            colors[2].fromPixel(colors[0]);
                            colors[2].add(colors[1]);
                            colors[2].mult(0.5f);
                            colors[3].fromARGB8(0);
                        }
                        // 4-byte table with color indexes in decompressed table
                        int indexes = data.getInt();
                        texelData.add(colors, indexes);
                    }
                    break;
                case // BC2
                DXT3:
                    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;
                        for (int i = 0; i < 16; ++i) {
                            alphasIndex |= i << i * 4;
                            byte a = (byte) ((alpha >> i * 4 & 0x0F) << 4);
                            alphas[i] = a >= 0 ? a / 255.0f : 1.0f - ~a / 255.0f;
                        }
                        short c0 = data.getShort();
                        short c1 = data.getShort();
                        int col0 = RGB565.RGB565_to_ARGB8(c0);
                        int col1 = RGB565.RGB565_to_ARGB8(c1);
                        colors[0].fromARGB8(col0);
                        colors[1].fromARGB8(col1);
                        // creating color2 = 2/3color0 + 1/3color1
                        colors[2].fromPixel(colors[0]);
                        colors[2].mult(2);
                        colors[2].add(colors[1]);
                        colors[2].divide(3);
                        // creating color3 = 1/3color0 + 2/3color1;
                        colors[3].fromPixel(colors[1]);
                        colors[3].mult(2);
                        colors[3].add(colors[0]);
                        colors[3].divide(3);
                        // 4-byte table with color indexes in decompressed table
                        int indexes = data.getInt();
                        texelData.add(colors, indexes, alphas, alphasIndex);
                    }
                    break;
                case // BC3
                DXT5:
                    float[] alphas = new float[8];
                    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;
                        //the casts to long must be done here because otherwise 32-bit integers would be shifetd by 32 and 40 bits which would result in improper values
                        long alphaIndices = data.get() | (long) data.get() << 8 | (long) data.get() << 16 | (long) data.get() << 24 | (long) data.get() << 32 | (long) data.get() << 40;
                        if (alphas[0] > alphas[1]) {
                            // 6 interpolated alpha values.
                            alphas[2] = (6 * alphas[0] + alphas[1]) / 7;
                            alphas[3] = (5 * alphas[0] + 2 * alphas[1]) / 7;
                            alphas[4] = (4 * alphas[0] + 3 * alphas[1]) / 7;
                            alphas[5] = (3 * alphas[0] + 4 * alphas[1]) / 7;
                            alphas[6] = (2 * alphas[0] + 5 * alphas[1]) / 7;
                            alphas[7] = (alphas[0] + 6 * alphas[1]) / 7;
                        } else {
                            alphas[2] = (4 * alphas[0] + alphas[1]) * 0.2f;
                            alphas[3] = (3 * alphas[0] + 2 * alphas[1]) * 0.2f;
                            alphas[4] = (2 * alphas[0] + 3 * alphas[1]) * 0.2f;
                            alphas[5] = (alphas[0] + 4 * alphas[1]) * 0.2f;
                            alphas[6] = 0;
                            alphas[7] = 1;
                        }
                        short c0 = data.getShort();
                        short c1 = data.getShort();
                        int col0 = RGB565.RGB565_to_ARGB8(c0);
                        int col1 = RGB565.RGB565_to_ARGB8(c1);
                        colors[0].fromARGB8(col0);
                        colors[1].fromARGB8(col1);
                        // creating color2 = 2/3color0 + 1/3color1
                        colors[2].fromPixel(colors[0]);
                        colors[2].mult(2);
                        colors[2].add(colors[1]);
                        colors[2].divide(3);
                        // creating color3 = 1/3color0 + 2/3color1;
                        colors[3].fromPixel(colors[1]);
                        colors[3].mult(2);
                        colors[3].add(colors[0]);
                        colors[3].divide(3);
                        // 4-byte table with color indexes in decompressed table
                        int indexes = data.getInt();
                        texelData.add(colors, indexes, alphas, alphaIndices);
                    }
                    break;
                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 (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, com.jme3.texture.image.ColorSpace.Linear) : new Image(Format.RGBA8, image.getWidth(), image.getHeight(), dataArray.get(0), com.jme3.texture.image.ColorSpace.Linear);
    if (newMipmapSizes != null) {
        result.setMipMapSizes(newMipmapSizes);
    }
    return result;
}
Also used : ArrayList(java.util.ArrayList) BufferedImage(java.awt.image.BufferedImage) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer) Format(com.jme3.texture.Image.Format)

Aggregations

Image (com.jme3.texture.Image)68 ByteBuffer (java.nio.ByteBuffer)38 Texture (com.jme3.texture.Texture)27 Texture2D (com.jme3.texture.Texture2D)19 ArrayList (java.util.ArrayList)19 Material (com.jme3.material.Material)18 TextureKey (com.jme3.asset.TextureKey)17 Vector3f (com.jme3.math.Vector3f)17 Format (com.jme3.texture.Image.Format)15 TextureCubeMap (com.jme3.texture.TextureCubeMap)14 ColorRGBA (com.jme3.math.ColorRGBA)13 PixelInputOutput (com.jme3.scene.plugins.blender.textures.io.PixelInputOutput)12 BufferedImage (java.awt.image.BufferedImage)12 Geometry (com.jme3.scene.Geometry)10 InputStream (java.io.InputStream)10 IOException (java.io.IOException)8 TerrainLodControl (com.jme3.terrain.geomipmap.TerrainLodControl)7 TerrainQuad (com.jme3.terrain.geomipmap.TerrainQuad)7 DistanceLodCalculator (com.jme3.terrain.geomipmap.lodcalc.DistanceLodCalculator)7 AbstractHeightMap (com.jme3.terrain.heightmap.AbstractHeightMap)7