VSync

I know this has been asked multiple times but does anyone know if there is a way yet to synchronize to the VSYNC pulse for Java2D. There is simply no way to get smooth motion without it and I can’t find any information on how to do it.
I found some references to an API being added in 7 but nothing on the API itself. Is there anything in JavaFX?

People on the internet, including me, recommend to just use a BufferStrategy.

If you want to have “smooth motion” in terms of an FPS cap, you need to search for game loops. There is awesome stuff around there.

I am using a BufferStrategy, it doesn’t help because the show() doesn’t wait for the vsync, so it’s very easy to get 1 frame displayed twice and then a frame skipped on the next cycle. Missing a single frame is actually quite noticeable.

The only way to get properly smooth motion is to have 1 frame per monitor refresh any other way looks glitchy.

Since you also asked for JavaFX, googleing gave me this:
http://hg.openjdk.java.net/jdk7/2d/jdk/file/a389af17df10/src/share/classes/sun/java2d/pipe/hw/ExtendedBufferCapabilities.java

(Mentioned in one of our threads…)

I saw that but note it’s in the sun namespace so not officially part of the JDK. I assume it’s something you can enable with vm args.

Oh… okey…

No clue then :persecutioncomplex: :-\

I’ve been waiting for quite some time for the equivalent of javascript requestAnimationFrame() but nobody seems to care that much about it for Java2D. Hopefully JavaFX takes off and it becomes important enough to add. If anyone doesn’t realize why it matters I suggest having a browse at: http://www.jankfree.com/

So I tried the ExtendedBufferCapabilities and it works like a charm, beautiful smooth movement, so I think I’ll just wrap it in some exception handling and hope it makes it into Java 8.

Edit: Unfortunately it only works if my laptop is using an external monitor… In fact the createBufferStrategy with page flipping doesn’t work either in this case (throws the same AWTException), :frowning:

I think you should just go on and create a capped game loop. In java2D there currently is no equivalent of the “requestAnimationFrame()”… You have to code the game loop yourself and you seem to be experienced enough.

If you want to get an idea, or just want a solution of a working game loop, have a look at my utilities.

Also, there should be no problem with the missing vsync, since you’ve got double buffering, which should eliminate all artifacts.

Artifacts (like tearing) are not the problem. The problem is to achieve smooth motion VSYNC is essential.

Say you have a character moving across the screen at 1 pixel per frame. You have no idea when the frame will be actually be displayed it could be up to 16ms (at 60 Hz) from the point you calculate it. So even though you might create a series of frames with positions 1,2,3,4,5,6 they could be displayed like 1,2,2,4,5,5,6 depending on the relative timing of the show() and the vsync.

People don’t tend realize how much of a difference it makes until they see the same thing done right. Done wrong it just looks a bit amateurish but you can’t quite put your finger on the problem. The second you see it done properly it just looks so much better.

For a good explanation (and why vsync is the only real solution) of the problem I suggest watching:

hAzhayTnhEI

hmmm…if you are referring to the very jerky motion when you move an object slow in java2D that is because it does everything in ints. It can only ever move something by and int wich means you can’t get really smooth movement slower then 1 pixel.

I have never had any issues using double buffering and not getting perfectly smooth motion that is not less then 1 pixel per frame.

Also, I don’t think anyone really has the time to go and watch an hour long video hoping to find wth your are talking about. Maybe you have like amazing eyes or something because I really have never seen these “artifacts” you are talking about when properly double buffering.

So it seems you are very experienced.

Then try out either LWJGL or JogAmp.
Both being a wrapper for opengl, and both giving you the ability to do VSync.

Which one is better? I don’t want to start the thousandth flamewar, so here I try to be objective:

LWJGL is pretty much based on static stuff. Princec says that this would make more sense, since OpenGL is written “static” too.
The windowing system is also static and very very easy. So you only have to say “Display.create()” and initialize some gl stuff (which you could leave out, but you better don’t) and you’re ready to draw stuff. Then call “Display.update()”, and if you want you can use “Display.setVSyncEnabled(true);” so you have vsyncing when you call “Display.update()”.
One big contra: You can’t have two Displays in lwjgl, since its pretty much static stuff.
Summed up: LWJGL is very very very easy to use and learn, you could copy code directly from C to Java and it would almost work. It gives you only one window, but this shouldn’t be the problem for a game.

