Estoy notando una gran diferencia de rendimiento entre Java & JOGL y C# & Tao.OpenGL cuando ambos cargan PNG desde el almacenamiento en la memoria y al cargar esa imagen Buffered (java) o mapa de bits (C# - ambos son PNG en el disco duro) 'en' OpenGL.Cargando PNG en problemas de rendimiento OpenGL - Java y JOGL mucho más lento que C# & Tao.OpenGL
Esta diferencia es bastante grande, así que supuse que estaba haciendo algo mal, sin embargo después de bastante buscar e intentar con diferentes técnicas de carga, no he podido reducir esta diferencia.
Con Java obtengo una imagen cargada en 248ms y cargada en OpenGL en 728ms Lo mismo en C# toma 54ms para cargar la imagen, y 34ms para cargar/crear textura.
La imagen en cuestión es una PNG que contiene transparencias, con un tamaño de 7200x255, utilizada para un sprite animado en 2D. Me doy cuenta de que el tamaño es realmente bastante ridículo y estoy considerando cortar el sprite, sin embargo, la gran diferencia sigue ahí (y confusa).
En el lado de Java el código es el siguiente:
BufferedImage image = ImageIO.read(new File(fileName));
texture = TextureIO.newTexture(image, false);
texture.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
texture.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
El código C# utiliza:
Bitmap t = new Bitmap(fileName);
t.RotateFlip(RotateFlipType.RotateNoneFlipY);
Rectangle r = new Rectangle(0, 0, t.Width, t.Height);
BitmapData bd = t.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, tID);
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, t.Width, t.Height, 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, bd.Scan0);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
t.UnlockBits(bd);
t.Dispose();
Después de un buen montón de pruebas que sólo se puede llegar a la conclusión de que Java/JOGL es más lento aquí - la lectura de PNG puede no ser tan rápida o que todavía estoy haciendo algo mal.
Gracias.
Edit2:
he encontrado que la creación de un nuevo BufferedImage con formato TYPE_INT_ARGB_PRE disminuye el tiempo de carga de OpenGL textura casi a la mitad - esto incluye tener que crear el nuevo BufferedImage, conseguir la Graphics2D de ella y luego hacer que la ya cargada imagen a ella.
Edit3: Resultados de puntos de referencia para 5 variaciones. Escribí una pequeña herramienta de evaluación comparativa, los siguientes resultados provienen de cargar un conjunto de 33 pngs, la mayoría son muy anchos, 5 veces.
testStart: ImageIO.read(file) -> TextureIO.newTexture(image)
result: avg = 10250ms, total = 51251
testStart: ImageIO.read(bis) -> TextureIO.newTexture(image)
result: avg = 10029ms, total = 50147
testStart: ImageIO.read(file) -> TextureIO.newTexture(argbImage)
result: avg = 5343ms, total = 26717
testStart: ImageIO.read(bis) -> TextureIO.newTexture(argbImage)
result: avg = 5534ms, total = 27673
testStart: TextureIO.newTexture(file)
result: avg = 10395ms, total = 51979
ImageIO.read (bis) se refiere a la técnica descrita en la respuesta de James Branigan a continuación. argbImage se refiere a la técnica descrita en mi anterior edición:
img = ImageIO.read(file);
argbImg = new BufferedImage(img.getWidth(), img.getHeight(), TYPE_INT_ARGB_PRE);
g = argbImg.createGraphics();
g.drawImage(img, 0, 0, null);
texture = TextureIO.newTexture(argbImg, false);
Cualquier más métodos de carga (ya sea imágenes de archivo, o imágenes a OpenGL) sería apreciada, voy a actualizar estos puntos de referencia.
El mismo punto de referencia ejecutado en C# utilizando Tao toma avg 1106ms, total 5531ms.Todavía 5 veces más rápido que el método más rápido que he encontrado para Java/JOGL. –