| 1 | gwlarson | 3.1 | #ifndef lint | 
| 2 | schorsch | 3.11 | static const char       RCSid[] = "$Id: rglfile.c,v 3.10 2003/11/14 17:22:06 schorsch Exp $"; | 
| 3 | gwlarson | 3.1 | #endif | 
| 4 |  |  | /* | 
| 5 |  |  | * Load Radiance object(s) and create OpenGL display lists | 
| 6 |  |  | */ | 
| 7 |  |  |  | 
| 8 | greg | 3.5 | #include "copyright.h" | 
| 9 | schorsch | 3.10 |  | 
| 10 |  |  | #include <ctype.h> | 
| 11 | greg | 3.4 |  | 
| 12 | schorsch | 3.9 | #include "rtprocess.h" | 
| 13 | gwlarson | 3.1 | #include "radogl.h" | 
| 14 |  |  |  | 
| 15 |  |  | #ifndef NLIST2ALLOC | 
| 16 |  |  | #define NLIST2ALLOC     16              /* batch of display lists to get */ | 
| 17 |  |  | #endif | 
| 18 |  |  |  | 
| 19 |  |  | FUN  ofun[NUMOTYPE] = INIT_OTYPE; | 
| 20 |  |  |  | 
| 21 | gwlarson | 3.3 | static int      nextlist, nlistleft = 0; | 
| 22 | gwlarson | 3.1 |  | 
| 23 | gwlarson | 3.3 |  | 
| 24 | schorsch | 3.11 | void | 
| 25 |  |  | initotypes(void)                        /* initialize ofun array */ | 
| 26 | gwlarson | 3.1 | { | 
| 27 |  |  | if (ofun[OBJ_SPHERE].funp == o_sphere) | 
| 28 |  |  | return;                 /* already done */ | 
| 29 |  |  | /* assign surface types */ | 
| 30 |  |  | ofun[OBJ_SPHERE].funp = | 
| 31 |  |  | ofun[OBJ_BUBBLE].funp = o_sphere; | 
| 32 |  |  | ofun[OBJ_FACE].funp = o_face; | 
| 33 |  |  | ofun[OBJ_CONE].funp = | 
| 34 |  |  | ofun[OBJ_CUP].funp = | 
| 35 |  |  | ofun[OBJ_CYLINDER].funp = | 
| 36 |  |  | ofun[OBJ_TUBE].funp = o_cone; | 
| 37 |  |  | ofun[OBJ_RING].funp = o_ring; | 
| 38 |  |  | ofun[OBJ_SOURCE].funp = o_source; | 
| 39 |  |  | ofun[OBJ_INSTANCE].funp = o_instance; | 
| 40 | greg | 3.7 | ofun[OBJ_MESH].funp = o_unsupported; | 
| 41 | gwlarson | 3.1 | /* assign material types */ | 
| 42 |  |  | ofun[MAT_TRANS].funp = | 
| 43 |  |  | ofun[MAT_PLASTIC].funp = | 
| 44 |  |  | ofun[MAT_METAL].funp = m_normal; | 
| 45 |  |  | ofun[MAT_GLASS].funp = | 
| 46 |  |  | ofun[MAT_DIELECTRIC].funp = | 
| 47 |  |  | ofun[MAT_INTERFACE].funp = m_glass; | 
| 48 |  |  | ofun[MAT_PLASTIC2].funp = | 
| 49 |  |  | ofun[MAT_METAL2].funp = | 
| 50 |  |  | ofun[MAT_TRANS2].funp = m_aniso; | 
| 51 |  |  | ofun[MAT_TDATA].funp = | 
| 52 |  |  | ofun[MAT_PDATA].funp = | 
| 53 |  |  | ofun[MAT_MDATA].funp = | 
| 54 |  |  | ofun[MAT_TFUNC].funp = | 
| 55 |  |  | ofun[MAT_PFUNC].funp = | 
| 56 |  |  | ofun[MAT_MFUNC].funp = m_brdf; | 
| 57 |  |  | ofun[MAT_BRTDF].funp = m_brdf2; | 
| 58 |  |  | ofun[MAT_GLOW].funp = | 
| 59 |  |  | ofun[MAT_LIGHT].funp = | 
| 60 |  |  | ofun[MAT_SPOT].funp = | 
| 61 |  |  | ofun[MAT_ILLUM].funp = m_light; | 
| 62 |  |  | ofun[MAT_MIRROR].funp = m_mirror; | 
| 63 |  |  | ofun[MAT_DIRECT1].funp = | 
| 64 |  |  | ofun[MAT_DIRECT2].funp = m_prism; | 
| 65 |  |  | } | 
| 66 |  |  |  | 
| 67 |  |  |  | 
| 68 |  |  | int | 
| 69 |  |  | newglist()                      /* allocate an OGL list id */ | 
| 70 |  |  | { | 
| 71 | gwlarson | 3.3 | if (!nlistleft--) { | 
| 72 | gwlarson | 3.1 | nextlist = glGenLists(NLIST2ALLOC); | 
| 73 | gwlarson | 3.3 | if (!nextlist) | 
| 74 |  |  | error(SYSTEM, "no list space left in newglist"); | 
| 75 |  |  | nlistleft = NLIST2ALLOC-1; | 
| 76 | gwlarson | 3.1 | } | 
| 77 |  |  | return(nextlist++); | 
| 78 |  |  | } | 
| 79 |  |  |  | 
| 80 |  |  |  | 
| 81 | greg | 3.4 | void | 
| 82 | gwlarson | 3.1 | rgl_checkerr(where)             /* check for GL or GLU error */ | 
| 83 |  |  | char    *where; | 
| 84 |  |  | { | 
| 85 |  |  | register GLenum errcode; | 
| 86 |  |  |  | 
| 87 |  |  | while ((errcode = glGetError()) != GL_NO_ERROR) { | 
| 88 |  |  | sprintf(errmsg, "OpenGL error %s: %s", | 
| 89 |  |  | where, gluErrorString(errcode)); | 
| 90 |  |  | error(WARNING, errmsg); | 
| 91 |  |  | } | 
| 92 |  |  | } | 
| 93 |  |  |  | 
| 94 |  |  |  | 
| 95 |  |  | int | 
| 96 | gwlarson | 3.3 | rgl_filelist(ic, inp, nl)       /* load scene files into display list */ | 
| 97 | gwlarson | 3.1 | int     ic; | 
| 98 |  |  | char    **inp; | 
| 99 | gwlarson | 3.3 | int     *nl;                    /* returned number of lists (optional) */ | 
| 100 | gwlarson | 3.1 | { | 
| 101 |  |  | int     listid; | 
| 102 |  |  |  | 
| 103 |  |  | initotypes();           /* prepare */ | 
| 104 |  |  | listid = newglist(); | 
| 105 |  |  | glNewList(listid, GL_COMPILE); | 
| 106 |  |  | lightinit();            /* start light source list */ | 
| 107 |  |  | while (ic--)            /* load each file */ | 
| 108 |  |  | rgl_load(*inp++); | 
| 109 |  |  | surfclean();            /* clean up first pass */ | 
| 110 |  |  | lightclean();           /* clean up light sources also */ | 
| 111 |  |  | glEndList();            /* end of top display list */ | 
| 112 |  |  | lightdefs();            /* define light sources */ | 
| 113 |  |  | loadoctrees();          /* load octrees (sublists) for instances */ | 
| 114 | gwlarson | 3.3 | if (nl != NULL)         /* return total number of lists allocated */ | 
| 115 |  |  | *nl = nextlist - listid; | 
| 116 | gwlarson | 3.1 | return(listid);         /* all done -- return list id */ | 
| 117 |  |  | } | 
| 118 |  |  |  | 
| 119 |  |  |  | 
| 120 |  |  | int | 
| 121 | gwlarson | 3.3 | rgl_octlist(fname, cent, radp, nl)      /* load scen into display list */ | 
| 122 | gwlarson | 3.1 | char    *fname; | 
| 123 |  |  | FVECT   cent;                   /* returned octree center (optional) */ | 
| 124 | schorsch | 3.8 | RREAL   *radp;                  /* returned octree size (optional) */ | 
| 125 | gwlarson | 3.3 | int     *nl;                    /* returned number of lists (optional) */ | 
| 126 | gwlarson | 3.1 | { | 
| 127 |  |  | double  r; | 
| 128 |  |  | int     listid; | 
| 129 |  |  | /* modeled after rgl_filelist() */ | 
| 130 |  |  | initotypes(); | 
| 131 |  |  | /* check the octree and get its size */ | 
| 132 |  |  | r = checkoct(fname, cent); | 
| 133 |  |  | if (radp != NULL) *radp = r; | 
| 134 |  |  | /* start the display list */ | 
| 135 |  |  | listid = newglist(); | 
| 136 |  |  | glNewList(listid, GL_COMPILE); | 
| 137 |  |  | lightinit();            /* start light source list */ | 
| 138 |  |  | loadoct(fname);         /* load octree objects into display list */ | 
| 139 |  |  | surfclean();            /* clean up and close top list */ | 
| 140 |  |  | lightclean();           /* clean up light sources also */ | 
| 141 |  |  | glEndList();            /* close top list */ | 
| 142 |  |  | lightdefs();            /* define light sources */ | 
| 143 |  |  | loadoctrees();          /* load referenced octrees into sublists */ | 
| 144 | gwlarson | 3.3 | if (nl != NULL)         /* return total number of lists allocated */ | 
| 145 |  |  | *nl = nextlist - listid; | 
| 146 | gwlarson | 3.1 | return(listid); | 
| 147 |  |  | } | 
| 148 |  |  |  | 
| 149 |  |  |  | 
| 150 | greg | 3.4 | void | 
| 151 | gwlarson | 3.1 | rgl_load(inpspec)               /* convert scene description into OGL calls */ | 
| 152 |  |  | char    *inpspec; | 
| 153 |  |  | { | 
| 154 |  |  | char    *fgetline(); | 
| 155 |  |  | FILE    *infp; | 
| 156 |  |  | char    buf[1024]; | 
| 157 |  |  | register int    c; | 
| 158 |  |  |  | 
| 159 |  |  | if (inpspec == NULL) { | 
| 160 |  |  | infp = stdin; | 
| 161 |  |  | inpspec = "standard input"; | 
| 162 |  |  | } else if (inpspec[0] == '!') { | 
| 163 |  |  | if ((infp = popen(inpspec+1, "r")) == NULL) { | 
| 164 |  |  | sprintf(errmsg, "cannot execute \"%s\"", inpspec); | 
| 165 |  |  | error(SYSTEM, errmsg); | 
| 166 |  |  | } | 
| 167 |  |  | } else if ((infp = fopen(inpspec, "r")) == NULL) { | 
| 168 |  |  | sprintf(errmsg, "cannot open scene file \"%s\"", inpspec); | 
| 169 |  |  | error(SYSTEM, errmsg); | 
| 170 |  |  | } | 
| 171 |  |  | while ((c = getc(infp)) != EOF) { | 
| 172 |  |  | if (isspace(c)) | 
| 173 |  |  | continue; | 
| 174 |  |  | if (c == '#') {                         /* comment */ | 
| 175 |  |  | fgets(buf, sizeof(buf), infp); | 
| 176 |  |  | } else if (c == '!') {                  /* command */ | 
| 177 |  |  | ungetc(c, infp); | 
| 178 |  |  | fgetline(buf, sizeof(buf), infp); | 
| 179 |  |  | rgl_load(buf); | 
| 180 |  |  | } else {                                /* object */ | 
| 181 |  |  | ungetc(c, infp); | 
| 182 |  |  | rgl_object(inpspec, infp); | 
| 183 |  |  | } | 
| 184 |  |  | } | 
| 185 |  |  | if (inpspec[0] == '!') | 
| 186 |  |  | pclose(infp); | 
| 187 |  |  | else | 
| 188 |  |  | fclose(infp); | 
| 189 |  |  | } | 
| 190 |  |  |  | 
| 191 |  |  |  | 
| 192 | greg | 3.4 | void | 
| 193 | gwlarson | 3.1 | rgl_object(name, fp)                    /* read the next object */ | 
| 194 |  |  | char  *name; | 
| 195 |  |  | FILE  *fp; | 
| 196 |  |  | { | 
| 197 |  |  | static OBJREC   ob; | 
| 198 |  |  | char  sbuf[MAXSTR]; | 
| 199 |  |  | int  rval; | 
| 200 |  |  | /* get modifier */ | 
| 201 |  |  | strcpy(sbuf, "EOF"); | 
| 202 |  |  | fgetword(sbuf, MAXSTR, fp); | 
| 203 |  |  | ob.omod = 0;                    /* use ob.os for pointer to material */ | 
| 204 | greg | 3.6 | if (!strcmp(sbuf, VOIDID) || !strcmp(sbuf, ALIASMOD)) | 
| 205 | gwlarson | 3.1 | ob.os = NULL; | 
| 206 |  |  | else | 
| 207 |  |  | ob.os = (char *)getmatp(sbuf); | 
| 208 |  |  | /* get type */ | 
| 209 |  |  | strcpy(sbuf, "EOF"); | 
| 210 |  |  | fgetword(sbuf, MAXSTR, fp); | 
| 211 | greg | 3.6 | if ((ob.otype = otype(sbuf)) < 0) { | 
| 212 | gwlarson | 3.1 | sprintf(errmsg, "(%s): unknown type \"%s\"", name, sbuf); | 
| 213 |  |  | error(USER, errmsg); | 
| 214 |  |  | } | 
| 215 |  |  | /* get identifier */ | 
| 216 |  |  | sbuf[0] = '\0'; | 
| 217 |  |  | fgetword(sbuf, MAXSTR, fp); | 
| 218 |  |  | ob.oname = sbuf; | 
| 219 |  |  | /* get arguments */ | 
| 220 | greg | 3.6 | if (ob.otype == MOD_ALIAS) { | 
| 221 | gwlarson | 3.1 | char  sbuf2[MAXSTR];            /* get alias */ | 
| 222 |  |  | strcpy(sbuf2, "EOF"); | 
| 223 |  |  | fgetword(sbuf2, MAXSTR, fp); | 
| 224 |  |  | if (ob.os == NULL) | 
| 225 |  |  | ob.os = (char *)getmatp(sbuf2); | 
| 226 |  |  | o_default(&ob);                 /* fake reference */ | 
| 227 |  |  | return; | 
| 228 |  |  | } | 
| 229 |  |  | if ((rval = readfargs(&ob.oargs, fp)) == 0) { | 
| 230 |  |  | sprintf(errmsg, "(%s): bad arguments", name); | 
| 231 |  |  | objerror(&ob, USER, errmsg); | 
| 232 |  |  | } else if (rval < 0) { | 
| 233 |  |  | sprintf(errmsg, "(%s): error reading scene", name); | 
| 234 |  |  | error(SYSTEM, errmsg); | 
| 235 |  |  | } | 
| 236 |  |  | /* execute */ | 
| 237 |  |  | (*ofun[ob.otype].funp)(&ob); | 
| 238 |  |  | /* free arguments */ | 
| 239 |  |  | freefargs(&ob.oargs); | 
| 240 |  |  | } |