From 2f4e0ebfac400a517c3bd88fe61ff1cfd35b0477 Mon Sep 17 00:00:00 2001 From: "Grayson Riffe (Laptop)" Date: Tue, 24 Aug 2021 12:31:15 -0500 Subject: [PATCH] Added Drawable, rewrote changing states, and organized class definitions and macros --- NothinFancy/NothinFancy.vcxproj | 2 + NothinFancy/NothinFancy.vcxproj.filters | 6 + NothinFancy/src/Application.cpp | 155 ++++++++++++----------- NothinFancy/src/Renderer/Drawable.cpp | 11 ++ NothinFancy/src/Renderer/Renderer.cpp | 6 +- NothinFancy/src/Renderer/Shader.cpp | 3 +- NothinFancy/src/Renderer/VertexArray.cpp | 12 +- NothinFancy/src/Utility.cpp | 8 +- NothinFancy/src/include/Application.h | 21 +-- NothinFancy/src/include/Drawable.h | 12 ++ NothinFancy/src/include/Renderer.h | 6 + NothinFancy/src/include/Utility.h | 8 +- 12 files changed, 141 insertions(+), 109 deletions(-) create mode 100644 NothinFancy/src/Renderer/Drawable.cpp create mode 100644 NothinFancy/src/include/Drawable.h diff --git a/NothinFancy/NothinFancy.vcxproj b/NothinFancy/NothinFancy.vcxproj index 6a553ae..b77e288 100644 --- a/NothinFancy/NothinFancy.vcxproj +++ b/NothinFancy/NothinFancy.vcxproj @@ -193,6 +193,7 @@ + @@ -203,6 +204,7 @@ + diff --git a/NothinFancy/NothinFancy.vcxproj.filters b/NothinFancy/NothinFancy.vcxproj.filters index 8342d6f..d9aa77b 100644 --- a/NothinFancy/NothinFancy.vcxproj.filters +++ b/NothinFancy/NothinFancy.vcxproj.filters @@ -39,6 +39,9 @@ Source Files + + Source Files + @@ -77,6 +80,9 @@ Header Files + + Header Files + diff --git a/NothinFancy/src/Application.cpp b/NothinFancy/src/Application.cpp index 2fcbf5b..e0eca42 100644 --- a/NothinFancy/src/Application.cpp +++ b/NothinFancy/src/Application.cpp @@ -12,7 +12,9 @@ namespace nf { Application::Application(Config& config) : m_currentConfig(config), m_wndPlacement{ sizeof(m_wndPlacement) }, - m_running(false) + m_running(false), + m_defaultStateAdded(false), + m_stateChange(false) { Log("Creating NF application"); Log("Width: " + std::to_string(m_currentConfig.width) + ", Height: " + std::to_string(m_currentConfig.height) + ", Fullscreen: " + std::to_string(m_currentConfig.fullscreen) + ", Title: " + m_currentConfig.title); @@ -38,28 +40,25 @@ namespace nf { SetClassLongPtr(m_window, GCLP_HCURSOR, (LONG_PTR)hCursor); } - void Application::addState(IGamestate* state, const char* stateName) { + void Application::addState(IGamestate* state,const std::string& stateName) { if (m_states.find(stateName) == m_states.end()) { m_states[stateName] = state; } - else { + else Error("State \"" + (std::string)stateName + (std::string)"\" already exists!"); - } } - void Application::addDefaultState(const char* stateName) { + void Application::addDefaultState(const std::string& stateName) { if (!m_defaultStateAdded) { if (m_states.find(stateName) != m_states.end()) { m_DefaultState = m_states[stateName]; m_defaultStateAdded = true; } - else { + else Error("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!"); - } } - else { + else Error("More than one default state defined!"); - } } void Application::run() { @@ -81,6 +80,13 @@ namespace nf { mainThread.join(); } + void Application::changeState(const std::string& stateName) { + if (m_states.find(stateName) == m_states.end()) + Error("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!"); + m_stateChange = true; + m_nextState = stateName; + } + void Application::showWindow(bool show) { if (show) ShowWindow(m_window, SW_SHOW); @@ -88,15 +94,8 @@ namespace nf { ShowWindow(m_window, SW_HIDE); } - void Application::changeState(const char* stateName) { - if (m_states.find(stateName) != m_states.end()) { - m_currentState->onExit(); - m_currentState = m_states[stateName]; - m_currentState->onEnter(this); - } - else { - Error("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!"); - } + const HWND& Application::getWindow() { + return m_window; } void Application::changeConfig(const Config& in) { @@ -113,10 +112,6 @@ namespace nf { SetWindowPos(m_window, HWND_TOP, x, y, in.width, in.height, SWP_NOOWNERZORDER | SWP_FRAMECHANGED); } - const HWND& Application::getWindow() { - return m_window; - } - const Config& Application::getConfig() const { return m_currentConfig; } @@ -134,41 +129,6 @@ namespace nf { } } - void Application::startIntroState() { - m_sIntro = new IntroGamestate; - m_sIntro->onEnter(this); - m_currentState = m_sIntro; - } - - void Application::runMainGameThread() { - m_renderer = new Renderer(this); - startIntroState(); - std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); - const std::chrono::duration wait_time = std::chrono::nanoseconds(1000000000 / 60); - auto next_time = start_time + wait_time; - while (m_running) { - start_time = std::chrono::steady_clock::now(); - m_currentState->update(); - m_currentState->render(); - m_renderer->doFrame(); - m_frames++; - m_fpsClock2 = std::chrono::steady_clock::now(); - m_fpsDuration = m_fpsClock2 - m_fpsClock1; - if (m_fpsDuration.count() >= 1.0) { - m_FPS = m_frames; - m_frames = 0; - Log("FPS: " + std::to_string(m_FPS)); - m_fpsClock1 = std::chrono::steady_clock::now(); - //TODO: Rework calculating FPS - } - std::this_thread::sleep_until(next_time); - m_deltaTime = (double)(std::chrono::steady_clock::now() - start_time).count(); - next_time += wait_time; - } - m_currentState->onExit(); - delete m_renderer; - } - void Application::registerWindowClass() { if (!FindWindow(L"NFClass", NULL)) { m_wclassName = L"NFClass"; @@ -180,25 +140,8 @@ namespace nf { wclass.lpfnWndProc = Application::WindowProc; RegisterClass(&wclass); } - else { + else Error("Cannot run two NF applications at once!"); - } - } - //TODO: Test fullscreen graphcis - void Application::toggleFullscreen() { - DWORD wndStyle = GetWindowLong(m_window, GWL_STYLE); - if (wndStyle & WS_OVERLAPPEDWINDOW) { - GetWindowPlacement(m_window, &m_wndPlacement); - MONITORINFO mi = { sizeof(mi) }; - GetMonitorInfo(MonitorFromWindow(m_window, MONITOR_DEFAULTTOPRIMARY), &mi); - SetWindowLong(m_window, GWL_STYLE, wndStyle & ~WS_OVERLAPPEDWINDOW); - SetWindowPos(m_window, HWND_TOP, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, SWP_NOOWNERZORDER | SWP_FRAMECHANGED); - } - else { - SetWindowLong(m_window, GWL_STYLE, m_defaultWindowStyle); - SetWindowPlacement(m_window, &m_wndPlacement); - SetWindowPos(m_window, NULL, 0, 0, m_currentConfig.width, m_currentConfig.height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); - } } RECT Application::getWindowRect() const { @@ -222,6 +165,66 @@ namespace nf { x = monX - (m_currentConfig.width / 2); y = monY - (m_currentConfig.height / 2); } + //TODO: Test fullscreen graphcis + void Application::toggleFullscreen() { + DWORD wndStyle = GetWindowLong(m_window, GWL_STYLE); + if (wndStyle & WS_OVERLAPPEDWINDOW) { + GetWindowPlacement(m_window, &m_wndPlacement); + MONITORINFO mi = { sizeof(mi) }; + GetMonitorInfo(MonitorFromWindow(m_window, MONITOR_DEFAULTTOPRIMARY), &mi); + SetWindowLong(m_window, GWL_STYLE, wndStyle & ~WS_OVERLAPPEDWINDOW); + SetWindowPos(m_window, HWND_TOP, mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top, SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } + else { + SetWindowLong(m_window, GWL_STYLE, m_defaultWindowStyle); + SetWindowPlacement(m_window, &m_wndPlacement); + SetWindowPos(m_window, NULL, 0, 0, m_currentConfig.width, m_currentConfig.height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_FRAMECHANGED); + } + } + + void Application::runMainGameThread() { + m_renderer = new Renderer(this); + startIntroState(); + std::chrono::steady_clock::time_point start_time = std::chrono::steady_clock::now(); + const std::chrono::duration wait_time = std::chrono::nanoseconds(1000000000 / 60); + auto next_time = start_time + wait_time; + while (m_running) { + start_time = std::chrono::steady_clock::now(); + m_currentState->update(); + m_currentState->render(); + m_renderer->doFrame(); + m_frames++; + if (m_stateChange) + doStateChange(); + m_fpsClock2 = std::chrono::steady_clock::now(); + m_fpsDuration = m_fpsClock2 - m_fpsClock1; + if (m_fpsDuration.count() >= 1.0) { + m_FPS = m_frames; + m_frames = 0; + Log("FPS: " + std::to_string(m_FPS)); + m_fpsClock1 = std::chrono::steady_clock::now(); + //TODO: Rework calculating FPS + } + std::this_thread::sleep_until(next_time); + m_deltaTime = (double)(std::chrono::steady_clock::now() - start_time).count(); + next_time += wait_time; + } + m_currentState->onExit(); + delete m_renderer; + } + + void Application::startIntroState() { + m_sIntro = new IntroGamestate; + m_sIntro->onEnter(this); + m_currentState = m_sIntro; + } + + void Application::doStateChange() { + m_stateChange = false; + m_currentState->onExit(); + m_currentState = m_states[m_nextState]; + m_currentState->onEnter(this); + } LRESULT CALLBACK Application::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { Application* app = (Application*)GetProp(hWnd, L"App"); @@ -294,7 +297,7 @@ namespace nf { Application::~Application() { Log("Exiting NF application"); - for (std::pair state : m_states) { + for (std::pair state : m_states) { IGamestate* curr = state.second; delete curr; } diff --git a/NothinFancy/src/Renderer/Drawable.cpp b/NothinFancy/src/Renderer/Drawable.cpp new file mode 100644 index 0000000..5ee25a7 --- /dev/null +++ b/NothinFancy/src/Renderer/Drawable.cpp @@ -0,0 +1,11 @@ +#include "Drawable.h" + +namespace nf { + Drawable::Drawable() { + + } + + Drawable::~Drawable() { + + } +} \ No newline at end of file diff --git a/NothinFancy/src/Renderer/Renderer.cpp b/NothinFancy/src/Renderer/Renderer.cpp index fa22db1..c89c77d 100644 --- a/NothinFancy/src/Renderer/Renderer.cpp +++ b/NothinFancy/src/Renderer/Renderer.cpp @@ -33,9 +33,8 @@ namespace nf { m_hglrc = wglCreateContext(m_hdc); wglMakeCurrent(m_hdc, m_hglrc); glewExperimental = GL_TRUE; - if (glewInit() != GLEW_OK) { + if (glewInit() != GLEW_OK) Error("Could not initialize GLEW!"); - } const int attrib[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 3, @@ -57,9 +56,8 @@ namespace nf { SwapBuffers(m_hdc); GLenum err = glGetError(); - if (err != GL_NO_ERROR) { + if (err != GL_NO_ERROR) Error("OpenGL error " + std::to_string(err)); - } } Renderer::~Renderer() { diff --git a/NothinFancy/src/Renderer/Shader.cpp b/NothinFancy/src/Renderer/Shader.cpp index 4519e5e..ada799e 100644 --- a/NothinFancy/src/Renderer/Shader.cpp +++ b/NothinFancy/src/Renderer/Shader.cpp @@ -49,9 +49,8 @@ namespace nf { //TODO: Create overloaded setUniform function void Shader::getUniformLocation(const char* uniformName) { unsigned int loc = glGetUniformLocation(m_id, uniformName); - if (loc == -1) { + if (loc == -1) Error("Uniform \"" + (std::string)uniformName + "\" does not exist!"); - } m_uniformLocations[uniformName] = loc; } diff --git a/NothinFancy/src/Renderer/VertexArray.cpp b/NothinFancy/src/Renderer/VertexArray.cpp index 9ee84e8..397ac9c 100644 --- a/NothinFancy/src/Renderer/VertexArray.cpp +++ b/NothinFancy/src/Renderer/VertexArray.cpp @@ -14,9 +14,8 @@ namespace nf { } void VertexArray::addBuffer(const void* data, const size_t size) { - if (!m_lastBufferHasLayout) { + if (!m_lastBufferHasLayout) Error("Buffer added to vertex array has no layout!"); - } m_buffers.push_back(new VertexBuffer(data, size)); m_buffers.back()->bind(); m_lastBufferHasLayout = false; @@ -25,9 +24,8 @@ namespace nf { template<> void VertexArray::push(unsigned int count) { - if (m_lastBufferHasLayout) { + if (m_lastBufferHasLayout) Error("Tried to modify a vertex array's buffer after the layout was final!"); - } m_lastBufferLayout.push_back({ GL_FLOAT, count, GL_FALSE }); m_lastStride += count * sizeof(GL_FLOAT); } @@ -45,12 +43,10 @@ namespace nf { } void VertexArray::bind(unsigned int buffer) { - if (m_buffers.empty()) { + if (m_buffers.empty()) Error("No buffers and layouts added to vertex array before being bound!"); - } - if (!m_lastBufferHasLayout) { + if (!m_lastBufferHasLayout) Error("Buffer added to vertex array has no layout!"); - } glBindVertexArray(m_id); } diff --git a/NothinFancy/src/Utility.cpp b/NothinFancy/src/Utility.cpp index 4df4592..f840c18 100644 --- a/NothinFancy/src/Utility.cpp +++ b/NothinFancy/src/Utility.cpp @@ -84,10 +84,8 @@ namespace nf { } std::ofstream out; out.open(filename); - if (!out) { + if (!out) Error("File \"" + (std::string)filename + (std::string)"\" could not be written!"); - return false; - } out << in; out.close(); return true; @@ -96,10 +94,8 @@ namespace nf { std::string readFile(const char* filename) { std::ifstream in; in.open(filename); - if (!in) { + if (!in) Error("File \"" + (std::string)filename + (std::string)"\" could not be read!"); - return NULL; - } std::stringstream ss; ss << in.rdbuf(); return ss.str(); diff --git a/NothinFancy/src/include/Application.h b/NothinFancy/src/include/Application.h index 732f529..44bc629 100644 --- a/NothinFancy/src/include/Application.h +++ b/NothinFancy/src/include/Application.h @@ -17,11 +17,11 @@ namespace nf { void setWindowIcon(HANDLE hIcon); void setWindowCursor(HCURSOR hCursor); - void addState(IGamestate* state, const char* stateName); - void addDefaultState(const char* stateName); + void addState(IGamestate* state, const std::string& stateName); + void addDefaultState(const std::string& stateName); void run(); + void changeState(const std::string& stateName); void showWindow(bool show); - void changeState(const char* stateName); const HWND& getWindow(); void changeConfig(const Config& in); const Config& getConfig() const; @@ -30,12 +30,13 @@ namespace nf { ~Application(); private: - void startIntroState(); - void runMainGameThread(); void registerWindowClass(); - void toggleFullscreen(); 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); @@ -56,13 +57,15 @@ namespace nf { const double m_minFrametime = 1.0 / m_targetFPS; int m_FPS; - //Inactive states states to potentially be active during the Application's lifetime + //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; + std::unordered_map m_states; IntroGamestate* m_sIntro; IGamestate* m_DefaultState; - bool m_defaultStateAdded = false; + bool m_defaultStateAdded; IGamestate* 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]; diff --git a/NothinFancy/src/include/Drawable.h b/NothinFancy/src/include/Drawable.h new file mode 100644 index 0000000..2470563 --- /dev/null +++ b/NothinFancy/src/include/Drawable.h @@ -0,0 +1,12 @@ +#pragma once + +namespace nf { + class Drawable { + public: + Drawable(); + + ~Drawable(); + private: + + }; +} \ No newline at end of file diff --git a/NothinFancy/src/include/Renderer.h b/NothinFancy/src/include/Renderer.h index b4d25ac..6715cc0 100644 --- a/NothinFancy/src/include/Renderer.h +++ b/NothinFancy/src/include/Renderer.h @@ -1,6 +1,9 @@ #pragma once +#include #include +#include "Drawable.h" + namespace nf { class Application; @@ -16,5 +19,8 @@ namespace nf { HDC m_hdc; HGLRC m_hglrc; + + std::vector m_lGame; + std::vector m_lUI; }; } \ No newline at end of file diff --git a/NothinFancy/src/include/Utility.h b/NothinFancy/src/include/Utility.h index 6dfc601..dcd9705 100644 --- a/NothinFancy/src/include/Utility.h +++ b/NothinFancy/src/include/Utility.h @@ -16,8 +16,8 @@ namespace nf { //Prints a nicely-formatted message complete with a timestamp #define Log(x) nf::Debug::LogImp(x) //Prints error message and breaks the debugger -#define Error(x) nf::Debug::ErrorImp(x,__FILENAME__, __LINE__);\ -__debugbreak(); +#define Error(x) {nf::Debug::ErrorImp(x,__FILENAME__, __LINE__);\ +__debugbreak();} class Debug { private: @@ -34,8 +34,8 @@ __debugbreak(); #else #define DEBUGINIT #define Log(x) -#define Error(x) MessageBox(FindWindow(L"NFClass", NULL), toWide(x), L"NF Engine Error", MB_OK | MB_ICONERROR);\ -std::exit(-1) +#define Error(x) {MessageBox(FindWindow(L"NFClass", NULL), toWide(x), L"NF Engine Error", MB_OK | MB_ICONERROR);\ +std::exit(-1);} #endif const wchar_t* toWide(const char* in);