diff --git a/NothinFancy/src/Application.cpp b/NothinFancy/src/Application.cpp index 90e0276..ecc6292 100644 --- a/NothinFancy/src/Application.cpp +++ b/NothinFancy/src/Application.cpp @@ -340,14 +340,8 @@ namespace nf { m_fpsClock2 = std::chrono::steady_clock::now(); m_fpsDuration = m_fpsClock2 - m_fpsClock1; - if (m_fpsDuration.count() >= 0.2) { + if (m_fpsDuration.count() >= 0.1) { m_FPS = (int)std::round(1.0 / m_deltaTime); -#ifdef NFDEBUG - static int i = 0; - i++; - if (i % 5 == 0) - NFLog("FPS: " + std::to_string(m_FPS)); -#endif m_fpsClock1 = std::chrono::steady_clock::now(); } } diff --git a/NothinFancy/src/Utility.cpp b/NothinFancy/src/Utility.cpp index 243c7d0..65c7fc9 100644 --- a/NothinFancy/src/Utility.cpp +++ b/NothinFancy/src/Utility.cpp @@ -35,9 +35,9 @@ namespace nf { printCurrentTime(); std::printf("NF "); SetConsoleTextAttribute(cmd, 6); - std::printf("Log: "); + std::printf("Log"); SetConsoleTextAttribute(cmd, 7); - std::printf("%s\n", in); + std::printf(": %s\n", in); } void Debug::LogImp(const std::string& in) { diff --git a/NothinFancy/src/include/nf/Cubemap.h b/NothinFancy/src/include/nf/Cubemap.h index 19c5752..44985a7 100644 --- a/NothinFancy/src/include/nf/Cubemap.h +++ b/NothinFancy/src/include/nf/Cubemap.h @@ -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 customCubemap + * @ref customCubemaps */ class Cubemap : public Drawable, public NFObject { public: diff --git a/docs/images/applifetime.png b/docs/images/applifetime.png index a405b23..9a96041 100644 Binary files a/docs/images/applifetime.png and b/docs/images/applifetime.png differ diff --git a/docs/images/blankproject.png b/docs/images/blankproject.png deleted file mode 100644 index 23294a1..0000000 Binary files a/docs/images/blankproject.png and /dev/null differ diff --git a/docs/images/blanktemplate.png b/docs/images/blanktemplate.png new file mode 100644 index 0000000..1e14792 Binary files /dev/null and b/docs/images/blanktemplate.png differ diff --git a/docs/images/custommodel.png b/docs/images/custommodel.png new file mode 100644 index 0000000..aadd4ba Binary files /dev/null and b/docs/images/custommodel.png differ diff --git a/docs/images/exportsettings.png b/docs/images/exportsettings.png new file mode 100644 index 0000000..62767be Binary files /dev/null and b/docs/images/exportsettings.png differ diff --git a/docs/images/modeltut1.png b/docs/images/modeltut1.png new file mode 100644 index 0000000..1560263 Binary files /dev/null and b/docs/images/modeltut1.png differ diff --git a/docs/images/modeltut2.png b/docs/images/modeltut2.png new file mode 100644 index 0000000..15c5ff4 Binary files /dev/null and b/docs/images/modeltut2.png differ diff --git a/docs/images/modeltut3.png b/docs/images/modeltut3.png new file mode 100644 index 0000000..a4657a4 Binary files /dev/null and b/docs/images/modeltut3.png differ diff --git a/docs/images/ui.png b/docs/images/ui.png new file mode 100644 index 0000000..734070a Binary files /dev/null and b/docs/images/ui.png differ diff --git a/docs/pages/1_install.md b/docs/pages/1_install.md index dec5f27..6b15cd8 100644 --- a/docs/pages/1_install.md +++ b/docs/pages/1_install.md @@ -50,11 +50,11 @@ top toolbar. Once the solution has been opened, you can find the `main.cpp` file inside the `src` folder as shown below. -@image html blankproject.png "The template opened in Visual Studio" width=70% +@image html blanktemplate.png "The template opened in Visual Studio" width=70% -To build the project, go to Build -> Build Solution or Build Project, which will not build +To build the project, go to Build -> Build Solution or Build Project. The latter 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 at once. +both your app and assets. @note When the "Build Assets" project is built, the resulting NFPacks are moved to the output `assets` directory next to your .exe for you. diff --git a/docs/pages/2_tutorial.md b/docs/pages/2_tutorial.md index 19ecefb..85b5be9 100644 --- a/docs/pages/2_tutorial.md +++ b/docs/pages/2_tutorial.md @@ -20,7 +20,7 @@ from `main`. Most of the code that programs the engine's behavior should be call 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. +header contains every class and function you will need. @section createConfigTut Creating a Config @@ -29,9 +29,8 @@ 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 +- `fullscreen` - `true` sets the display to the size of the monitor the app is opened on - `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: @@ -336,12 +335,92 @@ 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 `NFAssetCreator.exe` creates these for you. For a complete guide, please -see @ref assets. +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% @section createUITut Creating a UI -@todo Lighting page? +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 debuggingTut Debugging Your App diff --git a/docs/pages/4_assets.md b/docs/pages/4_assets.md index 7ea8541..e460bfb 100644 --- a/docs/pages/4_assets.md +++ b/docs/pages/4_assets.md @@ -1,14 +1,100 @@ @page assets Asset System @tableofcontents -This page details NF's asset system and custom NFPack format. +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` @section buildAssets How to Build Your Assets -@todo Asset system page +This is the basic workflow when working with assets: -@section customFonts Custom Font Assets +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 customButtons Custom Button Assets +@section customModels Models -@section customCubemap Custom Cubemap Assets \ No newline at end of file +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 + +@section customButtons Button Textures + +@section customCubemaps Cubemaps + +@section customSounds Sounds \ No newline at end of file diff --git a/docs/theme.css b/docs/theme.css index 59fbbfb..6cfa997 100644 --- a/docs/theme.css +++ b/docs/theme.css @@ -5,7 +5,7 @@ img:not([src='logofull.png']):not([src="search/mag_sel.svg"]):not([src="doxygen.svg"]):not([src="logo.png"]) { - box-shadow: 0.5em 0.5em 0.5em grey; + filter: drop-shadow(0.5em 0.5em 0.5em grey); } div.caption