JogAmp consists of “JOGL” (openGL stuff), “JOAL” (openAL stuff) “JOCL” (openCL stuff) and propably some more I don’t know of, but these are the most important. (LWJGL gives OpenGL, OpenCL and OpenAL wrappes as well)
JogAmp is more Object.oriented, which means you can instantiate “GL” or “GL2” or whatever and use it for doing OpenGL stuff.
It allows you to have multiple windows and already gives you a pretty good GameLoop / Rendering loop. It as also allows you VSyncing.
You can use AWT or NEWT (their own windowing toolkit) to create windows and render with OpenGL.
And it gives you some little helpful helper-classes, like a wrapper around the Framebuffer api, called “Framebuffer”…
And more of the above example.

I hope I didn’t miss a point.

[quote]Also, I don’t think anyone really has the time to go and watch an hour long video hoping to find wth your are talking about. Maybe you have like amazing eyes or something because I really have never seen these “artifacts” you are talking about when properly double buffering.
[/quote]
Most of the relevant information about the problem is is in the first 10 minutes or so. The rest about profiling in chrome.

[quote]hmmm…if you are referring to the very jerky motion when you move an object slow in java2D that is because it does everything in ints.
[/quote]
No Java2D uses doubles and you can turn on different interpolation modes to get sub-pixel image interpolation, however this doesn’t really help unless you are updating at much higher rate than the refresh rate of the monitor. If you update at 300fps moving objects by very small amounts each time your positions will only be out by ~3ms which is probably not noticeable. The downside of this 4/5 of the frames you generate are never shown so it’s a pretty massive waste of CPU. Also this doesn’t work with up-scaled pixel art type graphics (the type I am doing at the moment) as you are typically moving objects ~ at 1/2 pixels per frame and can’t use sub-pixels.

[quote]Then try out either LWJGL or JogAmp.
[/quote]
I would prefer not to do this because it does impose a number of barriers to people trying my game, but it may be the only option. One downside is that setVSyncEnabled is not guaranteed to work either so it may not be much help.

An option I was considering was using javascript to call requestAnimationFrame() and drive each new frame from the browser itself but I’m not sure how reliable this would be or how much overhead it would create

I guess this would be VERY slow.

I really suggest to use an OpenGL wrapper, since this is lighting-fast and I don’t see where there would be barriers for the users. There is almost no succsessful java game out there written with Java2D. Everyone uses OpenGL.

You could also go on and try out some engines, as for example Slick2D (remember not to download it from the site, but from bitbucket), libGDX or the JRabbit engine. We have guys here who could help you with each of them, for example:
Slick2D: davedes, kevglass (but he is somehow not active)
libGDX: Nate and badlogicgames
JRabbit: CodeBunny (who is inactive right now too :frowning: According to profile: Last active 3 days ago…)

Could you seriously post an example of what you are talking about? I know what vsycn does and the biggest thing is screen tearing.

And java2D can use double but when you want to draw anything, it takes ints. Even if it uses double under the hood, the fact is, you can’t pass in doubles to the render methods. I also have played around with the different interpolation methods, most of which have to do with image filtering. I am talking about the ones you set in the graphics object. Java gives jerky movement when you move small amounts. I can give you an example of what I am talking about if you would like.

All the Graphics2D methods take double precision values and there is a full set of double precision Shape objects for the draw(Shape) method. Even if you stuck to the regular Graphics calls that take ints you can use the Graphics2D double precision translate to draw at floating point coordinates.

I think I might try to mock up a quick example applet to demonstrate the problem (and test how often ExtendedBufferCapabilities is available).

the performance hit for translate is ridiculous.

http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html

http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics2D.html

Yes you can draw shapes with doubles but most people draw sprites…images which still take ints.

So I tried using JavaFX and AnimationTimer as it appeared a likely candidate (you don’t specify the time delta) and it worked perfectly, vsync at last. Like requestAnimationFrame() you get one call per monitor refresh (verified by changing the refresh rate) and animation looks lovely and smooth!
Hopefully it’s fairly cross platform and works the same way in a browser plugin.

I am still using Java2D to draw my scene to a buffer and copying it to a JavaFX WriteableImage every frame. Not particularly efficient but better than running at 300fps.

That’s great! Thanks for the info shannon