diff --git a/Game/src/MainState.cpp b/Game/src/MainState.cpp index 5bd7dcc..5d4f146 100644 --- a/Game/src/MainState.cpp +++ b/Game/src/MainState.cpp @@ -3,16 +3,20 @@ MainState::MainState(nf::Application* app) : Gamestate(app) { + } void MainState::onEnter() { Log("MainState onEnter!"); + } void MainState::update(double deltaTime) { + } void MainState::render(nf::Renderer& renderer) { + } void MainState::onExit() { diff --git a/NothinFancy/NothinFancy.vcxproj b/NothinFancy/NothinFancy.vcxproj index f2c0745..182acac 100644 --- a/NothinFancy/NothinFancy.vcxproj +++ b/NothinFancy/NothinFancy.vcxproj @@ -94,7 +94,7 @@ Level3 true - GLEW_STATIC;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + NFENGINE;GLEW_STATIC;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir)src\include\;$(ProjectDir)dep\include\ $(IntDir)obj\ @@ -123,7 +123,7 @@ true true true - GLEW_STATIC;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + NFENGINE;GLEW_STATIC;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir)src\include\;$(ProjectDir)dep\include\ $(IntDir)obj\ @@ -152,7 +152,7 @@ Level3 true - GLEW_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + NFENGINE;GLEW_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir)src\include\;$(ProjectDir)dep\include\ $(IntDir)obj\ @@ -181,7 +181,7 @@ true true true - GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + NFENGINE;GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(ProjectDir)src\include\;$(ProjectDir)dep\include\ $(IntDir)obj\ @@ -211,6 +211,7 @@ + @@ -220,6 +221,7 @@ + diff --git a/NothinFancy/NothinFancy.vcxproj.filters b/NothinFancy/NothinFancy.vcxproj.filters index bdf998b..e1365df 100644 --- a/NothinFancy/NothinFancy.vcxproj.filters +++ b/NothinFancy/NothinFancy.vcxproj.filters @@ -48,6 +48,9 @@ Source Files + + Source Files + @@ -95,6 +98,9 @@ Header Files + + Header Files + diff --git a/NothinFancy/src/Application.cpp b/NothinFancy/src/Application.cpp index b35d95f..ef17049 100644 --- a/NothinFancy/src/Application.cpp +++ b/NothinFancy/src/Application.cpp @@ -211,6 +211,7 @@ namespace nf { std::this_thread::sleep_until(next_time); m_deltaTime = (double)(std::chrono::steady_clock::now() - start_time).count(); next_time += wait_time; + //TODO: Redo FPS AGAIN like how I did it in PongClone } m_currentState->onExit(); delete m_renderer; diff --git a/NothinFancy/src/Renderer/Drawable/Drawable.cpp b/NothinFancy/src/Renderer/Drawable/Drawable.cpp index 6b2607c..faf20e0 100644 --- a/NothinFancy/src/Renderer/Drawable/Drawable.cpp +++ b/NothinFancy/src/Renderer/Drawable/Drawable.cpp @@ -4,11 +4,7 @@ namespace nf { Drawable::Drawable() { - Log("Drawable constructor"); - } - Drawable::DrawableType Drawable::identity() { - return DrawableType::NF_NONE; } void Drawable::bind() { @@ -22,6 +18,5 @@ namespace nf { Drawable::~Drawable() { delete m_vao; delete m_ib; - delete m_shader; } } \ No newline at end of file diff --git a/NothinFancy/src/Renderer/Drawable/Entity.cpp b/NothinFancy/src/Renderer/Drawable/Entity.cpp new file mode 100644 index 0000000..f16be9a --- /dev/null +++ b/NothinFancy/src/Renderer/Drawable/Entity.cpp @@ -0,0 +1,57 @@ +#include "Entity.h" + +namespace nf { + Entity::Entity() : + m_position(0.0), + m_rotation(0.0), + m_scale(1.0) + { + + } + + void Entity::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount) { + m_model = new Model; + m_model->create(vertexBufferData, vertexBufferSize, indexBufferData, indexBufferCount); + } + + void Entity::setLocation(float x, float y, float z) { + m_position = { x, y, z }; + } + + void Entity::setRotation(float x, float y, float z) { + m_rotation = { x, y, z }; + } + + void Entity::setScale(float x) { + m_rotation = { x, x, x }; + } + + void Entity::setScale(float x, float y, float z) { + m_scale = { x, y, z }; + } + + void Entity::bind(Shader* shader) { + m_model->bind(); + shader->bind(); + setModelMatrix(shader); + } + + Model* Entity::getModel() const { + return m_model; + } + + void Entity::setModelMatrix(Shader* shader) { + glm::mat4 model(1.0f); + model = glm::translate(model, glm::vec3(m_position.x, m_position.y, m_position.z)); + model = glm::rotate(model, glm::radians(m_rotation.x), glm::vec3(1.0, 0.0, 0.0)); + model = glm::rotate(model, glm::radians(m_rotation.y), glm::vec3(0.0, 1.0, 0.0)); + model = glm::rotate(model, glm::radians(m_rotation.z), glm::vec3(0.0, 0.0, 1.0)); + model = glm::scale(model, glm::vec3(m_scale.x, m_scale.y, m_scale.z)); + //TODO: fill out model matrix + shader->setUniform("model", model); + } + + Entity::~Entity() { + + } +} \ No newline at end of file diff --git a/NothinFancy/src/Renderer/Drawable/Model.cpp b/NothinFancy/src/Renderer/Drawable/Model.cpp index 06e8383..63f11d5 100644 --- a/NothinFancy/src/Renderer/Drawable/Model.cpp +++ b/NothinFancy/src/Renderer/Drawable/Model.cpp @@ -6,19 +6,13 @@ namespace nf { Model::Model() { } - void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const char* vertexShader, const char* fragmentShader) { + void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount) { m_vao = new VertexArray; m_vao->addBuffer(vertexBufferData, vertexBufferSize); m_vao->push(2); //TODO: Change this to 3 m_vao->finishBufferLayout(); m_ib = new IndexBuffer(indexBufferData, indexBufferCount); - if (vertexShader && fragmentShader) - m_shader = new Shader(vertexShader, fragmentShader); - } - - Drawable::DrawableType Model::identity() { - return DrawableType::NF_GAME; } void Model::bind() { @@ -26,16 +20,6 @@ namespace nf { Error("Tried to bind uninitialized model!"); m_vao->bind(); m_ib->bind(); - if (m_shader) { - m_shader->bind(); - //TODO: Set uniforms here such as position and texture - } - } - - bool Model::hasCustomShader() { - if (m_shader) - return true; - return false; } Model::~Model() { diff --git a/NothinFancy/src/Renderer/Renderer.cpp b/NothinFancy/src/Renderer/Renderer.cpp index 8b9b28e..4bf9944 100644 --- a/NothinFancy/src/Renderer/Renderer.cpp +++ b/NothinFancy/src/Renderer/Renderer.cpp @@ -54,37 +54,36 @@ namespace nf { glClearColor(0.0f, 0.0f, 0.0f, 1.0f); Win32Res vs(IDR_DEFAULTVERTEX); - m_defaultVertex = (const char*)vs.ptr; + const char* defaultVertex = (const char*)vs.ptr; Win32Res fs(IDR_DEFAULTFRAGMENT); - m_defaultFragment = (const char*)fs.ptr; - m_defaultShader = new Shader(m_defaultVertex, m_defaultFragment); + const char* defaultFragment = (const char*)fs.ptr; + if (defaultVertex == nullptr || defaultFragment == nullptr) + Error("Default engine resources not found! Please link nf.res to your application!"); + m_defaultShader = new Shader(defaultVertex, defaultFragment); } - void Renderer::render(Drawable& in) { + void Renderer::render(Entity& in) { if (&in == nullptr) - Error("Drawable object tried to render before being constructed!"); - if (in.identity() == Drawable::DrawableType::NF_UI) - m_lUI.push_back(&in); - else - m_lGame.push_back(&in); + Error("Tried to render Entity before being created!"); + m_lGame.push_back(&in); } void Renderer::doFrame() { glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - for (Drawable* draw : m_lGame) { - Model& curr = (Model&)*draw; - curr.bind(); - if (!curr.hasCustomShader()) - m_defaultShader->bind(); - glDrawElements(GL_TRIANGLES, curr.getIndexCount(), GL_UNSIGNED_INT, nullptr); + for (Entity* draw : m_lGame) { + Entity& curr = *draw; + curr.bind(m_defaultShader); + glDrawElements(GL_TRIANGLES, curr.getModel()->getIndexCount(), GL_UNSIGNED_INT, nullptr); } + m_lGame.clear(); for (Drawable* draw : m_lUI) { Drawable& curr = *draw; } + m_lUI.clear(); SwapBuffers(m_hdc); diff --git a/NothinFancy/src/Renderer/Shader.cpp b/NothinFancy/src/Renderer/Shader.cpp index beb8c4b..64f4e8c 100644 --- a/NothinFancy/src/Renderer/Shader.cpp +++ b/NothinFancy/src/Renderer/Shader.cpp @@ -49,7 +49,13 @@ namespace nf { Shader::current = m_id; } } - //TODO: Create overloaded setUniform function + + void Shader::setUniform(const char* name, glm::mat4& data) { + if (m_uniformLocations.find(name) != m_uniformLocations.end()) + getUniformLocation(name); + glUniformMatrix4fv(m_uniformLocations[name], 1, GL_FALSE, glm::value_ptr(data)); + } + void Shader::getUniformLocation(const char* uniformName) { unsigned int loc = glGetUniformLocation(m_id, uniformName); if (loc == -1) diff --git a/NothinFancy/src/include/Drawable.h b/NothinFancy/src/include/Drawable.h index 7a6d13e..86f3bfa 100644 --- a/NothinFancy/src/include/Drawable.h +++ b/NothinFancy/src/include/Drawable.h @@ -6,13 +6,8 @@ namespace nf { class Drawable { public: - enum class DrawableType { - NF_NONE, NF_GAME, NF_UI - }; - //TODO: Construct using Shader code and data from obj Drawable(); - virtual DrawableType identity(); virtual void bind(); unsigned int getIndexCount(); @@ -20,6 +15,5 @@ namespace nf { protected: VertexArray* m_vao; IndexBuffer* m_ib; - Shader* m_shader; }; } \ No newline at end of file diff --git a/NothinFancy/src/include/Entity.h b/NothinFancy/src/include/Entity.h new file mode 100644 index 0000000..39ef8d0 --- /dev/null +++ b/NothinFancy/src/include/Entity.h @@ -0,0 +1,34 @@ +#pragma once +#include "Model.h" + +namespace nf { + class Entity { + struct Vec3 { + Vec3(float x1) : x(x1), y(x1), z(x1) {} + Vec3(float x1, float y1, float z1) : x(x1), y(y1), z(z1) {} + float x, y, z; + }; + public: + Entity(); + + void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount); + //TODO: Do this using loaded assets somehow + void setLocation(float x, float y, float z); + void setRotation(float x, float y, float z); + void setScale(float x); + void setScale(float x, float y, float z); + + void bind(Shader* shader); + Model* getModel() const; + + ~Entity(); + private: + void setModelMatrix(Shader* shader); + + Model* m_model; + + Vec3 m_position; + Vec3 m_rotation; + Vec3 m_scale; + }; +} \ No newline at end of file diff --git a/NothinFancy/src/include/Model.h b/NothinFancy/src/include/Model.h index 841d22c..5295236 100644 --- a/NothinFancy/src/include/Model.h +++ b/NothinFancy/src/include/Model.h @@ -1,4 +1,9 @@ #pragma once +#ifdef NFENGINE +#include "glm/glm.hpp" +#include "glm/gtc/matrix_transform.hpp" +#endif + #include "Drawable.h" namespace nf { @@ -6,10 +11,8 @@ namespace nf { public: Model(); - void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const char* vertexShader = nullptr, const char* fragmentShader = nullptr); - DrawableType identity() override; + void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount); void bind() override; - bool hasCustomShader(); ~Model(); private: diff --git a/NothinFancy/src/include/NothinFancy.h b/NothinFancy/src/include/NothinFancy.h index f76b396..15f0fa8 100644 --- a/NothinFancy/src/include/NothinFancy.h +++ b/NothinFancy/src/include/NothinFancy.h @@ -1,5 +1,135 @@ //TODO: Rework this file to only contain functions the frontend will need to access -#include "Application.h" +#pragma once +#include +#include +#include + +#include "Config.h" +#include "IntroGamestate.h" + +namespace nf { + class Drawable; + class Shader; + class Model; + + class Entity { + struct Vec3 { + Vec3(float x1) : x(x1), y(x1), z(x1) {} + Vec3(float x1, float y1, float z1) : x(x1), y(y1), z(z1) {} + float x, y, z; + }; + public: + Entity(); + + void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount); + //TODO: Do this using loaded assets somehow + void setLocation(float x, float y, float z); + void setRotation(float x, float y, float z); + void setScale(float x); + void setScale(float x, float y, float z); + + void bind(Shader* shader); + Model* getModel() const; + + ~Entity(); + private: + void setModelMatrix(Shader* shader); + + Model* m_model; + + Vec3 m_position; + Vec3 m_rotation; + Vec3 m_scale; + }; + + class Renderer { + public: + Renderer(Application* app); + + void render(Entity& in); + + void doFrame(); + + ~Renderer(); + private: + Application* m_app; + + HDC m_hdc; + HGLRC m_hglrc; + + std::vector m_lGame; + std::vector m_lUI; + const char* m_defaultVertex; + const char* m_defaultFragment; + Shader* m_defaultShader; + }; + + class Application { + public: + Application(Config& conf); + Application() = delete; + Application(Application& other) = delete; + + void setWindowIcon(HANDLE hIcon); + void setWindowCursor(HCURSOR hCursor); + Renderer* getRenderer() const; + void addState(Gamestate* state, const std::string& stateName); + void addDefaultState(const std::string& stateName); + void run(); + void changeState(const std::string& stateName); + void showWindow(bool show); + const HWND& getWindow(); + void changeConfig(const Config& in); + const Config& getConfig() const; + int getFPS() const; + bool isInput(unsigned int code); + + ~Application(); + private: + void registerWindowClass(); + RECT getWindowRect() const; + void calculateNewWindowPos(int& x, int& y); + void toggleFullscreen(); + void runMainGameThread(); + void startIntroState(); + void doStateChange(); + + static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + Config m_currentConfig; + bool m_running; + HINSTANCE m_hInst; + LPCWSTR m_wclassName; + HWND m_window; + LONG m_defaultWindowStyle; + int m_altWidth, m_altHeight; + + std::chrono::duration m_fpsDuration; + double m_deltaTime; + std::chrono::steady_clock::time_point m_fpsClock1 = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point m_fpsClock2 = m_fpsClock1; + int m_frames; + const int m_targetFPS = 60; + const double m_minFrametime = 1.0 / m_targetFPS; + int m_FPS; + + //Inactive states to potentially be active during the Application's lifetime + //Mapped to const char* to be referenced later in the frontend + std::unordered_map m_states; + Gamestate* m_sIntro; + Gamestate* m_DefaultState; + bool m_defaultStateAdded; + Gamestate* m_currentState; + bool m_stateChange; + std::string m_nextState; + + //Array of booleans that represent keyboard and mouse input minus the scrollwheel + bool m_input[164]; + + //Renderer object to use OpenGL to render the current state + Renderer* m_renderer; + }; +} #include "Input.h" #include "Utility.h" \ No newline at end of file diff --git a/NothinFancy/src/include/Renderer.h b/NothinFancy/src/include/Renderer.h index 1c1cdc3..9c4b1e5 100644 --- a/NothinFancy/src/include/Renderer.h +++ b/NothinFancy/src/include/Renderer.h @@ -2,7 +2,7 @@ #include #include -#include "Model.h" +#include "Entity.h" namespace nf { class Application; @@ -11,7 +11,8 @@ namespace nf { public: Renderer(Application* app); - void render(Drawable& in); + void render(Entity& in); + //TODO: Create second render function for UIElements void doFrame(); @@ -22,10 +23,8 @@ namespace nf { HDC m_hdc; HGLRC m_hglrc; - std::vector m_lGame; + std::vector m_lGame; std::vector m_lUI; - const char* m_defaultVertex; - const char* m_defaultFragment; Shader* m_defaultShader; }; } \ No newline at end of file diff --git a/NothinFancy/src/include/Shader.h b/NothinFancy/src/include/Shader.h index 73171a2..3f34082 100644 --- a/NothinFancy/src/include/Shader.h +++ b/NothinFancy/src/include/Shader.h @@ -1,5 +1,9 @@ #pragma once #include +#ifdef NFENGINE +#include "glm/glm.hpp" +#include "glm/gtc/type_ptr.hpp" +#endif namespace nf { class Shader { @@ -7,12 +11,14 @@ namespace nf { Shader(const char* vertexSource, const char* fragmentSource); void bind(); - void getUniformLocation(const char* uniformName); + void setUniform(const char* name, glm::mat4& data); static unsigned int current; ~Shader(); private: + void getUniformLocation(const char* uniformName); + unsigned int m_id; std::unordered_map m_uniformLocations; }; diff --git a/notes.txt b/notes.txt index 630665b..91584c4 100644 --- a/notes.txt +++ b/notes.txt @@ -15,7 +15,7 @@ Remember to use tasks (//TODO: ) *Engine (Name?) "Nothin' Fancy" *Separate project *Namespaced -Refactor NothinFancy.h to ONLY include stuff the frontend needs +Refactor NothinFancy.h to ONLY include stuff the frontend needs (Does deleteing uneeded public funcitons do anything?) *AND get rid of NFENGINE *High CPU usage? *Debug and log system @@ -24,6 +24,7 @@ Refactor NothinFancy.h to ONLY include stuff the frontend needs *Alt-Enter *File IO functions *Keyboard and mouse click input +Check for memory leaks in deconstructors Separate Model and UIElement from Drawable Entity and Camera classes Mouse position input