Search in sources :

Example 1 with GLImageFormat

use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.

the class KTXLoader method getImageFormat.

/**
     * returns the JME image format from gl formats and types.
     * @param glFormat
     * @param glInternalFormat
     * @param glType
     * @return 
     */
private Image.Format getImageFormat(int glFormat, int glInternalFormat, int glType) {
    EnumSet<Caps> caps = EnumSet.allOf(Caps.class);
    GLImageFormat[][] formats = GLImageFormats.getFormatsForCaps(caps);
    for (GLImageFormat[] format : formats) {
        for (int j = 0; j < format.length; j++) {
            GLImageFormat glImgFormat = format[j];
            if (glImgFormat != null) {
                if (glImgFormat.format == glFormat && glImgFormat.dataType == glType) {
                    if (glFormat == glInternalFormat || glImgFormat.internalFormat == glInternalFormat) {
                        return Image.Format.values()[j];
                    }
                }
            }
        }
    }
    return null;
}
Also used : GLImageFormat(com.jme3.renderer.opengl.GLImageFormat) Caps(com.jme3.renderer.Caps)

Example 2 with GLImageFormat

use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.

the class TextureUtil method uploadTexture.

public void uploadTexture(Image image, int target, int index, boolean linearizeSrgb) {
    boolean getSrgbFormat = image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
    Image.Format jmeFormat = image.getFormat();
    GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);
    ByteBuffer data = null;
    int sliceCount = 1;
    if (index >= 0) {
        data = image.getData(index);
    }
    if (image.getData() != null && image.getData().size() > 0) {
        sliceCount = image.getData().size();
    }
    int width = image.getWidth();
    int height = image.getHeight();
    int depth = image.getDepth();
    int[] mipSizes = image.getMipMapSizes();
    int pos = 0;
    // TODO: Remove unneccessary allocation
    if (mipSizes == null) {
        if (data != null) {
            mipSizes = new int[] { data.capacity() };
        } else {
            mipSizes = new int[] { width * height * jmeFormat.getBitsPerPixel() / 8 };
        }
    }
    int samples = image.getMultiSamples();
    // For OGL3 core: setup texture swizzle.
    if (oglFormat.swizzleRequired) {
        setupTextureSwizzle(target, jmeFormat);
    }
    for (int i = 0; i < mipSizes.length; i++) {
        int mipWidth = Math.max(1, width >> i);
        int mipHeight = Math.max(1, height >> i);
        int mipDepth = Math.max(1, depth >> i);
        if (data != null) {
            data.position(pos);
            data.limit(pos + mipSizes[i]);
        }
        uploadTextureLevel(oglFormat, target, i, index, sliceCount, mipWidth, mipHeight, mipDepth, samples, data);
        pos += mipSizes[i];
    }
}
Also used : Format(com.jme3.texture.Image.Format) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer)

Example 3 with GLImageFormat

use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.

the class TextureUtil method uploadSubTexture.

public void uploadSubTexture(Image image, int target, int index, int x, int y, boolean linearizeSrgb) {
    if (target != GL.GL_TEXTURE_2D || image.getDepth() > 1) {
        throw new UnsupportedOperationException("Updating non-2D texture is not supported");
    }
    if (image.getMipMapSizes() != null) {
        throw new UnsupportedOperationException("Updating mip-mappped images is not supported");
    }
    if (image.getMultiSamples() > 1) {
        throw new UnsupportedOperationException("Updating multisampled images is not supported");
    }
    Image.Format jmeFormat = image.getFormat();
    if (jmeFormat.isCompressed()) {
        throw new UnsupportedOperationException("Updating compressed images is not supported");
    } else if (jmeFormat.isDepthFormat()) {
        throw new UnsupportedOperationException("Updating depth images is not supported");
    }
    boolean getSrgbFormat = image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb;
    GLImageFormat oglFormat = getImageFormatWithError(jmeFormat, getSrgbFormat);
    ByteBuffer data = null;
    if (index >= 0) {
        data = image.getData(index);
    }
    if (data == null) {
        throw new IndexOutOfBoundsException("The image index " + index + " is not valid for the given image");
    }
    data.position(0);
    data.limit(data.capacity());
    gl.glTexSubImage2D(target, 0, x, y, image.getWidth(), image.getHeight(), oglFormat.format, oglFormat.dataType, data);
}
Also used : Format(com.jme3.texture.Image.Format) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer)

Example 4 with GLImageFormat

