ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/rglinst.c
Revision: 3.3
Committed: Wed Jul 15 17:52:16 1998 UTC (25 years, 9 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.2: +1 -0 lines
Log Message:
added paranoid setting of glMatrixMode()

File Contents

# User Rev Content
1 gwlarson 3.1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ SGI";
5     #endif
6    
7     /*
8     * Routines for reading instances and converting to OpenGL.
9     */
10    
11     #include "radogl.h"
12     #include "octree.h"
13    
14 gwlarson 3.2 #define MAXLEVEL 16 /* maximum instance hierarchy level */
15    
16 gwlarson 3.1 typedef struct {
17     int listid; /* our list id */
18     short localmatl; /* uses local material only */
19     FVECT cent; /* center of octree cube */
20     char octfile[256]; /* octree file path */
21     } OCTINST; /* octree to instantiate */
22    
23     OBJECT nobjects; /* number of objects loaded so far */
24    
25     extern int free();
26    
27     static double ogetflt();
28     static long ogetint();
29     static char *ogetstr();
30     static int loadobj(), octerror(), skiptree();
31     static OCTINST *getoct();
32    
33     static char *infn; /* input file name */
34     static FILE *infp; /* input file stream */
35     static int objsize; /* size of stored OBJECT's */
36     static short otypmap[NUMOTYPE+8]; /* object type map */
37    
38     static long imhash(mod) char *mod; {return((long)mod);}
39     static LUTAB imtab = {imhash,NULL,NULL,NULL,0,NULL,0};
40    
41     static LUTAB ottab = LU_SINIT(free,free);
42    
43    
44     o_instance(o) /* convert instance to list call */
45     register OBJREC *o;
46     {
47     XF xfs;
48     register OCTINST *ot;
49     /* set up */
50     if (o->oargs.nsargs < 1)
51     objerror(o, USER, "missing octree");
52     setmaterial(NULL, NULL, 0);
53     /* put out transform (if any) */
54     if (o->oargs.nsargs > 1) {
55     if (xf(&xfs, o->oargs.nsargs-1, o->oargs.sarg+1) !=
56     o->oargs.nsargs-1)
57     objerror(o, USER, "bad transform");
58     glPushAttrib(GL_TRANSFORM_BIT);
59     if (xfs.sca < 1.-FTINY | xfs.sca > 1.+FTINY)
60     glEnable(GL_NORMALIZE);
61     glMatrixMode(GL_MODELVIEW);
62     glPushMatrix();
63     /* matrix order works out to same */
64     #ifdef SMLFLT
65     glMultMatrixf((GLfloat *)xfs.xfm);
66     #else
67     glMultMatrixd((GLdouble *)xfs.xfm);
68     #endif
69     }
70     ot = getoct(o->oargs.sarg[0]); /* get octree reference */
71     if (ot->localmatl &= o->os != NULL) /* set material */
72     setmaterial(o->os, ot->cent, 0);
73     /* call the assigned list */
74     glCallList(ot->listid);
75    
76     if (o->oargs.nsargs > 1) { /* end transform */
77 gwlarson 3.3 glMatrixMode(GL_MODELVIEW);
78 gwlarson 3.1 glPopMatrix();
79     glPopAttrib();
80     }
81     rgl_checkerr("creating instance");
82     }
83    
84    
85     static int
86     buildoctlist(lp) /* build octree list */
87     LUENT *lp;
88     {
89     int old_dolights = dolights, old_domats = domats;
90     register OCTINST *op = (OCTINST *)lp->data;
91    
92     domats = !op->localmatl; /* do materials only if needed */
93     dolights = 0; /* never do light sources */
94     glNewList(op->listid, GL_COMPILE);
95     loadoct(op->octfile); /* load objects into display list */
96     surfclean(); /* clean up */
97     glEndList();
98     dolights = old_dolights; /* restore */
99     domats = old_domats;
100     return(1); /* return success */
101     }
102    
103    
104     int
105     loadoctrees() /* load octrees we've saved up */
106     {
107 gwlarson 3.2 int levelsleft = MAXLEVEL;
108 gwlarson 3.1 int nocts = 0;
109     LUTAB looptab;
110     /* loop through new octree references */
111     while (ottab.tsiz) {
112 gwlarson 3.2 if (!levelsleft--)
113     error(USER, "too many octree levels -- instance loop?");
114 gwlarson 3.1 copystruct(&looptab, &ottab);
115     ottab.tsiz = 0;
116     nocts += lu_doall(&looptab, buildoctlist);
117     lu_done(&looptab);
118     }
119     return(nocts);
120     }
121    
122    
123     static OCTINST *
124     getoct(name) /* get/assign octree list id */
125     char *name;
126     {
127     extern char *getpath(), *getlibpath();
128     char *path;
129     register LUENT *lp;
130     register OCTINST *op;
131    
132     if ((lp = lu_find(&ottab, name)) == NULL)
133     goto memerr;
134     if (lp->key == NULL) {
135     lp->key = (char *)malloc(strlen(name)+1);
136     if (lp->key == NULL)
137     goto memerr;
138     strcpy(lp->key, name);
139     }
140     if ((op = (OCTINST *)lp->data) == NULL) {
141     path = getpath(name, getlibpath(), R_OK);
142     if (path == NULL) {
143     sprintf(errmsg, "cannot find octree \"%s\"", name);
144     error(USER, errmsg);
145     }
146     op = (OCTINST *)(lp->data = (char *)malloc(sizeof(OCTINST)));
147     strcpy(op->octfile, path);
148     checkoct(op->octfile, op->cent);
149     op->listid = newglist();
150     op->localmatl = ~0;
151     }
152     return(op);
153     memerr:
154     error(SYSTEM, "out of memory in getoct");
155     }
156    
157    
158     double
159     checkoct(fname, cent) /* check octree file for validity */
160     char *fname;
161     FVECT cent;
162     {
163     char sbuf[64];
164     FILE *fp = infp;
165     char *fn = infn;
166     double siz = 0.;
167     register int i;
168    
169     if ((infp = fopen(infn=fname, "r")) == NULL) {
170     sprintf(errmsg, "cannot open octree file \"%s\"", fname);
171     error(SYSTEM, errmsg);
172     }
173     #ifdef MSDOS
174     setmode(fileno(infp), O_BINARY);
175     #endif
176     /* get header */
177     if (checkheader(infp, OCTFMT, NULL) < 0)
178     octerror(USER, "not an octree");
179     /* check format */
180     if ((objsize = ogetint(2)-OCTMAGIC) <= 0 ||
181     objsize > MAXOBJSIZ || objsize > sizeof(long))
182     octerror("incompatible octree format");
183     if (cent != NULL) { /* get boundaries (compute center) */
184     for (i = 0; i < 3; i++)
185     cent[i] = atof(ogetstr(sbuf));
186     siz = atof(ogetstr(sbuf))*.5;
187     cent[0] += siz; cent[1] += siz; cent[2] += siz;
188     } else { /* get size (radius) only */
189     for (i = 0; i < 3; i++)
190     ogetstr(sbuf);
191     siz = atof(ogetstr(sbuf))*.5;
192     }
193     fclose(infp);
194     infp = fp;
195     infn = fn;
196     return(siz);
197     }
198    
199    
200     loadoct(fname) /* read in objects from octree */
201     char *fname;
202     {
203     OBJECT fnobjects;
204     char sbuf[256];
205     int nf;
206     register int i;
207     long m;
208    
209     infn = fname;
210     infp = fopen(fname, "r"); /* assume already checked */
211     #ifdef MSDOS
212     setmode(fileno(infp), O_BINARY);
213     #endif
214     /* skip header */
215     getheader(infp, NULL, NULL);
216     /* get format */
217     objsize = ogetint(2)-OCTMAGIC;
218     /* skip boundaries */
219     for (i = 0; i < 4; i++)
220     ogetstr(sbuf);
221     nf = 0; /* load object files */
222     while (*ogetstr(sbuf)) {
223     rgl_load(sbuf);
224     nf++;
225     }
226     /* get number of objects */
227     fnobjects = m = ogetint(objsize);
228     if (fnobjects != m)
229     octerror(USER, "too many objects");
230    
231     if (nf == 0) {
232     skiptree();
233     for (i = 0; *ogetstr(sbuf); i++)
234     if ((otypmap[i] = otype(sbuf)) < 0) {
235     sprintf(errmsg, "unknown type \"%s\"", sbuf);
236     octerror(WARNING, errmsg);
237     }
238     lu_init(&imtab, 1000); nobjects = 0;
239     while (loadobj() != OVOID)
240     ;
241     lu_done(&imtab);
242     if (nobjects != fnobjects)
243     octerror(USER, "inconsistent object count");
244     }
245     fclose(infp);
246     return(nf);
247     }
248    
249    
250     static char *
251     ogetstr(s) /* get null-terminated string */
252     char *s;
253     {
254     extern char *getstr();
255    
256     if (getstr(s, infp) == NULL)
257     octerror(USER, "truncated octree");
258     return(s);
259     }
260    
261    
262     static long
263     ogetint(siz) /* get a siz-byte integer */
264     int siz;
265     {
266     extern long getint();
267     register long r;
268    
269     r = getint(siz, infp);
270     if (feof(infp))
271     octerror(USER, "truncated octree");
272     return(r);
273     }
274    
275    
276     static double
277     ogetflt() /* get a floating point number */
278     {
279     extern double getflt();
280     double r;
281    
282     r = getflt(infp);
283     if (feof(infp))
284     octerror(USER, "truncated octree");
285     return(r);
286     }
287    
288    
289     static
290     skiptree() /* skip octree on input */
291     {
292     register int i;
293    
294     switch (getc(infp)) {
295     case OT_EMPTY:
296     return;
297     case OT_FULL:
298     for (i = ogetint(objsize)*objsize; i-- > 0; )
299     if (getc(infp) == EOF)
300     octerror(USER, "truncated octree");
301     return;
302     case OT_TREE:
303     for (i = 0; i < 8; i++)
304     skiptree();
305     return;
306     case EOF:
307     octerror(USER, "truncated octree");
308     default:
309     octerror(USER, "damaged octree");
310     }
311     }
312    
313    
314     static
315     loadobj() /* get next object */
316     {
317     static OBJREC ob;
318     char idbuf[MAXSTR], sbuf[MAXSTR];
319     register LUENT *lep;
320     register int i;
321     register long m;
322     /* get type */
323     i = ogetint(1);
324     if (i == -1)
325     return(OVOID); /* terminator */
326     if ((ob.otype = otypmap[i]) < 0)
327     octerror(USER, "reference to unknown type");
328     /* get modifier */
329     if ((m = ogetint(objsize)) != OVOID && (OBJECT)m != m)
330     octerror(USER, "too many objects");
331     if ((ob.omod = m) != OVOID && domats) {
332     if ((lep = lu_find(&imtab, (char *)m)) == NULL)
333     goto memerr;
334     ob.os = lep->data;
335     } else
336     ob.os = NULL;
337     /* get name id */
338     ob.oname = ogetstr(idbuf);
339     /* get string arguments */
340     if (ob.oargs.nsargs = ogetint(2)) {
341     ob.oargs.sarg = (char **)malloc
342     (ob.oargs.nsargs*sizeof(char *));
343     if (ob.oargs.sarg == NULL)
344     goto memerr;
345     for (i = 0; i < ob.oargs.nsargs; i++)
346     ob.oargs.sarg[i] = savestr(ogetstr(sbuf));
347     } else
348     ob.oargs.sarg = NULL;
349     /* get integer arguments */
350     #ifdef IARGS
351     if (ob.oargs.niargs = ogetint(2)) {
352     ob.oargs.iarg = (long *)malloc
353     (ob.oargs.niargs*sizeof(long));
354     if (ob.oargs.iarg == NULL)
355     goto memerr;
356     for (i = 0; i < ob.oargs.niargs; i++)
357     ob.oargs.iarg[i] = ogetint(4);
358     } else
359     ob.oargs.iarg = NULL;
360     #endif
361     /* get real arguments */
362     if (ob.oargs.nfargs = ogetint(2)) {
363     ob.oargs.farg = (FLOAT *)malloc
364     (ob.oargs.nfargs*sizeof(FLOAT));
365     if (ob.oargs.farg == NULL)
366     goto memerr;
367     for (i = 0; i < ob.oargs.nfargs; i++)
368     ob.oargs.farg[i] = ogetflt();
369     } else
370     ob.oargs.farg = NULL;
371     /* process object */
372     (*ofun[ob.otype].funp)(&ob);
373     /* record material if modifier */
374     if (ismodifier(ob.otype)) {
375     if ((lep = lu_find(&imtab, (char *)nobjects)) == NULL)
376     goto memerr;
377     lep->key = (char *)nobjects;
378     lep->data = (char *)getmatp(ob.oname);
379     }
380     freefargs(&ob.oargs); /* free arguments */
381     return(nobjects++); /* return object id */
382     memerr:
383     error(SYSTEM, "out of memory in loadobj");
384     }
385    
386    
387     static
388     octerror(etyp, msg) /* octree error */
389     int etyp;
390     char *msg;
391     {
392     char msgbuf[128];
393    
394     sprintf(msgbuf, "(%s): %s", infn, msg);
395     error(etyp, msgbuf);
396     }