Added Drawable, rewrote changing states, and organized class definitions and macros
This commit is contained in:
parent
1f6bb4630c
commit
2f4e0ebfac
@ -193,6 +193,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\Application.cpp" />
|
||||
<ClCompile Include="src\IntroGamestate.cpp" />
|
||||
<ClCompile Include="src\Renderer\Drawable.cpp" />
|
||||
<ClCompile Include="src\Renderer\IndexBuffer.cpp" />
|
||||
<ClCompile Include="src\Renderer\Renderer.cpp" />
|
||||
<ClCompile Include="src\Renderer\Shader.cpp" />
|
||||
@ -203,6 +204,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\include\Application.h" />
|
||||
<ClInclude Include="src\include\Config.h" />
|
||||
<ClInclude Include="src\include\Drawable.h" />
|
||||
<ClInclude Include="src\include\IGamestate.h" />
|
||||
<ClInclude Include="src\include\IndexBuffer.h" />
|
||||
<ClInclude Include="src\include\IntroGamestate.h" />
|
||||
|
@ -39,6 +39,9 @@
|
||||
<ClCompile Include="src\Renderer\Shader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\Renderer\Drawable.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\include\Config.h">
|
||||
@ -77,6 +80,9 @@
|
||||
<ClInclude Include="src\include\Shader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\include\Drawable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Natvis Include="NatvisFile.natvis" />
|
||||
|
@ -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<double> 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<double> 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<const char*, IGamestate*> state : m_states) {
|
||||
for (std::pair<std::string, IGamestate*> state : m_states) {
|
||||
IGamestate* curr = state.second;
|
||||
delete curr;
|
||||
}
|
||||
|
11
NothinFancy/src/Renderer/Drawable.cpp
Normal file
11
NothinFancy/src/Renderer/Drawable.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include "Drawable.h"
|
||||
|
||||
namespace nf {
|
||||
Drawable::Drawable() {
|
||||
|
||||
}
|
||||
|
||||
Drawable::~Drawable() {
|
||||
|
||||
}
|
||||
}
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<float>(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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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<const char*, IGamestate*> m_states;
|
||||
std::unordered_map<std::string, IGamestate*> 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];
|
||||
|
12
NothinFancy/src/include/Drawable.h
Normal file
12
NothinFancy/src/include/Drawable.h
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
namespace nf {
|
||||
class Drawable {
|
||||
public:
|
||||
Drawable();
|
||||
|
||||
~Drawable();
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <Windows.h>
|
||||
|
||||
#include "Drawable.h"
|
||||
|
||||
namespace nf {
|
||||
class Application;
|
||||
|
||||
@ -16,5 +19,8 @@ namespace nf {
|
||||
|
||||
HDC m_hdc;
|
||||
HGLRC m_hglrc;
|
||||
|
||||
std::vector<Drawable*> m_lGame;
|
||||
std::vector<Drawable*> m_lUI;
|
||||
};
|
||||
}
|
@ -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);
|
||||
|
Reference in New Issue
Block a user