use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.

the class TextureUtil method uploadSubTexture.

/**
     * Update the texture currently bound to target at with data from the given Image at position x and y. The parameter
     * index is used as the zoffset in case a 3d texture or texture 2d array is being updated.
     *
     * @param image Image with the source data (this data will be put into the texture)
     * @param target the target texture
     * @param index the mipmap level to update
     * @param x the x position where to put the image in the texture
     * @param y the y position where to put the image in the texture
     */
public static void uploadSubTexture(Image image, int target, int index, int x, int y, boolean linearizeSrgb) {
    GL gl = GLContext.getCurrentGL();
    Image.Format fmt = image.getFormat();
    GLImageFormat glFmt = getImageFormatWithError(fmt, image.getColorSpace() == ColorSpace.sRGB && linearizeSrgb);
    ByteBuffer data = null;
    if (index >= 0 && image.getData() != null && image.getData().size() > 0) {
        data = image.getData(index);
    }
    int width = image.getWidth();
    int height = image.getHeight();
    int depth = image.getDepth();
    if (data != null) {
        gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);
    }
    int[] mipSizes = image.getMipMapSizes();
    int pos = 0;
    // TODO: Remove unneccessary allocation
    if (mipSizes == null) {
        if (data != null) {
            mipSizes = new int[] { data.capacity() };
        } else {
            mipSizes = new int[] { width * height * fmt.getBitsPerPixel() / 8 };
        }
    }
    int samples = image.getMultiSamples();
    for (int i = 0; i < mipSizes.length; i++) {
        int mipWidth = Math.max(1, width >> i);
        int mipHeight = Math.max(1, height >> i);
        int mipDepth = Math.max(1, depth >> i);
        if (data != null) {
            data.position(pos);
            data.limit(pos + mipSizes[i]);
        }
        // to remove the cumbersome if/then/else stuff below we'll update the pos right here and use continue after each
        // gl*Image call in an attempt to unclutter things a bit
        pos += mipSizes[i];
        int glFmtInternal = glFmt.internalFormat;
        int glFmtFormat = glFmt.format;
        int glFmtDataType = glFmt.dataType;
        if (glFmt.compressed && data != null) {
            if (target == GL2ES2.GL_TEXTURE_3D) {
                gl.getGL2ES2().glCompressedTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtInternal, data.limit(), data);
                continue;
            }
            // all other targets use 2D: array, cubemap, 2d
            gl.getGL2ES2().glCompressedTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtInternal, data.limit(), data);
            continue;
        }
        if (target == GL2ES2.GL_TEXTURE_3D) {
            gl.getGL2ES2().glTexSubImage3D(target, i, x, y, index, mipWidth, mipHeight, mipDepth, glFmtFormat, glFmtDataType, data);
            continue;
        }
        if (samples > 1) {
            throw new IllegalStateException("Cannot update multisample textures");
        }
        gl.glTexSubImage2D(target, i, x, y, mipWidth, mipHeight, glFmtFormat, glFmtDataType, data);
        continue;
    }
}
Also used : GL(com.jogamp.opengl.GL) Format(com.jme3.texture.Image.Format) Image(com.jme3.texture.Image) ByteBuffer(java.nio.ByteBuffer)

Example 5 with GLImageFormat

use of com.jme3.renderer.opengl.GLImageFormat in project jmonkeyengine by jMonkeyEngine.

the class KTXWriter method write.

/**
     * Writes an image with the given params
     * 
     * textureType, allows one to write textureArrays, Texture3D, and TextureCubeMaps.
     * Texture2D will write a 2D image.
     * Note that the fileName should contain the extension (.ktx sounds like a wise choice)
     * @param image the image to write
     * @param textureType the texture type
     * @param fileName the name of the file to write
     */
