From c3474a4c05e6897fe484803682bca066eb365b56 Mon Sep 17 00:00:00 2001 From: Lauchmelder Date: Thu, 18 Nov 2021 20:03:02 +0100 Subject: [PATCH] Added coordinate system --- src/Axis.cpp | 19 ++++++- src/Axis.hpp | 6 ++ src/CMakeLists.txt | 2 +- src/CoordinateSystem.cpp | 87 +++++++++++++++++++++++++++++ src/CoordinateSystem.hpp | 28 ++++++++++ src/Orbital.cpp | 30 +++++----- src/Orbital.hpp | 1 + src/main.cpp | 118 ++++++++++++++++++++++++++------------- 8 files changed, 232 insertions(+), 59 deletions(-) create mode 100644 src/CoordinateSystem.cpp create mode 100644 src/CoordinateSystem.hpp diff --git a/src/Axis.cpp b/src/Axis.cpp index 5711f35..d0b33c1 100644 --- a/src/Axis.cpp +++ b/src/Axis.cpp @@ -13,7 +13,8 @@ Shader* Axis::defaultShader = nullptr; -Axis::Axis(const glm::vec3& direction, float length) +Axis::Axis(const glm::vec3& direction, float length) : + color({0.6f, 0.6f, 0.6f}) { if (defaultShader == nullptr) { @@ -25,13 +26,15 @@ Axis::Axis(const glm::vec3& direction, float length) out vec3 outColor; + uniform vec3 color; + uniform mat4 model; uniform mat4 view; uniform mat4 projection; void main() { - outColor = vec3(0.6f, 0.6f, 0.6f); + outColor = color; gl_Position = projection * view * model * vec4(position, 1.0f); } )", @@ -52,6 +55,7 @@ Axis::Axis(const glm::vec3& direction, float length) const unsigned int axisRingResolution = 80; + // TODO: We're literally creating a new VAO for every axis object. Bad. vertices.push_back(0.0f); vertices.push_back(0.0f); vertices.push_back(length); @@ -102,4 +106,15 @@ void Axis::BindDefaultShader(Camera& camera) defaultShader->SetMatrix("model", glm::value_ptr(modelMatrix)); defaultShader->SetMatrix("view", glm::value_ptr(camera.GetViewMatrix())); defaultShader->SetMatrix("projection", glm::value_ptr(camera.GetProjectionMatrix())); + defaultShader->SetVector3("color", glm::value_ptr(color)); +} + +const glm::mat4 Axis::GetModelMatrix() +{ + return modelMatrix; +} + +float* Axis::GetColorVPtr() +{ + return glm::value_ptr(color); } diff --git a/src/Axis.hpp b/src/Axis.hpp index 73856fd..b899508 100644 --- a/src/Axis.hpp +++ b/src/Axis.hpp @@ -12,6 +12,12 @@ public: Axis(const glm::vec3& direction, float length); void BindDefaultShader(Camera& camera); + const glm::mat4 GetModelMatrix(); + + float* GetColorVPtr(); + +public: + glm::vec3 color; private: static Shader* defaultShader; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 050228a..ccb3e71 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(orbitals "main.cpp" "Model.cpp" "Shader.cpp" "Camera.cpp" "Orbital.cpp" "Axis.cpp") +add_executable(orbitals "main.cpp" "Model.cpp" "Shader.cpp" "Camera.cpp" "Orbital.cpp" "Axis.cpp" "CoordinateSystem.cpp") # Add GLFW, GLM, GLAD and ImGui include directories to target target_include_directories(orbitals PRIVATE diff --git a/src/CoordinateSystem.cpp b/src/CoordinateSystem.cpp new file mode 100644 index 0000000..eee853c --- /dev/null +++ b/src/CoordinateSystem.cpp @@ -0,0 +1,87 @@ +#include "CoordinateSystem.hpp" + +#include + +#include "Shader.hpp" +#include "Axis.hpp" +#include "Camera.hpp" + +Shader* CoordinateSystem::defaultShader = nullptr; + +CoordinateSystem::CoordinateSystem() : + modelMatrix(1.0f) +{ + if (defaultShader == nullptr) + { + defaultShader = new Shader( + R"( + #version 460 core + + layout(location = 0) in vec3 position; + + out vec3 outColor; + + uniform vec3 axisColor; + + uniform mat4 axisModel; + uniform mat4 model; + uniform mat4 view; + uniform mat4 projection; + + void main() + { + outColor = axisColor; + gl_Position = projection * view * model * axisModel * vec4(position, 1.0f); + } + )", + + R"( + #version 460 core + + in vec3 outColor; + out vec4 FragColor; + + void main() + { + FragColor = vec4(outColor, 1.0f); + } + )" + ); + } + + axes[0] = new Axis(glm::vec3(1.0f, 0.0f, 0.0f), 4.0f); + axes[0]->color = glm::vec3(1.0f, 0.0f, 0.0f); + + axes[1] = new Axis(glm::vec3(0.0f, 1.0f, 0.0f), 4.0f); + axes[1]->color = glm::vec3(0.0f, 1.0f, 0.0f); + + axes[2] = new Axis(glm::vec3(0.0f, 0.0f, 1.0f), 4.0f); + axes[2]->color = glm::vec3(0.0f, 0.0f, 1.0f); + +} + +CoordinateSystem::~CoordinateSystem() +{ + delete axes[2]; + delete axes[1]; + delete axes[0]; +} + +void CoordinateSystem::BindDefaultShader(Camera& camera) +{ + defaultShader->Bind(); + + defaultShader->SetMatrix("model", glm::value_ptr(modelMatrix)); + defaultShader->SetMatrix("view", glm::value_ptr(camera.GetViewMatrix())); + defaultShader->SetMatrix("projection", glm::value_ptr(camera.GetProjectionMatrix())); +} + +void CoordinateSystem::Draw() +{ + for (Axis* axis : axes) + { + defaultShader->SetMatrix("axisModel", glm::value_ptr(axis->GetModelMatrix())); + defaultShader->SetVector3("axisColor", glm::value_ptr(axis->color)); + axis->Draw(); + } +} diff --git a/src/CoordinateSystem.hpp b/src/CoordinateSystem.hpp new file mode 100644 index 0000000..cf1160b --- /dev/null +++ b/src/CoordinateSystem.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include + +#include + +#include "Axis.hpp" + +class Shader; +class Camera; + +class CoordinateSystem +{ +public: + CoordinateSystem(); + ~CoordinateSystem(); + + void BindDefaultShader(Camera& camera); + void Draw(); + + Axis* GetAxis(unsigned int index) { return axes[index]; }; + +private: + std::array axes; + glm::mat4 modelMatrix; + + static Shader* defaultShader; +}; \ No newline at end of file diff --git a/src/Orbital.cpp b/src/Orbital.cpp index 03bea42..d71035f 100644 --- a/src/Orbital.cpp +++ b/src/Orbital.cpp @@ -21,7 +21,8 @@ std::complex SphericalHarmonic(unsigned int l, unsigned int m, float the unsigned int Fac(unsigned int n); Orbital::Orbital(int l, int m) : - l(l), m(m), positiveColor({ 0.1f, 0.85f, 0.1f }), negativeColor({ 0.85f, 0.1f, 0.1f }) + l(l), m(m), positiveColor({ 1.0f, 1.0f, 0.5f }), negativeColor({ 0.5f, 1.0f, 1.0f }), + resolution(70) { if (defaultShader == nullptr) { @@ -92,18 +93,15 @@ float* Orbital::GetNegativeColorVPtr() void Orbital::UpdateModel() { - unsigned int verticesPerRing = 70; - unsigned int rings = 70; - vertices.clear(); indices.clear(); - for (int ring = 0; ring <= rings; ring++) + for (int ring = 0; ring <= resolution; ring++) { - for (int vertex = 0; vertex < verticesPerRing; vertex++) + for (int vertex = 0; vertex < resolution; vertex++) { - float phi = vertex * TWO_PI / verticesPerRing; - float theta = ring * PI / rings; + float phi = vertex * TWO_PI / resolution; + float theta = ring * PI / resolution; std::complex value = SphericalHarmonic(l, std::abs(m), theta, phi); @@ -125,17 +123,17 @@ void Orbital::UpdateModel() } } - for (int ring = 0; ring < rings; ring++) + for (int ring = 0; ring < resolution; ring++) { - for (int vertex = 0; vertex < verticesPerRing; vertex++) + for (int vertex = 0; vertex < resolution; vertex++) { - indices.push_back(verticesPerRing * ring + vertex); - indices.push_back(verticesPerRing * ring + ((vertex + 1) % verticesPerRing)); - indices.push_back(verticesPerRing * (ring + 1) + ((vertex + 1) % verticesPerRing)); + indices.push_back(resolution * ring + vertex); + indices.push_back(resolution * ring + ((vertex + 1) % resolution)); + indices.push_back(resolution * (ring + 1) + ((vertex + 1) % resolution)); - indices.push_back(verticesPerRing * ring + vertex); - indices.push_back(verticesPerRing * (ring + 1) + ((vertex + 1) % verticesPerRing)); - indices.push_back(verticesPerRing * (ring + 1) + vertex); + indices.push_back(resolution * ring + vertex); + indices.push_back(resolution * (ring + 1) + ((vertex + 1) % resolution)); + indices.push_back(resolution * (ring + 1) + vertex); } } diff --git a/src/Orbital.hpp b/src/Orbital.hpp index f449693..bd7f0cd 100644 --- a/src/Orbital.hpp +++ b/src/Orbital.hpp @@ -21,6 +21,7 @@ private: public: glm::vec3 positiveColor, negativeColor; int l, m; + unsigned int resolution; private: static Shader* defaultShader; diff --git a/src/main.cpp b/src/main.cpp index 7b97dc5..f8e5e4a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,7 +8,7 @@ #include #include "Orbital.hpp" -#include "Axis.hpp" +#include "CoordinateSystem.hpp" #include "Shader.hpp" #include "Camera.hpp" @@ -27,6 +27,10 @@ void OnKeyPressed(GLFWwindow* window, int key, int scancode, int action, int mod void ProcessInput(GLFWwindow* window); +void DrawOrbitalSettings(Orbital& orbital); +void DrawGeneralSettings(Camera& camera); +void DrawMathematicalSettings(CoordinateSystem& cs); + int main(int argc, char** argv) { // Initialize GLFW and let it know what OpenGL version/profile we're using @@ -72,21 +76,18 @@ int main(int argc, char** argv) ImGui::StyleColorsDark(); + CoordinateSystem csystem; + // Create some orbital and set up its transformation matrix // TODO: the matrix should probably be part of Model Orbital orbital(2, 1); - Axis axisX(glm::vec3(1.0f, 0.0f, 0.0f), 4.0f); - Axis axisY(glm::vec3(0.0f, 1.0f, 0.0f), 4.0f); - Axis axisZ(glm::vec3(0.0f, 0.0f, 1.0f), 4.0f); - - glm::mat4 modelMatrix = glm::mat4(1.0f); - modelMatrix = glm::rotate(modelMatrix, glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); - modelMatrix = glm::scale(modelMatrix, glm::vec3(3.0f)); // Set up a camera // TODO: should the projection matrix be part of the camera? Camera camera(110.0f, 1200.0f / 800.0f); - camera.SetPosition(glm::vec3(0.0f, 0.0f, 3.0f)); + camera.SetPosition(glm::vec3(0.0f, 0.0f, 4.0f)); + + glm::vec3 clearColor(0.0f, 0.0f, 0.05f); // Data that we want to be able to access from anywhere UserData data = { @@ -116,7 +117,7 @@ int main(int argc, char** argv) ProcessInput(window); // Clear screen - glClearColor(0.0f, 0.0f, 0.05f, 0.0f); + glClearColor(clearColor.x, clearColor.y, clearColor.z, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Start new ImGui Frame @@ -127,38 +128,14 @@ int main(int argc, char** argv) orbital.BindDefaultShader(camera); orbital.Draw(); - axisX.BindDefaultShader(camera); - axisX.Draw(); + csystem.BindDefaultShader(camera); + csystem.Draw(); - axisY.BindDefaultShader(camera); - axisY.Draw(); + ImGui::Begin("Settings"); - axisZ.BindDefaultShader(camera); - axisZ.Draw(); - - ImGui::Begin("Orbital Settings"); - - if (ImGui::CollapsingHeader("Properties")) - { - ImGui::SliderInt("l", &orbital.l, 0, 10); - if (orbital.m > orbital.l) - orbital.m = orbital.l; - else if (orbital.m < -orbital.l) - orbital.m = -orbital.l; - - ImGui::SliderInt("m", &orbital.m, -orbital.l, orbital.l); - - if (ImGui::Button("Generate")) - { - orbital.UpdateModel(); - } - } - - if (ImGui::CollapsingHeader("Appearance")) - { - ImGui::ColorEdit3("Positive Value Color", orbital.GetPositiveColorVPtr()); - ImGui::ColorEdit3("Negative Value Color", orbital.GetNegativeColorVPtr()); - } + DrawOrbitalSettings(orbital); + DrawGeneralSettings(camera); + DrawMathematicalSettings(csystem); ImGui::End(); @@ -240,3 +217,64 @@ void ProcessInput(GLFWwindow* window) if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) data->camera->MoveUp(-cameraSpeed, data->frametime); } + +void DrawOrbitalSettings(Orbital& orbital) +{ + if (ImGui::CollapsingHeader("Orbital Settings")) + { + + if (ImGui::TreeNode("Properties")) + { + ImGui::SliderInt("l", &orbital.l, 0, 8); + if (orbital.m > orbital.l) + orbital.m = orbital.l; + else if (orbital.m < -orbital.l) + orbital.m = -orbital.l; + + ImGui::SliderInt("m", &orbital.m, -orbital.l, orbital.l); + + ImGui::SliderInt("Resolution", (int*)&orbital.resolution, 10, 1000); + + if (ImGui::Button("Generate")) + { + orbital.UpdateModel(); + } + + ImGui::TreePop(); + ImGui::Separator(); + } + + if (ImGui::TreeNode("Appearance")) + { + ImGui::ColorEdit3("Positive Value Color", orbital.GetPositiveColorVPtr()); + ImGui::ColorEdit3("Negative Value Color", orbital.GetNegativeColorVPtr()); + + ImGui::TreePop(); + ImGui::Separator(); + } + } +} + +void DrawGeneralSettings(Camera& camera) +{ + if(ImGui::CollapsingHeader("Camera Settings")) + { + + } +} + +void DrawMathematicalSettings(CoordinateSystem& cs) +{ + if (ImGui::CollapsingHeader("Coordinate System Settings")) + { + if (ImGui::TreeNode("Axes")) + { + ImGui::ColorEdit3("x-Axis color", cs.GetAxis(0)->GetColorVPtr()); + ImGui::ColorEdit3("y-Axis color", cs.GetAxis(1)->GetColorVPtr()); + ImGui::ColorEdit3("z-Axis color", cs.GetAxis(2)->GetColorVPtr()); + + ImGui::TreePop(); + ImGui::Separator(); + } + } +}