ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhd_geom.c
Revision: 3.7
Committed: Fri Jan 29 15:04:03 1999 UTC (25 years, 3 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.6: +4 -2 lines
Log Message:
addes savestr() call to gmAddGeom() for safety

File Contents

# Content
1 /* Copyright (c) 1999 Silicon Graphics, Inc. */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ SGI";
5 #endif
6
7 /*
8 * Geometry drawing operations for OpenGL driver.
9 */
10
11 #include "radogl.h"
12 #include "rhdriver.h"
13
14 #ifndef MAXGEO
15 #define MAXGEO 8 /* maximum geometry list length */
16 #endif
17 #ifndef MAXPORT
18 #define MAXPORT (MAXGEO*4) /* maximum number of portal files */
19 #endif
20
21 int gmPortals = 0; /* current portal GL list id */
22 static char *curportlist[MAXPORT]; /* current portal list */
23 static char *newportlist[MAXPORT]; /* new portal file list */
24
25 static struct gmEntry {
26 char *gfile; /* geometry file name */
27 FVECT cent; /* centroid */
28 FLOAT rad; /* radius */
29 int listid; /* display list identifier */
30 } gmCurrent[MAXGEO], gmNext[MAXGEO]; /* current and next list */
31
32 #define FORALLGEOM(ot,i) for (i=0;i<MAXGEO&&ot[i].gfile!=NULL;i++)
33
34 #define FORALLPORT(pl,i) for (i=0;i<MAXPORT&&pl[i]!=NULL;i++)
35
36 extern char *nextword();
37
38
39 gmNewGeom(file) /* add new geometry to next list */
40 char *file;
41 {
42 register int i, j;
43 /* check if already in next list */
44 FORALLGEOM(gmNext, i)
45 if (!strcmp(file, gmNext[i].gfile))
46 return;
47 if (i >= MAXGEO) {
48 error(WARNING, "too many section octrees -- ignoring extra");
49 return;
50 }
51 /* check if copy in current list */
52 FORALLGEOM(gmCurrent, j)
53 if (!strcmp(file, gmCurrent[j].gfile)) {
54 copystruct(&gmNext[i], &gmCurrent[j]);
55 return;
56 }
57 /* else load new octree */
58 gmNext[i].gfile = savestr(file);
59 dolights = 0;
60 domats = 1;
61 gmNext[i].listid = rgl_octlist(file, gmNext[i].cent, &gmNext[i].rad);
62 gmNext[i].rad *= 1.732; /* go to corners */
63 #ifdef DEBUG
64 fprintf(stderr, "Loaded octree \"%s\" into listID %d with radius %f\n",
65 file, gmNext[i].listid, gmNext[i].rad);
66 #endif
67 }
68
69
70 gmEndGeom() /* make next list current */
71 {
72 register int i, j;
73
74 FORALLGEOM(gmCurrent, i) {
75 FORALLGEOM(gmNext, j)
76 if (gmNext[j].listid == gmCurrent[i].listid)
77 break;
78 if (j >= MAXGEO || gmNext[j].gfile == NULL) {
79 glDeleteLists(gmCurrent[i].listid, 1); /* not found */
80 freestr(gmCurrent[i].gfile);
81 }
82 }
83 bcopy((char *)gmNext, (char *)gmCurrent, sizeof(gmNext));
84 bzero((char *)gmNext, sizeof(gmNext));
85 }
86
87
88 int
89 gmDrawGeom() /* draw current list of octrees */
90 {
91 register int n;
92
93 FORALLGEOM(gmCurrent, n)
94 glCallList(gmCurrent[n].listid);
95 return(n);
96 }
97
98
99 gmDrawPortals(r, g, b, a) /* draw portals with specific RGBA value */
100 int r, g, b, a;
101 {
102 if (!gmPortals || r<0 & g<0 & b<0 & a<0)
103 return;
104 glPushAttrib(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT|
105 GL_POLYGON_BIT|GL_LIGHTING_BIT);
106 glDisable(GL_LIGHTING);
107 glDisable(GL_DITHER);
108 glShadeModel(GL_FLAT);
109 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
110 /* don't actually write depth */
111 glDepthMask(GL_FALSE);
112 /* draw only selected channels */
113 glColorMask(r>=0, g>=0, b>=0, a>=0);
114 glColor4ub(r&0xff, g&0xff, b&0xff, a&0xff);
115 glCallList(gmPortals); /* draw them portals */
116 glPopAttrib();
117 }
118
119
120 gmDepthLimit(dl, vorg, vdir) /* compute approximate depth limits for view */
121 double dl[2];
122 FVECT vorg, vdir;
123 {
124 FVECT v;
125 double dcent;
126 register int i;
127
128 dl[0] = FHUGE; dl[1] = 0.;
129 FORALLGEOM(gmCurrent, i) {
130 VSUB(v, gmCurrent[i].cent, vorg);
131 dcent = DOT(v, vdir);
132 if (dl[0] > dcent-gmCurrent[i].rad)
133 dl[0] = dcent-gmCurrent[i].rad;
134 if (dl[1] < dcent+gmCurrent[i].rad)
135 dl[1] = dcent+gmCurrent[i].rad;
136 }
137 if (dl[0] < 0.)
138 dl[0] = 0.;
139 }
140
141
142 gmNewPortal(pflist) /* add portal file(s) to our new list */
143 char *pflist;
144 {
145 register int i, j;
146 char newfile[128];
147
148 if (pflist == NULL)
149 return;
150 while ((pflist = nextword(newfile, sizeof(newfile), pflist)) != NULL) {
151 FORALLPORT(newportlist,i)
152 if (!strcmp(newportlist[i], newfile))
153 goto endloop; /* in list already */
154 if (i >= MAXPORT) {
155 error(WARNING, "too many portals -- ignoring extra");
156 return;
157 }
158 newportlist[i] = savestr(newfile);
159 endloop:;
160 }
161 }
162
163
164 static int
165 sstrcmp(ss0, ss1)
166 char **ss0, **ss1;
167 {
168 return(strcmp(*ss0, *ss1));
169 }
170
171
172 int
173 gmEndPortal() /* close portal list and return GL list */
174 {
175 register int n;
176
177 FORALLPORT(newportlist, n);
178 if (!n) { /* free old GL list */
179 if (gmPortals)
180 glDeleteLists(gmPortals, 1);
181 gmPortals = 0;
182 } else
183 qsort(newportlist, n, sizeof(char *), sstrcmp);
184 FORALLPORT(newportlist, n) /* compare sorted lists */
185 if (curportlist[n] == NULL ||
186 strcmp(curportlist[n],newportlist[n])) {
187 /* load new list */
188 if (gmPortals)
189 glDeleteLists(gmPortals, 1);
190 FORALLPORT(newportlist, n);
191 dolights = 0;
192 domats = 0;
193 gmPortals = rgl_filelist(n, newportlist);
194 break;
195 }
196 FORALLPORT(curportlist, n) /* free old file list */
197 freestr(curportlist[n]);
198 bcopy((char *)newportlist, (char *)curportlist, sizeof(newportlist));
199 bzero((char *)newportlist, sizeof(newportlist));
200 return(gmPortals); /* return GL list id */
201 }