Search in sources :

Example 1 with Format

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

the class GeometryBatchFactory method mergeGeometries.

/**
     * Merges all geometries in the collection into
     * the output mesh. Creates a new material using the TextureAtlas.
     * 
     * @param geometries
     * @param outMesh
     */
public static void mergeGeometries(Collection<Geometry> geometries, Mesh outMesh) {
    int[] compsForBuf = new int[VertexBuffer.Type.values().length];
    Format[] formatForBuf = new Format[compsForBuf.length];
    boolean[] normForBuf = new boolean[VertexBuffer.Type.values().length];
    int totalVerts = 0;
    int totalTris = 0;
    int totalLodLevels = 0;
    int maxWeights = -1;
    Mode mode = null;
    for (Geometry geom : geometries) {
        totalVerts += geom.getVertexCount();
        totalTris += geom.getTriangleCount();
        totalLodLevels = Math.min(totalLodLevels, geom.getMesh().getNumLodLevels());
        Mode listMode;
        int components;
        switch(geom.getMesh().getMode()) {
            case Points:
                listMode = Mode.Points;
                components = 0;
                break;
            case LineLoop:
            case LineStrip:
            case Lines:
                listMode = Mode.Lines;
                components = 2;
                break;
            case TriangleFan:
            case TriangleStrip:
            case Triangles:
                listMode = Mode.Triangles;
                components = 3;
                break;
            default:
                throw new UnsupportedOperationException();
        }
        for (VertexBuffer vb : geom.getMesh().getBufferList().getArray()) {
            int currentCompsForBuf = compsForBuf[vb.getBufferType().ordinal()];
            if (vb.getBufferType() != Type.Index && currentCompsForBuf != 0 && currentCompsForBuf != vb.getNumComponents()) {
                throw new UnsupportedOperationException("The geometry " + geom + " buffer " + vb.getBufferType() + " has different number of components than the rest of the meshes " + "(this: " + vb.getNumComponents() + ", expected: " + currentCompsForBuf + ")");
            }
            compsForBuf[vb.getBufferType().ordinal()] = vb.getNumComponents();
            formatForBuf[vb.getBufferType().ordinal()] = vb.getFormat();
            normForBuf[vb.getBufferType().ordinal()] = vb.isNormalized();
        }
        maxWeights = Math.max(maxWeights, geom.getMesh().getMaxNumWeights());
        if (mode != null && mode != listMode) {
            throw new UnsupportedOperationException("Cannot combine different" + " primitive types: " + mode + " != " + listMode);
        }
        mode = listMode;
        compsForBuf[Type.Index.ordinal()] = components;
    }
    outMesh.setMaxNumWeights(maxWeights);
    outMesh.setMode(mode);
    if (totalVerts >= 65536) {
        // make sure we create an UnsignedInt buffer so
        // we can fit all of the meshes
        formatForBuf[Type.Index.ordinal()] = Format.UnsignedInt;
    } else {
        formatForBuf[Type.Index.ordinal()] = Format.UnsignedShort;
    }
    // generate output buffers based on retrieved info
    for (int i = 0; i < compsForBuf.length; i++) {
        if (compsForBuf[i] == 0) {
            continue;
        }
        Buffer data;
        if (i == Type.Index.ordinal()) {
            data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalTris);
        } else {
            data = VertexBuffer.createBuffer(formatForBuf[i], compsForBuf[i], totalVerts);
        }
        VertexBuffer vb = new VertexBuffer(Type.values()[i]);
        vb.setupData(Usage.Static, compsForBuf[i], formatForBuf[i], data);
        vb.setNormalized(normForBuf[i]);
        outMesh.setBuffer(vb);
    }
    int globalVertIndex = 0;
    int globalTriIndex = 0;
    for (Geometry geom : geometries) {
        Mesh inMesh = geom.getMesh();
        geom.computeWorldMatrix();
        Matrix4f worldMatrix = geom.getWorldMatrix();
        int geomVertCount = inMesh.getVertexCount();
        int geomTriCount = inMesh.getTriangleCount();
        for (int bufType = 0; bufType < compsForBuf.length; bufType++) {
            VertexBuffer inBuf = inMesh.getBuffer(Type.values()[bufType]);
            VertexBuffer outBuf = outMesh.getBuffer(Type.values()[bufType]);
            if (inBuf == null || outBuf == null) {
                continue;
            }
            if (Type.Index.ordinal() == bufType) {
                int components = compsForBuf[bufType];
                IndexBuffer inIdx = inMesh.getIndicesAsList();
                IndexBuffer outIdx = outMesh.getIndexBuffer();
                for (int tri = 0; tri < geomTriCount; tri++) {
                    for (int comp = 0; comp < components; comp++) {
                        int idx = inIdx.get(tri * components + comp) + globalVertIndex;
                        outIdx.put((globalTriIndex + tri) * components + comp, idx);
                    }
                }
            } else if (Type.Position.ordinal() == bufType) {
                FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
                FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                doTransformVerts(inPos, globalVertIndex, outPos, worldMatrix);
            } else if (Type.Normal.ordinal() == bufType) {
                FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
                FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                doTransformNorms(inPos, globalVertIndex, outPos, worldMatrix);
            } else if (Type.Tangent.ordinal() == bufType) {
                FloatBuffer inPos = (FloatBuffer) inBuf.getDataReadOnly();
                FloatBuffer outPos = (FloatBuffer) outBuf.getData();
                int components = inBuf.getNumComponents();
                doTransformTangents(inPos, globalVertIndex, components, outPos, worldMatrix);
            } else {
                inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount);
            }
        }
        globalVertIndex += geomVertCount;
        globalTriIndex += geomTriCount;
    }
}
Also used : FloatBuffer(java.nio.FloatBuffer) ShortBuffer(java.nio.ShortBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IntBuffer(java.nio.IntBuffer) Buffer(java.nio.Buffer) Mode(com.jme3.scene.Mesh.Mode) FloatBuffer(java.nio.FloatBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) Matrix4f(com.jme3.math.Matrix4f) Format(com.jme3.scene.VertexBuffer.Format)

Example 2 with Format

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

the class TextureAtlas method convertImageToAwt.

private Image convertImageToAwt(Image source) {
    //use awt dependent classes without actual dependency via reflection
    try {
        Class clazz = Class.forName("jme3tools.converters.ImageToAwt");
        if (clazz == null) {
            return null;
        }
        Image newImage = new Image(format, source.getWidth(), source.getHeight(), BufferUtils.createByteBuffer(source.getWidth() * source.getHeight() * 4), null, ColorSpace.Linear);
        clazz.getMethod("convert", Image.class, Image.class).invoke(clazz.newInstance(), source, newImage);
        return newImage;
    } catch (InstantiationException ex) {
    } catch (IllegalAccessException ex) {
    } catch (IllegalArgumentException ex) {
    } catch (InvocationTargetException ex) {
    } catch (NoSuchMethodException ex) {
    } catch (SecurityException ex) {
    } catch (ClassNotFoundException ex) {
    }
    return null;
}
Also used : Image(com.jme3.texture.Image) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 3 with Format

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

the class TextureAtlas method getAtlasTexture.

/**
     * Creates a new atlas texture for the given map name.
     * @param mapName
     * @return the atlas texture
     */
public Texture getAtlasTexture(String mapName) {
    if (images == null) {
        return null;
    }
    byte[] image = images.get(mapName);
    if (image != null) {
        //TODO check if color space shouldn't be sRGB
        Texture2D tex = new Texture2D(new Image(format, atlasWidth, atlasHeight, BufferUtils.createByteBuffer(image), null, ColorSpace.Linear));
        tex.setMagFilter(Texture.MagFilter.Bilinear);
        tex.setMinFilter(Texture.MinFilter.BilinearNearestMipMap);
        tex.setWrap(Texture.WrapMode.EdgeClamp);
        return tex;
    }
    return null;
}
Also used : Texture2D(com.jme3.texture.Texture2D) Image(com.jme3.texture.Image)

Example 4 with Format

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

the class TextureAtlas method drawImage.

private void drawImage(Image source, int x, int y, String mapName) {
    if (images == null) {
        images = new HashMap<String, byte[]>();
    }
    byte[] image = images.get(mapName);
    //Texture Atlas should linearize the data if the source image isSRGB        
    if (image == null) {
        image = new byte[atlasWidth * atlasHeight * 4];
        images.put(mapName, image);
    }
    //TODO: all buffers?
    ByteBuffer sourceData = source.getData(0);
    int height = source.getHeight();
    int width = source.getWidth();
    Image newImage = null;
    for (int yPos = 0; yPos < height; yPos++) {
        for (int xPos = 0; xPos < width; xPos++) {
            int i = ((xPos + x) + (yPos + y) * atlasWidth) * 4;
            if (source.getFormat() == Format.ABGR8) {
                int j = (xPos + yPos * width) * 4;
                //a
                image[i] = sourceData.get(j);
                //b
                image[i + 1] = sourceData.get(j + 1);
                //g
                image[i + 2] = sourceData.get(j + 2);
                //r
                image[i + 3] = sourceData.get(j + 3);
            } else if (source.getFormat() == Format.BGR8) {
                int j = (xPos + yPos * width) * 3;
                //a
                image[i] = 1;
                //b
                image[i + 1] = sourceData.get(j);
                //g
                image[i + 2] = sourceData.get(j + 1);
                //r
                image[i + 3] = sourceData.get(j + 2);
            } else if (source.getFormat() == Format.RGB8) {
                int j = (xPos + yPos * width) * 3;
                //a
                image[i] = 1;
                //b
                image[i + 1] = sourceData.get(j + 2);
                //g
                image[i + 2] = sourceData.get(j + 1);
                //r
                image[i + 3] = sourceData.get(j);
            } else if (source.getFormat() == Format.RGBA8) {
                int j = (xPos + yPos * width) * 4;
                //a
                image[i] = sourceData.get(j + 3);
                //b
                image[i + 1] = sourceData.get(j + 2);
                //g
                image[i + 2] = sourceData.get(j + 1);
                //r
                image[i + 3] = sourceData.get(j);
            } else if (source.getFormat() == Format.Luminance8) {
                int j = (xPos + yPos * width) * 1;
                //a
                image[i] = 1;
                //b
                image[i + 1] = sourceData.get(j);
                //g
                image[i + 2] = sourceData.get(j);
                //r
                image[i + 3] = sourceData.get(j);
            } else if (source.getFormat() == Format.Luminance8Alpha8) {
                int j = (xPos + yPos * width) * 2;
                //a
                image[i] = sourceData.get(j + 1);
                //b
                image[i + 1] = sourceData.get(j);
                //g
                image[i + 2] = sourceData.get(j);
                //r
                image[i + 3] = sourceData.get(j);
            } else {
                //ImageToAwt conversion
                if (newImage == null) {
                    newImage = convertImageToAwt(source);
                    if (newImage != null) {
                        source = newImage;
                        sourceData = source.getData(0);
                        int j = (xPos + yPos * width) * 4;
                        //a
                        image[i] = sourceData.get(j);
                        //b
                        image[i + 1] = sourceData.get(j + 1);
                        //g
                        image[i + 2] = sourceData.get(j + 2);
                        //r
                        image[i + 3] = sourceData.get(j + 3);
                    } else {
                        throw new UnsupportedOperationException("Cannot draw or convert textures with format " + source.getFormat());
                    }
                } else {
                    throw new UnsupportedOperationException("Cannot draw textures with format " + source.getFormat());
                }
            }
        }
    }
}
Also used : Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer)

