Documentation/Programming Articles/Overview of a GuiRenderer

From NeoAxis 3D Engine Wiki

Jump to: navigation, search
Go to higher level

Contents

Introduction

In this article you will examine the GuiRenderer class that implements GUI rendering. You will learn to display simple objects (such as rectangle, line, triangle and text) as well as use GuiRenderer for viewing debug information and game statistics.

You can also use GuiRenderer for creating GUI classes. You can find more information on creating GUI with GuiRenderer here.

GuiRenderer is available through the OnRenderUI method of the game window class or control class:

public class ActionGameWindow : GameWindow
{
 
    ...
 
    protected override void OnRenderUI(GuiRenderer renderer)
    {
        base.OnRenderUI(renderer);
 
        ...
 
        //Place your code here
    }
}

The GuiRenderer is set as a parameter in the OnRenderUI method.

In the examples below we will be using the OnRenderUI method of the ActionGameWindow class (first- or third-person shooter window), stored in the Game project. This method does already have the code calling its parent OnRenderUI method as well as thirty more lines of code after which you can program the parameters you need.

To see these examples in action you will have to compile the code and start a map using the ActionGameWindow class (e.g. TankDemo).

Rendering a painted rectangle

For rendering a painted rectangle the AddQuad method of the GuiRenderer class is used. It is possible both to paint a rectangle and to put a texture on it.

The list of available methods includes:

void AddQuad( Rect rectangle, Rect textureCoordRectangle, Texture texture, ColorValue color, bool clamp )
void AddQuad( Rect rectangle, Rect textureCoordRectangle, Texture texture, ColorValue color )
void AddQuad( Rect rectangle, Rect textureCoordRectangle, Texture texture )
void AddQuad( Rect rectangle, ColorValue color )

The simple method that paints a rectangle with one color has the following parameters:

Parameter Description
rectangle Rectangle position. Coordinates are proportionate to screen size. The coordinates of the upper-left corner of the screen are (0, 0), while those for the lower-right corner are (1, 1).
color Rectangle color. Consists of four components: Red, Green, Blue and Alpha (transparency).

Now let us examine the AddQuad method (applying textures to a rectangle) and its parameters.

Parameter Description
rectangle Rectangle position. Coordinates are proportionate to screen size. The coordinates of the upper-left corner of the screen are (0, 0), while those for the lower-right corner are (1, 1).
textureCoordRectangle The coordinates of the upper-left corner of the screen are (0, 0), while those for the lower-right corner are (1, 1).
texture A texture to be applied to the rectangle.
color Color multiplier. After applying the texture each pixel’s color is multiplied by this value.
clamp Switches texture overlapping on/off. Texture coordinates clamps at 1.0.

The example below renders two rectangles: a painted one and one with a texture.

renderer.AddQuad(new Rect(.3f, .1f, .7f, .4f), new ColorValue(0, 1, 0, .5f));
 
Texture texture = TextureManager.Instance.Load( "Types\\StaticObjects\\StaticBox\\StaticBox.dds" );
renderer.AddQuad(new Rect(.3f, .5f, .7f, .8f), new Rect(0, 0, 1, 1), texture);
Rendering a painted rectangle

Rendering lines and rectangles

The list of available methods includes:

void AddLine( Vec2 start, Vec2 end, ColorValue color )
void AddRectangle( Rect rectangle, ColorValue color )

Lines are rendered using the AddLine method of the GuiRenderer class. The method has three parameters:

Parameter Description
start Coordinates of the line origin (proportionate to screen size).
end Coordinates of the line end (proportionate to screen size).
color Color of the line.

For rendering rectangles the AddRectangle method is used. Unlike the AddQuad method this method does not paint the rectangle. The list of method’s parameters includes:

Parameter Description
rectangle Coordinates of the rectangle (proportionate to screen size).
color Rectangle color.

The example below renders two lines and a rectangle:

renderer.AddLine(new Vec2(.3f, .3f), new Vec2(.7f, .7f), new ColorValue(1, 0, 0));
renderer.AddLine(new Vec2(.3f, .7f), new Vec2(.7f, .3f), new ColorValue(1, 0, 0));
renderer.AddRectangle(new Rect(.3f, .3f, .7f, .7f), new ColorValue(1, 0, 0));
Rendering lines and rectangles

Rendering text

There are two methods in the GuiRender class for rendering text: AddText and AddTextLines. While the first one renders a single line, the second one renders a list..

The list of available methods includes:

void AddText( Font font, string text, Vec2 position, HorizontalAlign horizontalAlign, VerticalAlign verticalAlign, ColorValue color )
void AddText( string text, Vec2 position, HorizontalAlign horizontalAlign, VerticalAlign verticalAlign, ColorValue color )
void AddText( string text, Vec2 position, HorizontalAlign horizontalAlign, VerticalAlign verticalAlign )
void AddText( string text, Vec2 position )
void AddTextLines( Font font, IList<string> lines, Vec2 pos, Vec2 step, HorizontalAlign horizontalAlign, VerticalAlign verticalAlign, ColorValue color )
void AddTextLines( IList<string> lines, Vec2 pos, Vec2 step, HorizontalAlign horizontalAlign, VerticalAlign verticalAlign, ColorValue color )

There are 4 variants of the AddText method. The list of parameters includes:

Parameter Description
font Text font.
text The text to be displayed on the screen.
position Text position on the screen (coordinates should be proportionate to screen size).
horizontalAlign Horizontal alignment. Can be set to: Left, Center and Right.
verticalAlign Vertical alignment. Can be set to: Top, Center and Bottom.
color Font color.

Not let us examine the parameters of the AddTextLines method used for rendering lists of lines:

Prameter Description
lines Line list to be displayed on the screen.
pos Line list position on the screen (coordinates should be proportionate to screen size).
step Text position on the screen (should be proportionate to screen size).
horizontalAlign Horizontal alignment. Can be set to: Top, Center and Bottom.
verticalAlign Vertical alignment. Can be set to: Top, Center and Bottom.
color Font color.

The example below illustrates the use of both methods:

renderer.AddText(renderer.DefaultFont, "GuiRenderer Test", new Vec2(.5f, .4f), HorizontalAlign.Center, 
    VerticalAlign.Center, new ColorValue(0, 0, 1));
renderer.AddTextLines(new List<string> { "Line #1", "Line #2", "Line #3" }, new Vec2(.4f, .5f), 
    new Vec2(.03f, .02f), HorizontalAlign.Center, VerticalAlign.Top, new ColorValue(0, 1, 0));
Displaying list on the screen

Now you will learn to render with your own font.

First, declare a variable (make it an element of the ActionGameWindow' class) to store your font in it.

Font myFont;

Now you have to load the new font. Do it with the FontManager class (add a code loading the new font at the end of the OnAttach method):

protected override void OnAttach()
{
	base.OnAttach();
	...
	myFont = FontManager.Instance.LoadFont("PrecompiledImageExample", .1f);
}

As you see, you have specified font name and size in the LoadFont method (font side is proportionate to screen size)

Now, render a text with your new font by putting the following code in the end of the OnRenderUI method:

//Text rendering. The first parameter is the font name.
renderer.AddText(myFont, "GuiRenderer Test", new Vec2(.5f, .4f), HorizontalAlign.Center,
    VerticalAlign.Center, new ColorValue(0, 0, 1));
Rendering your own font

You can learn more about font use in NeoAxis Engine here.

Rendering triangles

Triangle rendering is implemented with the AddTriangles method. This method requires coordinates of three triangle apexes to work.

The list of available methods includes:

void AddTriangles( IList<TriangleVertex> vertices )
void AddTriangles( IList<TriangleVertex> vertices, Texture texture, bool clamp )

The parameter list of the AddTriangles method includes:

Parameter Description
vertices The list of triangle vertices. Each vertex has information on its position, color and texture coordinates. When a texture is applied to the triangle, its vertex color is multiplied by texture pixel color.
texture A texture to be applied to the triangle.
clamp Switches texture overlapping on/off. Texture coordinates clamps at 1.0.

Just as with rectangles you can paint and apply texture to triangles.

The example below renders a gradient triangle and two triangles with applied textures, thus making a parallelogram:

List<GuiRenderer.TriangleVertex> vertices1 = new List<GuiRenderer.TriangleVertex>() {
    new GuiRenderer.TriangleVertex(new Vec2(.5f, .1f), new ColorValue(1, 0, 0, .5f)),
    new GuiRenderer.TriangleVertex(new Vec2(.3f, .3f), new ColorValue(0, 1, 0, .5f)),
    new GuiRenderer.TriangleVertex(new Vec2(.7f, .3f), new ColorValue(0, 0, 1, .5f))};
renderer.AddTriangles(vertices1);
 
List<GuiRenderer.TriangleVertex> vertices2 = new List<GuiRenderer.TriangleVertex>() {
    new GuiRenderer.TriangleVertex(new Vec2(.4f, .5f), new ColorValue(1, 1, 1), new Vec2(0, 0)),
    new GuiRenderer.TriangleVertex(new Vec2(.7f, .5f), new ColorValue(1, 1, 1), new Vec2(1, 0)),
    new GuiRenderer.TriangleVertex(new Vec2(.6f, .8f), new ColorValue(1, 1, 1), new Vec2(1, 1)),
    new GuiRenderer.TriangleVertex(new Vec2(.4f, .5f), new ColorValue(1, 1, 1), new Vec2(0, 0)),
    new GuiRenderer.TriangleVertex(new Vec2(.3f, .8f), new ColorValue(1, 1, 1), new Vec2(0, 1)),
    new GuiRenderer.TriangleVertex(new Vec2(.6f, .8f), new ColorValue(1, 1, 1), new Vec2(1, 1))};
Texture texture = TextureManager.Instance.Load("Types\\StaticObjects\\StaticBox\\StaticBox.dds");
renderer.AddTriangles(vertices2, texture, true);
Вывод на экран треугольников

Rendering behind the scene

The GuiRenderer class enables GUI elements rendering behind 3D scene. E.g. you can render 3D objects with some background video on.

To make GUI element render behind a 3D scene you have to call the PushRenderBehindScene method of the GuiRenderer class. In order for the rendering to succeed this method’s parameter has to be set to true. After having rendered all the objects you have to restore this parameter's initial value by calling the PopRenderBehindScene method.

As an example the OnRenderUI method will be implemented in the MainMenuWindow class (stored in the MainMenuWindow.cs file of the Game project).

protected override void OnRenderUI(GuiRenderer renderer)
{
    //Turning the “background rendering” mode on
    renderer.PushRenderBehindScene(true);
 
    //Creating a texture
    Texture texture = TextureManager.Instance.Load("Types\\StaticObjects\\StaticBox\\StaticBox.dds");
 
    //Creating a rectangle with the applied texture
    renderer.AddQuad(new Rect(0, 0, 1, 1), new Rect(0, 0, 1, 1), texture);
 
    // Turning the “background rendering” mode off
    renderer.PopRenderBehindScene();
}
Rendering a UI behind a scene

Clipping

The GuiRenderer enables clipping in the user-specified region. Using the PushClipRectangle you can set a clipping rectangular (you can set several regions as well).

Below you can see the code that implements clipping:

//Switching clipping mode on
renderer.PushClipRectangle(new Rect(.25f, .25f, .75f, .75f));
 
//Creating a texture
Texture texture = TextureManager.Instance.Load("Types\\StaticObjects\\StaticBox\\StaticBox.dds");
 
//Rendering a rectangle with an applied texture
renderer.AddQuad(new Rect(0, 0, 1, 1), new Rect(0, 0, 1, 1), texture);
 
// Switching clipping mode off
renderer.PopClipRectangle();
Clipping GUI elements

Changing the blending function

While rendering painted rectangles or triangles you can specify the color to paint them with or by which texture pixels will be multiplied. This color has a transparency component used for blending. There are two blending functions you can adjust:

  • AlphaBlend – pixel color is mixed with the background color,
  • AlphaAdd - pixel color is added to the background color.

You can select the blending function by means of the PushSpecialBlendingType method of the GuiRenderer class. Blending function is a parameter of the BlendingTypes method. After having complete the blending function use, the PopSpecialBlendingType method is called that removes the last added blending function.

The default blending function is AlphaBlend.

The code below is using both blending functions subsequently removing them:

//Creating a texture
Texture texture = TextureManager.Instance.Load("Types\\StaticObjects\\StaticBox\\StaticBox.dds");
 
//Rendering a painted rectangle with the AlphaBlend function. The AlphaBlend is switched on by default.
renderer.AddQuad(new Rect(.1f, .375f, .45f, .625f), new Rect(0, 0, 1, 1), texture, new ColorValue(1, 1, 1, .5f));
 
//Changing the blending function
renderer.PushSpecialBlendingType(GuiRenderer.BlendingTypes.AlphaAdd);
 
//Rendering a painted rectangle
renderer.AddQuad(new Rect(.55f, .375f, .9f, .625f), new Rect(0, 0, 1, 1), texture, new ColorValue(1, 1, 1, .5f));
 
//Removing the blending functions
renderer.PopSpecialBlendingType();
Изменение функции блендинга

Custom Shader Mode

In NeoAxis you can process GUI elements using your own shaders. This mode is switched on with the PushCustomShaderMode method of the GuiRenderer class. This method has the following parameters:

Parameter Description
sourceFileName Path to the shader file from the Data folder of your project.
additionalTextures The list of additional textures.
parameters The list of parameters transferred to the shader.

After having rendered all the objects you have to restore this parameter's initial value by calling the PopCustomShaderMode method.

In order to see the UI being processed with shaders call the NeoAxis Engine Demo and press the Gui Test button.

Gui renderer10.jpg

You can find a code using user-shaders in the GuiTestWindow.cs file of the Game project. Below you can see the lines from this code implementing UI processing with shaders:

//The list of additional textures
List<GuiRenderer.CustomShaderModeTexture> additionalTextures = new List<GuiRenderer.CustomShaderModeTexture>();
//Adding a texture to the list
additionalTextures.Add( new GuiRenderer.CustomShaderModeTexture( "Gui\\Various\\Engine.png", false ) );
 
//The list of parameters
List<GuiRenderer.CustomShaderModeParameter> parameters = new List<GuiRenderer.CustomShaderModeParameter>();
float offsetX = ( EngineApp.Instance.Time / 60 ) % 1;
Vec2 mouse = EngineApp.Instance.MousePosition;
//Adding a parameter to the list
parameters.Add( new GuiRenderer.CustomShaderModeParameter( "testParameter", new Vec4( offsetX, mouse.X, mouse.Y, 0 ) ) );
 
//Switching the user-shader mode on
renderer.PushCustomShaderMode( "Materials\\Common\\CustomGuiRenderingExample.cg_hlsl", additionalTextures, parameters )

You can find the shader code in this file Bin\Data\Materials\Common\CustomGuiRenderingExample.cg_hlsl:

// Copyright (C) 2006-2011 NeoAxis Group Ltd.
 
void main_vp(
	uniform float4x4 worldViewProjMatrix,
	uniform float4 viewportSize,
 
	float4 position : POSITION,
	float4 vertexColor : COLOR0,
	float2 texCoord : TEXCOORD0,
 
	out float4 oPosition : POSITION,
	out float2 oTexCoord : TEXCOORD0,
	out float4 oVertexColor : TEXCOORD1,
	out float2 oViewportSizeInPixels : TEXCOORD2,
	out float2 oScreenPosition : TEXCOORD3
	)
{
	oPosition = mul(worldViewProjMatrix, position);
	oTexCoord = texCoord;
	oVertexColor = vertexColor;
	oViewportSizeInPixels = viewportSize.xy;
	oScreenPosition = (float2(position.x, -position.y) + 1) / 2;
}
 
void main_fp(
	float2 texCoord : TEXCOORD0,
	half4 vertexColor : TEXCOORD1,
	float2 viewportSizeInPixels : TEXCOORD2,
	float2 screenPosition : TEXCOORD3,
 
	uniform sampler2D diffuseMap : register(s0),
	uniform sampler2D additionalMap : register(s1),
 
	uniform float4 testParameter,
 
	out half4 oColor : COLOR)
{
/*
	//default code
	oColor = (half4)tex2D(diffuseMap, texCoord) * vertexColor;
*/
 
/*
	//simple example
	vertexColor *= half4(1, 0, 0, vertexColor.a);
	oColor = (half4)tex2D(diffuseMap, texCoord) * vertexColor;
	return;
*/
 
	float aspectRatio = viewportSizeInPixels.x / viewportSizeInPixels.y;
 
	//calculate tex coord for additional map
	float offsetX = testParameter.x;
	float2 additionalMapTexCoord = float2(screenPosition.x, (screenPosition.y - .5f) * 2.2f / aspectRatio + .5f);
	//make scroll and waving
	additionalMapTexCoord.x += offsetX;
	additionalMapTexCoord.y += sin((offsetX - screenPosition.x) * 100) * .01f;
	//clamp by Y
	additionalMapTexCoord.y = saturate(additionalMapTexCoord.y);
 
	//circle
	float2 mouse = testParameter.yz;
	float2 diff = screenPosition - mouse;
	float distance = length(float2(diff.x * aspectRatio, diff.y));
	float alpha = .3f;
	if(distance < .3f)
		alpha = 4;
	if(distance < .29f)
		alpha = 1;
	vertexColor.a *= alpha;
 
	half4 color = (half4)tex2D(diffuseMap, texCoord);
	color.rgb += tex2D(additionalMap, additionalMapTexCoord).rgb;
	oColor = color * vertexColor;
}
Using user-shaders