int init_engine(bool skybox_on, bool shadows_on) { struct shader_config { Renderer *renderer; std::string v_shader; std::string f_shader; }; std::vector<struct shader_config> configs = { { &phong, "phong", "phong" }, { &color_direct, "phong", "color_direct" } }; if (skybox_on) { configs.push_back( { &skybox_shader, "skybox", "skybox" } ); } std::string shaders_dir = getBinDir() + BIN2SHADERS; for (const auto &config : configs) { if (config.renderer->init(shaders_dir + config.v_shader + ".vert", shaders_dir + config.f_shader + ".frag")) { fprintf(stderr, "Could not initialize shader (%s, %s).\n", config.v_shader.c_str(), config.f_shader.c_str()); return -1; } } if (shadows_on) { shadows_enabled = true; } // Create skybox. if (skybox_on) { skybox_enabled = true; auto skybox_mesh = OBJBuilder(getBinDir() + BIN2DATA + "skybox.obj").build(); if (!skybox_mesh.size()) { fprintf(stderr, "WARNING: Could not build skybox.\n"); return 0; } skybox_mesh[0]->material = nullptr; auto skybox = get_renderable(skybox_mesh[0].get(), &skybox_shader); auto skybox_dir = getBinDir() + BIN2SKYBOX; create_cube_map( (skybox_dir + "negz.jpg").c_str(), (skybox_dir + "posz.jpg").c_str(), (skybox_dir + "posy.jpg").c_str(), (skybox_dir + "negy.jpg").c_str(), (skybox_dir + "negx.jpg").c_str(), (skybox_dir + "posx.jpg").c_str(), GL_TEXTURE0 + skybox_texture_index ); renderable_clumps.push_back(std::make_unique<std::vector<Renderable>>()); renderable_clumps[renderable_clumps.size() - 1]->push_back(std::move(skybox)); skybox_shader.add_object(nullptr, renderable_clumps[renderable_clumps.size() - 1].get()); } return 0; }
bool CommonData::checkIni() { bool ret = true; if (ret) ret = this->checkFileExists(getBinDir()); if (!ret) { qFatal("Bin Dir not found"); exit(INIFILE_WRONG); //questo errore e' fatale } if (ret) ret = this->checkFileExists(getImgDir()); if (!ret) { qFatal("Img Dir not found"); exit(INIFILE_WRONG); //questo errore e' fatale } if (ret) ret = this->checkFileExists(getDocDir()); if (!ret) { qFatal("Doc Dir not found"); exit(INIFILE_WRONG); //questo errore e' fatale } if (ret) ret = this->checkFileExists(getReportDir()); if (!ret) { qFatal("Reports Dir not found"); exit(INIFILE_WRONG); //questo errore e' fatale } if (ret) ret = this->checkFileExists(getQrDir()); if (ret) ret = this->checkFileExists(getBiblioDir()); if (ret) ret = this->checkFileExists(getHtmlDir()); if (ret) ret = this->checkFileExists(getBlocknotesDir()); if (ret) ret = this->checkFileExists(getTexDir()); if (ret) ret = this->checkFileExists(getCollezione()); if (ret) ret = this->checkFileExists(getContenitori()); if (ret) ret = this->checkFileExists(getContatti()); if (ret) ret = this->checkFileExists(getBiblioteca()); if (ret) ret = this->checkFileExists(getLinks()); if (ret) ret = this->checkFileExists(getBackupDir()); return ret; }
int load_vision_link_lib() { void *handle = dlopen((getBinDir() + VISION_LINK_LIB).c_str(), RTLD_LAZY); if (!handle) { fprintf(stderr, "ERROR: Could not load vision link lib: %s\n", dlerror()); return -1; } create_link = reinterpret_cast<VisionLink *(*)()>(dlsym(handle, "create_link")); if (!create_link) { fprintf(stderr, "ERROR: Could not find create_link symbol in vision link lib.\n"); return -1; } return 0; }
int main(int argc, char **argv) { std::string model_filename; if (argc < 2) { model_filename = getBinDir() + BIN2CONFIG + DEFAULT_CONFIG; } else { model_filename = argv[1]; } shm_init(); glfwSetErrorCallback(error_callback); if (!glfwInit()) { return -1; } glfwWindowHint(GLFW_SAMPLES, 4); // TODO how many samples? glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); GLFWwindow *window = glfwCreateWindow(DEFAULT_WIDTH, DEFAULT_HEIGHT, "CUAUV Visualizer " VERSION, NULL, NULL); if (!window) { fprintf(stderr, "ERROR: Failed to create window.\n"); return -1; } glfwMakeContextCurrent(window); if (init_engine(true, true)) { fprintf(stderr, "ERROR: Failed to initalize graphics engine.\n"); return -1; } cam.direction = NORTH; cam.up = UP; cam.width = DEFAULT_WIDTH; cam.height = DEFAULT_HEIGHT; cam.fov = 1.0; libconfig::Config config; config.setOptions(libconfig::Setting::OptionAutoConvert); try { config.readFile(model_filename.c_str()); } catch (libconfig::ParseException &pe) { fprintf(stderr, "ERROR parsing config file %s:%d %s\n", pe.getFile(), pe.getLine(), pe.getError()); return -1; } std::unordered_map<std::string, GLuint> texture_map; auto &objects = config.lookup("objects"); for (const auto &object : objects) { std::string name("Poor nameless object"); object.lookupValue("name", name); std::unique_ptr<SceneObject> scene_object; bool is_sub = (object.exists("sub") && ((bool)object.lookup("sub")) == true) || objects.getLength() == 1; if (!object.exists("model")) { scene_object = std::make_unique<SceneObject>(); if (!scene_object) { fprintf(stderr, "ERROR: Could not allocate memory for SceneObject!\n"); continue; } load_axes(scene_object.get()); } else { auto mesh_object = std::make_unique<MeshObject>(); if (!mesh_object) { fprintf(stderr, "ERROR: Could not allocate memory for MeshObject!\n"); continue; } std::string mesh_name = object.lookup("model"); auto get_file_name = [] (const std::string &filename, const char *folder) { if (filename[0] == '/') { return filename; } return getBinDir() + folder + filename; }; if (load_model(get_file_name(mesh_name, BIN2DATA), mesh_object.get())) { fprintf(stderr, "ERROR: failed to make model \"%s\".\n", mesh_name.c_str()); } if (object.exists("texture")) { std::string texture = object.lookup("texture"); if (texture_map.find(texture) == texture_map.end()) { GLuint texture_ind; if (load_texture(get_file_name(texture, BIN2TEXTURES), texture_ind)) { fprintf(stderr, "WARNING: texture \"%s\" failed to load.\n", texture.c_str()); } texture_map[texture] = texture_ind; } mesh_object->set_texture(texture_map[texture]); } if (object.exists("alpha")) { mesh_object->set_alpha(object.lookup("alpha")); } scene_object = std::move(mesh_object); } auto grab_vec = [&object, &name] (const std::string &att_name, glm::vec3 id_v) -> std::function<glm::vec3()> { auto id = [id_v] { return id_v; }; if (object.exists(att_name)) { auto &att = object.lookup(att_name); if (att.getLength() == 3) { glm::vec3 vec(att[0], att[1], att[2]); return [vec] { return vec; }; } std::string att_s = att; if (att_s == "kalman") { return get_sub_position; } else { fprintf(stderr, "ERROR: Invalid %s for object \"%s\".\n", att_name.c_str(), name.c_str()); } } else { return id; } return id; }; auto grab_orientation = [&object, &name] (const std::string &att_prefix) -> std::function<glm::fquat()> { auto id = [] { return quat_from_hpr(0, 0, 0); }; if (object.exists(att_prefix + "_hpr")) { auto &att = object.lookup(att_prefix + "_hpr"); if (att.getLength() == 3) { glm::fquat q = quat_from_hpr(att[0], att[1], att[2]); return [q] { return q; }; } std::string att_s = att; if (att_s == "desires") { return get_desire_quat; } else { fprintf(stderr, "ERROR: Invalid orientation_hpr for object \"%s\".\n", name.c_str()); } } else if (object.exists(att_prefix + "_q")) { std::string att_s = object.lookup(att_prefix + "_q"); if (att_s == "kalman") { return get_sub_quat; } else { fprintf(stderr, "ERROR: Invalid orientation_q for object \"%s\".\n", name.c_str()); } } return id; }; scene_object->get_position = grab_vec("position", glm::vec3(0, 0, 0)); auto orient_f = grab_orientation("orientation"); scene_object->get_orientation = [orient_f] () { return orient_f(); }; auto mesh_f = grab_orientation("mesh_offset"); scene_object->mesh_offset = mesh_f(); scene_object->get_scale = grab_vec("scale", glm::vec3(1, 1, 1)); if (object.exists("exclude_renders")) { auto &excludes = object.lookup("exclude_renders"); for (const auto &render : excludes) { std::unordered_map<std::string, char> value_map = { {"main", RENDER_MAIN}, {"offscreen", RENDER_OFFSCREEN}, {"shadow", RENDER_SHADOW} }; if (value_map.find(render) == value_map.end()) { std::string s; for (const auto &pair : value_map) { s += pair.first + " "; } fprintf(stderr, "WARNING: Invalid exclude_renders for object \"%s\". " "Possible values are: %s\n", name.c_str(), s.c_str()); } else { scene_object->exclude |= value_map[render]; } } } if (object.exists("camera_attachments")) { if (!load_vision_link_lib()) { auto &cams = object.lookup("camera_attachments"); for (const auto &cam : cams) { auto &pos = cam.lookup("pos"); auto &orient = cam.lookup("orientation"); unsigned int width = DEFAULT_WIDTH; unsigned int height = DEFAULT_HEIGHT; float fov = 1.0; cam.lookupValue("width", width); cam.lookupValue("height", height); cam.lookupValue("fov", fov); add_sub_camera(cam.lookup("name"), width, height, fov, glm::vec3(pos[0], pos[1], pos[2]), quat_from_hpr(orient[0], orient[1], orient[2])); } } else { fprintf(stderr, "WARNING: Loading vision link library failed; " "vision output unavailable.\n"); } } if (is_sub) { sub = scene_object.get(); } scene_objects.push_back(std::move(scene_object)); } if (!sub) { fprintf(stderr, "WARNING: no sub designated; sub follow mode will not work.\n"); } add_light(&light1); add_light(&light2); glfwSetFramebufferSizeCallback(window, reshape_callback); glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, [] (GLFWwindow *w, double x, double y) { mouse_handlers[mouse_state](w, x, y); }); glClearColor(0.0, 0.0, 0.0, 1.0); glClearDepth(1.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); mouse_move_mode_off(window); mouse_handlers[MOUSE] = handle_mouse_move; mouse_handlers[FIXED] = [] (GLFWwindow *w, int x, int y) {}; register_action(GLFW_KEY_M, [window] { if (mouse_state == MOUSE) { mouse_move_mode_off(window); } else { mouse_move_mode_on(window); } }); register_action(GLFW_KEY_F, [] { if (sub) { sub_follow = !sub_follow; if (sub_follow) { cam.up = UP; } } }); register_action(GLFW_KEY_H, [] { heading_lock = !heading_lock; if (heading_lock) { cam_angle = 0.0; } }); register_action(GLFW_KEY_X, toggle_skybox); register_action(GLFW_KEY_Z, toggle_shadows); register_action(GLFW_KEY_V, toggle_offscreen_rendering); register_action(GLFW_KEY_ESCAPE, [window] () { mouse_move_mode_off(window); }); int width, height; glfwGetFramebufferSize(window, &width, &height); reshape_callback(window, width, height); draw_loop(window); glfwDestroyWindow(window); glfwTerminate(); return 0; }