ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhd_geom.c
Revision: 3.10
Committed: Tue May 13 17:58:33 2003 UTC (20 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 3.9: +4 -4 lines
Log Message:
Changed (char *) casts for memory copies to (void *) and other fixes

File Contents

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