Added coordinate system

This commit is contained in:
Lauchmelder 2021-11-18 20:03:02 +01:00
parent 3b900db1db
commit c3474a4c05
8 changed files with 232 additions and 59 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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

87
src/CoordinateSystem.cpp Normal file
View file

@ -0,0 +1,87 @@
#include "CoordinateSystem.hpp"
#include <glm/gtc/type_ptr.hpp>
#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();
}
}

28
src/CoordinateSystem.hpp Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include <array>
#include <glm/matrix.hpp>
#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<Axis*, 3> axes;
glm::mat4 modelMatrix;
static Shader* defaultShader;
};

View file

@ -21,7 +21,8 @@ std::complex<double> 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);
}
}

View file

@ -21,6 +21,7 @@ private:
public:
glm::vec3 positiveColor, negativeColor;
int l, m;
unsigned int resolution;
private:
static Shader* defaultShader;

View file

@ -8,7 +8,7 @@
#include <backends/imgui_impl_opengl3.h>
#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();
}
}
}