Vsync in Flex/Flash/AS3?
Asked Answered
B

3

9

I work on a 2D shooter game with lots of moving objects on the screen (bullets etc).

I use BitmapData.copyPixels(...) to render entire screen to a buffer:BitmapData. Then I "copyPixels" from "buffer" to screen:BitmapData. The framerate is 60.

private var bitmap:Bitmap = new Bitmap();
private var buffer:Bitmap = new Bitmap();

private function start():void {
    addChild(bitmap);
}

private function onEnterFrame():void {
    // render into "buffer"
    // copy "buffer" -> "bitmap"
}

The problem is that the sprites are tearing apart: some part of a sprite got shifted horizontally.

It looks like a PC game with VSYNC turned off.

Did anyone solve this problem?

UPDATE: the question is not about performance, but about getting rid of screen tearing.

[!] UPDATE: I've created another question and here you may try both implementations: using Flash way or BitmapData+copyPixels()

Berceuse answered 12/6, 2009 at 23:13 Comment(4)
the others are right, that this approach isn't very suitable for flash player ... still, i'm amazed, it doesn't work at all ... few questions: - did you try to lock the bitmapData you are drawing into? (if not, this may help a lot!) - are you using transparent bitmaps? (general performance killer) - dir you try Stage::invalidate and rendering on Event.RENDER instead of rendering? greetz back2dosLanyard
- lock/unlock didn't help because copying "buffer" -> "bitmap" produces single event, so it is same single notification in both cases - I do use transparent bitmaps for projectiles - but, again, the problem is not in performance, the problem is in screen tearing - I tried to: * prepare "buffer" + stage.invalidate() in ENTER_EVENT and then * copy "buffer" -> "bitmap" in RENDER event Same result (screen tearing), but higher CPU consumption(I guess because it is because of events fired by stage.invalidate() )Berceuse
Screen tearing is related to performance. That's the only way to fix your tearing.Brookins
@Brookins I can't agree. Performance has nothing to do with screen tearing, because I use double-buffer. In case of poor performance I would get lower FPS but not screen tearing.Berceuse
M
7

I feel your pain as I'm currently in the trenches developing my own game. At default settings, the Flash renderer produces horrible screen tearing / v-sync issues, regardless of what code you produce.

This is why I was pleased to have found the most simple, elegant answer, that wasn't re-factoring code (which doesn't help a single bit, the problem is the Flash player, not code).

Just enable Hardware Acceleration in your Publish Settings. There's two different options:

Level 1: Direct; and Level 2: GPU.

Read more about it at the official documentation: Specify publish settings for SWF files, and decide what option is best for your game.

Target market does play a factor here, if it's a serious game for gamers, you don't need to worry about possible performance issues, as most gamers have GPU's.

This article did not provide me with the solution specifically, but lead me in the right direction. BUT, if your game is going to be in a browser window, you might have to use the same technique of setting wmode to direct or gpu as well.

Mellicent answered 14/3, 2010 at 22:42 Comment(6)
Do you happen to know if there's a metadata tag attribute that can be specified for that? (For FlashDevelop AS-only games, without FLAs). Something along the lines: [SWF(hardwareAcc="gpu")] does that exists?Magistrate
The only other parameter I know of is wmode, which can be set in the html file embedding your Flash file. I'm sure there must be something that can achieve this without the Flash IDE.Mellicent
What's the conclusion? This is really a Flash player's problem and we can't do anything to improve it?Grover
Well, yes and no. Without enabling some kind of hardware acceleration in Flash, screen tearing will occur. If you enable it, Flash will render fine.Mellicent
Even with some hardware rendering, tearing can still occur. I tried it using Context3D at 60fps with context.clear(random color). Tearing still occurs, albeit a little bit better than before where it was really obvious.Laurenlaurena
active.tutsplus.com/tutorials/animation/… really helped me. Tells you to set wmode to direct in your html.Fulfil
B
-4

First thing you might want to do is stop treating the Flash Player like it is DOS. The Flash Player is a highly optimized 2D game engine as it is and I don't really understand why you are trying to reinvent the wheel by copying lots of bitmap slices around. Of course you will have performance issues.

The Flash Player doesn't let you sync to any vertical or horizontal blank because the Flash Player simply doesn't have any concept of this.

I personally think that you should rethink you approach if you want 'smoother' animation. The Flash Player is certainly capable of this, you're just trying the wrong approach.

Boggart answered 12/6, 2009 at 23:21 Comment(3)
Strange thing, copying chucks of bytes (bitmaps) in memory should be easier for computer rather than rendering it with math calculations. There should be a reason why "cacheAsBitmap" exist in Flash. Also, check this: aralbalkan.com/759Berceuse
Your Sprites (DisplayObject's) do not have to be vector at all. The Flash Player is optimized to deal with this. When you start to recreate in ActionScript with bitmaps what the Flash Player already does very well and is optimized for, then you're just missing the point. I think you should read more of Tinic Uro blog: kaourantin.netBoggart
@Luke: Your answer would be more useful if it suggested a practical alternative, rather than just saying the original approach is wrong. There are several sources online suggesting the use of bitmaps and copyToPixels in the context of making 2D games so it's not the original poster who's doing the reinventing.Improvised
B
-5

Don't save things to BitmapData, that will kill, absolutely kill your app. Bitmap Data is not very performant.

Make all your game elements in flash, as Sprites(or MovieClips if you must), and then work how flash was meant to work, as a vector animation platform. It was never optimized for 2d bitmap graphics. 2d vector graphics work well, and even if you import bitmaps they will work better moving around then they will rendered to a BitmapData object.

Brookins answered 12/6, 2009 at 23:25 Comment(4)
If I'll give up with buffering and add bitmaps as native Flash sprites (still bitmaps), then will it solve the VSYNC problem?Berceuse
No it won't. But it will look far better than what you currently have. As I said in my answer to your question, the Flash Player has no concept of vsync. When you set the fps to 60 (which is absurd but that's beside the point) then the Flash Player will TRY to generate 60 fps. In reality it will almost never accomplish this.Boggart
I've found there are defininitely times you should use Bitmapdata for performance improvement.Objectify
@Matt But your entire app, rendered in a BitmapData object every frame? This is seriously a bad idea. I'm not saying BitmapData is not useful.Brookins

© 2022 - 2024 — McMap. All rights reserved.