// main function int main(int argc, char** argv) { auto args = parse_cmdline(argc, argv, { "03_animate", "view scene", { {"resolution", "r", "image resolution", typeid(int), true, jsonvalue() } }, { {"scene_filename", "", "scene filename", typeid(string), false, jsonvalue("scene.json")}, {"image_filename", "", "image filename", typeid(string), true, jsonvalue("")} } }); // generate/load scene either by creating a test scene or loading from json file scene_filename = args.object_element("scene_filename").as_string(); scene = nullptr; if(scene_filename.length() > 9 and scene_filename.substr(0,9) == "testscene") { int scene_type = atoi(scene_filename.substr(9).c_str()); scene = create_test_scene(scene_type); scene_filename = scene_filename + ".json"; } else { scene = load_json_scene(scene_filename); } error_if_not(scene, "scene is nullptr"); image_filename = (args.object_element("image_filename").as_string() != "") ? args.object_element("image_filename").as_string() : scene_filename.substr(0,scene_filename.size()-5)+".png"; if(not args.object_element("resolution").is_null()) { scene->image_height = args.object_element("resolution").as_int(); scene->image_width = scene->camera->width * scene->image_height / scene->camera->height; } animate_reset(scene); subdivide(scene); uiloop(); }
// scene update void animate_update(Scene* scene, bool skinning_gpu) { scene->animation->time ++; if(scene->animation->time >= scene->animation->length) animate_reset(scene); animate_frame(scene); if(not skinning_gpu) animate_skin(scene); simulate(scene); }
// main function int main(int argc, char** argv) { auto args = parse_cmdline(argc, argv, { "04_animate", "raytrace a scene", { {"resolution", "r", "image resolution", "int", true, jsonvalue() } }, { {"scene_filename", "", "scene filename", "string", false, jsonvalue("scene.json")}, {"image_filename", "", "image filename", "string", true, jsonvalue("")} } }); scene_filename = args.object_element("scene_filename").as_string(); image_filename = (args.object_element("image_filename").as_string() != "") ? args.object_element("image_filename").as_string() : scene_filename.substr(0,scene_filename.size()-5)+".png"; scene = load_json_scene(scene_filename); if(not args.object_element("resolution").is_null()) { scene->image_height = args.object_element("resolution").as_int(); scene->image_width = scene->camera->width * scene->image_height / scene->camera->height; } animate_reset(scene); subdivide(scene); uiloop(); }
// uiloop void uiloop() { auto ok = glfwInit(); error_if_not(ok, "glfw init error"); // setting an error callback glfwSetErrorCallback([](int ecode, const char* msg){ return error(msg); }); // glfwWindowHint(GLFW_SAMPLES, scene->image_samples*scene->image_samples); auto window = glfwCreateWindow(scene->image_width, scene->image_height, "graphics13 | animate", NULL, NULL); error_if_not(window, "glfw window error"); glfwMakeContextCurrent(window); glfwSetCharCallback(window, [](GLFWwindow* window, unsigned int key) { switch (key) { case 's': scene->draw_captureimage = true; break; case ' ': scene->draw_animated = not scene->draw_animated; break; case '.': animate_update(scene); break; case 'g': scene->animation->gpu_skinning = not scene->animation->gpu_skinning; animate_reset(scene); break; case 'n': scene->draw_normals = not scene->draw_normals; break; case 'w': scene->draw_wireframe = not scene->draw_wireframe; break; } }); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); #ifdef _WIN32 auto ok1 = glewInit(); error_if_not(GLEW_OK == ok1, "glew init error"); #endif auto state = new ShadeState(); init_shaders(state); init_textures(scene,state); animate_reset(scene); auto mouse_last_x = -1.0; auto mouse_last_y = -1.0; auto last_update_time = glfwGetTime(); while(not glfwWindowShouldClose(window)) { auto title = tostring("graphics14 | animate | %03d", scene->animation->time); glfwSetWindowTitle(window, title.c_str()); if(scene->draw_animated) { if(glfwGetTime() - last_update_time > scene->animation->dt) { last_update_time = glfwGetTime(); animate_update(scene); } } glfwGetFramebufferSize(window, &scene->image_width, &scene->image_height); scene->camera->width = (scene->camera->height * scene->image_width) / scene->image_height; shade(scene,state); if(glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT)) { double x, y; glfwGetCursorPos(window, &x, &y); if (mouse_last_x < 0 or mouse_last_y < 0) { mouse_last_x = x; mouse_last_y = y; } auto delta_x = x - mouse_last_x, delta_y = y - mouse_last_y; set_view_turntable(scene->camera, delta_x*0.01, -delta_y*0.01, 0, 0, 0); mouse_last_x = x; mouse_last_y = y; } else { mouse_last_x = -1; mouse_last_y = -1; } if(scene->draw_captureimage) { auto image = image3f(scene->image_width,scene->image_height); glReadPixels(0, 0, scene->image_width, scene->image_height, GL_RGB, GL_FLOAT, &image.at(0,0)); write_png(image_filename, image, true); scene->draw_captureimage = false; } glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); delete state; }