Reworked gamestates to reset NF objects when exiting states; Intro state + fading is now based on delta time

This commit is contained in:
Grayson Riffe (Desktop) 2021-09-08 02:09:20 -05:00
parent 6e3a576fef
commit 2d3b3653ff
29 changed files with 260 additions and 108 deletions

View File

@ -230,6 +230,7 @@
<ClInclude Include="src\include\Input.h" />
<ClInclude Include="src\include\Light.h" />
<ClInclude Include="src\include\Model.h" />
<ClInclude Include="src\include\NFObject.h" />
<ClInclude Include="src\include\NothinFancy.h" />
<ClInclude Include="src\include\Renderer.h" />
<ClInclude Include="src\include\Shader.h" />

View File

@ -146,6 +146,9 @@
<ClInclude Include="src\include\Cubemap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\include\NFObject.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Natvis Include="NatvisFile.natvis" />

View File

@ -18,6 +18,9 @@ namespace nf {
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);
if (getApp() != nullptr)
Error("Cannot create two NF Application objects!");
setApp(this);
m_hInst = GetModuleHandle(NULL);
registerWindowClass();
RECT windowSize = getWindowRect();
@ -97,6 +100,10 @@ namespace nf {
m_nextState = stateName;
}
Gamestate* Application::getCurrentState() {
return m_currentState;
}
void Application::showWindow(bool show) {
if (show)
ShowWindow(m_window, SW_SHOW);
@ -152,6 +159,10 @@ namespace nf {
m_mouseDiffY = 0;
}
Application* Application::getApp() {
return currentApp;
}
void Application::registerWindowClass() {
if (!FindWindow(L"NFClass", NULL)) {
m_wclassName = L"NFClass";
@ -249,43 +260,41 @@ namespace nf {
}
void Application::runMainGameThread() {
m_sIntro = new IntroGamestate;
m_currentState = m_sIntro;
m_renderer = new Renderer(this);
startIntroState();
m_currentState->setup(this);
m_currentState->onEnter();
m_renderer->setFade(true, false, true);
std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point currentFrame = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point lastFrame = std::chrono::steady_clock::now();
while (m_running) {
currentTime = std::chrono::steady_clock::now();
m_deltaTime = std::chrono::duration<double>(currentTime - lastFrame).count();
currentFrame = std::chrono::steady_clock::now();
m_deltaTime = std::chrono::duration<double>(currentFrame - lastFrame).count();
if (m_deltaTime >= m_minFrametime) {
lastFrame = std::chrono::steady_clock::now();
m_currentState->update(m_deltaTime);
m_currentState->render(*m_renderer);
m_renderer->doFrame(m_currentState->getCamera());
m_frames++;
m_renderer->doFrame(m_currentState->getCamera(), m_deltaTime);
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));
if (m_fpsDuration.count() >= 0.2) {
m_FPS = (int)(1.0 / m_deltaTime);
static int i = 0;
i++;
if (i % 5 == 0)
Log("FPS: " + std::to_string(m_FPS));
m_fpsClock1 = std::chrono::steady_clock::now();
}
}
m_currentState->onExit();
m_currentState->cleanup();
delete m_renderer;
}
void Application::startIntroState() {
m_sIntro = new IntroGamestate;
m_sIntro->setup(this);
m_currentState = m_sIntro;
m_currentState->onEnter();
}
void Application::doStateChange() {
static bool once = true;
if (once) {
@ -295,6 +304,7 @@ namespace nf {
if (m_renderer->isFadeOutComplete()) {
m_currentState->onExit();
m_currentState->cleanup();
m_currentState = m_states[m_nextState];
m_currentState->setup(this);
m_currentState->onEnter();
@ -304,6 +314,10 @@ namespace nf {
}
}
void Application::setApp(Application* app) {
currentApp = app;
}
LRESULT CALLBACK Application::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
Application* app = (Application*)GetProp(hWnd, L"App");
switch (uMsg) {
@ -358,4 +372,6 @@ namespace nf {
delete curr;
}
}
Application* Application::currentApp = nullptr;
}

View File

@ -1,5 +1,6 @@
#include "Assets.h"
#include "Application.h"
#include "Model.h"
#include "Utility.h"
@ -40,6 +41,7 @@ namespace nf {
void AssetPack::load(const char* packName) {
std::string path = "assets/" + (std::string)packName;
std::string packContents = readFile(path);
std::unordered_map<std::string, ACubemap*> cubemaps;
unsigned int cubemapCount = 0;
while (packContents.size()) {
unsigned int startingPos = packContents.find_first_of("#NFASSET ") + 9;
@ -68,12 +70,13 @@ namespace nf {
geometry->data[assetSize] = '\0';
geometry->alreadyLoaded = false;
geometry->loadedModel = nullptr;
if (packName == "base.nfpack")
geometry->isBaseAsset = true;
m_assets[assetName] = geometry;
continue;
}
if (extension == "png") {
if (assetName.find("_cmfront") != std::string::npos || assetName.find("_cmback") != std::string::npos || assetName.find("_cmtop") != std::string::npos || assetName.find("_cmbottom") != std::string::npos || assetName.find("_cmleft") != std::string::npos || assetName.find("_cmright") != std::string::npos) {
static std::unordered_map<std::string, ACubemap*> cubemaps;
std::string cmName = assetName.substr(0, assetName.find('_'));
ACubemap* curr;
if (cubemaps.find(cmName) == cubemaps.end()) {
@ -126,6 +129,8 @@ namespace nf {
texture->data = new char[assetSize];
std::memcpy(texture->data, &assetContents[0], assetSize);
texture->size = assetSize;
if (packName == "base.nfpack")
texture->isBaseAsset = true;
m_assets[assetName] = texture;
continue;
}
@ -142,13 +147,17 @@ namespace nf {
font->data = new char[assetSize];
std::memcpy(font->data, &assetContents[0], assetSize);
font->size = assetSize;
if (packName == "base.nfpack")
font->isBaseAsset = true;
m_assets[assetName] = font;
continue;
}
Error("Invalid asset extention in pack \"" + (std::string)packName + (std::string)"\"!");
}
if (cubemapCount % 6 != 0)
Error("Could not find full cubemap in pack \"" + (std::string)packName + (std::string)"\"!")
Error("Could not find full cubemap in pack \"" + (std::string)packName + (std::string)"\"!");
if (packName != "base.nfpack")
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
Asset* AssetPack::operator[](const char* in) {
@ -162,9 +171,14 @@ namespace nf {
return m_assets[in];
}
void AssetPack::destroy() {
unload();
}
void AssetPack::unload() {
for (auto curr : m_assets)
delete curr.second;
m_assets.clear();
}
AssetPack::~AssetPack() {

View File

@ -35,4 +35,13 @@ namespace nf {
void Gamestate::onExit() {
}
void Gamestate::cleanup() {
for (NFObject* curr : m_nfObjects)
curr->destroy();
m_nfObjects.clear();
delete camera;
app = nullptr;
}
}

View File

@ -7,34 +7,33 @@
namespace nf {
void IntroGamestate::onEnter() {
Log("Intro onEnter!");
logoTex.create(BaseAssets::logo, Vec2(0.0, 0.0));
logoTex.centered(true, true);
text.create("(C) Grayson Riffe 2021", Vec2(0.01, 0.025), Vec3(0.8));
text.setScale(0.6);
m_counter = 0;
m_logoTex.create(BaseAssets::logo, Vec2(0.0, 0.0));
m_logoTex.centered(true, true);
m_text.create("(C) Grayson Riffe 2021", Vec2(0.01, 0.025), Vec3(0.8));
m_text.setScale(0.6);
m_start = std::chrono::steady_clock::now();
}
void IntroGamestate::update(double deltaTime) {
if (m_counter >= 240) {
app->changeState(app->getDefaultState());
}
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
std::chrono::duration<double, std::ratio<1i64>> dur = now - m_start;
static double scale = 2.0;
logoTex.setScale(scale);
if (m_counter >= 20) {
scale += 0.002;
m_logoTex.setScale(scale);
if (dur.count() > 0.2) {
scale += 0.12 * deltaTime;
}
m_counter++;
if (app->isInput(NFI_SPACE))
m_counter = 240;
if (dur.count() > 3.5 || app->isInput(NFI_SPACE)) {
app->changeState(app->getDefaultState());
}
if (app->isInput(NFI_ESCAPE))
app->quit();
}
void IntroGamestate::render(Renderer& renderer) {
renderer.render(logoTex);
renderer.render(text);
renderer.render(m_logoTex);
renderer.render(m_text);
}
void IntroGamestate::onExit() {

View File

@ -120,6 +120,6 @@ namespace nf {
}
Camera::~Camera() {
m_app->trackMouse(false);
}
}

View File

@ -4,6 +4,7 @@
#include "GL/glew.h"
#include "stb_image.h"
#include "Application.h"
#include "Assets.h"
namespace nf {
@ -108,6 +109,8 @@ namespace nf {
m_vao->addBuffer(vb, sizeof(vb));
m_vao->push<float>(3);
m_vao->finishBufferLayout();
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
bool Cubemap::isConstructed() {
@ -122,8 +125,15 @@ namespace nf {
glDepthFunc(GL_LESS);
}
Cubemap::~Cubemap() {
if(m_constructed)
void Cubemap::destroy() {
if (m_constructed)
glDeleteTextures(1, &m_id);
m_constructed = false;
m_id = 0;
delete m_vao;
}
Cubemap::~Cubemap() {
}
}

View File

@ -2,6 +2,8 @@
#include<vector>
#include "Application.h"
#include "Model.h"
#include "Shader.h"
namespace nf {
@ -18,24 +20,28 @@ namespace nf {
void Entity::create(Asset* modelAsset, Asset* textureAsset) {
m_constructed = true;
AModel& model = *(AModel*)modelAsset;
//TODO: Change this when doing materials
if (model.alreadyLoaded && textureAsset == nullptr) {
m_model = model.loadedModel;
return;
}
if (!textureAsset)
Error("No texture given to Entity create function on new model load!");
ATexture& texture = *(ATexture*)textureAsset;
std::string obj = model.data;
m_model = new Model;
std::vector<float> vb;
std::vector<unsigned int> ib;
size_t ibCount = 0;
std::vector<float> tc;
std::vector<float> vn;
parseOBJ(obj, vb, ib, ibCount, tc, vn);
m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &vn[0], vn.size() * sizeof(float), &tc[0], tc.size() * sizeof(float), &texture);
model.alreadyLoaded = true;
model.loadedModel = m_model;
else {
if (!textureAsset)
Error("No texture given to Entity create function on new model load!");
ATexture& texture = *(ATexture*)textureAsset;
std::string obj = model.data;
m_model = new Model;
std::vector<float> vb;
std::vector<unsigned int> ib;
size_t ibCount = 0;
std::vector<float> tc;
std::vector<float> vn;
parseOBJ(obj, vb, ib, ibCount, tc, vn);
m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &vn[0], vn.size() * sizeof(float), &tc[0], tc.size() * sizeof(float), &texture);
model.alreadyLoaded = true;
model.loadedModel = m_model;
}
m_model->setBaseAsset(model.isBaseAsset);
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
bool Entity::isConstructed() {
@ -90,6 +96,22 @@ namespace nf {
shader->setUniform("model", model);
}
void Entity::destroy() {
m_constructed = false;
if(m_model && !m_model->isBaseAsset())
delete m_model;
m_model = nullptr;
m_position.x = 0.0;
m_position.y = 0.0;
m_position.z = 0.0;
m_rotation.x = 0.0;
m_rotation.y = 0.0;
m_rotation.z = 0.0;
m_scale.x = 1.0;
m_scale.y = 1.0;
m_scale.z = 1.0;
}
Entity::~Entity() {
}

View File

@ -1,11 +1,12 @@
#include "Light.h"
#include "Application.h"
#include "Shader.h"
namespace nf {
Light::Light() :
m_type(Type::POINT),
m_constructed(false),
m_type(Type::POINT),
m_strength(1.0f)
{
@ -18,6 +19,7 @@ namespace nf {
m_type = type;
m_strength = strength;
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
bool Light::isConstructed() {
@ -77,6 +79,14 @@ namespace nf {
return m_strength;
}
void Light::destroy() {
m_constructed = false;
m_type = Type::POINT;
m_position = Vec3(0.0);
m_color = Vec3(0.0);
m_strength = 1.0f;
}
Light::~Light() {
}

View File

@ -8,6 +8,7 @@
namespace nf {
Model::Model() :
m_base(false),
m_texture(nullptr)
{
@ -29,7 +30,7 @@ namespace nf {
}
else {
m_texture = new Texture;
m_texture->create(texture->data, texture->size);
m_texture->create(texture);
texture->alreadyLoaded = true;
texture->loadedTexture = m_texture;
}
@ -45,6 +46,14 @@ namespace nf {
m_ib->bind();
}
void Model::setBaseAsset(bool isBase) {
m_base = isBase;
}
bool Model::isBaseAsset() {
return m_base;
}
Model::~Model() {
delete m_texture;
}

View File

@ -4,6 +4,7 @@
#include "ft2build.h"
#include FT_FREETYPE_H
#include "Application.h"
#include "UIElement.h"
#include "Shader.h"
@ -53,6 +54,7 @@ namespace nf {
FT_Done_FreeType(ft);
newFont.alreadyLoaded = true;
newFont.loadedFont = m_font;
m_font->isBase = newFont.isBaseAsset;
}
m_vao = new VertexArray;
m_vao->addBuffer(nullptr, 0);
@ -61,6 +63,13 @@ namespace nf {
m_vao->addBuffer(nullptr, 0);
m_vao->push<float>(2);
m_vao->finishBufferLayout();
if (m_string == "NFLoadingText") {
m_string = "Loading...";
}
else {
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
}
void Text::setText(const std::string& string) {
@ -135,6 +144,18 @@ namespace nf {
}
}
void Text::destroy() {
m_constructed = false;
m_position = Vec2(0.0);
m_centeredX = m_centeredY = false;
m_string = std::string();
if (!m_font->isBase)
delete m_font;
m_color = Vec3(0.0);
m_scale = 1.0f;
m_opacity = 1.0f;
}
Text::~Text() {
}

View File

@ -26,7 +26,7 @@ namespace nf {
}
else {
m_texture = new Texture;
m_texture->create(tex->data, tex->size);
m_texture->create(tex);
}
m_vao = new VertexArray;
@ -84,6 +84,17 @@ namespace nf {
glDrawArrays(GL_TRIANGLES, 0, 6);
}
void UITexture::destroy() {
m_constructed = false;
m_position = Vec2(0.0);
m_centeredX = m_centeredY = false;
if (!m_texture->isBaseAsset())
delete m_texture;
m_scale = 1.0f;
m_opacity = 1.0f;
delete m_vao;
}
UITexture::~UITexture() {
}

View File

@ -8,6 +8,7 @@
#include "Shader.h"
#include "Light.h"
#include "Entity.h"
#include "Model.h"
#include "Cubemap.h"
#include "UIElement.h"
#include "Camera.h"
@ -107,7 +108,7 @@ namespace nf {
m_fadeVAO->push<float>(2);
m_fadeVAO->finishBufferLayout();
m_fadeIB = new IndexBuffer(fadeIB, 6);
m_loadingText.create("Loading...", Vec2(0.025, 0.044), Vec3(0.7, 0.7, 0.7));
m_loadingText.create("NFLoadingText", Vec2(0.025, 0.044), Vec3(0.7, 0.7, 0.7));
}
void Renderer::setFade(bool in, bool out, bool noText) {
@ -142,7 +143,7 @@ namespace nf {
m_cubemap = &in;
}
void Renderer::doFrame(Camera* camera) {
void Renderer::doFrame(Camera* camera, double dT) {
//Begin frame
glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -202,7 +203,7 @@ namespace nf {
m_loadingText.setOpacity(opacity);
m_loadingText.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height);
}
opacity -= 0.03;
opacity -= 0.8 * dT;
if (opacity <= 0.0) {
m_fadeIn = false;
m_fadeOutComplete = false;
@ -220,7 +221,7 @@ namespace nf {
m_loadingText.setOpacity(opacity);
m_loadingText.render(m_textShader, m_app->getConfig().width, m_app->getConfig().height);
}
opacity += 0.03;
opacity += 1.2 * dT;
if (opacity >= 1.0) {
m_fadeIn = false;
m_fadeOutComplete = true;

View File

@ -4,28 +4,33 @@
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include "Assets.h"
#include "Utility.h"
namespace nf {
Texture::Texture() :
m_isBase(false),
m_id(0),
m_x(0),
m_y(0)
{
glGenTextures(1, &m_id);
}
void Texture::create(const char* textureData, size_t textureSize) {
void Texture::create(ATexture* tex) {
int nChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char* texture = stbi_load_from_memory((unsigned char*)textureData, textureSize, &m_x, &m_y, &nChannels, 0);
unsigned char* texture = stbi_load_from_memory((unsigned char*)tex->data, tex->size, &m_x, &m_y, &nChannels, 0);
if (!texture)
Error("Texture failed to load from memory!");
glGenTextures(1, &m_id);
glBindTexture(GL_TEXTURE_2D, m_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_x, m_y, 0, nChannels == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, texture);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(texture);
m_isBase = tex->isBaseAsset;
}
void Texture::bind() {
@ -36,6 +41,10 @@ namespace nf {
return { (float)m_x, (float)m_y };
}
bool Texture::isBaseAsset() {
return m_isBase;
}
Texture::~Texture() {
glDeleteTextures(1, &m_id);
}

View File

@ -23,6 +23,7 @@ namespace nf {
const std::string& getDefaultState();
void run();
void changeState(const std::string& stateName);
Gamestate* getCurrentState();
void showWindow(bool show);
const HWND& getWindow();
void changeConfig(const Config& in);
@ -31,6 +32,7 @@ namespace nf {
bool isInput(unsigned int code);
void trackMouse(bool track);
void getMouseDiff(int& x, int& y);
static Application* getApp();
void quit();
~Application();
@ -41,11 +43,12 @@ namespace nf {
void toggleFullscreen();
void updateInput();
void runMainGameThread();
void startIntroState();
void doStateChange();
static void setApp(Application* app);
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static Application* currentApp;
Config m_currentConfig;
bool m_running;
bool m_quit;
@ -59,7 +62,6 @@ namespace nf {
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;

View File

@ -1,5 +1,6 @@
#pragma once
#include <unordered_map>
#include "NFObject.h"
namespace nf {
class Model;
@ -9,6 +10,7 @@ namespace nf {
struct Asset {
char* data = nullptr;
bool alreadyLoaded = false;
bool isBaseAsset = false;
virtual ~Asset();
};
@ -55,7 +57,7 @@ namespace nf {
~AFont() override;
};
class AssetPack {
class AssetPack : public NFObject {
public:
AssetPack();
@ -63,6 +65,7 @@ namespace nf {
Asset* operator[](const char* in);
Asset* operator[](std::string& in);
void destroy() override;
void unload();
~AssetPack();
private:

View File

@ -1,10 +1,11 @@
#pragma once
#include "NFObject.h"
#include "Drawable.h"
namespace nf {
struct Asset;
class Cubemap : public Drawable {
class Cubemap : public Drawable, public NFObject {
public:
Cubemap();
@ -12,6 +13,7 @@ namespace nf {
bool isConstructed();
void render();
void destroy() override;
~Cubemap();
private:
bool m_constructed;

View File

@ -1,12 +1,13 @@
#pragma once
#include "Model.h"
#include "Assets.h"
#include "NFObject.h"
#include "Utility.h"
namespace nf {
class Shader;
class Model;
class Entity {
class Entity : public NFObject {
public:
Entity();
@ -24,6 +25,7 @@ namespace nf {
void bind(Shader* shader);
Model* getModel() const;
void destroy() override;
~Entity();
private:
void setModelMatrix(Shader* shader);

View File

@ -1,5 +1,8 @@
#pragma once
#include <vector>
#include "Camera.h"
#include "NFObject.h"
namespace nf {
class Application;
@ -20,6 +23,9 @@ namespace nf {
virtual void render(Renderer& renderer);
virtual void onExit();
void cleanup();
std::vector<NFObject*> m_nfObjects;
protected:
Application* app;
Camera* camera;

View File

@ -1,4 +1,5 @@
#pragma once
#include "Gamestate.h"
#include "UITexture.h"
#include "Text.h"
@ -13,8 +14,8 @@ namespace nf {
void onExit() override;
private:
int m_counter;
UITexture logoTex;
Text text;
std::chrono::steady_clock::time_point m_start;
UITexture m_logoTex;
Text m_text;
};
}

View File

@ -1,10 +1,11 @@
#pragma once
#include "NFObject.h"
#include "Utility.h"
namespace nf {
class Shader;
class Light {
class Light : public NFObject {
public:
enum class Type {
DIRECTIONAL,
@ -25,6 +26,7 @@ namespace nf {
const Vec3& getColor();
const float getStrength();
void destroy() override;
~Light();
private:
bool m_constructed;

View File

@ -13,8 +13,12 @@ namespace nf {
void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const void* normalsBufferData, size_t normalsBufferSize, ATexture* texture);
void bind() override;
void setBaseAsset(bool isBase);
bool isBaseAsset();
~Model();
private:
bool m_base;
Texture* m_texture;
};
}

View File

@ -0,0 +1,11 @@
#pragma once
namespace nf {
class NFObject {
public:
virtual void destroy() = 0;
private:
};
}

View File

@ -9,6 +9,7 @@
#include "Utility.h"
#include "IntroGamestate.h"
#include "Assets.h"
#include "Entity.h"
#include "Light.h"
#include "Cubemap.h"
#include "Text.h"
@ -20,34 +21,6 @@ namespace nf {
class Shader;
class Model;
class Entity {
public:
Entity();
void create(Asset* modelAsset, Asset* textureAsset = nullptr);
void setPosition(double x, double y, double z);
void setPosition(const Vec3& position);
void setRotation(double x, double y, double z);
void setRotation(const Vec3& rotation);
void setScale(double x);
void setScale(double x, double y, double z);
void setScale(const Vec3& scale);
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);
@ -60,7 +33,7 @@ namespace nf {
void render(Light& in);
void render(Cubemap& in);
void doFrame(Camera* camera);
void doFrame(Camera* camera, double dT);
~Renderer();
private:
@ -103,6 +76,7 @@ namespace nf {
const std::string& getDefaultState();
void run();
void changeState(const std::string& stateName);
Gamestate* getCurrentState();
void showWindow(bool show);
const HWND& getWindow();
void changeConfig(const Config& in);
@ -111,6 +85,7 @@ namespace nf {
bool isInput(unsigned int code);
void trackMouse(bool track);
void getMouseDiff(int& x, int& y);
static Application* getApp();
void quit();
~Application();
@ -121,11 +96,12 @@ namespace nf {
void toggleFullscreen();
void updateInput();
void runMainGameThread();
void startIntroState();
void doStateChange();
static void setApp(Application* app);
static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static Application* currentApp;
Config m_currentConfig;
bool m_running;
bool m_quit;
@ -139,7 +115,6 @@ namespace nf {
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;

View File

@ -28,7 +28,7 @@ namespace nf {
void render(Light& in);
void render(Cubemap& in);
void doFrame(Camera* camera);
void doFrame(Camera* camera, double dT);
~Renderer();
private:

View File

@ -2,6 +2,7 @@
#include <map>
#include "UIElement.h"
#include "NFObject.h"
#include "Assets.h"
#include "Utility.h"
@ -15,9 +16,10 @@ namespace nf {
struct Font {
std::map<char, Character> m_characters;
bool isBase = false;
};
class Text : public UIElement {
class Text : public UIElement, public NFObject {
public:
Text();
@ -29,6 +31,7 @@ namespace nf {
void setOpacity(double opacity);
void render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) override;
void destroy() override;
~Text();
private:
std::string m_string;

View File

@ -2,16 +2,20 @@
#include "Utility.h"
namespace nf {
struct ATexture;
class Texture {
public:
Texture();
void create(const char* textureData, size_t textureSize);
void create(ATexture* tex);
void bind();
Vec2 getDimensions();
bool isBaseAsset();
~Texture();
private:
bool m_isBase;
unsigned int m_id;
int m_x;
int m_y;

View File

@ -1,12 +1,13 @@
#pragma once
#include "UIElement.h"
#include "NFObject.h"
#include "Utility.h"
namespace nf {
class Texture;
struct Asset;
class UITexture : public UIElement {
class UITexture : public UIElement, public NFObject {
public:
UITexture();
@ -16,6 +17,7 @@ namespace nf {
void setOpacity(double opacity);
void render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) override;
void destroy() override;
~UITexture();
private:
Texture* m_texture;