English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. Asm / Hardware (https://eab.abime.net/forumdisplay.php?f=112)
-   -   Blitter poly-line draw & filling - the 100th (https://eab.abime.net/showthread.php?t=73110)

Herpes 28 March 2014 12:11

Blitter poly-line draw & filling - the 100th
 
4 Attachment(s)
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 :D. 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...
http://eab.abime.net/attachment.php?...1&d=1396003993

which leads to the following when filled:
http://eab.abime.net/attachment.php?...1&d=1396004000

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 ...:banghead

ADDON: BTW I just found out if I draw my polygon without the eor of the edges and fill it - it works??? :confused
http://eab.abime.net/attachment.php?...1&d=1396004008 and http://eab.abime.net/attachment.php?...1&d=1396004016

I thought I would have understand the eor manipulation of the edges but obviously I totally suck :D

Any hints appreciated, thanks!

Leffmann 28 March 2014 22:21

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.

Herpes 29 March 2014 21:44

Quote:

Originally Posted by Leffmann (Post 946522)
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.

Hm, well I think these computations are correct. I appreciate your help since I got stuck. I add some code - maybe you see my error at once.

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

It is evident, that the eor trick - does not work properly - most likely understood it wrong.

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.

Leffmann 29 March 2014 22:56

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.

hooverphonique 30 March 2014 11:36

Quote:

Originally Posted by Herpes (Post 946435)
ADDON: BTW I just found out if I draw my polygon without the eor of the edges and fill it - it works??? :confused

that is pure coincidence, because your lines are too vertical.. try changing the angle of the box so some lines are closer to being horizontal ;)

Mrs Beanbag 31 March 2014 17:19

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?

Leffmann 02 April 2014 20:28

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.

Mrs Beanbag 02 April 2014 21:53

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).

Herpes 02 April 2014 23:11

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 :bash.
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.

Herpes 02 April 2014 23:23

1 Attachment(s)
Quote:

Originally Posted by hooverphonique (Post 946673)
that is pure coincidence, because your lines are too vertical.. try changing the angle of the box so some lines are closer to being horizontal ;)

Hm, not sure what you mean - I zoom a square & rotate and it works.
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.

Leffmann 03 April 2014 00:01

Quote:

Originally Posted by Mrs Beanbag (Post 947181)
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).

Yes, but this solution would be overly complex, because you need to take the slope and the length of the line into account. If you simplify it to just subtracting 1 from either DX or DY, after determining whether the line has a steep or low incline, you'll get a slightly different line, and it still requires more logic than the better solution:

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.

Mrs Beanbag 03 April 2014 00:31

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.

Photon 14 May 2014 01:34

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 :)


All times are GMT +2. The time now is 21:28.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.05332 seconds with 11 queries