diff --git a/zadanie-1/main.cpp b/zadanie-1/main.cpp index bd708c4..bf9388e 100644 --- a/zadanie-1/main.cpp +++ b/zadanie-1/main.cpp @@ -5,16 +5,34 @@ #include #include "shader.h" -// Konstante -const float g = 9.81f; // przyspieszenie ziemskie -const float r = 0.6f; // długość nici -const float dt = 0.01f; // krok czasowy +// Constants +const float g = 9.81f; // Gravitational acceleration +const float r = 0.6f; // Length of the string +const float initialDt = 0.01f; // Initial time step -// Zmienne globalne -float theta = 0.5f; // początkowy kąt -float omega = 0.0f; // początkowa prędkość kątowa +const float initTheta = 0.785f; // Initial angle +const float initOmega = 2.0f; // Initial angular velocity +const float initPrevTheta = initTheta - initialDt * initOmega; // Initial previous angle -GLuint VBO, VAO, EBO, shaderProgram; + +float dt = initialDt; +float currentT = 0.0f; + +// Pendulum state structure +struct Pendulum { + float theta; // Angle + float omega; // Angular velocity + float prev_theta; // Previous angle (for Verlet method) +}; + +// Pendulums +Pendulum pendulums[3] = { + {initTheta, initOmega, initPrevTheta}, // Pendulum 1 (Euler) + {initTheta, initOmega, initPrevTheta}, // Pendulum 2 (Verlet) + {initTheta, initOmega, initPrevTheta}, // Pendulum 3 (Runge-Kutta) +}; + +GLuint VBO, VAO, shaderProgram; void compileShaders(){ Shader shader("pendulum_vs.glsl", "pendulum_fs.glsl"); @@ -32,12 +50,16 @@ void initOpenGL() glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 4, nullptr, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 40, nullptr, GL_DYNAMIC_DRAW); // 4 pendulums * 2 vertices * (2 positions + 3 colors) - // Pozycja - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0); + // Position attribute + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); + // Color attribute + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float))); + glEnableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); } @@ -46,64 +68,82 @@ float f(float theta){ return -(g / r) * sin(theta); } -// Metoda Eulera -void updateEuler() +// Euler method +void updateEuler(Pendulum& p) { - float alpha = f(theta); // przyspieszenie kątowe - omega += alpha * dt; // aktualizacja prędkości kątowej - theta += omega * dt; // aktualizacja kąta + p.theta = p.theta + dt * p.omega; + p.omega = p.omega + f(p.theta) * dt; } -// Metoda Verleta -void updateVerlet() +// Verlet method +void updateVerlet(Pendulum& p) { - static float prev_theta = theta; - float alpha = f(theta); // przyspieszenie kątowe - float new_theta = 2 * theta - prev_theta + alpha * dt * dt; // aktualizacja kąta - prev_theta = theta; - theta = new_theta; + float new_theta = 2 * p.theta - p.prev_theta + f(p.theta) * dt * dt; + float old_theta = p.theta; + p.theta = new_theta; + p.prev_theta = old_theta; + + // Aktualizacja omega + p.omega = (p.theta - p.prev_theta) / (2 * dt); } -// Metoda Rungego-Kutty rzędu 4 -void updateRungeKutta() +// Runge-Kutta 4th order method +void updateRungeKutta(Pendulum& p) { - float k1_theta = omega; - float k1_omega = f(theta); + float k1_theta = p.omega; + float k1_omega = f(p.theta); - float k2_theta = omega + 0.5f * dt * k1_omega; - float k2_omega = f(theta + 0.5f * dt * k1_theta); + float k2_theta = p.omega + 0.5f * dt * k1_omega; + float k2_omega = f(p.theta + 0.5f * dt * k1_theta); - float k3_theta = omega + 0.5f * dt * k2_omega; - float k3_omega = f(theta + 0.5f * dt * k2_theta); + float k3_theta = p.omega + 0.5f * dt * k2_omega; + float k3_omega = f(p.theta + 0.5f * dt * k2_theta); - float k4_theta = omega + dt * k3_omega; - float k4_omega = f(theta + dt * k3_theta); + float k4_theta = p.omega + dt * k3_omega; + float k4_omega = f(p.theta + dt * k3_theta); - theta += (dt / 6.0f) * (k1_theta + 2.0f * k2_theta + 2.0f * k3_theta + k4_theta); - omega += (dt / 6.0f) * (k1_omega + 2.0f * k2_omega + 2.0f * k3_omega + k4_omega); + p.theta += (dt / 6.0f) * (k1_theta + 2.0f * k2_theta + 2.0f * k3_theta + k4_theta); + p.omega += (dt / 6.0f) * (k1_omega + 2.0f * k2_omega + 2.0f * k3_omega + k4_omega); } -void drawPendulum() +void drawPendulums() { - float x = r * sin(theta); - float y = -r * cos(theta); - - float vertices[] = { - 0.0f, 0.0f, // Punkt zaczepienia - x, y // Punkt masy - }; - - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); glBindVertexArray(VAO); - glDrawArrays(GL_LINES, 0, 2); - glDrawArrays(GL_POINTS, 1, 1); + std::vector> colors = { + {1.0f, 0.0f, 0.0f}, // EULER + {0.0f, 1.0f, 0.0f}, // VERLET + {0.0f, 0.0f, 1.0f}, // RK + {1.0f, 1.0f, 0.0f} // SIMPLE + }; + + std::vector vertices; + + for (int i = 0; i < 3; ++i) { + float x = r * sin(pendulums[i].theta); + float y = -r * cos(pendulums[i].theta); + + // Append vertices for the current pendulum + vertices.insert(vertices.end(), { + 0.0f, 0.0f, colors[i][0], colors[i][1], colors[i][2], // Attachment point + x, y, colors[i][0], colors[i][1], colors[i][2] // Mass point + }); + + // Debugging output for each pendulum's vertices +// std::cout << "Pendulum " << i + 1 << ": (" << x << ", " << y << "), Color: (" +// << colors[i][0] << ", " << colors[i][1] << ", " << colors[i][2] << ")" << std::endl; + } + + glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * vertices.size(), vertices.data()); + + for (int i = 0; i < 3; ++i) { + glDrawArrays(GL_LINES, i * 2, 2); + glDrawArrays(GL_POINTS, i * 2 + 1, 1); + } glBindVertexArray(0); } @@ -112,7 +152,7 @@ int main() { if (!glfwInit()) { - std::cerr << "Nie można zainicjalizować GLFW" << std::endl; + std::cerr << "Failed to initialize GLFW" << std::endl; return -1; } @@ -121,12 +161,10 @@ int main() glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - - - GLFWwindow* window = glfwCreateWindow(800, 600, "Wahadło Matematyczne", NULL, NULL); + GLFWwindow* window = glfwCreateWindow(800, 600, "Mathematical Pendulums", NULL, NULL); if (!window) { - std::cerr << "Nie można utworzyć okna GLFW" << std::endl; + std::cerr << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } @@ -135,7 +173,7 @@ int main() glewExperimental = GL_TRUE; if (glewInit() != GLEW_OK) { - std::cerr << "Nie można zainicjalizować GLEW" << std::endl; + std::cerr << "Failed to initialize GLEW" << std::endl; return -1; } @@ -144,37 +182,24 @@ int main() glOrtho(-2, 2, -2, 2, -1, 1); glMatrixMode(GL_MODELVIEW); - glPointSize(10.0f); + glPointSize(35.0f); initOpenGL(); - int method = 1; // Domyślnie metoda Eulera - - std::cout << "Wybierz metodę: (1) Euler, (2) Verlet, (3) Runge-Kutta: "; - std::cin >> method; while (!glfwWindowShouldClose(window)) { - switch (method) - { - case 1: - updateEuler(); - break; - case 2: - updateVerlet(); - break; - case 3: - updateRungeKutta(); - break; - default: - updateEuler(); - break; - } + updateEuler(pendulums[0]); + updateVerlet(pendulums[1]); + updateRungeKutta(pendulums[2]); - drawPendulum(); + drawPendulums(); glfwSwapBuffers(window); glfwPollEvents(); + + currentT += dt; + } glDeleteVertexArrays(1, &VAO); diff --git a/zadanie-1/pendulum_fs.glsl b/zadanie-1/pendulum_fs.glsl index fd7a8fd..448cd58 100644 --- a/zadanie-1/pendulum_fs.glsl +++ b/zadanie-1/pendulum_fs.glsl @@ -1,6 +1,8 @@ #version 330 core -out vec4 FragColor; +in vec3 fragColor; +out vec4 color; + void main() { - FragColor = vec4(1.0, 1.0, 1.0, 1.0); -} + color = vec4(fragColor, 1.0); +} \ No newline at end of file diff --git a/zadanie-1/pendulum_vs.glsl b/zadanie-1/pendulum_vs.glsl index e757fcc..3ba0ec7 100644 --- a/zadanie-1/pendulum_vs.glsl +++ b/zadanie-1/pendulum_vs.glsl @@ -1,6 +1,11 @@ #version 330 core -layout(location = 0) in vec2 aPos; +layout(location = 0) in vec2 position; +layout(location = 1) in vec3 color; + +out vec3 fragColor; + void main() { - gl_Position = vec4(aPos, 0.0, 1.0); -} + gl_Position = vec4(position, 0.0, 1.0); + fragColor = color; +} \ No newline at end of file