Tôi nhận thấy sự khác biệt hiệu suất lớn giữa Java & JOGL và C# & Tao.OpenGL khi tải PNG từ bộ nhớ vào bộ nhớ và khi tải BufferedImage (java) hoặc Bitmap (C# - cả hai đều là PNG trên ổ cứng) 'vào' OpenGL.Tải PNG thành các vấn đề về hiệu năng OpenGL - Java & JOGL chậm hơn nhiều so với C# & Tao.OpenGL
Sự khác biệt này khá lớn, vì vậy tôi cho rằng mình đã làm điều gì đó sai, tuy nhiên sau khá nhiều tìm kiếm và thử các kỹ thuật tải khác nhau, tôi không thể giảm sự khác biệt này.
Với Java, tôi tải hình ảnh trong 248ms và tải vào OpenGL trong 728ms Tương tự trên C# mất 54ms để tải hình ảnh và 34ms để tải/tạo kết cấu.
Hình ảnh được đề cập ở trên là PNG có độ trong suốt, có kích thước 7200x255, được sử dụng cho một hình động 2D. Tôi nhận ra kích thước thực sự là khá vô lý và đang xem xét cắt lên các sprite, tuy nhiên sự khác biệt lớn vẫn còn đó (và khó hiểu).
Về phía Java mã trông như thế này:
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);
Mã C# sử dụng:
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();
Sau khá nhiều thử nghiệm tôi chỉ có thể đi đến kết luận rằng Java/JOGL chỉ chậm hơn ở đây - việc đọc PNG có thể không nhanh hoặc tôi vẫn đang làm điều gì sai.
Cảm ơn.
Edit2:
Tôi đã tìm thấy rằng việc tạo một BufferedImage mới với định dạng TYPE_INT_ARGB_PRE giảm thời gian tải kết cấu OpenGL bằng gần một nửa - điều này bao gồm việc phải tạo ra BufferedImage mới, nhận được Graphics2D từ nó và sau đó vẽ các tải trước đây hình ảnh cho nó.
Chỉnh sửa3: Kết quả điểm chuẩn cho 5 biến thể. Tôi đã viết một công cụ đo điểm chuẩn nhỏ, các kết quả sau đây đến từ việc tải một bộ 33 png, hầu hết là rất rộng, 5 lần.
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) dùng để chỉ kỹ thuật được mô tả trong câu trả lời của James Branigan dưới đây. argbImage đề cập đến các kỹ thuật được mô tả trong chỉnh sửa trước đây của tôi:
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);
Bất kỳ phương pháp hơn xếp hàng (hoặc hình ảnh từ file, hoặc hình ảnh để OpenGL) sẽ được đánh giá, tôi sẽ cập nhật những tiêu chuẩn.
Cùng một điểm chuẩn chạy trong C# bằng cách sử dụng Tao mất tổng cộng 1106ms, tổng 5531ms.Vẫn nhanh hơn 5 lần so với phương thức nhanh nhất mà tôi đã tìm thấy cho Java/JOGL. –