home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
vr386
/
polyproc.asm
< prev
next >
Wrap
Assembly Source File
|
1993-12-26
|
11KB
|
587 lines
TITLE POLYPROC - POLY-PROCESSING PIPELINE IN ASSEMBLER
COMMENT $
// 26/12/93 by Dave Stampe
// All algorithms and code (c) 1993 by Dave Stampe
/*
This code is part of the REND386 project, created by Dave Stampe and
Bernie Roehl.
Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
May be freely used to write software for release into the public domain;
all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
for permission to incorporate any part of this software into their
products! Usually there is no charge for under 50-100 items for
low-cost or shareware, and terms are reasonable. Any royalties are used
for development, so equipment is often acceptable payment.
ATTRIBUTION: If you use any part of this source code or the libraries
in your projects, you must give attribution to REND386, Dave Stampe,
and Bernie Roehl in your documentation, source code, and at startup
of your program. Let's keep the freeware ball rolling! No more
code ripoffs please.
CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
See the COPYRITE.H file for more information.
*/
This file includes parts of the poly processing pipeline, including
transformation and clipping. It also computes the poly depth for sorting,
and does the backfacing poly math
/* Contact: dstampe@sunee.waterloo.edu */
$
.MODEL large
.386
.DATA
include 3dstruct.inc
include viewdata.inc
include rendmem.inc
.CODE RENDERER
;/***************** XY VERTEX TRANSFORM -> CAMERA COORDS ************/
;/* X, Y viewport xform, create new vertex copy if needed */
;/* can reuse previously transformed vertices */
; NVERTEX *xy_transform(VERTEX *v)
v equ DWORD PTR [bp+8] ; arguments
wx equ DWORD PTR [bp-4] ; locals
wy equ DWORD PTR [bp-8]
wz equ DWORD PTR [bp-12]
PUBLIC _xy_transform
_xy_transform proc far
.386
push ebp
mov ebp,esp
sub esp,20
push esi
push edi
push ecx
les bx,v
mov eax,es:[bx].V_nvptr ; is there an old copy available?
test eax,-1
jnz ptr_in_eax
ALLOCVTX ; returns new vertex in es:bx
; also in _nvalloc
les bx,DWORD PTR v
mov eax,DWORD PTR es:[bx].V_x
sub eax,DWORD PTR _VS_iview_x
mov DWORD PTR wx,eax
mov eax,DWORD PTR es:[bx].V_y
sub eax,DWORD PTR _VS_iview_y
mov DWORD PTR wy,eax
mov eax,DWORD PTR es:[bx].V_z
sub eax,DWORD PTR _VS_iview_z
mov DWORD PTR wz,eax
mov eax,DWORD PTR _VS_sfac1
mov edx,DWORD PTR wx
imul edx
mov esi,eax
mov edi,edx
mov eax,DWORD PTR _VS_sfac2
mov edx,DWORD PTR wy
imul edx
add esi,eax
adc edi,edx
mov eax,DWORD PTR _VS_sfac3
mov edx,DWORD PTR wz
imul edx
add esi,eax
adc edi,edx
shrd esi,edi,27; 29-PRESCALE
adc esi,0
mov ecx,esi
mov eax,DWORD PTR _VS_sfac4
mov edx,DWORD PTR wx
imul edx
mov esi,eax
mov edi,edx
mov eax,DWORD PTR _VS_sfac5
mov edx,DWORD PTR wy
imul edx
add esi,eax
adc edi,edx
mov eax,DWORD PTR _VS_sfac6
mov edx,DWORD PTR wz
imul edx
add esi,eax
adc edi,edx
shrd esi,edi,27; 29-PRESCALE
adc esi,0
mov eax,esi
mov esi,_nvalloc
mov DWORD PTR es:[bx].V_nvptr,esi
mov esi,DWORD PTR es:[bx].V_cz ;/* copy z (conv before) */
les bx, _nvalloc
mov DWORD PTR es:[bx].NV_x,ecx ;/* new x,y */
mov DWORD PTR es:[bx].NV_y,eax
mov DWORD PTR es:[bx].NV_z,esi
mov eax,_nvalloc
ptr_in_eax:
shld edx,eax,16
pop ecx
pop edi
pop esi
mov esp,ebp
pop ebp
ret
_xy_transform endp
;/********** PERSPECTIVE AND SCREEN CONVERT VERTEX ************/
; /* final processing for vertex passed */
; void *z_output(NVERTEX *nv) /* by clipper. Figure perspective */
; /* screen positions and poly outcodes */
; return soutcode
nv equ DWORD PTR [bp+8] ; arguments
PUBLIC _z_output
_z_output proc far
.386
push ebp
mov ebp,esp
push ecx
push edx
les bx,DWORD PTR nv ; is perspective done yet?
test BYTE PTR es:[bx].NV_persp,80h
jne skip_perspective
mov cl,BYTE PTR _VS_xshift ; prescale x, y for accuracy */
mov eax,DWORD PTR es:[bx].NV_x
cdq
shld edx,eax,cl
shl eax,cl
idiv DWORD PTR es:[bx].NV_z ;/* divide by z
add eax,DWORD PTR _VS_hsc ;/* add prescaled screen center */
and eax,0FFFFFFFCh ;/* lock to integer */;
mov DWORD PTR es:[bx].NV_xs,eax ;/* and store */
xor ch,ch
cmp eax,DWORD PTR _VS_right4
jle nsro ;/* check outcodes */
or ch,ORIGHT
nsro:
cmp eax,DWORD PTR _VS_left4
jge nslo
or ch,OLEFT
nslo:
mov cl,BYTE PTR _VS_yshift; ; same deal for y */
mov eax,DWORD PTR es:[bx].NV_y
cdq
shld edx,eax,cl
shl eax,cl
idiv DWORD PTR es:[bx].NV_z ;/* divide by z
neg eax ;/* except upside down */
add eax,DWORD PTR _VS_vsc
and eax,0FFFFFFFCh ;/* lock to integer */
mov DWORD PTR es:[bx].NV_ys,eax
cmp eax,DWORD PTR _VS_bottom4
jle nsbo
or ch,OBOTTOM
nsbo:
cmp eax,DWORD PTR _VS_top4
jge nsto
or ch,OTOP
nsto:
mov BYTE PTR es:[bx].NV_ocode,ch
or BYTE PTR es:[bx].NV_persp,80h
skip_perspective:
movzx ax,BYTE PTR es:[bx].NV_ocode ; return outcode
pop edx
pop ecx
mov esp,ebp
pop ebp
ret
_z_output endp
;/*********** CONVERT Z COORD OF VERTEX, SET OUTCODES ********/
; int z_convert_vertex(VERTEX *vtx);
vtx equ DWORD PTR [bp+8] ; arguments
PUBLIC _z_convert_vertex
_z_convert_vertex proc far
push ebp
mov ebp,esp
push esi
push edi
les si,DWORD PTR vtx
test BYTE PTR es:[si].V_zxflag,80h
jnz already_z ; check if already done
mov eax,DWORD PTR _VS_sfac7
mov edx,DWORD PTR es:[si].V_x
sub edx,DWORD PTR _VS_iview_x
imul edx
mov ebx,eax
mov edi,edx
mov eax,DWORD PTR _VS_sfac8
mov edx,DWORD PTR es:[si].V_y
sub edx,DWORD PTR _VS_iview_y
imul edx
add ebx,eax
adc edi,edx
mov eax,DWORD PTR _VS_sfac9
mov edx,DWORD PTR es:[si].V_z
sub edx,DWORD PTR _VS_iview_z
imul edx
add ebx,eax
adc edi,edx
shrd ebx,edi,27 ;29-PRESCALEZ
adc ebx,0
mov DWORD PTR es:[si].V_cz,ebx
or BYTE PTR es:[si].V_zxflag,80h
xor ax,ax
cmp ebx,DWORD PTR _VS_hither4
jge nonhither
or al,OHITHER
nonhither:
cmp ebx,DWORD PTR _VS_yon4
jle nonyon
or al,OYON
nonyon:
mov BYTE PTR es:[si].V_zocode,al
already_z:
movzx ax,BYTE PTR es:[si].V_zocode
pop edi
pop esi
mov esp,ebp
pop ebp
ret
_z_convert_vertex endp
;/*********** POLYGON BACKFACE TEST ***********/
; int is_poly_facing(POLY *p);
; returns sign of visibility dot product
p equ DWORD PTR [bp+8] ; arguments
nx equ DWORD PTR [bp-4] ; locals
ny equ DWORD PTR [bp-8]
nz equ DWORD PTR [bp-12]
PUBLIC _is_poly_facing
_is_poly_facing proc far
push ebp
mov ebp,esp
sub esp,20
push esi
push edi
les bx,DWORD PTR p
mov edx,DWORD PTR es:[bx].P_normx ; get normals
mov eax,DWORD PTR es:[bx].P_normy
mov DWORD PTR ny,eax
mov eax,DWORD PTR es:[bx].P_normz
mov DWORD PTR nz,eax
les bx,DWORD PTR es:[bx].P_points ; get first vertex
les bx,es:[bx]
mov eax,DWORD PTR es:[bx].V_x ; compute dot product
sub eax,DWORD PTR _VS_iview_x ; with VP to poly line
imul edx
mov esi,eax
mov edi,edx
mov eax,DWORD PTR es:[bx].V_y
sub eax,DWORD PTR _VS_iview_y
imul DWORD PTR ny
add esi,eax
adc edi,edx
mov eax,DWORD PTR es:[bx].V_z
sub eax,DWORD PTR _VS_iview_z
imul DWORD PTR nz
add esi,eax
adc edi,edx
mov ax,-1
jl proceed
mov ax,0
je proceed
mov ax,1
proceed:
pop edi
pop esi
mov esp,ebp
pop ebp
ret
_is_poly_facing endp
;/*********** CLIP HITHER Z COORD OF VERTEX ***********/
; creates new vertex from hither plane intercept of edge
; allocates new vertex
;
; NVERTEX *z_hither_clip(NVERTEX *v1, NVERTEX *v2);
v1 equ DWORD PTR [bp+8] ; arguments
v2 equ DWORD PTR [bp+12]
x1 equ DWORD PTR [bp-4] ; locals
y1 equ DWORD PTR [bp-8]
z1 equ DWORD PTR [bp-12]
x2 equ DWORD PTR [bp-16]
y2 equ DWORD PTR [bp-20]
z2 equ DWORD PTR [bp-24]
PUBLIC _z_hither_clip
_z_hither_clip proc far
push ebp
mov ebp,esp
sub esp,30
push ecx
les bx,DWORD PTR v1
mov eax, es:[bx].NV_x
mov DWORD PTR x1,eax
mov eax, es:[bx].NV_y
mov DWORD PTR y1,eax
mov eax, es:[bx].NV_z
mov DWORD PTR z1,eax
les bx,DWORD PTR v2
mov eax, es:[bx].NV_x
mov DWORD PTR x2,eax
mov eax, es:[bx].NV_y
mov DWORD PTR y2,eax
mov eax, es:[bx].NV_z
mov DWORD PTR z2,eax
ALLOCVTX ; returns new vertex in es:bx
; also in _nvalloc
mov ecx,z1 ;/* compute denominator */
sub ecx,z2
je zero_clipz ; zero!
jg other_way ; always clip in same direction
mov eax, _VS_hither4 ;/* compute new x */
sub eax,z2
mov edx,x1
sub edx,x2
imul edx
idiv ecx
add eax,x2
mov es:[bx].NV_x,eax
mov eax, _VS_hither4 ;/* compute new y */
sub eax,z2
mov edx,y1
sub edx,y2
imul edx
idiv ecx
add eax,y2
mov es:[bx].NV_y,eax
jmp endclipz
other_way:
neg ecx
mov eax, _VS_hither4 ;/* compute new x */
sub eax,z1
mov edx,x2
sub edx,x1
imul edx
idiv ecx
add eax,x1
mov es:[bx].NV_x,eax
mov eax, _VS_hither4 ;/* compute new y */
sub eax,z1
mov edx,y2
sub edx,y1
imul edx
idiv ecx
add eax,y1
mov es:[bx].NV_y,eax
jmp endclipz
zero_clipz:
mov eax,x1
mov es:[bx].NV_x,eax
mov eax,y1
mov es:[bx].NV_y,eax
endclipz:
mov eax,DWORD PTR _VS_hither4
mov DWORD PTR es:[bx].NV_z,eax
mov eax,_nvalloc
shld edx,eax,16
pop ecx
mov esp,ebp
pop ebp
ret
_z_hither_clip endp
;/************ COMPUTE AVERAGE DEPTH ************/
; long average_nvertex_depth(NVERTEX **nvp, int ncount);
; retruns average poly depth
nvp equ DWORD PTR [bp+8]
ncount equ WORD PTR [bp+12]
PUBLIC _average_nvertex_depth
_average_nvertex_depth proc far
push ebp
mov ebp,esp
push ecx
mov cx,ncount
nextvtx:
les bx,nvp
add WORD PTR nvp,4
les bx,DWORD PTR es:[bx]
add eax,es:[bx].NV_z
adc edx,0
dec cx
jg nextvtx
movzx ecx,WORD PTR ncount
idiv ecx
shld edx,eax,16
pop ecx ; prescaled depth, x4
mov esp,ebp
pop ebp
ret
_average_nvertex_depth endp
;/************ COMPUTE MAXIMUM DEPTH ************/
; long deepest_nvertex_depth(NVERTEX **nvp, int ncount);
; retruns average poly depth
nvp equ DWORD PTR [bp+8]
ncount equ WORD PTR [bp+12]
PUBLIC _deepest_nvertex_depth
_deepest_nvertex_depth proc far
push ebp
mov ebp,esp
mov dx,ncount
mov eax,080000001h ; big negative
nextdvtx:
les bx,nvp
add WORD PTR nvp,4
les bx,DWORD PTR es:[bx]
cmp eax,es:[bx].NV_z
jge nodeeper
mov eax,es:[bx].NV_z
nodeeper:
dec dx
jg nextdvtx
shld edx,eax,16
mov esp,ebp ; prescaled depth, x4
pop ebp
ret
_deepest_nvertex_depth endp
end