17 October 2020, 23:46 | #1 |
Registered User
Join Date: Apr 2020
Location: Kernelville
Posts: 15
|
Help with smooth 3D Cube in C on A500 using Draw() and Move()
As a challenge, I've taken it upon myself to delve into Amiga coding in C and attempt to make a few 3D routines.
Is it possible to create a decently smooth wireframe rotating cube using C that runs on a stock A500? I ask because I've seen [ Show youtube player ] and it seems he's managed to do it using pure C, but I haven't managed to do so yet. In my own attempt, I've tried double buffering (swapping out two bitmaps every frame). The flicker is reduced, but the frame rate is still abysmally slow, something like 1-2 frames per second. Even when I turn off rotation and just have basic horizontal movement, it's slow. On a souped-up UAE config it's smooth though. So I reckon it's nothing to do with the transformation parts, which are integer and use lookup tables for trig functions. I'm using a 320x200 screen with 2 bitplanes. My cube is pretty much self-explanatory: struct node cubeNodes[8] = {{-1, -1, -1},{-1, -1, 1},{-1, 1, -1},{-1, 1, 1},{1, -1, -1},{1, -1, 1},{1, 1, -1},{1, 1, 1}}; struct edge cubeEdges[12] = {{0, 1},{1, 3},{3, 2},{2, 0},{4, 5},{5, 7},{7, 6},{6, 4},{0, 4},{1, 5},{2, 6},{3, 7}}; My bitmap swapper: void swapBitmap(){ where rp is the RastPort and ri is RastInfo. My copper list updater: void updateCopperLists() { and finally, my draw routine which basically iterates through the object edges and does a Move() on the first vertex and a Draw() on the second vertex. On entry it swaps in the bitmap on which it'll draw on, and prior to exit updates the copper list so the bitmap is shown: swapBitmap(); FWIW I've also tried starting the main code with Forbid() and Disable() but it doesn't help speed up in any measurable sense. Anyone has any tips? Maybe it's something I'm overlooking? I'm pretty new to coding for the Amiga but I'd love to keep at it and get better as I've always wanted to code my own demo routines that can run on a bog standard A500. I'd like to move on to assembler later on, but first I'd like to be able to hash it out in C. |
18 October 2020, 08:32 | #2 |
<optimized out>
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
|
I think your updateCopperLists function may be doing more than it needs to. I don't think you should be calling MrgCop on every buffer flip. This example http://amigadev.elowar.com/read/ADCD.../node05B3.html certainly looks like it does less.
I have used the second method described here http://amigadev.elowar.com/read/ADCD.../node0346.html with success before, but can't find my code at the moment to demonstrate. Last edited by Ernst Blofeld; 18 October 2020 at 08:46. |
18 October 2020, 15:57 | #3 |
Total Chaos forever!
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
|
The OS routines are abysmally slow. Interface directly with the hardware for a massive speed boost.
|
18 October 2020, 21:52 | #4 | ||
Registered User
Join Date: Apr 2020
Location: Kernelville
Posts: 15
|
Quote:
Quote:
|
||
18 October 2020, 21:55 | #5 |
Registered User
Join Date: Apr 2020
Location: Kernelville
Posts: 15
|
|
18 October 2020, 22:13 | #6 | |
<optimized out>
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
|
Quote:
|
|
19 October 2020, 01:44 | #7 |
Total Chaos forever!
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
|
If you're using more than 2 bits per pixel, reduce the palette depth. This will speed up the blitter by freeing up bandwidth used by the display DMA. You should only need 3 foreground colors to draw a cube.
|
19 October 2020, 09:05 | #8 |
<optimized out>
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
|
Looking at the youtube clip, he's not doing half the work you are. He's drawing into a single bitplane, probably clearing only the bits he's touched, and probably not using double buffering as he can probably sync with the display as he's drawing so little. I'm sure you can get your stuff to be smoother once you've worked out where the time is going, but I wouldn't compare to his.
You may want to check out the bartman gcc vs-code stuff that will allow you to profile in a modernish way. Last edited by Ernst Blofeld; 19 October 2020 at 18:01. |
19 October 2020, 15:48 | #9 |
Total Chaos forever!
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
|
Looking at the YouTube clip there are 2 playfields at 1 bitplane each. The Copper work is best done only once. A double-buffered one bitplane screen is easy when there are only 2 copper lists. The copper does all the bitplane changes too.
|
19 October 2020, 22:52 | #10 | |||
Registered User
Join Date: Apr 2020
Location: Kernelville
Posts: 15
|
Quote:
Quote:
Quote:
Thanks for all the insight, I appreciate it a lot! |
|||
20 October 2020, 03:27 | #11 |
<optimized out>
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
|
|
27 October 2020, 14:04 | #12 | |
Registered User
Join Date: Apr 2020
Location: Kernelville
Posts: 15
|
Quote:
Anyway, that function was the culprit. I was doing some math with doubles and that killed the speed. I changed it over to integer math and everything is way, way faster now and smooth as butter. Here are some stats: Screen is 320x256, 1 bitplane, 1 cube scaling, rotating and moving across the screen. (A) Single buffer, no WaitTOF(): 30-31 with flicker (B) Single buffer, 1 WaitTOF(): 25 fps solid with flicker (C) Single buffer, 2 WaitTOF(): 16-17 fps with flicker (D) Double buffer, no WaitTOF(): 30-31 without flicker (E) Double buffer, 1 WaitTOF(): 25 fps solid without flicker (F) Double buffer, 2 WaitTOF(): 16-17 fps without flicker So out of the lot, D seems great. I guess B and E are at a constant 25 fps due to the WaitTOF() limiting refreshes. Using 2 WaitTOF()'s decreases performance and is not required since I'm not using interlaced modes. And without any work (no cube drawing and transformations): (G) Single buffer, no WaitTOF(): 357 fps (H) Single buffer, 1 WaitTOF(): 50 fps (I) Single buffer, 2 WaitTOF(): 25 fps (J) Double buffer, no WaitTOF(): 336 fps (K) Double buffer, 1 WaitTOF(): 50 fps (L) Double buffer, 2 WaitTOF(): 25 fps For the double buffer swapper, all I do is set the LOFCprList, SHFCprList, RastInfo and RastPort bitmaps and then do a LoadView() (no MakeVPort() and MrgCop()). |
|
27 October 2020, 14:32 | #13 |
Total Chaos forever!
Join Date: Aug 2007
Location: Waterville, MN, USA
Age: 49
Posts: 2,186
|
Beam sync with WaitTOF can free up some processor time for other functions because, unlike PC, vertical blank triggers an interrupt on Amiga.
|
27 October 2020, 16:07 | #14 |
<optimized out>
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Cube 68k | arti | support.Games | 41 | 03 December 2019 16:53 |
Rotating cube getting cutoff | Knocker | Coders. Asm / Hardware | 2 | 07 September 2016 08:13 |
Amiga Cube? | fondpondforever | Amiga scene | 3 | 25 June 2015 08:40 |
Move it Move it... (68000) | Gilloo | Coders. Asm / Hardware | 19 | 04 December 2011 17:36 |
Speccy on a cube | daznic | Retrogaming General Discussion | 1 | 03 June 2009 19:44 |
|
|