]>
Dogcows Code - chaz/rasterize/blob - scene.cc
a415ab084d0354342a420c3cd0a3876ca5d804f5
3 * CS5600 University of Utah
5 * mcgarvey@eng.utah.edu
15 #include "triangle.hh"
21 static int _scene_add_light(scene_t
* s
, FILE* file
);
22 static int _scene_add_sphere(scene_t
* s
, FILE* file
);
23 static int _scene_add_plane(scene_t
* s
, FILE* file
);
24 static int _scene_add_triangle(scene_t
* s
, FILE* file
);
40 scene_t
* scene_alloc(FILE* file
)
43 double eyeX
, eyeY
, eyeZ
, spotX
, spotY
, spotZ
, upX
, upY
, upZ
;
46 if (fscanf(file
, "U5 %d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
48 &eyeX
, &eyeY
, &eyeZ
, &spotX
, &spotY
, &spotZ
, &upX
, &upY
, &upZ
,
50 &aR
, &aG
, &aB
) != 16) {
51 fprintf(stderr
, "Cannot read scene header.\n");
55 vec_t eye
= vec_new(eyeX
, eyeY
, eyeZ
);
56 vec_t spot
= vec_new(spotX
, spotY
, spotZ
);
57 vec_t up
= vec_new(upX
, upY
, upZ
);
58 scal_t d
= S(1.0) / scal_tan((scal_t
)fovy
* S(0.5));
60 vec_t look
= vec_normalize(vec_sub(spot
, eye
));
61 vec_t screenCenter
= vec_scale(look
, d
);
62 vec_t screenU
= vec_normalize(vec_cross(look
, up
));
63 vec_t screenV
= vec_cross(screenU
, look
);
64 screenU
= vec_scale(screenU
, (scal_t
)aspect
);
66 scene_t
* s
= (scene_t
*)mem_alloc(sizeof(scene_t
));
70 s
->screenCenter
= screenCenter
;
75 s
->ambient
= color_new((scal_t
)aR
, (scal_t
)aG
, (scal_t
)aB
, S(1.0));
78 while (fscanf(file
, " %c", &type
) == 1) {
81 if (_scene_add_light(s
, file
) != 0) {
87 if (_scene_add_sphere(s
, file
) != 0) {
93 if (_scene_add_plane(s
, file
) != 0) {
99 if (_scene_add_triangle(s
, file
) != 0) {
108 fprintf(stderr
, "Unknown identifier: %c\n", type
);
113 if (s
->objects
) list_reverse(&s
->objects
);
121 void scene_destroy(scene_t
* s
)
123 if (s
->lights
) list_destroy(&s
->lights
);
124 if (s
->objects
) list_destroy(&s
->objects
);
130 * Add a light to the scene.
132 static int _scene_add_light(scene_t
* s
, FILE* file
)
134 double lx
, ly
, lz
, r
, g
, b
;
135 if (fscanf(file
, " %lf %lf %lf %lf %lf %lf",
136 &lx
, &ly
, &lz
, &r
, &g
, &b
) != 6) {
137 fprintf(stderr
, "Cannot read light values from scene.\n");
140 light_t
* l
= light_alloc(
142 color_new((scal_t
)r
, (scal_t
)g
, (scal_t
)b
, S(1.0))
144 list_push2(&s
->lights
, l
, mem_free
);
148 static int _scene_add_sphere(scene_t
* s
, FILE* file
)
150 double x
, y
, z
, radius
, r
, g
, b
;
151 if (fscanf(file
, " %lf %lf %lf %lf %lf %lf %lf",
152 &x
, &y
, &z
, &radius
, &r
, &g
, &b
) != 7) {
153 fprintf(stderr
, "Cannot read sphere values from scene.\n");
156 rt::element
* sphere
= new rt::sphere(
157 vec_new((scal_t
)x
, (scal_t
)y
, (scal_t
)z
),
159 color_new((scal_t
)r
, (scal_t
)g
, (scal_t
)b
, S(1.0))
161 list_push2(&s
->objects
, sphere
, DTOR(rt::sphere_destroy
));
165 static int _scene_add_plane(scene_t
* s
, FILE* file
)
167 double x
, y
, z
, nx
, ny
, nz
, r
, g
, b
;
168 if (fscanf(file
, " %lf %lf %lf %lf %lf %lf %lf %lf %lf",
169 &x
, &y
, &z
, &nx
, &ny
, &nz
, &r
, &g
, &b
) != 9) {
170 fprintf(stderr
, "Cannot read plane values from scene.\n");
173 rt::element
* plane
= new rt::plane(
174 vec_new((scal_t
)x
, (scal_t
)y
, (scal_t
)z
),
175 vec_new((scal_t
)nx
, (scal_t
)ny
, (scal_t
)nz
),
176 color_new((scal_t
)r
, (scal_t
)g
, (scal_t
)b
, S(1.0))
178 list_push2(&s
->objects
, plane
, DTOR(rt::plane_destroy
));
182 static int _scene_add_triangle(scene_t
* s
, FILE* file
)
184 double x1
, y1
, z1
, x2
, y2
, z2
, x3
, y3
, z3
, r
, g
, b
;
185 if (fscanf(file
, " %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
186 &x1
, &y1
, &z1
, &x2
, &y2
, &z2
, &x3
, &y3
, &z3
, &r
, &g
, &b
) != 12) {
187 fprintf(stderr
, "Cannot read triangle values from scene.\n");
190 rt::element
* triangle
= new rt::triangle(
191 vec_new((scal_t
)x1
, (scal_t
)y1
, (scal_t
)z1
),
192 vec_new((scal_t
)x2
, (scal_t
)y2
, (scal_t
)z2
),
193 vec_new((scal_t
)x3
, (scal_t
)y3
, (scal_t
)z3
),
194 color_new((scal_t
)r
, (scal_t
)g
, (scal_t
)b
, S(1.0))
196 list_push2(&s
->objects
, triangle
, DTOR(rt::triangle_destroy
));
201 list_t
* scene_elements(const scene_t
* s
)
206 list_t
* scene_lights(const scene_t
* s
)
211 color_t
scene_ambient(const scene_t
* s
)
217 raster_t
* scene_render(const scene_t
* s
)
223 raster_t
* p
= raster_alloc(s
->w
, s
->h
, COLOR_BLACK
);
225 /*for (list_t* i = s->lights; i; i = i->link) {*/
226 /*raster_light(p, *(light_t*)i->val);*/
230 printf("rendering scene...\n");
233 scal_t wh
= S(2.0) / (scal_t
)s
->w
;
234 scal_t hh
= S(2.0) / (scal_t
)s
->h
;
236 for (int y
= 0; y
< s
->h
; ++y
) {
237 for (int x
= 0; x
< s
->w
; ++x
) {
238 color_t
* pixel
= raster_color(p
, x
, y
);
239 scal_t u
= (scal_t
)x
* wh
- S(1.0);
240 scal_t v
= (scal_t
)y
* hh
- S(1.0);
241 vec_t rayDirection
= vec_add2(s
->screenCenter
,
242 vec_scale(s
->screenU
, u
), vec_scale(s
->screenV
, v
));
244 ray_t ray
= ray_normalize(ray_new(s
->eye
, rayDirection
));
246 rt::element
* nearestObj
= 0;
247 contact_t nearestHit
;
249 // find the nearest object along the ray
250 for (list_t
* i
= s
->objects
; i
; i
= i
->link
) {
251 rt::element
* obj
= (rt::element
*)i
->val
;
253 if (obj
->intersect(ray
, hit
) && (!nearestObj
|| hit
.d
< nearestHit
.d
)) {
260 *pixel
= nearestObj
->cast(nearestHit
, s
);
266 long dt
= timer_stop();
267 printf("render complete!\ntime\t%.3fms\n", (float)dt
/ 1000.0f
);
This page took 0.045067 seconds and 4 git commands to generate.