Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (526)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (593)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Page Flipping with Buffer Strategy  (Read 3188 times)
0 Members and 1 Guest are viewing this topic.
Offline dudley442

Senior Newbie




Java games rock!


« Posted 2003-07-16 01:05:11 »

First time poster here.  Smiley


Ever since I managed to get full-screen exclusive mode working, I've noticed that the faster moving objects tear like crazy.  I've scoured the net for one decent example of a simple page-flipping code and came up with nothing.  Everyone keeps linking to the "examples"   Roll Eyes on Sun's site, but there is no code whatsoever demonstrating the use of page-flipping.

Having a couple of words and pictures doesn't do it for this programmer.  Wish it did, but it doesn't.  Wink

I would be very grateful if any kind soul here could point me in the right direction -- that one, single example!
Offline tortoise

Junior Devvie




<3 Shmups


« Reply #1 - Posted 2003-07-16 01:23:15 »

It's actually pretty easy. Java does most of the work for you. This little thread outlines it, and I believe in the shared code forum there are other, more detailed, examples.

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=newbies;action=display;num=1057373581

Just keep in mind you have to call that setupBuffering() method  after the frame is fully created and visible.

The strategy.show() is where the magic happens. Java will either page flip or blit, depending on what the hardware is capable of.
Offline dudley442

Senior Newbie




Java games rock!


« Reply #2 - Posted 2003-07-16 12:16:23 »

Ah, thanks.  Looks like it's working.  Multi-buffer and page-flipping both return as true.

However, there's horrible full-screen flickering now.  I can tell that there's no more tearing, but the whole screen flashes with the background color.  It isn't exactly the "flickering" that you'd see in the old days when you didn't use the old-fashioned double-buffering, but it's more of a flashing.

The background itself doesn't clear out the area; I have to do a setColor(Color.blue) and fillRect(0,0,640,480), otherwise you get that effect like in Doom when you walk out of the walls.


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.applet.*;
import java.util.*;
import java.net.*;
import java.applet.Applet;
import javax.swing.*;
import java.io.*;


public class Gamer extends Frame implements KeyListener, MouseListener, MouseMotionListener
{
      BufferStrategy strategy;
      BufferCapabilities bufCap;

      GraphicsDevice device;
      GraphicsConfiguration gc;
      boolean inFullScreen;

      DisplayMode newDisplayMode;
      DisplayMode oldDisplayMode;

      public Gamer (String title, GraphicsDevice device)
      {
            super(device.getDefaultConfiguration());
                   this.device = device;

            oldDisplayMode = device.getDisplayMode();

            boolean isFullScreen = device.isFullScreenSupported();
              setUndecorated(isFullScreen);
              setResizable(!isFullScreen);

              if (isFullScreen)
            {
                        device.setFullScreenWindow(this);
                       validate();
                  inFullScreen = true;
                   }
           
            else
            {
                        pack();
                        setVisible(true);
                  inFullScreen = false;
              }

           

            newDisplayMode = new DisplayMode(640, 480, 32, 60);
            device.setDisplayMode(newDisplayMode);
            gc = device.getDefaultConfiguration();
            bufCap = gc.getBufferCapabilities();

            createBufferStrategy(3);
            strategy = getBufferStrategy();

            setBackground(Color.blue);

            while (true)
            {
                  if (loaded)
                  {
                        runningUpdate();
                        render();
                  }

                  try
                  {
                        Thread.sleep(20);
                  }

                  catch (InterruptedException e) {}
            }            
      }

      public void render ()
      {
            Graphics g1 = strategy.getDrawGraphics();

            Graphics2D g = (Graphics2D) g1;

            g.setColor(Color.blue);
            g.fillRect(0,0,640,480);

            // DRAWING

            g.dispose();
            strategy.show();
      }
           
      public static void main (String[] args)
      {
            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice myDevice = env.getDefaultScreenDevice();

            Gamer gamer = new Gamer("Gamer", myDevice);
            gamer.setSize(640, 480);
            gamer.setVisible(true);
      }
}



Could someone please tell me what I'm doing wrong here?  That's all the code relevant to the graphical aspect of my program.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Abuse

JGO Knight


Medals: 14


falling into the abyss of reality


« Reply #3 - Posted 2003-07-16 12:31:54 »

Quote
Ah, thanks.  Looks like it's working.  Multi-buffer and page-flipping both return as true.

However, there's horrible full-screen flickering now.  I can tell that there's no more tearing, but the whole screen flashes with the background color.  It isn't exactly the "flickering" that you'd see in the old days when you didn't use the old-fashioned double-buffering, but it's more of a flashing.

