image3f read_pnm(const string& filename, bool flipY) { int width, height, nc; float scale; unsigned char* buffer; char type; _read_pnm(filename, type, width, height, nc, scale, buffer); if (not buffer) { error_if_not(false, "failed to load image file %s", filename.c_str()); return image3f(); } error_if_not(nc == 3 && (type == 'f' || type == 'B'), "unsupported image format in file %s", filename.c_str()); image3f img(width,height); if(type == 'f') { float* buf = (float*)buffer; for(int i = 0; i < img.width()*img.height(); i ++) { img.data()[i] = vec3f(buf[i*3+0],buf[i*3+1],buf[i*3+2]) * scale; } } else if(type == 'B') { unsigned char* buf = (unsigned char*)buffer; for(int i = 0; i < img.width()*img.height(); i ++) { img.data()[i] = vec3f((float)buf[i*3+0],(float)buf[i*3+1],(float)buf[i*3+2]) * scale; } } if (buffer) delete [] buffer; if(flipY) img = img.flipy(); return img; }
// 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, "graphics14 | model", 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 'w': scene->draw_wireframe = ! 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); auto mouse_last_x = -1.0; auto mouse_last_y = -1.0; while(! glfwWindowShouldClose(window)) { 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 || 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; }
// uiloop void uiloop() { auto ok_glfw = glfwInit(); error_if_not(ok_glfw, "glfw init error"); // setting an error callback glfwSetErrorCallback([](int ecode, const char* msg){ return error(msg); }); glfwWindowHint(GLFW_SAMPLES, scene->image_samples); auto window = glfwCreateWindow(scene->image_width, scene->image_height, "graphics | animate", NULL, NULL); error_if_not(window, "glfw window error"); glfwMakeContextCurrent(window); glfwSetCharCallback(window, [](GLFWwindow* window, unsigned int key) { switch (key) { case 's': { save = true; } break; case ' ': { animate = not animate; } break; case '.': { animate_update(scene, skinning_gpu); } break; case 'g': { skinning_gpu = not skinning_gpu; animate_reset(scene); } break; case 'n': { draw_normals = not draw_normals; } break; case 'e': { draw_edges = not draw_edges; } break; case 'p': { draw_points = not draw_points; } break; case 'f': { draw_faces = not draw_faces; } break; } }); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); auto ok_glew = glewInit(); error_if_not(GLEW_OK == ok_glew, "glew init error"); init_shaders(); init_textures(scene); 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("graphics | animate | %03d", scene->animation->time); glfwSetWindowTitle(window, title.c_str()); if(animate) { if(glfwGetTime() - last_update_time > scene->animation->dt) { last_update_time = glfwGetTime(); animate_update(scene, skinning_gpu); } } if(save) { animate_reset(scene); for(auto i : range(scene->animation->length/3)) animate_update(scene, skinning_gpu); } glfwGetFramebufferSize(window, &scene->image_width, &scene->image_height); scene->camera->width = (scene->camera->height * scene->image_width) / scene->image_height; shade(scene); 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(save) { 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); save = false; } glfwSwapBuffers(window); glfwPollEvents(); } glfwDestroyWindow(window); glfwTerminate(); }