diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d2b52c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +build-noblending +.vscode diff --git a/README.md b/README.md index 64993eb..df947d6 100644 --- a/README.md +++ b/README.md @@ -14,10 +14,16 @@ ## Building instructions for Debian Linux distribution series(tested on Debian 12.5 stable): ### Dependences package install: + +* on debian ```bash sudo apt install libwayland-dev libx11-dev libxkbcommon-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev ``` +* on archlinux +If you have been using GUI on archlinux, you shouldn't install any. +Or you shoud install Desktop Environment. + ### Clone and Build: ```bash git clone https://git.suthby.org:2024/SuthbyPublic/JungleOpenSourceProjectRepo.git --recurse-submodules diff --git a/test/main.cpp b/test/main.cpp index 2356869..9b97476 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -11,11 +11,26 @@ #include "camera.h" #include +#include + +#ifdef __linux__ +#include +#endif +#ifdef _WIN32 +#include +#endif void framebuffer_size_callback(GLFWwindow *window, int width, int height); void mouse_callback(GLFWwindow *window, double xpos, double ypos); void scroll_callback(GLFWwindow *window, double xoffset, double yoffset); +void focus_callback(GLFWwindow *window, int focused); void processInput(GLFWwindow *window); +void delay_fps(int fps, int render_time_us); +void *getting_fps(void *window); + +bool running = true; +bool pausing = false; +bool just_dispaused = false; // settings const unsigned int SCR_WIDTH = 854; @@ -31,6 +46,22 @@ bool firstMouse = true; float deltaTime = 0.0f; // time between current frame and last frame float lastFrame = 0.0f; +// focuse controlling +bool window_focused = false; + +// window managing +int curr_width; +int curr_height; +int curr_x; +int curr_y; + +// monitors controlling +int monitor_count; +GLFWmonitor **monitors; + +// fps control +int fps; + int main() { // std::cout << "debug"; @@ -40,7 +71,8 @@ int main() glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - // glEnable(GL_BLEND); + glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_FALSE); + glfwWindowHint(GLFW_SCALE_FRAMEBUFFER, GLFW_FALSE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); @@ -55,10 +87,17 @@ int main() glfwTerminate(); return -1; } + + monitors = glfwGetMonitors(&monitor_count); + + pthread_t thr_getting_fps; + pthread_create(&thr_getting_fps, nullptr, getting_fps, window); + glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); + glfwSetWindowFocusCallback(window, focus_callback); // tell GLFW to capture our mouse glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); @@ -73,8 +112,6 @@ int main() // configure global opengl state // ----------------------------- - // glEnable(GL_BLEND); - // glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA); // glEnable(GL_DEPTH_TEST); // build and compile our shader zprogram @@ -247,8 +284,10 @@ int main() glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); - // render loop - // ----------- + + // glfwSetCursorPos(window, curr_x + curr_width / 2, curr_y + curr_height / 2); + // render loop + // ----------- while (!glfwWindowShouldClose(window)) { // per-frame time logic @@ -296,27 +335,19 @@ int main() // glDepthMask(GL_FALSE); // render transparent objects with blending enabled - // glEnable(GL_BLEND); - // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - // for (unsigned int i = 5; i < 10; i++) - // { - // ourShader.setIVec2("index", cubeTextures[i]); - - // // calculate the model matrix for each object and pass it to shader before drawing - // glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first - // model = glm::translate(model, glm::vec3(cubePositions[i])); - // ourShader.setMat4("model", model); - // glDrawArrays(GL_TRIANGLES, 0, 36); - // } - // glDisable(GL_BLEND); // glDisable(GL_DEPTH_TEST); // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) // ------------------------------------------------------------------------------- glfwSwapBuffers(window); glfwPollEvents(); + + float renderTime = static_cast(glfwGetTime()) - lastFrame; + delay_fps(fps, (int)(renderTime * 1000 * 1000)); } + running = false; + glDisable(GL_DEPTH_TEST); // optional: de-allocate all resources once they've outlived their purpose: @@ -332,10 +363,28 @@ int main() // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly // --------------------------------------------------------------------------------------------------------- +bool ESC_KEY_PRESSED = false; void processInput(GLFWwindow *window) { - if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) - glfwSetWindowShouldClose(window, true); + int esc_key_evetype = glfwGetKey(window, GLFW_KEY_ESCAPE); + if (!ESC_KEY_PRESSED && esc_key_evetype == GLFW_PRESS) + { + ESC_KEY_PRESSED = true; + pausing = !pausing; + if (!pausing) + just_dispaused = true; + if (!pausing) + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + else + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } + else if (esc_key_evetype == GLFW_RELEASE) + { + ESC_KEY_PRESSED = false; + } + + if (pausing) + return; if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera.ProcessKeyboard(FORWARD, deltaTime); @@ -350,7 +399,6 @@ void processInput(GLFWwindow *window) camera.ProcessKeyboard(UP, deltaTime); if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) camera.ProcessKeyboard(DOWN, deltaTime); - } // glfw: whenever the window size changed (by OS or user resize) this callback function executes @@ -359,16 +407,39 @@ void framebuffer_size_callback(GLFWwindow *window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. - glViewport(0, 0, width, height); + curr_width = width; + curr_height = height; + if ((double)width / height > (double)SCR_WIDTH / SCR_HEIGHT) + { // When profiled screen size rate less than new size + int vpwidth = width; + int vpheight = width * SCR_HEIGHT / SCR_WIDTH; + glViewport(0, -(vpheight - height) / 2, vpwidth, vpheight); + } + else + { // or more than + int vpheight = height; + int vpwidth = height * SCR_WIDTH / SCR_HEIGHT; + glViewport(-(vpwidth - width) / 2, 0, vpwidth, vpheight); + } } // glfw: whenever the mouse moves, this callback is called // ------------------------------------------------------- void mouse_callback(GLFWwindow *window, double xposIn, double yposIn) { + if (pausing) + return; + float xpos = static_cast(xposIn); float ypos = static_cast(yposIn); + if (just_dispaused) + { + lastX = xpos; + lastY = ypos; + just_dispaused = false; + } + if (firstMouse) { lastX = xpos; @@ -391,3 +462,66 @@ void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) { camera.ProcessMouseScroll(static_cast(yoffset)); } + +void focus_callback(GLFWwindow *window, int focused) +{ + if (focused) + { + window_focused = true; + } + else + { + window_focused = false; + pausing = true; + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } +} + +void *getting_fps(void *_window) +{ + GLFWwindow *window = static_cast(_window); + while (running) + { + glfwGetWindowPos(window, &curr_x, &curr_y); + glfwGetWindowSize(window, &curr_width, &curr_height); + // get current monitor's scale + int on_which = -1; + GLFWvidmode *vmode; + for (int i = 0; i < monitor_count; i++) + { + int monx, mony; + glfwGetMonitorPos(monitors[i], &monx, &mony); + GLFWvidmode *mode = const_cast(glfwGetVideoMode(monitors[i])); + if (curr_x >= monx && curr_x < mode->width && curr_y >= mony && curr_y < mode->height) + { + on_which = i; + vmode = mode; + break; + } + } + if (on_which != -1) + { + fps = vmode->refreshRate; + } +#ifdef __linux__ + usleep(1000); +#endif +#ifdef _WIN32 + Sleep(1); +#endif + } + std::cout << std::endl; + return nullptr; +} + +void delay_fps(int fps, int render_time_us) +{ +#ifdef __linux__ + int del = 1000 * 1000 / fps; + usleep(del - render_time_us); +#endif +#ifdef _WIN32 + int del = 1000 / fps; + Sleep(del - render_time_us / 1000); +#endif +}