Back to index

radiance  4R0+20100331
rglfile.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: rglfile.c,v 3.11 2004/03/28 20:33:12 schorsch Exp $";
00003 #endif
00004 /*
00005  * Load Radiance object(s) and create OpenGL display lists
00006  */
00007 
00008 #include "copyright.h"
00009 
00010 #include <ctype.h>
00011 
00012 #include "rtprocess.h"
00013 #include "radogl.h"
00014 
00015 #ifndef NLIST2ALLOC
00016 #define NLIST2ALLOC  16            /* batch of display lists to get */
00017 #endif
00018 
00019 FUN  ofun[NUMOTYPE] = INIT_OTYPE;
00020 
00021 static int    nextlist, nlistleft = 0;
00022 
00023 
00024 void
00025 initotypes(void)                   /* initialize ofun array */
00026 {
00027        if (ofun[OBJ_SPHERE].funp == o_sphere)
00028               return;                     /* already done */
00029                                           /* assign surface types */
00030        ofun[OBJ_SPHERE].funp =
00031        ofun[OBJ_BUBBLE].funp = o_sphere;
00032        ofun[OBJ_FACE].funp = o_face;
00033        ofun[OBJ_CONE].funp =
00034        ofun[OBJ_CUP].funp =
00035        ofun[OBJ_CYLINDER].funp =
00036        ofun[OBJ_TUBE].funp = o_cone;
00037        ofun[OBJ_RING].funp = o_ring;
00038        ofun[OBJ_SOURCE].funp = o_source;
00039        ofun[OBJ_INSTANCE].funp = o_instance;
00040        ofun[OBJ_MESH].funp = o_unsupported;
00041                                           /* assign material types */
00042        ofun[MAT_TRANS].funp =
00043        ofun[MAT_PLASTIC].funp =
00044        ofun[MAT_METAL].funp = m_normal;
00045        ofun[MAT_GLASS].funp =
00046        ofun[MAT_DIELECTRIC].funp =
00047        ofun[MAT_INTERFACE].funp = m_glass;
00048        ofun[MAT_PLASTIC2].funp =
00049        ofun[MAT_METAL2].funp =
00050        ofun[MAT_TRANS2].funp = m_aniso;
00051        ofun[MAT_TDATA].funp =
00052        ofun[MAT_PDATA].funp =
00053        ofun[MAT_MDATA].funp =
00054        ofun[MAT_TFUNC].funp =
00055        ofun[MAT_PFUNC].funp =
00056        ofun[MAT_MFUNC].funp = m_brdf;
00057        ofun[MAT_BRTDF].funp = m_brdf2;
00058        ofun[MAT_GLOW].funp =
00059        ofun[MAT_LIGHT].funp =
00060        ofun[MAT_SPOT].funp =
00061        ofun[MAT_ILLUM].funp = m_light;
00062        ofun[MAT_MIRROR].funp = m_mirror;
00063        ofun[MAT_DIRECT1].funp =
00064        ofun[MAT_DIRECT2].funp = m_prism;
00065 }
00066 
00067 
00068 int
00069 newglist()                  /* allocate an OGL list id */
00070 {
00071        if (!nlistleft--) {
00072               nextlist = glGenLists(NLIST2ALLOC);
00073               if (!nextlist)
00074                      error(SYSTEM, "no list space left in newglist");
00075               nlistleft = NLIST2ALLOC-1;
00076        }
00077        return(nextlist++);
00078 }
00079 
00080 
00081 void
00082 rgl_checkerr(where)         /* check for GL or GLU error */
00083 char   *where;
00084 {
00085        register GLenum      errcode;
00086 
00087        while ((errcode = glGetError()) != GL_NO_ERROR) {
00088               sprintf(errmsg, "OpenGL error %s: %s",
00089                             where, gluErrorString(errcode));
00090               error(WARNING, errmsg);
00091        }
00092 }
00093 
00094 
00095 int
00096 rgl_filelist(ic, inp, nl)   /* load scene files into display list */
00097 int    ic;
00098 char   **inp;
00099 int    *nl;                 /* returned number of lists (optional) */
00100 {
00101        int    listid;
00102 
00103        initotypes();        /* prepare */
00104        listid = newglist();
00105        glNewList(listid, GL_COMPILE);
00106        lightinit();         /* start light source list */
00107        while (ic--)         /* load each file */
00108               rgl_load(*inp++);
00109        surfclean();         /* clean up first pass */
00110        lightclean();        /* clean up light sources also */
00111        glEndList();         /* end of top display list */
00112        lightdefs();         /* define light sources */
00113        loadoctrees();              /* load octrees (sublists) for instances */
00114        if (nl != NULL)             /* return total number of lists allocated */
00115               *nl = nextlist - listid;
00116        return(listid);             /* all done -- return list id */
00117 }
00118 
00119 
00120 int
00121 rgl_octlist(fname, cent, radp, nl) /* load scen into display list */
00122 char   *fname;
00123 FVECT  cent;                /* returned octree center (optional) */
00124 RREAL  *radp;               /* returned octree size (optional) */
00125 int    *nl;                 /* returned number of lists (optional) */
00126 {
00127        double r;
00128        int    listid;
00129                             /* modeled after rgl_filelist() */
00130        initotypes();
00131                             /* check the octree and get its size */
00132        r = checkoct(fname, cent);
00133        if (radp != NULL) *radp = r;
00134                             /* start the display list */
00135        listid = newglist();
00136        glNewList(listid, GL_COMPILE);
00137        lightinit();         /* start light source list */
00138        loadoct(fname);             /* load octree objects into display list */
00139        surfclean();         /* clean up and close top list */
00140        lightclean();        /* clean up light sources also */
00141        glEndList();         /* close top list */
00142        lightdefs();         /* define light sources */
00143        loadoctrees();              /* load referenced octrees into sublists */
00144        if (nl != NULL)             /* return total number of lists allocated */
00145               *nl = nextlist - listid;
00146        return(listid);
00147 }
00148 
00149 
00150 void
00151 rgl_load(inpspec)           /* convert scene description into OGL calls */
00152 char   *inpspec;
00153 {
00154        char   *fgetline();
00155        FILE   *infp;
00156        char   buf[1024];
00157        register int  c;
00158 
00159        if (inpspec == NULL) {
00160               infp = stdin;
00161               inpspec = "standard input";
00162        } else if (inpspec[0] == '!') {
00163               if ((infp = popen(inpspec+1, "r")) == NULL) {
00164                      sprintf(errmsg, "cannot execute \"%s\"", inpspec);
00165                      error(SYSTEM, errmsg);
00166               }
00167        } else if ((infp = fopen(inpspec, "r")) == NULL) {
00168               sprintf(errmsg, "cannot open scene file \"%s\"", inpspec);
00169               error(SYSTEM, errmsg);
00170        }
00171        while ((c = getc(infp)) != EOF) {
00172               if (isspace(c))
00173                      continue;
00174               if (c == '#') {                           /* comment */
00175                      fgets(buf, sizeof(buf), infp);
00176               } else if (c == '!') {                    /* command */
00177                      ungetc(c, infp);
00178                      fgetline(buf, sizeof(buf), infp);
00179                      rgl_load(buf);
00180               } else {                           /* object */
00181                      ungetc(c, infp);
00182                      rgl_object(inpspec, infp);
00183               }
00184        }
00185        if (inpspec[0] == '!')
00186               pclose(infp);
00187        else
00188               fclose(infp);
00189 }
00190 
00191 
00192 void
00193 rgl_object(name, fp)               /* read the next object */
00194 char  *name;
00195 FILE  *fp;
00196 {
00197        static OBJREC ob;
00198        char  sbuf[MAXSTR];
00199        int  rval;
00200                                    /* get modifier */
00201        strcpy(sbuf, "EOF");
00202        fgetword(sbuf, MAXSTR, fp);
00203        ob.omod = 0;                /* use ob.os for pointer to material */
00204        if (!strcmp(sbuf, VOIDID) || !strcmp(sbuf, ALIASMOD))
00205               ob.os = NULL;
00206        else
00207               ob.os = (char *)getmatp(sbuf);
00208                                    /* get type */
00209        strcpy(sbuf, "EOF");
00210        fgetword(sbuf, MAXSTR, fp);
00211        if ((ob.otype = otype(sbuf)) < 0) {
00212               sprintf(errmsg, "(%s): unknown type \"%s\"", name, sbuf);
00213               error(USER, errmsg);
00214        }
00215                                    /* get identifier */
00216        sbuf[0] = '\0';
00217        fgetword(sbuf, MAXSTR, fp);
00218        ob.oname = sbuf;
00219                                    /* get arguments */
00220        if (ob.otype == MOD_ALIAS) {
00221               char  sbuf2[MAXSTR];        /* get alias */
00222               strcpy(sbuf2, "EOF");
00223               fgetword(sbuf2, MAXSTR, fp);
00224               if (ob.os == NULL)
00225                      ob.os = (char *)getmatp(sbuf2);
00226               o_default(&ob);                    /* fake reference */
00227               return;
00228        }
00229        if ((rval = readfargs(&ob.oargs, fp)) == 0) {
00230               sprintf(errmsg, "(%s): bad arguments", name);
00231               objerror(&ob, USER, errmsg);
00232        } else if (rval < 0) {
00233               sprintf(errmsg, "(%s): error reading scene", name);
00234               error(SYSTEM, errmsg);
00235        }
00236                                    /* execute */
00237        (*ofun[ob.otype].funp)(&ob);
00238                                    /* free arguments */
00239        freefargs(&ob.oargs);
00240 }