java 2d performance
-
hey, ich spiele mich gerade ein bisschen mit java 2d herum
ich hab ein 640x480 java.awt.frame fenster gemacht mit einem canvas
in einer loop wird die paint funktion aufgerufen, wenn sie mehr oder weniger leer ist
@Override public void paint(Graphics g) { fillBackBuffer(); Graphics gr = this.getGraphics(); gr.drawImage(backBuffer, 0, 0, this); gr.dispose(); } public void fillBackBuffer() { if (backBuffer.validate(getGraphicsConfiguration()) == VolatileImage.IMAGE_INCOMPATIBLE) { backBuffer = createVolatileImage(640, 480); } Graphics2D graphics = backBuffer.createGraphics(); graphics.clearRect(0, 0, this.getWidth(), this.getHeight()); background.device = graphics; //background.render(); graphics.drawString("FPS: " + Clock.getInstance().getFramesPerSecond(), 70, 25); graphics.dispose(); }
läuft das ganze mit ca 2k frames pro sekunde
wenn ich aber die zeile //background.render(); wieder reintue, wobei die methode das hier macht:
@Override public void render() { device.drawImage(texture.getImage(), transformation, null); }
fällt die framerate runter auf 27 fps
das mit dem volatile image hab ich ziemlich 1:1 aus der java doku rausgenommen
jetzt meine frage, ist das normal? dass wenn man ein 640x480 großes bild rendert java sooo langsam ist?
wenn man sowas mit directx oder opengl macht selbst in software läuft es mit ka.... sicher über 200 fpsmache ich vllt etwas falsch?
//edit
http://java.sun.com/products/java-media/2D/samples/java2demo/Java2Demo.htmldieses applet von java demonstriert halt ihre ganzen java 2d render funktionen, rechts in der drop down box (unter arc curves zb) kann man unterschiedliche optionen auswählen, alle haben ca 30+ fps bei mir wie meine applikation aber "on screen" schießt sie wieder rauf auf 2k
also würde mich interessieren was "on screen" rendering jetzt genau macht in diesem java beispiel falls es jemand weiss (vor allem flackert es nicht wie es das normalerweise sollte wenn man wirklich direkt auf die component zeichnet obje backbuffer)
-
ok es lag scheinbar daran wie ich die bilder reingeladen habe, wenn ich es so mache
BufferedImage sourceImage = ImageIO.read(new File(aFilePath)); GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); newTexture.texture = gc.createCompatibleImage(sourceImage.getWidth(), sourceImage.getHeight(), sourceImage.getTransparency()); Graphics2D graphics = newTexture.texture.createGraphics(); graphics.setComposite(AlphaComposite.Src); graphics.drawImage(sourceImage, 0, 0, null); graphics.dispose();
wobei newTexture.texture ein bufferedimage ist
dann lässt sich das 640x480 bild mit 1300 fps rendern und wenn ich noch 250 kleiner 32x32 bilder mit color-keys rendere sinds immer noch 200+ fps was mir mal reicht
-
Vevusio schrieb:
wobei newTexture.texture ein bufferedimage ist
Ist es nicht besser immer VolatileImage zu verwenden?
VolatileImage is an image which can lose its contents at any time due to circumstances beyond the control of the application (e.g., situations caused by the operating system or by other applications). Because of the potential for hardware acceleration, a VolatileImage object can have significant performance benefits on some platforms.
-
naja nen backbuffer der jede sekunde 50+ mal neu beschrieben wird zu verlieren ist kein problem aber texturen die man permanent wiederverwendet neu laden zu müssen wäre schlecht
und der performance unterschied zwischen volatileimage und bufferedimage war nicht soo groß