Simple c++ app / game framework inspired by the single file c game engines and libraries, especially FWK.
It was designed to help with teaching programming, but it turns out it's pretty useful for other projects aswell.
This library / framework is:
- Simple to compile.
- Simple to initialize.
- Simple to use.
- Supports windowing and opengl (ES2).
- Modular (within reason).
- It is desktop only (Windows, Linux, OSX) for now (most code is multiplatform though).
Also:
- The codebase is simple and easy to read.
- Comes with it's own container classes and memory management.
- Comes as 2 (or 3) merged files. (This way it's actually simpler to use and setup compared to if it was single header!)
- It does not use exceptions.
A lite version is also available (sfwl).
Currently the framework contains 5 modules, they are additive:
Has:
- Typedefs
- Math defines, and a class
- Logging, and error macros
- Math helper classes (like Vector2, Vector3, Projection, Transform etc.)
- Containers
- Memory management
- Threading
- Subprocess handling
- Sockets
- Strings
- File and Directory handling
Does not depend on anything.
Has:
- Object, Reference, Resource classes
- Variant class that can store anything
- Signal class
Depends on Core.
A c++ abstraction over the opengl api.
Has:
- Shaders
- Materials
- Meshes
- Windowing
- Fonts
- Images
- Textures
- FrameBuffers
- Input handling
- An Application and a Scene class for easier development
Depends on Core and Object.
Contains a simple immediate renderer class. (called Renderer.)
Depends on Core, Object and Render Core.
Contains a class based renerer api.
Has classes like:
- Camera2D
- Camera3D
- MeshInstance 2D/3D
- Text2D
- TileMap
- Etc.
Depends on Core, Object and Render Core.
The library's lite version.
Same as the normal library except the math helper classes were removed (except for Vector2i, and Rect2i).
It only has 2 modules, Core, and Objects.
If you don't need the renderer then everything is extremely simple.
First grab a version that does not have the renderer.
Now you have 2 files: sfw.h
and sfw.cpp
or sfwl.h
and sfwl.cpp
depending on your choice.
If you use an ide, just add these files to your project (so the .cpp file gets compiled), and you are done.
If you are using a compiler directly, then just add sfw.cpp
or sfwl.cpp
to the list of files that you are compiling:
g++ / mingw:
g++ -g sfwl.cpp main.cpp -o prog
Note: -g means add debug information to the executable.
MSVC:
cl /Zi /EHsc /Feprog-vc.exe sfw.cpp main.cpp
Note: /Zi means add debug information to the executable.
If you are creating object files:
g++ / mingw:
g++ -g -c sfw.cpp -o sfw.o
g++ -g -c main.cpp -o main.o
g++ -g sfw.o main.o -o prog
MSVC:
cl /EHsc /Zi /c sfw.cpp /Fo:sfw.obj
cl /EHsc /Zi /c main.cpp /Fo:main.obj
cl /Zi /EHsc /Feprog-vc.exe sfw.obj main.obj
Note: You might need to set c++14 level compatibility depending on your compiler. While the codebase is somwhere between
c++89 and c++11, threads use classes from the std namespace that were added in c++14. Nowadays these are usually available
without any special setting, but if your compiler is older (or set differently) you might need to add something like:
-std=c++14
to your compile commands.
If you also want the renderer, first set everything up exactly as in the "Compilation without the renderer" section,
except you will have 3 files: sfw.h
and sfw.cpp
, and sfw_3rd.m
(this is actually a c header file, it has
the extencion .m
to make OSX builds easier).
As a second step we need to tell the linker to link to some of the libraries in the system dynamically in order to open windows and use opengl.
If you are using MSVC you are actually done, no need to do anything else as MSVC has a nice feature where
this can be done automatically. Search the codebase for #pragma comment
to see the libraries that get linked.
If you are using mingw (If you use the g++ command on windows, that is MingW!), this is how your last (linking) command changes:
g++ -g sfw.cpp main.cpp -lgdi32 -lShlwapi -lws2_32 -o prog
Or
g++ -g sfw.o main.o -lgdi32 -lShlwapi -lws2_32 -o prog
Note the position of the -l
commands, add those after your object (or .cpp) files.
Also, you don't need to add these to the other steps that does not create the final executable.
Note if you use clang, just replacing g++
to clang++
or clang
should work.
On debian based distributions run the following command to make sure that dependencies are installed:
sudo apt-get install libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev
Arch based systems should have these by default. For other distros consult the manual and / or the internet to see which packages are the equivalent of the ones listed above.
This is how your last (linking) command changes:
g++ -g sfw.cpp main.cpp -lX11 -o prog
Or
g++ -g sfw.o main.o -lX11 -o prog
Note the position of the -l
command, add those after your object (or .cpp) files.
Some g++ versions seem a lot more leanient, for example on Manjaro as of this writing
g++ -g -lX11 sfw.o main.o -o prog
works, but on the Raspberry pi (Raspian) it doesn't.
Also, you don't need to add these to the other steps that does not create the final executable.
Note if you use clang, just replacing g++
to clang++
or clang
should work.
If you need the renderer you will need to use clang on OSX.
First we need to setup SDK paths:
export SDKROOT=$(xcrun --show-sdk-path)
Set up some helper variables:
export cpp_args="-std=c++14 -w -framework cocoa -framework iokit -framework CoreFoundation -framework CoreAudio -framework AudioToolbox "
export m_args="-w -framework cocoa -framework iokit -framework CoreFoundation -framework CoreAudio -framework AudioToolbox "
On OSX sfw_3rd.m need to be compiled manually, separately:
(This is a workaround, because Objective-C and C++ code doesn't mix in a single file, but Objective-C and C does.)
clang++ -w $m_args -g -c sfw_3rd.m -o sfw_3rd.o
Now just compile everything else to objects:
clang++ $cpp_args -g -c sfw.cpp -o sfw.o
clang++ $cpp_args -g -c game_scene.cpp -o game_scene.o
clang++ $cpp_args -g -c main.cpp -o main.o
Then just link them together:
clang++ $cpp_args -g sfw.o sfw_3rd.o game_scene.o main.o -o game
If you want to edit the split version of the framework in the sfw
or sfwl
folder and you
want to generate a compiledb, currently the simples solution that I know of is to install
the compiledb
python module and just use it with the makefile in the root of the project.
Create virtual env:
python -m venv venv
Activate it (This is for bash on linux).
Commands for other shells: https://docs.python.org/3/library/venv.html#how-venvs-work
. ./venv/bin/activate
Install:
pip install compiledb
Run compiledb with make to generate compile_commands.json
compiledb make