Collada Texture flip


I'm loading a Collada model (exported from Blender) and have noticed that the textures are all flipped during the load process. This flip is relatively expensive so I'd like to avoid it. (set/get RGB are very high in the profiler)

Looking through ColladaImporter it appears the importer always calls TextureManager.loadTexture with the flip flag (implicitly) set to true.

Is this a restriction of the collada format (I looked through the spec for image and surface and did not see anything about image yUp) ?

Rgds

Paul

Have you thought about loading it in a different thread, running it as a background task ??

It's pretty typical to flip the texture because of the difference between the origin points of an image (upper left) and opengl (lower left).  I don't think it's a collada thing though, but don't know that for sure.


Turns out ImageIO was loading my png files into a BufferedImage of type CUSTOM_TYPE which made the flip loop really, really slow. I've added some code to TextureManager to encourage ImageIO to load into one of the preferred BufferedImage formats.

How do I get this update reviewed and (hopefully) integrated into cvs ? Should I file and bug including a diff ?

Rgds

Paul

If it's pretty small, go ahead and post here.  Otherwise, please submit a bug report.


Heres the patch for TextureManager that 'strongly encourages' ImageIO to load images into JME's prefered format. Depending on the internal structure of the original image file this can give a significant performance increase to the texture flip operation.

43a44
> import java.net.URISyntaxException;
67a69,75
> import java.io.File;
> import java.io.FileInputStream;
> import javax.imageio.ImageReadParam;
> import javax.imageio.ImageReader;
> import javax.imageio.ImageTypeSpecifier;
> import javax.imageio.stream.FileCacheImageInputStream;
> import javax.imageio.stream.FileImageInputStream;
441c449
<        InputStream is;
---
>        InputStream is=null;
443c451
<            is = file.openStream();
---
>            is = file.openStream();           
472c480,481
<                java.awt.Image image = ImageIO.read(stream);
---
> //                java.awt.Image image = ImageIO.read(stream);
>                java.awt.Image image = readImage(fileExt, stream);
484a494,558
>   
>    /**
>      * Load the image as either TYPE_3BYTE_BGR or TYPE_4BYTE_ABGR
>      * @param fileExt
>      * @param imageIn
>      * @return
>      * @throws java.io.IOException
>      */
>    private static BufferedImage readImage(String fileExt, InputStream imageIn) throws IOException {
>        BufferedImage image;
>        ImageTypeSpecifier imageType;
>        int width;
>        int height;
>       
>        if (imageIn==null)
>            throw new IOException("Null Stream");
>       
>        String format = fileExt.substring(1);  // Remove .
>        ImageReader reader = (ImageReader)ImageIO.getImageReadersByFormatName(format).next();
>
>        try {
>            // Not ideal as we are creating a cache file, but as we are processing
>            // a stream we don't have access to the local file info
>            reader.setInput(new FileCacheImageInputStream(imageIn,null));
>            imageType = reader.getRawImageType(0);
>            if (imageType == null) {
>                // Workaround for Mac issue getting image type of JPEG images.
>                // Look through the list to find the first type with
>                // a non-null ColorModel
>                for (Iterator<ImageTypeSpecifier> i = reader.getImageTypes(0);
>                      i.hasNext();)
>                {
>                    ImageTypeSpecifier temp = i.next();
>                    if (temp != null && temp.getColorModel() != null) {
>                        imageType = temp;
>                        break;
>                    }
>                }
>               
>                // if there is still no image type, throw an exception
>                if (imageType == null) {
>                    throw new IOException("Cannot get image type for " + fileExt);
>                }
>            }   
>            width = reader.getWidth(0);
>            height = reader.getHeight(0);
>        } catch(IndexOutOfBoundsException ioob) {
>            logger.warning("Corrupt image file ");
>            // The image file is corrupt
>            throw new IOException("Image read failure");
>        }
>           
>        if (imageType.getColorModel().getTransparency()==ColorModel.OPAQUE) {
>            image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
>        } else {
>            image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
>        }
>        ImageReadParam param = reader.getDefaultReadParam();
>        param.setDestination(image);
>        image = reader.read(0,param);
>       
>        reader.dispose();
>       
>        return image;
>    }

Thanks, that also helps with other issues I was seeing with black&white jpgs.  In cvs now.