diff --git a/libhart/scene/camera.hpp b/libhart/scene/camera.hpp index 4d4945a..504e9a2 100644 --- a/libhart/scene/camera.hpp +++ b/libhart/scene/camera.hpp @@ -24,8 +24,8 @@ public: void MouseMoved(glm::vec2 mouseDelta); // Updatable by - float MouseSensitivity = 0.1f; - float CameraSpeed = 2.0f; + float MouseSensitivity = 0.4f; + float CameraSpeed = 0.2f; void UpdatePosition(glm::vec3 position); void UpdateEulerLookDirection(float roll, float pitch, float yaw); @@ -36,7 +36,6 @@ public: glm::vec3 LookDirection = {}; private: - glm::mat4 viewMatrix = {}; glm::mat4 projMatrix = {}; diff --git a/libhart/scene/material.hpp b/libhart/scene/material.hpp index 7b9b913..0650fc4 100644 --- a/libhart/scene/material.hpp +++ b/libhart/scene/material.hpp @@ -4,12 +4,20 @@ namespace inferno { +class Shader; + class Material { public: - Material(); + Material(std::string name); ~Material(); - std::string name; + std::string getName(); + void setGlShader(Shader* shader); + Shader* getGlShader(); + +private: + std::string mName; + Shader* mGlShader; }; } diff --git a/libhart/scene/mesh.hpp b/libhart/scene/mesh.hpp index a54ac1e..ca7065b 100644 --- a/libhart/scene/mesh.hpp +++ b/libhart/scene/mesh.hpp @@ -8,12 +8,13 @@ namespace inferno { class ObjLoader; +class Material; struct Vert { glm::vec3 Position; glm::vec3 Normal; - glm::vec2 UV; + // glm::vec2 UV; }; class Mesh @@ -29,6 +30,11 @@ public: std::vector* norm, std::vector* uv); + int getIndexCount(); + + void setMaterial(Material* mat); + Material* getMaterial(); + // Raster public: GLuint getVAO(); @@ -43,6 +49,8 @@ private: private: ObjLoader* mObjLoader; + Material* mMaterial; + std::vector mVerticies; }; diff --git a/libhart/scene/scene.hpp b/libhart/scene/scene.hpp index 1cbd1b7..906950a 100644 --- a/libhart/scene/scene.hpp +++ b/libhart/scene/scene.hpp @@ -5,6 +5,8 @@ namespace inferno { class SceneObject; +class Camera; +class Mesh; class Sky; class Scene @@ -13,10 +15,16 @@ public: Scene(); ~Scene(); - SceneObject* newObject(); + void setCamera(Camera* camera); + Camera* getCamera(); + void addMesh(Mesh* mesh); + + const std::vector& getRenderables(); private: - std::vector mObjects; + std::vector mMeshs; + + Camera* mCurrentCamera; Sky* mCurrentSky; }; diff --git a/res/shaders/basic.glsl b/res/shaders/basic.glsl index 19aceda..5d3623e 100644 --- a/res/shaders/basic.glsl +++ b/res/shaders/basic.glsl @@ -1,7 +1,8 @@ -#type vertex +#type vertex #version 330 -in vec3 position; +layout (location = 0) in vec3 position; +layout (location = 1) in vec3 normal; uniform mat4 model; uniform mat4 view; @@ -17,5 +18,5 @@ void main() { out vec4 outColour; void main() { - outColour = vec4(0.58, 0.61, 0.627, 1.0); + outColour = vec4(1, 0, 0, 1); } diff --git a/src/graphics.hpp b/src/graphics.hpp index dd4a854..a66e8f0 100644 --- a/src/graphics.hpp +++ b/src/graphics.hpp @@ -17,3 +17,4 @@ extern "C" // glm #include +#include diff --git a/src/inferno.cpp b/src/inferno.cpp index 6b3652a..cf40135 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -4,6 +4,13 @@ #include "gui/layout.hpp" #include "window.hpp" +#include "preview_renderer/renderer.hpp" +#include "preview_renderer/shader.hpp" +#include "scene/camera.hpp" +#include "scene/scene.hpp" +#include "scene/material.hpp" +#include "scene/mesh.hpp" + #include #include @@ -12,9 +19,12 @@ using namespace inferno; -Inferno::Inferno() +Inferno::Inferno() + : mScene(), + mRasterRenderer() { // MOTD + spdlog::set_level(spdlog::level::trace); spdlog::info("INFERNO HART v" INFERNO_VERSION); // Create window @@ -46,40 +56,70 @@ void Inferno::uiPreset() void Inferno::input() { // KBD & MOUSE - static double dxpos, dypos; - double xpos, ypos; - glfwGetCursorPos(mWin->getGLFWWindow(), &xpos, &ypos); + static glm::dvec2 dMouseDelta; + glm::dvec2 tempMousePos; + glfwGetCursorPos(mWin->getGLFWWindow(), &tempMousePos.x, &tempMousePos.y); - mouseDelta.x = (int)(dxpos - xpos); - mouseDelta.y = (int)(dypos - ypos); - dxpos = xpos; dypos = ypos; + mouseDelta = dMouseDelta - tempMousePos; + dMouseDelta = tempMousePos; + + kbdDelta = glm::vec3(0.0f); + + if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_W) == GLFW_PRESS) kbdDelta.z += 1.0f; + if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_A) == GLFW_PRESS) kbdDelta.x -= 1.0f; + if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_S) == GLFW_PRESS) kbdDelta.z -= 1.0f; + if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_D) == GLFW_PRESS) kbdDelta.x += 1.0f; + if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_SPACE) == GLFW_PRESS) kbdDelta.y += 1.0f; + if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) kbdDelta.y -= 1.0f; } int Inferno::run() { - mWin->setFPSMode(); + // mWin->setFPSMode(); - while (true) { + Camera camera; + Mesh cornell; + cornell.loadOBJ("res/cornell-box.obj"); + cornell.ready(); + + Material basicMaterial("basic"); + Shader basicShader; + basicShader.load("res/shaders/basic.glsl")->link(); + basicMaterial.setGlShader(&basicShader); + cornell.setMaterial(&basicMaterial); + + mScene.addMesh(&cornell); + mScene.setCamera(&camera); + + mRasterRenderer.setScene(&mScene); + + while (true) + { if (!mWin->newFrame()) { break; } // UI - ImGuiID dockspace_id = ImGui::GetID("main"); + // ImGuiID dockspace_id = ImGui::GetID("main"); - // set the main window to the dockspace and then on the first launch set the preset - static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode; - if (ImGui::DockBuilderGetNode(dockspace_id) == NULL) { this->uiPreset(); } - ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); + // // set the main window to the dockspace and then on the first launch set the preset + // static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode; + // if (ImGui::DockBuilderGetNode(dockspace_id) == NULL) { this->uiPreset(); } + // ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags); - std::cout << mouseDelta.x << " " << mouseDelta.y << std::endl; - - ImGui::Begin("Preview"); - ImGui::End(); + this->input(); + camera.MouseMoved(mouseDelta); + camera.MoveCamera(kbdDelta); - ImGui::Begin("Render"); - ImGui::End(); + mRasterRenderer.draw(); - ImGui::Begin("Inferno HART"); - ImGui::End(); + + // ImGui::Begin("Preview"); + // ImGui::End(); + + // ImGui::Begin("Render"); + // ImGui::End(); + + // ImGui::Begin("Inferno HART"); + // ImGui::End(); GLenum err; while((err = glGetError()) != GL_NO_ERROR) { diff --git a/src/inferno.hpp b/src/inferno.hpp index 280f7b2..9cc6af3 100644 --- a/src/inferno.hpp +++ b/src/inferno.hpp @@ -1,6 +1,8 @@ #pragma once #include "graphics.hpp" +#include "preview_renderer/renderer.hpp" +#include "scene/scene.hpp" #include @@ -8,8 +10,6 @@ namespace inferno { class Window; -class RasterizeRenderer; -class Scene; class Inferno : public helpers::Singleton { @@ -27,8 +27,8 @@ public: glm::vec3 kbdDelta; private: - RasterizeRenderer* mRasterRenderer; - Scene* mScene; + RasterizeRenderer mRasterRenderer; + Scene mScene; private: Window* mWin; diff --git a/src/preview_renderer/renderer.cpp b/src/preview_renderer/renderer.cpp index bbc5582..650084a 100644 --- a/src/preview_renderer/renderer.cpp +++ b/src/preview_renderer/renderer.cpp @@ -1,7 +1,11 @@ #include "renderer.hpp" +#include "shader.hpp" + #include #include +#include +#include using namespace inferno; @@ -32,5 +36,21 @@ void RasterizeRenderer::prepare() void RasterizeRenderer::draw() { + for (Mesh* m : mCurrentScene->getRenderables()) + { + m->getMaterial()->getGlShader()->use(); + GLint uniTrans = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "model"); + glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f))); + GLint uniView = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "view"); + glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(mCurrentScene->getCamera()->GetViewMatrix())); + + GLint uniProj = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "proj"); + glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(mCurrentScene->getCamera()->GetProjectionMatrix())); + + glBindVertexArray(m->getVAO()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->getEBO()); + + glDrawElements(GL_TRIANGLES, m->getIndexCount(), GL_UNSIGNED_INT, 0); + } } diff --git a/src/preview_renderer/renderer.hpp b/src/preview_renderer/renderer.hpp index 7de4e8c..738db14 100644 --- a/src/preview_renderer/renderer.hpp +++ b/src/preview_renderer/renderer.hpp @@ -4,7 +4,6 @@ namespace inferno { -class Camera; class Scene; class RasterizeRenderer @@ -20,7 +19,6 @@ public: void draw(); private: - Camera* mCurrentCamera; Scene* mCurrentScene; }; diff --git a/src/preview_renderer/shader.cpp b/src/preview_renderer/shader.cpp index 871245e..53946b0 100644 --- a/src/preview_renderer/shader.cpp +++ b/src/preview_renderer/shader.cpp @@ -3,6 +3,13 @@ #include #include +inline std::string trim(std::string& str) +{ + str.erase(str.find_last_not_of(' ')+1); //suffixing spaces + str.erase(0, str.find_first_not_of(' ')); //prefixing spaces + return str; +} + static std::unordered_map Shader2Index = { {GL_VERTEX_SHADER, 0}, {GL_GEOMETRY_SHADER, 1}, @@ -18,20 +25,20 @@ std::string textFromFile(const std::filesystem::path& path) { } -_Shader::_Shader() +Shader::Shader() : mShaders({ GL_NONE, GL_NONE, GL_NONE}) , mProgram(0) { } -_Shader::~_Shader() { +Shader::~Shader() { for (int i = 0; i < 3; i++) { if (mShaders[i] == GL_NONE) continue; glDeleteShader(mShaders[i]); } } -std::shared_ptr<_Shader> _Shader::load(std::filesystem::path path) { +Shader* Shader::load(std::filesystem::path path) { assert(std::filesystem::exists(path)); @@ -49,6 +56,8 @@ std::shared_ptr<_Shader> _Shader::load(std::filesystem::path path) { def.def += loadedShaderSource[j]; } def.end = j; i = j; // advance i + def.def = trim(def.def); + def.key = trim(def.key); mDefinitions.push_back(def); } } @@ -63,6 +72,7 @@ std::shared_ptr<_Shader> _Shader::load(std::filesystem::path path) { if (type->def == "vertex") glType = GL_VERTEX_SHADER; if (type->def == "geometry") glType = GL_GEOMETRY_SHADER; if (type->def == "fragment") glType = GL_FRAGMENT_SHADER; + std::cout << "TYPE: " << type->def << " i " << glType << std::endl; assert(glType != GL_NONE); @@ -76,10 +86,10 @@ std::shared_ptr<_Shader> _Shader::load(std::filesystem::path path) { i++; } - return shared_from_this(); + return this; } -std::shared_ptr<_Shader> _Shader::link() { +Shader* Shader::link() { mProgram = glCreateProgram(); @@ -93,28 +103,34 @@ std::shared_ptr<_Shader> _Shader::link() { } glLinkProgram(mProgram); - return shared_from_this(); + return this; } -std::shared_ptr<_Shader> _Shader::use() { +Shader* Shader::use() { glUseProgram(mProgram); - return shared_from_this(); + return this; } -std::shared_ptr<_Shader> _Shader::unUse() { +Shader* Shader::unUse() { glUseProgram(0); - return shared_from_this(); + return this; } -void _Shader::addAttribute(const std::string& attribute) { +GLuint Shader::getProgram() +{ + return mProgram; +} + + +void Shader::addAttribute(const std::string& attribute) { mAttributes[attribute] = glGetAttribLocation(mProgram, attribute.c_str()); } -void _Shader::addUniform(const std::string& uniform) { +void Shader::addUniform(const std::string& uniform) { mUniformLocations[uniform] = glGetUniformLocation(mProgram, uniform.c_str()); } -bool _Shader::mCheckShader(GLuint uid) { +bool Shader::mCheckShader(GLuint uid) { GLint isCompiled = 0; glGetShaderiv(uid, GL_COMPILE_STATUS, &isCompiled); if(isCompiled == GL_FALSE) @@ -136,8 +152,8 @@ bool _Shader::mCheckShader(GLuint uid) { return true; } -std::vector _Shader::mGetKeys(std::string key) { - std::vector ret; +std::vector Shader::mGetKeys(std::string key) { + std::vector ret; for (const auto& p : mDefinitions) if (p.key == key) ret.push_back(&p); return ret; } diff --git a/src/preview_renderer/shader.hpp b/src/preview_renderer/shader.hpp index 6478cc6..f2661e3 100644 --- a/src/preview_renderer/shader.hpp +++ b/src/preview_renderer/shader.hpp @@ -10,18 +10,20 @@ namespace inferno { -class _Shader : public std::enable_shared_from_this<_Shader> { +class Shader { public: - _Shader(); - ~_Shader(); + Shader(); + ~Shader(); - std::shared_ptr<_Shader> preprocessorDefine(std::string statement); + Shader* preprocessorDefine(std::string statement); - std::shared_ptr<_Shader> load(std::filesystem::path path); - std::shared_ptr<_Shader> link(); + Shader* load(std::filesystem::path path); + Shader* link(); - std::shared_ptr<_Shader> use(); - std::shared_ptr<_Shader> unUse(); + Shader* use(); + Shader* unUse(); + + GLuint getProgram(); void addAttribute(const std::string& attribute); void addUniform(const std::string& uniform); @@ -51,8 +53,7 @@ private: std::string def; }; std::vector mDefinitions; - std::vector mGetKeys(std::string key); + std::vector mGetKeys(std::string key); }; -typedef std::shared_ptr<_Shader> Shader; } diff --git a/src/scene/camera.cpp b/src/scene/camera.cpp index 9c702a6..c6ebfd9 100644 --- a/src/scene/camera.cpp +++ b/src/scene/camera.cpp @@ -78,7 +78,10 @@ void Camera::UpdateProjection(int width, int height) void Camera::MoveCamera(glm::vec3 posDelta) { + if (glm::length(posDelta) == 0) return; + // Rotate by camera direction + glm::vec3 delta(0.0f); glm::mat2 rotate { cos(Yaw), -sin(Yaw), sin(Yaw), cos(Yaw) @@ -87,6 +90,8 @@ void Camera::MoveCamera(glm::vec3 posDelta) glm::vec2 f(0.0, 1.0); f = f * rotate; + delta = posDelta * glm::vec3(f.x, 0.0f, f.y); + // get current view matrix glm::mat4 mat = GetViewMatrix(); glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]); @@ -94,9 +99,9 @@ void Camera::MoveCamera(glm::vec3 posDelta) // 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; + Position.x += delta.x * CameraSpeed; + Position.z += delta.z * CameraSpeed; + Position.y += delta.y * CameraSpeed; // update the view matrix UpdateView(); @@ -104,6 +109,7 @@ void Camera::MoveCamera(glm::vec3 posDelta) void Camera::MouseMoved(glm::vec2 mouseDelta) { + if (glm::length(mouseDelta) == 0) return; // note that yaw and pitch must be converted to radians. // this is done in UpdateView() by glm::rotate Yaw += MouseSensitivity * (mouseDelta.x / 100); diff --git a/src/scene/material.cpp b/src/scene/material.cpp index e69de29..5c20b01 100644 --- a/src/scene/material.cpp +++ b/src/scene/material.cpp @@ -0,0 +1,26 @@ +#include + +#include "preview_renderer/shader.hpp" + +using namespace inferno; + +Material::Material(std::string name) + : mName(name) +{ + +} + +Material::~Material() +{ + +} + +void Material::setGlShader(Shader* shader) +{ + mGlShader = shader; +} + +Shader* Material::getGlShader() +{ + return mGlShader; +} diff --git a/src/scene/mesh.cpp b/src/scene/mesh.cpp index 39af479..c5d4fc3 100644 --- a/src/scene/mesh.cpp +++ b/src/scene/mesh.cpp @@ -23,7 +23,6 @@ void Mesh::loadOBJ(std::filesystem::path file) int vertCount = mObjLoader->getVertCount(); - for (int i = 0; i < vertCount; i += 3) { Vert vert; @@ -65,11 +64,10 @@ void Mesh::ready() // 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); + + spdlog::debug("MESH READY"); } GLuint Mesh::getVAO() @@ -86,3 +84,18 @@ GLuint Mesh::getEBO() { return mEBO; } + +int Mesh::getIndexCount() +{ + return mObjLoader->getIndexCount(); +} + +void Mesh::setMaterial(Material* mat) +{ + mMaterial = mat; +} + +Material* Mesh::getMaterial() +{ + return mMaterial; +} diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index e0a6db9..e2d14a4 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -1,6 +1,8 @@ #include #include +#include +#include using namespace inferno; @@ -14,7 +16,22 @@ Scene::~Scene() } -SceneObject* Scene::newObject() +void Scene::setCamera(Camera* camera) { - + mCurrentCamera = camera; +} + +Camera* Scene::getCamera() +{ + return mCurrentCamera; +} + +void Scene::addMesh(Mesh* mesh) +{ + mMeshs.push_back(mesh); +} + +const std::vector& Scene::getRenderables() +{ + return mMeshs; } diff --git a/src/window.cpp b/src/window.cpp index 35631a5..d4412dd 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -73,6 +73,11 @@ KeyCallback Window::getKeyCallback() bool Window::newFrame() { glfwPollEvents(); + if (mWinMode == WIN_MODE_FPS) + { + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + glfwSetCursorPos(window, (double)width / 2, (double)height / 2); + } if (glfwWindowShouldClose(window)) { return false; } glfwGetWindowSize(window, &width, &height); @@ -84,22 +89,16 @@ bool Window::newFrame() ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); - ImGui::Begin("main", nullptr, WINDOW_FLAGS); - ImGui::SetWindowPos(ImVec2(0, 0)); - ImGui::SetWindowSize(ImVec2(width, height)); + // ImGui::Begin("main", nullptr, WINDOW_FLAGS); + // ImGui::SetWindowPos(ImVec2(0, 0)); + // ImGui::SetWindowSize(ImVec2(width, height)); return true; } void Window::render() { - if (mWinMode == WIN_MODE_FPS) - { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); - glfwSetCursorPos(window, (double)width / 2, (double)height / 2); - } - - ImGui::End(); + // ImGui::End(); ImGui::Render(); auto io = ImGui::GetIO(); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);