First application¶
This guide takes you through writing a small application using RæptorCogs. By the end of this tutorial, you will have a basic understanding of how to create a window and render simple graphics using the framework.
Step by step¶
Including RæptorCogs headers¶
To start using RæptorCogs in your application, you need to include the necessary header.
#include <RaeptorCogs/RaeptorCogs.hpp>
This header includes all the core functionalities of RæptorCogs. It allow you to manipulate the state of the framework, create windows, render graphics, and handle input events.
When using components like Sprite or Text, you may need to include their specific headers as well:
#include <RaeptorCogs/Graphics/Sprite.hpp>
#include <RaeptorCogs/Graphics/Text.hpp>
Which will give you access to the classes and functions needed to work with these graphics elements.
Initializing and terminating RæptorCogs¶
Before using any RæptorCogs functionality, you must initialize the framework.
This is done by calling the RaeptorCogs::Initialize() function.
It is important to call this function at the beginning of your application, before creating any windows
or rendering graphics.
RaeptorCogs::Initialize();
At the end of your application, you should call RaeptorCogs::Destroy() to clean up resources
and properly terminate the framework.
RaeptorCogs::Destroy();
This ensures that all allocated resources are released and that the application exits cleanly.
Initializing the Renderer¶
The Renderer is responsible for all rendering operations in RæptorCogs. Before you can render anything, you need to initialize the Renderer with the desired graphics backend (e.g., OpenGL).
RaeptorCogs::Renderer().Initialize(RaeptorCogs::GraphicsBackend::GL);
// Initialize OpenGL backend
This initializes the Renderer to use the OpenGL graphics backend. You can choose other backends if supported by your system. This step is crucial as it sets up the necessary graphics context for rendering.
Creating a window¶
To create a window where your graphics will be displayed, use the Platform::createWindow() method of the Renderer.
You can specify the width, height, and title of the window.
RaeptorCogs::Window* window = RaeptorCogs::Renderer().CreateWindow(
800,
600,
"My First RæptorCogs Application"
);
This creates a window with a width of 800 pixels, a height of 600 pixels, and the title “My First RæptorCogs Application”.
Entering the main loop¶
After creating the window, you need to enter the main loop of your application. This loop will keep your application running,
handle events, and render graphics until the window is closed. To do this, use the RaeptorCogs::Renderer::StartLoop()
method. This method takes a function that will be called each frame to perform rendering and a pointer to the window you
created earlier.
RaeptorCogs::Renderer().StartLoop(
[](RaeptorCogs::Window* win) {
// Rendering code goes here
},
window
);
Checking inputs¶
Inside the main loop function, you can check for input events such as keyboard and mouse actions. RæptorCogs provides methods to check the state of keys and mouse buttons. For example, to check if the Escape key is pressed, you can use the following code:
if (RaeptorCogs::Input().isKeyPressed(RaeptorCogs::Key::Escape)) {
// Close the window if Escape is pressed
}
Rendering with RæptorCogs¶
Inside the main loop function, you can add your rendering code. This is where you will clear the screen, draw sprites, text, and other graphics elements. Here is a simple example of clearing the screen and rendering a sprite:
RaeptorCogs::Renderer().StartLoop(
[](RaeptorCogs::Window* win) {
// Create and render a sprite
RaeptorCogs::Sprite2D sprite;
sprite.setPosition({400.0f, 300.0f}); // Center of the window
sprite.setSize({100.0f, 100.0f}); // Size of the sprite
sprite.setColor({1.0f, 0.0f, 0.0f}); // Red color
RaeptorCogs::Renderer().add(sprite); // Add sprite to the renderer
RaeptorCogs::Renderer().render(*win); // Render all added elements
},
window
);
Reading the timer¶
During each iteration of the main loop, you may want to read the time elapsed since the last frame. This is useful for
animations and time-based updates.
You can use the RaeptorCogs::Time::getDeltaTime() method to get the time in seconds since the last frame.
float deltaTime = RaeptorCogs::Time().getDeltaTime();
You can also get the total time since the application started using RaeptorCogs::Time::getTime().
float totalTime = RaeptorCogs::Time().getTime();
Putting it together¶
Now that you have the basic components, you can put them together in a simple application. Below is a complete example that initializes RæptorCogs, creates a window, and enters the main rendering loop.
1#include <RaeptorCogs/RaeptorCogs.hpp>
2#include <RaeptorCogs/Sprite.hpp>
3#include <RaeptorCogs/Window.hpp>
4#include <RaeptorCogs/IO/Texture.hpp>
5#include <RaeptorCogs/Text.hpp>
6#include <RaeptorCogs/Camera.hpp>
7
8constexpr int WINDOW_WIDTH = 800;
9constexpr int WINDOW_HEIGHT = 600;
10
11RaeptorCogs::Camera2D camera;
12
13RaeptorCogs::Sprite2D raeptorLogoSprite;
14
15struct RaeptorParticle {
16 RaeptorCogs::Sprite2D sprite;
17 float speed;
18};
19
20std::array<RaeptorParticle, 10000> raeptorParticles;
21
22RaeptorCogs::Text2D raeptorText;
23RaeptorCogs::Text2D creditsText;
24
25float lastTime = 0.0f;
26
27std::string GetFpsString() {
28 std::ostringstream fps;
29 fps << std::fixed << std::setprecision(2) << 1.0f / RaeptorCogs::Time().getDeltaTime();
30 return fps.str();
31}
32
33void UpdateText() {
34 std::ostringstream fps;
35 fps << std::fixed << std::setprecision(2) << 1.0f / RaeptorCogs::Time().getDeltaTime();
36 raeptorText.setContent("Welcome to RæptorCogs!\nC++ Graphics/Game Engine Framework (" + GetFpsString() + " fps)");
37}
38
39void Initialize() {
40 RaeptorCogs::Renderer().add(camera);
41
42 RaeptorCogs::Font &defaultFont = RaeptorCogs::ResourceManager<RaeptorCogs::Font>().get_or_create("assets/fonts/Alef-Bold.ttf");
43 defaultFont.onLoad = [&]() {
44 std::cout << "Default font loaded!" << std::endl;
45 raeptorText = RaeptorCogs::Text2D(defaultFont);
46 raeptorText.setZIndex(10.0f);
47 raeptorText.setTextSize(48.0f);
48 raeptorText.setPosition({0.0f, -200.0f});
49 raeptorText.setAnchor({0.5f, 0.5f});
50 raeptorText.setAlignment(RaeptorCogs::TextAlignment::CENTER);
51 RaeptorCogs::Renderer().add(raeptorText);
52 creditsText = RaeptorCogs::Text2D(defaultFont, "RæptorCogs Demo - © RÆPTOR\nDeveloped by Estorc\n2025 © MIT License");
53 creditsText.setZIndex(10.0f);
54 creditsText.setTextSize(24.0f);
55 creditsText.setPosition({0.0f, 250.0f});
56 creditsText.setAnchor({0.5f, 0.5f});
57 creditsText.setAlignment(RaeptorCogs::TextAlignment::CENTER);
58 RaeptorCogs::Renderer().add(creditsText);
59 };
60
61 RaeptorCogs::Texture& logoTexture = RaeptorCogs::ResourceManager<RaeptorCogs::Texture>().create("assets/textures/raeptor-cogs-logo.png");
62 logoTexture.onLoad = [&]() {
63 std::cout << "RaeptorCogs logo texture loaded!" << std::endl;
64 raeptorLogoSprite.setTexture(logoTexture);
65 raeptorLogoSprite.setPosition({0.0f, 0.0f});
66 raeptorLogoSprite.setAnchor({0.5f, 0.5f});
67 raeptorLogoSprite.setSize({200.0f, 200.0f});
68 raeptorLogoSprite.setZIndex(5.0f);
69 RaeptorCogs::Renderer().add(raeptorLogoSprite);
70 for (size_t i = 0; i < raeptorParticles.size(); ++i) {
71 raeptorParticles[i].sprite.setTexture(logoTexture);
72 float scale = RaeptorCogs::Random().getFloat(0.1f, 1.0f);
73 raeptorParticles[i].sprite.setScale({scale, scale});
74 raeptorParticles[i].sprite.setSize({20.0f, 20.0f});
75 raeptorParticles[i].sprite.setPosition({0.0f, INFINITY});
76 raeptorParticles[i].sprite.setAnchor({0.5f, 0.5f});
77 raeptorParticles[i].sprite.setColor({RaeptorCogs::Random().getFloat(0.0f, 1.0f), RaeptorCogs::Random().getFloat(0.0f, 1.0f), RaeptorCogs::Random().getFloat(0.0f, 1.0f)});
78 RaeptorCogs::Renderer().add(raeptorParticles[i].sprite);
79 raeptorParticles[i].speed = 50.0f + RaeptorCogs::Random().getFloat(0.0f, 150.0f);
80 }
81 };
82}
83
84void Update(RaeptorCogs::Window& mainWindow) {
85
86 raeptorText.setRotation(sinf(RaeptorCogs::Time().getTime()) * 0.1f);
87 if (lastTime + 1.0f < RaeptorCogs::Time().getTime() && raeptorText.isVisible()) {
88 lastTime = RaeptorCogs::Time().getTime();
89 UpdateText();
90 mainWindow.setTitle("RæptorCogs Demo - " + GetFpsString() + " FPS");
91 }
92
93 glm::vec2 frameSize = glm::vec2(mainWindow.getSize()) * 1.8f;
94 camera.setZoom(sinf(RaeptorCogs::Time().getTime() * 3.0f) * 0.2f + 1.5f);
95 raeptorLogoSprite.setRotation(sinf(RaeptorCogs::Time().getTime()) * 0.5f);
96 raeptorLogoSprite.setScale({1.0f + 0.1f * sinf(RaeptorCogs::Time().getTime() * 2.0f),
97 1.0f + 0.1f * sinf(RaeptorCogs::Time().getTime() * 2.0f)});
98 for (size_t i = 0; i < raeptorParticles.size(); ++i) {
99 glm::vec2 pos = raeptorParticles[i].sprite.getPosition();
100 pos.y += raeptorParticles[i].speed * RaeptorCogs::Time().getDeltaTime();
101 if (pos.y > frameSize.y / 2.0f) {
102 pos.y = -frameSize.y / 2.0f;
103 pos.x = RaeptorCogs::Random().getFloat(0.0f, frameSize.x) - frameSize.x / 2.0f;
104 }
105 raeptorParticles[i].sprite.setPosition(pos);
106 raeptorParticles[i].sprite.setRotation(raeptorParticles[i].sprite.getRotation() + raeptorParticles[i].speed / 30.0f * RaeptorCogs::Time().getDeltaTime());
107 }
108 RaeptorCogs::Renderer().render(mainWindow);
109}
110
111int main() {
112 RaeptorCogs::Initialize();
113 RaeptorCogs::Renderer().initialize();
114 Initialize();
115 RaeptorCogs::Window& mainWindow = *RaeptorCogs::Platform().createWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "RaeptorCogs Demo");
116 mainWindow.setIcon({
117 "assets/icons/raeptor-cogs-icon-16.png",
118 "assets/icons/raeptor-cogs-icon-32.png",
119 "assets/icons/raeptor-cogs-icon-48.png",
120 "assets/icons/raeptor-cogs-icon-128.png"
121 });
122 RaeptorCogs::StartLoop(Update, mainWindow);
123 RaeptorCogs::Destroy();
124 return 0;
125}
The program above can be found in the repository as examples/demo/src/main.cpp. This example demonstrates the basic structure of a RæptorCogs application, including initialization, window creation, and the main rendering loop.