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. Simple Shapes - Rectangles
Mission NodeSDK 6.2C++renderingProject Included

Simple Shapes - Rectangles

Rendering Rectangles The next simple graphics primitive that follows a line and can be rendered with WOWCube API is a rectangle . In geometry, a rectangle is...

Examples / SDK 6.2 / C++ / rendering

Rendering - Rectangles

The next simple graphics primitive that follows a line and can be rendered with WOWCube API is a rectangle.

In geometry, a rectangle is a shape that has four sides and four corners. Its two sides meet at right angles, each measuring 90 degrees. The opposite sides of a retangle have the same lengths and are parallel.

Two sides are said to be parallel when the distance between them remains the same at all points.

To draw a rectangle, we would want to provide coordinates of two points A and B, which are tophand left and bottomhand right corners of a rectangle and the fill color.

The coordinates define screen positions of each corner.

In computer graphics, two types of rectangles are defined: a solid rectangle and an outlined rectangle. The difference is in the way how these shapes are drawn. A solid rectangle is a shape filled with a color, while an outlined rectangle has visible edges, but no filling, i.e it is transparent from inside.

Unlike the solid rectangle, an outlined rectangle can be drawn as a composition of four lines. That is why WOWCube API does not provide a dedicated funcion for rendering of such objects.

The fill color of a rectangle is defined as RGB value.

The RGB color model is an additive color model in which the red, green and blue primary colors of light are added together in various ways to reproduce a broad spectrum of colors. The name of the model comes from the first letters of the three primary colors: Red, Green and Blue

Actual values of each primary color range from 0 to 255, the range that a single 8-bit byte can offer. Since higher value means brighter color, the (0,0,0) represents no color, or so-called transparent color, (1,1,1) gives solid black, while (255,255,255) gives white.

The example

In order to demonstrate rectangle rendering, we will create a small cubeapp that renders a couple of rectangles that change size and position. As a matter of fact, the rendering is close to a very basic variant of an old-school "tunnel fly-through" effect.

As usual, the algorithmical side of the example is very simple: there are several rectangles that are rendered from far to near and change their size over time to create the illusion of flying through a tunnel.

So let's get to the code...

Initially, we declare a small array of rectangle objects. Each object will have two properties - the distance from the viewer and the horizontal offset. First property allows us to define how "far" the object is from us; obviously, the further object is the smaller it looks. The second property is more like for just an eye-candy, it lets us change position of a rectangle thus imitating a 'winding' tunnel.

Simple Shapes - Rectangles
CPP
1typedef struct
2{
3 int dist;
4 int xoffset;
5} Rect_t;
6
7Rect_t rects[2];
8
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

Then, we need to initialize this array with initial values. The initialization is very simple, we just create two rectangle objects at particular distances in InitializeResources():

Simple Shapes - Rectangles
CPP
1void Rectangles::InitializeResources()
2{
3 ...
4 //Create rects
5 for(int i=0;i<2;i++)
6 {
7 rects[i].dist = 90-40*i;
8 }
9 ...
10}
11
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

And now the only thing's left is to actually animate object positions on timer and render them.

The function that renders a rectangle object looks like this:

Simple Shapes - Rectangles
CPP
1void Rectangles::drawRect(int cx, int cy, int dist, int xoffset)
2{
3 float d = ((float)dist/100)*128;
4
5 //cacluclate size of a rectange
6 int size = 128-(int)d;
7
8 //calculate colors
9 int color = (size+10)*2;
10 if(color>255) color = 255;
11
12 int bgcolor = color/15;
13 if(bgcolor>100) bgcolor = 100;
14
15 //calculate horizontal offset
16 int xoff = ((int)d*xoffset)/90;
17 cx+=xoff;
18
19 //calculate border width
20 int border = 7-(dist*6)/90;
21
22 //Render rectangles
23
24 int x = cx-size;
25 int y = cy-size;
26 int w = size*2;
27 int h = size*2;
28
29 Cubios::GFX_drawRectangle(x, y, w, h, color|(0<<8)|(0<<16)|(255<<24));
30
31 x = cx-size+border;
32 y = cy-size+border;
33 w = (size-border)*2;
34 h = (size-border)*2;
35
36 Cubios::GFX_drawRectangle(x, y, w, h, bgcolor|(bgcolor<<8)|(bgcolor<<16)|(255<<24));
37}
38
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

It takes four input parameters - two coordinates of a center of rectangle, a distance from the viewer and a horizontal offset value. Then it calculates the actual size of rectangle's sides, the colors and the thickness of a border. And then it uses two identical WOWCube API calls to render a bordered rectangle on screen.

For the rendering, GFX_drawRectangle function is used:

Simple Shapes - Rectangles
CPP
1i32_t GFX_drawRectangle(i32_t x0, i32_t y0, i32_t w, i32_t h, u32_t color)
2
3 Parameters:
4 x0,y0 - a screen coordinate of a top-left corner of the rectangle
5 w,h - dimantions of the rectangle in screen coordinates
6 color - a hexadecimal representation of color of the rectangle
7
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

Finally, we would want to actually animate rectangle objects.

The animation is split in two parts: the calculation of linear motion of rectangle objects towards the viewer and the generation of horizontal shift values to imitate the winding.

Linear motion of rectangles is implemented in on_Render() callback. The algorithm is rather simple: each time the WOWCube device screens are refreshed, rectagles are drawn and the distance from each rectangle object to the viewer gets decremented till it hits zero. Then the object is returned to its original position, and the process repeats.

The only bit tricky part here is, tunnel effect requires rectangles to be drawn in a particular order, from nearest one to the endmost. Otherwise, rectangles will overlap incorrectly.

Things like this are typicaly solved with sorting algorithms. If objects in a set should be rendered with a particular order, they are getting sorted by either a distance from the viewer or another sorting criteria.

In this example, however, we are dealing with the simplest case of just two objects that still must be ordered before rendering, but can be simply flip-flopped with conditional if statement.

Sorting functions are outside of the scope of this example. Please see WOWCube API documentation and the corresponding examples

Simple Shapes - Rectangles
CPP
1void Rectangles::on_Render(std::array<Cubios::Screen, 3>& screens)
2{
3 for(auto it = screens.begin(); it != screens.end(); ++it)
4 {
5 Cubios::GFX_setRenderTarget(it->ID());
6 Cubios::GFX_clear(Colors::black);
7
8 if(rects[0].dist>rects[1].dist)
9 {
10 for(int i=1;i>=0;i--)
11 {
12 this->drawRect(128, 128, rects[i].dist,rects[i].xoffset);
13
14 rects[i].dist-=5;
15 if(rects[i].dist<=0) rects[i].dist = 90;
16
17 rects[i].xoffset = (int)(fOffset);
18 }
19 }
20 else
21 {
22 for(int i=0;i<2;i++)
23 {
24 this->drawRect(128, 128, rects[i].dist,rects[i].xoffset);
25
26 rects[i].dist-=5;
27 if(rects[i].dist<=0) rects[i].dist = 90;
28
29 rects[i].xoffset = (int)(fOffset);
30 }
31 }
32
33 Cubios::GFX_render();
34 }
35}
36
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

And the last bit, the on_PhysicsTick() callbacks looks like this:

Simple Shapes - Rectangles
CPP
1void Rectangles::on_PhysicsTick(const std::array<Cubios::Screen, 3>& screens)
2{
3 fOffset = sin(fParam)*30;
4 fParam+=0.085;
5}
6
Wrapped for easier reading. Turn wrap off to inspect exact line lengths.

In this callback, we use sine function to generate a periodically changing values of horizontal offset of rectangles.

Context Rail

Project files

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

On This Page

Rendering RectanglesThe example
Context Rail

Related nodes

info.json
Examples / SDK 6.2 / C++ / rendering / Simple Shapes - Rectangles
Rectangles.cpp
Examples / SDK 6.2 / C++ / rendering / Simple Shapes - Rectangles / project / src
Rectangles.h
Examples / SDK 6.2 / C++ / rendering / Simple Shapes - Rectangles / project / src
wowcubeapp-build.json
Examples / SDK 6.2 / C++ / rendering / Simple Shapes - Rectangles / project
Previous Node
wowcubeapp-build.json
Examples / SDK 6.2 / C++ / rendering / Simple Shapes - Lines / project
Next Node
info.json
Examples / SDK 6.2 / C++ / rendering / Simple Shapes - Rectangles