Chapter 1: Introduction
Welcome to Terreate Wiki
Welcome to the Terreate documentation. This documentation is intended to provide a comprehensive guide to the Terreate platform, including its features, capabilities, and how to use it.
What is Terreate
Terreate is a 3D game library for C++. This repository is designed for creating 3D games with SDL and OpenGL.
If you want to know about the licensing, see licensing section.
Let's start!
Now, let's dive into the journey of Terreate!
Library dependency
Here's the packages that are used in this library.
- SDL
Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D. It is used by video playback software, emulators, and popular games including Valve's award winning catalog and many Humble Bundle games. SDL officially supports Windows, macOS, Linux, iOS, and Android. Support for other platforms may be found in the source code. SDL is written in C, works natively with C++, and there are bindings available for several other languages, including C# and Python. SDL is distributed under the zlib license. This license allows you to use SDL freely in any software.
from SDL website - glad
Multi-Language GL/GLES/EGL/GLX/WGL Loader-Generator based on the official specs.
from glad website - glm
OpenGL Mathematics (GLM) is a header only C++ mathematics library for graphics software based on the OpenGL Shading Language (GLSL) specifications.
from GLM README.md - freetype
FreeType is a freely available software library to render fonts. It is written in C, designed to be small, efficient, highly customizable, and portable while capable of producing high-quality output (glyph images) of most vector and bitmap font formats.
from FreeType website
Build Dependency
This library uses cmake to build the projects so make sure to install cmake before building this library.
on Windows
There is no additional dependence to build this library on Windows.
on Linux
If you are using linux environment, these packages are needed to build and execute.
(Package names might be different in package managers. The names listed below are example in nix)
- alsa-lib
- hidapi
- ibus
- dbus
- jack2
- libdecor
- libGL
- libpulseaudio
- libusb1
- libsysprof-capture
- libdrm
- xorg.libX11
- xorg.libXcursor
- xorg.libXinerama
- xorg.libXrandr
- xorg.libXi
- xorg.libXext
- xorg.libXrender
- xorg.libXtst
- libxkbcommon
- mesa
- pipewire
- sndio
- wayland
- wayland-protocols
Building project
Make sure you installed cmake before building.
Build outputs
In this example, build outputs are stored in <REPOSITRY ROOT DIR>/build/ folder.
Cmake options
TERREATE_BUILD_TEST
Default: ON
Specifies whether to build test code.
TERREATE_DEBUG_BUILD
Default: OFF
Specifies whether to build in debug mode. In debug mode, TERREATE_DEBUG_MODE is defined.
Windows & Linux
Make sure you installed dependencies before building.
cmake -S . -B build
cmake --build build
nix installed env
nix develop // or `direnv allow` if you have direnv.
cmake -S . -B build
cmake --build build
Licensing
This repository is provided under the BSD-3-CLAUSE license. So you can use this library whatever you want.
You don't have to contact me to use.
Contact
If you want to contact me, please send an e-mail to upiscium@gmail.com.
Chapter2: The basics
Create a window
Section overview
- Window representation
- Simple game loop
In this section, we will create our first simplest application. It is only a blank black window.
Create Context
First, we need to create a manager of Terreate, called Context. Context is a manager for all resources or resource handlers that are used in the program. The first thing we need to do is create a Context class instance:
#include "Terreate/Terreate.hpp"
int main() {
Terreate::Context context;
return 0;
}
Once you execute the program above, you will see that the program immediately terminates and returns code 0.
Create Window
Next, we need to create a Window to represent our awesome app. Windows are created by the createWindow() function, which is a method of the Context class:
#include "Terreate/Terreate.hpp"
int main() {
Terreate::Context context;
auto window = context.createWindow(700, 500, "My first window");
// or
// Terreate::shared<Terreate::Window> window = context.createWindow(700, 500, "My first window");
return 0;
}
If you execute this code, you may see a black window for a moment.
Define Mainloop
In the current code, we cannot see our awesome app due to the life time of the window. Now, we will add Mainloop that keeps the window and other objects in our app alive until the app terminates.
#include "Terreate/Terreate.hpp"
int main() {
...
while (context.valid()) {
window->fill(0.85, 0, 0);
window->clear();
window->update();
context.tick(120);
}
return 0;
}
Now, we can see the black blank window in front of us!
Handle events
Section overview
-
Use event handler of
Context -
Retrieve window associated events via
Event. - Use pub-sub event system
Review the last section
In the last section, "Create a Window", we created a simple base app that shows only a black blank window. The code that we created is shown below.
#include "Terreate/Terreate.hpp"
int main() {
Terreate::Context context;
auto window = context.createWindow(700, 500, "My first window");
while (context.valid()) {
window->fill(0.85, 0, 0);
window->clear();
window->update();
context.tick(120);
}
return 0;
}
In this section, we will handle some events that is associated to window.
Get event handler
The first thing we need to do is to get an event handler from the Context:
...
int main() {
...
auto window = context.createWindow(700, 500, "My first window");
auto event = context.getEventHandler();
...
}
EventHandler has various events that is essential to create applications like mouse, clipboard, keyboard, text input(including IME), and more! If you want to know more about the events, see Event type documentation for more information.
Subscribe to an event
Earlier we got the event handler from the context, but this is not enough to get the event itself - in order to get the event, we need to register a callback to the event:
#include <Terreate/Terreate.hpp>
#include <iostream>
int main() {
...
auto event = context.getEventHandler();
auto mousePosCallback = [](u64 timestamp, shared<Window> window, shared<Mouse> mouse, vec2 const &pos, vec2 const &rel) {
std::cout << "Mouse moved to: (" << pos.x << ", " << pos.y << ")" << std::endl;
};
event->onMouseMotion.subscribe(mousePosCallback);
...
}
This code outputs the mouse position when the mouse cursor is moved. Let's take a look at this step by step. First, we get a handler from context. Next, we define the callback for retrieving the event. The arguments of function is defined for each event type. This is shown in the Event callback type documentation.
Finally, we called subscribe to register the callback to event.