Advice on Triple Buffering

Miscellaneous Forums/General Discussion/Advice on Triple Buffering

I recently implemented some triple buffering in a game I'm making in Blitz Plus i.e. draw everything to an image in memory (not on the video card) and then call Drawblock to copy it all to the video card. This allows me to use ReadPixelFast on the image in memory for cool effects like transparency etc. and it works about 5 times faster than if I use ReadPixelFast on the Backbuffer.

Problem is that all the standard blitz functions like DrawBlock and DrawImage seem to be much slower in memory than when they are used on the BackBuffer. This means that the draw routine in my game has gone from 5ms to 20ms on an Athlon 1GHz i.e. around 4 times slower! This makes the game drop from silky smooth >60FPS to half that i.e. around 30FPS and this has a noticable effect on the animations and mouse pointer movement.

I tried writing my own draw block function with WritePixelFast but it was WAY too slow even though it was just locking the buffer, looping and unlocking.

So my quesiton is should I a) keep the triple buffer and really make use of it with some cool effects, but up the min system specs to 2GHz or b) restore the old straight to BackBuffer code and allow 1GHz (and less) users to play the game? or c) something else amazing that I don't know yet?!

You see my dilemma, logic would say, the more PCs that can play it, the bigger the market = more sales but it may not look as cool and thus sales could be lost.

Btw, buying BlitzMax and recoding it all is not an option at this point, but the next game WILL be in Max as I'm fed up with software rendering being so slow.

It has been suggested by Indiepath to use a dirty rects method, i.e. only draw the bits that have change but to do this you have to store the background behind the thing you are drawing so that it can be replaced the next frame. This means twice as much drawing for every object and if you have a lot of objects all moving at once, it could be slower than my brute force method of DrawBlock the background and then draw everything on it. Unless I'm missing something here?

Any suggestions (or flames ;-) are really appreciated.
Thanks in advance.

P.S. I've put this in General Discussion because, although I'm using Blitz Plus, I think that the concept of raising min spec for better effects and alienating users is a general discussion point.

Do both methods and have it as a configurable option within the game.

Can't you do transparency effects by using the 3D hardware instead of brute forcing a Read/WritePixelFast method? Better to get the GPU doing some work rather than the CPU.

If you plan on selling it, then you need to ensure it runs on as much hardware as possible to maximize your potential market (means lower spec is better). So either implement a dirty rect way of dealing with the screen, or convert it back to hardware. Re-thinking those effects where needed.

Does also kind of matter as to what type of game this is as well. For example, if its a game for all audiences, then def go the low spec way. If its a game for hard-core gamers, you could get away with upping the specs a little.

Grey, I thought all created images are stored in VRAM. It certainly seems to be the case using the 2D command set in blitz3D. Is blitz+ different?

However, I have experienced a huge slowdown when creating images that won't fit into VRAM, so are paged out to AGP system RAM. The constant swapping in-and-out of the image slows things terribly. Could this be an issue in your case?

Thanks for ideas guys:

Vinyl: could do an option (turn off eye candy) but have to code and test everything twice (bummer). Can't use the 3D hardware in BlitzPlus AND this limits user base of course AND 3D hardware can have dramtically different performance.

Shagwana: As ame is puzzle game not hardcore gamer game, you are probably right about maximising market (I know this at my business hard but my techie side wants to keep the cool effects, sigh)

Big10p: In BlitzPLus when you create an image, you can specify a flag on the end, it has 3 settings, the two important settings are 1 - managed (i.e. in system memory so it won't corrupt on alt+tab) 2 - dynamic (on video card so fast but will corrup on alt+tab, so I very rarely use this).

Basically all my images are in memory and there is only a single copy to the Backbuffer (video card) at one point thus minimise the traffic to/from the video card. In fact there is none from the the video card at all now as all ReadPixelFast commands are done to the 3rd buffer (memory image).

Any more?

It has been suggested by Indiepath to use a dirty rects method, i.e. only draw the bits that have change but to do this you have to store the background behind the thing you are drawing so that it can be replaced the next frame. This means twice as much drawing for every object and if you have a lot of objects all moving at once, it could be slower than my brute force method of DrawBlock the background and then draw everything on it. Unless I'm missing something here?

1) Don't redraw all the background each frame, only draw the parts of the background that have are covered by a dirty rect.
2) Don't redraw the whole of an image, only draw the parts of the image (if any) that are within a Dirty Rect.

Here's my workflow

1) Do all image movements and animations etc.
2) If image is different to last frame then mark the image area as dirty (cycle through all visible images)
3) Merge all DirtyRects (so there is no overlapping)
4) Draw background, but only parts that are within DirtyRects, this is easy - just cycle through the dirtyrects and use DrawImageRect bgImage,0,0,Dirty_rect_x,Dirty_rect_y,Dirty_rect_width,Dirty_rect_height
5) Cycle through all images and draw the parts that are within dirty rects, if at all.
6) Flip
7) Clear All dirtyRects and loop to 1.

* I wish I had a copy of B+ and I could do some code for you.

Isn't using CopyRect faster than DrawBlock? Or doesn't that work on images stored in system RAM?

Sorry Grey, it didn't register that you were using B+.

I would have kept my opinion to myself otherwise ;) (see my sig for details).

Hmm Copyrect, I'll check it out. Draw block is very fast but DrawImage is slower as it uses a transparency mask.

Tim: Yeah thanks, that's how I thought it worked, when I said "store the background" I was talking about behind each individual object. As my background is a full-screen image anyway, I should be able to use Copy rect to update the dirty rect areas. The idea of only drawing part of an image/object if need be is interesting but to be honest it probably won't occur much as when a sprite moves, you need to redraw it all. I think I might give this system a go and see what I can come up with. Yet another technical problem to delay development, sigh.

Lol, have a look at the BMAX code I emailed you, it's all there.

will do.