WOWCube Docs logo
WOWCube Docs
Mission Control
Section Shortcuts
APIExamplesSourceWOWConnectChangelog
Filters
SDK and language defaults persist in cookies.
SDK version
Navigation Tree
Collapsed by default, focused on the active path.
Made byMcKay Seamons
GitHub
  1. Home
  2. Docs
  3. Examples
  4. Gfx Engine - Bitmaps
Mission NodeSDK 6.1C++renderingProject Included

Gfx Engine - Bitmaps

Gfx Engine Bitmaps Bitmaps (or sprites) are the same type of GFX Engine objects as text, background and any other object that can be added to the scene. In p...

Examples / SDK 6.1 / C++ / rendering

Gfx Engine - Bitmaps

Bitmaps (or sprites) are the same type of GFX Engine objects as text, background and any other object that can be added to the scene.

In principle, the previous examples are quite enough to get acquainted with the capabilities of the engine, in particular with the rendering of bitmaps. However, we want to make an application that does not just draw something, but renders something cool and beautiful, right?

Ok, but before moving to the actual example, let's get a little deeper into the bitmaps and ways of dealing with them.

So, in order to draw a bitmap on the screen using GFX Engine, we need to do the following:

  • Create a Sprite object and register it in the scene
  • Set its parameters, if necessary
  • Add an object to the screen inside the Begin()-End() block in the on_Render() function

Let's look at each step separately.

Step 1 - Initialization

The Sprite class has 4 constructors, each of which can be used to create a new instance of the class object:

Gfx Engine - Bitmaps
CPP
1Sprite(std::string name, const Cubios::Math::Transform& t);
2Sprite(std::string name, float x, float y);
3Sprite(std::string name);
4Sprite(const Sprite& sprite);
5
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

Since the class is responsible for rendering the image, the required parameter is the name of the image file. The rest of the parameters are optional and can be set later, but the filename can only be set when the object is created.

As you can see from the source above, the sprite can be immediately initialized with coordinates for rendering or with a full Transform class containing coordinates, rotation angle and mirroring, or you can simply pass the file name.

So overall, Sprite, like any other drawable object in GFX Engine, has the following standard parameters:

  • Math::Transform Transform
    Contains information about the current position, rotation, scaling and mirroring

  • Math::Color Color
    Contains color information. Depending on the class, the meaning of this parameter may vary. For example, for the Sprite class, this parameter is the color key, and for the Text class, the actual color of the text

  • int32_t ScreenAngle
    Holds current angle of screen rotation (an angle that is used if automatic rotation is enabled)

  • bool Visible
    Object visibility flag. If it is set to false, the object won't be rendered even if it is added to a screen

  • Screen* Parent
    A pointer to the screen the object is currently added to

All these parameters can be changed arbitrarily both when creating an object and when adding it to the screen using insert modifiers.

Registering a sprite in a scene can be done in two ways. You can either register a sprite and get an identifier automatically,

Gfx Engine - Bitmaps
CPP
1mySpriteID = this->Scene.CreateObject(new Sprite("spriteImage.webp",Transform(120,120,0)));
2
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

or you can set a known identifier in advance.

Gfx Engine - Bitmaps
CPP
1this->Scene.CreateObjectWithID(mySpriteID, new Sprite("spriteImage.webp",Transform(120,120,0)));
2
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

The choice of registration method depends on the application initialization logic.

Step 2 - Setting parameters

In some cases, after creating an object and registering it in the scene, you need to set additional parameters. These parameters are typically unique to the object class and are not part of the list of parameters passed to the constructor. However, after creating an instance of a class, you can also set parameters that are common to all classes.

For example, the following shows the creation and registration of a Sprite class object, followed by setting the color key color and the value of the alpha component:

Gfx Engine - Bitmaps
CPP
1this->Scene.CreateObjectWithID(mySpriteID,new Sprite("cube.png",Transform(120,120,0)));
2this->Scene[mySpriteID]->Color.Set(0xFFFFFFFF);
3this->Scene[mySpriteID]->Color.SetA(255);
4
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

Step 3 - Rendering

Objects are drawn by adding them to the current screen. The addition is done inside the Begin()-End() block, which is used to inform the engine about the start and end of the process of adding objects, as well as about the orientation control mode and automatic rotation.

An elementary example looks like this:

Gfx Engine - Bitmaps
CPP
1for(auto it = screens.begin(); it != screens.end(); ++it)
2 {
3 //Start adding objects to a screen
4 it->Begin(TOPOLOGY_orientation_mode_t::ORIENTATION_MODE_GRAVITY,true);
5
6 it->Add(this->Scene[mySpriteID]);
7
8 //Finish adding objects
9 it->End();
10 }
11
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

The Screen::Add() function returns a pointer to the object that was added. Therefore, if it is necessary to dynamically change any object parameters (for example, the position on the screen), in-place setters are used, as shown below:

Gfx Engine - Bitmaps
CPP
1for(auto it = screens.begin(); it != screens.end(); ++it)
2 {
3 //Start adding objects to a screen
4 it->Begin(TOPOLOGY_orientation_mode_t::ORIENTATION_MODE_GRAVITY,true);
5
6 it->Add(this->Scene[mySpriteID])->SetPosition(xOffset,120);
7
8 //Finish adding objects
9 it->End();
10 }
11
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

or more complex example:

Gfx Engine - Bitmaps
CPP
1for(auto it = screens.begin(); it != screens.end(); ++it)
2{
3 //Start adding objects to a screen
4 it->Begin(TOPOLOGY_orientation_mode_t::ORIENTATION_MODE_GRAVITY,true);
5
6 //Use in-place setters for changing Text content and position
7 dynamic_cast<Text*>(it->Add(this->Scene[GfxObjects::myText]))
8 ->SetPosition(120,60+50*sin(a));
9
10
11 dynamic_cast<Text*>(it->Add(this->Scene[GfxObjects::myText2]))
12 ->SetPosition(120,120+50*sin(a+0.6));
13
14 dynamic_cast<Text*>(it->Add(this->Scene[GfxObjects::myText3]))
15 ->SetContent(this->words.at(this->currWord))
16 ->SetPosition(120,180+50*sin(a+1.2))
17 ->SetColor(Cubios::random(0xFFCCCCCC,0xFFFFFFFF));
18
19 //Finish adding objects
20 it->End();
21}
22
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

The Example

In this example, we will create an animated cubemap.

In truth, the word "animated" in this context is not entirely correct, since in fact the image on the cubemap is static... but the cubemap itself will smoothly scroll along the edges, which will create a three-dimensional effect.

So, the first step, as always, is the initialization of resources in the InitializeResources() function. We load image files for each face of the cubemap:

Gfx Engine - Bitmaps
CPP
1void GfxBitmaps::InitializeResources()
2{
3 ...
4
5 this->scroller.Sides[0][2] = this->Scene.CreateObject(new Sprite("s1_1.webp",Transform(120,120,0)));
6 this->scroller.Sides[0][3] = this->Scene.CreateObject(new Sprite("s1_2.webp",Transform(120,120,0)));
7 this->scroller.Sides[0][0] = this->Scene.CreateObject(new Sprite("s1_3.webp",Transform(120,120,0)));
8 this->scroller.Sides[0][1] = this->Scene.CreateObject(new Sprite("s1_4.webp",Transform(120,120,0)));
9
10 this->scroller.Sides[1][2] = this->Scene.CreateObject(new Sprite("s2_1.webp",Transform(120,120,0)));
11 this->scroller.Sides[1][3] = this->Scene.CreateObject(new Sprite("s2_2.webp",Transform(120,120,0)));
12 this->scroller.Sides[1][0] = this->Scene.CreateObject(new Sprite("s2_3.webp",Transform(120,120,0)));
13 this->scroller.Sides[1][1] = this->Scene.CreateObject(new Sprite("s2_4.webp",Transform(120,120,0)));
14
15 this->scroller.Sides[2][2] = this->Scene.CreateObject(new Sprite("s3_1.webp",Transform(120,120,0)));
16 this->scroller.Sides[2][3] = this->Scene.CreateObject(new Sprite("s3_2.webp",Transform(120,120,0)));
17 this->scroller.Sides[2][0] = this->Scene.CreateObject(new Sprite("s3_3.webp",Transform(120,120,0)));
18 this->scroller.Sides[2][1] = this->Scene.CreateObject(new Sprite("s3_4.webp",Transform(120,120,0)));
19
20 this->scroller.Sides[3][2] = this->Scene.CreateObject(new Sprite("s4_1.webp",Transform(120,120,0)));
21 this->scroller.Sides[3][3] = this->Scene.CreateObject(new Sprite("s4_2.webp",Transform(120,120,0)));
22 this->scroller.Sides[3][0] = this->Scene.CreateObject(new Sprite("s4_3.webp",Transform(120,120,0)));
23 this->scroller.Sides[3][1] = this->Scene.CreateObject(new Sprite("s4_4.webp",Transform(120,120,0)));
24
25 ...
26}
27
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

