home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Virtual Reality Homebrewer's Handbook
/
vr.iso
/
vr386
/
viewrend.asm
< prev
next >
Wrap
Assembly Source File
|
1996-03-19
|
10KB
|
496 lines
TITLE VIEWREND - RENDERER SUPPORT MATH 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 computes all the mathematically fiddly stuff for
rendering, and caches it in the viewport structures. It
also unpacks the viewport to static variables to make
rendering more efficient. These two steps permit efficient viewpoint
and look angle changes while keeping the renderer configuration flexible
/* Contact: dstampe@sunee.waterloo.edu */
$
.MODEL large
.386
.DATA
include 3dstruct.inc ; 3D structures
create_data equ 1 ; force data to be created
include viewdata.inc ; static data for rendering
; /* tables for sphere object clipping: */
; extern long sclip_C[800]; /* 1/sqrt(zoom^2 + 1) table */
; extern long sclip_M[800]; /* zoom * C table (table: i = 32*zoom) */
; /* range: FOV = 2*atan(1/zoom) */
; /* or about 150 to 7 degrees */
; /* thus: for smaller window, divide zoom by fraction of h. screen */
extrn _sclip_C:DWORD ; tables for volume clip computations
extrn _sclip_M:DWORD
.CODE RENDERER
VS_COPY MACRO n ;; macro to copy dword to temp
mov eax,es:[bx].VP_&n
mov _VS_&n , eax
ENDM
;void render_set_view(VIEW *v) /* copy viewport data to fast access area */
v equ [bp+8] ; arguments
PUBLIC _render_set_view
_render_set_view proc far
.386
push ebp
mov ebp,esp
push edx
push ecx
les bx,DWORD PTR v
mov dx,es:[bx].VP_orientation
mov _VS_orientation,dx
mov eax,es:[bx].VP_sx ; unpack, mirror scaling factors
test dx,XFLIP
je pos_sx
neg eax
pos_sx:
mov _VS_sx,eax
mov eax,es:[bx].VP_sy
test dx,YFLIP
je pos_sy
neg eax
pos_sy:
mov _VS_sy,eax
mov eax,es:[bx].VP_scx ; copy and scale matrix entries
mov _VS_scx,eax
mov eax,es:[bx].VP_scy
mov _VS_scy,eax
mov eax,es:[bx].VP_xform00
mov _VS_fact1,eax
imul DWORD PTR _VS_sx
shrd eax,edx,16
adc eax,0
mov _VS_sfac1,eax
mov eax,es:[bx].VP_xform01
mov _VS_fact2,eax
imul DWORD PTR _VS_sx
shrd eax,edx,16
adc eax,0
mov _VS_sfac2,eax
mov eax,es:[bx].VP_xform02
mov _VS_fact3,eax
imul DWORD PTR _VS_sx
shrd eax,edx,16
adc eax,0
mov _VS_sfac3,eax
mov eax,es:[bx].VP_xform10
mov _VS_fact4,eax
imul DWORD PTR _VS_sy
shrd eax,edx,16
adc eax,0
mov _VS_sfac4,eax
mov eax,es:[bx].VP_xform11
mov _VS_fact5,eax
imul DWORD PTR _VS_sy
shrd eax,edx,16
adc eax,0
mov _VS_sfac5,eax
mov eax,es:[bx].VP_xform12
mov _VS_fact6,eax
imul DWORD PTR _VS_sy
shrd eax,edx,16
adc eax,0
mov _VS_sfac6,eax
mov eax,es:[bx].VP_xform20 ; Z entries unscaled
mov _VS_fact7,eax
mov _VS_sfac7,eax
mov eax,es:[bx].VP_xform21
mov _VS_fact8,eax
mov _VS_sfac8,eax
mov eax,es:[bx].VP_xform22
mov _VS_fact9,eax
mov _VS_sfac9,eax
mov eax,es:[bx].VP_xform30 ; copy view position
mov _VS_iview_x,eax
mov eax,es:[bx].VP_xform31
mov _VS_iview_y,eax
mov eax,es:[bx].VP_xform32
mov _VS_iview_z,eax
mov cx,2 ;PRESCALEZ ; copy, prescale clipping values
mov eax,es:[bx].VP_yon
mov _VS_yon,eax
shl eax,cl
mov _VS_yon4,eax
mov eax,es:[bx].VP_hither
mov _VS_hither,eax
shl eax,cl
mov _VS_hither4,eax
mov cx,2 ;PRESCALE
mov eax,es:[bx].VP_left
mov _VS_left,eax
shl eax,cl
mov _VS_left4,eax
mov eax,es:[bx].VP_right
mov _VS_right,eax
shl eax,cl
mov _VS_right4,eax
mov eax,es:[bx].VP_top
mov _VS_top,eax
shl eax,cl
mov _VS_top4,eax
mov eax,es:[bx].VP_bottom
mov _VS_bottom,eax
shl eax,cl
mov _VS_bottom4,eax
mov eax,es:[bx].VP_hsc ; scaled centering factors
shl eax,cl
mov _VS_hsc,eax
mov eax,es:[bx].VP_vsc
shl eax,cl
mov _VS_vsc,eax
VS_COPY hsw
VS_COPY hsh
VS_COPY left_C
VS_COPY left_M
VS_COPY right_C
VS_COPY right_M
VS_COPY top_C
VS_COPY top_M
VS_COPY bot_C
VS_COPY bot_M
mov ax,es:[bx].VP_xshift
mov _VS_xshift,ax
mov ax,es:[bx].VP_yshift
mov _VS_yshift,ax
pop ecx
pop edx
mov esp,ebp
pop ebp
ret
_render_set_view endp
; /* compute screen and viewport */
; /* factors. These stay constant */
; /* over eye point changes */
;void initialize_screen_factors(VIEW *v)
v equ [bp+8] ; arguments
ti equ WORD PTR [bp-4] ; locals
bi equ WORD PTR [bp-8]
li equ WORD PTR [bp-12]
ri equ WORD PTR [bp-16]
zoom equ DWORD PTR [bp-20]
x_offset equ DWORD PTR [bp-24]
y_offset equ DWORD PTR [bp-28]
orient equ WORD PTR es:[bx].VP_orientation ; viewport flip flags
aspect equ DWORD PTR es:[bx].VP_aspect ; viewport aspect ratio
hsh equ DWORD PTR es:[bx].VP_hsh ; viewport screen dimensions
hsw equ DWORD PTR es:[bx].VP_hsw
hsc equ DWORD PTR es:[bx].VP_hsc ; viewport scaling factors
vsc equ DWORD PTR es:[bx].VP_vsc
scx equ DWORD PTR es:[bx].VP_scx ; viewport scaling factors
scy equ DWORD PTR es:[bx].VP_scy
sx equ DWORD PTR es:[bx].VP_sx ; viewport scaling mantissa
sy equ DWORD PTR es:[bx].VP_sy
xshift equ WORD PTR es:[bx].VP_xshift ; viewport scaling exponent
yshift equ WORD PTR es:[bx].VP_yshift
top equ DWORD PTR es:[bx].VP_top ; viewport window clip
bottom equ DWORD PTR es:[bx].VP_bottom
left equ DWORD PTR es:[bx].VP_left
right equ DWORD PTR es:[bx].VP_right
PUBLIC _initialize_screen_factors
_initialize_screen_factors proc far
.386
push ebp
mov ebp,esp
sub sp,32
push edi
push esi
push edx
push ecx
les bx,DWORD PTR v ; viewport pointer
mov eax,es:[bx].VP_xoffset ; load locals
mov x_offset,eax
mov eax,es:[bx].VP_yoffset
mov y_offset,eax
mov eax,left ; compute screen "center"
add eax,right
shr eax,1
add eax,x_offset
mov hsc,eax
mov eax,top
add eax,bottom
shr eax,1
add eax,y_offset
mov vsc,eax
mov eax,right ; half-screen dimensions
sub eax,left
shr eax,1
mov hsw,eax
mov eax,bottom
sub eax,top
shr eax,1
mov hsh,eax
mov eax,es:[bx].VP_zoom ; clip zoom range
cmp eax,08000h ; less than 0.5?
jge clip_low
mov eax,08000h
clip_low:
cmp eax,0100000h ; greater than 16?
jle clip_high
mov eax,0100000h
clip_high:
mov zoom,eax
test orient,XFLIP
je noxflip
neg x_offset
noxflip:
test orient,YFLIP
je noyflip
neg y_offset
noyflip: ; COMPUTE EDGES OF WINDOW
mov eax,zoom ;/* left pc = z*w/(w+xo) */
mov edx,hsw
imul edx
push eax
push edx
mov esi,hsw
add esi,x_offset
idiv esi
shr eax,12
cmp ax,799
jbe clip_li
mov ax,799
clip_li:
mov li,ax
pop edx
pop eax
mov esi,hsw ;/* right pc = z*w/(w-xo) */
sub esi,x_offset
idiv esi
shr eax,12
cmp ax,799
jbe clip_ri
mov ax,799
clip_ri:
mov ri,ax
;/* compute vert. scale zoom */
;/* zoom * hsw / hsh * (aspect/65536.0); */
mov eax,zoom ; /* <16.16> */
mul DWORD PTR aspect ; /* <16.16> -> <32.32> */
shrd eax,edx,16 ; /* -> <16.16> */
mul DWORD PTR hsw
div DWORD PTR hsh ; /* still <16.16> */
mov edx,hsh ; /* top pc = z*h/(h+yo) */
imul edx
push edx
push eax
mov esi,hsh
add esi,y_offset
idiv esi
shr eax,12
cmp ax,799
jbe clip_ti
mov ax,799
clip_ti:
mov ti,ax
pop eax ; /* bot pc = z*h/(h-yo) */
pop edx
mov esi,hsh
sub esi,y_offset
idiv esi
shr eax,12
cmp ax,799
jbe clip_bi
mov ax,799
clip_bi:
mov bi,ax
; now look up clipping volume slopes!
les si,_sclip_C
mov bx,li
shl bx,2
mov eax,es:[bx+si]
mov bx,ri
shl bx,2
mov edx,es:[bx+si]
mov bx,ti
shl bx,2
mov ecx,es:[bx+si]
mov bx,bi
shl bx,2
mov edi,es:[bx+si]
les bx,v
mov es:[bx].VP_left_C,eax
mov es:[bx].VP_right_C,edx
mov es:[bx].VP_top_C,ecx
mov es:[bx].VP_bot_C,edi
les si,_sclip_M
mov bx,li
shl bx,2
mov eax,es:[bx+si]
mov bx,ri
shl bx,2
mov edx,es:[bx+si]
mov bx,ti
shl bx,2
mov ecx,es:[bx+si]
mov bx,bi
shl bx,2
mov edi,es:[bx+si]
les bx,v
mov es:[bx].VP_left_M,eax
mov es:[bx].VP_right_M,edx
mov es:[bx].VP_top_M,ecx
mov es:[bx].VP_bot_M,edi
; /* compute screen scaling factors */
; /* which are pseudo-floating point */
; /* to maximize precision and range */
; /* width sets overall scaling */
;/* sx = v->hsw * (zoom/65536.0); */
;/* sy = v->hsw * (zoom/65536.0) * (v->aspect/65536.0); */
mov eax,zoom ;/* <16.16> */
mul DWORD PTR aspect ;/* <16.16> -> <32.32> */
shrd eax,edx,16 ;/* -> <16.16> */
mul DWORD PTR hsw ;/* <16.0> -> <48.16> */
mov scy, eax
bsr ecx,eax ; comvert to "float"
sub cx,15
jg nofixs
xor cx,cx
nofixs:
shrd eax,edx,cl ;/* normalize to <16.16> */
mov DWORD PTR sy,eax
add cx,2 ;PRESCALEZ ;/* and record shift */
mov yshift,cx
mov eax,zoom ;/* <16.16> */
mul DWORD PTR hsw ;/* <16.0> -> <48.16> */
mov scx,eax
bsr ecx,eax
sub cx,15 ; comvert to "float"
jg nofixs2
xor cx,cx
nofixs2:
shrd eax,edx,cl ;/* normalize to <16.16> */
mov DWORD PTR sx,eax
add cx,2 ;PRESCALEZ
mov xshift,cx ;/* and record shift */
pop ecx
pop edx
pop esi
pop edi
mov esp,ebp
pop ebp
ret
_initialize_screen_factors endp
end