#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 keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods); 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); glfwSetKeyCallback(window, keyboard_callback); 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, true); ImGui_ImplOpenGL3_Init("#version 330 core"); // Shaders Shader ourShader("resources/shaders/vert.glsl", "resources/shaders/frag.glsl"); Shader directional_lightShader("resources/shaders/vert.glsl", "resources/shaders/directional_light.glsl"); Shader point_lightShader("resources/shaders/vert.glsl", "resources/shaders/point_light.glsl"); Shader light_cubeShader("resources/shaders/vert.glsl", "resources/shaders/light_object.glsl"); // Models Model croissant("resources/models/croissant/source/croissant.obj"); Model cube("resources/models/cube/cube.obj"); // Objects 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)); Object light_cube(cube, glm::vec3(1.2f, 1.0f, 2.0f), glm::vec3(0.05f, 0.05f, 0.05f), glm::vec3(0.0f, 0.0f, 0.0f)); static float positionX = 0.0f; static float positionY = 0.0f; static float positionZ = 0.0f; static float lightCubePositionX = 1.2f; static float lightCubePositionY = 1.0f; static float lightCubePositionZ = 2.0f; static float* light_color = new float[3]{1.0f, 1.0f, 1.0f}; while(!glfwWindowShouldClose(window)) { float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; glfwPollEvents(); processInput(window); if (mouseCaptured) io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); 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::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::SliderFloat("Light Cube Position X", &lightCubePositionX, -5.0f, 5.0f); ImGui::SliderFloat("Light Cube Position Y", &lightCubePositionY, -5.0f, 5.0f); ImGui::SliderFloat("Light Cube Position Z", &lightCubePositionZ, -5.0f, 5.0f); ImGui::ColorEdit3("Light Cube Color", light_color); ImGui::End(); glm::mat4 view = camera.GetViewMatrix(); glm::mat4 projection = glm::perspective(glm::radians(45.0f), float(width) / float(height), 0.1f, 100.0f); // Bacis lighting 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); ourShader.setMat4("view", view); ourShader.setMat4("projection", projection); // Directional light 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); directional_lightShader.setMat4("view", view); directional_lightShader.setMat4("projection", projection); // Point light point_lightShader.use(); point_lightShader.setVec3("viewPos", camera.Position); point_lightShader.setVec3("light.position", lightCubePositionX, lightCubePositionY, lightCubePositionZ); point_lightShader.setVec3("light.color", light_color[0], light_color[1], light_color[2]); point_lightShader.setVec3("light.ambient", 0.2f, 0.2f, 0.2f); point_lightShader.setVec3("light.diffuse", 0.5f, 0.5f, 0.5f); point_lightShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); point_lightShader.setFloat("light.constant", 1.0f); point_lightShader.setFloat("light.linear", 0.09f); point_lightShader.setFloat("light.quadratic", 0.032f); point_lightShader.setMat4("view", view); point_lightShader.setMat4("projection", projection); object1.setPosition(glm::vec3(positionX, positionY, positionZ)); object1.Draw(point_lightShader, deltaTime); object2.setAcceleration(glm::vec3(0.0f, 0.001f, 0.0f)); object2.Draw(point_lightShader, deltaTime); object3.setAcceleration(glm::vec3(0.0f, -0.001f, 0.0f)); object3.Draw(point_lightShader, deltaTime); // Light cube shader light_cubeShader.use(); light_cubeShader.setMat4("view", view); light_cubeShader.setMat4("projection", projection); light_cubeShader.setVec3("lightColor", light_color[0], light_color[1], light_color[2]); light_cube.setPosition(glm::vec3(lightCubePositionX, lightCubePositionY, lightCubePositionZ)); light_cube.Draw(light_cubeShader, 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 && !ImGui::GetIO().WantCaptureMouse) { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); mouseCaptured = true; } } void keyboard_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {} 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); } void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {} void mouse_scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {}