Small improvements; User guide work
@ -340,14 +340,8 @@ namespace nf {
|
|||||||
|
|
||||||
m_fpsClock2 = std::chrono::steady_clock::now();
|
m_fpsClock2 = std::chrono::steady_clock::now();
|
||||||
m_fpsDuration = m_fpsClock2 - m_fpsClock1;
|
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);
|
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();
|
m_fpsClock1 = std::chrono::steady_clock::now();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,9 +35,9 @@ namespace nf {
|
|||||||
printCurrentTime();
|
printCurrentTime();
|
||||||
std::printf("NF ");
|
std::printf("NF ");
|
||||||
SetConsoleTextAttribute(cmd, 6);
|
SetConsoleTextAttribute(cmd, 6);
|
||||||
std::printf("Log: ");
|
std::printf("Log");
|
||||||
SetConsoleTextAttribute(cmd, 7);
|
SetConsoleTextAttribute(cmd, 7);
|
||||||
std::printf("%s\n", in);
|
std::printf(": %s\n", in);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debug::LogImp(const std::string& in) {
|
void Debug::LogImp(const std::string& in) {
|
||||||
|
@ -12,7 +12,7 @@ namespace nf {
|
|||||||
* A cubemap is a cube with a texture on each one of its 6 sides.
|
* A cubemap is a cube with a texture on each one of its 6 sides.
|
||||||
*
|
*
|
||||||
* @sa @ref createCubemapTut
|
* @sa @ref createCubemapTut
|
||||||
* @ref customCubemap
|
* @ref customCubemaps
|
||||||
*/
|
*/
|
||||||
class Cubemap : public Drawable, public NFObject {
|
class Cubemap : public Drawable, public NFObject {
|
||||||
public:
|
public:
|
||||||
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 70 KiB |
BIN
docs/images/blanktemplate.png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
docs/images/custommodel.png
Normal file
After Width: | Height: | Size: 547 KiB |
BIN
docs/images/exportsettings.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
docs/images/modeltut1.png
Normal file
After Width: | Height: | Size: 519 KiB |
BIN
docs/images/modeltut2.png
Normal file
After Width: | Height: | Size: 572 KiB |
BIN
docs/images/modeltut3.png
Normal file
After Width: | Height: | Size: 544 KiB |
BIN
docs/images/ui.png
Normal file
After Width: | Height: | Size: 706 KiB |
@ -50,11 +50,11 @@ 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.
|
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
|
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
|
@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.
|
||||||
|
@ -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).
|
your state's [update function](@ref nf::Gamestate::update).
|
||||||
|
|
||||||
To allow a translate unit to use the engine, you must include `NothinFancy.h`. This
|
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
|
@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`
|
- `width` - The width of the window if `fullscreen` is set to `false`
|
||||||
- `height` - The height 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
|
- `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:
|
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
|
@section customAssetsTut Adding Your Assets
|
||||||
|
|
||||||
NF's asset system builds your assets into NFPacks that the engine reads at runtime. The
|
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
|
external tool `NFAssetBuilder.exe` creates these for you. You can then access these packs
|
||||||
see @ref assets.
|
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
|
@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
|
@section debuggingTut Debugging Your App
|
||||||
|
|
||||||
|
@ -1,14 +1,100 @@
|
|||||||
@page assets Asset System
|
@page assets Asset System
|
||||||
@tableofcontents
|
@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
|
@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
|
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
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
img:not([src='logofull.png']):not([src="search/mag_sel.svg"]):not([src="doxygen.svg"]):not([src="logo.png"])
|
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
|
div.caption
|
||||||
|