ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/hd/rhd_geom.c
Revision: 3.14
Committed: Thu Jan 1 11:21:55 2004 UTC (20 years, 3 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 3.13: +33 -18 lines
Log Message:
Ansification and prototypes.

File Contents

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