ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/rt/rpict.c
Revision: 1.8
Committed: Wed Sep 13 15:21:41 1989 UTC (34 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.7: +17 -16 lines
Log Message:
Added xres,yres variables so we don't mung ourview.[hv]resolu

File Contents

# Content
1 /* Copyright (c) 1986 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * rpict.c - routines and variables for picture generation.
9 *
10 * 8/14/85
11 */
12
13 #include "ray.h"
14
15 #ifdef BSD
16 #include <sys/time.h>
17 #include <sys/resource.h>
18 #endif
19
20 #include "view.h"
21
22 #include "random.h"
23
24 VIEW ourview = STDVIEW(512); /* view parameters */
25
26 int psample = 4; /* pixel sample size */
27 double maxdiff = .05; /* max. difference for interpolation */
28 double dstrpix = 0.67; /* square pixel distribution */
29
30 double dstrsrc = 0.0; /* square source distribution */
31 double shadthresh = .05; /* shadow threshold */
32 double shadcert = .5; /* shadow certainty */
33
34 int maxdepth = 6; /* maximum recursion depth */
35 double minweight = 5e-3; /* minimum ray weight */
36
37 COLOR ambval = BLKCOLOR; /* ambient value */
38 double ambacc = 0.2; /* ambient accuracy */
39 int ambres = 32; /* ambient resolution */
40 int ambdiv = 128; /* ambient divisions */
41 int ambssamp = 0; /* ambient super-samples */
42 int ambounce = 0; /* ambient bounces */
43 char *amblist[128]; /* ambient include/exclude list */
44 int ambincl = -1; /* include == 1, exclude == 0 */
45
46 int ralrm = 0; /* seconds between reports */
47
48 double pctdone = 0.0; /* percentage done */
49
50 extern long nrays; /* number of rays traced */
51
52 static int xres, yres; /* output x and y resolution */
53
54 #define MAXDIV 32 /* maximum sample size */
55
56 #define pixjitter() (.5+dstrpix*(.5-frandom()))
57
58
59 quit(code) /* quit program */
60 int code;
61 {
62 if (code || ralrm > 0) /* report status */
63 report();
64
65 exit(code);
66 }
67
68
69 report() /* report progress */
70 {
71 #ifdef BSD
72 struct rusage rubuf;
73 double t;
74
75 getrusage(RUSAGE_SELF, &rubuf);
76 t = (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
77 t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
78 getrusage(RUSAGE_CHILDREN, &rubuf);
79 t += (rubuf.ru_utime.tv_usec + rubuf.ru_stime.tv_usec) / 1e6;
80 t += rubuf.ru_utime.tv_sec + rubuf.ru_stime.tv_sec;
81
82 sprintf(errmsg, "%ld rays, %4.2f%% done after %5.4f CPU hours\n",
83 nrays, pctdone, t/3600.0);
84 #else
85 sprintf(errmsg, "%ld rays, %4.2f%% done\n", nrays, pctdone);
86 #endif
87 eputs(errmsg);
88
89 if (ralrm > 0)
90 alarm(ralrm);
91 }
92
93
94 render(oldfile) /* render the scene */
95 char *oldfile;
96 {
97 COLOR *scanbar[MAXDIV+1]; /* scanline arrays of pixel values */
98 int ypos; /* current scanline */
99 COLOR *colptr;
100 register int i;
101
102 if (psample < 1)
103 psample = 1;
104 else if (psample > MAXDIV)
105 psample = MAXDIV;
106 /* output resolution may be smaller */
107 xres = ourview.hresolu - (ourview.hresolu % psample);
108 yres = ourview.vresolu - (ourview.vresolu % psample);
109
110 for (i = 0; i <= psample; i++) {
111 scanbar[i] = (COLOR *)malloc((xres+1)*sizeof(COLOR));
112 if (scanbar[i] == NULL)
113 error(SYSTEM, "out of memory in render");
114 }
115 /* write out boundaries */
116 fputresolu(YMAJOR|YDECR, xres, yres, stdout);
117
118 ypos = yres - salvage(oldfile); /* find top line */
119 fillscanline(scanbar[0], ypos, psample); /* top scan */
120
121 for (ypos -= psample; ypos > -psample; ypos -= psample) {
122
123 colptr = scanbar[psample]; /* get last scanline */
124 scanbar[psample] = scanbar[0];
125 scanbar[0] = colptr;
126
127 fillscanline(scanbar[0], ypos, psample); /* base scan */
128
129 fillscanbar(scanbar, ypos, psample);
130
131 for (i = psample-1; i >= 0; i--)
132 if (fwritescan(scanbar[i], xres, stdout) < 0)
133 goto writerr;
134 if (fflush(stdout) == EOF)
135 goto writerr;
136 pctdone = 100.0*(yres-ypos)/yres;
137 }
138
139 for (i = 0; i <= psample; i++)
140 free((char *)scanbar[i]);
141 return;
142 writerr:
143 error(SYSTEM, "write error in render");
144 }
145
146
147 fillscanline(scanline, y, xstep) /* fill scan line at y */
148 register COLOR *scanline;
149 int y, xstep;
150 {
151 int b = xstep;
152 register int i;
153
154 pixvalue(scanline[0], 0, y);
155
156 for (i = xstep; i <= xres; i += xstep) {
157
158 pixvalue(scanline[i], i, y);
159
160 b = fillsample(scanline+i-xstep, i-xstep, y, xstep, 0, b/2);
161 }
162 }
163
164
165 fillscanbar(scanbar, y, ysize) /* fill interior */
166 register COLOR *scanbar[];
167 int y, ysize;
168 {
169 COLOR vline[MAXDIV+1];
170 int b = ysize;
171 register int i, j;
172
173 for (i = 0; i < xres; i++) {
174
175 copycolor(vline[0], scanbar[0][i]);
176 copycolor(vline[ysize], scanbar[ysize][i]);
177
178 b = fillsample(vline, i, y, 0, ysize, b/2);
179
180 for (j = 1; j < ysize; j++)
181 copycolor(scanbar[j][i], vline[j]);
182 }
183 }
184
185
186 int
187 fillsample(colline, x, y, xlen, ylen, b) /* fill interior points */
188 register COLOR *colline;
189 int x, y;
190 int xlen, ylen;
191 int b;
192 {
193 double ratio;
194 COLOR ctmp;
195 int ncut;
196 register int len;
197
198 if (xlen > 0) /* x or y length is zero */
199 len = xlen;
200 else
201 len = ylen;
202
203 if (len <= 1) /* limit recursion */
204 return(0);
205
206 if (b > 0 || bigdiff(colline[0], colline[len], maxdiff)) {
207
208 pixvalue(colline[len>>1], x + (xlen>>1), y + (ylen>>1));
209 ncut = 1;
210
211 } else { /* interpolate */
212
213 copycolor(colline[len>>1], colline[len]);
214 ratio = (double)(len>>1) / len;
215 scalecolor(colline[len>>1], ratio);
216 copycolor(ctmp, colline[0]);
217 ratio = 1.0 - ratio;
218 scalecolor(ctmp, ratio);
219 addcolor(colline[len>>1], ctmp);
220 ncut = 0;
221 }
222 /* recurse */
223 ncut += fillsample(colline, x, y, xlen>>1, ylen>>1, (b-1)/2);
224
225 ncut += fillsample(colline + (len>>1), x + (xlen>>1), y + (ylen>>1),
226 xlen - (xlen>>1), ylen - (ylen>>1), b/2);
227
228 return(ncut);
229 }
230
231
232 pixvalue(col, x, y) /* compute pixel value */
233 COLOR col; /* returned color */
234 int x, y; /* pixel position */
235 {
236 static RAY thisray; /* our ray for this pixel */
237
238 rayview(thisray.rorg, thisray.rdir, &ourview,
239 x + pixjitter(), y + pixjitter());
240
241 rayorigin(&thisray, NULL, PRIMARY, 1.0);
242
243 rayvalue(&thisray); /* trace ray */
244
245 copycolor(col, thisray.rcol); /* return color */
246 }
247
248
249 int
250 salvage(oldfile) /* salvage scanlines from killed program */
251 char *oldfile;
252 {
253 COLR *scanline;
254 FILE *fp;
255 int x, y;
256
257 if (oldfile == NULL)
258 return(0);
259 else if ((fp = fopen(oldfile, "r")) == NULL) {
260 sprintf(errmsg, "cannot open recover file \"%s\"", oldfile);
261 error(WARNING, errmsg);
262 return(0);
263 }
264 /* discard header */
265 getheader(fp, NULL);
266 /* get picture size */
267 if (fgetresolu(&x, &y, fp) != (YMAJOR|YDECR)) {
268 sprintf(errmsg, "bad recover file \"%s\"", oldfile);
269 error(WARNING, errmsg);
270 fclose(fp);
271 return(0);
272 }
273
274 if (x != xres || y != yres) {
275 sprintf(errmsg, "resolution mismatch in recover file \"%s\"",
276 oldfile);
277 error(USER, errmsg);
278 return(0);
279 }
280
281 scanline = (COLR *)malloc(xres*sizeof(COLR));
282 if (scanline == NULL)
283 error(SYSTEM, "out of memory in salvage");
284 for (y = 0; y < yres; y++) {
285 if (freadcolrs(scanline, xres, fp) < 0)
286 break;
287 if (fwritecolrs(scanline, xres, stdout) < 0)
288 goto writerr;
289 }
290 if (fflush(stdout) == EOF)
291 goto writerr;
292 free((char *)scanline);
293 fclose(fp);
294 unlink(oldfile);
295 return(y);
296 writerr:
297 error(SYSTEM, "write error in salvage");
298 }