ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhd_geom.c
Revision: 3.8
Committed: Fri Jan 29 15:33:36 1999 UTC (25 years, 2 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 3.7: +8 -4 lines
Log Message:
added number of lists for proper list deallocation

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