home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / qmapwos / src / poly.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-09  |  2.9 KB  |  135 lines

  1. /*  QMAP: Quake level viewer
  2.  *
  3.  *   poly.c    Copyright 1997 Sean Barett
  4.  *
  5.  *   Render a Quake polygon:
  6.  *      read it from the db
  7.  *      transform it into 3d
  8.  *      clip it in 3d
  9.  *      compute the 2d texture gradients
  10.  *      scan convert
  11.  *      pass off the spans
  12.  */
  13.  
  14. #include "bspfile.h"
  15. #include "fix.h"
  16. #include "3d.h"
  17. #include "tm.h"
  18. #include "tmap3d.h"
  19. #include "surface.h"
  20.  
  21. point_3d pts[32], *default_vlist[32];
  22.  
  23. void setup_default_point_list(void)
  24. {
  25.    int i;
  26.    for (i=0; i < 32; ++i)
  27.       default_vlist[i] = &pts[i];
  28. }
  29.  
  30. fix scan[768][2];
  31.  
  32. void scan_convert(point_3d *a, point_3d *b)
  33. {
  34.    void *temp;
  35.    int right;
  36.    fix x,dx;
  37.    int y,ey;
  38.  
  39.    if (a->sy == b->sy)
  40.       return;
  41.  
  42.    if (a->sy < b->sy) {
  43.       right = 0;
  44.    } else {
  45.       temp = a;
  46.       a = b;
  47.       b = temp;
  48.       right = 1;
  49.    }
  50.  
  51.    // compute dxdy
  52.    dx = FLOAT_TO_INT(65536.0 * (b->sx - a->sx) / (b->sy - a->sy));
  53.    x = a->sx;
  54.    y = fix_cint(a->sy);
  55.    ey = fix_cint(b->sy);
  56.  
  57.    // fixup x location to 'y' (subpixel correction in y)
  58.    x += FLOAT_TO_INT(((double) dx * ((y << 16) - a->sy)) / 65536.0);
  59.  
  60.    while (y < ey) {
  61.       scan[y][right] = x;
  62.       x += dx;
  63.       ++y;
  64.    }
  65. }
  66.  
  67. void draw_poly(int n, point_3d **vl)
  68. {
  69.    int i,j, y,ey;
  70.    fix ymin,ymax;
  71.  
  72.    // find max and min y height
  73.    ymin = ymax = vl[0]->sy;
  74.    for (i=1; i < n; ++i) {
  75.            if (vl[i]->sy < ymin) ymin = vl[i]->sy;
  76.       else if (vl[i]->sy > ymax) ymax = vl[i]->sy;
  77.    }
  78.    
  79.    // scan out each edge
  80.    j = n-1;
  81.    for (i=0; i < n; ++i) {
  82.       scan_convert(vl[i], vl[j]);
  83.       j = i;
  84.    }
  85.  
  86.     y = fix_cint(ymin);
  87.    ey = fix_cint(ymax);
  88.  
  89.    // iterate over all spans and draw
  90.  
  91.    while (y < ey) {
  92.       int sx = fix_cint(scan[y][0]), ex = fix_cint(scan[y][1]);
  93.       if (sx < ex)
  94.          qmap_draw_span(y, sx, ex);
  95.       ++y;
  96.    }
  97. }
  98.  
  99. void draw_face(int face)
  100. {
  101.    int n = dfaces[face].numedges;
  102.    int se = dfaces[face].firstedge;
  103.    int i,codes_or=0,codes_and=0xff;
  104.    point_3d **vlist;
  105.  
  106.    for (i=0; i < n; ++i) {
  107.       int edge = dsurfedges[se+i];
  108.       if (edge < 0)
  109.          transform_point(&pts[i], (vector *) VERTEX(dedges[-edge].v[1]));
  110.       else
  111.          transform_point(&pts[i], (vector *) VERTEX(dedges[ edge].v[0]));
  112.       codes_or  |= pts[i].ccodes;
  113.       codes_and &= pts[i].ccodes;
  114.    }
  115.  
  116.    if (codes_and) return;  // abort if poly outside frustrum
  117.  
  118.    if (codes_or) {
  119.       // poly crosses frustrum, so clip it
  120.       n = clip_poly(n, default_vlist, codes_or, &vlist);
  121.    } else
  122.       vlist = default_vlist;
  123.  
  124.    if (n) {
  125.       bitmap bm;
  126.       float u,v;
  127.       int tex = dfaces[face].texinfo;
  128.       int mip = compute_mip_level(face);
  129.       get_tmap(&bm, face, texinfo[tex].miptex, mip, &u, &v);
  130.       qmap_set_texture(&bm);
  131.       compute_texture_gradients(face, tex, mip, u, v);
  132.       draw_poly(n, vlist);
  133.    }
  134. }
  135.