// // Handle and render scene // // Copyright (C) J. Belson 2001.07.15 // // $Author: jon $ : $Date: 2003/10/11 18:11:00 $ // #include #undef WITH_FORK struct count_tri { int num_tri; int depth; int max_depth; count_tri() { num_tri = 0; depth = 0; max_depth = 0; } ~count_tri() { printf("num_tri = %d\n", num_tri); printf("max_depth = %d\n", max_depth); } void inc_depth(void) { depth++; if (depth > max_depth) { max_depth = depth; } } void dec_depth(void) { depth--; } } tri; #include "bm_window.h" #include "env_map.h" #include "handler_land.h" #include "handler_sky.h" #include "hfield.h" #include "perlin.h" #include "point2d.h" #include "procedural.h" #include "progress.h" #include "renderer.h" #include "scene.h" #include "settings.h" #include "skylight.h" #include "stopwatch.h" #include "texture.h" #include "triangle3d.h" #include "zbuffer.h" /** * Constructor */ scene::scene(bm_window* win) : land(0), sky(false), env(0) { // Get the display and render sizes win->get_render_size(&scene_width, &scene_height); fbuffer = win->get_buffer(); bytes_per_row = win->bytes_per_row(); threshold = 0.1; threshold = 0.03; textures = false; shadows = false; reflections = false; atmospherics = false; my_settings = settings::get_instance(); my_settings->get_bool(LIGHTING, &lighting); my_settings->get_bool(DEBUG_SHOW_ENV_MAPS, &show_env_maps); //use_env = true; use_env = false; if (use_env) { env = new env_map(ENV_MAP_SIZE); } } /** * Destructor */ scene::~scene() { if (land) delete land; if (env) delete env; } /** * Provide a heightfield from which to get height data */ void scene::set_land(hfield* hf) { land = hf; } /** * Enable/disable sky rendering */ void scene::set_sky(bool b) { sky = b; } /** * Create a camera matrix for given heading * Note: if heading lies along the y axes, the matrix will not be valid * @param heading Vector representing view direction */ matrix scene::make_camera_matrix(const vector3d& heading) { vector3d vec = -heading; vector3d up(0, 1, 0); vector3d v1 = up.vector_product(vec); v1.normalise(); vector3d v2 = vec.vector_product(v1); v2.normalise(); vector3d v3 = vec; v3.normalise(); matrix m = matrix(v1, v2, v3); return m.transpose(); } /** * Create camera matrix given the viewing direction * @param pos Camera position * @param heading Vector representing view direction */ void scene::set_view(const point3d& pos, const vector3d heading) { viewpoint = pos; camera = make_camera_matrix(heading); } void scene::set_textures(bool b) { textures = b; } void scene::set_shadows(bool b) { shadows = b; } void scene::set_reflections(bool b) { reflections = b; } void scene::set_atmospherics(bool b) { atmospherics = b; } /** * Metric for render detail */ void scene::set_detail(int detail) { threshold = 0.094 - detail/100.0; printf("threshold = %f\n", threshold); } /** * Display environmental reflection map for debugging purposes */ void scene::show_env_map(void) { static const int pos[][2] = { { ENV_MAP_SIZE, ENV_MAP_SIZE }, { ENV_MAP_SIZE*2, ENV_MAP_SIZE }, { ENV_MAP_SIZE, 0 }, { 0, ENV_MAP_SIZE }, { ENV_MAP_SIZE, 2*ENV_MAP_SIZE }, { 3*ENV_MAP_SIZE, ENV_MAP_SIZE } }; for (int i=0; i<6; i++) { uint32* p = env->get_map(i); uint32* q = fbuffer + pos[i][0] + pos[i][1]*bytes_per_row/4; for (int y=0; yclear_buffer(); #ifndef WITH_FORK prog = new progress("Initialising..."); prog->show(); #endif render_info ri; // Create environmental maps if required if (use_env) { if (prog) { prog->set_message("Creating environmental maps..."); } renderer* r = new renderer(0, scene_height, 0); r->set_blend(false); r->set_lighting(false); ri.prog = prog; ri.rend = r; // XXX for now assume env map is smaller than image ri.zb = zb; // Vectors representing each of the orthogonal directions static const float rot[6][3] = { { 0, 0, -1 }, // FORWARD { 1, 0, 0 }, // RIGHT { 0, 1, -0.001 }, // UP { -1, 0, 0 }, // LEFT { 0, -1, -0.001 }, // DOWN { 0, 0, 1 }, // BACK }; for (int i=0; i<6; i++) { std::printf("Creating env map %d\n", i); ri.fbuffer = env->get_map(i); ri.bytes_per_row = ENV_MAP_SIZE*4; zb->clear_buffer(); vector3d v(rot[i][0], rot[i][1], rot[i][2]); v.normalise(); std::cout << "Vector = " << v << std::endl; matrix m = make_camera_matrix(v); m.dump(); handler_sky* handler = new handler_sky(ENV_MAP_SIZE, ENV_MAP_SIZE, ri); handler->set_camera(point3d(0, 8, 0), m); handler->set_threshold(threshold); handler->set_shadows(shadows); handler->render(); delete handler; } delete r; if (show_env_maps) { show_env_map(); } } ri.fbuffer = fbuffer; ri.bytes_per_row = bytes_per_row; #ifndef WITH_FORK ri.prog = prog; #else ri.prog = 0; #endif ri.zb = zb; if (sky) { if (prog) { prog->set_message("Rendering sky..."); } renderer* r = new renderer(0, scene_width, 0); r->set_blend(false); bool realistic_sky; my_settings->get_bool(SKY_REALISTIC, &realistic_sky); r->set_lighting(!realistic_sky); ri.rend = r; zb->clear_buffer(); handler_sky* handler = new handler_sky(scene_width, scene_height, ri); handler->set_camera(viewpoint, camera); handler->set_threshold(threshold); handler->set_shadows(shadows); handler->render(); delete handler; delete r; } if (land) { if (prog) { prog->set_message("Rendering land..."); } renderer* r = new renderer(0, scene_width, 0 /*prog*/); r->set_blend(false); r->set_fog(atmospherics); r->set_lighting(lighting); ri.rend = r; int seed; my_settings->get_int(PREVIEW_SEED, &seed); land->seed_rand(seed); zb->clear_buffer(); handler_land* handler = new handler_land(scene_width, scene_height, ri); handler->set_heightfield(land); handler->set_camera(viewpoint, camera); handler->set_threshold(threshold); handler->set_textures(textures); handler->set_reflections(reflections); handler->set_shadows(shadows); if (use_env) { handler->set_env_map(env); } handler->render(); delete handler; delete r; } #ifndef WITH_FORK delete prog; #endif delete zb; time_t t = timer.get_time(); std::cout << "Render took " << t/100 << "." << t%100 << "s" << std::endl; }