Am I double buffering correctly? Do I need to?

Hi guys. Thanks in advance for the help.

I’m whipping up a 2D engine for the first time. I’ve copied my render loop below. What seeking help for here is a better understanding of BufferStrategy and Buffering to an offscreen Image, when they should be employed, and if I’m doing it wrong.

One approach I’ve read about is reading images into an array of pixels then using a blit method to insert them on a per pixel basis to an offscreen image, then painting the image. I believe I’ve began preparing for this method below.

Would it be a better idea just to read the image into a BufferedImage and then use the drawImage() method to draw it onto the Graphics of the BufferStrategy? Moreover, when I draw text and lines would I be drawing them onto the offscreenGraphics? or the Graphics of the BufferStrategy?


    public void render() {
        BufferStrategy bs = getBufferStrategy();
        if (bs == null) {
            createBufferStrategy(3);
            requestFocus();
            return;
        }


        Graphics g = bs.getDrawGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.translate((getWidth() - GAME_WIDTH * SCALE) / 2, (getHeight() - GAME_HEIGHT * SCALE) / 2);
        g.clipRect(0, 0, GAME_WIDTH * SCALE, GAME_HEIGHT * SCALE);


        offscreenGraphics.setBackground(Color.WHITE);
        offscreenGraphics.clearRect(0, 0, getWidth(), getHeight());
        offscreenGraphics.setColor(Color.BLACK);
        offscreenGraphics.drawLine(0, 0, 100, 100);

        // Stress test of changing each pixel individually.
        for (int x = 0; x < GAME_HEIGHT; x++) {
            for (int y = 0; y < GAME_WIDTH; y++) {
                pixels[(x * GAME_WIDTH) + y] = 0xFF3333;
            }
        }

        // Testing drawing a line
        offscreenGraphics.draw(new Line2D.Double(5, 5, 500, 500));

        // Testing drawing a string.
        offscreenGraphics.drawString(Integer.toString(framesPerSecond), 100, 100);

        g.drawImage(offscreenImage, 0, 0, GAME_WIDTH * SCALE, GAME_HEIGHT * SCALE, 0, 0, GAME_WIDTH, GAME_HEIGHT, null);
        g.dispose();
        bs.show();
    }

Other code that I’m using is:

        renderHints.put(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
        offscreenGraphics.setRenderingHints(renderHints);

I’m no expert and I’m sure raking or someone will clarify, but I thought when you used a BufferStrategy, it created your offscreen area for you, and you draw with the ‘Graphics g = bs.getDrawGraphics();’, and bs.show() will switch the buffer, or blit it to screen. And I think you should just read images into a bufferedimage then draw them with the same ‘g’ from earlier

Yup, there is no need to add the extra overhead of another Image. Just draw directly to BufferStrategy’s Graphics2D and then call show().
This code shows the best way to setup BufferStrategy.

Awesome code. Is it still possible to work on a BufferStrategy on a per pixel basis? Suppose that I wanted to blit all the pixels into black and white for a dream sequence.

Its interesting that I got my Rendering loop ideas largely from Notch’s Ludum Dare entries. I wonder if he does his 2D game rendering sub-optimally.

No, to work on per pixel basis, you’ll have to create a BufferedImage instance. The best and fastest way to create a BufferedImage, is to create a compatible one (line 87).

Thanks mate I do appreciate the help.

I jumped from about 80fps to 170fps after implementing your code. Thats without even changing the double handling of the BufferStrategy and BufferedImage. ;D