2012-04-03 93 views
1

我在循環創造了多種視覺對象以避免OutOfMemoryError異常:Java3D的:如何同時使用紋理

... 
Package packet; // a visual packet 
for(int i = 0; i < numberOfSteps; i++){ 
    packet = new Package(packetSize, packetSize, packetSize); 

    // position, rotate, etc. and add to scene graph 
} 
... 

的包裝基本上只是一個簡單的立方體紋理。封裝的建築工如下所示:

public Package(float x, float y, float z) { 
    Appearance appear = new Appearance(); 
    BufferedImage filename = null; 

    try { 
     filename = ImageIO.read(getClass().getResource("package.jpg")); 
    } catch (IOException e) { 
        e.printStackTrace(); 
     System.exit(1); 
    } 

    TextureLoader loader = new TextureLoader(filename); 
    ImageComponent2D image = loader.getImage(); 
    Texture2D texture = new Texture2D(Texture.BASE_LEVEL, Texture.RGBA, 
      image.getWidth(), image.getHeight()); 
    texture.setImage(0, image); 
    appear.setTexture(texture); 
    textureCube = new Box(x, y, z, Box.GENERATE_TEXTURE_COORDS, appear); 
} 

所以我一遍又一遍的加載相同的紋理在循環,最終導致OutOfMemoryError異常。無論如何避免/優化?

回答

3

最明顯的優化是緩存你BufferedImage

class ImageProvider{ 

    private static Map<String, Image> images = new HashMap<String, Image>(); 

    public static Image getImage(String filename){ 
     if(!images.contains(filename)) 
      try { 
       images.put(filename, ImageIO.read(ImageProvider.class.getResource(filename)); 
      } catch (IOException ignore){ 
       //will return null if image cannot be loaded 
      } 

     return images.get(filename); 
    } 
} 

根據您之後進行的操作,你也可以緩存你ImageComponent2D對象和/或您的Texture2D對象。

0

而不是一遍又一遍地創建一個新的紋理,嘗試重新安排您的代碼,以便它重用相同的紋理。這樣,紋理只需要加載一次,並因此使用更少的內存。

0

所以簡短的回答是肯定的。你可以進行優化,除非我誤以爲理論上你可以重複使用同一個「Package」對象,只是改變其中的一些參數以減少內存使用,你可以多次將該紋理加載到內存中創建

相關問題