Compare commits

..

No commits in common. "master" and "v0.5.0" have entirely different histories.

32 changed files with 113 additions and 475 deletions

View File

@ -5,10 +5,6 @@
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="ProdDebug|x64">
<Configuration>ProdDebug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@ -28,12 +24,6 @@
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
@ -49,9 +39,6 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
@ -61,11 +48,6 @@
<OutDir>$(ProjectDir)bin\$(Platform)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)int\$(Platform)$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'">
<OutDir>$(ProjectDir)bin\$(Platform)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)int\$(Platform)$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)bin\$(Platform)$(Configuration)\</OutDir>
@ -75,7 +57,7 @@
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFDEBUG;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(SolutionDir)NothinFancy\src\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>
@ -96,37 +78,6 @@ if exist "$(OutDir)assets" (rmdir "$(OutDir)assets" /S /Q &amp;&amp; goto end) e
mkdir "$(OutDir)assets"
move "*.nfpack" "$(OutDir)assets\"
cd "$(SolutionDir)NothinFancy\assets"
if exist "base.nfpack" (copy "base.nfpack" "$(OutDir)assets\")</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFDEBUG;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(SolutionDir)NothinFancy\src\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EntryPointSymbol>mainCRTStartup</EntryPointSymbol>
<IgnoreSpecificDefaultLibraries>libcmt.lib</IgnoreSpecificDefaultLibraries>
<AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
<LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>
</Link>
<PostBuildEvent>
<Command>cd assets
"$(SolutionDir)NFAssetBuilder\bin\x64Release\NFAssetBuilder.exe"
if exist "$(OutDir)assets" (rmdir "$(OutDir)assets" /S /Q &amp;&amp; goto end) else goto end
:end
mkdir "$(OutDir)assets"
move "*.nfpack" "$(OutDir)assets\"
cd "$(SolutionDir)NothinFancy\assets"
if exist "base.nfpack" (copy "base.nfpack" "$(OutDir)assets\")</Command>
</PostBuildEvent>
</ItemDefinitionGroup>

View File

@ -7,10 +7,6 @@
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'">
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerWorkingDirectory>$(OutDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>

View File

@ -7,9 +7,11 @@
#include <set>
void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) {
std::vector<char> obj(&OBJin[0], &OBJin[0] + OBJin.size());
std::vector<char> mtl(&MTLin[0], &MTLin[0] + MTLin.size());
std::unordered_map<std::string, TempMaterial*> mats;
parseMaterials(mats, MTLin);
parseMaterials(mats, mtl);
std::vector<float> vbRaw, tcRaw, vnRaw;
std::string usingMat;
@ -17,16 +19,19 @@ void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) {
bool tcPresent = false, vnPresent = false;
size_t position = 0;
std::stringstream ss(OBJin);
std::string line;
while (std::getline(ss, line)) {
std::stringstream ss2(line);
while (true) {
size_t nextLine = std::search(obj.begin() + position, obj.end(), "\n", "\n" + std::strlen("\n")) - (obj.begin() + position);
if (!nextLine)
break;
std::vector<char> line(&obj[position], &obj[position + nextLine]);
position += nextLine + 1;
std::stringstream ss(std::string(&line[0], line.size()));
std::string firstWord;
ss2 >> firstWord;
ss >> firstWord;
if (std::strcmp(&firstWord[0], "v") == 0) {
float x = 0.0f, y = 0.0f, z = 0.0f;
ss2 >> x >> y >> z;
ss >> x >> y >> z;
vbRaw.push_back(x);
vbRaw.push_back(y);
vbRaw.push_back(z);
@ -34,21 +39,21 @@ void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) {
else if (std::strcmp(&firstWord[0], "vt") == 0) {
tcPresent = true;
float u = 0.0f, v = 0.0f;
ss2 >> u >> v;
ss >> u >> v;
tcRaw.push_back(u);
tcRaw.push_back(v);
}
else if (std::strcmp(&firstWord[0], "vn") == 0) {
vnPresent = true;
float x = 0.0f, y = 0.0f, z = 0.0f;
ss2 >> x >> y >> z;
ss >> x >> y >> z;
vnRaw.push_back(x);
vnRaw.push_back(y);
vnRaw.push_back(z);
}
else if (std::strcmp(&firstWord[0], "usemtl") == 0) {
std::string matName;
ss2 >> matName;
ss >> matName;
usingMat = matName;
}
else if (std::strcmp(&firstWord[0], "f") == 0) {
@ -59,8 +64,8 @@ void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) {
unsigned int vertexIndex[3], uvIndex[3], vnIndex[3];
char temp;
ss2 >> 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 (ss2.rdbuf()->in_avail() > 1)
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!");
mats[usingMat]->vbIndices.push_back(vertexIndex[0]);
mats[usingMat]->vbIndices.push_back(vertexIndex[1]);
@ -257,41 +262,43 @@ void cookModel(std::string& OBJin, std::string& MTLin, std::string& out) {
out.append((char*)vboIndices.data(), indicesSize);
}
void parseMaterials(std::unordered_map<std::string, TempMaterial*>& mats, std::string& mtl) {
void parseMaterials(std::unordered_map<std::string, TempMaterial*>& mats, std::vector<char>& mtl) {
std::string currMat;
size_t position = 0;
std::stringstream ss(mtl);
std::string line;
while (std::getline(ss, line)) {
std::stringstream ss2(line);
while (true) {
size_t nextLine = std::search(mtl.begin() + position, mtl.end(), "\n", "\n" + std::strlen("\n")) - (mtl.begin() + position);
if (position + nextLine >= mtl.size())
break;
std::vector<char> line(&mtl[position], &mtl[position + nextLine]);
position += nextLine + 1;
std::stringstream ss(std::string(&line[0], line.size()));
std::string firstWord;
ss2 >> firstWord;
ss >> firstWord;
if (std::strcmp(&firstWord[0], "newmtl") == 0) {
ss2 >> currMat;
ss >> currMat;
mats[currMat] = new TempMaterial;
}
else if (std::strcmp(&firstWord[0], "Kd") == 0) {
float r = 0.0f, g = 0.0f, b = 0.0f;
ss2 >> r >> g >> b;
ss >> r >> g >> b;
mats[currMat]->diffuseColor = Vec3(r, g, b);
}
else if (std::strcmp(&firstWord[0], "map_Kd") == 0) {
std::string texName = getTextureName(ss2);
std::string texName = getNewLine(ss);
mats[currMat]->diffuseTextureName = texName;
}
else if (std::strcmp(&firstWord[0], "map_Ks") == 0) {
std::string texName = getTextureName(ss2);
std::string texName = getNewLine(ss);
mats[currMat]->specularTextureName = texName;
}
else if (std::strcmp(&firstWord[0], "map_Bump") == 0) {
std::string texName = getTextureName(ss2);
std::string texName = getNewLine(ss);
mats[currMat]->normalTextureName = texName;
}
else if (std::strcmp(&firstWord[0], "Ns") == 0) {
float s = 0.0f;
ss2 >> s;
ss >> s;
mats[currMat]->shininess = s;
}
}
@ -323,12 +330,4 @@ std::vector<std::string> getNeededTextures(std::string mtl) {
for (const auto& curr : tex)
out.push_back(curr);
return out;
}
std::string getTextureName(std::stringstream& ss) {
std::string out;
std::getline(ss, out);
out = out.substr(out.find_last_of("\\/") + 1);
return out;
}

View File

@ -27,6 +27,5 @@ struct TempMaterial {
};
void cookModel(std::string& in, std::string& MTLin, std::string& out);
void parseMaterials(std::unordered_map<std::string, TempMaterial*>& mats, std::string& mtl);
std::vector<std::string> getNeededTextures(std::string mtl);
std::string getTextureName(std::stringstream& ss);
void parseMaterials(std::unordered_map<std::string, TempMaterial*>& mats, std::vector<char>& mtl);
std::vector<std::string> getNeededTextures(std::string mtl);

View File

@ -5,10 +5,6 @@
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="ProdDebug|x64">
<Configuration>ProdDebug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
@ -35,13 +31,6 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@ -53,9 +42,6 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
@ -67,16 +53,11 @@
<OutDir>$(ProjectDir)bin\$(Platform)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)int\$(Platform)$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(ProjectDir)bin\$(Platform)$(Configuration)\</OutDir>
<IntDir>$(ProjectDir)int\$(Platform)$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFDEBUG;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>
@ -135,43 +116,6 @@
<PostBuildEvent />
<PostBuildEvent>
<Command>cd assets
"$(SolutionDir)NFAssetBuilder\bin\x64Release\NFAssetBuilder.exe"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ProdDebug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NFDEBUG;GLEW_STATIC;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(ProjectDir)src\include\;$(ProjectDir)dep\include\</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)obj\</ObjectFileName>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<TreatWarningAsError>true</TreatWarningAsError>
<WholeProgramOptimization>false</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
<Lib>
<AdditionalDependencies>glew32s.lib;opengl32.lib;freetype.lib;xaudio2.lib;Cabinet.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;PhysXFoundation.lib;PhysXCommon.lib;PhysX.lib;PhysXCooking.lib;PhysXExtensions.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Lib>
<Lib>
<AdditionalLibraryDirectories>$(ProjectDir)dep\lib\Release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4006 %(AdditionalOptions)</AdditionalOptions>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
</Lib>
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
<PostBuildEvent />
<PostBuildEvent>
<Command>cd assets
"$(SolutionDir)NFAssetBuilder\bin\x64Release\NFAssetBuilder.exe"</Command>
</PostBuildEvent>
</ItemDefinitionGroup>

View File

@ -80,7 +80,7 @@ namespace nf {
void Application::run() {
NFLog("Running application...");
#ifdef NFDEBUG
#ifdef _DEBUG
Debug::startTimer();
SetThreadDescription(GetCurrentThread(), L"Input Thread");
SetConsoleTitle(toWide("Nothin' Fancy v" + (std::string)NFVERSION).data());
@ -115,10 +115,9 @@ namespace nf {
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
mainThread.join();
#ifdef NFDEBUG
#ifdef _DEBUG
Debug::stopTimer();
#endif
NFLog("Exited application");
}
bool Application::hasCustomWindowIcon() {
@ -313,7 +312,7 @@ namespace nf {
}
void Application::runMainGameThread() {
#ifdef NFDEBUG
#ifdef _DEBUG
SetThreadDescription(GetCurrentThread(), L"Main Engine Thread");
#endif
m_renderer = new Renderer(this);
@ -340,8 +339,14 @@ namespace nf {
m_fpsClock2 = std::chrono::steady_clock::now();
m_fpsDuration = m_fpsClock2 - m_fpsClock1;
if (m_fpsDuration.count() >= 0.1) {
if (m_fpsDuration.count() >= 0.2) {
m_FPS = (int)std::round(1.0 / m_deltaTime);
#ifdef _DEBUG
static int i = 0;
i++;
if (i % 5 == 0)
NFLog("FPS: " + std::to_string(m_FPS));
#endif
m_fpsClock1 = std::chrono::steady_clock::now();
}
}
@ -447,6 +452,7 @@ namespace nf {
break;
}
case WM_CLOSE: {
NFLog("Exiting NF application");
DestroyWindow(hWnd);
return 0;
}

View File

@ -59,7 +59,7 @@ namespace nf {
}
void AudioEngine::runAudioThread() {
#ifdef NFDEBUG
#ifdef _DEBUG
SetThreadDescription(GetCurrentThread(), L"Audio Thread");
#endif
//Wait to initialize stuff until the master voice is created if it hasn't been already

View File

@ -7,7 +7,7 @@
namespace nf {
class PhysicsErrorCallback : public PxErrorCallback {
virtual void reportError(PxErrorCode::Enum code, const char* message, const char* file, int line) {
#ifdef NFDEBUG
#ifdef _DEBUG
Debug::ErrorImp(message, file, line);
__debugbreak();
#else

View File

@ -16,10 +16,8 @@ namespace nf {
static const float deg2rad = (float)M_PI / 180.0f;
#ifdef NFDEBUG
std::chrono::steady_clock::time_point Debug::m_initTime = std::chrono::high_resolution_clock::now();
bool Debug::m_timerStarted = false;
static HANDLE cmd = GetStdHandle(STD_OUTPUT_HANDLE);
#ifdef _DEBUG
NFDEBUGINIT;
void Debug::startTimer() {
m_timerStarted = true;
@ -33,34 +31,45 @@ namespace nf {
void Debug::LogImp(const char* in) {
if(m_timerStarted)
printCurrentTime();
std::printf("NF ");
SetConsoleTextAttribute(cmd, 6);
std::printf("Log");
SetConsoleTextAttribute(cmd, 7);
std::printf(": %s\n", in);
std::printf("NF Log: %s\n", in);
}
void Debug::LogImp(const std::string& in) {
LogImp(in.c_str());
if (m_timerStarted)
printCurrentTime();
std::printf("NF Log: ");
std::cout << in << "\n";
}
void Debug::LogImp(int in) {
LogImp(std::to_string(in));
if (m_timerStarted)
printCurrentTime();
std::printf("NF Log: %i\n", in);
}
void Debug::LogImp(float in) {
LogImp(std::to_string(in));
if (m_timerStarted)
printCurrentTime();
std::printf("NF Log: %.4f\n", in);
}
//TODO: Test every Error in release mode
void Debug::ErrorImp(const char* in, const char* filename, int line) {
if (m_timerStarted)
printCurrentTime();
static HANDLE cmd = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(cmd, FOREGROUND_RED);
std::printf("NF Error (%s, %i): %s\n", filename, line, in);
SetConsoleTextAttribute(cmd, 7);
}
void Debug::ErrorImp(const std::string& in, const char* filename, int line) {
ErrorImp(in.c_str(), filename, line);
if (m_timerStarted)
printCurrentTime();
static HANDLE cmd = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(cmd, FOREGROUND_RED);
std::printf("NF Error (%s, %i): ", filename, line);
std::cout << in << "\n";
SetConsoleTextAttribute(cmd, 7);
}
void Debug::printCurrentTime() {
@ -82,7 +91,7 @@ namespace nf {
if (!m_loading)
NFLog("\"" + m_funcName + (std::string)"\" took " + std::to_string(dur.count() * 1000.0f) + (std::string)" ms.");
else
NFLog("Loading state took " + std::to_string(dur.count()) + (std::string)" seconds.");
NFLog("Loading took " + std::to_string(dur.count()) + (std::string)" seconds.");
}
#endif

View File

@ -12,7 +12,7 @@ namespace nf {
* A cubemap is a cube with a texture on each one of its 6 sides.
*
* @sa @ref createCubemapTut
* @ref customCubemaps
* @ref customCubemap
*/
class Cubemap : public Drawable, public NFObject {
public:

View File

@ -21,9 +21,12 @@ namespace nf {
* Current version of the engine in the format major.minor.patch
*/
#define NFVERSION "0.5.0"
#if defined(NFDEBUG) || defined(doxygen)
#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 NFDEBUGINIT std::chrono::steady_clock::time_point Debug::m_initTime = std::chrono::high_resolution_clock::now(); \
bool Debug::m_timerStarted = false
/**
* @defgroup macros Macros
*
@ -110,7 +113,7 @@ __debugbreak();}
#define NFSleepS(x)
#define NFSleepMS(x)
#define NFLog(x)
#define NFError(x) {MessageBox(FindWindow(L"NFClass", NULL), nf::toWide(x).data(), L"NF Engine Error", MB_OK | MB_ICONERROR);\
#define NFError(x) {MessageBox(FindWindow(L"NFClass", NULL), toWide(x).data(), L"NF Engine Error", MB_OK | MB_ICONERROR);\
std::exit(-1);}
#define NFTimeFunc
#define NFTimerLoad
@ -411,9 +414,9 @@ std::exit(-1);}
float w;
};
#ifndef NFIMPL
const std::wstring toWide(const char* in);
const std::wstring toWide(const std::string& in);
#ifndef NFIMPL
Vec4 degToQuat(const Vec3& in);
#endif

View File

@ -15,26 +15,19 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
ProdDebug|x64 = ProdDebug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1B9C5361-E301-41BF-97E7-56D65F11E2BB}.Debug|x64.ActiveCfg = Debug|x64
{1B9C5361-E301-41BF-97E7-56D65F11E2BB}.Debug|x64.Build.0 = Debug|x64
{1B9C5361-E301-41BF-97E7-56D65F11E2BB}.ProdDebug|x64.ActiveCfg = ProdDebug|x64
{1B9C5361-E301-41BF-97E7-56D65F11E2BB}.ProdDebug|x64.Build.0 = ProdDebug|x64
{1B9C5361-E301-41BF-97E7-56D65F11E2BB}.Release|x64.ActiveCfg = Release|x64
{1B9C5361-E301-41BF-97E7-56D65F11E2BB}.Release|x64.Build.0 = Release|x64
{B7FEC2D6-1D8F-487E-89CB-FD611FD1AEB6}.Debug|x64.ActiveCfg = Debug|x64
{B7FEC2D6-1D8F-487E-89CB-FD611FD1AEB6}.Debug|x64.Build.0 = Debug|x64
{B7FEC2D6-1D8F-487E-89CB-FD611FD1AEB6}.ProdDebug|x64.ActiveCfg = ProdDebug|x64
{B7FEC2D6-1D8F-487E-89CB-FD611FD1AEB6}.ProdDebug|x64.Build.0 = ProdDebug|x64
{B7FEC2D6-1D8F-487E-89CB-FD611FD1AEB6}.Release|x64.ActiveCfg = Release|x64
{B7FEC2D6-1D8F-487E-89CB-FD611FD1AEB6}.Release|x64.Build.0 = Release|x64
{771B4AEE-E2C6-4745-AC40-1EF57149612E}.Debug|x64.ActiveCfg = Release|x64
{771B4AEE-E2C6-4745-AC40-1EF57149612E}.Debug|x64.Build.0 = Release|x64
{771B4AEE-E2C6-4745-AC40-1EF57149612E}.ProdDebug|x64.ActiveCfg = Release|x64
{771B4AEE-E2C6-4745-AC40-1EF57149612E}.ProdDebug|x64.Build.0 = Release|x64
{771B4AEE-E2C6-4745-AC40-1EF57149612E}.Release|x64.ActiveCfg = Release|x64
{771B4AEE-E2C6-4745-AC40-1EF57149612E}.Release|x64.Build.0 = Release|x64
EndGlobalSection

View File

@ -169,7 +169,7 @@ HTML_HEADER = header.html
HTML_FOOTER = footer.html
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET = theme.css
HTML_EXTRA_FILES = images/favicon.png videos/buttondemo.mp4
HTML_EXTRA_FILES = images/favicon.png
HTML_COLORSTYLE_HUE = 30
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 618 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 519 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 572 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 KiB

View File

@ -15,15 +15,15 @@ In order to develop an NF application, you must first have the following:
The current version of the engine can be downloaded [here](http://graysonriffe.com/nf/nf.zip).
@note Your antivirus may first need to scan some of the included binaries and your
build output before they can be run. You should never get a message from any antivirus
@note Windows Security may first need to scan some of the included binaries and your
build output before they can be run. You should never get a message from Windows Security
that a virus has been found in any of these files.
Inside the zip file, you will find:
- **example** - The example app complete with the source and a build
- **manual** - An offline version of this manual
- **index.html** - The main page
- **index.html** - The homepage
- **redist** - MSVC Redistributable (See @ref packagingTut)
- **template** - A template MSVC project already setup to work with the engine
@ -44,19 +44,20 @@ project (`NFApp` by default), can be renamed at any time.
@note The template project is setup to build *Debug* and *Release* configurations. The *Debug*
configuration includes a console window with debug output. The *Release* configuration does
not have this console window, and will run as fast as possible with maximum optimizations.
By default, the current configuration can be changed in the top toolbar.
not have this console window. By default, the current configuration can be changed in the
top toolbar.
Once the solution has been opened, you can find the `main.cpp` file inside the `src` folder:
Once the solution has been opened, you can find the `main.cpp` file inside the `src` folder
as shown below.
@image html blanktemplate.png "The template opened in Visual Studio" width=70%
@image html blankproject.png "The template opened in Visual Studio" width=70%
To build the project, go to Build -> Build Solution or Build Project. The latter will not build
To build the project, go to Build -> Build Solution or Build Project, which will not build
your assets. You can also also hit the default keyboard shortcut of `Ctrl-Shift-B` to build
both your app and assets.
both your app and assets at once.
@note When the "Build Assets" project is built, the resulting NFPacks are moved to
the output `assets` directory next to your `.exe` for you.
the output `assets` directory next to your .exe for you.
NF is a **statically-linked** library. This means that your build will not
rely on any external dlls other than the MSVC redistributable. See @ref packagingTut.
rely on any external dlls other than the MSVC redistributable.

View File

@ -15,14 +15,12 @@ main thread of an NF app might be typically doing in the program's lifetime.
@image html applifetime.png "The lifetime of a typical NF app" width=20%
Using this architecture, you might not even write any functions that are called
Using the engine's architecture, you might not even write any functions that are called
from `main`. Most of the code that programs the engine's behavior should be called in
your state's [update function](@ref nf::Gamestate::update).
To allow a translate unit to use the engine, you must include `NothinFancy.h`. This
header contains every class and function you will need.
---
header contains every class and function.
@section createConfigTut Creating a Config
@ -31,8 +29,9 @@ engine should display on the screen. nf::Config has these fields:
- `width` - The width of the window if `fullscreen` is set to `false`
- `height` - The height of the window if `fullscreen` is set to `false`
- `fullscreen` - `true` sets the display to the size of the monitor the app is opened on
- `fullscreen` - `true` sets the display to the size of the monitor the app is
- `title` - The title of the window shown on the caption bar and taskbar
opened on
To create a 1280 by 720 window with a title of "NF Example", you would write:
@ -53,7 +52,7 @@ We then pass this config to an nf::Application
@section createAppTut Creating and Configuring an Application
The nf::Application class represents an instance of the engine. This is the point where
you will attach your states and run your application.
you will attach your states and run the engine.
@note In a program and on a single machine, there can only be one single instance of
this class at a time. Attempting to create mulitple will result in an error.
@ -65,7 +64,7 @@ nf::Application app(conf);
~~~
Constructing an application doesn't do much. It merely allows you to access the member
functions to setup your application and run it later.
functions to setup your application.
Here are some functions you might want to call at this point:
@ -87,7 +86,7 @@ Once these functions have been called, the app can be run:
~~~cpp
CustomGamestate* customState = new CustomGamestate; //Inherits nf::Gamestate
app.addState(customState, "State 1"); //"State 1" is this state's identifier.
app.addState(customState, "State 1"); //"State One" is this state's identifier.
app.setDefaultState("State 1"); //Will error without this
app.run(); //Blocks until exit
~~~
@ -337,104 +336,12 @@ After rendering, our world will have a background.
@section customAssetsTut Adding Your Assets
NF's asset system builds your assets into NFPacks that the engine reads at runtime. The
external tool `NFAssetBuilder.exe` creates these for you. You can then access these packs
through the nf::AssetPack class. For a complete guide, please see @ref assets.
@image html custommodel.png "An example of a custom model" width=50%
external tool `NFAssetCreator.exe` creates these for you. For a complete guide, please
see @ref assets.
@section createUITut Creating a UI
NF currently has three classes of UI objects:
- nf::Text - A string of text on the screen
- nf::UITexture - Any 2D texture to put on the screen
- nf::Button - A horizontal button that can be clicked with the mouse
To create a text:
~~~cpp
text.create("NF Test", nf::Vec2(0.8, 0.1));
text.setScale(2.0);
std::string string = "More Text";
text.setText(string);
~~~
@note The default font is Microsoft's Segoe UI Light, but a text's font
[can be changed](@ref customFonts).
To create a texture on the UI:
~~~cpp
texture.create(nf::BaseAssets::logo, nf::Vec2(0.1, 0.1));
~~~
To create a clickable button:
~~~cpp
button.create(nf::Vec2(0.1, 0.1), "Text on button");
//You can also center any of these three classes by calling
button.centered(true, false);
//where the first bool is the x-axis and the second is the y-axis
~~~
The default button textures [can also be changed](@ref customButtons).
Since buttons are controlled by the mouse, they cannot be interacted with in our current
camera mode. Let's add a keybind that will switch between the appropriate modes.
~~~cpp
//In our update function...
if (app->isKeyPressed(NFI_E))
camera->setType(camera->getType() == nf::Camera::Type::UI ? nf::Camera::Type::FIRST_PERSON : nf::Camera::Type::UI);
if (button.isClicked()) {
NFLog("Clicked!);
}
~~~
@image html ui.png "Our new UI with a working button" width=70%
@section soundTut Adding Sound
Our app is silent as of now. To play a sound, create an nf::Sound object and call its
[play](@ref nf::Sound::play) function. Creating a sound requires a custom asset to be
loaded. See the [assets page](@ref customSounds).
NF supports 3D sound.
~~~cpp
sound.create(pack.get("Sound.ogg"));
//In update somewhere...
sound.play();
~~~
If a sound is played like this (with no position set), it will sound as if it is coming from
every direction. But if we set the position of the sound, it will sound as if it originates
from that position. This can either be done by setting a static position in the world,
or by specifying an existing nf::Entity, which will cause the sound to always play at that
entity's origin (probably inside the model).
~~~cpp
//Play at a static position:
sound.setPosition(nf::Vec3(10.0, 25.0, 15.0));
//Play dynamically wherever the target entity is:
sound.setEntity(entity2);
~~~
@section gamestateSwitchTut Switching Gamestates
To unload the current state and load another state, call:
~~~cpp
app->changeState("State 2"); //String identifier we defined earlier
~~~
@note The currently running state that calls [changeState](@ref nf::Application::changeState)
does not stop running right away. The `update` and `render` functions of that state are called
until the loading screen fades in completely.
@todo Lighting page?
@section debuggingTut Debugging Your App
@ -461,6 +368,5 @@ Other than that, a build can be very simple:
- **NFApp.exe** - The application binary which is named from the MSVC project
- **assets** - The folder which holds your NFPacks
- **base.nfpack** - The NFPack that holds both critical and default assets
- **Your Assets** - The rest of the NFPacks your application needs
These are the only files you need to package in your build.

View File

@ -1,181 +1,14 @@
@page assets Asset System
@tableofcontents
This page details NF's asset system and how to work with it.
The following table shows the currently supported file types that the asset builder
will accept.
Asset Type | Supported File Type(s)
-|-
Model | Wavefront `.obj` / `.mtl`
Font | TrueType `.ttf`
Texture (Models, UI, Buttons, Cubemaps) | `.png` or `.jpg`
Audio | `.wav` or Ogg Vorbis `.ogg`
This page details NF's asset system and custom NFPack format.
@section buildAssets How to Build Your Assets
This is the basic workflow when working with assets:
@todo Asset system page
1. Create a folder in your project's `asset` folder. The name of the folder will be the
name of the output pack in the form `foldername.nfpack`.
2. Place your assets anywhere inside this folder, including in any subfolders.
3. Build the packs by either building the "Build Assets" project in the template or by
manually running `NFAssetBuilder.exe` by clicking on it. If you choose this method, you
must also manually copy the needed packs to your app's `assets` directory.
4. In your code, create an nf::AssetPack object and call the [load](@ref nf::AssetPack::load)
function while passing in the name of the pack, including the extension.
5. Call the [get](@ref nf::AssetPack::get) function with the name of the asset file
to retrieve an Asset pointer to use in various `create` functions.
@section customFonts Custom Font Assets
---
@section customButtons Custom Button Assets
@section customModels Models
To import a custom model into NF, it must first meet some requirements:
- Format must be a Wavefront `.obj` file
- The model must include both texture coordinate and normal data
- All faces must be triangles
- There must exist a `.mtl` file with the same name as the `.obj` file somewhere in the
pack folder that contains material information
Using Blender can fill all of these requirements easily. This tutorial uses Blender v3.0.0.
Let's say I have this teapot I want to place in a scene:
@image html modeltut1.png "My starting model" width=50%
It has enough detail already, but I want it to look smooth, so I'll make sure smooth
shading is turned on for this object. This makes every part of the model smooth, but I
don't want that on the handle of the lid. I want to see an edge there. The solution here
is to turn on Object Data -> Normals -> "Auto Smooth" in the properties editor
and adjust the degree threshold until I get what I want.
This should be the result:
@image html modeltut2.png "Our smooth model with a few sharp edges" width=50%
Now that that's done, I want to create the material this teapot will have. I want to
apply a texture, so I'm going to unwrap the model and texture it. Blender materials
translate directly into NF materials, so feel free to add multiple materials on the same
model that use different textures.
To add a color texture to a material, direct an "Image Texture" to the "Base Color"
input of the default Principled BSDF. This can either be done through the properties editor
or node editor.
@todo Talk about specular and normal maps
@image html modeltut3.png "Our textured model" width=50%
I am now ready to export this model, so first make sure your model is selected, then
go to File -> Export -> Wavefront (.obj). This will bring up another window where we will
set some important options.
Under the "Geometry" heading, make sure these are checked. The model will not import into
the engine unless all of these are checked.
@image html exportsettings.png "Important Export Settings" width=10%
Now that we have a pair of `.obj` and `.mtl` files, we can move them into our pack folder.
Back in the code, once we have a loaded nf::AssetPack, we can create an entity with our
new model like so:
~~~cpp
//ap is the nf::AssetPack that has our NFPack loaded
entity2.create(ap.get("teapot.obj"), nf::Vec3(0.0)); //Reference asset by name, including extension
~~~
Lastly, don't forget to build your assets before running.
Used in the tutorial app, our model looks like this:
@image html custommodel.png "Our teapot in the engine" width=50%
---
@section customFonts Fonts
Custom fonts can be implemented very easily. All you need to do is include a TrueType
`.ttf` font in your assets and reference it when you create texts:
~~~cpp
text.create("Cool Font", nf::Vec2(0.1, 0.2), nf::Vec3(1.0f), 1.0f, 1.0f, ap.get("font.ttf"));
~~~
@image html customfont.png "A text using the font \"Corsiva\"" width=30%
---
@section customButtons Button Textures
The default button textures can be overridden by adding textures with certain names
to your assets where "name" can be anything you choose as an identifier.
- **name_buttonidle** - The texture that shows when the button is idle
- **name_buttonhover** - The texture that shows when the mouse hovers over the button
- **name_buttonpressed** - The texture that shows when the button clicked
These images can be of any accepted image format. They should all have the same dimensions.
@warning If a button texture set is incomplete, the engine will error when it reads the
NFPack.
Once the textures are in place, they can be accessed in your nf::AssetPack like
this:
~~~cpp
//Text can still be added on top, but I already have text on my texture, so I'll leave it blank.
button.create(nf::Vec2(0.1, 0.1), "", ap.get("name.button"));
~~~
With these three textures:
@image html examplebuttonidle.png "Idle" width=20%
@image html examplebuttonhover.png "Hover" width=20%
@image html examplebuttonpressed.png "Pressed" width=20%
We get this result:
@htmlonly
<video src="buttondemo.mp4" autoplay loop muted width=50%>
@endhtmlonly
---
@section customCubemaps Cubemaps
Cubemaps are like button textures. Each cubemap consists of 6 textures that are mapped
to the inside of a giant, unreachable cube in your scene. The engine takes care of rendering
it. All you need to do is supply these 6 textures in your assets with specific filenames.
Here, "name" can be anything you choose as an identifier.
- **name_cmfront** - The front texture (-Z direction)
- **name_cmback** - The back texture (+Z direction)
- **name_cmright** - The right texture (+X direction)
- **name_cmleft** - The left texture (-X direction)
- **name_cmtop** - The top texture (+Y direction)
- **name_cmbottom** - The bottom texture (-Y direction)
Once the textures are in place, they can be accessed in your nf::AssetPack like
this:
~~~cpp
cubemap.create(ap.get("name.cm"));
~~~
---
@section customSounds Sounds
Sounds are the easiest to include.
All you need to do is place the sound file in your assets and reference it by name
when creating an nf::Sound object:
~~~cpp
sound.create(ap.get("sound.ogg"));
~~~
@section customCubemap Custom Cubemap Assets

View File

@ -1,9 +1,8 @@
@tableofcontents
Nothin' Fancy (abbreviated as NF) is an experimental 3D game engine written in C++
for Windows. The engine allows the user to program 3D applications with high-level
C++. NF was created by Grayson Riffe in 2021. This manual aims to aid the user
with using NF to create games and visualizations. It contains the
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 the
[user guide](tutorial.html) and the [API reference](namespaces.html).
@image html logofull.png "Engine Logo" width=15%
@ -26,7 +25,7 @@ at any time.
- Customizable UI
- Text
- Textures
- Buttons with customizable textures
- Buttons also with customizable textures
Example App
===

View File

@ -3,15 +3,14 @@
text-align: left;
}
video, img:not([src="logo.png"]):not([src='logofull.png']):not([src="search/mag_sel.svg"]):not([src="doxygen.svg"])
img:not([src='logofull.png']):not([src="search/mag_sel.svg"]):not([src="doxygen.svg"]):not([src="logo.png"])
{
filter: drop-shadow(0.5em 0.5em 0.5em grey);
box-shadow: 0.5em 0.5em 0.5em grey;
}
div.caption
{
margin-top: 0.2em;
margin-bottom: 0.5em;
margin-top: 0.5em;
}
#nav-sync

Binary file not shown.