ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhd_geom.c
Revision: 3.13
Committed: Mon Jul 21 22:30:18 2003 UTC (20 years, 8 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 3.12: +2 -2 lines
Log Message:
Eliminated copystruct() macro, which is unnecessary in ANSI.
Reduced ambiguity warnings for nested if/if/else clauses.

File Contents

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