The background itself doesn't clear out the area; I have to do a setColor(Color.blue) and fillRect(0,0,640,480), otherwise you get that effect like in Doom when you walk out of the walls.

Could someone please tell me what I'm doing wrong here?  That's all the code relevant to the graphical aspect of my program.


You arn't doing anything wrong, Unless you specify otherwise, that is the default behaviour for BufferStrategy. (BufferCapabilities.FlipContents UNDEFINED)

If you want the BufferStrategy to clear to the background color, you should construct the BufferStrategy using a BufferCapabilities object set to BufferCapabilities.FlipContents BACKGROUND.

However, its no slower than filling it yourself with a fillRect(0,0,getWidth,getHeight()); so i'd just stick with what you are doing atm.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline dudley442

Senior Newbie




Java games rock!


« Reply #4 - Posted 2003-07-16 12:42:24 »

I'm still wondering about that flashing effect that's going on.  I've noticed that the more buffers I use -- createBufferStrategy(numBuffers) --  the slower the frequency of the flash.

I'm doing something wrong here to cause this flashing effect.  It is definitely the background color that's doing it.  When the background is set to red, it'll flash red, etc.  Leaving it alone will flash white.

Red--Blue--Red flashing looks pretty cool and seizure-inducing, but it's not what I wanted for the game, exactly.  Wink

I'll try experimenting with a few other ideas I have, but so far, no luck.
Offline Abuse

JGO Knight


Medals: 14


falling into the abyss of reality


« Reply #5 - Posted 2003-07-16 12:54:48 »

You are redrawing the entire screen every repaint, arn't you?

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline kevglass

« JGO Spiffy Duke »


Medals: 210
Projects: 24
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #6 - Posted 2003-07-16 12:56:58 »

Don't you need to override paint() and update() to prevent the standard AWT stuff redrawing the screen?

Kev

Offline tortoise

Junior Devvie




<3 Shmups


« Reply #7 - Posted 2003-07-16 13:04:58 »

that's probably it, a setIgnoreRepaint(true) could do the trick. I've never had the flashing problems but I also always set to ignore repaints.
Offline dudley442

Senior Newbie




Java games rock!


« Reply #8 - Posted 2003-07-16 13:13:08 »

Whew!  Thanks everyone!   Grin Grin Grin

The setIgnoreRepaint(true) did the trick.  Now everything runs perfectly in fullscreen and without a single tear effect.
Offline dudley442

Senior Newbie




Java games rock!


« Reply #9 - Posted 2003-07-16 14:39:34 »

Seems like I've run into a totally different snag now.   Wink

I implemented the BufferStrategy as opposed to the old update() and paint() methods, and now my .png graphics -- which make extensive use of an alpha channel and partial transparency -- slow the game down considerably.  The more of them there are on the screen, the worse it is.

Before, without using strategy.show(), the performance was as quick as the Gingerbread Man, no matter how many of them I had on the screen at any given time.

I'd hate to have to go back to high-speed ripping and tearing, but I love my large corona effects.

Does anyone know what it is about using BufferStrategy that significantly downgrades the performance of images that utilize the alpha channel?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline kevglass

« JGO Spiffy Duke »


Medals: 210
Projects: 24
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #10 - Posted 2003-07-16 14:48:22 »

If you're on windows you might try these:

   -Dsun.java2d.translaccel=true
   -Dsun.java2d.ddforcevram=true  

Java accelerated graphics arn't keen on the alpha channel.

Kev

Offline tortoise

Junior Devvie




<3 Shmups


« Reply #11 - Posted 2003-07-16 14:58:08 »

Also make sure the BufferedImage that results from loading the png is actually accelerated. If you load your pngs via ImageIO, then they're not accelerated in my experience (is that truly the case?)

I always load them via ImageIO, create a blank accelerated BufferedImage (via GraphicsConfiguration.createCompatibleImage( width, height, transparency ) ), then copy the ImageIO made image into the blank one.

When you later notice your game running like jerky molasses in Linux, that's when you may rethink Java2D altogether  Grin
Offline kevglass

« JGO Spiffy Duke »


Medals: 210
Projects: 24
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #12 - Posted 2003-07-16 15:14:22 »

That being said, the accelerated graphics alpha will get fixed eventually.

Kev

Offline Abuse

JGO Knight


Medals: 14


falling into the abyss of reality


« Reply #13 - Posted 2003-07-16 16:23:39 »

...eventually

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline dudley442

Senior Newbie




Java games rock!


