FILLED VECTORS (PARTE 3)


CLIPPING

Viene usato quando una faccia esce dalla zona visibile dello screen. Con questa routine e' possibile disegnare solo i pezzi del poligono interni allo screen ed eliminare quelli esterni.

Esempio:

Poligono da disegnare :


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

Schermo:

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

Somma:

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

Uso del clipping:


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

Per tagliare le parti esterne allo screen e' necessario prendere in considerazione una linea del poligono alla volta, controllare le coordinate dei 2 punti e, nel caso in cui solo un punto esca dallo screen, calcolare le intersezioni con lo screen.

Esistono alcuni casi in cui e' inutile disegnare una linea:

* entrambi i punti escono dallo screen

* la linea e' orizzontale

Se la linea e' orizzontale e' inutile disegnarla, facciamo un esempio pratico:

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

Il blitter riempe una zona di memoria iniziando quando trova un pixel e finendo quando ne trova un altro. Nell'esempio avremo il poligono perfettamente riempito solo con le due linee verticali.

Ecco il sorgente in codice assembler 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   ->    NON DISEGNARE LINEA
	bne.s	Continua
NO_LINEA:
	rts

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

* CONTROLLO LATO SINISTRO

	tst.l	d0
	bpl.s	NOClippingSinistro	; se d0 positivo allora no clip. sinistro

	tst.l	d1			; d0 < 0 , d1 < 0     FUORI SCREEN
	bmi.s	NO_LINEA

** CLIPPING SINISTRO
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:
* CONTROLLO LATO DESTRO
	cmp.l	#320,d1			; se d1 < 320 no clipping sinistro
	blt.s	NoClippingDestro
	cmp.l	#320,d0			; d0 >= 320 , d1 > 320     FUORI SCREEN
	bge.s	NO_LINEA

** CLIPPING DESTRO
	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 = pre ogni X, quante Y si sposta ?
	sub.w	#320,d1		; 320 pixel senza 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:

* CONTROLLO IN ALTO
	tst.l	d2		; se d2 > 0 no clipping
	bpl.s	NoClippingAlto
	tst.l	d3		; d3 < 0 , d2 < 0     FUORI SCREEN
	bmi.s	NO_LINEA


* CLIPPING ALTO
	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 = pre ogni Y, quante X si sposta ?
	neg.l	d2		; d2 = d2 negato
	mulu.l	d2,d4		; d1 = d1 * d5
	swap	d4		; d5 >> 16
	add.w	d4,d0		; New Y  ->  X = 105
	moveq	#0,d2

NoClippingAlto:
* CONTROLLO BASSO
	cmp.l	#256,d3		; se d3 < 256  NO CLIPPING BASSO
	blt.s	NoClippingBasso
	cmp.l	#256,d2		; d3 > 256, d2 >= 256     FUORI SCREEN
	bge.w	NO_LINEA

* CLIPPING BASSO
	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 = pre ogni Y, quante X si sposta ?
	sub.w	#256,d3		; 256 pixel senza 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:

* QUESTE SONO LE COORDINATE CALCOLATE !!!

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

	rts


Pagina Principale


    Scritto da: Alfredo Ornaghi      e-mail: ted@intercom.it
                ITALY                   tel: