Started writing a manual; Lots of changes

This commit is contained in:
Grayson Riffe (Laptop) 2021-11-25 14:01:20 -06:00
parent f884847513
commit 3b5b608ae9
53 changed files with 3851 additions and 241 deletions

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.vs/
bin/
int/
manual/
*.aps
*.res
*.nfpack

View File

@ -98,8 +98,8 @@ if exist "base.nfpack" (copy "base.nfpack" "$(OutDir)assets\")</Command>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
<AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
<Profile>true</Profile>
<AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
<PostBuildEvent>
<Command>cd assets

View File

@ -1,7 +1,7 @@
#include "MainState.h"
void MainState::onEnter() {
Log("MainState onEnter!");
NFLog("MainState onEnter!");
currCamType = nf::Camera::Type::FIRST_PERSON;
camera->setType(currCamType);
ap.load("example.nfpack");
@ -31,7 +31,7 @@ void MainState::onEnter() {
for (int y = 0; y < 3; y++) {
for (int z = 0; z < 3; z++) {
entities.push_back(new nf::Entity);
entities.back()->create(ap.get("2mats.obj"), nf::Entity::Type::DYNAMIC);
entities.back()->create(nf::BaseAssets::cone, nf::Entity::Type::DYNAMIC);
entities.back()->setPosition(nf::Vec3(5.0 + x * 2.05, 1.0 + y * 2.05, -5.0 + z * 2.05));
}
}
@ -52,20 +52,21 @@ void MainState::update(float deltaTime) {
camera->setType(currCamType);
}
float speed = 5.0;
float speed;
if (camera->getType() == nf::Camera::Type::FIRST_PERSON) {
if (app->isKeyHeld(NFI_SHIFT))
speed = 20.0;
speed = 20.0f;
else
speed = 5.0;
speed = 5.0f;
speed *= deltaTime;
if (app->isKeyHeld(NFI_W))
camera->moveForward(speed * deltaTime);
camera->moveZ(speed);
if (app->isKeyHeld(NFI_S))
camera->moveBackward(speed * deltaTime);
camera->moveZ(-speed);
if (app->isKeyHeld(NFI_D))
camera->moveRight(speed * deltaTime);
camera->moveX(speed);
if (app->isKeyHeld(NFI_A))
camera->moveLeft(speed * deltaTime);
camera->moveX(-speed);
}
text.setText("FPS: " + std::to_string(app->getFPS()));
@ -134,7 +135,7 @@ void MainState::render(nf::Renderer& renderer) {
}
void MainState::onExit() {
Log("MainState onExit!");
NFLog("MainState onExit!");
entities.clear();
}

View File

@ -57,7 +57,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFENGINE; GLEW_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(ProjectDir)dep\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>
@ -89,7 +89,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFENGINE; GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(ProjectDir)dep\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>

View File

@ -5,7 +5,7 @@
#include "Utility.h"
namespace nf {
DEBUGINIT;
NFDEBUGINIT;
Application::Application(Config& config) :
m_currentConfig(config),
@ -18,21 +18,12 @@ namespace nf {
m_stateChange(false),
m_stateChangeStarted(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);
NFLog("Creating NF application");
NFLog("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(true) != nullptr)
Error("Cannot create two NF Application objects!");
NFError("Cannot create two NF Application objects!");
setApp(this);
m_hInst = GetModuleHandle(NULL);
registerWindowClass();
RECT windowSize = getWindowRect();
int x = 0;
int y = 0;
calculateNewWindowPos(x, y);
m_window = CreateWindowEx(NULL, m_wclassName, toWide(m_currentConfig.title).data(), WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, x, y, windowSize.right, windowSize.bottom, NULL, NULL, m_hInst, NULL);
SetProp(m_window, L"App", this);
if (m_currentConfig.fullscreen) toggleFullscreen();
}
void Application::setWindowIcon(HICON hIcon) {
@ -47,19 +38,19 @@ namespace nf {
Renderer* Application::getRenderer() const {
if (!m_renderer)
Error("Application not running yet!");
NFError("Application not running yet!");
return m_renderer;
}
AudioEngine* Application::getAudioEngine() const {
if(!m_audio)
Error("Application not running yet!");
NFError("Application not running yet!");
return m_audio;
}
PhysicsEngine* Application::getPhysicsEngine() const {
if (!m_physics)
Error("Application not running yet!");
NFError("Application not running yet!");
return m_physics;
}
@ -68,7 +59,7 @@ namespace nf {
m_states[stateName] = state;
}
else
Error("State \"" + (std::string)stateName + (std::string)"\" already exists!");
NFError("State \"" + (std::string)stateName + (std::string)"\" already exists!");
}
void Application::setDefaultState(const std::string& stateName) {
@ -78,10 +69,10 @@ namespace nf {
m_defaultStateAdded = true;
}
else
Error("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!");
NFError("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!");
}
else
Error("More than one default state defined!");
NFError("More than one default state defined!");
}
const std::string& Application::getDefaultState() {
@ -92,6 +83,15 @@ namespace nf {
#ifdef _DEBUG
SetThreadDescription(GetCurrentThread(), L"Input Thread");
#endif
m_hInst = GetModuleHandle(NULL);
registerWindowClass();
RECT windowSize = getWindowRect();
int x = 0;
int y = 0;
calculateNewWindowPos(x, y);
m_window = CreateWindowEx(NULL, m_wclassName, toWide(m_currentConfig.title).data(), WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, x, y, windowSize.right, windowSize.bottom, NULL, NULL, m_hInst, NULL);
SetProp(m_window, L"App", this);
if (m_currentConfig.fullscreen) toggleFullscreen();
showWindow(true);
m_running = true;
MSG msg = { };
@ -119,7 +119,7 @@ namespace nf {
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!");
NFError("State \"" + (std::string)stateName + (std::string)"\" doesn't exist!");
m_stateChange = true;
m_nextState = m_states[stateName];
}
@ -210,7 +210,7 @@ namespace nf {
Application* Application::getApp(bool first) {
if (!currentApp && !first)
Error("No Application has been created yet!");
NFError("No Application has been created yet!");
return currentApp;
}
@ -226,7 +226,7 @@ namespace nf {
RegisterClass(&wclass);
}
else
Error("Cannot run multiple NF applications concurrently!");
NFError("Cannot run multiple NF applications concurrently!");
}
RECT Application::getWindowRect() const {
@ -303,7 +303,7 @@ namespace nf {
void Application::quit() {
m_quit = true;
Log("Exiting NF application");
NFLog("Exiting NF application");
}
void Application::runMainGameThread() {
@ -340,7 +340,7 @@ namespace nf {
static int i = 0;
i++;
if (i % 5 == 0)
Log("FPS: " + std::to_string(m_FPS));
NFLog("FPS: " + std::to_string(m_FPS));
#endif
m_fpsClock1 = std::chrono::steady_clock::now();
}

View File

@ -44,7 +44,9 @@ namespace nf {
}
AssetPack::AssetPack() {
AssetPack::AssetPack() :
m_loaded(false)
{
}
@ -87,7 +89,7 @@ namespace nf {
}
curr = cubemaps[cmName];
if (curr->numImages == 6)
Error("Duplicate cubemap images in pack \"" + (std::string)packName + (std::string)"\"!");
NFError("Duplicate cubemap images in pack \"" + (std::string)packName + (std::string)"\"!");
if (assetName.find("_cmfront") != std::string::npos) {
curr->frontData = new char[assetSize];
std::memcpy(curr->frontData, &assetContents[0], assetSize);
@ -135,7 +137,7 @@ namespace nf {
}
curr = buttons[buttonName];
if (curr->numImages == 3)
Error("Duplicate button images in pack \"" + (std::string)packName + (std::string)"\"!");
NFError("Duplicate button images in pack \"" + (std::string)packName + (std::string)"\"!");
if (assetName.find("_buttonidle") != std::string::npos) {
curr->idleTex.data = new char[assetSize];
std::memcpy(curr->idleTex.data, &assetContents[0], assetSize);
@ -196,12 +198,12 @@ namespace nf {
m_assets[assetName] = sound;
continue;
}
Error("Invalid asset extention in pack \"" + (std::string)packName + (std::string)"\"!");
NFError("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)"\"!");
NFError("Could not find full cubemap in pack \"" + (std::string)packName + (std::string)"\"!");
if (buttonCount % 3 != 0)
Error("Could not find full button set in pack \"" + (std::string)packName + (std::string)"\"!");
NFError("Could not find full button set in pack \"" + (std::string)packName + (std::string)"\"!");
while (packContentsOBJ.size()) {
size_t startingPos = packContentsOBJ.find_first_of("#NFASSET ") + 9;
@ -244,26 +246,35 @@ namespace nf {
}
}
m_loaded = true;
if (packName != "base.nfpack") {
if (!Application::getApp()->getCurrentState()->isRunning())
Application::getApp()->getCurrentState()->m_nfObjects.push_back(this);
}
}
bool AssetPack::isLoaded() {
return m_loaded;
}
Asset* AssetPack::get(const char* in) {
if (!m_loaded) NFError("AssetPack has not been loaded yet!");
if (m_assets.find(in) == m_assets.end())
Error("Could not find asset \"" + (std::string)in + (std::string)"\" in asset pack!");
NFError("Could not find asset \"" + (std::string)in + (std::string)"\" in asset pack!");
return m_assets[in];
}
Asset* AssetPack::get(std::string& in) {
if (!m_loaded) NFError("AssetPack has not been loaded yet!");
return get(in.c_str());
}
Asset* AssetPack::operator[](const char* in) {
if (!m_loaded) NFError("AssetPack has not been loaded yet!");
return get(in);
}
Asset* AssetPack::operator[](std::string& in) {
if (!m_loaded) NFError("AssetPack has not been loaded yet!");
return get(in.c_str());
}
@ -275,6 +286,8 @@ namespace nf {
for (auto curr : m_assets)
delete curr.second;
m_assets.clear();
m_loaded = false;
}
AssetPack::~AssetPack() {

View File

@ -14,10 +14,10 @@ namespace nf {
{
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if (FAILED(hr))
Error("Could not initialize COM!");
NFError("Could not initialize COM!");
hr = XAudio2Create(&m_engine);
if (FAILED(hr))
Error("Could not initialize the audio engine!");
NFError("Could not initialize the audio engine!");
#ifdef _DEBUG
XAUDIO2_DEBUG_CONFIGURATION debug = { 0 };
debug.TraceMask = XAUDIO2_LOG_ERRORS | XAUDIO2_LOG_WARNINGS;
@ -30,7 +30,7 @@ namespace nf {
else if (SUCCEEDED(hr))
m_isActive = true;
else
Error("Could not initialize the audio engine!");
NFError("Could not initialize the audio engine!");
m_threadRunning = true;
m_thread = std::thread(&AudioEngine::runAudioThread, this);
}
@ -45,7 +45,7 @@ namespace nf {
return true;
}
else {
Error("Could not initialize audio!");
NFError("Could not initialize audio!");
return false;
}
}
@ -115,7 +115,7 @@ namespace nf {
break;
}
else if (!SUCCEEDED(hr))
Error("Could not play sound!");
NFError("Could not play sound!");
curr.voice = source;
curr.voice->SubmitSourceBuffer(curr.buffer);
curr.voice->SetVolume(curr.volume);

View File

@ -39,15 +39,15 @@ namespace nf {
}
void Gamestate::onEnter() {
Error("Gamestate has no overridden onEnter function!");
NFError("Gamestate has no overridden onEnter function!");
}
void Gamestate::update(float deltaTime) {
Error("Gamestate has no overridden update function!");
NFError("Gamestate has no overridden update function!");
}
void Gamestate::render(Renderer& renderer) {
Error("Gamestate has no overridden render function!");
NFError("Gamestate has no overridden render function!");
}
Camera* Gamestate::getCamera() {
@ -67,7 +67,7 @@ namespace nf {
}
void Gamestate::onExit() {
Error("Gamestate has no overridden onExit function!");
NFError("Gamestate has no overridden onExit function!");
}
void Gamestate::stop() {

View File

@ -6,7 +6,7 @@
namespace nf {
void IntroGamestate::onEnter() {
Log("Intro onEnter!");
NFLog("Intro onEnter!");
m_scale = 2.0;
m_logoTex.create(BaseAssets::logo, Vec2(0.0, 0.0));
m_logoTex.centered(true, true);
@ -37,6 +37,6 @@ namespace nf {
}
void IntroGamestate::onExit() {
Log("Intro onExit!");
NFLog("Intro onExit!");
}
}

View File

@ -23,7 +23,7 @@ namespace nf {
void Button::create(const Vec2& position, std::string string, Asset* buttonAsset, float scale, float opacity) {
if (m_constructed)
Error("Button already created!");
NFError("Button already created!");
m_constructed = true;
m_position = position;
m_string = string;
@ -36,12 +36,12 @@ namespace nf {
m_text.setOpacity(m_opacity);
AButton* button;
if ((button = dynamic_cast<AButton*>(buttonAsset)) == nullptr)
Error("Non-button asset passed to Button::create!");
NFError("Non-button asset passed to Button::create!");
m_idleTexture = new Texture(&button->idleTex);
m_hoverTexture = new Texture(&button->hoverTex);
m_pressedTexture = new Texture(&button->pressedTex);
if (!((m_idleTexture->getDimensions() == m_hoverTexture->getDimensions()) && (m_idleTexture->getDimensions() == m_pressedTexture->getDimensions()))) {
Error("Button images are not the same size!");
NFError("Button images are not the same size!");
}
float tc[3][4] = {
0.0, 1.0,

View File

@ -18,7 +18,7 @@ namespace nf {
void Cubemap::create(Asset* cubemapAsset) {
if (m_constructed)
Error("Cubemap already created!");
NFError("Cubemap already created!");
m_constructed = true;
ACubemap& cm = *(ACubemap*)cubemapAsset;
glGenTextures(1, &m_id);

View File

@ -24,12 +24,12 @@ namespace nf {
void Entity::create(Asset* modelAsset, Type type) {
if (m_constructed)
Error("Entity already created!");
NFError("Entity already created!");
m_constructed = true;
m_type = type;
AModel* model;
if ((model = dynamic_cast<AModel*>(modelAsset)) == nullptr)
Error("Non-model asset passed to Entity::create!");
NFError("Non-model asset passed to Entity::create!");
if (model->alreadyLoaded) {
m_model = model->loadedModel;
}

View File

@ -14,7 +14,7 @@ namespace nf {
void Light::create(const Vec3& position, const Vec3& color, float strength, Type type) {
if (m_constructed)
Error("Light already created!");
NFError("Light already created!");
m_constructed = true;
m_position = position;
m_color = color;

View File

@ -94,11 +94,11 @@ namespace nf {
void Sound::create(Asset* soundAsset) {
if (m_constructed)
Error("Sound already created!");
NFError("Sound already created!");
m_constructed = true;
ASound* sound;
if ((sound = dynamic_cast<ASound*>(soundAsset)) == nullptr)
Error("Non-sound asset passed to Sound::create!");
NFError("Non-sound asset passed to Sound::create!");
std::string data(sound->data, sound->size);
size_t dataSize;
@ -107,7 +107,7 @@ namespace nf {
else if (data.find("RIFF") == 0)
dataSize = loadWAV(data);
else
Error("Sound asset not of correct format!");
NFError("Sound asset not of correct format!");
m_xBuffer.pAudioData = (unsigned char*)m_buffer;
m_xBuffer.AudioBytes = (unsigned int)dataSize;
@ -167,11 +167,11 @@ namespace nf {
unsigned int fileSize = *(unsigned int*)&data[4];
size_t fmtPos;
if ((fmtPos = data.find("fmt")) == std::string::npos)
Error("WAV not of correct format!");
NFError("WAV not of correct format!");
std::memcpy(&m_format, &data[fmtPos + 8], 16);
size_t dataPos;
if ((dataPos = data.find("data")) == std::string::npos)
Error("WAV not of correct m_format!");
NFError("WAV not of correct m_format!");
unsigned int dataSize = *(unsigned int*)&data[dataPos + 4];
m_buffer = new char[dataSize];
std::memcpy(m_buffer, &data[dataPos + 8], dataSize);

View File

@ -19,7 +19,7 @@ namespace nf {
void Text::create(const std::string& string, const Vec2& position, const Vec3& color, float opacity, float scale, Asset* fontAsset) {
if (m_constructed)
Error("Text already created!");
NFError("Text already created!");
m_constructed = true;
m_string = string;
m_position = position;
@ -28,7 +28,7 @@ namespace nf {
m_opacity = opacity;
AFont* font;
if ((font = dynamic_cast<AFont*>(fontAsset)) == nullptr)
Error("Non-font asset passed to Text::create!");
NFError("Non-font asset passed to Text::create!");
if (font->alreadyLoaded) {
m_font = font->loadedFont;
}
@ -36,10 +36,10 @@ namespace nf {
m_font = new Font;
FT_Library ft;
if (FT_Init_FreeType(&ft))
Error("Could not initialize FreeType!");
NFError("Could not initialize FreeType!");
FT_Face face;
if (FT_New_Memory_Face(ft, (const unsigned char*)font->data, (unsigned int)font->size, 0, &face))
Error("Could not load font!");
NFError("Could not load font!");
FT_Set_Pixel_Sizes(face, 0, 160);
for (unsigned char c = 0; c < 128; c++) {
FT_Load_Char(face, c, FT_LOAD_RENDER);

View File

@ -18,11 +18,11 @@ namespace nf {
void UITexture::create(Asset* textureAsset, const Vec2& position, float scale, float opacity) {
if (m_constructed)
Error("UITexture already created!");
NFError("UITexture already created!");
m_constructed = true;
ATexture* tex;
if ((tex = dynamic_cast<ATexture*>(textureAsset)) == nullptr)
Error("Non-texture asset passed to UITexture::create!");
NFError("Non-texture asset passed to UITexture::create!");
m_position = position;
m_scale = scale;
m_opacity = opacity;

View File

@ -11,7 +11,7 @@ namespace nf {
Debug::ErrorImp(message, file, line);
__debugbreak();
#else
Error(message);
NFError(message);
#endif
}
};
@ -33,7 +33,7 @@ namespace nf {
m_err = new PhysicsErrorCallback;
m_foundation = PxCreateFoundation(PX_PHYSICS_VERSION, m_alloc, *m_err);
if (!m_foundation)
Error("Could not initialize physics engine!");
NFError("Could not initialize physics engine!");
#ifdef _DEBUG
m_pvd = PxCreatePvd(*m_foundation);
@ -43,11 +43,11 @@ namespace nf {
m_phy = PxCreatePhysics(PX_PHYSICS_VERSION, *m_foundation, PxTolerancesScale(), false, m_pvd);
if (!m_phy)
Error("Could not initialize physics engine!");
NFError("Could not initialize physics engine!");
m_cooking = PxCreateCooking(PX_PHYSICS_VERSION, *m_foundation, PxCookingParams(PxTolerancesScale()));
if (!m_cooking)
Error("Could not initialize physics engine!");
NFError("Could not initialize physics engine!");
unsigned int threads = std::thread::hardware_concurrency() - 1;
if (threads < 0) threads = 0;
@ -177,7 +177,7 @@ namespace nf {
PxDefaultMemoryOutputStream buf;
if (!m_cooking->cookConvexMesh(desc, buf))
Error("Could not create convex mesh!");
NFError("Could not create convex mesh!");
PxDefaultMemoryInputData in(buf.getData(), buf.getSize());
PxConvexMesh* mesh = m_phy->createConvexMesh(in);
@ -195,7 +195,7 @@ namespace nf {
PxDefaultMemoryOutputStream buf;
if (!m_cooking->cookTriangleMesh(desc, buf))
Error("Could not create triangle mesh!");
NFError("Could not create triangle mesh!");
PxDefaultMemoryInputData in(buf.getData(), buf.getSize());
PxTriangleMesh* mesh = m_phy->createTriangleMesh(in);
@ -218,7 +218,7 @@ namespace nf {
else if (m_triangleMeshes.find(entity->getModel()) != m_triangleMeshes.end())
triangleMesh = m_triangleMeshes[entity->getModel()];
else
Error("No physics mesh found for this entity!");
NFError("No physics mesh found for this entity!");
//Dynamic or static
if (type == Entity::Type::DYNAMIC) {

View File

@ -31,30 +31,23 @@ namespace nf {
return m_type;
}
void Camera::moveForward(float speed) {
Vec3 temp = m_front * speed;
void Camera::move(const Vec2& offset) {
moveX(offset.x);
moveZ(offset.y);
}
void Camera::moveZ(float offset) {
Vec3 temp = m_front * offset;
m_position += temp;
}
void Camera::moveBackward(float speed) {
Vec3 temp = m_front * speed;
m_position -= temp;
}
void Camera::moveRight(float speed) {
void Camera::moveX(float offset) {
glm::vec3 front = { m_front.x, m_front.y, m_front.z };
glm::vec3 temp = glm::normalize(glm::cross(front, glm::vec3(0.0, 1.0, 0.0))) * speed;
glm::vec3 temp = glm::normalize(glm::cross(front, glm::vec3(0.0, 1.0, 0.0))) * offset;
Vec3 move = { temp.x, temp.y, temp.z };
m_position += move;
}
void Camera::moveLeft(float speed) {
glm::vec3 front = { m_front.x, m_front.y, m_front.z };
glm::vec3 temp = glm::normalize(glm::cross(front, glm::vec3(0.0, 1.0, 0.0))) * speed;
Vec3 move = { temp.x, temp.y, temp.z };
m_position -= move;
}
void Camera::setPosition(float x, float y, float z) {
m_position = { x, y, z };
}
@ -81,7 +74,7 @@ namespace nf {
return m_front;
}
void Camera::bind(Shader* gBufferShader, Shader* lightingShader, Shader* cubemapShader) {
void Camera::update(Shader* gBufferShader, Shader* lightingShader, Shader* cubemapShader) {
glm::mat4 view;
switch (m_type) {
@ -104,7 +97,7 @@ namespace nf {
break;
}
case Type::ORBIT: {
//TODO: Camera orbit mode
break;
}
case Type::FIXED: {

View File

@ -11,7 +11,7 @@ namespace nf {
}
void Drawable::bind() {
Error("Tried to bind an invalid object!");
NFError("Tried to bind an invalid object!");
}
unsigned int Drawable::getIndexCount() {

View File

@ -19,7 +19,7 @@ namespace nf {
m_newLine("\n")
{
if (model->neededTextures.size() > 32)
Error("Model exceedes 32 texture limit!");
NFError("Model exceedes 32 texture limit!");
std::vector<char> file(model->data, model->data + model->size);
size_t mtlPos = std::search(file.begin(), file.end(), m_newMtl, m_newMtl + std::strlen(m_newMtl)) - file.begin();
std::vector<char> mtl(&file[mtlPos], &file[0] + file.size());
@ -72,15 +72,15 @@ namespace nf {
}
else if (std::strcmp(&firstWord[0], "f") == 0) {
if (!tcPresent)
Error("No texture coordinates found in model!");
NFError("No texture coordinates found in model!");
if (!vnPresent)
Error("No normals found in model!");
NFError("No normals found in model!");
unsigned int vertexIndex[3], uvIndex[3], vnIndex[3];
char temp;
ss >> vertexIndex[0] >> temp >> uvIndex[0] >> temp >> vnIndex[0] >> vertexIndex[1] >> temp >> uvIndex[1] >> temp >> vnIndex[1] >> vertexIndex[2] >> temp >> uvIndex[2] >> temp >> vnIndex[2];
if (ss.rdbuf()->in_avail() > 1)
Error("Model has non-triangle faces!");
NFError("Model has non-triangle faces!");
mats[usingMat]->vbIndices.push_back(vertexIndex[0]);
mats[usingMat]->vbIndices.push_back(vertexIndex[1]);
mats[usingMat]->vbIndices.push_back(vertexIndex[2]);
@ -232,7 +232,7 @@ namespace nf {
matCount++;
}
if (m_materials.size() > 32)
Error("Model exceedes 32 material limit!");
NFError("Model exceedes 32 material limit!");
m_vao = new VertexArray;
m_vao->addBuffer(&vboPositions[0], vboPositions.size() * sizeof(float));
m_vao->pushFloat(3);

View File

@ -59,7 +59,7 @@ namespace nf {
wglMakeCurrent(m_hdc, m_hglrc);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
Error("Could not initialize GLEW!");
NFError("Could not initialize GLEW!");
const int attrib[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
@ -71,7 +71,7 @@ namespace nf {
wglMakeCurrent(m_hdc, m_hglrc);
//TODO: Configure V-Sync with a custom max FPS
wglSwapIntervalEXT(0);
Log("OpenGL version: " + std::string((char*)glGetString(GL_VERSION)));
NFLog("OpenGL version: " + std::string((char*)glGetString(GL_VERSION)));
glDepthFunc(GL_LESS);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -137,23 +137,23 @@ namespace nf {
void Renderer::render(Entity& in) {
if (in.isConstructed() == false)
Error("Tried to render Entity before being created!");
NFError("Tried to render Entity before being created!");
m_lGame.push_back(&in);
//TODO: Sort transparent objects by distance; Farthest first
}
void Renderer::render(UIElement& in) {
if (in.isConstructed() == false)
Error("Tried to render a UI element before being created!");
NFError("Tried to render a UI element before being created!");
m_lUI.push_back(&in);
}
void Renderer::render(Light& in) {
if (in.isConstructed() == false)
Error("Tried to render a light before being created!");
NFError("Tried to render a light before being created!");
m_lights.push_back(&in);
}
void Renderer::render(Cubemap& in) {
if (in.isConstructed() == false)
Error("Tried to render a cubemap before being created!");
NFError("Tried to render a cubemap before being created!");
m_cubemap = &in;
}
@ -163,7 +163,7 @@ namespace nf {
glViewport(0, 0, m_app->getConfig().width, m_app->getConfig().height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 proj = glm::perspective(glm::radians(45.0f), (float)m_app->getConfig().width / (float)m_app->getConfig().height, 0.1f, 1000.0f);
camera->bind(m_gBufferShader, m_lightingShader, m_cubemapShader);
camera->update(m_gBufferShader, m_lightingShader, m_cubemapShader);
//First, fill the gBuffer with entities
m_gBufferShader->setUniform("proj", proj);
@ -284,7 +284,7 @@ namespace nf {
//Check for OpenGL errors
GLenum err = glGetError();
if (err != GL_NO_ERROR)
Error("OpenGL error " + std::to_string(err));
NFError("OpenGL error " + std::to_string(err));
//Show completed frame
SwapBuffers(m_hdc);
@ -292,7 +292,7 @@ namespace nf {
void Renderer::setAmbient(float am) {
if (am < 0.0f)
Error("Cannot have a negative ambient light strength!");
NFError("Cannot have a negative ambient light strength!");
m_lightingShader->setUniform("ambientStrength", am);
}

View File

@ -37,7 +37,7 @@ namespace nf {
char* message = new char[length];
glGetShaderInfoLog(curr, length, &length, message);
message[length - 2] = 0;
Error("OpenGL Error: " + (std::string)message);
NFError("OpenGL Error: " + (std::string)message);
}
}
glAttachShader(m_id, vs);
@ -51,7 +51,7 @@ namespace nf {
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length);
char* message = new char[length];
glGetProgramInfoLog(m_id, length, &length, message);
Error("OpenGL Error: " + (std::string)message);
NFError("OpenGL Error: " + (std::string)message);
}
glDetachShader(m_id, vs);
glDetachShader(m_id, fs);
@ -72,7 +72,7 @@ namespace nf {
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &length);
char* message = new char[length];
glGetProgramInfoLog(m_id, length, &length, message);
Error("OpenGL Error: " + (std::string)message);
NFError("OpenGL Error: " + (std::string)message);
}
}
@ -108,7 +108,7 @@ namespace nf {
void Shader::getUniformLocation(const std::string& uniformName) {
unsigned int loc = glGetUniformLocation(m_id, uniformName.c_str());
if (loc == -1)
Error("Uniform \"" + (std::string)uniformName + "\" does not exist!");
NFError("Uniform \"" + (std::string)uniformName + "\" does not exist!");
m_uniformLocations[uniformName] = loc;
}

View File

@ -18,7 +18,7 @@ namespace nf {
stbi_set_flip_vertically_on_load(true);
unsigned char* texture = stbi_load_from_memory((unsigned char*)tex->data, (unsigned int)tex->size, &m_x, &m_y, &nChannels, 0);
if (!texture)
Error("Texture failed to load from memory!");
NFError("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);

View File

@ -15,7 +15,7 @@ namespace nf {
void VertexArray::addBuffer(const void* data, const size_t size) {
if (!m_lastBufferHasLayout)
Error("Buffer added to vertex array has no layout!");
NFError("Buffer added to vertex array has no layout!");
m_buffers.push_back(new VertexBuffer(data, size));
m_buffers.back()->bind();
m_lastBufferHasLayout = false;
@ -24,14 +24,14 @@ namespace nf {
void VertexArray::pushFloat(unsigned int count) {
if (m_lastBufferHasLayout)
Error("Tried to modify a vertex array's buffer after the layout was final!");
NFError("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);
}
void VertexArray::pushInt(unsigned int count) {
if (m_lastBufferHasLayout)
Error("Tried to modify a vertex array's buffer after the layout was final!");
NFError("Tried to modify a vertex array's buffer after the layout was final!");
m_lastBufferLayout.push_back({ GL_INT, count, GL_FALSE });
m_lastStride += count * sizeof(GL_INT);
}
@ -53,9 +53,9 @@ namespace nf {
void VertexArray::bind() {
if (m_buffers.empty())
Error("No buffers and layouts added to vertex array before being bound!");
NFError("No buffers and layouts added to vertex array before being bound!");
if (!m_lastBufferHasLayout)
Error("Buffer added to vertex array has no layout!");
NFError("Buffer added to vertex array has no layout!");
glBindVertexArray(m_id);
}

View File

@ -114,7 +114,7 @@ namespace nf {
std::ofstream out;
out.open(filename, std::ios::binary);
if (!out)
Error("File \"" + (std::string)filename + (std::string)"\" could not be written!");
NFError("File \"" + (std::string)filename + (std::string)"\" could not be written!");
std::string write(in);
if (encrypted) {
for (unsigned int i = 0; i < write.size(); i++)
@ -132,7 +132,7 @@ namespace nf {
std::ifstream in;
in.open(filename, std::ios::binary);
if (!in)
Error("File \"" + (std::string)filename + (std::string)"\" could not be read!");
NFError("File \"" + (std::string)filename + (std::string)"\" could not be read!");
std::stringstream ss;
ss << in.rdbuf();
std::string read(ss.str());

View File

@ -2,53 +2,183 @@
#include <chrono>
#include <unordered_map>
#include <array>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "Config.h"
#include "IntroGamestate.h"
#include "Renderer.h"
#include "Gamestate.h"
#ifndef NFIMPL
#include "IntroGamestate.h"
#include "AudioEngine.h"
#ifdef NFENGINE
#include "PhysicsEngine.h"
#endif
//TODO: Document ALL frontend functions in new include files for the frontend only
namespace nf {
class AudioEngine;
class PhysicsEngine;
/**
* @brief Main class
*
* This class handles low-level Windows APIs and provides a window.
* Every NF applicaiton will create one.
*/
class Application {
public:
Application(Config& conf);
Application() = delete;
Application(Application& other) = delete;
/**
* @brief Main constructor
* @param conf Configuration to be applied to the app as default. Must be provided.
*/
Application(Config& conf);
/**
* @brief Sets the app's window icon
* @param hIcon Valid HICON loaded with a Windows API funciton like LoadIcon
*
* This also sets the window's taskbar icon.
*/
void setWindowIcon(HICON hIcon);
/**
* @brief Sets the app's cursor
* @param hCursor Valid HCURSOR loaded with a Windows API funciton like LoadCursor
*/
void setWindowCursor(HCURSOR hCursor);
/**
* @brief Adds a Gamestate to the app's available gamestates
* @param state Pointer to the Gamestate instance
* @param stateName Name of the state to be used later
*
* Gamestates can only be accessed in an app if this funciton has been called.
* The stateName is added to the app's list of states that can be switched to later.
*/
void addState(Gamestate* state, const std::string& stateName);
/**
* @brief Sets the state the app should switch to after the logo gamestate
* @param stateName Name of a priviously-added state
*
* @note The gamestate must have already been added to the app by calling addState.
*/
void setDefaultState(const std::string& stateName);
/**
* @brief Queries the name of the current gamestate
* @return Name of current gamestate
*/
const std::string& getDefaultState();
/**
* @brief Runs the application
*
* This funciton initializes and runs the main loop on the calling thread.
*
* @note This function will not return untill the engine exits.
*/
void run();
/**
* @brief Change to a different gamestate
* @param stateName name of the gamestate to switch to
*
* This function starts the process of unloading the current gamestate and loading
* a new one.
*
* @note The actual gamestate switching does not happen immediately before the next
* frame, but instead after a short amount of time for the engine to fade to a
* loading screen.
*/
void changeState(const std::string& stateName);
/**
* @brief Sets the visibility of the main window
* @param show Show the window?
*
* This function can be called at any time, regardless of the state of the application.
*/
void showWindow(bool show);
/**
* @brief Changes the app's config
* @param in The configuration to replace the current one
*
* This function reads in the new Config and sets up the engine to reflect it.
*
* @sa Config
*/
void changeConfig(const Config& in);
/**
* @brief Queries the current configuration
* @return A const reference to the current configuration of the app
*
* @sa Config
*/
const Config& getConfig() const;
/**
* @brief Queries the current FPS
* @return The current FPS
*
* @todo Start averaging the FPS instead of calculating it every frame.
*/
int getFPS() const;
/**
* @brief Queries if a certain key is currently down
* @param code An NFI code representing a keyboard key
* @return If the key is down
*
* This function returns true for every frame that a key is held down for. This is
* perfect for continuous movement or really anything that involves holding keys.
*/
bool isKeyHeld(unsigned int code);
/**
* @brief Queries if a certain key has been pressed
* @param code An NFI code representing a keyboard key
* @return If the key has been pressed
*
* This function returns true for only one frame that a key is held down for.
* This is perfect for toggling menus, actions, etc.
*/
bool isKeyPressed(unsigned int code);
/**
* @brief Queries if a certain mouse button is currently down
* @param code An NFI code representing a mouse button
* @return If the mouse button is down
*
* This function returns true for every frame that a mouse button is held down for.
* This is perfect for automatic weapons, dragging objects, etc.
*/
bool isMouseHeld(unsigned int code);
/**
* @brief Queries if a certain mouse button has been pressed
* @param code An NFI code representing a mouse button
* @return If the mouse button has been pressed
*
* This function returns true for only one frame that a mouse button is held down for.
* This is perfect for semi-automatic weapons, actions, etc.
*/
bool isMouseClicked(unsigned int code);
/**
* @brief Queries the cursor's current position in the window
* @return The coordinates of the cursor in window space
*
* A return value of (0, 0) represents the top-left corner of the window while
* a return value of (window width, window height) represents the bottom-right
* corner of the window.
*/
Vec2 getMousePos();
/**
* @brief Exits the main loop and cleans up the engine
*
* @todo Free up the possibility for an implementation to create another app
* before it exits.
*/
void quit();
#ifndef NFIMPL
Renderer* getRenderer() const;
AudioEngine* getAudioEngine() const;
PhysicsEngine* getPhysicsEngine() const;
void addState(Gamestate* state, const std::string& stateName);
void setDefaultState(const std::string& stateName);
const std::string& getDefaultState();
void run();
bool hasCustomWindowIcon();
void changeState(const std::string& stateName);
Gamestate* getCurrentState();
void showWindow(bool show);
const HWND& getWindow();
void changeConfig(const Config& in);
const Config& getConfig() const;
int getFPS() const;
bool isKeyHeld(unsigned int code);
bool isKeyPressed(unsigned int code);
bool isMouseClicked(unsigned int code);
bool isMouseHeld(unsigned int code);
void trackMouse(bool track);
void getMouseDiff(int& x, int& y);
Vec2 getMousePos();
static Application* getApp(bool first = false);
void quit();
#endif
~Application();
private:
void registerWindowClass();
@ -101,8 +231,10 @@ namespace nf {
//Renderer object to use OpenGL to render the current state
Renderer* m_renderer;
//Handles nf::Sound objects and calculates 3D sounds
AudioEngine* m_audio;
//Calculates physics
PhysicsEngine* m_physics;
};
}

View File

@ -72,37 +72,136 @@ namespace nf {
~ASound() override;
};
/**
* @brief A representation of a nfpack file
*
* With this class, you can access your custom assets with the get functions.
*/
class AssetPack : public NFObject {
public:
AssetPack(const AssetPack& other) = delete;
/**
* @brief Constructor
*
* See @ref obLifetime
*/
AssetPack();
/**
* @brief Loads a specified nfpack into memory
* @param packName name of pack to load relative to the `assets` directory
*
* After calling this function, future calls to @ref get will return an Asset pointer.
*
* @warning Because this function could take a considerable amount of time when
* dealing with very large packs, it is not recomended to call this function
* in a Gamestate::update or Gamestate::render function.
*/
void load(const char* packName);
/**
* @brief Queries whether or not a pack has been loaded
* @return If a pack is loaded
*/
bool isLoaded();
/**
* @brief Gets a specified Asset pointer from a string literal
* @param in name of asset file to retrieve
* @return An Asset pointer
*/
Asset* get(const char* in);
/**
* @brief Gets a specified Asset pointer from an std::string
* @param in name of asset file to retrieve
* @return An Asset pointer
*/
Asset* get(std::string& in);
/**
* @brief Gets a specified Asset pointer from a string literal
* @param in name of asset file to retrieve
* @return An Asset pointer
*
* This function allows you to get assets like this:
*
* ~~~
* Asset* model = assetPack["model.obj"];
* ~~~
*/
Asset* operator[](const char* in);
/**
* @brief Gets a specified Asset pointer from an std::string
* @param in name of asset file to retrieve
* @return An Asset pointer
*
* This function allows you to get assets like this:
*
* ~~~
* std::string str = "model.obj";
* Asset* model = assetPack[str];
* ~~~
*/
Asset* operator[](std::string& in);
void destroy() override;
/**
* @brief Unloads the pack from memory
*
* This function can be useful if you have an AssetPack object as a member of
* a Gamestate and want to unload it at a specific time.
*/
void unload();
void destroy() override;
~AssetPack();
private:
bool m_loaded;
std::unordered_map<std::string, Asset*> m_assets;
};
/**
* @brief A collection of a few defualt assets included in `base.nfpack`
*
* All models have a default, grey material.
*/
struct BaseAssets {
/**
* @brief A cube
*/
static AModel* cube;
/**
* @brief A flattened cube
*/
static AModel* plane;
/**
* @brief A sphere
*/
static AModel* sphere;
/**
* @brief A cone
*/
static AModel* cone;
/**
* @brief A cylinder
*/
static AModel* cylinder;
/**
* @brief A torus
*/
static AModel* torus;
/**
* @brief NF logo
*/
static ATexture* logo;
/**
* @brief Default cubemap
*/
static ACubemap* cubemap;
/**
* @brief Default font
*
* The default font is Segoe UI Light.
*/
static AFont* font;
/**
* @brief Default button textures
*
* @sa @ref customButtons
*/
static AButton* button;
};
}

View File

@ -10,15 +10,45 @@ namespace nf {
class Texture;
struct Asset;
/**
* @brief A UI button
*
* Buttons can be customized to use three different textures: an idle, hover, and pressed
* texture.
*
* @sa @ref customButtons
* @ref createUI
*/
class Button : public UIElement, public NFObject {
public:
Button(const Button& other) = delete;
/**
* @brief Constructor
*
* See @ref obLifetime
*/
Button();
/**
* @brief Creates a UI button
* @param position Position vector in screen space
* @param string Text to show on the button; Can be an empty string; Optional
* @param buttonAsset A custom button asset; Optional
* @param scale Scale of the button; Optional
* @param opacity Opacity of the button; Optional
*/
void create(const Vec2& position, std::string string = "", Asset* buttonAsset = nf::BaseAssets::button, float scale = 1.0f, float opacity = 1.0f);
/**
* @brief Queries whether or not the button has been clicked
* @return If the button has been clicked
*
* @note This function returns true for only one frame when the mouse button
* is released on top of the button.
*/
bool isClicked();
#ifndef NFIMPL
const char* identity() override;
void render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight, Application* app, Shader* textShader);
bool isClicked();
#endif
void destroy() override;
~Button();
private:

View File

@ -5,32 +5,110 @@ namespace nf {
class Application;
class Shader;
//TODO: Make sure there are always newlines here;
/**
* @brief The viewpoint for the engine
*/
class Camera {
public:
/**
* @brief Dictates the behavior of a camera's movement
*/
enum class Type {
/**
* @brief No mouse capture
*
* Perfect for selecting menus with the mouse
*/
UI,
/**
* @brief First-person mouse-look movement
*/
FIRST_PERSON,
/**
* @brief Orbit movement around either a position or Entity
*/
ORBIT,
/**
* @brief Fixed to either a position or Entity
*/
FIXED
};
#ifndef NFIMPL
Camera(Application* app);
#else
Camera() = delete;
Camera(const Camera& other) = delete;
#endif
/**
* @brief Sets the camera's type
* @param cameraType the @ref Type to change to
*/
void setType(Type cameraType);
/**
* @brief Queries the current @ref Type of the camera
* @return The current Type of the camera
*/
Type getType() const;
void moveForward(float speed);
void moveBackward(float speed);
void moveRight(float speed);
void moveLeft(float speed);
/**
* @brief Moves the camera given an offset
* @param offset Offset vector
*
* The x component of the offset is added to the x coordinate of the camera
* while the y component is added to the z coordinate.
*/
void move(const Vec2& offset);
/**
* @brief Moves the camera forwards and backwards
* @param offset The amount to move the camera in the Z direction
*/
void moveZ(float offset);
/**
* @brief Moves the camera left and right
* @param offset The amount to move the camera in the X direction
*/
void moveX(float offset);
/**
* @brief Sets the position of the camera with three floats
* @param x X component
* @param y Y component
* @param z Z component
*/
void setPosition(float x, float y, float z);
/**
* @brief Sets the position of the camera with a Vec3
* @param position Position vector
*/
void setPosition(const Vec3& position);
/**
* @brief Queries the position of the camera
* @return The position of the camera
*/
const Vec3& getPosition();
void setRotation(float x, float y);
/**
* @brief Sets the rotation of the camera given a pitch and yaw
* @param yaw Left and right rotation in degrees
* @param pitch Up and down rotation in degrees
*/
void setRotation(float yaw, float pitch);
/**
* @brief Sets the rotation of the camera given a Vec2
* @param rotation Rotation vector
*
* The x component of the rotation represents yaw (left and right rotation)
* while the y component represents pitch (up and down rotation).
* Both are in degrees.
*/
void setRotation(const Vec2& rotation);
/**
* @brief Gets the rotation of the camera
* @return The rotation of the camera
*/
const Vec3& getRotation();
void bind(Shader* gBufferShader, Shader* lightingShader, Shader* cubemapShader);
#ifndef NFIMPL
void update(Shader* gBufferShader, Shader* lightingShader, Shader* cubemapShader);
#endif
~Camera();
private:
Application* m_app;

View File

@ -1,11 +1,33 @@
#pragma once
namespace nf {
/**
* @brief Configuration for NF
*
* This struct contains basic information about the engine's window.
*
* @todo Add more things here such as mouse sensativity and FPS target?
*/
struct Config {
public:
/**
* @brief Width of the engine window (should fullscreen be false)
*/
unsigned int width;
/**
* @brief Height of the engine window (should fullscreen be false)
*/
unsigned int height;
/**
* @brief Sets fullscreen
*
* If fullscreen, the engine will be displayed at the current monitor's
* resolution.
*/
bool fullscreen;
/**
* @brief Title of the engine's window
*/
const char* title;
};
}

View File

@ -6,14 +6,38 @@ namespace nf {
struct Asset;
class Shader;
/**
* @brief A skybox in the background of a gamestate's world
*
* A cubemap is a cube with a texture on each one of its 6 sides.
*
* @sa @ref createCubemap @ref customCubemap
*/
class Cubemap : public Drawable, public NFObject {
public:
/**
* @brief Constructor
*
* See @ref obLifetime
*/
Cubemap();
/**
* @brief Creates a cubemap
* @param cubemapAsset A cubemap asset retrieved from an AssetPack
*
* This function will prepare the cubemap to be rendered.
*
* @warning Trying to render a cubemap before creating it will result in an error.
*/
void create(Asset* cubemapAsset);
/**
* @brief Queries whether or not the cubemap has been created
* @return If the cubemap has been created
*/
bool isConstructed();
#ifndef NFIMPL
void render(Shader* shader);
#endif
void destroy() override;
~Cubemap();
private:

View File

@ -2,7 +2,7 @@
#include "Assets.h"
#include "NFObject.h"
#include "Utility.h"
#ifdef NFENGINE
#ifndef NFIMPL
#include "glm/glm.hpp"
#endif
@ -10,45 +10,149 @@ namespace nf {
class Shader;
class Model;
/**
* @brief Represents a 3D object in the world
*
* Every entity has a position, rotation, and scale with respect to the world.
* Every entity also has an associated Model it was created with.
*/
class Entity : public NFObject {
public:
/**
* @brief Dictates the behavior of an entity in the physics simulation
*/
enum class Type {
/**
* @brief Will not move, but will participate in the simulation
*/
STATIC,
/**
* @brief Will move and participate in the simulation
*/
DYNAMIC,
/**
* @brief Will not move, but will participate in the simulation;
* This type allows concave meshes. This type is meant for environmental
* meshes such as landscapes and the insides of buildings or similar.
*/
MAP,
/**
* @brief Will not participate in the simulation; This is perfect for debris
* on the ground like trash or books.
*/
DETAIL
};
Entity(const Entity& other) = delete;
/**
* @brief Constructor
*
* See @ref obLifetime
*/
Entity();
/**
* @brief Creates an entity
* @param modelAsset A model Asset pointer
* @param type @ref Type of entity; Defaults to Type::STATIC
*
* This function will initialize an entity by loading its associated model from
* the modelAsset parameter.
*
* @warning Calling this function twice before the state exits will result in an
* error. See @ref isConstructed.
*/
void create(Asset* modelAsset, Type type = Type::STATIC);
/**
* @brief Queries whether or not the entity has been created
* @return If the entity has been created
*/
bool isConstructed();
/**
* @brief Queries the type of the entity
* @return The type of the entity
*/
Type getType();
/**
* @brief Sets the position of the origin of the entity with three floats
* @param x X component
* @param y Y component
* @param z Z component
*/
void setPosition(float x, float y, float z);
/**
* @brief Sets the position of the origin of the entity with a Vec3
* @param position The position vector
*/
void setPosition(const Vec3& position);
/**
* @brief Sets the rotation of the origin of the entity with three floats in degrees
* @param x X component
* @param y Y component
* @param z Z component
*/
void setRotation(float x, float y, float z);
/**
* @brief Sets the rotation of the origin of the entity with a Vec3
* @param rotation The rotation vector in degrees
*/
void setRotation(const Vec3& rotation);
/**
* @brief Sets the scale of the entity with three floats
* @param x X component
* @param y Y component
* @param z Z component
*/
void setScale(float x, float y, float z);
/**
* @brief Sets the scale of the entity with a Vec3
* @param scale The scale vector
*/
void setScale(const Vec3& scale);
/**
* @brief Sets the scale of the entity with a single scalar
* @param x The single scalar for all three axes
*/
void setScale(float x);
/**
* @brief Sets the linear velocy of the entity with three floats
* @param x X component
* @param y Y component
* @param z Z component
*/
void setVelocity(float x, float y, float z);
/**
* @brief Sets the linear velocy of the entity with a Vec3
* @param velocity The velocity vector
*/
void setVelocity(const Vec3& velocity);
/**
* @brief Sets the mass of the entity
* @param mass The mass
*
* Experiment with different values to get an idea of the scale of masses.
*/
void setMass(float mass);
/**
* @brief Queries the current position of the entity
* @return The entity's current position
*/
const Vec3& getPosition();
/**
* @brief Queries the current rotation of the entity
* @return The entity's current rotation as a quaternion
*/
const Vec4& getRotation();
/**
* @brief Queries the current scale of the entity
* @return The entity's current scale
*/
const Vec3& getScale();
#ifndef NFIMPL
void setPositionPhysics(const Vec3& position);
void setRotationPhysics(const Vec4& rotation);
bool needsPhysicsUpdate();
void render(Shader* shader, bool onlyDepth);
Model* getModel() const;
#ifdef NFENGINE
const glm::mat4 getModelMatrix();
#endif
void destroy() override;

View File

@ -13,31 +13,98 @@ namespace nf {
class Model;
class Texture;
/**
* @brief A state NF can be in that includes a collection of objects and user-defined
* behavior
*
* Every user-defined state inherits from this class.
*/
class Gamestate {
public:
Gamestate();
//TODO: Add this to other objects
Gamestate(const Gamestate& other) = delete;
/**
* @brief Default constructor; Must be used
*/
Gamestate();
/**
* @brief The state's 'constructor'
*
* This function runs when the state is started.
*/
virtual void onEnter();
/**
* @brief Update function
* @param deltaTime Amount of time the previous frame took to produce in seconds
*
* This function is called every frame. It is called before render.
*
* The deltaTime parameter's purpose is to create non-frame-dependant gameplay. This
* number should be multiplied with user numbers likes velocities. Doing this will
* produce output that will look the same on higher and lower framerates.
*/
virtual void update(float deltaTime);
/**
* @brief Render function
* @param renderer A reference to the Renderer object
*
* This function will contain calls to Renderer::render to decide what will be drawn
* on the next frame.
*
* @sa Renderer
*/
virtual void render(Renderer& renderer);
/**
* @brief The state's 'destructor'
*
* This function runs when the state is exited.
*
* It is imperitive that the class members are 'reset' back to their default values
* here. This does not include members of the Gamestate that are NF objects
* such as entites and UIElements.
*
* For more information see the @ref gamestates.
*/
virtual void onExit();
/**
* @brief Returns the state's Camera
* @return The state's camera
*/
Camera* getCamera();
/**
* @brief Sets the state's ambient light level
* @param stength Light level multiplier; Defaults to 0.1f
*
* An ambient light level of 0.0f is perfect for pitch dark rooms where no light means
* completely black while a level of 1.0f means full-bright.
*/
void setAmbientLight(float stength);
/**
* @brief Sets the state's gravity in a certain direction
* @param gravity A vector representing a direction the force of gravity should act in
* In units of Earth gravity
*
* The default gravity of a state is:
*
* ~~~
* Vec3(0.0, -1.0, 0.0);
* ~~~
*/
void setGravity(const Vec3& gravity);
/**
* @brief Sets the state's gravity downward
* @param strength A multiplier in units of Earth gravity
*
* The default is 1.0f;
*/
void setGravity(float strength);
#ifndef NFIMPL
void run(Application* app, bool physics = true);
bool isRunning();
bool isLoading();
virtual void onEnter();
virtual void update(float deltaTime);
virtual void render(Renderer& renderer);
Camera* getCamera();
//Defaults to 0.1f
void setAmbientLight(float stength);
//In units of Earth gravity (9.81 m/s^2)
void setGravity(const Vec3& gravity);
void setGravity(float strength);
virtual void onExit();
void stop();
#endif
//TODO: Probably change these to private members?
std::vector<NFObject*> m_nfObjects;
std::vector<Entity*> m_entsToDelete;
std::unordered_set<Model*> m_modelsToDelete;

View File

@ -5,27 +5,89 @@
namespace nf {
class Shader;
/**
* @brief A light in a gamestate's world
*
* Lights are completely dynamic and can have different colors and strengths. They
* are also movable.
*/
class Light : public NFObject {
public:
/**
* @brief Dictates the behavior of a light
*/
enum class Type {
DIRECTIONAL,
POINT
/**
* @brief A light that has a position in the world and casts light in every
* direction
*/
POINT,
/**
* @brief A light that has no position, but only a direction; Perfect for
* sunlight
*/
DIRECTIONAL
};
/**
* @brief Constructor
*
* See @ref obLifetime
*/
Light();
/**
* @brief Creates a light
* @param position Starting position vector of the light
* @param color Color vector in (red, green, blue) order from 0.0f to 1.0f
* @param strength Strength of the light; Optional
* @param type Type of the light; Optional
*/
void create(const Vec3& position, const Vec3& color, float strength = 1.0f, Type type = Type::POINT);
/**
* @brief Queries whether or not the light has been created
* @return If the light has been created
*/
bool isConstructed();
/**
* @brief Sets the position of the light with a Vec3
* @param position The position vector
*
* For directional lights, this will change the direction instead of the position.
*/
void setPosition(const Vec3& position);
/**
* @brief Sets the color of the light
* @param color The color vector in (red, green, blue) order from 0.0f to 1.0f
*/
void setColor(const Vec3& color);
/**
* @brief Sets the strength of the light
* @param strength The strength
*/
void setStrength(float strength);
void bind(Shader* shader, unsigned int lightNumber);
/**
* @brief Queries the type of the light
* @return The type of the light
*/
Type getType();
/**
* @brief Gets the position of the light
* @return The position of the light
*/
const Vec3& getPosition();
/**
* @brief Gets the color of the light
* @return The color vector
*/
const Vec3& getColor();
/**
* @brief Gets the strength of the light
* @return The strength
*/
const float getStrength();
#ifndef NFIMPL
void bind(Shader* shader, unsigned int lightNumber);
#endif
void destroy() override;
~Light();
private:

View File

@ -2,11 +2,11 @@
//TODO: Rework this file to only contain functions the frontend will need to access
//Maybe a implementation define here?
//TODO: Prevent including other headers other than this one
#include <chrono>
#include <unordered_map>
#include <array>
#include <Windows.h>
#ifndef NFIMPL
#define NFIMPL 1
#endif
#include "Config.h"
#include "Application.h"

View File

@ -17,22 +17,59 @@ namespace nf {
class VertexArray;
class IndexBuffer;
/**
* @brief Handles rendering user objects
*
* This should only be accessed in a gamestate's render function.
*
* @todo Maybe move to something like rendering everything automatically and adding a
* show function to entities and UI stuff?
*/
class Renderer {
public:
Renderer(Application* app);
/**
* @brief Renders an Entity
* @param in Entity to render
*
* This function adds an Entity to the list of entites to render in the next frame.
*
* @note An entity will participate in the physics simulation if it is setup to
* do so regardless of if it is rendered or not.
*/
void render(Entity& in);
/**
* @brief Renders a UIElement
* @param in UIElement to render
*
* This function adds a UIElement to the list UIElements to render in the next frame.
*/
void render(UIElement& in);
/**
* @brief Renders a Light
* @param in Light to render
*
* This function adds a Light to the list of lights to render in the next frame.
*/
void render(Light& in);
/**
* @brief Renders a Cubemap
* @param in Cubemap to render
*
* This function sets the next frame's Cubemap.
*
* @note Because only one Cubemap can be rendered in a frame, only the last call to
* this function before a frame is produced will take effect.
*/
void render(Cubemap& in);
#ifndef NFIMPL
void setFade(bool in, bool out, bool text = true);
bool isFadeOutComplete();
void render(Entity& in);
void render(UIElement& in);
void render(Light& in);
void render(Cubemap& in);
void doFrame(Camera* camera, float dT);
void setAmbient(float am);
Renderer(Application* app);
~Renderer();
#endif
private:
void loadBaseAssets();
void createShadowMaps();

View File

@ -7,15 +7,58 @@ namespace nf {
struct Asset;
class Entity;
/**
* @brief A stream of audio; Could be a sound effect or music
*
* NF currently supports WAV and Ogg Vorbis files.
*/
class Sound : public NFObject {
public:
/**
* @brief Constructor
*
* See @ref obLifetime
*/
Sound();
/**
* @brief Creates a sound
* @param soundAsset A sound asset retrieved from an AssetPack
*
* The referenced sound can be of any format. This function will take care of
* figuring that out and loading it accordingly.
*/
void create(Asset* soundAsset);
/**
* @brief Sets the volume of the sound
* @param volume Volume; Can be higher than 1.0f
*/
void setVolume(float volume);
/**
* @brief Sets the target Entity of the sound
* @param entity The target entity
*
* This function will bind the sound to a specific entity. When it is played,
* it will sound like the sound is coming from the target entity.
*/
void setEntity(Entity& entity);
/**
* @brief Sets the static location the sound should play at
* @param position A position vector
*/
void setPosition(const Vec3& position);
/**
* @brief Plays the sound
* @param loop If the sound should forever loop when it completes playing
*
* This function can be called multiple times to play multiple instances of the
* sound.
*/
void play(bool loop = false);
/**
* @brief Stops the sound
*
* This function will stop all instances of the sound if multiple are playing
*/
void stop();
void destroy() override;

View File

@ -19,18 +19,53 @@ namespace nf {
bool isBase = false;
};
/**
* @brief A UI string
*
* Custom fonts are supported. See @ref customFonts
*/
class Text : public UIElement, public NFObject {
public:
/**
* @brief Constructor
*
* See @ref obLifetime
*/
Text();
/**
* @brief Creates UI text
* @param string The text itself
* @param position Position vector in screen space
* @param color Color vector; Optional
* @param opacity Opacity of the text; Optional
* @param scale Scale of the text; Optional
* @param fontAsset Custom font asset; Optional
*/
void create(const std::string& string, const Vec2& position, const Vec3& color = {1.0, 1.0, 1.0}, float opacity = 1.0f, float scale = 1.0f, Asset* fontAsset = BaseAssets::font);
const char* identity() override;
/**
* @brief Sets the displayed text
* @param string The new text to display
*/
void setText(const std::string& string);
/**
* @brief Sets the text's color
* @param color The new color vector
*/
void setColor(const Vec3& color);
/**
* @brief Sets the text's scale
* @param scale The new scale
*/
void setScale(float scale);
/**
* @brief Sets the text's opacity
* @param opacity The new opacity
*/
void setOpacity(float opacity);
#ifndef NFIMPL
const char* identity() override;
void render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight, bool onButton = false, float buttonWidth = 0.0f, float buttonHeight = 0.0f, const Vec2& buttonPos = Vec2());
#endif
void destroy() override;
~Text();
private:

View File

@ -7,16 +7,41 @@ namespace nf {
class Texture;
struct Asset;
/**
* @brief A UI image
*
* This class represents a texture that can be added to the UI.
*/
class UITexture : public UIElement, public NFObject {
public:
/**
* @brief Constructor
*
* See @ref obLifetime
*/
UITexture();
/**
* @brief Creates a UI texture
* @param textureAsset Texture asset retrieved from an AssetPack
* @param position Position vector in screen space
* @param scale Scale of the texture
* @param opacity Opacity of the texture
*/
void create(Asset* textureAsset, const Vec2& position, float scale = 1.0f, float opacity = 1.0f);
const char* identity() override;
/**
* @brief Sets the texture's scale
* @param scale The new scale
*/
void setScale(float scale);
/**
* @brief Sets the texture's opacity
* @param opacity The new opacity
*/
void setOpacity(float opacity);
#ifndef NFIMPL
const char* identity() override;
void render(Shader* shader, unsigned int windowWidth, unsigned int windowHeight) override;
#endif
void destroy() override;
~UITexture();
private:

View File

@ -4,22 +4,48 @@
#include <string>
#include <Windows.h>
/**
* @brief Nothin' Fancy namespace
*
* Every class and struct lives inside of this namespace
*
* It could be useful to `using` this namespace:
*
* ~~~
* using namespace nf;
* ~~~
*/
namespace nf {
#ifdef _DEBUG
#if defined(_DEBUG) || defined(doxygen)
//Strips __FILE__ down to only the name of the file
#define __FILENAME__ strrchr(__FILE__, '\\') + 1
//Initializes static variables needed for debugging
#define DEBUGINIT std::chrono::steady_clock::time_point Debug::m_initTime = std::chrono::high_resolution_clock::now();
//Sleep for an amount of seconds
#define SleepS(x) std::this_thread::sleep_for(std::chrono::seconds(x))
//Sleep for an amount of milliseconds
#define SleepMS(x) std::this_thread::sleep_for(std::chrono::milliseconds(x))
//Prints a nicely-formatted message complete with a timestamp
#define Log(x) nf::Debug::LogImp(x)
//Prints error message and breaks the debugger in debug mode
#define Error(x) {nf::Debug::ErrorImp(x,__FILENAME__, __LINE__);\
#define NFDEBUGINIT std::chrono::steady_clock::time_point Debug::m_initTime = std::chrono::high_resolution_clock::now();
/**
* Pauses the engine for a set amount of seconds
*/
#define NFSleepS(x) std::this_thread::sleep_for(std::chrono::seconds(x))
/**
* Pauses the engine for a set amount of milliseconds
*/
#define NFSleepMS(x) std::this_thread::sleep_for(std::chrono::milliseconds(x))
/**
* In debug mode, this prints a nicely-formatted message complete with a timestamp.
*
* In release mode, this does nothing.
*/
#define NFLog(x) nf::Debug::LogImp(x)
/**
* In debug mode, the error message is printed to the console and the debugger is broken.
*
* In release mode, the error message is shown in a message box and the application
* closes when the message box is closed.
*/
#define NFError(x) {nf::Debug::ErrorImp(x,__FILENAME__, __LINE__);\
__debugbreak();}
/**
* @brief Handles NFLog and NFError calls
*/
class Debug {
private:
static std::chrono::steady_clock::time_point m_initTime;
@ -33,24 +59,70 @@ __debugbreak();}
static void ErrorImp(const std::string& in, const char* filename, int line);
};
#else
#define DEBUGINIT
#define Log(x)
//Shows error dialog with specified message then exits
#define Error(x) {MessageBox(FindWindow(L"NFClass", NULL), toWide(x).data(), L"NF Engine Error", MB_OK | MB_ICONERROR);\
#define NFDEBUGINIT
#define NFSleepS(x)
#define NFSleepMS(x)
#define NFLog(x)
#define NFError(x) {MessageBox(FindWindow(L"NFClass", NULL), toWide(x).data(), L"NF Engine Error", MB_OK | MB_ICONERROR);\
std::exit(-1);}
#endif
/**
* @brief Two component vector
*
* Similar to Vec3 and Vec4.
*
* Supports operators + - * / += -= *= /= ==
*/
struct Vec2 {
Vec2() : x(0.0), y(0.0) {}
/**
* @brief Default constructor
*
* Initializes all components to 0.0f
*/
Vec2() : x(0.0f), y(0.0f) {}
/**
* @brief Single constructor
* @param x1
*
* Sets all components to x1
*/
Vec2(float x1) : x(x1), y(x1) {}
/**
* @brief Double constructor
* @param x1
* @param y1
*
* Initializes the vector with the specified values
*/
Vec2(float x1, float y1) : x(x1), y(y1) {}
/**
* @brief Single constructor (double version)
* @param x1
*
* Double compatibility
*/
Vec2(double x1) : x((float)x1), y((float)x1) {}
/**
* @brief Double constructor (double version)
* @param x1
* @param y1
*
* Double compatibility
*/
Vec2(double x1, double y1) : x((float)x1), y((float)y1) {}
Vec2 operator+(const Vec2& rhs) const {
return Vec2(x + rhs.x, y + rhs.y);
}
Vec2 operator-(const Vec2& rhs) const {
return Vec2(x - rhs.x, y - rhs.y);
}
Vec2 operator*(const float scalar) const {
return Vec2(x * scalar, y * scalar);
}
Vec2 operator/(const Vec2& rhs) const {
return Vec2(x / rhs.x, y / rhs.y);
}
Vec2& operator+=(const Vec2& rhs) {
this->x += rhs.x;
this->y += rhs.y;
@ -61,23 +133,86 @@ std::exit(-1);}
this->y -= rhs.y;
return *this;
}
Vec2& operator*=(const Vec2& rhs) {
this->x *= rhs.x;
this->y *= rhs.y;
return *this;
}
Vec2& operator/=(const Vec2& rhs) {
this->x /= rhs.x;
this->y /= rhs.y;
return *this;
}
bool operator==(const Vec2& rhs) {
return this->x == rhs.x && this->y == rhs.y;
}
float x, y;
/**
* @brief X component
*/
float x;
/**
* @brief Y components
*/
float y;
};
/**
* @brief Three component vector
*
* Similar to Vec2 and Vec4
*
* Supports operators + - * / += -= *= /= ==
*/
struct Vec3 {
Vec3() : x(0.0), y(0.0), z(0.0) {}
/**
* @brief Default constructor
*
* Initializes all components to 0.0f
*/
Vec3() : x(0.0f), y(0.0f), z(0.0f) {}
/**
* @brief Single constructor
* @param x1
*
* Sets all components to x1
*/
Vec3(float x1) : x(x1), y(x1), z(x1) {}
/**
* @brief Triple constructor
* @param x1
* @param y1
* @param z1
*
* Initializes the vector with the specified values
*/
Vec3(float x1, float y1, float z1) : x(x1), y(y1), z(z1) {}
/**
* @brief Single constructor (double version)
* @param x1
*
* Double compatibility
*/
Vec3(double x1) : x((float)x1), y((float)x1), z((float)x1) {}
/**
* @brief Triple constructor (double version)
* @param x1
* @param y1
* @param z1
*
* Double compatibility
*/
Vec3(double x1, double y1, double z1) : x((float)x1), y((float)y1), z((float)z1) {}
Vec3 operator+(const Vec3& rhs) const {
return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
}
Vec3 operator-(const Vec3& rhs) const {
return Vec3(x - rhs.x, y - rhs.y, z - rhs.z);
}
Vec3 operator*(const float scalar) const {
return Vec3(x * scalar, y * scalar, z * scalar);
}
Vec3 operator/(const Vec3& rhs) const {
return Vec3(x / rhs.x, y / rhs.y, z / rhs.z);
}
Vec3& operator+=(const Vec3& rhs) {
this->x += rhs.x;
this->y += rhs.y;
@ -90,23 +225,94 @@ std::exit(-1);}
this->z -= rhs.z;
return *this;
}
Vec3& operator*=(const Vec3& rhs) {
this->x *= rhs.x;
this->y *= rhs.y;
this->z *= rhs.z;
return *this;
}
Vec3& operator/=(const Vec3& rhs) {
this->x /= rhs.x;
this->y /= rhs.y;
this->z /= rhs.z;
return *this;
}
bool operator==(const Vec3& rhs) {
return this->x == rhs.x && this->y == rhs.y && this->z == rhs.z ;
}
float x, y, z;
/**
* @brief X component
*/
float x;
/**
* @brief Y component
*/
float y;
/**
* @brief Z component
*/
float z;
};
/**
* @brief Four component vector
*
* Similar to Vec2 and Vec3
*
* Supports operators + - * / += -= *= /= ==
*/
struct Vec4 {
Vec4() : x(0.0), y(0.0), z(0.0), w(0.0) {}
/**
* @brief Default constructor
*
* Initializes all components to 0.0f
*/
Vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {}
/**
* @brief Single constructor
* @param x1
*
* Sets all components to x1
*/
Vec4(float x1) : x(x1), y(x1), z(x1), w(x1) {}
/**
* @brief Quadruple constructor
* @param x1
* @param y1
* @param z1
* @param w1
*
* Initializes the vector with the specified values
*/
Vec4(float x1, float y1, float z1, float w1) : x(x1), y(y1), z(z1), w(w1) {}
/**
* @brief Single constructor (double version)
* @param x1
*
* Double compatibility
*/
Vec4(double x1) : x((float)x1), y((float)x1), z((float)x1), w((float)x1) {}
/**
* @brief Quadruple constructor (double version)
* @param x1
* @param y1
* @param z1
* @param w1
*
* Double compatibility
*/
Vec4(double x1, double y1, double z1, double w1) : x((float)x1), y((float)y1), z((float)z1), w((float)w1) {}
Vec4 operator+(const Vec4& rhs) const {
return Vec4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w);
}
Vec4 operator-(const Vec4& rhs) const {
return Vec4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w);
}
Vec4 operator*(const float scalar) const {
return Vec4(x * scalar, y * scalar, z * scalar, w * scalar);
}
Vec4 operator/(const Vec4& rhs) const {
return Vec4(x / rhs.x, y / rhs.y, z / rhs.z, w / rhs.w);
}
Vec4& operator+=(const Vec4& rhs) {
this->x += rhs.x;
this->y += rhs.y;
@ -121,10 +327,39 @@ std::exit(-1);}
this->w -= rhs.w;
return *this;
}
Vec4& operator*=(const Vec4& rhs) {
this->x *= rhs.x;
this->y *= rhs.y;
this->z *= rhs.z;
this->w *= rhs.w;
return *this;
}
Vec4& operator/=(const Vec4& rhs) {
this->x /= rhs.x;
this->y /= rhs.y;
this->z /= rhs.z;
this->w /= rhs.w;
return *this;
}
bool operator==(const Vec4& rhs) {
return this->x == rhs.x && this->y == rhs.y && this->z == rhs.z && this->w == rhs.w;
}
float x, y, z, w;
/**
* @brief X component
*/
float x;
/**
* @brief Y component
*/
float y;
/**
* @brief Z component
*/
float z;
/**
* @brief W component
*/
float w;
};
const std::wstring toWide(const char* in);
@ -132,6 +367,26 @@ std::exit(-1);}
Vec4 degToQuat(const Vec3& in);
/**
* @brief Writes a stream of bytes as as std::string into a file in a specified location
* @param filename Path and name of file to be written, including extensions; Relative or absolute
* @param in Input std::string to be written
* @param encrypted Write the file encrypted?
*
* This function, as well as readFile, supports a basic and unsecure form of encryption.
* This is meant to discourage players from easily modifying stats, saves, etc.
*/
void writeFile(const std::string& filename, const std::string& in, bool encrypted = false);
/**
* @brief Reads a file's bytes into an std::string
* @param filename Path and name of file to be read, including extensions; Relative or absolute
* @param compressed Internal use only as of now
* @return An std::string containing the specified file's bytes
*
* This function automatically detects whether or not the target file is encrypted
* and decrypts it if it is.
*
* @todo If files aren't found, the engine errors. Change this.
*/
std::string readFile(const std::string& filename, bool compressed = false);
}

346
docs/Doxyfile Normal file
View File

@ -0,0 +1,346 @@
# Doxyfile 1.9.2
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "Nothin' Fancy"
PROJECT_NUMBER = 0.1
PROJECT_BRIEF = "C++ 3D Game Engine"
PROJECT_LOGO = images/logo.png
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
JAVADOC_BANNER = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
PYTHON_DOCSTRING = YES
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
OPTIMIZE_OUTPUT_SLICE = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 1
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PRIV_VIRTUAL = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = NO
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
RESOLVE_UNNAMED_PARAMS = YES
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = NO
HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
SHOW_HEADERFILE = YES
SHOW_INCLUDE_FILES = NO
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
STRICT_PROTO_MATCHING = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE = layout.xml
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_IF_INCOMPLETE_DOC = YES
WARN_NO_PARAMDOC = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = pages \
../NothinFancy/src/include
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h \
*.md
RECURSIVE = YES
EXCLUDE = ../NothinFancy/src/include/IntroGamestate.h
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH = examples
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH = images
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE = main.md
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
SOURCE_TOOLTIPS = YES
USE_HTAGS = NO
VERBATIM_HEADERS = NO
CLANG_ASSISTED_PARSING = NO
CLANG_ADD_INC_PATHS = YES
CLANG_OPTIONS =
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = manual
HTML_FILE_EXTENSION = .html
HTML_HEADER = header.html
HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET = theme.css
HTML_EXTRA_FILES = favicon.png
HTML_COLORSTYLE_HUE = 30
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = NO
HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = YES
FULL_SIDEBAR = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
FORMULA_MACROFILE =
USE_MATHJAX = NO
MATHJAX_VERSION = MathJax_2
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH =
MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE =
SEARCHENGINE = YES
SERVER_BASED_SEARCH = NO
EXTERNAL_SEARCH = NO
SEARCHENGINE_URL =
SEARCHDATA_FILE = searchdata.xml
EXTERNAL_SEARCH_ID =
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME =
MAKEINDEX_CMD_NAME = makeindex
LATEX_MAKEINDEX_CMD = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_SUBDIR =
MAN_LINKS = NO
#---------------------------------------------------------------------------
# Configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = doxygen
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10
DOT_UML_DETAILS = NO
DOT_WRAP_THRESHOLD = 17
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES

BIN
docs/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

74
docs/header.html Normal file
View File

@ -0,0 +1,74 @@
<!-- HTML header for doxygen 1.9.2-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="shortcut icon" type="image/png" href="$relpath^favicon.png"/>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
<script type="text/javascript">var page_layout=1;</script>
<!--END FULL_SIDEBAR-->
<!--END DISABLE_INDEX-->
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
</head>
<body>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
<div id="side-nav" class="ui-resizable side-nav-resizable"><!-- do not remove this div, it is closed by doxygen! -->
<!--END FULL_SIDEBAR-->
<!--END DISABLE_INDEX-->
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">$projectname<!--BEGIN PROJECT_NUMBER--><span id="projectnumber">&#160;$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
<!--END !PROJECT_NAME-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<!--BEGIN !FULL_SIDEBAR-->
<td>$searchbox</td>
<!--END !FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
<!--BEGIN SEARCHENGINE-->
<!--BEGIN FULL_SIDEBAR-->
<tr><td colspan="2">$searchbox</td></tr>
<!--END FULL_SIDEBAR-->
<!--END SEARCHENGINE-->
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

BIN
docs/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
docs/images/logofull.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 937 KiB

240
docs/layout.xml Normal file
View File

@ -0,0 +1,240 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.9.2 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="yes" title="API">
<tab type="namespacelist" visible="yes" title="Class List" intro="Here, you can find a list of every useful class to use in NF."/>
<tab type="namespacemembers" visible="no" title="" intro=""/>
</tab>
<tab type="concepts" visible="yes" title="">
</tab>
<tab type="interfaces" visible="yes" title="">
<tab type="interfacelist" visible="yes" title="" intro=""/>
<tab type="interfaceindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="interfacehierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="no" title="API">
<tab type="classlist" visible="no" title="Classes" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="no" title="" intro=""/>
</tab>
<tab type="structs" visible="yes" title="">
<tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
</tab>
<tab type="exceptions" visible="yes" title="">
<tab type="exceptionlist" visible="yes" title="" intro=""/>
<tab type="exceptionindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="exceptionhierarchy" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="no" title="">
<tab type="filelist" visible="no" title="" intro=""/>
<tab type="globals" visible="no" title="" intro=""/>
</tab>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<concepts visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a concept page -->
<concept>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<definition visible="yes" title=""/>
<detaileddescription title=""/>
<authorsection visible="yes"/>
</concept>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

19
docs/pages/1_install.md Normal file
View File

@ -0,0 +1,19 @@
@page install Installation
@tableofcontents
This page details how to install NF in a MSVC project.
@section prereq Prerequisites
In order to create an NF application, you must first have the following:
- Visual Studio 2022 or later (MSVC v143 or later)
- A 64 bit computer as NF is 64 bit only
- A compatible graphics card (See @ref issues)
- Apt C++ knowledge
- The engine itself
@todo Link download here?
@section projSetup Step One: Project Setup
@note kdlsjfldksjf

21
docs/pages/2_tutorial.md Normal file
View File

@ -0,0 +1,21 @@
@page tutorial Tutorial
@tableofcontents
This tutorial aims to teach the basics of the engine and how to use it.
First, follow the steps on the @ref install page. Once NF has been installed into a new
MSVC project in Visual Studio, you can begin here.
@section createConfig Creating a Config
@todo The tutorial page
@section createUI Creating a UI
@section createCubemap Adding a Cubemap (Skybox)
@todo Lighting page?
@image html logofull.png "NF Logo" width=200px
Really cool

View File

@ -0,0 +1,8 @@
@page gamestates Gamestate System
@tableofcontents
@todo The gamestates page
@section enterAndExit onEnter and onExit
@section obLifetime Object Lifetime

13
docs/pages/4_assets.md Normal file
View File

@ -0,0 +1,13 @@
@page assets Asset System
This page details NF's asset system and custom pack format.
@section buildAssets How to Build Your Assets
@todo Asset system page
@section customFonts Custom Font Assets
@section customButtons Custom Button Assets
@section customCubemap Custom Cubemap Assets

6
docs/pages/5_issues.md Normal file
View File

@ -0,0 +1,6 @@
@page issues Known Issues
This page includes the known issues of the engine in order of importance.
1. Shader compilation errors
- This issue is caused by differences in graphics drivers and what exact OpenGL shader code they will compile. **This issue will be attended to soon.**

35
docs/pages/main.md Normal file
View File

@ -0,0 +1,35 @@
@tableofcontents
Nothin' Fancy (abbreviated as NF) is an experimental 3D game engine written in C++
for Windows. It was created by Grayson Riffe in 2021. This manual aims to aid the end-user
with using this engine to create games and visualizations. It contains a user guide and
the API reference.
@image html logofull.png "Engine Logo" width=200px
Features
===
In its current form, NF is always changing and evolving, so some of these features could change
at any time.
- @ref gamestates
- @ref assets
- Easy-to-use input
- Deffered renderer
- Materials system
- Color, specular, and normal texture support
- Cubemap support
- 3D sound support
- Rigid body physics
- Customizable UI
- Text
- Textures
- Buttons also with customizable textures
Example App
===
You can download the source or build for the example game that includes all of the
aforementioned features.
@todo Example App download

1827
docs/theme.css Normal file

File diff suppressed because it is too large Load Diff