Back to index

radiance  4R0+20100331
Defines | Functions | Variables
rhd_ogl.c File Reference
#include <time.h>
#include <GL/glx.h>
#include <GL/glu.h>
#include "standard.h"
#include "rhd_odraw.h"
#include "rhdisp.h"
#include "paths.h"
#include "x11icon.h"

Go to the source code of this file.

Defines

#define RAYQLEN   0 /* max. rays to queue before flush */
#define MINWIDTH   480 /* minimum graphics window width */
#define MINHEIGHT   400 /* minimum graphics window height */
#define VIEWDIST   356 /* assumed viewing distance (mm) */
#define BORWIDTH   5 /* border width */
#define FEQ(a, b)   ((a)-(b) <= FTINY && (a)-(b) >= -FTINY)
#define VWHEADLOCK   01 /* head position is locked flag */
#define VWPERSP   02 /* perspective view is set */
#define VWORTHO   04 /* orthographic view is set */
#define VWCHANGE   010 /* view has changed */
#define VWSTEADY   020 /* view is now steady */
#define VWMAPPED   040 /* window is mapped */
#define GAMMA   1.4 /* default gamma correction */
#define FRAMESTATE(s)   (((s)&(ShiftMask|ControlMask))==(ShiftMask|ControlMask))
#define MOVPCT   7 /* percent distance to move /frame */
#define MOVDIR(b)   ((b)==Button1 ? 1 : (b)==Button2 ? 0 : -1)
#define MOVDEG   (-5) /* degrees to orbit CW/down /frame */
#define MOVORB(s)   ((s)&ShiftMask ? 1 : (s)&ControlMask ? -1 : 0)
#define setstereobuf(bid)
#define ourscreen   DefaultScreen(ourdisplay)
#define ourroot   RootWindow(ourdisplay,ourscreen)
#define ourmask
#define levptr(etype)   ((etype *)&currentevent)
#define setzrat()   (dev_zrat = 1. - dev_zmin/dev_zmax)
#define mapdepth(d)   ((d)>0.9995 ? FHUGE : dev_zmin/(1.-(d)*dev_zrat))

Functions

static void checkglerr (char *where)
static void xferdepth (void)
static void freedepth (void)
static double getdistance (int dx, int dy, FVECT direc)
static int mytmflags (void)
static void getevent (void)
static void draw3dline (register FVECT wp[2])
static void draw_grids (int fore)
static int moveview (int dx, int dy, int mov, int orb)
static void getframe (XButtonPressedEvent *ebut)
static void getmove (XButtonPressedEvent *ebut)
static void getkey (register XKeyPressedEvent *ekey)
static void fixwindow (register XExposeEvent *eexp)
static void resizewindow (register XConfigureEvent *ersz)
static void waitabit (void)
static void setglpersp (void)
static void setglortho (void)
static void wipeclean (void)
time_t time ()
void dev_open (char *id)
void dev_close (void)
void dev_clear (void)
int dev_view (register VIEW *nv)
void dev_section (char *gfn, char *pfn)
void dev_auxcom (char *cmd, char *args)
VIEWdev_auxview (int n, int hvres[2])
int dev_input (void)
void dev_value (COLR c, FVECT d, FVECT p)
int dev_flush (void)

Variables

static const char RCSid [] = "$Id: rhd_ogl.c,v 3.30 2006/06/07 17:52:04 schorsch Exp $"
TMstructtmGlobal
char odev_args [64]
static GLfloat * depthbuffer = NULL
static int rayqleft = 0
static XEvent currentevent
static unsigned long ourblack = 0
static unsigned long ourwhite = ~0
static Display * ourdisplay = NULL
static XVisualInfo * ourvinf
static Window gwind = 0
static GLXContext gctx
static double pwidth
static double pheight
static double dev_zmin
static double dev_zmax
static double dev_zrat
static int inpresflags
static int viewflags
int gmPortals

Define Documentation

#define BORWIDTH   5 /* border width */

Definition at line 49 of file rhd_ogl.c.

#define FEQ (   a,
 
)    ((a)-(b) <= FTINY && (a)-(b) >= -FTINY)

Definition at line 53 of file rhd_ogl.c.

#define FRAMESTATE (   s)    (((s)&(ShiftMask|ControlMask))==(ShiftMask|ControlMask))

Definition at line 65 of file rhd_ogl.c.

#define GAMMA   1.4 /* default gamma correction */

Definition at line 63 of file rhd_ogl.c.

#define levptr (   etype)    ((etype *)&currentevent)

Definition at line 81 of file rhd_ogl.c.

#define mapdepth (   d)    ((d)>0.9995 ? FHUGE : dev_zmin/(1.-(d)*dev_zrat))

Definition at line 113 of file rhd_ogl.c.

#define MINHEIGHT   400 /* minimum graphics window height */

Definition at line 43 of file rhd_ogl.c.

#define MINWIDTH   480 /* minimum graphics window width */

Definition at line 42 of file rhd_ogl.c.

#define MOVDEG   (-5) /* degrees to orbit CW/down /frame */

Definition at line 69 of file rhd_ogl.c.

#define MOVDIR (   b)    ((b)==Button1 ? 1 : (b)==Button2 ? 0 : -1)

Definition at line 68 of file rhd_ogl.c.

#define MOVORB (   s)    ((s)&ShiftMask ? 1 : (s)&ControlMask ? -1 : 0)

Definition at line 70 of file rhd_ogl.c.

#define MOVPCT   7 /* percent distance to move /frame */

Definition at line 67 of file rhd_ogl.c.

#define ourmask
Value:
(StructureNotifyMask|ExposureMask|KeyPressMask|\
                     ButtonPressMask|ButtonReleaseMask)

