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

# Content
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 #define MAXLEVEL 16 /* maximum instance hierarchy level */
15
16 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 glMatrixMode(GL_MODELVIEW);
78 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 int levelsleft = MAXLEVEL;
108 int nocts = 0;
109 LUTAB looptab;
110 /* loop through new octree references */
111 while (ottab.tsiz) {
112 if (!levelsleft--)
113 error(USER, "too many octree levels -- instance loop?");
114 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 }