diff --git a/libhart/scene/camera.hpp b/libhart/scene/camera.hpp index a680e62..e9129c6 100644 --- a/libhart/scene/camera.hpp +++ b/libhart/scene/camera.hpp @@ -1,29 +1,48 @@ #pragma once -#include +#include +#include namespace inferno { -class Camera -{ +class Camera { public: - Camera(); - ~Camera(); + Camera(); + Camera(int w, int h); + void UpdateView(); + + glm::mat4 GetViewMatrix(); + glm::mat4 GetProjectionMatrix(); + glm::mat4 GetFrustrumMatrix(); + + void UpdateProjection(int width, int height); + + // Keyboard + void MoveCamera(glm::vec3 posDelta); + // Mouse Delta + void MouseMoved(glm::vec2 mouseDelta); + + // Updatable by + float MouseSensitivity = 0.1f; + float CameraSpeed = 2.0f; + + void UpdatePosition(glm::vec3 position); + void UpdateEulerLookDirection(float roll, float pitch, float yaw); + void UpdateLookDirection(glm::vec3 lookDirection); + + glm::vec3 Position = {}; + float Roll, Pitch, Yaw; + glm::vec3 LookDirection = {}; private: - // View - glm::vec3 Eye; - glm::vec3 Target; - glm::vec3 Up; - - // Projection - float FovY; - float Aspect; - float ZNear; + glm::mat4 viewMatrix = {}; + glm::mat4 projMatrix = {}; + }; + } diff --git a/libhart/scene/mesh.hpp b/libhart/scene/mesh.hpp index fa6fa51..a54ac1e 100644 --- a/libhart/scene/mesh.hpp +++ b/libhart/scene/mesh.hpp @@ -1,18 +1,28 @@ #pragma once #include +#include #include namespace inferno { +class ObjLoader; + +struct Vert +{ + glm::vec3 Position; + glm::vec3 Normal; + glm::vec2 UV; +}; + class Mesh { public: Mesh(); ~Mesh(); - void loadOBJ(); + void loadOBJ(std::filesystem::path file); void ready(); void getVerticies(std::vector* vert, @@ -23,17 +33,17 @@ public: public: GLuint getVAO(); GLuint getVBO(); + GLuint getEBO(); private: GLuint mVAO; GLuint mVBO; + GLuint mEBO; glm::mat4 mModel; private: - std::vector mVerticies; - std::vector mNormals; - std::vector mUVs; - + ObjLoader* mObjLoader; + std::vector mVerticies; }; } diff --git a/res/shaders/basic.glsl b/res/shaders/basic.glsl new file mode 100644 index 0000000..e69de29 diff --git a/src/inferno.cpp b/src/inferno.cpp index ec7fba1..6b273be 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -2,6 +2,7 @@ #include #include "gui/layout.hpp" +#include "window.hpp" #include #include @@ -10,7 +11,7 @@ #include #include -using namespace core; +namespace inferno { Inferno::Inferno(int argc, char** argv) { @@ -21,6 +22,11 @@ Inferno::Inferno(int argc, char** argv) mWin = new Window("Inferno v" INFERNO_VERSION, 1280, 720); } +Inferno::~Inferno() +{ + +} + void Inferno::uiPreset() { ImGuiID dockspace_id = ImGui::GetID("main"); @@ -39,6 +45,7 @@ void Inferno::uiPreset() int Inferno::run() { + while (true) { if (!mWin->newFrame()) { break; } ImGuiID dockspace_id = ImGui::GetID("main"); @@ -101,3 +108,5 @@ int Inferno::run() delete mWin; return 0; } + +} diff --git a/src/inferno.hpp b/src/inferno.hpp index b5427be..526a796 100644 --- a/src/inferno.hpp +++ b/src/inferno.hpp @@ -1,16 +1,32 @@ #pragma once -#include "window.hpp" -namespace core { +namespace inferno { + +class Window; +class GLFWwindow; + + +class RasterizeRenderer; +class Scene; + + class Inferno { public: Inferno(int argc, char** argv); - int run(); + ~Inferno(); + void uiPreset(); + int run(); private: - Window* mWin = NULL; + RasterizeRenderer* mRasterRenderer; + + Scene* mScene; + +private: + Window* mWin; }; + } diff --git a/src/main.cpp b/src/main.cpp index 132349d..9380328 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,7 @@ int main(int argc, char** argv) { try { - core::Inferno inferno(argc, argv); + inferno::Inferno inferno(argc, argv); return inferno.run(); } catch (std::exception e) diff --git a/src/preview_renderer/renderer.cpp b/src/preview_renderer/renderer.cpp index e69de29..bbc5582 100644 --- a/src/preview_renderer/renderer.cpp +++ b/src/preview_renderer/renderer.cpp @@ -0,0 +1,36 @@ +#include "renderer.hpp" + +#include +#include + +using namespace inferno; + +RasterizeRenderer::RasterizeRenderer() +{ + +} + +RasterizeRenderer::~RasterizeRenderer() +{ + +} + +void RasterizeRenderer::setScene(Scene* scene) +{ + mCurrentScene = scene; +} + +void RasterizeRenderer::setTarget(GLuint renderTarget) +{ + +} + +void RasterizeRenderer::prepare() +{ + +} + +void RasterizeRenderer::draw() +{ + +} diff --git a/src/preview_renderer/renderer.hpp b/src/preview_renderer/renderer.hpp index d9535b4..7de4e8c 100644 --- a/src/preview_renderer/renderer.hpp +++ b/src/preview_renderer/renderer.hpp @@ -1,5 +1,7 @@ #pragma once +#include + namespace inferno { class Camera; @@ -12,9 +14,10 @@ public: ~RasterizeRenderer(); void setScene(Scene* scene); + void setTarget(GLuint renderTarget); void prepare(); - void pass(); + void draw(); private: Camera* mCurrentCamera; diff --git a/src/scene/camera.cpp b/src/scene/camera.cpp index e69de29..9c702a6 100644 --- a/src/scene/camera.cpp +++ b/src/scene/camera.cpp @@ -0,0 +1,140 @@ +#include + +using namespace inferno; + +Camera::Camera() +{ + projMatrix = glm::perspective( glm::radians( 45.0f ), 1.0f, 0.1f, 1000.0f ); + + Roll = 0.0f; + Pitch = 0.0f; + Yaw = 0.0f; + + Position = {}; + LookDirection = {}; + + viewMatrix = {}; + + UpdateView(); +} + +Camera::Camera(int w, int h) +{ + projMatrix = glm::perspective(glm::radians(45.0f), (float)w / (float)h, 0.1f, 1000.0f); + + Roll = 0.0f; + Pitch = 0.0f; + Yaw = 0.0f; + + Position = {}; + LookDirection = {}; + + viewMatrix = {}; + + UpdateView(); +} + +void Camera::UpdateView() +{ + // roll can be removed + glm::mat4 matRoll = glm::mat4(1.0f); //identity matrix; + glm::mat4 matPitch = glm::mat4(1.0f);//identity matrix + glm::mat4 matYaw = glm::mat4(1.0f); //identity matrix + + // roll, pitch and yaw + matRoll = glm::rotate( matRoll, Roll, glm::vec3(0.0f, 0.0f, 1.0f)); + matPitch = glm::rotate( matPitch, Pitch, glm::vec3(1.0f, 0.0f, 0.0f)); + matYaw = glm::rotate( matYaw, Yaw, glm::vec3( 0.0f, 1.0f, 0.0f)); + + glm::mat4 rotate = matRoll * matPitch * matYaw; + + glm::mat4 translate = glm::mat4(1.0f); + translate = glm::translate(translate, -Position); + + viewMatrix = rotate * translate; + + // Work out Look Vector + glm::mat4 inverseView = glm::inverse(viewMatrix); + + LookDirection.x = inverseView[2][0]; + LookDirection.y = inverseView[2][1]; + LookDirection.z = inverseView[2][2]; +} + +glm::mat4 Camera::GetViewMatrix() +{ + return viewMatrix; +} + +glm::mat4 Camera::GetProjectionMatrix() +{ + return projMatrix; +} + +void Camera::UpdateProjection(int width, int height) +{ + projMatrix = glm::perspective(glm::radians(45.0f), (float)width / (float)height, 0.1f, 1000.0f); +} + +void Camera::MoveCamera(glm::vec3 posDelta) +{ + // Rotate by camera direction + glm::mat2 rotate { + cos(Yaw), -sin(Yaw), + sin(Yaw), cos(Yaw) + }; + + glm::vec2 f(0.0, 1.0); + f = f * rotate; + + // get current view matrix + glm::mat4 mat = GetViewMatrix(); + glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]); + glm::vec3 strafe(mat[0][0], mat[1][0], mat[2][0]); + + // forward vector must be negative to look forward. + // read :http://in2gpu.com/2015/05/17/view-matrix/ + Position.x += posDelta.x * CameraSpeed; + Position.z += posDelta.z * CameraSpeed; + Position.y += posDelta.y * CameraSpeed; + + // update the view matrix + UpdateView(); +} + +void Camera::MouseMoved(glm::vec2 mouseDelta) +{ + // note that yaw and pitch must be converted to radians. + // this is done in UpdateView() by glm::rotate + Yaw += MouseSensitivity * (mouseDelta.x / 100); + Pitch += MouseSensitivity * (mouseDelta.y / 100); + Pitch = glm::clamp(Pitch, -M_PI / 2, M_PI / 2); + + UpdateView(); +} + +void Camera::UpdatePosition(glm::vec3 position) +{ + Position = position; + + UpdateView(); +} + +void Camera::UpdateEulerLookDirection(float roll, float pitch, float yaw) +{ + Roll = roll; Pitch = pitch; Yaw = yaw; + LookDirection.x = cos(Yaw) * cos(Pitch); + LookDirection.y = sin(Yaw) * cos(Pitch); + LookDirection.z = sin(Pitch); + + UpdateView(); +} + +void Camera::UpdateLookDirection(glm::vec3 lookDirection) +{ + LookDirection = lookDirection; + Pitch = asin(-lookDirection.y); + Yaw = atan2(lookDirection.x, lookDirection.z); + + UpdateView(); +} diff --git a/src/scene/mesh.cpp b/src/scene/mesh.cpp index 80d83fb..39af479 100644 --- a/src/scene/mesh.cpp +++ b/src/scene/mesh.cpp @@ -2,6 +2,8 @@ #include +#include + using namespace inferno; Mesh::Mesh() @@ -11,10 +13,76 @@ Mesh::Mesh() Mesh::~Mesh() { - + delete mObjLoader; } -void Mesh::loadOBJ() +void Mesh::loadOBJ(std::filesystem::path file) { + mObjLoader = new ObjLoader(); + mObjLoader->load(file); + int vertCount = mObjLoader->getVertCount(); + + + for (int i = 0; i < vertCount; i += 3) + { + Vert vert; + vert.Position = { + mObjLoader->getPositions()[i], + mObjLoader->getPositions()[i+1], + mObjLoader->getPositions()[i+2], + }; + vert.Normal = { + mObjLoader->getNormals()[i], + mObjLoader->getNormals()[i+1], + mObjLoader->getNormals()[i+2], + }; + mVerticies.push_back(vert); + } +} + +void Mesh::ready() +{ + // TODO: ready check + + glGenVertexArrays(1, &mVAO); + glGenBuffers(1, &mVBO); + glGenBuffers(1, &mEBO); + + glBindVertexArray(mVAO); + // load data into vertex buffers + + glBindBuffer(GL_ARRAY_BUFFER, mVBO); + glBufferData(GL_ARRAY_BUFFER, mVerticies.size() * sizeof(Vert), &mVerticies[0], GL_STATIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mEBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mObjLoader->getIndexCount() * sizeof(unsigned int), &mObjLoader->getFaces()[0], GL_STATIC_DRAW); + + // set the vertex attribute pointers + // vertex Positions + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)0); + // vertex normals + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)offsetof(Vert, Normal)); + // vertex texture coords + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)offsetof(Vert, UV)); + + glBindVertexArray(0); +} + +GLuint Mesh::getVAO() +{ + return mVAO; +} + +GLuint Mesh::getVBO() +{ + return mVBO; +} + +GLuint Mesh::getEBO() +{ + return mEBO; } diff --git a/src/scene/objloader.cpp b/src/scene/objloader.cpp index d07bdf4..c0a4a5e 100644 --- a/src/scene/objloader.cpp +++ b/src/scene/objloader.cpp @@ -45,11 +45,16 @@ ObjLoader::ObjLoader() } +ObjLoader::~ObjLoader() +{ + +} + void ObjLoader::load(std::filesystem::path file) { if (!std::filesystem::exists(file)) { - spdlog::error("OBJ File does not exist at ", file); + spdlog::error("OBJ File does not exist at ", file.string()); return; } @@ -57,7 +62,7 @@ void ObjLoader::load(std::filesystem::path file) inf.open(file.c_str(), std::ios_base::in); if (!inf.is_open()) { - spdlog::error("Failed to open OBJ file ", file); + spdlog::error("Failed to open OBJ file ", file.string()); return; } diff --git a/src/window.cpp b/src/window.cpp index dc87fcc..53e0be8 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2,13 +2,17 @@ #include "spdlog/spdlog.h" -using namespace core; +using namespace inferno; Window::Window(std::string title, int width, int height) { this->width = width; this->height = height; setupGLFW(title); + + glfwSetKeyCallback(getGLFWWindow(), glfwKeyCallback); + glfwSetCursorPosCallback(getGLFWWindow(), glfwMouseCallback); + setupImGui(); } @@ -147,6 +151,16 @@ void Window::shutdownGLFW() glfwTerminate(); } +void Window::glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) +{ + +} + +void Window::glfwMouseCallback(GLFWwindow* window, double xpos, double ypos) +{ + +} + void Window::glfwErrorCallback(int error, const char* description) { spdlog::error("[GLFW {0}] {1}", error, description); } diff --git a/src/window.hpp b/src/window.hpp index a9b857d..1b18760 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -6,7 +6,9 @@ #define WINDOW_FLAGS ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoCollapse -namespace core { +namespace inferno { + + class Window { @@ -25,12 +27,17 @@ public: void getPos(int& x, int& y); GLFWwindow* getGLFWWindow() { return window; } + + private: void setupGLFW(std::string title); void setupImGui(); void shutdownImGui(); void shutdownGLFW(); + static void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); + static void glfwMouseCallback(GLFWwindow* window, double xpos, double ypos); + static void glfwErrorCallback(int error, const char* description);