public void write(Image image, Class<? extends Texture> textureType, String fileName) {
    FileOutputStream outs = null;
    try {
        File file = new File(filePath + "/" + fileName);
        outs = new FileOutputStream(file);
        DataOutput out = new DataOutputStream(outs);
        //fileID
        out.write(fileIdentifier);
        //endianness
        out.writeInt(0x04030201);
        GLImageFormat format = getGlFormat(image.getFormat());
        //glType
        out.writeInt(format.dataType);
        //glTypeSize
        out.writeInt(1);
        //glFormat
        out.writeInt(format.format);
        //glInernalFormat
        out.writeInt(format.internalFormat);
        //glBaseInternalFormat
        out.writeInt(format.format);
        //pixelWidth
        out.writeInt(image.getWidth());
        //pixelHeight
        out.writeInt(image.getHeight());
        int pixelDepth = 1;
        int numberOfArrayElements = 1;
        int numberOfFaces = 1;
        if (image.getDepth() > 1) {
            //pixelDepth
            if (textureType == Texture3D.class) {
                pixelDepth = image.getDepth();
            }
        }
        if (image.getData().size() > 1) {
            //numberOfArrayElements
            if (textureType == TextureArray.class) {
                numberOfArrayElements = image.getData().size();
            }
            //numberOfFaces                
            if (textureType == TextureCubeMap.class) {
                numberOfFaces = image.getData().size();
            }
        }
        out.writeInt(pixelDepth);
        out.writeInt(numberOfArrayElements);
        out.writeInt(numberOfFaces);
        int numberOfMipmapLevels = 1;
        //numberOfMipmapLevels
        if (image.hasMipmaps()) {
            numberOfMipmapLevels = image.getMipMapSizes().length;
        }
        out.writeInt(numberOfMipmapLevels);
        //bytesOfKeyValueData
        String keyValues = "KTXorientation\0S=r,T=u\0";
        int bytesOfKeyValueData = keyValues.length() + 4;
        int padding = 3 - ((bytesOfKeyValueData + 3) % 4);
        bytesOfKeyValueData += padding;
        out.writeInt(bytesOfKeyValueData);
        //keyAndValueByteSize
        out.writeInt(bytesOfKeyValueData - 4 - padding);
        //values
        out.writeBytes(keyValues);
        pad(padding, out);
        int offset = 0;
        //iterate over data
        for (int mipLevel = 0; mipLevel < numberOfMipmapLevels; mipLevel++) {
            int width = Math.max(1, image.getWidth() >> mipLevel);
            int height = Math.max(1, image.getHeight() >> mipLevel);
            int imageSize;
            if (image.hasMipmaps()) {
                imageSize = image.getMipMapSizes()[mipLevel];
            } else {
                imageSize = width * height * image.getFormat().getBitsPerPixel() / 8;
            }
            out.writeInt(imageSize);
            for (int arrayElem = 0; arrayElem < numberOfArrayElements; arrayElem++) {
                for (int face = 0; face < numberOfFaces; face++) {
                    int nbPixelWritten = 0;
                    for (int depth = 0; depth < pixelDepth; depth++) {
                        ByteBuffer byteBuffer = image.getData(getSlice(face, arrayElem));
                        // BufferUtils.ensureLargeEnough(byteBuffer, imageSize);
                        log.log(Level.FINE, "position {0}", byteBuffer.position());
                        byteBuffer.position(offset);
                        byte[] b = getByteBufferArray(byteBuffer, imageSize);
                        out.write(b);
                        nbPixelWritten = b.length;
                    }
                    //cube padding
                    if (numberOfFaces == 6 && numberOfArrayElements == 0) {
                        padding = 3 - ((nbPixelWritten + 3) % 4);
                        pad(padding, out);
                    }
                }
            }
            //mip padding
            log.log(Level.FINE, "skipping {0}", (3 - ((imageSize + 3) % 4)));
            padding = 3 - ((imageSize + 3) % 4);
            pad(padding, out);
            offset += imageSize;
        }
    } catch (FileNotFoundException ex) {
        Logger.getLogger(KTXWriter.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
        Logger.getLogger(KTXWriter.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        try {
            if (outs != null) {
                outs.close();
            }
        } catch (IOException ex) {
            Logger.getLogger(KTXWriter.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
Also used : DataOutput(java.io.DataOutput) DataOutputStream(java.io.DataOutputStream) FileOutputStream(java.io.FileOutputStream) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) GLImageFormat(com.jme3.renderer.opengl.GLImageFormat) File(java.io.File) ByteBuffer(java.nio.ByteBuffer)

Aggregations

ByteBuffer (java.nio.ByteBuffer)5 Image (com.jme3.texture.Image)4 Format (com.jme3.texture.Image.Format)4 GLImageFormat (com.jme3.renderer.opengl.GLImageFormat)2 GL (com.jogamp.opengl.GL)2 Caps (com.jme3.renderer.Caps)1 DataOutput (java.io.DataOutput)1 DataOutputStream (java.io.DataOutputStream)1 File (java.io.File)1 FileNotFoundException (java.io.FileNotFoundException)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1