]> Dogcows Code - chaz/rasterize/blob - scene.c
import project 3 files; added blending
[chaz/rasterize] / scene.c
1
2 /*
3 * CS5600 University of Utah
4 * Charles McGarvey
5 * mcgarvey@eng.utah.edu
6 */
7
8 #include <errno.h>
9
10 #include "list.h"
11 #include "model.h"
12 #include "mat.h"
13 #include "scene.h"
14
15
16 static int _model_set_colors(model_t* m, FILE* file);
17 static int _model_add_translate(model_t* m, FILE* file);
18 static int _model_add_rotate(model_t* m, FILE* file);
19 static int _model_add_scale(model_t* m, FILE* file);
20 static int _model_set_material(model_t* m, FILE* file);
21 static int _scene_set_ambient(scene_t* s, FILE* file);
22 static int _scene_add_light(scene_t* s, FILE* file);
23
24
25 struct scene
26 {
27 list_t* models;
28 int w, h;
29 mat_t view;
30 mat_t projection;
31 vec_t eye;
32 list_t* lights;
33 color_t ambient;
34 };
35
36
37 scene_t* scene_alloc(FILE* file)
38 {
39 int w, h;
40 double eyeX, eyeY, eyeZ, spotX, spotY, spotZ, upX, upY, upZ;
41 double fovy, aspect, near, far;
42 double aR, aG, aB;
43 if (fscanf(file, "U4 %d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
44 &w, &h,
45 &eyeX, &eyeY, &eyeZ, &spotX, &spotY, &spotZ, &upX, &upY, &upZ,
46 &fovy, &aspect, &near, &far,
47 &aR, &aG, &aB) != 18) {
48 fprintf(stderr, "Cannot read scene header.\n");
49 return NULL;
50 }
51
52 scene_t* s = (scene_t*)mem_alloc(sizeof(scene_t));
53 s->models = NULL;
54 s->w = w;
55 s->h = h;
56 s->view = MAT_LOOKAT(vec_new( (scal_t)eyeX, (scal_t)eyeY, (scal_t)eyeZ),
57 vec_new((scal_t)spotX, (scal_t)spotY, (scal_t)spotZ),
58 vec_new( (scal_t)upX, (scal_t)upY, (scal_t)upZ));
59 s->eye = vec_new(eyeX, eyeY, eyeZ);
60 s->projection = MAT_PERSPECTIVE((scal_t)fovy, (scal_t)aspect, (scal_t)near, (scal_t)far);
61 s->lights = NULL;
62 s->ambient = color_new((scal_t)aR, (scal_t)aG, (scal_t)aB, S(1.0));
63
64 char filename[4096];
65 model_t* m = NULL;
66
67 #define _ASSERT_G \
68 if (m == NULL) { \
69 fprintf(stderr, "Unexpected line before group is specified.\n"); \
70 goto fail; \
71 }
72
73 char type;
74 while (fscanf(file, " %c", &type) == 1) {
75 switch (type) {
76 case 'g':
77 if (fgets(filename, 4096, file) == NULL) {
78 fprintf(stderr, "Cannot read model filename.\n");
79 }
80 m = model_alloc(trim(filename));
81 if (m == NULL) {
82 goto fail;
83 }
84 list_push2(&s->models, m, DTOR(model_destroy));
85 break;
86
87 case 'c':
88 _ASSERT_G;
89 if (_model_set_colors(m, file) != 0) {
90 goto fail;
91 }
92 break;
93
94 case 't':
95 _ASSERT_G;
96 if (_model_add_translate(m, file) != 0) {
97 goto fail;
98 }
99 break;
100
101 case 'r':
102 if (_model_add_rotate(m, file) != 0) {
103 goto fail;
104 }
105 break;
106
107 case 's':
108 _ASSERT_G;
109 if (_model_add_scale(m, file) != 0) {
110 goto fail;
111 }
112 break;
113
114 case 'l':
115 if (_scene_add_light(s, file) != 0) {
116 goto fail;
117 }
118 break;
119
120 case 'p':
121 _ASSERT_G;
122 if (_model_set_material(m, file) != 0) {
123 goto fail;
124 }
125 break;
126
127 case 'X':
128 goto done;
129
130 default:
131 fprintf(stderr, "Unknown identifier: %c\n", type);
132 }
133 }
134 #undef _ASSERT_G
135
136 done:
137 list_reverse(&s->models);
138 return s;
139
140 fail:
141 scene_destroy(s);
142 return NULL;
143 }
144
145 void scene_destroy(scene_t* s)
146 {
147 list_destroy(&s->models);
148 list_destroy(&s->lights);
149 mem_free(s);
150 }
151
152
153 /*
154 * Set the colors of the triangles in the group as defined in a file.
155 */
156 static int _model_set_colors(model_t* m, FILE* file)
157 {
158 double a, r, g, b;
159 if (fscanf(file, " %lf %lf %lf %lf", &a, &r, &g, &b) != 4) {
160 fprintf(stderr, "Cannot read color values from scene.\n");
161 return -1;
162 }
163
164 for (const list_t* i = model_geometry(m); i; i = i->link) {
165 tri_t* t = (tri_t*)i->val;
166 t->a.c = color_new((colorchan_t)r, (colorchan_t)g, (colorchan_t)b, (colorchan_t)a);
167 t->b.c = color_new((colorchan_t)r, (colorchan_t)g, (colorchan_t)b, (colorchan_t)a);
168 t->c.c = color_new((colorchan_t)r, (colorchan_t)g, (colorchan_t)b, (colorchan_t)a);
169 }
170 return 0;
171 }
172
173 /*
174 * Concat a translation matrix to the transformation as defined in a file.
175 */
176 static int _model_add_translate(model_t* m, FILE* file)
177 {
178 double tx, ty, tz;
179 if (fscanf(file, " %lf %lf %lf", &tx, &ty, &tz) != 3) {
180 fprintf(stderr, "Cannot read translate coordinates from scene.\n");
181 return -1;
182 }
183 mat_t transform = MAT_TRANSLATE((scal_t)tx, (scal_t)ty, (scal_t)tz);
184 model_transform(m, &transform);
185 return 0;
186 }
187
188 /*
189 * Concat a rotation matrix to the transformation as defined in a file.
190 */
191 static int _model_add_rotate(model_t* m, FILE* file)
192 {
193 double theta, ax, ay, az;
194 if (fscanf(file, " %lf %lf %lf %lf", &theta, &ax, &ay, &az) != 4) {
195 fprintf(stderr, "Cannot read rotation angle from scene.\n");
196 return -1;
197 }
198 mat_t transform = MAT_ROTATE((scal_t)theta, (scal_t)ax, (scal_t)ay, (scal_t)az);
199 model_transform(m, &transform);
200 return 0;
201 }
202
203 /*
204 * Concat a scale matrix to the transformation as defined in a file.
205 */
206 static int _model_add_scale(model_t* m, FILE* file)
207 {
208 double sx, sy, sz;
209 if (fscanf(file, " %lf %lf %lf", &sx, &sy, &sz) != 3) {
210 fprintf(stderr, "Cannot read scale factors from scene.\n");
211 return -1;
212 }
213 mat_t transform = MAT_SCALE((scal_t)sx, (scal_t)sy, (scal_t)sz);
214 model_transform(m, &transform);
215 return 0;
216 }
217
218 /*
219 * Set the specular highlight and shininess factor for the group.
220 */
221 static int _model_set_material(model_t* m, FILE* file)
222 {
223 double sr, sg, sb, shininess;
224 if (fscanf(file, " %lf %lf %lf %lf", &sr, &sg, &sb, &shininess) != 4) {
225 fprintf(stderr, "Cannot read material information from scene.\n");
226 return -1;
227 }
228 model_material(m, color_new((scal_t)sr, (scal_t)sg, (scal_t)sb, S(1.0)), (scal_t)shininess);
229 return 0;
230 }
231
232 /*
233 * Add a light to the scene.
234 */
235 static int _scene_add_light(scene_t* s, FILE* file)
236 {
237 double lx, ly, lz, r, g, b;
238 if (fscanf(file, " %lf %lf %lf %lf %lf %lf",
239 &lx, &ly, &lz, &r, &g, &b) != 6) {
240 fprintf(stderr, "Cannot read light values from scene.\n");
241 return -1;
242 }
243 light_t* l = light_alloc(
244 vec_new(lx, ly, lz),
245 color_new((scal_t)r, (scal_t)g, (scal_t)b, S(1.0)),
246 color_new((scal_t)r, (scal_t)g, (scal_t)b, S(1.0))
247 );
248 list_push2(&s->lights, l, mem_free);
249 return 0;
250 }
251
252
253 raster_t* scene_render(scene_t* s)
254 {
255 #if VERBOSITY >= 3
256 timer_start();
257 #endif
258
259 raster_t* p = raster_alloc(s->w, s->h, COLOR_BLACK);
260 raster_view(p, &s->view);
261 raster_projection(p, &s->projection);
262 raster_eye(p, s->eye);
263 raster_ambient(p, s->ambient);
264
265 for (list_t* i = s->lights; i; i = i->link) {
266 raster_light(p, *(light_t*)i->val);
267 }
268
269 #if VERBOSITY >= 3
270 printf("rendering scene...\n");
271 #endif
272
273 for (list_t* gi = s->models; gi; gi = gi->link) {
274 model_t* m = (model_t*)gi->val;
275 raster_draw_model(p, m);
276 }
277
278 #if VERBOSITY >= 3
279 long dt = timer_stop();
280 printf("render complete!\ntime\t%.3fms\n", (float)dt / 1000.0f);
281 #endif
282
283 return p;
284 }
285
This page took 0.046672 seconds and 4 git commands to generate.