/* * CS5600 University of Utah * Charles McGarvey * mcgarvey@eng.utah.edu */ #include #include "light.hh" #include "list.hh" #include "vec.hh" #include "scene.hh" static int _scene_add_light(scene_t* s, FILE* file); static int _scene_add_sphere(scene_t* s, FILE* file); static int _scene_add_plane(scene_t* s, FILE* file); struct scene { int w, h; vec_t eye; vec_t spot; vec_t up; list_t* lights; list_t* spheres; list_t* planes; color_t ambient; }; scene_t* scene_alloc(FILE* file) { int w, h; double eyeX, eyeY, eyeZ, spotX, spotY, spotZ, upX, upY, upZ; double fovy, aspect; double aR, aG, aB; if (fscanf(file, "U5 %d %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", &w, &h, &eyeX, &eyeY, &eyeZ, &spotX, &spotY, &spotZ, &upX, &upY, &upZ, &fovy, &aspect, &aR, &aG, &aB) != 16) { fprintf(stderr, "Cannot read scene header.\n"); return NULL; } scene_t* s = (scene_t*)mem_alloc(sizeof(scene_t)); s->w = w; s->h = h; s->eye = vec_new(eyeX, eyeY, eyeZ); s->spot = vec_new(spotX, spotY, spotZ); s->up = vec_new(upX, upY, upZ); // what to do with fovy and aspect... s->lights = NULL; s->spheres = NULL; s->planes = NULL; s->ambient = color_new((scal_t)aR, (scal_t)aG, (scal_t)aB, S(1.0)); char type; while (fscanf(file, " %c", &type) == 1) { switch (type) { case 'l': if (_scene_add_light(s, file) != 0) { goto fail; } break; case 's': if (_scene_add_sphere(s, file) != 0) { goto fail; } break; case 'p': if (_scene_add_plane(s, file) != 0) { goto fail; } break; case 'X': goto done; default: fprintf(stderr, "Unknown identifier: %c\n", type); } } #undef _ASSERT_G done: if (s->spheres) list_reverse(&s->spheres); if (s->planes) list_reverse(&s->planes); return s; fail: scene_destroy(s); return NULL; } void scene_destroy(scene_t* s) { if (s->lights) list_destroy(&s->lights); if (s->spheres) list_destroy(&s->spheres); if (s->planes) list_destroy(&s->planes); mem_free(s); } /* * Add a light to the scene. */ static int _scene_add_light(scene_t* s, FILE* file) { double lx, ly, lz, r, g, b; if (fscanf(file, " %lf %lf %lf %lf %lf %lf", &lx, &ly, &lz, &r, &g, &b) != 6) { fprintf(stderr, "Cannot read light values from scene.\n"); return -1; } light_t* l = light_alloc( vec_new(lx, ly, lz), color_new((scal_t)r, (scal_t)g, (scal_t)b, S(1.0)), color_new((scal_t)r, (scal_t)g, (scal_t)b, S(1.0)) ); list_push2(&s->lights, l, mem_free); return 0; } static int _scene_add_sphere(scene_t* s, FILE* file) { double x, y, z, radius, r, g, b; if (fscanf(file, " %lf %lf %lf %lf %lf %lf %lf", &x, &y, &z, &radius, &r, &g, &b) != 7) { fprintf(stderr, "Cannot read sphere values from scene.\n"); return -1; } /*list_push2(&s->spheres, s, mem_free);*/ return 0; } static int _scene_add_plane(scene_t* s, FILE* file) { double x, y, z, nx, ny, nz, r, g, b; if (fscanf(file, " %lf %lf %lf %lf %lf %lf %lf %lf %lf", &x, &y, &z, &nx, &ny, &nz, &r, &g, &b) != 9) { fprintf(stderr, "Cannot read plane values from scene.\n"); return -1; } /*list_push2(&s->planes, s, mem_free);*/ return 0; } raster_t* scene_render(scene_t* s) { #if VERBOSITY >= 3 timer_start(); #endif raster_t* p = raster_alloc(s->w, s->h, COLOR_BLACK); /*for (list_t* i = s->lights; i; i = i->link) {*/ /*raster_light(p, *(light_t*)i->val);*/ /*}*/ #if VERBOSITY >= 3 printf("rendering scene...\n"); #endif // RENDER IT #if VERBOSITY >= 3 long dt = timer_stop(); printf("render complete!\ntime\t%.3fms\n", (float)dt / 1000.0f); #endif return p; }