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

  1. /*  QMAP: Quake level viewer
  2.  *
  3.  *   render.c  Copyright 1997 Sean Barrett 
  4.  *
  5.  *   "render" scenes by traversing over the
  6.  *   database, marking already-visited things,
  7.  *   using the PVS information and the "marksurface"
  8.  *   info; use one bsp routine to sort
  9.  */
  10.  
  11. #include "bspfile.h"
  12. #include "3d.h"
  13. #include "render.h"
  14. #include "bsp.h"
  15. #include "scr.h"
  16. #include "poly.h"
  17.  
  18. char vis_face[MAX_MAP_FACES/8+1];
  19. char vis_leaf[MAX_MAP_LEAFS/8+1];
  20.  
  21. #define is_marked(x)     (vis_face[(x) >> 3] &   (1 << ((x) & 7)))
  22. #define mark_face(x)     (vis_face[(x) >> 3] |=  (1 << ((x) & 7)))
  23. #define unmark_face(x)   (vis_face[(x) >> 3] &= ~(1 << ((x) & 7)))
  24.  
  25. #if 1
  26.   // this works if IEEE, sizeof(float) == sizeof(int)
  27.   #define FLOAT_POSITIVE(x)   (* (int *) (x) >= 0)
  28. #else
  29.   #define FLOAT_POSITIVE(x)   ((x) >= 0)
  30. #endif
  31.  
  32. int bbox_inside_plane(short *mins, short *maxs, dplane_t *plane)
  33. {
  34.    int i;
  35.    short pt[3];
  36.  
  37.    // use quick test from graphics gems
  38.  
  39.    for (i=0; i < 3; ++i)
  40.       if (FLOAT_POSITIVE(&plane->normal[i])) // fast test assuming IEEE
  41.          pt[i] = maxs[i];
  42.       else
  43.          pt[i] = mins[i];
  44.  
  45.    return plane->normal[0]*pt[0] + plane->normal[1]*pt[1]
  46.         + plane->normal[2]*pt[2] >= plane->dist;
  47. }
  48.  
  49. int node_in_frustrum(dnode_t *node, dplane_t *planes)
  50. {
  51.    if (!bbox_inside_plane(node->mins, node->maxs, planes+0)
  52.     || !bbox_inside_plane(node->mins, node->maxs, planes+1)
  53.     || !bbox_inside_plane(node->mins, node->maxs, planes+2)
  54.     || !bbox_inside_plane(node->mins, node->maxs, planes+3))
  55.       return 0;
  56.    return 1;
  57. }
  58.  
  59. int leaf_in_frustrum(dleaf_t *node, dplane_t *planes)
  60. {
  61.    if (!bbox_inside_plane(node->mins, node->maxs, planes+0)
  62.     || !bbox_inside_plane(node->mins, node->maxs, planes+1)
  63.     || !bbox_inside_plane(node->mins, node->maxs, planes+2)
  64.     || !bbox_inside_plane(node->mins, node->maxs, planes+3))
  65.       return 0;
  66.    return 1;
  67. }
  68.  
  69. void mark_leaf_faces(int leaf)
  70. {
  71.    int n = dleafs[leaf].nummarksurfaces;
  72.    int ms = dleafs[leaf].firstmarksurface;
  73.    int i;
  74.  
  75.    for (i=0; i < n; ++i) {
  76.       int s = dmarksurfaces[ms+i];
  77.       if (!is_marked(s)) {
  78.          mark_face(s);
  79.       }
  80.    }
  81. }
  82.  
  83. int visit_visible_leaves(vector *cam_loc)
  84. {
  85.    int n, v, i;
  86.  
  87.    memset(vis_leaf, 0, sizeof(vis_leaf));
  88.  
  89.    n = find_leaf(cam_loc);
  90.  
  91.    if (n == 0 || dleafs[n].visofs < 0)
  92.       return 0;
  93.  
  94.    v = dleafs[n].visofs;
  95.    for (i = 1; i < numleafs; ) { 
  96.       if (dvisdata[v] == 0) {
  97.          i += 8 * dvisdata[v+1];    // skip some leaves
  98.          v+=2;
  99.       } else {
  100.          int j;
  101.          for (j = 0; j <8; j++, i++)
  102.             if (dvisdata[v] & (1<<j) )
  103.                vis_leaf[i>>3] |= (1 << (i & 7));
  104.          ++v;
  105.       }
  106.    }
  107.    return 1;
  108. }
  109.  
  110. // during a bsp recursion, draw all of the faces
  111. // stored on this node which are visible (i.e. just
  112. // test their mark flag)
  113. void render_node_faces(int node, int side)
  114. {
  115.    int i,n,f;
  116.    n = dnodes[node].numfaces;
  117.    f = dnodes[node].firstface;
  118.    for (i=0; i < n; ++i) {
  119.       if (is_marked(f)) {
  120.          if (dfaces[f].side == side)
  121.             draw_face(f);
  122.          unmark_face(f);
  123.       }
  124.       ++f;
  125.    }
  126. }
  127.  
  128. void render_world(vector *loc)
  129. {
  130.    dplane_t planes[4];
  131.    compute_view_frustrum(planes);
  132.  
  133.    if (!visit_visible_leaves(loc)) {
  134.       memset(scr_buf, 0, 320*200);
  135.       memset(vis_leaf, 255, sizeof(vis_leaf));
  136.    }
  137.  
  138.    bsp_visit_visible_leaves(loc, planes);
  139.    bsp_render_world(loc, planes);
  140. }
  141.