Fullscreen Tearing

Hey everybody,

I’m having a bit of a problem here. I’m remaking a Mario game, and everything worked fine with the scrolling until I added fullscreen support. Whenever you move and the scrolling takes effect, I see quite a bit of “tearing.” It’s mostly visible on the pipe. The game is here: http://www.myexh.com/~gonav341/Mario.php (it is WebStart, but I use PHP to change the header to JNLP; my host doesn’t support JNLP). It can’t be my rendering code (or scrolling code) either because in windowed mode, it works perfectly fine.

I also tried using the -Dsun.java2d.opengl=True (when running with a .bat file) and this fixed the problem perfectly. But as this can’t be enabled in a JAR (or via WebStart), I can’t use it to fix this problem. Maybe there’s a method built in Java to enable the 2D OpenGL pipeline?

Or maybe it’s just my code I’m using to enter fullscreen? I use the following (to create the Frame and BufferStrategy and enter FSEM):

		// Create the Frame.
		frame = new Frame("Mario");

		frame.add(this);
		frame.setResizable(false);
		frame.setUndecorated(true);

		frame.pack();
		frame.setVisible(true);

		// Initialize the back buffer.
		createBufferStrategy(2);
		buffer = getBufferStrategy();
		screen = (Graphics2D)buffer.getDrawGraphics();

		// Set the display mode and enter fullscreen mode.
		GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
		if (gd.isFullScreenSupported()) {
			gd.setFullScreenWindow(frame);
			if (gd.isDisplayChangeSupported()) {
				try {
					int refresh = gd.getDisplayMode().getRefreshRate();
					gd.setDisplayMode(new DisplayMode(gameW, gameH, 32, refresh));
				} catch(Exception e) {
					gd.setFullScreenWindow(null);
					System.out.println("No suitable display mode was found. Switching back to windowed mode.");
				}
			} else {
				gd.setFullScreenWindow(null);
				System.out.println("Display mode change not supported. Switching back to windowed mode.");
			}
		} else {
			System.out.println("Fullscreen mode not supported. Using windowed mode.");
		}

Note: this refers to the Canvas in which my BufferStrategy is created for.

I appreciate the help. Thanks in advanced.

Hi,

To get vertical retrace sync on windows (this requires full screen mode but no options, ie without opengl) use a BufferStrategy with 3 buffers. This enables page-flipping which is what vertical syncing needs.

You can use the ogl pipeline with webstart (see my jnlp for an example, just open it using Notepad - http://www.freewebs.com/commanderkeith/STG/STGopengl.jnlp) or in a JAR by using System.setProperty(); Note that the programmatic System way of doing it won’t work with webstart.

There’s a previous post where I was finding out about that stuff here: http://www.java-gaming.org/forums/index.php?topic=14092.0

Good luck!

Keith

Using the property tag in the JNLP file works like a charm - no problems. However, whenever I use System.setProperty(“sun.java2d.opengl”, “True”) (not launched via WebStart, but locally), most of the time (not always), it throws a NullPointerException:

Exception in thread "main" java.lang.NullPointerException: BufferedImage cannot
be null
        at sun.awt.image.SurfaceManager.getManager(SurfaceManager.java:61)
        at sun.awt.image.SurfaceManager.getManager(SurfaceManager.java:45)
        at sun.java2d.SurfaceData.restoreContents(SurfaceData.java:122)
        at sun.java2d.opengl.WGLSurfaceData$WGLOffScreenSurfaceData.getReplaceme
nt(WGLSurfaceData.java:204)
        at sun.java2d.SunGraphics2D.revalidateAll(SunGraphics2D.java:2181)
        at sun.java2d.SunGraphics2D.getCompClip(SunGraphics2D.java:463)
        at sun.java2d.pipe.DrawImage.renderImageCopy(DrawImage.java:463)
        at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:51)
        at sun.java2d.pipe.DrawImage.copyImage(DrawImage.java:876)
        at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:2847)
        at sun.java2d.SunGraphics2D.drawImage(SunGraphics2D.java:2832)
        at Mario.gameLoop(Mario.java:530)
        at Mario.startGame(Mario.java:187)
        at Mario.<init>(Mario.java:120)
        at Mario.main(Mario.java:782)

Any idea why this is happening here? I don’t know why it says BufferedImage cannot be null. I’m using a BufferStrategy; however, all of my images being drawn are BufferedImages. But I checked my images, and none of them are null - and they work fine without setting this property.
When I use the -Dsun.java2d.opengl=True when I launch my game from a .bat file, it works fine - no problem.

By the way, thanks for the information, the property tag for the JNLP works perfect. Also, three buffers has the same tearing problem (as I thought this might be the problem too before I posted).

That’s strange. I can only say check your own code again. If you’re sure its not your code, try it with a different JRE (1.5 vs 1.6) and if it works on one but not the other you know its a bug… and that reminds me - In Java 6 the java 2D OGL pipeline crashes when you switch to fullscreen - Chris Campbell said he’s working on a fix for an upcoming update however. There’s a bug for it somewhere whioch was mentioned here.

Cool, no sweat. Have a look at the other ones I’ve got too which use noddraw (http://www.freewebs.com/commanderkeith/STG/STGnoddraw.jnlp) and directx/3D (http://www.freewebs.com/commanderkeith/STG/STGddraw.jnlp). You may want to try them with your game too.

That’s a pity. Maybe someone could correct me but I think the requirements for page flipping are the following:

  • windows with default or the direct-draw type options
  • full screen mode
  • a 3+ buffered BufferStrategy
  • a video card??

By the way, i just tried your mario webstart game (which is pretty cool!) and saw some flicker & artifacts as if there’s no buffering. That isn’t what you mean by tearing is it?

In Java 6, I don’t have any problems. I tried my game 6 or 7 times straight and never got an exception and it worked great. In Java 5, I tried it once then again and it crashed. Must be a Java 5 bug.

I’ll have to check out your other examples (including the first one) later as I’m having a very annoying WebStart problem here. All of my non-fullscreen WebStart windows are not showing anything in them (like ignore repaint has been turned on and nothing has been painted on the Frame) - the windows are just completely transparent (except the border and title bar). That includes the start up (eg the loading part WS does, and the warning for signed applets).

Well, I know my setup is more than sufficient for page-flipping.

Maybe you tested the old version. If you try it again it should work with the OpenGL pipeline enabled. The tearing was really only visible when the screen was scrolling to follow the player (looked kind of like there was no back buffer only in certain parts of the screen, not the whole screen; mainly on the pipe).

EDIT
That property tag for the JNLP only appears to work with Java 6 WebStart. What can I do to allow Java 5?

Okay, after long and hard brain-storming… I figured out how to prevent the tearing problem (without the need for the OpenGL pipeline). For one, I finally figured out how to actually get page-flipping working. I had to place my buffer.show() inside my FPS limiter if-statement to synchronize the drawing to the refresh rate of the monitor. So now it works great. Thanks for all the help though!