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

  1.     TITLE    POLYPROC - POLY-PROCESSING PIPELINE IN ASSEMBLER
  2.  
  3.     COMMENT $
  4.  
  5. // 26/12/93 by Dave Stampe
  6. // All algorithms and code (c) 1993 by Dave Stampe
  7.  
  8. /*
  9.  This code is part of the REND386 project, created by Dave Stampe and
  10.  Bernie Roehl.
  11.  
  12.  Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
  13.  
  14.  May be freely used to write software for release into the public domain;
  15.  all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
  16.  for permission to incorporate any part of this software into their
  17.  products!  Usually there is no charge for under 50-100 items for
  18.  low-cost or shareware, and terms are reasonable.  Any royalties are used
  19.  for development, so equipment is often acceptable payment.
  20.  
  21.  ATTRIBUTION:  If you use any part of this source code or the libraries
  22.  in your projects, you must give attribution to REND386, Dave Stampe,
  23.  and Bernie Roehl in your documentation, source code, and at startup
  24.  of your program.  Let's keep the freeware ball rolling!  No more
  25.  code ripoffs please.
  26.  
  27.  CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
  28.  See the COPYRITE.H file for more information.
  29. */
  30.  
  31. This file includes parts of the poly processing pipeline, including
  32. transformation and clipping.  It also computes the poly depth for sorting,
  33. and does the backfacing poly math
  34.  
  35. /* Contact: dstampe@sunee.waterloo.edu */
  36.  
  37.         $
  38.  
  39.     .MODEL large
  40.     .386
  41.  
  42.     .DATA
  43.  
  44. include 3dstruct.inc
  45. include viewdata.inc
  46. include rendmem.inc
  47.  
  48.     .CODE RENDERER
  49.  
  50. ;/***************** XY VERTEX TRANSFORM -> CAMERA COORDS ************/
  51.  
  52. ;/* X, Y viewport xform, create new vertex copy if needed */
  53. ;/* can reuse previously transformed vertices          */
  54.  
  55. ; NVERTEX *xy_transform(VERTEX *v)
  56.  
  57. v     equ    DWORD PTR [bp+8]          ; arguments
  58.  
  59. wx    equ    DWORD PTR [bp-4]    ; locals
  60. wy    equ    DWORD PTR [bp-8]
  61. wz    equ    DWORD PTR [bp-12]
  62.  
  63.     PUBLIC    _xy_transform
  64.  
  65. _xy_transform    proc    far
  66.  
  67.     .386
  68.     push    ebp
  69.     mov    ebp,esp
  70.     sub    esp,20
  71.  
  72.     push    esi
  73.     push    edi
  74.     push    ecx
  75.  
  76.     les    bx,v
  77.     mov    eax,es:[bx].V_nvptr    ; is there an old copy available?
  78.     test    eax,-1
  79.     jnz    ptr_in_eax
  80.  
  81.     ALLOCVTX    ; returns new vertex in es:bx
  82.             ; also in _nvalloc
  83.  
  84.     les    bx,DWORD PTR v
  85.  
  86.     mov    eax,DWORD PTR es:[bx].V_x
  87.     sub    eax,DWORD PTR _VS_iview_x
  88.     mov    DWORD PTR wx,eax
  89.  
  90.     mov    eax,DWORD PTR es:[bx].V_y
  91.     sub    eax,DWORD PTR _VS_iview_y
  92.     mov    DWORD PTR wy,eax
  93.  
  94.     mov    eax,DWORD PTR es:[bx].V_z
  95.     sub    eax,DWORD PTR _VS_iview_z
  96.     mov    DWORD PTR wz,eax
  97.  
  98.     mov    eax,DWORD PTR _VS_sfac1
  99.     mov    edx,DWORD PTR wx
  100.     imul    edx
  101.     mov    esi,eax
  102.     mov    edi,edx
  103.  
  104.     mov    eax,DWORD PTR _VS_sfac2
  105.     mov    edx,DWORD PTR wy
  106.     imul    edx
  107.     add    esi,eax
  108.     adc    edi,edx
  109.  
  110.     mov    eax,DWORD PTR _VS_sfac3
  111.     mov    edx,DWORD PTR wz
  112.     imul    edx
  113.     add    esi,eax
  114.     adc    edi,edx
  115.  
  116.     shrd    esi,edi,27; 29-PRESCALE
  117.     adc    esi,0
  118.     mov    ecx,esi
  119.  
  120.     mov    eax,DWORD PTR _VS_sfac4
  121.     mov    edx,DWORD PTR wx
  122.     imul    edx
  123.     mov    esi,eax
  124.     mov    edi,edx
  125.  
  126.     mov    eax,DWORD PTR _VS_sfac5
  127.     mov    edx,DWORD PTR wy
  128.     imul    edx
  129.     add    esi,eax
  130.     adc    edi,edx
  131.  
  132.     mov    eax,DWORD PTR _VS_sfac6
  133.     mov    edx,DWORD PTR wz
  134.     imul    edx
  135.     add    esi,eax
  136.     adc    edi,edx
  137.  
  138.     shrd    esi,edi,27; 29-PRESCALE
  139.     adc    esi,0
  140.     mov    eax,esi
  141.  
  142.     mov    esi,_nvalloc
  143.     mov    DWORD PTR es:[bx].V_nvptr,esi
  144.  
  145.     mov    esi,DWORD PTR es:[bx].V_cz   ;/* copy z (conv before) */
  146.  
  147.     les    bx, _nvalloc
  148.     mov    DWORD PTR es:[bx].NV_x,ecx    ;/* new x,y */
  149.     mov    DWORD PTR es:[bx].NV_y,eax
  150.     mov    DWORD PTR es:[bx].NV_z,esi
  151.  
  152.     mov    eax,_nvalloc
  153.  
  154. ptr_in_eax:
  155.     shld    edx,eax,16
  156.  
  157.     pop    ecx
  158.     pop    edi
  159.     pop    esi
  160.  
  161.     mov    esp,ebp
  162.     pop    ebp
  163.     ret
  164.  
  165. _xy_transform    endp
  166.  
  167.  
  168.  
  169. ;/********** PERSPECTIVE AND SCREEN CONVERT VERTEX ************/
  170.  
  171. ;                 /* final processing for vertex passed */
  172. ; void *z_output(NVERTEX *nv) /* by clipper.  Figure perspective    */
  173. ;                                /* screen positions and poly outcodes */
  174. ; return soutcode
  175.  
  176. nv      equ    DWORD PTR [bp+8]          ; arguments
  177.  
  178.     PUBLIC    _z_output
  179.  
  180. _z_output    proc    far
  181.  
  182.     .386
  183.     push    ebp
  184.     mov    ebp,esp
  185.  
  186.     push    ecx
  187.     push    edx
  188.  
  189.     les    bx,DWORD PTR nv              ; is perspective done yet?
  190.     test    BYTE PTR es:[bx].NV_persp,80h
  191.     jne    skip_perspective
  192.  
  193.     mov    cl,BYTE PTR _VS_xshift       ; prescale x, y for accuracy  */
  194.  
  195.     mov    eax,DWORD PTR es:[bx].NV_x
  196.     cdq
  197.     shld    edx,eax,cl
  198.     shl    eax,cl
  199.     idiv    DWORD PTR es:[bx].NV_z         ;/* divide by z
  200.     add    eax,DWORD PTR _VS_hsc        ;/* add prescaled screen center */
  201.     and    eax,0FFFFFFFCh             ;/* lock to integer */;
  202.     mov    DWORD PTR es:[bx].NV_xs,eax  ;/* and store */
  203.  
  204.     xor    ch,ch
  205.     cmp    eax,DWORD PTR _VS_right4
  206.     jle    nsro                            ;/* check outcodes */
  207.     or    ch,ORIGHT
  208. nsro:
  209.     cmp    eax,DWORD PTR _VS_left4
  210.     jge     nslo
  211.     or    ch,OLEFT
  212. nslo:
  213.     mov    cl,BYTE PTR _VS_yshift;      ; same deal for y */
  214.  
  215.     mov    eax,DWORD PTR es:[bx].NV_y
  216.     cdq
  217.     shld    edx,eax,cl
  218.     shl    eax,cl
  219.     idiv    DWORD PTR es:[bx].NV_z         ;/* divide by z
  220.     neg    eax                            ;/* except upside down */
  221.     add    eax,DWORD PTR _VS_vsc
  222.     and    eax,0FFFFFFFCh             ;/* lock to integer */
  223.     mov    DWORD PTR es:[bx].NV_ys,eax
  224.  
  225.     cmp    eax,DWORD PTR _VS_bottom4
  226.     jle    nsbo
  227.     or    ch,OBOTTOM
  228. nsbo:
  229.     cmp    eax,DWORD PTR _VS_top4
  230.     jge     nsto
  231.     or    ch,OTOP
  232. nsto:
  233.     mov    BYTE PTR es:[bx].NV_ocode,ch
  234.     or    BYTE PTR es:[bx].NV_persp,80h
  235.  
  236. skip_perspective:
  237.     movzx    ax,BYTE PTR es:[bx].NV_ocode  ; return outcode
  238.  
  239.     pop    edx
  240.     pop    ecx
  241.  
  242.     mov    esp,ebp
  243.     pop    ebp
  244.     ret
  245.  
  246. _z_output    endp
  247.  
  248.  
  249.  
  250. ;/*********** CONVERT Z COORD OF VERTEX, SET OUTCODES ********/
  251.  
  252. ; int z_convert_vertex(VERTEX *vtx);
  253.  
  254.  
  255. vtx      equ    DWORD PTR [bp+8]        ; arguments
  256.  
  257.     PUBLIC    _z_convert_vertex
  258.  
  259. _z_convert_vertex    proc    far
  260.  
  261.     push    ebp
  262.     mov    ebp,esp
  263.  
  264.     push    esi
  265.     push    edi
  266.  
  267.     les    si,DWORD PTR vtx
  268.  
  269.     test    BYTE PTR es:[si].V_zxflag,80h
  270.     jnz    already_z           ; check if already done
  271.  
  272.     mov    eax,DWORD PTR _VS_sfac7
  273.     mov    edx,DWORD PTR es:[si].V_x
  274.     sub    edx,DWORD PTR _VS_iview_x
  275.     imul    edx
  276.     mov    ebx,eax
  277.     mov    edi,edx
  278.  
  279.     mov    eax,DWORD PTR _VS_sfac8
  280.     mov    edx,DWORD PTR es:[si].V_y
  281.     sub    edx,DWORD PTR _VS_iview_y
  282.     imul    edx
  283.     add    ebx,eax
  284.     adc    edi,edx
  285.  
  286.     mov    eax,DWORD PTR _VS_sfac9
  287.     mov    edx,DWORD PTR es:[si].V_z
  288.     sub    edx,DWORD PTR _VS_iview_z
  289.     imul    edx
  290.     add    ebx,eax
  291.     adc    edi,edx
  292.  
  293.     shrd    ebx,edi,27 ;29-PRESCALEZ
  294.     adc    ebx,0
  295.  
  296.     mov    DWORD PTR es:[si].V_cz,ebx
  297.     or     BYTE PTR es:[si].V_zxflag,80h
  298.  
  299.     xor    ax,ax
  300.     cmp    ebx,DWORD PTR _VS_hither4
  301.     jge    nonhither
  302.     or    al,OHITHER
  303. nonhither:
  304.     cmp     ebx,DWORD PTR _VS_yon4
  305.     jle    nonyon
  306.     or    al,OYON
  307. nonyon:
  308.     mov     BYTE PTR es:[si].V_zocode,al
  309. already_z:
  310.     movzx   ax,BYTE PTR es:[si].V_zocode
  311.  
  312.     pop    edi
  313.     pop    esi
  314.  
  315.     mov    esp,ebp
  316.     pop    ebp
  317.     ret
  318.  
  319. _z_convert_vertex    endp
  320.  
  321.  
  322. ;/*********** POLYGON BACKFACE TEST ***********/
  323.  
  324. ; int is_poly_facing(POLY *p);
  325. ; returns sign of visibility dot product
  326.  
  327.  
  328. p      equ    DWORD PTR [bp+8]        ; arguments
  329.  
  330. nx    equ    DWORD PTR [bp-4]    ; locals
  331. ny    equ    DWORD PTR [bp-8]
  332. nz    equ    DWORD PTR [bp-12]
  333.  
  334.     PUBLIC    _is_poly_facing
  335.  
  336. _is_poly_facing    proc    far
  337.  
  338.     push    ebp
  339.     mov    ebp,esp
  340.     sub    esp,20
  341.  
  342.     push    esi
  343.     push    edi
  344.  
  345.     les    bx,DWORD PTR p
  346.  
  347.     mov     edx,DWORD PTR es:[bx].P_normx    ; get normals
  348.     mov    eax,DWORD PTR es:[bx].P_normy
  349.     mov    DWORD PTR ny,eax
  350.     mov    eax,DWORD PTR es:[bx].P_normz
  351.     mov    DWORD PTR nz,eax
  352.  
  353.     les    bx,DWORD PTR es:[bx].P_points   ; get first vertex
  354.     les    bx,es:[bx]
  355.  
  356.     mov    eax,DWORD PTR es:[bx].V_x    ; compute dot product
  357.     sub    eax,DWORD PTR _VS_iview_x        ; with VP to poly line
  358.     imul    edx
  359.     mov    esi,eax
  360.     mov    edi,edx
  361.  
  362.     mov    eax,DWORD PTR es:[bx].V_y
  363.     sub    eax,DWORD PTR _VS_iview_y
  364.     imul    DWORD PTR ny
  365.     add    esi,eax
  366.     adc    edi,edx
  367.  
  368.     mov    eax,DWORD PTR es:[bx].V_z
  369.     sub    eax,DWORD PTR _VS_iview_z
  370.     imul    DWORD PTR nz
  371.     add    esi,eax
  372.     adc    edi,edx
  373.     mov    ax,-1
  374.     jl      proceed
  375.     mov    ax,0
  376.     je    proceed
  377.     mov    ax,1
  378.  
  379. proceed:
  380.     pop    edi
  381.     pop    esi
  382.  
  383.     mov    esp,ebp
  384.     pop    ebp
  385.     ret
  386.  
  387. _is_poly_facing    endp
  388.  
  389.  
  390.  
  391. ;/*********** CLIP HITHER Z COORD OF VERTEX ***********/
  392.  
  393. ; creates new vertex from hither plane intercept of edge
  394. ; allocates new vertex
  395. ;
  396. ; NVERTEX *z_hither_clip(NVERTEX *v1, NVERTEX *v2);
  397.  
  398.  
  399. v1      equ    DWORD PTR [bp+8]        ; arguments
  400. v2      equ    DWORD PTR [bp+12]
  401.  
  402. x1    equ    DWORD PTR [bp-4]    ; locals
  403. y1    equ    DWORD PTR [bp-8]
  404. z1    equ    DWORD PTR [bp-12]
  405. x2    equ    DWORD PTR [bp-16]
  406. y2    equ    DWORD PTR [bp-20]
  407. z2    equ    DWORD PTR [bp-24]
  408.  
  409.     PUBLIC    _z_hither_clip
  410.  
  411. _z_hither_clip    proc    far
  412.  
  413.     push    ebp
  414.     mov    ebp,esp
  415.     sub    esp,30
  416.  
  417.     push    ecx
  418.  
  419.     les    bx,DWORD PTR v1
  420.     mov    eax, es:[bx].NV_x
  421.     mov    DWORD PTR x1,eax
  422.     mov    eax, es:[bx].NV_y
  423.     mov    DWORD PTR y1,eax
  424.     mov    eax, es:[bx].NV_z
  425.     mov    DWORD PTR z1,eax
  426.  
  427.     les    bx,DWORD PTR v2
  428.     mov    eax, es:[bx].NV_x
  429.     mov    DWORD PTR x2,eax
  430.     mov    eax, es:[bx].NV_y
  431.     mov    DWORD PTR y2,eax
  432.     mov    eax, es:[bx].NV_z
  433.     mov    DWORD PTR z2,eax
  434.  
  435.     ALLOCVTX    ; returns new vertex in es:bx
  436.             ; also in _nvalloc
  437.  
  438.     mov    ecx,z1       ;/* compute denominator */
  439.     sub    ecx,z2
  440.     je    zero_clipz   ; zero!
  441.     jg    other_way    ; always clip in same direction
  442.  
  443.     mov    eax, _VS_hither4   ;/* compute new x */
  444.     sub    eax,z2
  445.     mov    edx,x1
  446.     sub    edx,x2
  447.     imul    edx
  448.     idiv    ecx
  449.     add    eax,x2
  450.     mov    es:[bx].NV_x,eax
  451.  
  452.     mov    eax, _VS_hither4   ;/* compute new y */
  453.     sub    eax,z2
  454.     mov    edx,y1
  455.     sub    edx,y2
  456.     imul    edx
  457.     idiv    ecx
  458.     add    eax,y2
  459.     mov     es:[bx].NV_y,eax
  460.     jmp    endclipz
  461.  
  462. other_way:
  463.     neg    ecx
  464.  
  465.     mov    eax, _VS_hither4   ;/* compute new x */
  466.     sub    eax,z1
  467.     mov    edx,x2
  468.     sub    edx,x1
  469.     imul    edx
  470.     idiv    ecx
  471.     add    eax,x1
  472.     mov    es:[bx].NV_x,eax
  473.  
  474.     mov    eax, _VS_hither4   ;/* compute new y */
  475.     sub    eax,z1
  476.     mov    edx,y2
  477.     sub    edx,y1
  478.     imul    edx
  479.     idiv    ecx
  480.     add    eax,y1
  481.     mov     es:[bx].NV_y,eax
  482.     jmp    endclipz
  483.  
  484.  
  485. zero_clipz:
  486.     mov    eax,x1
  487.     mov    es:[bx].NV_x,eax
  488.     mov    eax,y1
  489.     mov    es:[bx].NV_y,eax
  490. endclipz:
  491.     mov    eax,DWORD PTR _VS_hither4
  492.     mov    DWORD PTR es:[bx].NV_z,eax
  493.  
  494.     mov    eax,_nvalloc
  495.     shld    edx,eax,16
  496.  
  497.     pop    ecx
  498.  
  499.     mov    esp,ebp
  500.     pop    ebp
  501.     ret
  502.  
  503. _z_hither_clip    endp
  504.  
  505.  
  506.  
  507. ;/************ COMPUTE AVERAGE DEPTH ************/
  508.  
  509. ; long average_nvertex_depth(NVERTEX **nvp, int ncount);
  510. ; retruns average poly depth
  511.  
  512. nvp    equ    DWORD PTR [bp+8]
  513. ncount    equ    WORD PTR [bp+12]
  514.  
  515.     PUBLIC    _average_nvertex_depth
  516.  
  517. _average_nvertex_depth    proc    far
  518.  
  519.     push    ebp
  520.     mov    ebp,esp
  521.  
  522.     push    ecx
  523.  
  524.     mov    cx,ncount
  525. nextvtx:
  526.     les    bx,nvp
  527.     add    WORD PTR nvp,4
  528.     les    bx,DWORD PTR es:[bx]
  529.     add    eax,es:[bx].NV_z
  530.     adc    edx,0
  531.     dec    cx
  532.     jg    nextvtx
  533.  
  534.     movzx    ecx,WORD PTR ncount
  535.     idiv    ecx
  536.  
  537.     shld    edx,eax,16
  538.  
  539.     pop    ecx        ; prescaled depth, x4
  540.  
  541.     mov    esp,ebp
  542.     pop    ebp
  543.     ret
  544.  
  545. _average_nvertex_depth    endp
  546.  
  547.  
  548. ;/************ COMPUTE MAXIMUM DEPTH ************/
  549.  
  550. ; long deepest_nvertex_depth(NVERTEX **nvp, int ncount);
  551. ; retruns average poly depth
  552.  
  553. nvp    equ    DWORD PTR [bp+8]
  554. ncount    equ    WORD PTR [bp+12]
  555.  
  556.     PUBLIC    _deepest_nvertex_depth
  557.  
  558. _deepest_nvertex_depth    proc    far
  559.  
  560.     push    ebp
  561.     mov    ebp,esp
  562.  
  563.     mov    dx,ncount
  564.     mov    eax,080000001h    ; big negative
  565. nextdvtx:
  566.     les    bx,nvp
  567.     add    WORD PTR nvp,4
  568.     les    bx,DWORD PTR es:[bx]
  569.     cmp    eax,es:[bx].NV_z
  570.     jge    nodeeper
  571.     mov    eax,es:[bx].NV_z
  572. nodeeper:
  573.     dec    dx
  574.     jg    nextdvtx
  575.  
  576.     shld    edx,eax,16
  577.  
  578.     mov    esp,ebp         ; prescaled depth, x4
  579.     pop    ebp
  580.     ret
  581.  
  582. _deepest_nvertex_depth    endp
  583.  
  584.  
  585.  
  586.     end
  587.