28 March 2014, 12:11 | #1 |
... aka Amix73
Join Date: Jan 2009
Location: Austria
Posts: 87
|
Blitter poly-line draw & filling - the 100th
Hi guys!
In the last weeks I wrecked my brain to make a decent line drawing routine - not that there wouldn't be enough of and very optimized ones already in the thousands - but I wanted my OWN and without help - so to say reinventing my personal wheel . Well I managed it somehow and I happily found a nice solution to simplify the Octant finding by drawing all lines in the same direction thus concentrating on only one halve of the Octants (depending on the coordinate system up or down). Sorry I try to keep it short.... Here are my problem(s): When I then went on to filling - I found out that setting "single-bit" for lines is not enough. I read about EOR drawing mode and shaping the edges and the nice trick omitting the 1st pixel by pointing BLTDPT to a scratch area. Anyway my routine still sucks - have a look - this is what happens if I use the eor edge trick... which leads to the following when filled: WHAT the heck I am doing here? Why are the two edges and ONLY the two edges are shifted to the left!?! I cannot figure it out myself ... Any suggestions? Shall I post my routine or is this a common and boring mistake? I don't get it ... ADDON: BTW I just found out if I draw my polygon without the eor of the edges and fill it - it works??? and I thought I would have understand the eor manipulation of the edges but obviously I totally suck Any hints appreciated, thanks! |
28 March 2014, 22:21 | #2 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
How are you calculating the A shift value and the C pointer? I'm guessing that's where your error is.
The A shift value must be set to X1%16, and the C pointer must point to the word in memory where the first pixel, (X1, Y1), is plotted. |
29 March 2014, 21:44 | #3 | |
... aka Amix73
Join Date: Jan 2009
Location: Austria
Posts: 87
|
Quote:
Code:
move.w d0,d4 ; copy x1 to work with move.w d1,d5 ; 4: copy y1 to work with moveq #planewidth_bytes,d6 mulu d6,d5 ; plane-width in bytes * y1-coordinate add.w d5,a0 ; add vertical offset to plane address lsr.w #3,d4 ; horizontal word-offset [bytes] => div by 8 not 16 andi.w #$fffe,d4 ; and mask out the pixel shift add.w d4,a0 ; correct address ... ; determine the pixel-shift of the start point within the first word ; d0=x1 andi.l #$f,d0 ; det. horizontal pixel-offset for point1 ; the infamous eor trick :D move.w d0,d5 ; copy pixel shift eor.b #$f,d5 ; shape it for filling ror.l #4,d0 ; bring to pos 12-15 for Blitcon0 ... WAITBLT bchg d5,(a0) ; eor trick move.l d3,$62(a6) ; B,A-MOD:2*A, 2*(a-B) move.w d6,$52(a6) ; A-POTH (lo): 2*A-B move.l a0,$48(a6) ; C-POTH move.l a4,$54(a6) ; D-POTH for filling polygons point to scratch move.l d0,$40(a6) ; BLTCON move.w d2,$58(a6) ; BLTSIZE rts But when I remove the EOR-Trick and DON'T draw the first pixel since I set BLTDPT to a scratch area - it works (you can see the filled square in prev. post). Currently it does the following (at least I would like it to): The line-draw mode must be set to EOR as well. the pixel shift is between 0-15 so what one gets with EOR.B $F,d5 is the invert of the pixel shift value in d5 e.g. pix-shift=5 => $A. Then you just bchg this value in the start-word of point-1 which leads to a 0 if the bit was already set (and therefor it will be drawn with the blitter) OR leads to a 1 if the bit was not NOT set (and therefor it will NOT be drawn with the blitter). Where am I wrong? Thanks for your help. |
|
29 March 2014, 22:56 | #4 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Ok, I misunderstood your post at first, but I see now what you mean with the "EOR trick"
The problem is that you're rounding the memory address of the first pixel to an even address. The bchg instruction (and bset, bclr and btst) with memory destination operate on a single byte, so half of the time you're drawing 8 pixels to the left, because the memory address has been rounded. You can just pass the address as it is to the Blitter, it doesn't have to be even. The better solution is the one you've already found: pointing D to a couple of scratch bytes. |
30 March 2014, 11:36 | #5 |
ex. demoscener "Bigmama"
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,637
|
|
31 March 2014, 17:19 | #6 |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
I don't understand what you are doing here. You are drawing the lines using the blitter (in EOR mode) and then also drawing the corner points as well with BCHG? Why would you need to do that?
|
02 April 2014, 20:28 | #7 |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
It's to make sure nothing is plotted on the first scanline covered by the line. It's one of the things you have to do to get a well-formed outline for inversion-filling with the Blitter.
|
02 April 2014, 21:53 | #8 |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
I have written my own blitter 3D engine without doing this, all you need to do is make the line 1 pixel shorter and thereby don't plot anything on the last scanline covered by the line (it makes no difference whether it is the top or bottom point that you omit as long as you're consistent).
|
02 April 2014, 23:11 | #9 |
... aka Amix73
Join Date: Jan 2009
Location: Austria
Posts: 87
|
Thanks guys!
I thought it would make sense when BLTC == BLTDPT to shape the edges but I again fell for the bchg - byte access on memory . Beside that I did not get it to work when I fetched the word into a register, bchg-ed and wrote it back... Pointing BLTDPT to a scratch area does the trick and that works for me for the beginning. Thanks for reading and commenting on this topic. |
02 April 2014, 23:23 | #10 | |
... aka Amix73
Join Date: Jan 2009
Location: Austria
Posts: 87
|
Quote:
What I did is to point BLTDPT to scratch area and draw lines in EOR mode - with SINGLE-Bit set that's all. Attached you find the Amiga executable - to see that there is no bleeding. So at first I though I need to shape the edges but obviously I don't. Drawing the line from the second pixel on does the trick. Last edited by Herpes; 03 April 2014 at 02:03. Reason: not proper English ;-) |
|
03 April 2014, 00:01 | #11 | |
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
Quote:
Because of how the Blitter works, pointing D to a couple of scratch bytes lets us conveniently discard the first scanline it draws, regardless of the direction, slope and length of the line. |
|
03 April 2014, 00:31 | #12 |
Glastonbridge Software
Join Date: Jan 2012
Location: Edinburgh/Scotland
Posts: 2,243
|
you shouldn't change the slope of the line just by reducing BLTSIZE, surely. For four of the octants this is trivial, simply use BLTSIZE = (dmax *64)+2 instead of +66.
|
14 May 2014, 01:34 | #13 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,652
|
Remember that the absolutely simplest case for testing if your linedraw is good enough to be filled is a single polygon where all angles are >=90. That's not to say Herpes' linedraw isn't up to the task, I haven't tested the source.
But there are many test levels up from a single poly, f.ex. a glenz dumbbell consisting of 3 joined convex objects. I might write an article on Coppershade actually |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
CPU Filling vs. Blitter Filling Routine | victim | Coders. General | 18 | 26 January 2014 02:15 |
Clipping line for blitter fill | leonard | Coders. Asm / Hardware | 12 | 27 April 2013 12:03 |
Blitter filling routine used in games | Codetapper | Coders. General | 2 | 26 January 2012 10:20 |
Filling with the blitter... | Lonewolf10 | Coders. Tutorials | 7 | 13 September 2011 14:30 |
Line mode blitter | absence | Coders. General | 4 | 25 September 2009 20:50 |
|
|