Flip

BlitzMax Forums/BlitzMax Programming/Flip

Mordax_Praetorian(Posted 2006) [#1]
I need to rig up a replacement for the Flip command that will just copy the back buffer to the front without modifying whats on the back buffer at all

Unfortunatly I cant find a way to directly affect the front buffer at all, and this is hampering my efforts

Any help would be apreciated


Dreamora(Posted 2006) [#2]
You can't.
BlitzMax is 3D only and 3d needs switch of buffers.

The only way to "can so" would be writting direct api functions to do so, ie not BM commands or something the like.


H&K(Posted 2006) [#3]
What you can do, is fake tripple buffer. Copy the backbuffer to an image before flip, then flip, then copy the image back to the new backbuffer


Mordax_Praetorian(Posted 2006) [#4]
Right'o

I had that before as a temporery fix but if thats the only way to do it then I guess I'll stick with it


Mordax_Praetorian(Posted 2006) [#5]
Ok, this simply isnt working

I swapped my engine over to only redrawing what was new from the last update yesterday in order to increase performance to an acceptable level

This works fine in windowed mode, where as far as I can tell the back buffer isnt affected by Flip, however in Full Screen mode it is

I implimented the image solution, and asked here before testing it in full screen mode, I just did that and it makes the whole thing run like treacle, even on my reasonably powered PC

How on earth do you impliment this solution without the immense slowdown of grabbing and drawing the entire screen as an image everytime anything on the screen needs to update?


H&K(Posted 2006) [#6]
Thats the way it is Im afraid.
When you flip you cannot be sure that the backbuffers are going to be in the same place, so you normaly do a CLS, if you are doing my sudgestion, then you dont need a cls, which will speed it a bit.

But I would expect at min you to be able to do 2000 of these draws each second, on a good modern system


TartanTangerine (was Indiepath)(Posted 2006) [#7]
I've implemented a system like this for BMAX (on all platforms in windowed and fullscreen, openGL and DirectX), it only Flips the areas of the screen that changed since the last Flip. It was developed for my software render module but does provide a nifty little speed up for other games where there is not too much happening at once. Just don't expect it to increase your FPS when more than 50% of the screen needs constant updates.

Email me if you want the code but beware that I have neither the time or the inclination to support it.

Tim.


Mordax_Praetorian(Posted 2006) [#8]
*sigh* Where oh where did gaming go so wrong?

I dont care about fluffy 3D effects, I want a game that plays well, even with a system that offers such immense programming power and "speed" I'm still stuck with putting up with gameplay crippeling crap for a few useless graphical tweaks

I dont allow the tools I use to affect the shape of my work, they do not determine the finished product, if the tools offer resistance I simply beat them until they produce exactly the shape I want, it is and always will be my will alone that affects the shape of my work regardless of the tool

Thus I will find a new way of doing this with as little affect on speed as possible

Of course, since I know how to do it in windowed mode, I could simply sacrifice full screen and go with it, but I invisioned my work in full screen and throwing it away would be allowing the tools to affect the shape of the work, none the less I would be doing that if worst comes to worst

Indepeth: That sounds like a good place to start, ty for the offer


H&K(Posted 2006) [#9]
Well...... I use windowed mode, but my window has no boarders and is ingame calculated to be the same size as the screen. With a full canvas on top. In essence you dont realise that is a window. It looks that a fullscreen


Mordax_Praetorian(Posted 2006) [#10]
Indepath I cant find your E-Mail address

If you could either post it here, or throw me an E-Mail at <removed> I can get the address that way


TartanTangerine (was Indiepath)(Posted 2006) [#11]
sent email, you might want to remove your email now.


Mordax_Praetorian(Posted 2006) [#12]
done

thanks in advance


TartanTangerine (was Indiepath)(Posted 2006) [#13]
Actually you can grab the code here (in unoptimised form) : http://modules.indiepath.com/forum/viewtopic.php?t=40


ImaginaryHuman(Posted 2006) [#14]
You don't have to use the standard form of Flip(), you can do the timing yourself (except perhaps the vertical blank sync) and then do something like glCopyPixels() to copy from the backbuffer to the front buffer without EVER actually flipping buffers at all. Without vsync you may notice tearing, though, and this may not always work on all platforms. Reason being that on some computers with certain o/s versions or certain GL drivers, the understanding of what is the front buffer and what is the back buffer becomes totally confused and beyond access from BlitzMax to figure it out. On my old iBook for example this is the case - you can't tell opengl to use the backbuffer, or the front buffer, because the o/s seems to have its own idea about which is which, whether they are swapped, or what is being viewed. The only thing you can be sure of is that drawing starts with the backbuffer before any flips occur. After that it's anyone's game. But that said, this wouldn't matter if you never do an official flip and just do a copypixels.

Also to clarify, the reason for doublebuffering has nothing to do with whether the display is 3d or not. It's simply to hide drawing process until the frame is complete so the user doesn't see things being drawn while the graphics card is showing the pixels. It doesn't matter if you're doing 2d or 3d.


Mordax_Praetorian(Posted 2006) [#15]
glCopyPixels?

So there IS an alternative then, but I'm guessing the "gl" part means that it wont work in DX mode

I had a brainwave while eating dinner just now for another method of my own, but the problems you stated with GL drivers probably mean it wont work in GL mode

Thus, it seems that I have been presented with 2 seperate methods for the 2 seperate systems

Heres what I thought of for DX mode

Instead of having DirtyRects, one has "DirtyObjects", you need 2 things for this:
1) Everything that can be displayed on the screen has an int variable asociated with it, lets call it Updt for now
2) A global int, lets call it UpdtAll

Everytime your program decides that an objects status on the screen needs updating, it sets the Updt int to a value of 2
Every time you clear the screen, or otherwise need everything drawn for whatever reason, you set UpdtAll to 2

As your drawing routines check each object, they do not draw it if its Updt is zero, and after drawing they reduce Updt by 1, unless UpdtAll is above zero in which case it draws everything

At the end of the draw routines, if UpdtAll is above zero, 1 is subtracted from its value

This gives everything that could update a memory of 2 updates, thus when you flip the screen and the old unupdated screen comes back, all past updates are repeated and everything should thus be happy and fast

What do you guys think?


TartanTangerine (was Indiepath)(Posted 2006) [#16]
IT won't work :(

The reason for using Rects is so that we can identify what regions of the screen need updating as a result of an object changing the display. What your idea fails to account for is that when object 1 intersects object 2 then both will need updating. Now consider that object 2 also intersects objects 3,4 & 5 - will you update these also? How will your system identify them?


Mordax_Praetorian(Posted 2006) [#17]
In my own engine, this is thankfuly quite possible as everything is drawn on a background of 32*32 pixel tiles so:

Object 1 needs to update
It detects what tiles are underneith it (because the objects all work on the same co-ord system the tiles do, and remember their size) and those tiles are told to draw as well
All other objects that use those tiles also have to redraw

I have the systems for detecting all this stuff optimised already, so it seems like the best solution, but outside of that I can see that the solution would be quite limited

I would simply go with the rectangle solution, however it would probably take me days to understand the code and this way I get to develop something new that might help out quite a few people


ImaginaryHuman(Posted 2006) [#18]
Yah glCopyPixels() is OpenGL only. Surely there is something similar to copy between buffers in DX.


Mordax_Praetorian(Posted 2006) [#19]
How does one use glCopyPixels()? There doesnt seem to be any documentation for it, and although I found the source code for it, it confuses me a lot

Also, I implimented my DX solution and it works like a charm, first time I tested it I went right through the stress testing routine I scripted and didnt even realise that Debug Mode was on, I just hope it works on comps other than my own, but my Alpha Testing Team will be seeing to that tonight


Dreamora(Posted 2006) [#20]
glCopyPixels is an OpenGL function not a BM one so you will need to read the OpenGL documentations


Mordax_Praetorian(Posted 2006) [#21]
ok, I will go have a look, thanks


tonyg(Posted 2006) [#22]
Certainly not tested :
Graphics 640,480
image:TImage=LoadImage("max.png")
DrawImage image,0,0
tg_flip(0,0,100,100)
WaitKey()
Function tg_flip(sx:Int,sy:Int,ex:Int,ey:Int)
	Local src[]=[sx,sy,ex,ey]
	Local dest[]=[sx,sy,ex,ey]
	primarydevice.PrimarySurface.Blt dest,primarydevice.BackBuffer,src,0,Null
End Function

<edit> for DX obviously.


Mordax_Praetorian(Posted 2006) [#23]
Well, I implimented my method into my engine and sent a test build to my alpha testers

Reports indicate that the system runs flawlessly, and uber-quickly on pretty much all windows systems

Not had any linux testers get back to me yet