Zadanie 2 stable version

This commit is contained in:
Władysław Kuczerenko 2024-06-10 00:32:59 +02:00
parent 9f4f44f895
commit 17875206bf

View File

@ -9,14 +9,26 @@
#include "shader.h" #include "shader.h"
#include <cstdlib> #include <cstdlib>
const float g = 9.81f; #include <imgui.h>
const float airResistance = 0.1f; #include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
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 windowWidth = 1200;
const int windowHeight = 800; const int windowHeight = 800;
float startTime; 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 { struct Ball {
@ -25,6 +37,18 @@ struct Ball {
float r, g, b; 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<Ball> balls(10); // Wektor przechowujący 10 kul std::vector<Ball> balls(10); // Wektor przechowujący 10 kul
GLuint shaderProgram; GLuint shaderProgram;
GLuint VAO, VBO; GLuint VAO, VBO;
@ -33,15 +57,15 @@ void initializeBalls() {
srand(static_cast<unsigned>(time(0))); // Inicjalizujemy generator liczb losowych srand(static_cast<unsigned>(time(0))); // Inicjalizujemy generator liczb losowych
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
float angle = 15.0f + static_cast<float>(rand() % 60); // Losowy kąt między 15 a 75 stopni float localAngle = angle + static_cast<float>(rand() % 60); // <angle, angle + 60>
float speed = 5.0f + static_cast<float>(rand() % 20); // Losowa prędkość między 5 a 25 float localSpeed = speed + static_cast<float>(rand() % 5);
balls[i] = { balls[i] = {
.x = 0.0f, .x = 0.0f,
.y = 2.0f * i, // Ustawienie kul na tej samej wysokości początkowej .y = 2.0f * i, // Ustawienie kul na tej samej wysokości początkowej
.z = 0.0f, .z = 0.0f,
.vx = static_cast<float>(speed * cos(angle * M_PI / 180.0f)), .vx = static_cast<float>(localSpeed * cos(localAngle * M_PI / 180.0f)),
.vy = static_cast<float>(speed * sin(angle * M_PI / 180.0f)), .vy = static_cast<float>(localSpeed * sin(localAngle * M_PI / 180.0f)),
.vz = 0.0f, .vz = 0.0f,
.r = static_cast<float>(rand()) / RAND_MAX, .r = static_cast<float>(rand()) / RAND_MAX,
.g = static_cast<float>(rand()) / RAND_MAX, .g = static_cast<float>(rand()) / RAND_MAX,
@ -50,8 +74,89 @@ void initializeBalls() {
} }
startTime = glfwGetTime(); // Ustawienie początkowego czasu symulacji 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(){ void compileShaders(){
Shader shader("circle_vs.glsl", "circle_fs.glsl"); Shader shader("circle_vs.glsl", "circle_fs.glsl");
@ -61,13 +166,13 @@ void compileShaders(){
// Funkcja do integracji Rungego-Kutty // Funkcja do integracji Rungego-Kutty
void rungeKuttaStep(Ball &ball, float dt) { void rungeKuttaStep(Ball &ball, float dt) {
float k1vx = -airResistance * ball.vx; 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 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 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 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.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); ball.vy += (dt / 6.0f) * (k1vy + 2.0f * k2vy + 2.0f * k3vy + k4vy);
@ -125,7 +230,7 @@ void display() {
glUseProgram(shaderProgram); glUseProgram(shaderProgram);
// Ustawienie widoku kamery // 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); glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)windowWidth / (float)windowHeight, 0.1f, 100.0f);
// Renderowanie każdej z 10 kul // Renderowanie każdej z 10 kul
@ -149,6 +254,7 @@ void display() {
drawSphere(); // Rysowanie kuli drawSphere(); // Rysowanie kuli
} }
renderImGui();
glfwSwapBuffers(glfwGetCurrentContext()); // Przełączanie buforów glfwSwapBuffers(glfwGetCurrentContext()); // Przełączanie buforów
} }
@ -157,7 +263,7 @@ void update() {
float currentTime = glfwGetTime(); float currentTime = glfwGetTime();
float dt = 0.01f; float dt = 0.01f;
if (currentTime - startTime >= delay) { if (isLaunched && (currentTime - startTime >= delay)) {
for (auto &ball : balls) { for (auto &ball : balls) {
rungeKuttaStep(ball, dt); rungeKuttaStep(ball, dt);
} }
@ -193,7 +299,7 @@ int main() {
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 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) { if (!window) {
std::cerr << "Failed to create GLFW window" << std::endl; std::cerr << "Failed to create GLFW window" << std::endl;
glfwTerminate(); glfwTerminate();
@ -209,6 +315,7 @@ int main() {
return -1; return -1;
} }
initImGui();
initializeBalls(); initializeBalls();
setupOpenGL(); setupOpenGL();
@ -218,6 +325,8 @@ int main() {
glfwPollEvents(); glfwPollEvents();
} }
cleanUpImGui();
glDeleteVertexArrays(1, &VAO); glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO); glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram); glDeleteProgram(shaderProgram);