#include #include #include #include #include #include #include #include static App app; glm::vec2 g_cursor_pos; int mkpath(const std::string& dir, mode_t mode = DEFFILEMODE) { struct stat sb; if (dir.empty()) { errno = EINVAL; return 1; } if (!stat(dir.c_str(), &sb)) return 0; mkpath(dirname(strdupa(dir.c_str())), mode); int ret = mkdir(dir.c_str(), mode); chmod(dir.c_str(), S_IRWXU); if (ret != 0) LOG("mkdir failed with error %d on %s", errno, dir.c_str()); return ret; } std::string linux_home_path() { struct passwd *pw = getpwuid(getuid()); return pw->pw_dir; } void linux_update_fps(int frames) { static char title_fps[512]; sprintf(title_fps, "PanoPainter - %d fps", frames); glfwSetWindowTitle(app.glfw_window, title_fps); } void error_log(int code, const char * s) { printf("glfw error: %s", s); } int main(int argc, char** args) { GLFWwindow* wnd = nullptr; glfwSetErrorCallback(error_log); if (!glfwInit()) { printf("could not initialize glfw\n"); return 1; } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_FORWARD_COMPAT); wnd = glfwCreateWindow(800, 600, "PanoPainter", nullptr, nullptr); if (!wnd) { printf("could not create window\n"); return 1; } glfwSetCursorPosCallback(wnd, [](GLFWwindow* wnd, double x, double y){ g_cursor_pos = glm::vec2(x, y); app.ui_task_async([=]{ app.mouse_move(x, y, 1.f, kEventSource::Mouse, false); }); }); glfwSetMouseButtonCallback(wnd, [](GLFWwindow* wnd, int button, int action, int mods){ app.ui_task_async([=]{ if (action == GLFW_PRESS) app.mouse_down(button, g_cursor_pos.x, g_cursor_pos.y, 1.f, kEventSource::Mouse, false); else if (action == GLFW_RELEASE) app.mouse_up(button, g_cursor_pos.x, g_cursor_pos.y, kEventSource::Mouse, false); }); }); glfwSetWindowSizeCallback(wnd, [](GLFWwindow* wnd, int width, int height){ app.ui_task_async([=]{ app.resize(width, height); }); }); glfwSetWindowCloseCallback(wnd, [](GLFWwindow* wnd){ app.ui_task([] { if (!app.request_close()) glfwSetWindowShouldClose(app.glfw_window, GLFW_FALSE); }); }); glfwSetWindowRefreshCallback(wnd, [](GLFWwindow* wnd){ app.ui_task_async([=]{ app.redraw = true; }, true); }); glfwMakeContextCurrent(wnd); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { printf("Failed to initialize OpenGL context\n"); return -1; } printf("GL: %s\n", glGetString(GL_VERSION)); printf("Renderer: %s\n", glGetString(GL_RENDER)); printf("Vendor: %s\n", glGetString(GL_VENDOR)); glfwShowWindow(wnd); umask(0); App::I = &app; app.initLog(); app.create(); app.width = 800; app.height = 600; app.glfw_window = wnd; app.render_thread_start(); app.ui_thread_start(); while (!glfwWindowShouldClose(wnd)) { glfwWaitEvents(); } app.ui_thread_stop(); app.render_thread_stop(); app.terminate(); return 0; }