« Reply #14 - Posted 2003-07-17 00:52:03 »

I tried it.  I loaded the .png image through the ImageIO and then brought it over to a BufferedImage via createCompatibleImage.  I set both flags to true.  One rocketship didn't seem to do that much damage to the framerate.  But a few more certainly did.  Sad



When all I used was update() and paint(), I could get 60+ fps on a PIII 750mhz with this many rocketships on the screen.  (Same level of transparency.)

Now, even with accelerated BufferedImages, I barely get 3 fps on a PIV 2.4ghz in the same situation.

You'd think that if hardware mode wasn't faster than software, it'd be at least within the ballpark.  Wink


So a buffered image created with createCompatibleImage is automatically sent to VRAM if ImageCapabilities.isAccelerated() returns true?
Offline Abuse

JGO Knight


Medals: 14


falling into the abyss of reality


« Reply #15 - Posted 2003-07-17 09:00:05 »

Quote
I tried it.  I loaded the .png image through the ImageIO and then brought it over to a BufferedImage via createCompatibleImage.  I set both flags to true.  One rocketship didn't seem to do that much damage to the framerate.  But a few more certainly did.  Sad

When all I used was update() and paint(), I could get 60+ fps on a PIII 750mhz with this many rocketships on the screen.  (Same level of transparency.)

Now, even with accelerated BufferedImages, I barely get 3 fps on a PIV 2.4ghz in the same situation.

You'd think that if hardware mode wasn't faster than software, it'd be at least within the ballpark.  Wink


There lies part of the dilemma, drawing an image with an alpha channel to a vram backBuffer when alpha composite is not accelerated is incredibly slow. (the image has to be read back from vram, before the alpha composite can begin)

So, on a system without hardware AlphaCompositing, performance will be far far better by keeping the backBuffer in main mem.
However, this obviously eliminates the potencial for hardware acceleration on regular OPAQUE, and BITMASK images as well.

I think what Sun need to add, is a 'request capabilities' type interface, where by you specify what type of images you intend on drawing (OPAQUE,BITMASK, TRANSLUCENT), the api will then pick the best back buffer for you situation.

Quote
So a buffered image created with createCompatibleImage is automatically sent to VRAM if ImageCapabilities.isAccelerated() returns true?


Not exactly, when a ManagedImage (the type of Image elligable for hardware acceleration, that is returned from createCompatibleImage) is drawn 2 times, it is cached in vram.
If the image (the version in main memory) is subsequently modified, the vram cached version becomes useless, and is disgarded. (and has to be recached on a subsequent blit)

Incidentaly, you must have something not quite right in your code, cos hardware accelerated AlphaCompositing does work [in windows, with 1.4.1_02 or later] Cheesy

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline dudley442

Senior Newbie




Java games rock!


« Reply #16 - Posted 2003-07-17 12:41:17 »

I am such an idiot!  Cheesy Cheesy Cheesy

Know what I did with the flags?  I put them after Java MyProgram.   Wink

Now the game runs just as fast as it did in the first place!  Thanks very much for the help.  Now that I've got everything technologically speaking, I can finally buckle down and concentrate on the game itself.  Grin
Offline kevglass

« JGO Spiffy Duke »


Medals: 210
Projects: 24
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #17 - Posted 2003-07-17 12:48:25 »

Na, an idiot wouldn't have found it. Its just the sorta thing that screws things up for ages..

Well done, good luck, etc..

Kev

Offline Abuse

JGO Knight


Medals: 14


falling into the abyss of reality


« Reply #18 - Posted 2003-07-17 15:05:50 »

Quote
I am such an idiot!  Cheesy Cheesy Cheesy

Know what I did with the flags?  I put them after Java MyProgram.   Wink


hehe, I thought you might have set them after an AWT component had been initialised. (I believe they have to be set before the AWT is initialised)
But putting them after the program.... well.... yeah LOL

hope you'll post the game when its complete? Wink

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

toopeicgaming1999 (71 views)
2014-11-26 15:22:04

toopeicgaming1999 (60 views)
2014-11-26 15:20:36

toopeicgaming1999 (14 views)
2014-11-26 15:20:08

SHC (27 views)
2014-11-25 12:00:59

SHC (25 views)
2014-11-25 11:53:45

Norakomi (31 views)
2014-11-25 11:26:43

Gibbo3771 (25 views)
2014-11-24 19:59:16

trollwarrior1 (38 views)
2014-11-22 12:13:56

xFryIx (77 views)
2014-11-13 12:34:49

digdugdiggy (55 views)
2014-11-12 21:11:50
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!