FILLED VECTORS (Part 3)


CLIPPING

It is used when a face comes out from the screen's visible area. By using this routine it is possible to draw only the faces's parts which are inside the screen and eliminate the ones outside.

Example: Faces to be drawed :


             /\
            /  \
           /    \
          /      \
         /        \
         \        /
          \      /
           \    /
            \  /
             \/

Screen :

         +---------+
         |         |
         |         |
         |         |
         |         |
         |         |
         |         |
         |         |
         |         |
         +---------+

Sum :

            /\
           /  \
         +/----\---+
         /      \  |
        /|       \ |
        \|       / |
         \      /  |
         |\    /   |
         | \  /    |
         |  \/     |
         |         |
         +---------+

Sum with clipping :

         +/----\---+
         /      \  |
         |       \ |
         |       / |
         \      /  |
         |\    /   |
         | \  /    |
         |  \/     |
         |         |
         +---------+

In order to cut the parts outside the screen it is needed to take into consideration each face's line separately, to check the co-ordinates of the two points and, in case that only one point comes out from the screen, to calculate the intersections whit the screen.

In some cases it is useless to draw a line:

* both points are out of the screen

* the line is horizontal

In case that the line is horizontal it is useless to draw, here is an example:


               ----------
               |        |
               |        |
               |        |
               |        |
               |        |
               |        |
               ----------

The blitter fills a memory's area starting when it finds a pixel and finishing when it finds another one. In our example the face is perfectly filled only thanks to the two vertical line.

Here is the source's code in assembler for 68020+


	move.l	#X0,d0
	move.l	#Y0,d2
	move.l	#X1,d1
	move.l	#Y1,d3

* START CLIPPING
Clip:
	cmp.l	d2,d3		; se y1 = y2   ->    DON'T DRAW THE LINE
	bne.s	Continua
NO_LINEA:
	rts

* X0 < X1
Continua:
	cmp.l	d0,d1
	bgt.s	X0MinoreX1
	exg.l	d0,d1
	exg.l	d2,d3
X0MinoreX1:

* CHECK OF THE LEFT SIZE

	tst.l	d0
	bpl.s	NOClippingSinistro	; if d0 positive than NOClippingSinistro

	tst.l	d1			; d0 < 0 , d1 < 0     outside the screen
	bmi.s	NO_LINEA

** LEFT CLIPPING
ClipSinistro:

	moveq	#0,d4
	moveq	#0,d5
	move.w	d1,d4		; d4 = x1
	sub.w	d0,d4		; d4 = x1 - x0
	move.w	d3,d5		; d5 = y1
	sub.w	d2,d5		; d5 = y1 - y0
	swap	d5		; d5 << 16
	divs.l	d4,d5		; WARNING : 68020+
				; d5 = d5 / d4 = pre ogni X, quante Y si sposta ?
	neg.l	d0		; d0 = d0 negato
	mulu.l	d0,d5		; WARNING : 68020+
				; d0 = d0 * d5
	swap	d5		; d5 >> 16
	add.w	d5,d2		; New Y  ->  X = 0
	moveq	#0,d0

NOClippingSinistro:
* CHECK OF THE RIGHT SIZE
	cmp.l	#320,d1			; if d1 < 320 than NoClippingDestro
	blt.s	NoClippingDestro
	cmp.l	#320,d0			; d1 > 320 , d0 > 320   outside the scren
	bge.s	NO_LINEA

** RIGHT CLIPPING
	moveq	#0,d4
	moveq	#0,d5
	move.w	d1,d4		; d4 = x1
	sub.w	d0,d4		; d4 = x1 - x0
	move.w	d3,d5		; d5 = y1
	sub.w	d2,d5		; d5 = y1 - y0
	swap	d5		; d5 << 16
	divs.l	d4,d5		; d5 = d5 / d4
	sub.w	#320,d1		; 320 pixel without clipping
	mulu.l	d1,d5		; d1 = d1 * d5
	swap	d5		; d5 >> 16
	sub.w	d5,d3		; New Y  ->  X = 105
	move.w	#319,d1

NoClippingDestro:

* VOGLIO Y0 < Y1
	cmp.l	d2,d3
	bgt.s	Y0MinoreY1
	exg.l	d0,d1
	exg.l	d2,d3
Y0MinoreY1:

* CHECK OF THE HIGH SIZE
	tst.l	d2		; if d2 > 0 NoclippingAlto
	bpl.s	NoClippingAlto
	tst.l	d3		; d3 < 0 , d2 < 0     outside the screen
	bmi.s	NO_LINEA


* HIGH CLIPPING
	moveq	#0,d4
	moveq	#0,d5
	move.w	d1,d4		; d4 = x1
	sub.w	d0,d4		; d4 = x1 - x0
	move.w	d3,d5		; d5 = y1
	sub.w	d2,d5		; d5 = y1 - y0
	swap	d4		; d4 << 16
	divs.l	d5,d4		; d4 = d5 / d4
	neg.l	d2		; d2 = d2 neg
	mulu.l	d2,d4		; d1 = d1 * d5
	swap	d4		; d5 >> 16
	add.w	d4,d0		; New Y  ->  X = 105
	moveq	#0,d2

NoClippingAlto:
* CHECK OF THE LOW SIZE
	cmp.l	#256,d3		; if d3 < 256  NOCLIPPINGBASSO
	blt.s	NoClippingBasso
	cmp.l	#256,d2		; d3 > 256, d2 >= 256     outside the screen
	bge.w	NO_LINEA

* LOW CLIPPING
	moveq	#0,d4
	moveq	#0,d5
	move.w	d1,d4		; d4 = x1
	sub.w	d0,d4		; d4 = x1 - x0
	move.w	d3,d5		; d5 = y1
	sub.w	d2,d5		; d5 = y1 - y0
	swap	d4		; d4 << 16
	divs.l	d5,d4		; d4 = d5 / d4
	sub.w	#256,d3		; 256 pixel without clipping
	mulu.l	d3,d4		; d1 = d1 * d5
	swap	d4		; d5 >> 16
	sub.w	d4,d1		; New Y  ->  X = 105
	move.w	#255,d3

NoClippingBasso:

* THESE ARE THE CALCULATED CO-ORDINATES

* D0 = X0
* D1 = X1
* D2 = Y0
* D3 = Y1

	rts


Main Page


    Written By: Alfredo Ornaghi      e-mail: ted@intercom.it
                ITALY                   tel: