Skip to main content
Version: 1.0.0-preview.38

Rendering Rectangles

Guide Source Code

Go to the

guide project to see the source code for a fully working example of this guide.

This guide will show you only some steps relative to the guide project.
It will only show you the most essential information related to rendering rectangles.
The guide project uses most of the concepts discussed in the previous guides.

Rendering primitive shapes is a fundamental part of game development. Shapes can be used to create custom UI elements for guides, tutorials, and even debug drawing.

What is debug drawing, you ask?

Debug drawing renders shapes to the screen to help you debug your game. For example, you could draw a rectangle for sprites bounding box to help you see where the sprite is on the screen, which can help with debugging issues with collision detection.

In this guide, you will learn how to render rectangles to the screen using Velaptor.

The rectangle has different attributes you can set to customize how the rectangle will look. These attributes range from position, size, color, gradients, and even the radius of the corners.

Let's render some rectangles!

Creating & Rendering Rectangles

Creating a rectangle is just as easy as creating any C# object. The type to use when creating a rectangle is RectShape. The RectShape type is a record struct. Using a struct keeps things performant and lightweight.

Creating Empty Rectangle

Here is an example of creating a rectangle.

var rect = new RectShape();

The code above will create a rectangle with all attributes set to default values. If you were to render this, you would not see anything. The reason for this would be that we did not set the size of the rectangle.

Let's give the rectangle a size by setting the Width and Height properties.

var rect = new RectShape();
rect.Width = 100;
rect.Height = 100;

Rendering The Rectangle

To render the rectangle, we must create an IShapeRenderer renderer.

public Game()
{
// If you are rendering from a `Game` class, make sure you have a batcher
this.batcher = RendererFactory.CreateBatcher();
this.shapeRenderer = RendererFactory.CreateShapeRenderer();
}

Now that we have the renderer, we can render the rectangle to the screen. Add the code below to an OnDraw() lifecycle method in your Game or scene class.

protected void OnDraw(FrameTime frameTime)
{
IBatcher.Begin();

this.shapeRenderer.Render(rect);

IBatcher.End();
}

You should end up with a rectangle that looks like the image below.

rendered-rect

Rectangle Color

Setting the color of the rectangle involves setting the 'Color' property. This uses the System.Drawing.Color struct that is built right into dotnet.

var rect = new RectShape();
rect.Color = Color.RoyalBlue;

This should give you a rectangle that looks like the image below.

rendered-rect

Rectangle Position

Dealing with the position of the rectangle is straightforward. You can set the position of the rectangle by using the following properties:

  1. Position
  2. Top
  3. Bottom
  4. Left
  5. Right

Changing the values of the properties above will affect the other property values. For example, let's say your rectangle was at the position of (10, 20) and the size was (100, 200).

If you were to move the rectangle to the right by 30 pixels to using the Left property, then the value of the Right property would be 130.

The result is that it makes rectangle positioning easy to work with. Your code will also be more readable and maintainable because you can use the property that makes the most sense for the situation and the rest of your code.

Check out the code below:

var rect = new RectShape();

rect.Width = 10;
rect.Height = 20;
rect.Position = new Vector2(100, 200);

/* Starting Positions:
* Left: 95
* Right: 105
* Top: 190
* Bottom: 210
*/

rect.Left += 2;

/* Positions After Moving Left:
* Left: 97
* Right: 107
* Top: 190
* Bottom: 210
*/

rect.Top += 2;

/* Positions After Moving Down:
* Left: 95
* Right: 105
* Top: 192
* Bottom: 212
*/

rect.Width += 10;

/* Positions After Increasing Width:
* Left: 92
* Right: 112
* Top: 192
* Bottom: 212
*/

rect.Height += 20;

/* Positions After Increasing Width:
* Left: 92
* Right: 112
* Top: 182
* Bottom: 222
*/
NOTE ABOUT POSITIONING

The Position of a RectShape is relative to the center of the rectangle.
Not the top left corner.

Did you notice that the Width and Height properties changed the values of the Left, Right, Top, and Bottom properties?

Since the position of the rectangle is relative to the center of the rectangle, changing the value of the Width and Height of the rectangle will affect the position of the sides of the rectangle.

Solid & Empty Rectangles

You can render rectangles as solid or empty by setting the IsSolid property to true or false.

Here is an example of how to create a solid rectangle:

var rect = new RectShape(); // My default is solid

rect.IsSolid = false; // I am not solid
rect.IsSolid = true; // I am solid again

Border Thickness

When it comes to the border thickness, it is only visible when the rectangle is not solid. The border thickness is set using the BorderThickness property and is of type float.

Refer to the code below to see how to set the border thickness.

var rect = new RectShape();
rect.Width = 100;
rect.Height = 100;

rect.IsSolid = false;
rect.BorderThickness = 25;

Using the settings above, this is what your rectangle would look like.

border-thickness

Corner Radius

You can use the CornerRadius property to control the radius of the rectangle's corners. This property is of type CornerRadius, which is a read-only record struct.

Different Values Per Corner

Create a corner radius with different values for each corner.

var rect = new RectShape();
rect.CornerRadius = new CornerRadius(10, 20, 30, 40);

If the width and height of the rectangle were 80, the result would be like the image below.

radius-sample

All Corners The Same

If you want all radius values to be the same, use the code below.

var rect = new RectShape();
rect.CornerRadius = new CornerRadius(25);

If the width and height of the rectangle was 100, the result would be like the image below.

all-corners-same

One Corner At A Time

What if you wanted to change only one of the corners and keep the rest the same?
You can reduce code using the following static methods on the CornerRadius struct.

var rect = new RectShape();
rect.CornerRadius = new CornerRadius(200);

rect.CornerRadius = CornerRadius.SetTopLeft(rect.CornerRadius, 10);
rect.CornerRadius = CornerRadius.SetTopRight(rect.CornerRadius, 20);
rect.CornerRadius = CornerRadius.SetBottomRight(rect.CornerRadius, 30);
rect.CornerRadius = CornerRadius.SetBottomLeft(rect.CornerRadius, 40);

Empty Radius

If you want to empty the CornerRaduis or check if the CornerRaduis is empty.

var rect = new RectShape();
rect.CornerRadius = new CornerRadius(100);

var isEmpty = rect.CornerRadius.IsEmpty; // False

// NOTE: The 'Empty' method does not empty the current instance. It just creates a new empty instance.
rect.CornerRadius = CornerRadius.Empty();

isEmpty = rect.CornerRadius.IsEmpty; // True

Radius Limits

One thing to note is that there are internal limits to the radius values, which are as follows:

  1. The minimum value is 0. Any values below 0 will be set to 0.
  2. The maximum value is always limited to half of the smallest width or height of the rectangle that the radius is affecting.
VALUES LARGER THEN THE maximum

Using values larger than the smallest half-width or height or values smaller than 0 is okay.
The rectangle will be rendered at the minimum or maximum value. This is all taken care of for you.

Let's give a quick example. If the rectangle's width is 100 and the height is 200. The maximum value for the radius will be 50.

If you want to update the radius values to scale proportionally as the width or height of the rectangle changes, you have to implement this on your own.

Color Gradients

You can apply color gradients to the rectangle, which can come in two types. Apply the gradient type by setting the GradientType property to either GradientType.Horizontal or GradientType.Vertical.

These gradients will transition from one color to another using the GradientStart and GradientStop properties.

The code below shows you how you could have a horizontal color gradient that would transition from
Color.MediumSeaGreen to Color.MediumPurple, and a vertical color gradient that would transition from Color.Teal to Color.DarkOrange.

var hGradRect = new RectShape();
// Horizontal gradient rectangle
hGradRect.GradientType = GradientType.Horizontal;
hGradRect.GradientStart = Color.MediumSeaGreen;
hGradRect.GradientStop = Color.MediumPurple;

// Vertical gradient rectangle
var vGradRect = new RectShape();
vGradRect.GradientType = GradientType.Vertical;
vGradRect.GradientStart = Color.Teal;
vGradRect.GradientStop = Color.DarkOrange;

This would end with the result shown below.

horizontal-gradient vertical-gradient

GRADIENTS WHEN SET TO NONE

Even if you have the GradientStart and GradientStop properties set, if the GradientType is set to GradientType.None, the gradient will not be rendered, and the rectangle will be rendered using the Color property.

Vector Containment

You can quickly check if the rectangle contains a Vector2 in 2D space. Checking if a RectShape contains a Vector2 is done using the Contains() method.

var rect = new RectShape();
rect.Position = new Vector2(50, 50);
rect.Width = 100;
rect.Height = 100;


var vector = new Vector2(10, 10);
var isNotContained = rect.Contains(vector); // False

vector = new Vector2(60, 60);
var isContained = rect.Contains(vector); // True