37 |
|
#include "x11icon.h" |
38 |
|
|
39 |
|
#ifndef RAYQLEN |
40 |
< |
#define RAYQLEN 10240 /* max. rays to queue before flush */ |
40 |
> |
#define RAYQLEN 50000 /* max. rays to queue before flush */ |
41 |
|
#endif |
42 |
|
|
43 |
|
#ifndef PORTALP |
55 |
|
#define FEQ(a,b) ((a)-(b) <= FTINY && (a)-(b) >= -FTINY) |
56 |
|
#endif |
57 |
|
|
58 |
+ |
#define VWHEADLOCK 01 /* head position is locked flag */ |
59 |
+ |
#define VWPERSP 02 /* perspective view is set */ |
60 |
+ |
#define VWORTHO 04 /* orthographic view is set */ |
61 |
+ |
#define VWCHANGE 010 /* view has changed */ |
62 |
+ |
#define VWSTEADY 020 /* view is now steady */ |
63 |
+ |
#define VWMAPPED 040 /* window is mapped */ |
64 |
+ |
|
65 |
|
#define GAMMA 1.4 /* default gamma correction */ |
66 |
|
|
67 |
|
#define FRAMESTATE(s) (((s)&(ShiftMask|ControlMask))==(ShiftMask|ControlMask)) |
104 |
|
|
105 |
|
static XEvent currentevent; /* current event */ |
106 |
|
|
100 |
– |
static int mapped = 0; /* window is mapped? */ |
107 |
|
static unsigned long ourblack=0, ourwhite=~0; |
108 |
|
|
109 |
|
static Display *ourdisplay = NULL; /* our display */ |
121 |
|
|
122 |
|
static int inpresflags; /* input result flags */ |
123 |
|
|
124 |
< |
static int headlocked; /* lock vertical motion */ |
124 |
> |
static int viewflags; /* what's happening with view */ |
125 |
|
|
120 |
– |
static int isperspective; /* perspective/ortho view */ |
121 |
– |
|
122 |
– |
static int viewsteady; /* is view steady? */ |
123 |
– |
|
126 |
|
static int resizewindow(), getevent(), getkey(), moveview(), wipeclean(), |
127 |
|
xferdepth(), freedepth(), setglortho(), |
128 |
|
setglpersp(), getframe(), getmove(), fixwindow(), mytmflags(); |
144 |
|
extern char *getenv(); |
145 |
|
static RGBPRIMS myprims = STDPRIMS; |
146 |
|
#if (PORTALP<0) |
147 |
< |
static int atlBest[] = {GLX_RGBA, GLX_RED_SIZE,8, |
148 |
< |
GLX_GREEN_SIZE,8, GLX_BLUE_SIZE,8, |
149 |
< |
GLX_DEPTH_SIZE,15, None}; |
147 |
> |
static int atlBest[] = {GLX_RGBA, GLX_DOUBLEBUFFER, |
148 |
> |
GLX_RED_SIZE,8, GLX_GREEN_SIZE,8, |
149 |
> |
GLX_BLUE_SIZE,8, GLX_DEPTH_SIZE,15, None}; |
150 |
> |
static int atlOK[] = {GLX_RGBA, GLX_DOUBLEBUFFER, |
151 |
> |
GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, |
152 |
> |
GLX_BLUE_SIZE,4, GLX_DEPTH_SIZE,15, None}; |
153 |
|
#else |
154 |
< |
static int atlBest[] = {GLX_RGBA, GLX_RED_SIZE,8, |
155 |
< |
GLX_GREEN_SIZE,8, GLX_BLUE_SIZE,8, |
156 |
< |
GLX_ALPHA_SIZE,2, GLX_DEPTH_SIZE,15, None}; |
154 |
> |
static int atlBest[] = {GLX_RGBA, GLX_DOUBLEBUFFER, |
155 |
> |
GLX_RED_SIZE,8, GLX_GREEN_SIZE,8, |
156 |
> |
GLX_BLUE_SIZE,8, GLX_ALPHA_SIZE,2, |
157 |
> |
GLX_DEPTH_SIZE,15, None}; |
158 |
> |
static int atlOK[] = {GLX_RGBA, GLX_DOUBLEBUFFER, |
159 |
> |
GLX_RED_SIZE,4, GLX_GREEN_SIZE,4, |
160 |
> |
GLX_BLUE_SIZE,4, GLX_ALPHA_SIZE,2, |
161 |
> |
GLX_DEPTH_SIZE,15, None}; |
162 |
|
#endif |
163 |
|
char *ev; |
164 |
|
double gamval = GAMMA; |
190 |
|
#endif |
191 |
|
/* find a usable visual */ |
192 |
|
ourvinf = glXChooseVisual(ourdisplay, ourscreen, atlBest); |
193 |
+ |
if (ourvinf == NULL) |
194 |
+ |
ourvinf = glXChooseVisual(ourdisplay, ourscreen, atlOK); |
195 |
|
CHECK(ourvinf==NULL, USER, "no suitable visuals available"); |
196 |
|
/* get a context */ |
197 |
|
gctx = glXCreateContext(ourdisplay, ourvinf, NULL, GL_TRUE); |
248 |
|
glXMakeCurrent(ourdisplay, gwind, gctx); |
249 |
|
glEnable(GL_DEPTH_TEST); |
250 |
|
glDepthFunc(GL_LEQUAL); |
251 |
< |
glDisable(GL_DITHER); |
251 |
> |
glEnable(GL_DITHER); |
252 |
|
glFrontFace(GL_CCW); |
253 |
|
glDisable(GL_CULL_FACE); |
254 |
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); |
265 |
|
checkglerr("setting rendering parameters"); |
266 |
|
copystruct(&odev.v, &stdview); |
267 |
|
odev.v.type = VT_PER; |
268 |
< |
headlocked = 0; /* free up head movement */ |
257 |
< |
viewsteady = 1; /* view starts static */ |
258 |
< |
isperspective = -1; /* but no view set, yet */ |
268 |
> |
viewflags = VWSTEADY; /* view starts static */ |
269 |
|
/* map the window */ |
270 |
|
XMapWindow(ourdisplay, gwind); |
271 |
|
dev_input(); /* sets size and view angles */ |
355 |
|
VSUM(vwright.vp, nv->vp, nv->hvec, d); |
356 |
|
/* setview(&vwright); -- Unnecessary */ |
357 |
|
#endif |
358 |
< |
} else |
359 |
< |
viewsteady = 1; |
358 |
> |
viewflags |= VWCHANGE; |
359 |
> |
} |
360 |
|
wipeclean(); |
361 |
|
return(1); |
362 |
|
} |
452 |
|
{ |
453 |
|
int ndrawn; |
454 |
|
|
455 |
< |
if (mapped && isperspective > 0) { |
455 |
> |
if ((viewflags&(VWMAPPED|VWPERSP)) == (VWMAPPED|VWPERSP)) { |
456 |
|
#ifdef STEREO |
457 |
|
pushright(); /* draw right eye */ |
458 |
|
ndrawn = gmDrawGeom(); |
459 |
|
#ifdef DOBJ |
460 |
|
ndrawn += dobj_render(); |
461 |
|
#endif |
462 |
< |
if (ndrawn) |
463 |
< |
gmDrawPortals(PORTRED, PORTGRN, PORTBLU, PORTALP); |
462 |
> |
if (ndrawn && gmPortals) |
463 |
> |
gmDrawPortals(PORTRED,PORTGRN,PORTBLU,PORTALP); |
464 |
|
checkglerr("rendering right eye"); |
465 |
|
popright(); /* draw left eye */ |
466 |
|
#endif |
468 |
|
#ifdef DOBJ |
469 |
|
ndrawn += dobj_render(); |
470 |
|
#endif |
471 |
< |
if (ndrawn) |
472 |
< |
gmDrawPortals(PORTRED, PORTGRN, PORTBLU, PORTALP); |
471 |
> |
if (ndrawn && gmPortals) |
472 |
> |
gmDrawPortals(PORTRED,PORTGRN,PORTBLU,PORTALP); |
473 |
> |
glXSwapBuffers(ourdisplay, gwind); |
474 |
|
checkglerr("rendering base view"); |
475 |
|
} |
476 |
< |
if (mapped && viewsteady) |
477 |
< |
if (isperspective > 0) { /* first time after steady */ |
478 |
< |
if (ndrawn) |
479 |
< |
xferdepth(); /* transfer and clear depth */ |
480 |
< |
setglortho(); /* set orthographic view */ |
481 |
< |
} else if (!isperspective) { |
476 |
> |
if ((viewflags&(VWMAPPED|VWSTEADY|VWPERSP|VWORTHO)) == |
477 |
> |
(VWMAPPED|VWSTEADY|VWPERSP)) { |
478 |
> |
/* first time after steady */ |
479 |
> |
if (ndrawn) |
480 |
> |
xferdepth(); /* transfer and clear depth */ |
481 |
> |
setglortho(); /* set orthographic view */ |
482 |
> |
|
483 |
> |
} |
484 |
> |
if ((viewflags&(VWMAPPED|VWSTEADY|VWPERSP|VWORTHO)) == |
485 |
> |
(VWMAPPED|VWSTEADY|VWORTHO)) { |
486 |
> |
/* else update cones */ |
487 |
|
#ifdef STEREO |
488 |
< |
pushright(); |
489 |
< |
odUpdate(1); /* draw right eye */ |
490 |
< |
popright(); |
488 |
> |
pushright(); |
489 |
> |
odUpdate(1); /* draw right eye */ |
490 |
> |
popright(); |
491 |
|
#endif |
492 |
< |
odUpdate(0); /* draw left eye */ |
493 |
< |
} |
494 |
< |
glFlush(); /* flush OpenGL */ |
492 |
> |
odUpdate(0); /* draw left eye */ |
493 |
> |
glFlush(); /* flush OpenGL */ |
494 |
> |
} |
495 |
|
rayqleft = RAYQLEN; |
496 |
|
/* flush X11 and return # pending */ |
497 |
|
return(odev.inpready = XPending(ourdisplay)); |
528 |
|
} |
529 |
|
/* allocate alpha buffer for portals */ |
530 |
|
if (gmPortals) |
531 |
< |
cbuf = (GLubyte *)malloc(odev.hres*odev.vres* |
531 |
> |
cbuf = (GLubyte *)malloc(odev.hres*odev.vres * |
532 |
|
(4*sizeof(GLubyte))); |
533 |
|
else |
534 |
|
cbuf = NULL; |
619 |
|
double d; |
620 |
|
|
621 |
|
setstereobuf(STEREO_BUFFER_RIGHT); |
622 |
< |
if (isperspective > 0) { |
622 |
> |
if (viewflags & VWPERSP) { |
623 |
|
glMatrixMode(GL_MODELVIEW); |
624 |
|
glPushMatrix(); |
625 |
|
d = -eyesepdist / sqrt(odev.v.hn2); |
633 |
|
static |
634 |
|
popright() /* pop off right view & buffer */ |
635 |
|
{ |
636 |
< |
if (isperspective > 0) { |
636 |
> |
if (viewflags & VWPERSP) { |
637 |
|
glMatrixMode(GL_MODELVIEW); |
638 |
|
glPopMatrix(); |
639 |
|
} |
676 |
|
resizewindow(levptr(XConfigureEvent)); |
677 |
|
break; |
678 |
|
case UnmapNotify: |
679 |
< |
mapped = 0; |
679 |
> |
viewflags &= ~VWMAPPED; |
680 |
|
break; |
681 |
|
case MapNotify: |
682 |
|
odRemap(0); |
683 |
< |
mapped = 1; |
683 |
> |
viewflags |= VWMAPPED; |
684 |
|
break; |
685 |
|
case Expose: |
686 |
|
fixwindow(levptr(XExposeEvent)); |
767 |
|
d = MOVPCT/100. * mov; |
768 |
|
VSUM(nv.vp, nv.vp, odir, d); |
769 |
|
} |
770 |
< |
if (!mov ^ !orb && headlocked) { /* restore head height */ |
770 |
> |
if (!mov ^ !orb && viewflags&VWHEADLOCK) { /* restore height */ |
771 |
|
VSUM(v1, odev.v.vp, nv.vp, -1.); |
772 |
|
d = DOT(v1, nv.vup); |
773 |
|
VSUM(nv.vp, nv.vp, odev.v.vup, d); |
816 |
|
|
817 |
|
XNoOp(ourdisplay); /* makes sure we're not idle */ |
818 |
|
|
819 |
< |
viewsteady = 0; /* flag moving view */ |
819 |
> |
viewflags &= ~VWSTEADY; /* flag moving view */ |
820 |
|
setglpersp(&odev.v); /* start us off in perspective */ |
821 |
|
while (!XCheckMaskEvent(ourdisplay, |
822 |
|
ButtonReleaseMask, levptr(XEvent))) { |
837 |
|
#ifdef DOBJ |
838 |
|
ndrawn += dobj_render(); |
839 |
|
#endif |
840 |
< |
if (ndrawn) |
841 |
< |
gmDrawPortals(PORTRED, PORTGRN, PORTBLU, PORTALP); |
840 |
> |
if (ndrawn && gmPortals) |
841 |
> |
gmDrawPortals(PORTRED,PORTGRN,PORTBLU,PORTALP); |
842 |
|
popright(); |
843 |
|
#endif |
844 |
|
/* redraw octrees */ |
846 |
|
#ifdef DOBJ |
847 |
|
ndrawn += dobj_render(); /* redraw objects */ |
848 |
|
#endif |
849 |
< |
if (ndrawn) |
849 |
> |
if (ndrawn && gmPortals) |
850 |
|
gmDrawPortals(PORTRED, PORTGRN, PORTBLU, PORTALP); |
851 |
< |
glFlush(); |
852 |
< |
if (!ndrawn) { |
851 |
> |
glXSwapBuffers(ourdisplay, gwind); |
852 |
> |
if (!ndrawn) |
853 |
|
sleep(1); /* for reasonable interaction */ |
838 |
– |
#ifdef STEREO |
839 |
– |
pushright(); |
840 |
– |
draw_grids(0); |
841 |
– |
popright(); |
842 |
– |
#endif |
843 |
– |
draw_grids(0); |
844 |
– |
} |
854 |
|
} |
855 |
|
if (!(inpresflags & DFL(DC_SETVIEW))) { /* do final motion */ |
856 |
|
movdir = MOVDIR(levptr(XButtonReleasedEvent)->button); |
858 |
|
wy = levptr(XButtonReleasedEvent)->y; |
859 |
|
moveview(wx, odev.vres-1-wy, movdir, movorb); |
860 |
|
} |
861 |
+ |
viewflags |= VWSTEADY; /* done goofing around */ |
862 |
|
} |
863 |
|
|
864 |
|
|
905 |
|
odev.v.vp[2] + odev.v.vdir[2], |
906 |
|
odev.v.vup[0], odev.v.vup[1], odev.v.vup[2]); |
907 |
|
checkglerr("setting perspective view"); |
898 |
– |
isperspective = 1; |
908 |
|
vec[0] = vec[1] = vec[2] = 0.; vec[3] = 1.; |
909 |
|
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, vec); |
910 |
|
vec[0] = -odev.v.vdir[0]; |
920 |
|
glEnable(GL_LIGHT0); |
921 |
|
glEnable(GL_LIGHTING); /* light our GL objects */ |
922 |
|
glShadeModel(GL_SMOOTH); |
923 |
+ |
viewflags &= ~VWORTHO; |
924 |
+ |
viewflags |= VWPERSP; |
925 |
|
} |
926 |
|
|
927 |
|
|
928 |
|
static |
929 |
|
setglortho() /* set up orthographic view for cone drawing */ |
930 |
|
{ |
931 |
+ |
glDrawBuffer(GL_FRONT); /* use single-buffer mode */ |
932 |
|
/* set view matrix */ |
933 |
|
glMatrixMode(GL_PROJECTION); |
934 |
|
glLoadIdentity(); |
935 |
|
glOrtho(0., (double)odev.hres, 0., (double)odev.vres, |
936 |
|
0.001*OMAXDEPTH, 1.001*(-OMAXDEPTH)); |
937 |
|
checkglerr("setting orthographic view"); |
926 |
– |
isperspective = 0; |
938 |
|
glDisable(GL_LIGHTING); /* cones are constant color */ |
939 |
|
glShadeModel(GL_FLAT); |
940 |
+ |
viewflags &= ~VWPERSP; |
941 |
+ |
viewflags |= VWORTHO; |
942 |
|
} |
943 |
|
|
944 |
|
|
945 |
|
static |
946 |
|
wipeclean() /* prepare for redraw */ |
947 |
|
{ |
948 |
< |
/* clear depth buffer */ |
948 |
> |
glDrawBuffer(GL_BACK); /* use double-buffer mode */ |
949 |
> |
/* clear buffers */ |
950 |
|
#ifdef STEREO |
951 |
|
setstereobuf(STEREO_BUFFER_RIGHT); |
952 |
< |
glClear(GL_DEPTH_BUFFER_BIT); |
952 |
> |
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); |
953 |
|
setstereobuf(STEREO_BUFFER_LEFT); |
954 |
|
#endif |
955 |
< |
glClear(GL_DEPTH_BUFFER_BIT); |
942 |
< |
if (viewsteady) /* clear samples if steady */ |
943 |
< |
odClean(); |
955 |
> |
glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); |
956 |
|
freedepth(); |
957 |
+ |
if ((viewflags&(VWCHANGE|VWSTEADY)) == |
958 |
+ |
(VWCHANGE|VWSTEADY)) { /* clear samples if new */ |
959 |
+ |
odClean(); |
960 |
+ |
viewflags &= ~VWCHANGE; /* change noted */ |
961 |
+ |
} |
962 |
|
setglpersp(&odev.v); /* reset view & clipping planes */ |
963 |
|
} |
964 |
|
|
978 |
|
return; |
979 |
|
switch (buf[0]) { |
980 |
|
case 'h': /* turn on height motion lock */ |
981 |
< |
headlocked = 1; |
981 |
> |
viewflags |= VWHEADLOCK; |
982 |
|
return; |
983 |
|
case 'H': /* turn off height motion lock */ |
984 |
< |
headlocked = 0; |
984 |
> |
viewflags &= ~VWHEADLOCK; |
985 |
|
return; |
986 |
|
case 'l': /* retrieve last view */ |
987 |
|
inpresflags |= DFL(DC_LASTVIEW); |
1010 |
|
return; |
1011 |
|
case CTRL('R'): /* redraw screen */ |
1012 |
|
odRemap(0); |
1013 |
< |
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
1013 |
> |
glClear(GL_DEPTH_BUFFER_BIT); |
1014 |
|
#ifdef STEREO |
1015 |
|
setstereobuf(STEREO_BUFFER_RIGHT); |
1016 |
< |
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
1016 |
> |
glClear(GL_DEPTH_BUFFER_BIT); |
1017 |
|
setstereobuf(STEREO_BUFFER_LEFT); |
1018 |
|
#endif |
1019 |
|
return; |
1102 |
|
odev.v.vert = 2.*180./PI * atan(0.5/VIEWDIST*pheight*odev.vres); |
1103 |
|
|
1104 |
|
inpresflags |= DFL(DC_SETVIEW); |
1105 |
+ |
viewflags |= VWCHANGE; |
1106 |
|
} |