#include #include #include #include #include #include #include #include #include #include #include #include #include #include void framebuffer_size_callback(GLFWwindow* window, int width, int height); void processInput(GLFWwindow *window); void mouse_pos_callback(GLFWwindow* window, double xpos, double ypos); void mouse_button_callback(GLFWwindow* window, int button, int action, int mods); void mouse_scroll_callback(GLFWwindow* window, double xoffset, double yoffset); unsigned int width = 800; unsigned int height = 600; Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); float lastX = width / 2.0f; float lastY = height / 2.0f; bool firstMouse = true; bool mouseCaptured = false; float deltaTime = 0.0f; float lastFrame = 0.0f; int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetCursorPosCallback(window, mouse_pos_callback); glfwSetMouseButtonCallback(window, mouse_button_callback); glfwSetScrollCallback(window, mouse_scroll_callback); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } glViewport(0, 0, width, height); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glEnable(GL_DEPTH_TEST); //stbi_set_flip_vertically_on_load(true); // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange; ImGui::StyleColorsDark(); ImGui_ImplGlfw_InitForOpenGL(window, false); ImGui_ImplOpenGL3_Init("#version 330 core"); Shader ourShader("resources/shaders/vert.glsl", "resources/shaders/frag.glsl"); Shader directional_lightShader("resources/shaders/vert.glsl", "resources/shaders/directional_light.glsl"); Model croissant("resources/models/croissant/source/croissant.obj"); Model cube("resources/models/cube/cube.obj"); Object object1(croissant, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.1f, 0.1f, 0.1f), glm::vec3(0.0f, 0.0f, 0.0f)); Object object2(croissant, glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.1f, 0.1f, 0.1f), glm::vec3(0.0f, 0.0f, 0.0f)); Object object3(croissant, glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.1f, 0.1f, 0.1f), glm::vec3(0.0f, 0.0f, 0.0f)); static float positionX = 0.0f; static float positionY = 0.0f; static float positionZ = 0.0f; while(!glfwWindowShouldClose(window)) { float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; glfwPollEvents(); if (mouseCaptured || !io.WantCaptureMouse) processInput(window); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); double mouseX, mouseY; glfwGetCursorPos(window, &mouseX, &mouseY); ImGui::Begin("Settings"); ImGui::Text("FPS: %.2f", 1.0f / deltaTime); ImGui::Text("Mouse Captured: %s", mouseCaptured ? "Yes" : "No"); ImGui::Text("ImGui want capture mouse: %s", io.WantCaptureMouse ? "Yes" : "No"); ImGui::Text("ImGui mouse position: (%.2f, %.2f)", io.MousePos.x, io.MousePos.y); ImGui::Text("GLFW mouse position: (%.2f, %.2f)", mouseX, mouseY); ImGui::SliderFloat("Object 1 Position X", &positionX, -5.0f, 5.0f); ImGui::SliderFloat("Object 1 Position Y", &positionY, -5.0f, 5.0f); ImGui::SliderFloat("Object 1 Position Z", &positionZ, -5.0f, 5.0f); ImGui::End(); // Bacis lighting ourShader.use(); ourShader.setVec3("viewPos", camera.Position); ourShader.setVec3("light.position", 1.2f, 1.0f, 2.0f); ourShader.setVec3("light.color", 1.0f, 1.0f, 1.0f); ourShader.setVec3("light.ambient", 0.2f, 0.2f, 0.2f); ourShader.setVec3("light.diffuse", 0.5f, 0.5f, 0.5f); ourShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); // Directional light directional_lightShader.use(); directional_lightShader.setVec3("light.direction", -0.2f, -1.0f, -0.3f); directional_lightShader.setVec3("light.color", 1.0f, 1.0f, 1.0f); directional_lightShader.setVec3("light.ambient", 0.2f, 0.2f, 0.2f); directional_lightShader.setVec3("light.diffuse", 0.5f, 0.5f, 0.5f); directional_lightShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); glm::mat4 view = camera.GetViewMatrix(); glm::mat4 projection = glm::perspective(glm::radians(45.0f), float(width) / float(height), 0.1f, 100.0f); ourShader.setMat4("view", view); ourShader.setMat4("projection", projection); object1.setPosition(glm::vec3(positionX, positionY, positionZ)); object1.Draw(directional_lightShader, deltaTime); object2.setAcceleration(glm::vec3(0.0f, 0.001f, 0.0f)); object2.Draw(directional_lightShader, deltaTime); object3.setAcceleration(glm::vec3(0.0f, -0.001f, 0.0f)); object3.Draw(directional_lightShader, deltaTime); ImGui::Render(); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); } ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); glfwTerminate(); return 0; } void framebuffer_size_callback(GLFWwindow* window, int new_width, int new_height) { width = new_width; height = new_height; glViewport(0, 0, new_width, new_height); } void processInput(GLFWwindow *window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS && mouseCaptured) { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); mouseCaptured = false; } if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS && mouseCaptured) camera.ProcessKeyboard(FORWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS && mouseCaptured) camera.ProcessKeyboard(BACKWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS && mouseCaptured) camera.ProcessKeyboard(LEFT, deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS && mouseCaptured) camera.ProcessKeyboard(RIGHT, deltaTime); if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS && !mouseCaptured) { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); mouseCaptured = true; } } void mouse_pos_callback(GLFWwindow* window, double xposIn, double yposIn) { float xpos = static_cast(xposIn); float ypos = static_cast(yposIn); if (firstMouse) { lastX = xpos; lastY = ypos; firstMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; if (mouseCaptured){ camera.ProcessMouseMovement(xoffset, yoffset); ImGui_ImplGlfw_CursorPosCallback(window, -FLT_MAX, -FLT_MAX); } else ImGui_ImplGlfw_CursorPosCallback(window, xpos, ypos); } void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { ImGui_ImplGlfw_MouseButtonCallback(window, button, action, mods); } void mouse_scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { ImGui_ImplGlfw_ScrollCallback(window, xoffset, yoffset); }