home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / lighting.asm < prev    next >
Assembly Source File  |  1996-03-19  |  6KB  |  265 lines

  1.     TITLE    LIGHTING - MATH FOR LIGHTING IN ASSEMBLER
  2.  
  3.     COMMENT $
  4.  
  5.  
  6. /* Routines for cosine or other lighting         */
  7. /* All code and algorithms created by Dave Stampe    */
  8. /* converted to assembly 17/12/93 by Dave Stampe     */
  9.  
  10. // All algorithms and code (c) 1993 by Dave Stampe
  11.  
  12. /*
  13.  This code is part of the REND386 project, created by Dave Stampe and
  14.  Bernie Roehl.
  15.  
  16.  Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
  17.  
  18.  May be freely used to write software for release into the public domain;
  19.  all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
  20.  for permission to incorporate any part of this software into their
  21.  products!  Usually there is no charge for under 50-100 items for
  22.  low-cost or shareware, and terms are reasonable.  Any royalties are used
  23.  for development, so equipment is often acceptable payment.
  24.  
  25.  ATTRIBUTION:  If you use any part of this source code or the libraries
  26.  in your projects, you must give attribution to REND386, Dave Stampe,
  27.  and Bernie Roehl in your documentation, source code, and at startup
  28.  of your program.  Let's keep the freeware ball rolling!  No more
  29.  code ripoffs please.
  30.  
  31.  CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
  32.  See the COPYRITE.H file for more information.
  33. */
  34.  
  35.  
  36. This code does a very fast computation of cosine for lighting.
  37. It figures N.V/(mag(N)/mag(V) to 8 bit accuracy, where N is the poly
  38. normal, and V is the vector from the lightsource to the polygon.
  39. It is optimized by using the fact that the normls are all scaled to
  40. a known magnitude, and by preshifting V and N so an 8-bit multiply can be
  41. used in the magnitude computation.
  42.  
  43. A value between -127 and +127 is returned for the cosine (-1.0 to +1.0)
  44.  
  45. /* Contact: dstampe@sunee.waterloo.edu */
  46.  
  47.         $
  48.  
  49.     .MODEL large
  50.  
  51.     .DATA
  52.  
  53.         ; int sqrtable[1024];
  54.         ;   /*integer lookup for square root to 8 bit precision */
  55.  
  56. extrn   _sqrtable
  57.  
  58.  
  59.     .CODE RENDERING
  60.     .386
  61.  
  62.  
  63. MULT29     MACRO a,b                 ; multiply <3.29> -> eax
  64.     mov    eax,DWORD PTR a
  65.     imul    DWORD PTR b
  66.     shrd    eax,edx,29
  67.     adc    eax,0
  68.     ENDM
  69.  
  70. MMULT29 MACRO a,b,c               ; multiply 3 of <3.29> -> eax
  71.     mov    eax,DWORD PTR a
  72.     imul    DWORD PTR b
  73.     shrd    eax,edx,29
  74.     adc    eax,0
  75.     imul    DWORD PTR c
  76.     shrd    eax,edx,29
  77.     adc    eax,0
  78.     ENDM
  79.  
  80. DOTPROD    MACRO a,b,c,x,y,z,p      ; dot product plus p, accum in ecx:ebx
  81.     mov    eax,a            ; result in eax
  82.     imul    DWORD PTR x
  83.     mov    ecx,edx
  84.     mov    ebx,eax
  85.     mov    eax,b
  86.     imul    DWORD PTR y
  87.     add    ebx,eax
  88.     adc    ecx,edx
  89.     mov    eax,c
  90.     imul    DWORD PTR z
  91.     add    eax,ebx
  92.     adc    edx,ecx
  93.     shrd    eax,edx,29
  94.     adc    eax,p
  95.     ENDM
  96.  
  97. ;/************** FAST COSINE LIGHT ANGLE COMPUTE **********/
  98.  
  99. ;    /* compute vector from light source to surface  */
  100. ;    /* find dot product, normalize by vector length */
  101. ;    /* returns -128<light<128 (signed 8-bit)        */
  102. ;    /* args: ligh characteristics, poly normal, point on poly */
  103. ;    /* point on poly is 0,0,0 for spotlight */
  104. ;
  105. ;int light_cosine(long nx, long ny, long nz,
  106. ;          long vx, long vy, long vz,
  107. ;          long lx, long ly, long lz );
  108.  
  109. nx    equ    [bp+8]          ; arguments
  110. ny    equ    [bp+12]
  111. nz     equ    [bp+16]
  112. vx        equ    [bp+20]
  113. vy     equ    [bp+24]
  114. vz    equ    [bp+28]
  115. lx    equ    [bp+32]
  116. ly    equ    [bp+36]
  117. lz    equ    [bp+40]
  118.  
  119. light    equ    [bp-4]        ; locals
  120.  
  121.     PUBLIC    _light_cosine
  122.  
  123. _light_cosine    proc    far
  124.  
  125.     push    ebp
  126.     mov    ebp,esp
  127.     sub    esp,4
  128.  
  129.     push    esi                 ; normal is normalized, just need to
  130.     push    edi                 ; find size of light vector
  131.     push    ecx
  132.     push    edx
  133.  
  134.     mov    eax,DWORD PTR lx    ;  delta X
  135.     sub    eax,vx
  136.     mov     ecx,eax
  137.     jge    xnn                 ; abs values -> ecx for scaling
  138.     neg    ecx
  139. xnn:
  140.     mov    vx,ecx
  141.     mov    ebx,ecx
  142.     imul    DWORD PTR nx        ; nx*dx
  143.     mov    edi,edx
  144.     mov    esi,eax
  145.  
  146.     mov    eax,DWORD PTR ly    ; delta Y
  147.     sub    eax,vy
  148.     mov     ecx,eax
  149.     jge    ynn                 ; abs value
  150.     neg    ecx
  151. ynn:
  152.     mov    vy,ecx
  153.     or    ebx,ecx            ; OR abs deltas for scaling test
  154.     imul    DWORD PTR ny
  155.     add    esi,eax            ; and continue with dot product
  156.     adc    edi,edx
  157.  
  158.     mov    eax,DWORD PTR lz   ; same for Z
  159.     sub    eax,vz
  160.     mov     ecx,eax
  161.     jge    znn
  162.     neg    ecx
  163. znn:
  164.     mov    vz,ecx
  165.     or    ebx,ecx
  166.     jnz    golight         ; /* max light at zero distance */
  167.     mov    ax,127
  168.     jmp    fincos
  169.  
  170. golight:
  171.     imul    DWORD PTR nz
  172.     add    esi,eax
  173.     adc    edi,edx           ;/* edi:esi now 64-bit dot product */
  174.  
  175.  
  176.       ; START OF LIGHT VECTOR MAG COMPUTE
  177.  
  178.     shrd    esi,edi,16        ; prescale
  179.     sar    edi,16            ; only did the prescale cause bsr
  180.                   ; is so slow on 386
  181.     xor    cx,cx
  182.     test    ebx,0ff000000h    ; fast size tests, shifts
  183.     je    not32sig          ; will let us use fast mults later
  184.     add    cx,16
  185.     jmp    shft16sig
  186. not32sig:
  187.     test    ebx,0ffff0000h
  188.     je    nonesig           ; prescale by 8 bits */
  189.     add    cx,8
  190. shft16sig:
  191.     shr    ebx,cl            ; conv. test to word (save 2 us) */
  192. nonesig:
  193.  
  194.     bsr    ax,bx          ; we test rest of bits
  195.     add    cx,ax
  196.     sub    cx,7              ; how many bits to normalize? */
  197.     je    noshiftn
  198.     jl    bumpup
  199.  
  200.     shr    DWORD PTR vx,cl   ; make into 8-bit numbers
  201.     shr    DWORD PTR vy,cl
  202.     shr    DWORD PTR vz,cl
  203.     shrd    esi,edi,cl
  204.     sar    edi,cl
  205.     jmp    noshiftn
  206. bumpup:
  207.     neg    cl
  208.     shl    DWORD PTR vx,cl
  209.     shl    DWORD PTR vy,cl
  210.     shl    DWORD PTR vz,cl
  211.     shld    edi,esi,cl
  212.     shl    esi,cl
  213.  
  214. noshiftn:
  215.     mov    al,BYTE PTR vx       ; now 8-bit diff's: find mag */
  216.     mul    al
  217.     mov    bx,ax                ; square all components, sum
  218.     xor    dx,dx
  219.  
  220.     mov    al,BYTE PTR vy
  221.     mul    al
  222.     add    bx,ax
  223.     adc    dx,0
  224.  
  225.     mov    al,BYTE PTR vz
  226.     mul    al
  227.     add    bx,ax
  228.     adc    dx,0
  229.  
  230.     shrd    bx,dx,7              ; lookup in sqrt table */
  231.     and     ebx,0FFFEh
  232.     push    esi
  233.     les    si,DWORD PTR _sqrtable
  234.     mov    ax,WORD PTR es:[bx+si]
  235.  
  236.     cwde
  237.     pop    esi
  238.  
  239.   ; END OF LIGHT VECTOR MAG COMPUTE 
  240.  
  241.     mov    ebx,eax
  242.     mov    edx,edi
  243.     mov    eax,esi
  244.     idiv    ebx              ; remove magnitude from dot product
  245.  
  246. fincos:      ; result is now in ax: 127*cosine !
  247.  
  248.     pop    edx
  249.     pop    ecx
  250.     pop    edi
  251.     pop    esi
  252.  
  253.     mov    esp,ebp
  254.     pop    ebp
  255.     ret
  256.  
  257. _light_cosine    endp
  258.  
  259.  
  260.  
  261.  
  262.     end
  263.  
  264.  
  265.