diff --git a/backend/include/backend/Camera.hpp b/backend/include/backend/Camera.hpp new file mode 100644 index 0000000..1a6e614 --- /dev/null +++ b/backend/include/backend/Camera.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include "Transformable.hpp" +#include "Drawable.hpp" + +// TODO: Find better name +class CameraBase : public Transformable +{ +public: + // "Scaling" doesn't really makes sense for a camera + void GetScale() = delete; + void SetScale(const glm::vec3&) = delete; + void Scale(const glm::vec3&) = delete; + + inline const glm::mat4& GetView() const + { + return transformation; + } + + inline const glm::mat4& GetProjection() const + { + return projection; + } + + inline void Draw(const Drawable& drawable) const + { + drawable.Draw(*this); + } + +protected: + glm::mat4 projection; +}; + + +class Camera : public CameraBase +{ +public: + Camera(float fov = 90.0f, float aspect = 1.0f, float zNear = 0.01f, float zFar = 100.0f) + { + projection = glm::perspective(glm::radians(fov), aspect, zNear, zFar); + } +}; + +class OrthogonalCamera : public CameraBase +{ +public: + OrthogonalCamera(float left = -1.0f, float right = 1.0f, float bottom = -1.0f, float top = 1.0f, float zNear = -100.0f, float zFar = 100.0f) + { + projection = glm::ortho(left, right, bottom, top, zNear, zFar); + } +}; \ No newline at end of file diff --git a/backend/include/backend/Drawable.hpp b/backend/include/backend/Drawable.hpp index 129362c..a46f7b4 100644 --- a/backend/include/backend/Drawable.hpp +++ b/backend/include/backend/Drawable.hpp @@ -4,6 +4,8 @@ #include "VertexArrayObject.hpp" #include "Shader.hpp" +class CameraBase; + enum class PrimitiveType { Lines = GL_LINES, @@ -21,8 +23,8 @@ public: Drawable(const Drawable& other) = delete; void operator=(const Drawable& other) = delete; - virtual void InitializeShader() = 0; - void Render(); + virtual void InitializeShader(const CameraBase& camera) const = 0; + void Draw(const CameraBase& camera) const; void SetPrimitiveType(PrimitiveType type); protected: diff --git a/backend/src/Drawable.cpp b/backend/src/Drawable.cpp index 95e2797..1d3a33c 100644 --- a/backend/src/Drawable.cpp +++ b/backend/src/Drawable.cpp @@ -1,9 +1,9 @@ #include "backend/Drawable.hpp" -void Drawable::Render() +void Drawable::Draw(const CameraBase& camera) const { shader->Use(); - InitializeShader(); + InitializeShader(camera); vao->Render(static_cast(type)); } diff --git a/src/Application.cpp b/src/Application.cpp index e035daf..4ff9a73 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -87,6 +87,13 @@ void Application::Init(int width, int height, const std::string& title) glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height) { + WindowData* data = (WindowData*)glfwGetWindowUserPointer(window); + + float aspectRatio = (float)width / (float)height; + *(data->camera) = Camera(100.0f, aspectRatio); + data->camera->Move(glm::vec3(0.0f, 0.0f, -4.0f)); + *(data->orthoCam) = OrthogonalCamera(-3.0f * aspectRatio, 3.0f * aspectRatio, -3.0f, 3.0f); + glViewport(0, 0, width, height); } ); @@ -102,6 +109,8 @@ void Application::Init(int width, int height, const std::string& title) } ); + glfwSetWindowUserPointer(window, &data); + // Set up ImGui IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -112,10 +121,22 @@ void Application::Init(int width, int height, const std::string& title) ImGui::StyleColorsDark(); + float aspectRatio = (float)windowWidth / (float)windowHeight; + camera = Camera(100.0f, aspectRatio); + camera.Move(glm::vec3(0.0f, 0.0f, -4.0f)); + + orthoCam = OrthogonalCamera(-3.0f * aspectRatio, 3.0f * aspectRatio, -3.0f, 3.0f); + + activeCamera = &camera; + cube = new Cuboid(); cubePosition = glm::vec3(0.0f); cubeOrientation = glm::vec3(0.0f); cubeScale = glm::vec3(1.0f); + + data.camera = &camera; + data.orthoCam = &orthoCam; + } void Application::Launch() @@ -135,12 +156,31 @@ void Application::Launch() ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - cube->Render(); + cube->Draw(*activeCamera); ImGui::Begin("Debug"); - ImGui::SliderFloat3("Position", &(cubePosition[0]), -2.0f, 2.0f); - ImGui::SliderFloat3("Orientation", &(cubeOrientation[0]), 0.0f, glm::two_pi()); - ImGui::SliderFloat3("Scale", &(cubeScale[0]), 0.0f, 2.0f); + + if (ImGui::CollapsingHeader("Cube")) + { + ImGui::SliderFloat3("Position", &(cubePosition[0]), -2.0f, 2.0f); + ImGui::SliderFloat3("Orientation", &(cubeOrientation[0]), 0.0f, glm::two_pi()); + ImGui::SliderFloat3("Scale", &(cubeScale[0]), 0.0f, 2.0f); + } + + if (ImGui::CollapsingHeader("Camera")) + { + ImGui::Columns(2); + ImGui::Text("Projection: "); + ImGui::NextColumn(); + if (ImGui::Button((activeCamera == &camera) ? "Perspective" : "Orthographic")) + { + if (activeCamera == &camera) + activeCamera = &orthoCam; + else + activeCamera = &camera; + } + } + ImGui::End(); ImGui::Render(); diff --git a/src/Application.hpp b/src/Application.hpp index c5c0e78..c06fc8a 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -1,10 +1,17 @@ #pragma once #include +#include "backend/Camera.hpp" #include "Cuboid.hpp" struct GLFWwindow; +struct WindowData +{ + Camera* camera; + OrthogonalCamera* orthoCam; +}; + class Application { ///////////////////////////////////////////////////////// @@ -33,6 +40,11 @@ public: private: GLFWwindow* window = nullptr; + WindowData data; + + Camera camera; + OrthogonalCamera orthoCam; + CameraBase* activeCamera; glm::vec3 cubeOrientation, cubePosition, cubeScale; Cuboid* cube; diff --git a/src/Cuboid.cpp b/src/Cuboid.cpp index a0563c2..a43ea44 100644 --- a/src/Cuboid.cpp +++ b/src/Cuboid.cpp @@ -6,6 +6,7 @@ #include #include "backend/ObjectManager.hpp" +#include "backend/Camera.hpp" #include "Util.hpp" Cuboid::Cuboid() @@ -81,9 +82,9 @@ Cuboid::Cuboid() perspective = glm::perspective(glm::radians(100.0f), 16.0f / 9.0f, 0.01f, 100.0f); } -void Cuboid::InitializeShader() +void Cuboid::InitializeShader(const CameraBase& camera) const { shader->SetUniform("model", transformation); - shader->SetUniform("view", view); - shader->SetUniform("perspective", perspective); + shader->SetUniform("view", camera.GetView()); + shader->SetUniform("perspective", camera.GetProjection()); } diff --git a/src/Cuboid.hpp b/src/Cuboid.hpp index 3d96069..2a01ec0 100644 --- a/src/Cuboid.hpp +++ b/src/Cuboid.hpp @@ -14,7 +14,7 @@ class Cuboid : public: Cuboid(); - void InitializeShader() override; + void InitializeShader(const CameraBase& camera) const override; private: