両方ともストレージからメモリにPNGをロードするとき、およびそのBufferedImage(java)またはビットマップ(C#-両方ともハードドライブ上のPNG)をOpenGLにロードするとき、JavaとJOGLとC#とTao.OpenGLのパフォーマンスに大きな違いがあることに気づきました。 。
この違いは非常に大きいので、何か間違ったことをしていると思いましたが、さまざまな読み込み手法を何度も検索して試した結果、この違いを減らすことができませんでした。
Javaを使用すると、画像が248ミリ秒で読み込まれ、OpenGLに728ミリ秒で読み込まれます。C#でも同じように、画像の読み込みに54ミリ秒、テクスチャの読み込み/作成に34ミリ秒かかります。
上記の画像は、2Dアニメーションスプライトに使用される7200x255のサイズの透明度を含むPNGです。サイズが本当にばかげていることに気づき、スプライトを切り取ることを検討していますが、大きな違いはまだあります(そして混乱します)。
Java側では、コードは次のようになります。
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);
C#コードは以下を使用します:
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();
かなり多くのテストを行った後、ここではJava / JOGLの速度が遅いという結論に達することができます。PNGの読み取りはそれほど速くないか、まだ何か間違っているという結論に達することができます。
ありがとう。
Edit2:
TYPE_INT_ARGB_PRE形式で新しいBufferedImageを作成すると、OpenGLテクスチャの読み込み時間がほぼ半分に短縮されることがわかりました。これには、新しいBufferedImageを作成し、そこからGraphics2Dを取得して、以前に読み込まれた画像をレンダリングする必要があります。
Edit3:5つのバリエーションのベンチマーク結果。私は小さなベンチマークツールを作成しました。次の結果は、33個のpngのセットを読み込んだ結果です。ほとんどの場合、非常に幅が広く、5回です。
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)は、以下のJamesBraniganの回答で説明されている手法を指します。argbImageは、以前の編集で説明した手法を参照しています。
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);
これ以上の読み込み方法(ファイルからの画像、またはOpenGLへの画像のいずれか)をいただければ幸いです。これらのベンチマークを更新します。