What is the difference between double buffering by:
-creating BufferedImage, drawing in it, and drawImage() onto screen,
-using BufferStrategy.
I have only used BufferStrategy once and it doesn’t seem that much different.
What is the difference between double buffering by:
-creating BufferedImage, drawing in it, and drawImage() onto screen,
-using BufferStrategy.
I have only used BufferStrategy once and it doesn’t seem that much different.
BufferStrategy is way faster . I cannot quantize this “way faster” right now, but I remember a few years ago when I was developing my first java game I almost cried with hapiness when I changed double buffering with BufferedImage to BufferStrategy and gaind something like 20 FPS .
Hmm, ok I will look into it a bit more.
But I still don’t understand how it is faster ???
BufferStrategy has the option of pointer flipping. Instead of copying the off screen buffer to the screen’s memory, the buffer simple says “Use this for memory the screen now”. It is not only faster, but also reduces tearing.
Oh so that’s the difference!
Thanks!!
This is valuable knowledge. Do you have any code samples or links with exanples of the difference in implementing this switch? Is it a class-for-class swap or is there a drastic pattern change required?
First stop for all API questions should be the Javadoc (http://download.oracle.com/javase/6/docs/api/). Look up BufferStrategy and BufferCapabilities. The class is well documented.
There is createBufferStrategy(int) in java.awt.Canvas and java.awt.Window. You call that first then get the BufferStrategy by calling getBufferStrategy(). All there is left is to getDrawGraphics() to get the Graphics object and then show() to show the image on the screen.
Hope that helped ;D
It did! I think you are the flash, replying to all my threads.
Oh wow I didn’t know you were the OP of that other thread about AWT
Glad to help anyway ;D
How does BufferStrategy differ from just using a Swing JPanel and drawing on that? JPanel automatically double buffers, doesn’t it? Really simple to use. I can do redraws under 20msec with it. ??? It seems quite good for beginning simple animations, as well as move-based or puzzle-based games. The “smoke” the click&drag animation in Hexara http://www.hexara.com are all done that way.
Generally go for bufferstrategy as buffer flipping is faster than bit copying. That is unless you are creating the entire screen image by manually manipulating bits in CPU memory, rather than on the GPU. In this case, you end up copying the entire buffer every frame anyway. If you implement BufferStrategy in this case, and the hardware doesn’t support it, then you can end up copying the buffer twice every frame!
If you want to use JFrame or JApplet, then draw on a JComponent and then you don’t need to worry about double buffering.
If you want to use Frame or Applet, then draw on a Canvas and use BufferStrategy.
So, let me get this straight: You can simply draw on the panel and it will auto double buffer? That sounds perfect.
I don’t recommend drawing on a JPanel, try JComponent.
Yes, you can draw on a JPanel and it automatically double buffers. ra4king is adamant that JComponent is better. There are probably good reasons and I defer to him, as I’m kind of cruising on the surface level of Java in many respects and have never used JComponent. But if you are looking for simplicity, you CAN do this:
Top level, JFrame. Then, instead of trying to do anything fancy with the “content pane” of the JFrame, just add a subclassed JPanel and draw/animate your objects on that. Easy peasy. We are talking beginning, get feet wet, intro to Java game programming, nothing fancy. But one can do a fair bit with this set up.
I think the main hazard/complication is that repaint() calls have to be done from some vantage point other than the JPanel itself, due to an aspect of “passive rendering”. If you put your game loop or timer on the JPanel with the animation, the Event Dispatch Thread will think it can be “more efficient” by collapsing the repaint calls together rather than treating each one as a separate event.
So, my solution has been to create a separate class with a Timer and have the Timer call the JPanel’s repaint() function. I use the java.util timer, and set it to repeat calls every 30 msec or thereabouts. But you could do something similar with a game loop. Main point, the game loop or timer should not be part of the JPanel class you are animating.
Do I hear howls of disagreement? 8) One can refactor in active rendering or other fancier animation schemes later.
JPanel is used as a container. You don’t draw on a container, you draw on a component
And yes, I agree that calling repaint() is passive rendering, which is why it’s good for beginners, but not recommended to keep doing.
When I made a quick test, I went up to 100 FPS without the repaint() calls being collapsed together so it’s not really that bad.
public class JComponent extends Container
The reason to use JPanel over JComponent is that JPanel calls setDoubleBuffered(true) in its constructor, while JComponent does not.
Yes yes I know but try adding components to a JComponent ;D
JComponent is automatically double buffered without any extra variables/method calls
The real gotcha is that JRootPane calls setDoubleBuffered(true) in its constructor, which causes all of its child components (i.e., everything) to be double-buffered, no matter what their value of their double-buffer flags are.