Definition at line 78 of file rhd_ogl.c.

#define ourroot   RootWindow(ourdisplay,ourscreen)

Definition at line 77 of file rhd_ogl.c.

#define ourscreen   DefaultScreen(ourdisplay)

Definition at line 76 of file rhd_ogl.c.

#define RAYQLEN   0 /* max. rays to queue before flush */

Definition at line 39 of file rhd_ogl.c.

#define setstereobuf (   bid)
Value:
(glXWaitGL(), \
                            XSGISetStereoBuffer(ourdisplay, gwind, bid), \
                            glXWaitX())

Definition at line 72 of file rhd_ogl.c.

#define setzrat ( )    (dev_zrat = 1. - dev_zmin/dev_zmax)

Definition at line 112 of file rhd_ogl.c.

#define VIEWDIST   356 /* assumed viewing distance (mm) */

Definition at line 46 of file rhd_ogl.c.

#define VWCHANGE   010 /* view has changed */

Definition at line 59 of file rhd_ogl.c.

#define VWHEADLOCK   01 /* head position is locked flag */

Definition at line 56 of file rhd_ogl.c.

#define VWMAPPED   040 /* window is mapped */

Definition at line 61 of file rhd_ogl.c.

#define VWORTHO   04 /* orthographic view is set */

Definition at line 58 of file rhd_ogl.c.

#define VWPERSP   02 /* perspective view is set */

Definition at line 57 of file rhd_ogl.c.

#define VWSTEADY   020 /* view is now steady */

Definition at line 60 of file rhd_ogl.c.


Function Documentation

static void checkglerr ( char *  where) [static]

Definition at line 526 of file rhd_ogl.c.

