home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / refresh.c < prev    next >
C/C++ Source or Header  |  1996-03-19  |  10KB  |  330 lines

  1. /* COMPLETELY rewritten by Dave Stampe Dec. 1993, */
  2. /* used to be render.c, now split off to uservid.c and this file */
  3.  
  4. // This code is the refresh-screen call.  All the other stuff was
  5. // moved to uservid.c
  6. // Also has Dave's axis-compass (much improved) and the new
  7. // prerender/postrender support
  8.  
  9.  
  10. /*
  11.  This code is part of the VR-386 project, created by Dave Stampe.
  12.  VR-386 is a desendent of REND386, created by Dave Stampe and
  13.  Bernie Roehl.  Almost all the code has been rewritten by Dave
  14.  Stampre for VR-386.
  15.  
  16.  Copyright (c) 1994 by Dave Stampe:
  17.  May be freely used to write software for release into the public domain
  18.  or for educational use; all commercial endeavours MUST contact Dave Stampe
  19.  (dstampe@psych.toronto.edu) for permission to incorporate any part of
  20.  this software or source code into their products!  Usually there is no
  21.  charge for under 50-100 items for low-cost or shareware products, and terms
  22.  are reasonable.  Any royalties are used for development, so equipment is
  23.  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 VR-386 and Dave Stampe,
  27.  and any other authors in your documentation, source code, and at startup
  28.  of your program.  Let's keep the freeware ball rolling!
  29.  
  30.  DEVELOPMENT: VR-386 is a effort to develop the process started by
  31.  REND386, improving programmer access by rewriting the code and supplying
  32.  a standard API.  If you write improvements, add new functions rather
  33.  than rewriting current functions.  This will make it possible to
  34.  include you improved code in the next API release.  YOU can help advance
  35.  VR-386.  Comments on the API are welcome.
  36.  
  37.  CONTACT: dstampe@psych.toronto.edu
  38. */
  39.  
  40.  
  41. #include <stdio.h>
  42. #include <dos.h>
  43. #include <stdlib.h>    /* labs */
  44.  
  45. #include "f3dkitd.h"
  46.  
  47. #include "vr_api.h"
  48. #include "pcdevice.h"    // register_render_start,end
  49. #include "intmath.h"
  50. #include "splits.h"
  51.  
  52. #define MAIN_VGA  1  /* for multi-VGA only */
  53. #define LEFT_VGA  2
  54. #define RIGHT_VGA 4
  55. #define ALL_VGA   7
  56.  
  57. #define MONOSCOPIC 0 /* stereo types */
  58. #define SWITCHED   1
  59. #define SPLITLR    3
  60. #define SEPARATE   5
  61.  
  62. extern struct Screeninfo *screeninfo;
  63.  
  64. extern int swap_eyes;
  65.  
  66. extern int show_location, show_compass, show_framerate;  // options
  67. extern int use_glove;
  68.  
  69. extern void user_draw_line(int x1, int y1, int x2, int y2, int color);
  70.  
  71.  
  72.     // draw an axis compass
  73.     // placed at abs. screen position and size
  74.     // has visibility sort, but no perspective
  75.     // usually just draw one eye for stereo,
  76.     // since results are disappointing without perspective
  77.  
  78.  
  79. static do_axis(int xc, int yc, int x, int y, int bcolor, int xcolor, char c)
  80. {
  81.   char st[] = "x";
  82.  
  83.   st[0] = c;
  84.  
  85.   if (current_orientation & XFLIP)
  86.     {
  87.       user_draw_line(xc,yc,xc-x,yc-y,bcolor);
  88.       user_text(xc-x-5,yc-y,bcolor,st);
  89.       user_draw_line(xc-1,yc+1,xc-1-x,yc+1-y,xcolor);
  90.       user_text(xc-x-5-1,yc-y+1,xcolor,st);
  91.     }
  92.   else
  93.     {
  94.       user_draw_line(xc,yc,x+xc,yc-y,bcolor);
  95.       user_text(x+xc+5,yc-y,bcolor,st);
  96.       user_draw_line(xc+1,yc+1,x+xc+1,yc-y+1,xcolor);
  97.       user_text(x+xc+5+1,yc-y+1,xcolor,st);
  98.     }
  99. }
  100.  
  101.     // xc,yx : screen location of center
  102.     // V : viewport
  103.     // xcolor,ycolor,zcolor: color of axes
  104.     // bcolor: "shadow" color
  105.  
  106. void coord_ref(WORD xc, WORD yc, WORD size, VIEW *v,
  107.               WORD xcolor, WORD ycolor, WORD zcolor, WORD bcolor)
  108. {
  109.   MATRIX m;
  110.   int i;
  111.   long x[3], y[3], z[3];               // coords from axes
  112.   int order[3] = {0,1,2};              // sort terms
  113.   int color[3];
  114.   char label[3] = {'x','y','z'};          // labels
  115.  
  116.   if (show_compass == 0) return;
  117.  
  118.   color [0] = xcolor;
  119.   color [1] = ycolor;
  120.   color [2] = zcolor;
  121.  
  122.   view_to_matrix(v,m);            // transform for axes
  123.   m[3][0] = m[3][1] = m[3][2] = 0;
  124.   matrix_transpose(m,m);
  125.  
  126.  
  127.   x[0] = size;  y[0] = 0;     z[0] = 0;    // axes to screen locations
  128.   x[1] = 0;     y[1] = size;  z[1] = 0;
  129.   x[2] = 0;     y[2] = 0;     z[2] = size;
  130.  
  131.   matrix_point(m, &x[0], &y[0], &z[0]);
  132.   matrix_point(m, &x[1], &y[1], &z[1]);
  133.   matrix_point(m, &x[2], &y[2], &z[2]);
  134.                        // aspect ratio fixup
  135.   y[0] = mulmuldiv(y[0],screeninfo->aspect,65536L);
  136.   y[1] = mulmuldiv(y[1],screeninfo->aspect,65536L);
  137.   y[2] = mulmuldiv(y[2],screeninfo->aspect,65536L);
  138.  
  139.   if (z[order[0]]<=z[order[1]])      // sort by depth so deepest first
  140.     {
  141.       i = order[0];
  142.       order[0] = order[1];
  143.       order[1] = i;
  144.     }
  145.   if (z[order[0]]<=z[order[2]])
  146.     {
  147.       i = order[0];
  148.       order[0] = order[2];
  149.       order[2] = i;
  150.     }
  151.   if (z[order[1]]<=z[order[2]])
  152.     {
  153.       i = order[1];
  154.       order[1] = order[2];
  155.       order[2] = i;
  156.     }
  157.  
  158.   do_axis(xc,yc, x[order[0]], y[order[0]], bcolor, color[order[0]], label[order[0]]);
  159.   do_axis(xc,yc, x[order[1]], y[order[1]], bcolor, color[order[1]], label[order[1]]);
  160.   do_axis(xc,yc, x[order[2]], y[order[2]], bcolor, color[order[2]], label[order[2]]);
  161. }
  162.  
  163.  
  164. static VIEW left_view, right_view;
  165.  
  166. void stop_stereo()
  167. {
  168.    right_page = left_page = current_video_page; /* stop stereo for now */
  169. }
  170.  
  171.  
  172.  
  173.  
  174. //////////////////////////////////////////
  175. ///  THESE ROUTINES LET YOU CONTROL HOW THE
  176. ///  SCREEN IS CLEARED AND WHAT IS DISPLAYED
  177. ///  THE ARGUMENTS ARE:
  178. ///  v : the view being draw.  left/right eye views are different
  179. ///  vpage: the video page being drawn
  180. ///  isfirst, islast:  1 if this is the first/last access to the
  181. ///                    video page.  Useful for toggling screen
  182. ///               clears etc. when several views are on the
  183. ///               same page
  184. ///  whicheye:  0 for left eye/mono, 1 for right eye view
  185. ///
  186.  
  187.  
  188. // found in <USCREEN.C>
  189.  
  190.     // This is called before drawing objects.  It should
  191.     // at least clear the screen
  192.  
  193. void prerender_process(VIEW *v, unsigned vpage, WORD isfirst, WORD whicheye);
  194.  
  195.     // This is called after drawing objects.  It can be used
  196.     // to put up status, etc.
  197.     // lots of if() stuff, but just because we're supporting
  198.     // so many stereo types
  199.  
  200. void postrender_process(VIEW *v, unsigned vpage, WORD islast, WORD whicheye);
  201.  
  202.  
  203.  
  204.     // where to save the screen while using menus
  205. WORD screen_save_video_page = 1;
  206. static WORD last_visible_video_page = 0;
  207. BOOL screen_has_been_saved = FALSE;
  208.  
  209.  
  210. extern int reframe;
  211.  
  212. void screen_refresh(CAMERA *c) /* now does stereo drawing */
  213. {
  214.  int mxpge = 2;
  215.  char st[100];
  216.  VIEW *v;
  217.  BOOL was_visible;
  218.  
  219.  register_render_start();
  220.  
  221.  screen_save_video_page = current_video_page;
  222.  last_visible_video_page = current_video_page;
  223.  
  224.  if (screeninfo->pages < 3) mxpge = 1; else mxpge = 2;
  225.  if(mxpge<2)  vsync();
  226.  
  227.  if (stereo_type == MONOSCOPIC)
  228.    {
  229.      current_video_page++;
  230.      if (current_video_page > mxpge) current_video_page = 0;
  231.      was_visible = last_cursor_hide(current_video_page);
  232.  
  233.      set_drawpage(current_video_page);
  234.  
  235.      v = select_camera_view(c,0);
  236.      prerender_process(v, current_video_page, 1, 0);
  237.      render_split(global_world_root, v);
  238.      postrender_process(v, current_video_page, 1, 0);
  239.      set_vpage(current_video_page);
  240.    }
  241.  else if (stereo_type==SPLITLR)
  242.    {
  243.      current_video_page++;
  244.      if (current_video_page > mxpge) current_video_page = 0;
  245.  
  246.      was_visible = last_cursor_hide(current_video_page);
  247.      v = select_camera_view(c,LEFT_EYE);
  248.      set_drawpage(current_video_page);
  249.      prerender_process(v, current_video_page, 1, 0&LEFT_EYE);
  250.      render_split(global_world_root, v);
  251.      postrender_process(v, current_video_page, 0, LEFT_EYE);
  252.  
  253.      v = select_camera_view(c,RIGHT_EYE);
  254.      set_drawpage(current_video_page);
  255.      prerender_process(v, current_video_page, 0, RIGHT_EYE);
  256.      set_drawpage(current_video_page);
  257.      render_split(global_world_root, v);
  258.      postrender_process(v, current_video_page, 1, RIGHT_EYE);
  259.  
  260.      set_vpage(current_video_page);
  261.  
  262.    }
  263.  else if (stereo_type == SWITCHED)
  264.    {
  265.      current_video_page = current_video_page ^ 2;  // need 4 pages for this!
  266.  
  267.      was_visible = last_cursor_hide(current_video_page);
  268.      v = select_camera_view(c,LEFT_EYE);
  269.      while ((has_switched&1) == 0) if (kbhit()) break;  // wait if not seen yet
  270.      set_drawpage(current_video_page);
  271.      prerender_process(v, current_video_page, 1, LEFT_EYE);
  272.      render_split(global_world_root, v);
  273.      postrender_process(v, current_video_page, 1, LEFT_EYE);
  274.  
  275.      v = select_camera_view(c,RIGHT_EYE);
  276.      while ((has_switched&2) == 0) if (kbhit()) break;
  277.      set_drawpage(current_video_page+1);
  278.      prerender_process(v, current_video_page+1, 1, RIGHT_EYE);
  279.      render_split(global_world_root, v);
  280.      postrender_process(v, current_video_page+1, 1, RIGHT_EYE);
  281.  
  282.      disable();
  283.      if (swap_eyes)
  284.        {
  285.      left_page = current_video_page+1; /* display them now */
  286.      right_page = current_video_page;
  287.        }
  288.      else
  289.        {
  290.      left_page = current_video_page;
  291.      right_page = current_video_page+1;
  292.        }
  293.      has_switched = 0;
  294.      enable();
  295.    }
  296.  else if (stereo_type == SEPARATE)   // seperate VGA buffers
  297.    {
  298.      current_video_page++;
  299.      if (current_video_page > mxpge) current_video_page = 0;
  300.  
  301.      was_visible = last_cursor_hide(current_video_page);
  302.      set_drawpage(current_video_page);
  303.      VGA_select(swap_eyes ? RIGHT_VGA : LEFT_VGA);
  304.      v = select_camera_view(c,LEFT_EYE);
  305.      prerender_process(v, current_video_page, 1, LEFT_EYE);
  306.      render_split(global_world_root, v);
  307.      postrender_process(v, current_video_page, 1, LEFT_EYE);
  308.  
  309.      VGA_select(swap_eyes ? LEFT_VGA : RIGHT_VGA);
  310.      v = select_camera_view(c,RIGHT_EYE);
  311.      prerender_process(v, current_video_page, 1, RIGHT_EYE);
  312.      render_split(global_world_root, v);
  313.      postrender_process(v, current_video_page, 1, RIGHT_EYE);
  314.  
  315.      VGA_select(LEFT_VGA);
  316.      set_vpage(current_video_page);
  317.      VGA_select(RIGHT_VGA);
  318.      set_vpage(current_video_page);
  319.      VGA_select(MAIN_VGA);        // usually same as left
  320.    }
  321.  
  322.  register_render_end();
  323.  
  324.  cursor_show();                // draw to current page
  325.  set_drawpage(current_video_page);
  326.  screen_has_been_saved = FALSE;
  327. }
  328.  
  329.  
  330.