added user interaction
This commit is contained in:
parent
e705b3a8d8
commit
df3c8e302b
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
@ -19,8 +20,8 @@ Shader* Orbital::defaultShader = nullptr;
|
||||||
std::complex<double> SphericalHarmonic(unsigned int l, unsigned int m, float theta, float phi);
|
std::complex<double> SphericalHarmonic(unsigned int l, unsigned int m, float theta, float phi);
|
||||||
unsigned int Fac(unsigned int n);
|
unsigned int Fac(unsigned int n);
|
||||||
|
|
||||||
Orbital::Orbital(unsigned int l, unsigned int m) :
|
Orbital::Orbital(int l, int m) :
|
||||||
l(l), m(m)
|
l(l), m(m), positiveColor({ 0.1f, 0.85f, 0.1f }), negativeColor({ 0.85f, 0.1f, 0.1f })
|
||||||
{
|
{
|
||||||
if (defaultShader == nullptr)
|
if (defaultShader == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +30,7 @@ Orbital::Orbital(unsigned int l, unsigned int m) :
|
||||||
#version 460 core
|
#version 460 core
|
||||||
|
|
||||||
layout(location = 0) in vec3 position;
|
layout(location = 0) in vec3 position;
|
||||||
layout(location = 1) in vec3 color;
|
layout(location = 1) in uint sign; // 1 = positive, 0 = negative
|
||||||
|
|
||||||
out vec3 outColor;
|
out vec3 outColor;
|
||||||
|
|
||||||
|
@ -37,9 +38,12 @@ Orbital::Orbital(unsigned int l, unsigned int m) :
|
||||||
uniform mat4 view;
|
uniform mat4 view;
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
|
|
||||||
|
uniform vec3 positiveColor;
|
||||||
|
uniform vec3 negativeColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outColor = color;
|
outColor = (sign > 0) ? positiveColor : negativeColor;
|
||||||
gl_Position = projection * view * model * vec4(position, 1.0f);
|
gl_Position = projection * view * model * vec4(position, 1.0f);
|
||||||
}
|
}
|
||||||
)",
|
)",
|
||||||
|
@ -58,8 +62,8 @@ Orbital::Orbital(unsigned int l, unsigned int m) :
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateModel();
|
|
||||||
CreateVAO();
|
CreateVAO();
|
||||||
|
UpdateModel();
|
||||||
|
|
||||||
modelMatrix = glm::rotate(modelMatrix, glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.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));
|
modelMatrix = glm::scale(modelMatrix, glm::vec3(3.0f));
|
||||||
|
@ -71,6 +75,19 @@ void Orbital::BindDefaultShader(Camera& camera)
|
||||||
defaultShader->SetMatrix("model", glm::value_ptr(modelMatrix));
|
defaultShader->SetMatrix("model", glm::value_ptr(modelMatrix));
|
||||||
defaultShader->SetMatrix("view", glm::value_ptr(camera.GetViewMatrix()));
|
defaultShader->SetMatrix("view", glm::value_ptr(camera.GetViewMatrix()));
|
||||||
defaultShader->SetMatrix("projection", glm::value_ptr(camera.GetProjectionMatrix()));
|
defaultShader->SetMatrix("projection", glm::value_ptr(camera.GetProjectionMatrix()));
|
||||||
|
|
||||||
|
defaultShader->SetVector3("positiveColor", glm::value_ptr(positiveColor));
|
||||||
|
defaultShader->SetVector3("negativeColor", glm::value_ptr(negativeColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
float* Orbital::GetPositiveColorVPtr()
|
||||||
|
{
|
||||||
|
return glm::value_ptr(positiveColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
float* Orbital::GetNegativeColorVPtr()
|
||||||
|
{
|
||||||
|
return glm::value_ptr(negativeColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Orbital::UpdateModel()
|
void Orbital::UpdateModel()
|
||||||
|
@ -78,6 +95,9 @@ void Orbital::UpdateModel()
|
||||||
unsigned int verticesPerRing = 70;
|
unsigned int verticesPerRing = 70;
|
||||||
unsigned int rings = 70;
|
unsigned int rings = 70;
|
||||||
|
|
||||||
|
vertices.clear();
|
||||||
|
indices.clear();
|
||||||
|
|
||||||
for (int ring = 0; ring <= rings; ring++)
|
for (int ring = 0; ring <= rings; ring++)
|
||||||
{
|
{
|
||||||
for (int vertex = 0; vertex < verticesPerRing; vertex++)
|
for (int vertex = 0; vertex < verticesPerRing; vertex++)
|
||||||
|
@ -85,25 +105,23 @@ void Orbital::UpdateModel()
|
||||||
float phi = vertex * TWO_PI / verticesPerRing;
|
float phi = vertex * TWO_PI / verticesPerRing;
|
||||||
float theta = ring * PI / rings;
|
float theta = ring * PI / rings;
|
||||||
|
|
||||||
std::complex value = SphericalHarmonic(l, m, theta, phi);
|
std::complex value = SphericalHarmonic(l, std::abs(m), theta, phi);
|
||||||
double distance = std::abs(std::real(value));
|
|
||||||
// std::cout << "(" << theta << ", " << phi << ") -> " << distance << std::endl;
|
double distance = 0.0f;
|
||||||
|
if(m < 0)
|
||||||
|
distance = std::abs(std::imag(value));
|
||||||
|
else
|
||||||
|
distance = std::abs(std::real(value));
|
||||||
|
|
||||||
vertices.push_back(distance * std::cos(phi) * std::sin(theta));
|
vertices.push_back(distance * std::cos(phi) * std::sin(theta));
|
||||||
vertices.push_back(distance * std::sin(phi) * std::sin(theta));
|
vertices.push_back(distance * std::sin(phi) * std::sin(theta));
|
||||||
vertices.push_back(distance * std::cos(theta));
|
vertices.push_back(distance * std::cos(theta));
|
||||||
|
|
||||||
if (std::real(value) < 0)
|
if (m < 0)
|
||||||
{
|
vertices.push_back(std::imag(value) >= 0);
|
||||||
vertices.push_back(0.85f);
|
|
||||||
vertices.push_back(0.1f);
|
|
||||||
vertices.push_back(0.1f);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
vertices.push_back(std::real(value) >= 0);
|
||||||
vertices.push_back(0.1f);
|
|
||||||
vertices.push_back(0.85f);
|
|
||||||
vertices.push_back(0.1f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,14 +138,16 @@ void Orbital::UpdateModel()
|
||||||
indices.push_back(verticesPerRing * (ring + 1) + vertex);
|
indices.push_back(verticesPerRing * (ring + 1) + vertex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateBufferData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Orbital::DefineVAOLayout()
|
void Orbital::DefineVAOLayout()
|
||||||
{
|
{
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float) + 1 * sizeof(unsigned int), (void*)0);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
|
glVertexAttribIPointer(1, 1, GL_UNSIGNED_INT, 3 * sizeof(float) + 1 * sizeof(unsigned int), (void*)(3 * sizeof(float)));
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,15 +8,21 @@ class Camera;
|
||||||
class Orbital : public Model
|
class Orbital : public Model
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Orbital(unsigned int l, unsigned int m);
|
Orbital(int l, int m);
|
||||||
|
|
||||||
void BindDefaultShader(Camera& camera);
|
void BindDefaultShader(Camera& camera);
|
||||||
|
float* GetPositiveColorVPtr();
|
||||||
|
float* GetNegativeColorVPtr();
|
||||||
|
void UpdateModel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateModel();
|
|
||||||
void DefineVAOLayout() final override;
|
void DefineVAOLayout() final override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
glm::vec3 positiveColor, negativeColor;
|
||||||
|
int l, m;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int l, m;
|
|
||||||
static Shader* defaultShader;
|
static Shader* defaultShader;
|
||||||
};
|
};
|
|
@ -47,6 +47,12 @@ void Shader::SetMatrix(const std::string& name, const float* data)
|
||||||
glUniformMatrix4fv(location, 1, GL_FALSE, data);
|
glUniformMatrix4fv(location, 1, GL_FALSE, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Shader::SetVector3(const std::string& name, const float* data)
|
||||||
|
{
|
||||||
|
unsigned int location = glGetUniformLocation(program, name.c_str());
|
||||||
|
glUniform3fv(location, 1, data);
|
||||||
|
}
|
||||||
|
|
||||||
void Shader::Bind()
|
void Shader::Bind()
|
||||||
{
|
{
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
|
|
|
@ -10,6 +10,7 @@ public:
|
||||||
~Shader();
|
~Shader();
|
||||||
|
|
||||||
void SetMatrix(const std::string& name, const float* data);
|
void SetMatrix(const std::string& name, const float* data);
|
||||||
|
void SetVector3(const std::string& name, const float* data);
|
||||||
|
|
||||||
void Bind();
|
void Bind();
|
||||||
|
|
||||||
|
|
26
src/main.cpp
26
src/main.cpp
|
@ -123,8 +123,30 @@ int main(int argc, char** argv)
|
||||||
orbital.BindDefaultShader(camera);
|
orbital.BindDefaultShader(camera);
|
||||||
orbital.Draw();
|
orbital.Draw();
|
||||||
|
|
||||||
ImGui::Begin("Test Window");
|
ImGui::Begin("Orbital Settings");
|
||||||
ImGui::Button("Test");
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
Loading…
Reference in a new issue