diff --git a/zadanie-2_new/main.cpp b/zadanie-2_new/main.cpp index 40e4c7d..da3dd0b 100644 --- a/zadanie-2_new/main.cpp +++ b/zadanie-2_new/main.cpp @@ -9,14 +9,26 @@ #include "shader.h" #include -const float g = 9.81f; -const float airResistance = 0.1f; +#include +#include +#include + + +const glm::vec3 initialCameraPos = glm::vec3(20, 20, 30); +const glm::vec3 initialCameraTarget = glm::vec3(0, 10, 0); +const glm::vec3 initialCameraUp = glm::vec3(0, 1, 0); +const float initialGravity = 9.81f; +const float initialAirResistance = 0.1f; +const float initialSpeed = 5.0f; +const float initialAngle = 45.0f; const int windowWidth = 1200; const int windowHeight = 800; float startTime; -const float delay = 2.0f; // 2-sekundowe opóźnienie +bool isLaunched = false; + +const float delay = 0.0f; // 2-sekundowe opóźnienie struct Ball { @@ -25,6 +37,18 @@ struct Ball { float r, g, b; }; + +float gravity = initialGravity; +float airResistance = initialAirResistance; +float speed = initialSpeed; +float angle = initialAngle * M_PI / 180.0f; + + +glm::vec3 cameraPos = initialCameraPos; +glm::vec3 cameraTarget = initialCameraTarget; +glm::vec3 cameraUp = initialCameraUp; + +GLFWwindow* window; std::vector balls(10); // Wektor przechowujący 10 kul GLuint shaderProgram; GLuint VAO, VBO; @@ -33,15 +57,15 @@ void initializeBalls() { srand(static_cast(time(0))); // Inicjalizujemy generator liczb losowych for (int i = 0; i < 10; ++i) { - float angle = 15.0f + static_cast(rand() % 60); // Losowy kąt między 15 a 75 stopni - float speed = 5.0f + static_cast(rand() % 20); // Losowa prędkość między 5 a 25 + float localAngle = angle + static_cast(rand() % 60); // + float localSpeed = speed + static_cast(rand() % 5); balls[i] = { .x = 0.0f, .y = 2.0f * i, // Ustawienie kul na tej samej wysokości początkowej .z = 0.0f, - .vx = static_cast(speed * cos(angle * M_PI / 180.0f)), - .vy = static_cast(speed * sin(angle * M_PI / 180.0f)), + .vx = static_cast(localSpeed * cos(localAngle * M_PI / 180.0f)), + .vy = static_cast(localSpeed * sin(localAngle * M_PI / 180.0f)), .vz = 0.0f, .r = static_cast(rand()) / RAND_MAX, .g = static_cast(rand()) / RAND_MAX, @@ -50,8 +74,89 @@ void initializeBalls() { } startTime = glfwGetTime(); // Ustawienie początkowego czasu symulacji + isLaunched = false; } +void initImGui(){ + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + ImGui::StyleColorsDark(); + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplOpenGL3_Init("#version 330 core"); +} + +void imGuiRenderCameraControlsFrame(){ + ImGui::Begin("Camera Control"); + ImGui::SliderFloat3("Camera Position", glm::value_ptr(cameraPos), -100.0f, 100.0f); + ImGui::SliderFloat3("Camera Target", glm::value_ptr(cameraTarget), -100.0f, 100.0f); + ImGui::SliderFloat3("Camera Up", glm::value_ptr(cameraUp), -1.0f, 1.0f); + + if(ImGui::Button("Reset Camera")){ + cameraPos = initialCameraPos; + cameraTarget = initialCameraTarget; + cameraUp = initialCameraUp; + } + + ImGui::End(); +} + +void imGuiRenderBallsControlsFrame(){ + ImGui::Begin("Balls Control"); + + ImGui::SliderFloat("Gravity", &gravity, 0.0f, 20.0f); + ImGui::SliderFloat("Air Resistance", &airResistance, 0.0f, 1.0f); + ImGui::SliderFloat("Speed", &speed, 0.0f, 20.0f); + ImGui::SliderFloat("Angle", &angle, 0.0f, 90.0f); + + if(ImGui::Button("Reset ball controls")){ + gravity = initialGravity; + airResistance = initialAirResistance; + speed = initialSpeed; + angle = initialAngle * M_PI / 180.0f; + } + + ImGui::End(); +} + +void imGuiBallsThrowingStateControlsFrame(){ + ImGui::Begin("Balls Throwing State"); + + for(int i = 0; i < 10; i++){ + ImGui::Text("Ball %d Position: (%.2f, %.2f, %.2f)", i + 1, balls[i].x, balls[i].y, balls[i].z); + } + + + if (ImGui::Button("Reset Balls")) { + initializeBalls(); + } + + if (ImGui::Button("Launch Balls")) { + isLaunched = true; + startTime = glfwGetTime(); // Resetowanie czasu startu + } + + ImGui::End(); +} + +void renderImGui(){ + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + imGuiRenderBallsControlsFrame(); + imGuiRenderCameraControlsFrame(); + imGuiBallsThrowingStateControlsFrame(); + + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); +} + +void cleanUpImGui(){ + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); +} void compileShaders(){ Shader shader("circle_vs.glsl", "circle_fs.glsl"); @@ -61,13 +166,13 @@ void compileShaders(){ // Funkcja do integracji Rungego-Kutty void rungeKuttaStep(Ball &ball, float dt) { float k1vx = -airResistance * ball.vx; - float k1vy = -g - airResistance * ball.vy; + float k1vy = -gravity - airResistance * ball.vy; float k2vx = -airResistance * (ball.vx + 0.5f * dt * k1vx); - float k2vy = -g - airResistance * (ball.vy + 0.5f * dt * k1vy); + float k2vy = -gravity - airResistance * (ball.vy + 0.5f * dt * k1vy); float k3vx = -airResistance * (ball.vx + 0.5f * dt * k2vx); - float k3vy = -g - airResistance * (ball.vy + 0.5f * dt * k2vy); + float k3vy = -gravity - airResistance * (ball.vy + 0.5f * dt * k2vy); float k4vx = -airResistance * (ball.vx + dt * k3vx); - float k4vy = -g - airResistance * (ball.vy + dt * k3vy); + float k4vy = -gravity - airResistance * (ball.vy + dt * k3vy); ball.vx += (dt / 6.0f) * (k1vx + 2.0f * k2vx + 2.0f * k3vx + k4vx); ball.vy += (dt / 6.0f) * (k1vy + 2.0f * k2vy + 2.0f * k3vy + k4vy); @@ -125,7 +230,7 @@ void display() { glUseProgram(shaderProgram); // Ustawienie widoku kamery - glm::mat4 view = glm::lookAt(glm::vec3(20, 20, 30), glm::vec3(0, 10, 0), glm::vec3(0, 1, 0)); + glm::mat4 view = glm::lookAt(cameraPos, cameraTarget, cameraUp); glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)windowWidth / (float)windowHeight, 0.1f, 100.0f); // Renderowanie każdej z 10 kul @@ -149,6 +254,7 @@ void display() { drawSphere(); // Rysowanie kuli } + renderImGui(); glfwSwapBuffers(glfwGetCurrentContext()); // Przełączanie buforów } @@ -157,7 +263,7 @@ void update() { float currentTime = glfwGetTime(); float dt = 0.01f; - if (currentTime - startTime >= delay) { + if (isLaunched && (currentTime - startTime >= delay)) { for (auto &ball : balls) { rungeKuttaStep(ball, dt); } @@ -193,7 +299,7 @@ int main() { glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - GLFWwindow* window = glfwCreateWindow(windowWidth, windowHeight, "Animacja 10 kul - Rzut ukośny", nullptr, nullptr); + window = glfwCreateWindow(windowWidth, windowHeight, "Animacja 10 kul - Rzut ukośny", nullptr, nullptr); if (!window) { std::cerr << "Failed to create GLFW window" << std::endl; glfwTerminate(); @@ -209,6 +315,7 @@ int main() { return -1; } + initImGui(); initializeBalls(); setupOpenGL(); @@ -218,6 +325,8 @@ int main() { glfwPollEvents(); } + cleanUpImGui(); + glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); glDeleteProgram(shaderProgram);