Note that the identifiers of the loaded resources are passed to the scroller, an instance of the custom Aperture class with the internal structure of which we propose to figure out on our own. We can only note that this class is used to control the process of scrolling images.

Now that the images are loaded, you can start displaying them on the screens in a smoothly changing position, i.e. scrolling. Moreover, you need to make sure that the scrolling occurs as similarly as possible on all modules.

To do this, we use the following approach: one module calculates the scroll offset and sends its value to other modules, which simply use it.

Calculate the current value of the scroll offset in on_Tick() function on module 0 and send it to the neighbours:

Gfx Engine - Bitmaps
CPP
1void GfxBitmaps::on_Tick(uint32_t currentTime, uint32_t deltaTime)
2{
3 if(this->Module==0)
4 {
5 this->scroller.Tick();
6
7 //Send the position to other modules
8 this->networkMessage.Reset(true);
9 this->networkMessage.WriteInt(this->scroller.Offset,32);
10 this->SendNetworkMessage(&this->networkMessage);
11 }
12}
13
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

Other modules will receive the scroll offset value via

Gfx Engine - Bitmaps
CPP
1void GfxBitmaps::on_Message(uint32_t type, uint8_t* pkt, u32_t size)
2{
3 NetworkMessage nm(pkt,size);
4
5 if(this->Module!=0)
6 {
7 this->scroller.Offset = nm.ReadInt(32);
8 }
9}
10
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

And of course, the rendering is done in on_Render() function:

Gfx Engine - Bitmaps
CPP
1void GfxBitmaps::on_Render(std::array<Cubios::Screen, 3>& screens)
2{
3 Cubios::TOPOLOGY_place_t place;
4 std::vector<Sprite_t> spr;
5
6 for(auto it = screens.begin(); it != screens.end(); ++it)
7 {
8 spr.clear();
9
10 //Start adding objects to a screen
11 it->Begin(TOPOLOGY_orientation_mode_t::ORIENTATION_MODE_GRAVITY,true);
12
13 TOPOLOGY_orientation_t dir = it->Direction();
14
15 if(dir!=TOPOLOGY_orientation_t::ORIENTATION_UP && dir!=TOPOLOGY_orientation_t::ORIENTATION_DOWN)
16 {
17 Cubios::TOPOLOGY_getPlace(this->Module, it->ID(),TOPOLOGY_orientation_mode_t::ORIENTATION_MODE_GRAVITY, &place);
18
19 //add fullscreen sprite
20 this->scroller.GetSprites(dir, place.position, &spr);
21
22 for(int i=0;i<spr.size();i++)
23 {
24 it->Add(this->Scene[this->scroller.Sides[spr[i].side][spr[i].place]])->SetPosition(spr[i].xOffset,120);
25 }
26 }
27 else
28 {
29 it->Add(Scene[myBackground]);
30 }
31
32 //Finish adding objects
33 it->End();
34 }
35}
36
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

The principle of rendering is simple: each time the screens are redrawn, an instance of the Aperture class is asked for a list of identifiers for pictures that should currently be drawn on a particular screen, taking into account the shift. Then the images from the list are added to the screen.

And a sort of quasi-animated cubemap comes out!

Context Rail

Project files

GfxBitmaps.cpp
project/src/GfxBitmaps.cpp
GfxBitmaps.h
project/src/GfxBitmaps.h
wowcubeapp-build.json
project/wowcubeapp-build.json
Jump Grid

On This Page

Gfx Engine BitmapsStep 1 InitializationStep 2 Setting parametersStep 3 RenderingThe Example
Context Rail

Related nodes

info.json
Examples / SDK 6.1 / C++ / rendering / Gfx Engine - Bitmaps
GfxBitmaps.cpp
Examples / SDK 6.1 / C++ / rendering / Gfx Engine - Bitmaps / project / src
GfxBitmaps.h
Examples / SDK 6.1 / C++ / rendering / Gfx Engine - Bitmaps / project / src
wowcubeapp-build.json
Examples / SDK 6.1 / C++ / rendering / Gfx Engine - Bitmaps / project
Previous Node
wowcubeapp-build.json
Examples / SDK 6.1 / C++ / rendering / Gfx Engine - Orientation / project
Next Node
info.json
Examples / SDK 6.1 / C++ / rendering / Gfx Engine - Bitmaps