Example 5 with Format

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

the class PFMLoader method load.

private Image load(InputStream in, boolean needYFlip) throws IOException {
    Format format = null;
    String fmtStr = readString(in);
    if (fmtStr.equals("PF")) {
        format = Format.RGB32F;
    } else if (fmtStr.equals("Pf")) {
        format = Format.Luminance32F;
    } else {
        throw new IOException("File is not PFM format");
    }
    String sizeStr = readString(in);
    int spaceIdx = sizeStr.indexOf(" ");
    if (spaceIdx <= 0 || spaceIdx >= sizeStr.length() - 1)
        throw new IOException("Invalid size syntax in PFM file");
    int width = Integer.parseInt(sizeStr.substring(0, spaceIdx));
    int height = Integer.parseInt(sizeStr.substring(spaceIdx + 1));
    if (width <= 0 || height <= 0)
        throw new IOException("Invalid size specified in PFM file");
    String scaleStr = readString(in);
    float scale = Float.parseFloat(scaleStr);
    ByteOrder order = scale < 0 ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN;
    boolean needEndienFlip = order != ByteOrder.nativeOrder();
    // make sure all unneccessary stuff gets deleted from heap
    // before allocating large amount of memory
    System.gc();
    int bytesPerPixel = format.getBitsPerPixel() / 8;
    int scanLineBytes = bytesPerPixel * width;
    ByteBuffer imageData = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
    byte[] scanline = new byte[width * bytesPerPixel];
    for (int y = height - 1; y >= 0; y--) {
        if (!needYFlip)
            imageData.position(scanLineBytes * y);
        int read = 0;
        int off = 0;
        do {
            read = in.read(scanline, off, scanline.length - off);
            off += read;
        } while (read > 0);
        if (needEndienFlip) {
            flipScanline(scanline);
        }
        imageData.put(scanline);
    }
    imageData.rewind();
    return new Image(format, width, height, imageData, null, ColorSpace.Linear);
}
Also used : Format(com.jme3.texture.Image.Format) IOException(java.io.IOException) ByteOrder(java.nio.ByteOrder) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer)

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