05 October 2017, 02:19 | #1 |
Registered User
Join Date: Mar 2017
Location: Minehead / UK
Posts: 608
|
Double Buffering
So, I've been playing on the PS4 lately but a while ago I went through the C Workshop thread here:
http://eab.abime.net/showthread.php?t=88332 That was fine. Then I started to modify the RenderFrame function to my own needs. I've long since had some code that for me was my equivalent of creating a simple bat and ball type game which was my way of doing a bit of a "Hello World" before i went any further. Except I could never get past this double-buffering hurdle. Allegedly the workshop uses double buffering and timers to switch the buffers. But when I add my code in to it rather than just drawing a nice pattern I can see the edges of the previous location being drawn as though it's not being buffered. The response on the initial thread was "post your code" so here it is: https://www.dropbox.com/s/ui8pve2i5n...kshop.tgz?dl=1 I'm building the code with CMake on Linux using Bebbo's gcc6 port and then running it on OS3.9 / FS-UAE, but it does exactly the same on my original Amiga hardware if I cut and paste and then build in StormC 3. In a nutshell, anyone know what's up? If anything! Cheers, Martin. PS: The application purely draws a "bat" that can be moved in 4 directions with the cursor keys. No more as yet. [EDIT] My CMake toolchain definition might be useful as it contains my compile flags etc. I doubt it's an issue but here it is anyway: Code:
# # toolchain-amigacc6.cmake # SET(CMAKE_SYSTEM_NAME Generic) SET(amigaos ${home}/Amidev/amigaos/m68k-amigaos) # specify the cross compiler SET(gccm68k /home/mart/Amidev/amigaos/bin) SET(CMAKE_C_COMPILER ${gccm68k}/m68k-amigaos-gcc) SET(CMAKE_CXX_COMPILER ${gccm68k}/m68k-amigaos-g++) set(CMAKE_C_FLAGS "-g -O2 -Wall -fomit-frame-pointer") set(CMAKE_CXX_FLAGS "-g -O2 -Wall -fomit-frame-pointer") # where is the target environment SET(CMAKE_FIND_ROOT_PATH ${amigaos}) # search for programs in the build host directories SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # for libraries and headers in the target directories SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) Last edited by MartinW; 05 October 2017 at 02:28. Reason: Added missing content |
05 October 2017, 19:59 | #2 |
Registered User
Join Date: Apr 2015
Location: Kandel, Germany
Posts: 17
|
I've just compiled your code with MaxonC++4 and Storm3 and I don't see the problem.
Anyway, to compile it, I had to make a change: You have defined GfxBase, IntuitionBase and TimerBase in engine.h, which creates those Variables in multiple modules of your project. So I declared them in engine.h with "extern" and defined them in engine.c. The resulting binary works fine to me. You can download the binary here: http://www.kaiiv.de/gfx_workshop Does this binary shows the same effects on your maschines? |
05 October 2017, 21:24 | #3 |
Registered User
Join Date: Mar 2017
Location: Minehead / UK
Posts: 608
|
Thank you very much for taking the time to download and look at my code.
It's been some years since I worked professionally in C so I do get confused at times. Most notably with pointers and includes / header files so thanks for the tip on the includes. Your version certainly exhibits the same behaviour in my emulated 3.9 install. I'm just going to go to where my machines are to try it on real hardware. I'm not sure I've tried either version on a 3.1 install so I'll try that as well as the 3.9. It may well be that there is no problem. But to me it seems when the bat is moving left or right, the leading edge of the bat is very flickery and I can noticeably see multiple frames at once. It's just not very smooth. Clearly line drawing probably isn't the best way to approach this, I'm sure a sprite would be better but I figured a box (4 lines) would be fine. There are other reasons for choosing line drawing too but more of that later if this can be made smooth. Will report back later. |
05 October 2017, 22:19 | #4 |
Registered User
Join Date: Apr 2015
Location: Kandel, Germany
Posts: 17
|
You can try, if a WaitBlit() at the beginning of RenderFrame() improves your situation: it might be possible, that the Blit to the Window's rastport is still in progress when you render a new frame.
|
06 October 2017, 02:02 | #5 |
Registered User
Join Date: Mar 2017
Location: Minehead / UK
Posts: 608
|
OK, so it does the same everywhere. I tried my GBA, my A1200, OS3.9, OS3.1, High Res Laced right down to Low Res. Same result. And adding the WaitBlit doesn't help.
After some playing about it seems that it's down to the number of pixels I'm moving the player each time (the 'step' value). It is currently set to 10 in order to give a reasonably fast movement. If I change this down to 2 the movement is buttery smooth and any flickering at the edges of the bat is gone. But of course this is far too slow for any game. I'm guessing I'm missing a technique or an approach to doing this and probably coming at it completely the wrong way. But I can't help but come back to the fact that I thought the double-buffering was meant to resolve this issue? [EDIT] Interestingly on OS3.1 the keycodes appear to be different. Left and Right go up and down. Up and Down do nothing. Need to verify if the key codes changed or if this is something my end. |
06 October 2017, 16:35 | #6 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,456
|
I looked at your code (though not super-thoroughly so take it as you will). What I can't find is the actual buffer switches. The code seems to call RepaintWindow() to switch buffers, but that function doesn't actually switch buffers - it just blits the contents of the just-updated back-buffer into the window's native buffer.
It's possible that is just too slow to update in time, which would give you screen-tearing or other similar effects. In 'normal' double buffering, the program draws to an invisible buffer and switches this buffer with the shown buffer during vertical blank (assuming it's done in time). That switch should not require any blitting, it should merely update the pointer used by the OS which determines what it is showing to the screen. --- If the code is really using double buffering (and hence I interpreted the loop wrong) be sure it shows the right buffer. It's surprisingly easy to make code that does switch buffers but either does it at the wrong time or does do it at the right time but ends up rendering to the visible buffer by accident. I've certainly made both mistakes more than once. |
06 October 2017, 21:18 | #7 |
Registered User
Join Date: Mar 2017
Location: Minehead / UK
Posts: 608
|
@roondar - you make a good point. I'm not sure I recall the tutorial doing the buffer switch either so I'll take another look through and see if it is or isn't doing it.
Just to clarify, do you literally just mean changing the pointer that is used in methods that require a rasterport / renderport (if that's what it's called, I'm not at that PC at the moment)? I know on my original code from some years back that is exactly what I did and I seem to remember thinking that it was too easy (and it didn't work). But then I wasn't timing it in any way like this workshop is doing. I may need to look for another example but I'm curious as to why I'm the only person that has come back to question this. But maybe I'm the only one so far to have played about with the code and tried to expend it beyond the original status? |
10 October 2017, 21:52 | #8 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,456
|
Sorry for the late reply, but I'm not really an expert on Amiga OS graphics stuff, I tend to use the hardware directly (because I find it more fun). That said, traditional double buffering means swapping the bitmap pointer to the screen between one that is finished and one you are about to draw on. This makes sure no half-way drawn graphics get shown.
However, I'm not all convinced after reading up on the Amiga Window structure that this is what your code does or even can do without some changes. First of all, it blits the update into the window's rastport rather than switch buffers (as I already said). Secondly, it uses the Window->Rport as a destination. Now, I can't easily find wether the rastport pointed to here points to the rastport of the screen buffer or not, but even if it did: I'd say this is not the route you wish to take for double buffering as changing the screen buffer via a pointer to a window could have unpredictable results (meaning I have no idea what poking random structures pointed to by the Window struct will do). My recommendation would be to not use a window at all, but a separate screen and have the OS deal with double buffering for you (by using the OS graphics library for bobs & sprites). AFAIK this can be done since OS 3.0, but I've never tried it myself so can't really help you there. Maybe there are others on the forum with more knowledge. If you do not wish to do this, an alternative -but less OS friendly- way would be to again use a screen and then update the screen bitmap pointer yourself as required. That will probably work, but I'm assuming this isn't really what Commodore had in mind for double buffering support back in the day. Last edited by roondar; 10 October 2017 at 21:54. Reason: Worded something more clearly |
11 October 2017, 00:20 | #9 |
Registered User
Join Date: Mar 2017
Location: Minehead / UK
Posts: 608
|
Hey no problem! Thanks for taking the time I haven't looked at it any more myself as my day job has been keeping me away from the Amiga.
I'm beginning to agree that maybe not using the window might be an easier way. I just need to find some time to dig into it and if I can, find some more examples. |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Latency tests - No difference between "No buffering" and "Double buffering" | Dr.Venom | support.WinUAE | 6 | 24 September 2017 10:18 |
how to display bob correctly with double buffering | Blackgoat | Coders. AMOS | 2 | 15 March 2016 22:10 |
Cons & Pros of buffering vs no buffering | vagrant | support.WinUAE | 9 | 27 February 2016 08:47 |
flawless double buffering | dalton | Coders. General | 2 | 17 May 2011 07:09 |
AGA double buffering using ChangeScreenBuffer() | NovaCoder | Coders. General | 1 | 03 November 2010 00:34 |
|
|