{
       register GLenum      errcode;

       while ((errcode = glGetError()) != GL_NO_ERROR) {
              sprintf(errmsg, "OpenGL error %s: %s",
                            where, gluErrorString(errcode));
              error(WARNING, errmsg);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void dev_auxcom ( char *  cmd,
char *  args 
)

Definition at line 405 of file rhd_ogl.c.

{
#ifdef DOBJ
       int    vischange;

       if ((vischange = dobj_command(cmd, args)) >= 0) {
              if (vischange) {
                     imm_mode = beam_sync(1) > 0;
                     dev_clear();
              }
              return;
       }
#endif
       sprintf(errmsg, "%s: unknown command", cmd);
       error(COMMAND, errmsg);
}

Here is the call graph for this function:

VIEW* dev_auxview ( int  n,
int  hvres[2] 
)

Definition at line 427 of file rhd_ogl.c.

{
       hvres[0] = odev.hres; hvres[1] = odev.vres;
       if (n == 0)
              return(&odev.v);
#ifdef STEREO
       if (n == 1)
              return(&vwright);
#endif
       return(NULL);
}
void dev_clear ( void  )

Definition at line 313 of file rhd_ogl.c.

{
       viewflags |= VWCHANGE;             /* pretend our view has changed */
       wipeclean();                /* clean off display and samples */
       dev_flush();                /* redraw geometry & get depth */
       rayqleft = 0;               /* hold off update */
}

Here is the call graph for this function:

void dev_close ( void  )

Definition at line 290 of file rhd_ogl.c.

{
#ifdef DOBJ
       dobj_cleanup();
#endif
       freedepth();
       gmEndGeom();
       gmEndPortal();
       odDone();
       glXMakeCurrent(ourdisplay, None, NULL);
       glXDestroyContext(ourdisplay, gctx);
       XDestroyWindow(ourdisplay, gwind);
       gwind = 0;
       XCloseDisplay(ourdisplay);
       ourdisplay = NULL;
       tmDone(tmGlobal);
       odev.v.type = 0;
       odev.hres = odev.vres = 0;
       odev.ifd = -1;
}

Here is the call graph for this function:

int dev_flush ( void  )

Definition at line 479 of file rhd_ogl.c.

{
       int    ndrawn;

       if ((viewflags&(VWMAPPED|VWPERSP)) == (VWMAPPED|VWPERSP)) {
#ifdef STEREO
              pushright();                /* draw right eye */
              ndrawn = gmDrawGeom();
#ifdef DOBJ
              ndrawn += dobj_render();
#endif
              checkglerr("rendering right eye");
              popright();                 /* draw left eye */
#endif
              ndrawn = gmDrawGeom();
#ifdef DOBJ
              ndrawn += dobj_render();
#endif
              glXSwapBuffers(ourdisplay, gwind);
              checkglerr("rendering base view");
       }
       if ((viewflags&(VWMAPPED|VWSTEADY|VWPERSP|VWORTHO)) ==
                     (VWMAPPED|VWSTEADY|VWPERSP)) {
                                   /* first time after steady */
              if (ndrawn)
                     xferdepth();  /* transfer and clear depth */
              setglortho();        /* set orthographic view */

       }
       if ((viewflags&(VWMAPPED|VWSTEADY|VWPERSP|VWORTHO)) ==
                     (VWMAPPED|VWSTEADY|VWORTHO)) {
                                   /* else update cones */
#ifdef STEREO
              pushright();
              odUpdate(1);         /* draw right eye */
              popright();
#endif
              odUpdate(0);         /* draw left eye */
              glFlush();           /* flush OpenGL */
       }
       rayqleft = RAYQLEN;
                                   /* flush X11 and return # pending */
       return(odev.inpready = XPending(ourdisplay));
}

Here is the call graph for this function:

int dev_input ( void  )

Definition at line 444 of file rhd_ogl.c.

{
       inpresflags = 0;

       do
              getevent();

       while (XPending(ourdisplay) > 0);

       odev.inpready = 0;

       return(inpresflags);
}

Here is the call graph for this function:

void dev_open ( char *  id)

Definition at line 157 of file rhd_ogl.c.

{
       extern char   *getenv();
       static RGBPRIMS      myprims = STDPRIMS;
       static int    atlBest[] = {GLX_RGBA, GLX_DOUBLEBUFFER,
                            GLX_RED_SIZE,8, GLX_GREEN_SIZE,8,
                            GLX_BLUE_SIZE,8, GLX_DEPTH_SIZE,15, None};
       static int    atlOK[] = {GLX_RGBA, GLX_DOUBLEBUFFER,
                            GLX_RED_SIZE,4, GLX_GREEN_SIZE,4,
                            GLX_BLUE_SIZE,4, GLX_DEPTH_SIZE,15, None};
       char   *ev;
       double gamval = GAMMA;
       RGBPRIMP      dpri = stdprims;
       XSetWindowAttributes ourwinattr;
       XWMHints      ourxwmhints;
       XSizeHints    oursizhints;
                                   /* check for unsupported stereo */
#ifdef NOSTEREO
       error(INTERNAL, "stereo display driver unavailable");
#endif
                                   /* open display server */
       ourdisplay = XOpenDisplay(NULL);
       CHECK(ourdisplay==NULL, USER,
                     "cannot open X-windows; DISPLAY variable set?");
#ifdef STEREO
       switch (XSGIQueryStereoMode(ourdisplay, ourroot)) {
       case STEREO_TOP:
       case STEREO_BOTTOM:
              break;
       case STEREO_OFF:
              error(USER,
              "wrong video mode: run \"/usr/gfx/setmon -n STR_TOP\" first");
       case X_STEREO_UNSUPPORTED:
              error(USER, "stereo mode not supported on this screen");
       default:
              error(INTERNAL, "unknown stereo mode");
       }
#endif
                                   /* find a usable visual */
       ourvinf = glXChooseVisual(ourdisplay, ourscreen, atlBest);
       if (ourvinf == NULL)
              ourvinf = glXChooseVisual(ourdisplay, ourscreen, atlOK);
       CHECK(ourvinf==NULL, USER, "no suitable visuals available");
                                   /* get a context */
       gctx = glXCreateContext(ourdisplay, ourvinf, NULL, GL_TRUE);
                                   /* set gamma and tone mapping */
       if ((ev = XGetDefault(ourdisplay, "radiance", "gamma")) != NULL
                     || (ev = getenv("DISPLAY_GAMMA")) != NULL)
              gamval = atof(ev);
       if ((ev = getenv("DISPLAY_PRIMARIES")) != NULL &&
                     sscanf(ev, "%f %f %f %f %f %f %f %f",
                            &myprims[RED][CIEX],&myprims[RED][CIEY],
                            &myprims[GRN][CIEX],&myprims[GRN][CIEY],
                            &myprims[BLU][CIEX],&myprims[BLU][CIEY],
                            &myprims[WHT][CIEX],&myprims[WHT][CIEY]) >= 6)
              dpri = myprims;
       tmGlobal = tmInit(mytmflags(), dpri, gamval);
       if (tmGlobal == NULL)
              error(SYSTEM, "not enough memory in dev_open");
                                   /* open window */
       ourwinattr.background_pixel = ourblack;
       ourwinattr.border_pixel = ourblack;
       ourwinattr.event_mask = ourmask;
                                   /* this is stupid */
       ourwinattr.colormap = XCreateColormap(ourdisplay, ourroot,
                            ourvinf->visual, AllocNone);
       gwind = XCreateWindow(ourdisplay, ourroot, 0, 0,
              DisplayWidth(ourdisplay,ourscreen)-2*BORWIDTH,
#ifdef STEREO
              (DisplayHeight(ourdisplay,ourscreen)-2*BORWIDTH)/2,
#else
              DisplayHeight(ourdisplay,ourscreen)-2*BORWIDTH,
#endif
              BORWIDTH, ourvinf->depth, InputOutput, ourvinf->visual,
              CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &ourwinattr);
       CHECK(gwind==0, SYSTEM, "cannot create window");
       XStoreName(ourdisplay, gwind, id);
                                   /* set window manager hints */
       ourxwmhints.flags = InputHint|IconPixmapHint;
       ourxwmhints.input = True;
       ourxwmhints.icon_pixmap = XCreateBitmapFromData(ourdisplay, gwind,
                     (char *)x11icon_bits, x11icon_width, x11icon_height);
       XSetWMHints(ourdisplay, gwind, &ourxwmhints);
       oursizhints.min_width = MINWIDTH;
#ifdef STEREO
       oursizhints.min_height = MINHEIGHT/2;
       oursizhints.max_width = DisplayWidth(ourdisplay,ourscreen)-2*BORWIDTH;
       oursizhints.max_height = (DisplayHeight(ourdisplay,ourscreen) -
                                   2*BORWIDTH)/2;
       oursizhints.flags = PMinSize|PMaxSize;
#else
       oursizhints.min_height = MINHEIGHT;
       oursizhints.flags = PMinSize;
#endif
       XSetNormalHints(ourdisplay, gwind, &oursizhints);
                                   /* set GLX context */
       glXMakeCurrent(ourdisplay, gwind, gctx);
       glEnable(GL_DEPTH_TEST);
       glDepthFunc(GL_LEQUAL);
       glClearColor(0, 0, 0, 0);
       glFrontFace(GL_CCW);
       glDisable(GL_CULL_FACE);
       glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
       glPixelStorei(GL_PACK_ALIGNMENT, 1);
       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
                                   /* figure out sensible view */
       pwidth = (double)DisplayWidthMM(ourdisplay, ourscreen) /
                     DisplayWidth(ourdisplay, ourscreen);
       pheight = (double)DisplayHeightMM(ourdisplay, ourscreen) /
                     DisplayHeight(ourdisplay, ourscreen);
#ifdef STEREO
       pheight *= 2.;
       setstereobuf(STEREO_BUFFER_LEFT);
#endif
       checkglerr("setting rendering parameters");
       odev.v = stdview;
       odev.v.type = VT_PER;
       viewflags = VWSTEADY;              /* view starts static */
                                   /* map the window */
       XMapWindow(ourdisplay, gwind);
       dev_input();                /* sets size and view angles */
       if (!odInit(DisplayWidth(ourdisplay,ourscreen) *
                     DisplayHeight(ourdisplay,ourscreen) / 3))
              error(SYSTEM, "insufficient memory for value storage");
       odev.name = id;
       odev.firstuse = 1;          /* can't recycle samples */
       odev.ifd = ConnectionNumber(ourdisplay);
}

Here is the call graph for this function:

void dev_section ( char *  gfn,
char *  pfn 
)

Definition at line 380 of file rhd_ogl.c.

{
       if (gfn == NULL) {
              gmEndGeom();
              gmEndPortal();
              wipeclean();         /* new geometry, so redraw it */
              return;
       }
       if (access(gfn, R_OK) == 0)
              gmNewGeom(gfn);
#ifdef DEBUG
       else {
              sprintf(errmsg, "cannot load octree \"%s\"", gfn);
              error(WARNING, errmsg);
       }
#endif
       if (pfn != NULL)
              gmNewPortal(pfn);
}

Here is the call graph for this function:

void dev_value ( COLR  c,
FVECT  d,
FVECT  p 
)

Definition at line 460 of file rhd_ogl.c.

{
#ifdef DOBJ
       if (dobj_lightsamp != NULL) {      /* in light source sampling */
              (*dobj_lightsamp)(c, d, p);
              return;
       }
#endif
       odSample(c, d, p);          /* add to display representation */
       if (!--rayqleft)
              dev_flush();         /* flush output */
}

Here is the caller graph for this function:

int dev_view ( register VIEW nv)

Definition at line 323 of file rhd_ogl.c.

{
#ifdef STEREO
       double d;
#endif
       if (nv->type != VT_PER ||          /* check view legality */
                     nv->horiz > 160. || nv->vert > 160.) {
              error(COMMAND, "illegal view type/angle");
              nv->type = odev.v.type;
              nv->horiz = odev.v.horiz;
              nv->vert = odev.v.vert;
              return(0);
       }
       if (nv != &odev.v) {
                                          /* resize window? */
              if (!FEQ(nv->horiz,odev.v.horiz) ||
                            !FEQ(nv->vert,odev.v.vert)) {
                     int    dw = DisplayWidth(ourdisplay,ourscreen);
                     int    dh = DisplayHeight(ourdisplay,ourscreen);

                     dw -= 25;     /* for window frame */
                     dh -= 50;
#ifdef STEREO
                     dh /= 2;
#endif
                     odev.hres = 2.*VIEWDIST/pwidth *
                                   tan(PI/180./2.*nv->horiz);
                     odev.vres = 2.*VIEWDIST/pheight *
                                   tan(PI/180./2.*nv->vert);
                     if (odev.hres > dw) {
                            odev.vres = dw * odev.vres / odev.hres;
                            odev.hres = dw;
                     }
                     if (odev.vres > dh) {
                            odev.hres = dh * odev.hres / odev.vres;
                            odev.vres = dh;
                     }
                     XResizeWindow(ourdisplay, gwind, odev.hres, odev.vres);
                     dev_input();  /* get resize event */
              }
              odev.v = *nv; /* setview() already called */
              viewflags |= VWCHANGE;
       }
#ifdef STEREO
       vwright = *nv;
       d = eyesepdist / sqrt(nv->hn2);
       VSUM(vwright.vp, nv->vp, nv->hvec, d);
       /* setview(&vwright);       -- Unnecessary */
#endif
       wipeclean();
       return(1);
}

Here is the call graph for this function:

static void draw3dline ( register FVECT  wp[2]) [static]

Definition at line 733 of file rhd_ogl.c.

{
       glVertex3d(wp[0][0], wp[0][1], wp[0][2]);
       glVertex3d(wp[1][0], wp[1][1], wp[1][2]);
}

Here is the caller graph for this function:

static void draw_grids ( int  fore) [static]

Definition at line 743 of file rhd_ogl.c.

{
       glPushAttrib(GL_LIGHTING_BIT|GL_ENABLE_BIT);
       glDisable(GL_LIGHTING);
       if (fore)
              glColor3ub(4, 250, 250);
       else
              glColor3ub(0, 0, 0);
       glBegin(GL_LINES);          /* draw each grid line */
       gridlines(draw3dline);
       glEnd();
       checkglerr("drawing grid lines");
       glPopAttrib();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fixwindow ( register XExposeEvent *  eexp) [static]

Definition at line 1119 of file rhd_ogl.c.

{
       int    xmin, ymin, xmax, ymax;

       if ((odev.hres == 0) | (odev.vres == 0)) {       /* first exposure */
              resizewindow((XConfigureEvent *)eexp);
              return;
       }
       xmin = eexp->x; xmax = eexp->x + eexp->width;
       ymin = odev.vres - eexp->y - eexp->height; ymax = odev.vres - eexp->y;

       if (xmin <= 0 && xmax >= odev.hres-1 &&
                     ymin <= 0 && ymax >= odev.vres) {
              DCHECK(eexp->count, WARNING, "multiple clear in fixwindow");
              wipeclean();                /* make sure we're go */
              return;
       }
                                          /* clear portion of depth */
       glPushAttrib(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
       glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
       glDepthFunc(GL_ALWAYS);
       glBegin(GL_POLYGON);
       glVertex3i(xmin, ymin, OMAXDEPTH);
       glVertex3i(xmax, ymin, OMAXDEPTH);
       glVertex3i(xmax, ymax, OMAXDEPTH);
       glVertex3i(xmin, ymax, OMAXDEPTH);
       glEnd();
#ifdef STEREO
       setstereobuf(STEREO_BUFFER_RIGHT);
       glBegin(GL_POLYGON);
       glVertex3i(xmin, ymin, OMAXDEPTH);
       glVertex3i(xmax, ymin, OMAXDEPTH);
       glVertex3i(xmax, ymax, OMAXDEPTH);
       glVertex3i(xmin, ymax, OMAXDEPTH);
       glEnd();
       odRedraw(1, xmin, ymin, xmax, ymax);
       setstereobuf(STEREO_BUFFER_LEFT);
#endif
       glPopAttrib();
       odRedraw(0, xmin, ymin, xmax, ymax);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void freedepth ( void  ) [static]

Definition at line 604 of file rhd_ogl.c.

{
       if (depthbuffer == NULL)
              return;
#ifdef STEREO
       odDepthMap(1, NULL);
       free((void *)depthright);
       depthright = NULL;
#endif
       odDepthMap(0, NULL);
       free((void *)depthbuffer);
       depthbuffer = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static double getdistance ( int  dx,
int  dy,
FVECT  direc 
) [static]

Definition at line 620 of file rhd_ogl.c.

{
       GLfloat       gldepth;
       double dist;

       if ((dx<0) | (dx>=odev.hres) | (dy<0) | (dy>=odev.vres))
              return(FHUGE);
       if (depthbuffer != NULL)
              dist = depthbuffer[dy*odev.hres + dx];
       else {
              glReadPixels(dx,dy, 1,1, GL_DEPTH_COMPONENT,
                            GL_FLOAT, &gldepth);
              if (gldepth <= FTINY)
                     return (FHUGE);      /* call failed */
              dist = mapdepth(gldepth);
       }
       if (dist >= .99*FHUGE)
              return(FHUGE);
       return((dist-odev.v.vfore)/DOT(direc,odev.v.vdir));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void getevent ( void  ) [static]

Definition at line 702 of file rhd_ogl.c.

{
       XNextEvent(ourdisplay, levptr(XEvent));
       switch (levptr(XEvent)->type) {
       case ConfigureNotify:
              resizewindow(levptr(XConfigureEvent));
              break;
       case UnmapNotify:
              viewflags &= ~VWMAPPED;
              break;
       case MapNotify:
              odRemap(0);
              viewflags |= VWMAPPED;
              break;
       case Expose:
              fixwindow(levptr(XExposeEvent));
              break;
       case KeyPress:
              getkey(levptr(XKeyPressedEvent));
              break;
       case ButtonPress:
              if (FRAMESTATE(levptr(XButtonPressedEvent)->state))
                     getframe(levptr(XButtonPressedEvent));
              else
                     getmove(levptr(XButtonPressedEvent));
              break;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void getframe ( XButtonPressedEvent *  ebut) [static]

Definition at line 823 of file rhd_ogl.c.

{
       int    startx = ebut->x, starty = ebut->y;
       int    endx, endy, midx, midy;
       FVECT  odir, v1;
       double d;
#ifdef DOBJ
       double d1;
#endif
                                          /* get mouse drag */
       XMaskEvent(ourdisplay, ButtonReleaseMask, levptr(XEvent));
       endx = levptr(XButtonReleasedEvent)->x;
       endy = levptr(XButtonReleasedEvent)->y;
       midx = (startx + endx) >> 1;
       midy = (starty + endy) >> 1;
                                          /* set focus distance */
       if (viewray(v1, odir, &odev.v,
                     (midx+.5)/odev.hres, (midy+.5)/odev.vres) < -FTINY)
              return;
       d = getdistance(midx, midy, odir); /* distance from front plane */
#ifdef DOBJ
       d1 = dobj_trace(NULL, v1, odir);
       if (d1 < d)
              d = d1;
#endif
       if (d < .99*FHUGE)
              odev.v.vdist = d + sqrt(dist2(v1, odev.v.vp));
                                          /* set frame for rendering */
       if ((endx == startx) | (endy == starty))
              return;
       if (endx < startx) {register int c = endx; endx = startx; startx = c;}
       if (endy < starty) {register int c = endy; endy = starty; starty = c;}
       sprintf(odev_args, "%.3f %.3f %.3f %.3f",
                     (startx+.5)/odev.hres, 1.-(endy+.5)/odev.vres,
                     (endx+.5)/odev.hres, 1.-(starty+.5)/odev.vres);
       inpresflags |= DFL(DC_FOCUS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void getkey ( register XKeyPressedEvent *  ekey) [static]

Definition at line 1035 of file rhd_ogl.c.

{
       Window rootw, childw;
       int    rootx, rooty, wx, wy;
       unsigned int  statemask;
       int  n;
       char   buf[8];

       n = XLookupString(ekey, buf, sizeof(buf), NULL, NULL);
       if (n != 1)
              return;
       switch (buf[0]) {
       case 'h':                   /* turn on height motion lock */
              viewflags |= VWHEADLOCK;
              return;
       case 'H':                   /* turn off height motion lock */
              viewflags &= ~VWHEADLOCK;
              return;
       case 'l':                   /* retrieve last view */
              inpresflags |= DFL(DC_LASTVIEW);
              return;
       case 'p':                   /* pause computation */
              inpresflags |= DFL(DC_PAUSE);
              return;
       case 'v':                   /* spit out view */
              inpresflags |= DFL(DC_GETVIEW);
              return;
       case 'f':                   /* frame view position */
              if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw,
                            &rootx, &rooty, &wx, &wy, &statemask))
                     return;              /* on another screen */
              sprintf(odev_args, "%.4f %.4f", (wx+.5)/odev.hres,
                            1.-(wy+.5)/odev.vres);
              inpresflags |= DFL(DC_FOCUS);
              return;
       case 'F':                   /* unfocus */
              odev_args[0] = '\0';
              inpresflags |= DFL(DC_FOCUS);
              return;
       case '\n':
       case '\r':                  /* resume computation */
              inpresflags |= DFL(DC_RESUME);
              return;
       case CTRL('R'):                    /* redraw screen */
              odRemap(0);                 /* new tone mapping */
              glClear(GL_DEPTH_BUFFER_BIT);
#ifdef STEREO
              setstereobuf(STEREO_BUFFER_RIGHT);
              glClear(GL_DEPTH_BUFFER_BIT);
              setstereobuf(STEREO_BUFFER_LEFT);
#endif
              return;
       case CTRL('L'):                    /* refresh from server */
              if (inpresflags & DFL(DC_REDRAW))
                     return;                     /* already called */
              XRaiseWindow(ourdisplay, gwind);
              XFlush(ourdisplay);         /* raise up window */
              sleep(1);                   /* wait for restacking */
              dev_clear();                /* clear buffer and samples */
              odRemap(1);                 /* start fresh histogram */
              inpresflags |= DFL(DC_REDRAW);     /* resend values from server */
              return;
       case 'K':                   /* kill rtrace process(es) */
              inpresflags |= DFL(DC_KILL);
              break;
       case 'R':                   /* restart rtrace */
              inpresflags |= DFL(DC_RESTART);
              break;
       case 'C':                   /* clobber holodeck */
              inpresflags |= DFL(DC_CLOBBER);
              break;
       case 'q':                   /* quit the program */
              inpresflags |= DFL(DC_QUIT);
              return;
       default:
              XBell(ourdisplay, 0);
              return;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void getmove ( XButtonPressedEvent *  ebut) [static]

Definition at line 875 of file rhd_ogl.c.

{
       int    movdir = MOVDIR(ebut->button);
       int    movorb = MOVORB(ebut->state);
       int    ndrawn;
       Window rootw, childw;
       int    rootx, rooty, wx, wy;
       unsigned int  statemask;

       XNoOp(ourdisplay);          /* makes sure we're not idle */

       viewflags &= ~VWSTEADY;            /* flag moving view */
       setglpersp();               /* start us off in perspective */
       while (!XCheckMaskEvent(ourdisplay,
                     ButtonReleaseMask, levptr(XEvent))) {
                                   /* pause so as not to move too fast */
              waitabit();
                                   /* get cursor position */
              if (!XQueryPointer(ourdisplay, gwind, &rootw, &childw,
                            &rootx, &rooty, &wx, &wy, &statemask))
                     break;        /* on another screen */
                                   /* compute view motion */
              if (!moveview(wx, odev.vres-1-wy, movdir, movorb)) {
                     sleep(1);
                     continue;     /* cursor in bad place */
              }
              draw_grids(1);              /* redraw grid */
#ifdef STEREO
              pushright();
              draw_grids(1);
              ndrawn = gmDrawGeom();
#ifdef DOBJ
              ndrawn += dobj_render();
#endif
              popright();
#endif
                                   /* redraw octrees */
              ndrawn = gmDrawGeom();
#ifdef DOBJ
              ndrawn += dobj_render();    /* redraw objects */
#endif
              glXSwapBuffers(ourdisplay, gwind);
              if (!ndrawn)
                     sleep(1);     /* for reasonable interaction */
       }
       if (!(inpresflags & DFL(DC_SETVIEW))) {   /* do final motion */
              movdir = MOVDIR(levptr(XButtonReleasedEvent)->button);
              wx = levptr(XButtonReleasedEvent)->x;
              wy = levptr(XButtonReleasedEvent)->y;
              moveview(wx, odev.vres-1-wy, movdir, movorb);
       }
       viewflags |= VWSTEADY;             /* done goofing around */
}

Here is the call graph for this function:

static int moveview ( int  dx,
int  dy,
int  mov,
int  orb 
) [static]

Definition at line 762 of file rhd_ogl.c.

{
       VIEW   nv;
       FVECT  odir, v1, wip;
       double d;
#ifdef DOBJ
       double d1;
#endif
                            /* start with old view */
       nv = odev.v;
                            /* orient our motion */
       if (viewray(v1, odir, &odev.v,
                     (dx+.5)/odev.hres, (dy+.5)/odev.vres) < -FTINY)
              return(0);           /* outside view */
       if (mov | orb) {     /* moving relative to geometry */
              d = getdistance(dx, dy, odir);     /* distance from front plane */
#ifdef DOBJ
              d1 = dobj_trace(NULL, v1, odir);
              if (d1 < d)
                     d = d1;
#endif
              if (d >= .99*FHUGE)
                     d = 0.5*(dev_zmax+dev_zmin);       /* just guess */
              VSUM(wip, v1, odir, d);
              VSUB(odir, wip, odev.v.vp);
       } else               /* panning with constant viewpoint */
              VCOPY(nv.vdir, odir);
       if (orb && mov) {           /* orbit left/right */
              spinvector(odir, odir, nv.vup, d=MOVDEG*PI/180.*mov);
              VSUM(nv.vp, wip, odir, -1.);
              spinvector(nv.vdir, nv.vdir, nv.vup, d);
       } else if (orb) {           /* orbit up/down */
              fcross(v1, odir, nv.vup);
              if (normalize(v1) == 0.)
                     return(0);
              spinvector(odir, odir, v1, d=MOVDEG*PI/180.*orb);
              VSUM(nv.vp, wip, odir, -1.);
              spinvector(nv.vdir, nv.vdir, v1, d);
       } else if (mov) {           /* move forward/backward */
              d = MOVPCT/100. * mov;
              VSUM(nv.vp, nv.vp, odir, d);
       }
       if (!mov ^ !orb && viewflags&VWHEADLOCK) {       /* restore height */
              VSUM(v1, odev.v.vp, nv.vp, -1.);
              d = DOT(v1, nv.vup);
              VSUM(nv.vp, nv.vp, odev.v.vup, d);
       }
       if (setview(&nv) != NULL)
              return(0);    /* illegal view */
       dev_view(&nv);
       inpresflags |= DFL(DC_SETVIEW);
       return(1);
}

Here is the call graph for this function:

static int mytmflags ( void  ) [static]

Definition at line 677 of file rhd_ogl.c.

{
       extern char   *progname;
       register char *cp, *tail;
                                   /* find basic name */
       for (cp = tail = progname; *cp; cp++)
              if (*cp == '/')
                     tail = cp+1;
       for (cp = tail; *cp && *cp != '.'; cp++)
              ;
#ifdef DEBUG
       if (cp > tail && cp[-1] == 'h')
              return(TM_F_HUMAN);
       else
              return(TM_F_CAMERA);
#else
       if (cp > tail && cp[-1] == 'h')
              return(TM_F_HUMAN|TM_F_NOSTDERR);
       else
              return(TM_F_CAMERA|TM_F_NOSTDERR);
#endif
}

Here is the caller graph for this function:

static void resizewindow ( register XConfigureEvent *  ersz) [static]

Definition at line 1165 of file rhd_ogl.c.

{
       glViewport(0, 0, ersz->width, ersz->height);

       if (ersz->width == odev.hres && ersz->height == odev.vres)
              return;

       odev.hres = ersz->width;
       odev.vres = ersz->height;

       odev.v.horiz = 2.*180./PI * atan(0.5/VIEWDIST*pwidth*odev.hres);
       odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres);

       inpresflags |= DFL(DC_SETVIEW);
       viewflags |= VWCHANGE;
}

Here is the caller graph for this function:

static void setglortho ( void  ) [static]

Definition at line 995 of file rhd_ogl.c.

{
       glDrawBuffer(GL_FRONT);            /* use single-buffer mode */
                                   /* set view matrix */
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       glOrtho(0., (double)odev.hres, 0., (double)odev.vres,
                     0.001*OMAXDEPTH, 1.001*(-OMAXDEPTH));
       checkglerr("setting orthographic view");
       glDisable(GL_LIGHTING);            /* cones are constant color */
       glShadeModel(GL_FLAT);
       viewflags &= ~VWPERSP;
       viewflags |= VWORTHO;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void setglpersp ( void  ) [static]

Definition at line 933 of file rhd_ogl.c.

{
       double d, xmin, xmax, ymin, ymax;
       GLfloat       vec[4];
       double depthlim[2];
                                   /* set depth limits */
       gmDepthLimit(depthlim, odev.v.vp, odev.v.vdir);
       if (depthlim[0] >= depthlim[1]) {
              dev_zmin = 1.;
              dev_zmax = 100.;
       } else {
              dev_zmin = 0.5*depthlim[0];
              dev_zmax = 1.25*depthlim[1];
              if (dev_zmin > dev_zmax/5.)
                     dev_zmin = dev_zmax/5.;
       }
       if (odev.v.vfore > FTINY)
              dev_zmin = odev.v.vfore;
       if (odev.v.vaft > FTINY)
              dev_zmax = odev.v.vaft;
       if (dev_zmin*500. < dev_zmax)
              dev_zmin = dev_zmax/500.;
       setzrat();
       xmax = dev_zmin * tan(PI/180./2. * odev.v.horiz);
       xmin = -xmax;
       d = odev.v.hoff * (xmax - xmin);
       xmin += d; xmax += d;
       ymax = dev_zmin * tan(PI/180./2. * odev.v.vert);
       ymin = -ymax;
       d = odev.v.voff * (ymax - ymin);
       ymin += d; ymax += d;
                                   /* set view matrix */
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       glFrustum(xmin, xmax, ymin, ymax, dev_zmin, dev_zmax);
       gluLookAt(odev.v.vp[0], odev.v.vp[1], odev.v.vp[2],
              odev.v.vp[0] + odev.v.vdir[0],
              odev.v.vp[1] + odev.v.vdir[1],
              odev.v.vp[2] + odev.v.vdir[2],
              odev.v.vup[0], odev.v.vup[1], odev.v.vup[2]);
       checkglerr("setting perspective view");
       vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.;
       glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vec);
       vec[0] = -odev.v.vdir[0];
       vec[1] = -odev.v.vdir[1];
       vec[2] = -odev.v.vdir[2];
       vec[3] = 0.;
       glLightfv(GL_LIGHT0, GL_POSITION, vec);
       vec[0] = vec[1] = vec[2] = .7; vec[3] = 1.;
       glLightfv(GL_LIGHT0, GL_SPECULAR, vec);
       glLightfv(GL_LIGHT0, GL_DIFFUSE, vec);
       vec[0] = vec[1] = vec[2] = .3; vec[3] = 1.;
       glLightfv(GL_LIGHT0, GL_AMBIENT, vec);
       glEnable(GL_LIGHT0);
       glEnable(GL_LIGHTING);             /* light our GL objects */
       glShadeModel(GL_SMOOTH);
       viewflags &= ~VWORTHO;
       viewflags |= VWPERSP;
}

Here is the call graph for this function:

Here is the caller graph for this function:

time_t time ( )

Here is the caller graph for this function:

static void waitabit ( void  ) [static]

Definition at line 865 of file rhd_ogl.c.

{
       struct timespec      ts;
       ts.tv_sec = 0;
       ts.tv_nsec = 100000000L;
       nanosleep(&ts, NULL);
}

Here is the caller graph for this function:

static void wipeclean ( void  ) [static]

Definition at line 1012 of file rhd_ogl.c.

{
       glDrawBuffer(GL_BACK);             /* use double-buffer mode */
       glReadBuffer(GL_BACK);
                                   /* clear buffers */
#ifdef STEREO
       setstereobuf(STEREO_BUFFER_RIGHT);
       glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
       setstereobuf(STEREO_BUFFER_LEFT);
#endif
       glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
       freedepth();
       if ((viewflags&(VWCHANGE|VWSTEADY)) ==
                     (VWCHANGE|VWSTEADY)) {      /* clear samples if new */
              odClean();
              viewflags &= ~VWCHANGE;            /* change noted */
       } else if (viewflags & VWSTEADY)
              odRedrawAll();
       setglpersp();               /* reset view & clipping planes */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void xferdepth ( void  ) [static]

Definition at line 541 of file rhd_ogl.c.

{
       register GLfloat     *dbp;
       register GLubyte     *pbuf;

       if (depthbuffer == NULL) {  /* allocate private depth buffer */
#ifdef STEREO
              depthright = (GLfloat *)malloc(
                            odev.hres*odev.vres*sizeof(GLfloat));
#endif
              depthbuffer = (GLfloat *)malloc(
                            odev.hres*odev.vres*sizeof(GLfloat));
              CHECK(depthbuffer==NULL, SYSTEM, "out of memory in xferdepth");
       }
                            /* allocate alpha buffer for portals */
       if (gmPortals)
              pbuf = (GLubyte *)malloc(odev.hres*odev.vres*sizeof(GLubyte));
       else
              pbuf = NULL;
#ifdef STEREO
       pushright();
       glReadPixels(0, 0, odev.hres, odev.vres,
                     GL_DEPTH_COMPONENT, GL_FLOAT, depthright);
       if (pbuf != NULL) {
              glClear(GL_COLOR_BUFFER_BIT);
              gmDrawPortals(0xff, -1, -1, -1);
              glReadPixels(0, 0, odev.hres, odev.vres,
                            GL_RED, GL_UNSIGNED_BYTE, pbuf);
       }
       for (dbp = depthright + odev.hres*odev.vres; dbp-- > depthright; )
              if (pbuf != NULL && pbuf[dbp-depthright]&0x40)
                     *dbp = FHUGE;
              else
                     *dbp = mapdepth(*dbp);
       glClear(GL_DEPTH_BUFFER_BIT);
       odDepthMap(1, depthright);
       popright();
#endif
                            /* read back depth buffer */
       glReadPixels(0, 0, odev.hres, odev.vres,
                     GL_DEPTH_COMPONENT, GL_FLOAT, depthbuffer);
       if (pbuf != NULL) {
              glClear(GL_COLOR_BUFFER_BIT);             /* find portals */
              gmDrawPortals(0xff, -1, -1, -1);
              glReadPixels(0, 0, odev.hres, odev.vres,
                            GL_RED, GL_UNSIGNED_BYTE, pbuf);
#ifdef DEBUG
              glXSwapBuffers(ourdisplay, gwind);
#endif
       }
       for (dbp = depthbuffer + odev.hres*odev.vres; dbp-- > depthbuffer; )
              if (pbuf != NULL && pbuf[dbp-depthbuffer]&0x40)
                     *dbp = FHUGE;
              else
                     *dbp = mapdepth(*dbp);
       glClear(GL_DEPTH_BUFFER_BIT);             /* clear system depth buffer */
       odDepthMap(0, depthbuffer);        /* transfer depth data */
       if (pbuf != NULL)
              free((void *)pbuf);         /* free our portal buffer */
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

XEvent currentevent [static]

Definition at line 98 of file rhd_ogl.c.

GLfloat* depthbuffer = NULL [static]

Definition at line 89 of file rhd_ogl.c.

double dev_zmax [static]

Definition at line 109 of file rhd_ogl.c.

double dev_zmin [static]

Definition at line 109 of file rhd_ogl.c.

double dev_zrat [static]

Definition at line 110 of file rhd_ogl.c.

GLXContext gctx [static]

Definition at line 105 of file rhd_ogl.c.

int gmPortals

Definition at line 22 of file rhd_geom.c.

Window gwind = 0 [static]

Definition at line 104 of file rhd_ogl.c.

int inpresflags [static]

Definition at line 115 of file rhd_ogl.c.

char odev_args[64]

Definition at line 87 of file rhd_ogl.c.

unsigned long ourblack = 0 [static]

Definition at line 100 of file rhd_ogl.c.

Display* ourdisplay = NULL [static]

Definition at line 102 of file rhd_ogl.c.

XVisualInfo* ourvinf [static]

Definition at line 103 of file rhd_ogl.c.

unsigned long ourwhite = ~0 [static]

Definition at line 100 of file rhd_ogl.c.

double pheight [static]

Definition at line 107 of file rhd_ogl.c.

double pwidth [static]

Definition at line 107 of file rhd_ogl.c.

int rayqleft = 0 [static]

Definition at line 96 of file rhd_ogl.c.

const char RCSid[] = "$Id: rhd_ogl.c,v 3.30 2006/06/07 17:52:04 schorsch Exp $" [static]

Definition at line 2 of file rhd_ogl.c.

Definition at line 85 of file rhd_ogl.c.

int viewflags [static]

Definition at line 117 of file rhd_ogl.c.