Setting up a project and render loop

This first tutorial covers setting up a project, setting up a render loop and accessing the Irrlicht 3D graphics engine. The steps outlined here are the starting point for all games developed in Ginjo-Builder. The following topics are covered in this tutorial:

  1. Creating a project
  2. Writing a compiler options XML file
  3. Entry point and Irrlicht options
  4. Irrlicht namespaces
  5. SceneManager
  6. Loading a model
  7. Render loop
  8. Running the program

The tutorial's code files and media files are installed along with Ginjo-Builder and can be accessed from the 'Project' window that is shown when the editor starts. This tutorial is called '01_RenderLoop' in the 'Tutorials' tab.

1. Creating a project

A program consists of source files which have the extension .gbc, the project file that has the extension .gbp, and a compiler options XML file.

When you start Ginjo-Builder an empty project is automatically created. Alternatively, you can create a new project through the Project menu. (See Editor basics for a brief description of managing projects and files.) Right click on project's top level tree node named "New GBP(Unsaved)" and select Rename folder (or click on the Rename folder icon in the project tree's toolbar). Rename the folder to "RenderLoop".

Your project tree should look like the following after you rename the top node:

Next, save the project as "MyProject.gbp" from the Project menu. Once a project is saved on disc, changes made to the project will automatically be saved when the project is closed or the editor is closed.

2. Writing a compiler options XML file

Ginjo-Builder will look for an XML file that has the same name as the top level tree node in the project tree. In our case this is "RenderLoop", so we need to create a file called "RenderLoop.xml". (See Compiler options for a list of recognized XML elements.)

Your project tree should look like the following after you have saved the two files:

The compiler options XML file and .gbc files are the only ones the compiler cares about. You can safely include other files in the project tree, as they will be ignored by the compiler.

There are two required elements in the XML file: <exe> and <startup>. The <exe> element specifies the executables path (including the name). When running in debug mode the executable is not created, but the <exe> tag is still required, because the path is set as the programs current directory so that you can use relative paths in your code when loading sounds, graphics etc. (The 1.0 release will allow for creating standalone programs ('exe' files) that you can distribute.) The <startup> element specifies the entry point for the program. This is the function that will be called when your program starts. Format is "FileName.FunctionName", and the startup function must be of the form:

function FunctionName(var:String cmdArgs[]) returns Int32

Enter the following into the "RenderLoop.xml" file and save it. (The file is only parsed, and therefore the changes only take effect, when the file is saved.)

<?xml version="1.0" encoding="utf-8"?>
<root>
   <exe path=".\game.exe" />
   <startup name="myGame.main" />
</root>

3. Entry point and Irrlicht options

In our XML file we specified the startup function as "myGame.main". Double-click on "myGame.gbc" in the project tree to open it, and add the following function, called "main". When you run your program this is the function where execution starts.

function main(var:string cmdArgs[]) returns Int32
{

}

Now we are ready to initialize the Irrlicht 3D engine. In Irrlicht parlance we create and "Irrlicht device", through which we can interact with the game engine. Ginjo-Builder provides access to Irrlicht through the GB namespace. For this example we will only need to use three options, we will let the Irrlicht engine use the defaults for other options. Our code becomes:

function main(var:string cmdArgs[]) returns Int32
{
   var:gb.IrrlichtCreationParameters options=new gb.IrrlichtCreationParameters()
   //Without anti-aliasing our model edges would be jagged 
   options.AntiAliasing=255
   //Tell Irrlicht to use OpenGL for graphics
   options.DriverType=gb.video.DriverType.OpenGL
   //Turn off logging, we won't be using it for now
   options.LoggingLevel=gb.LogLevel.None
   
   var:gb.IrrlichtDevice device = gb.IrrlichtDevice.CreateDevice(options)
   //Also set our window's title
   device.SetWindowCaption('Hello World')
}

Note that you can use the IntelliDoc Symbol Info feature to look-up symbol types and definitions. The 'lightbulb' button on the toolbar looks-up the symbol type for the current cursor location and displays it in a tooltip. Pressing F1 also shows the tooltip.

4. Irrlicht namespaces

Ginjo-Builder provides access to Irrlicht through the GB namespace:

Namespace Description
GB Everything in the Irrlicht Engine can be found in this namespace
GB.core Basic classes such as vectors and planes are in this namespace
GB.video Classes for accessing the video driver. All 2d and 3d rendering is done here.
GB.scene All scene management can be found in this namespace: Mesh loading, special scene nodes, billboards, etc
GB.io Like most C++ libraries, Irrlicht duplicates functionality of standard language libraries. This namespace provides interfaces for input/output: Reading and writing files, accessing zip archives, xml files, etc. We discourage the use of GB.io, you should use the .NET System.IO namespace instead.
GB.gui The gui namespace contains useful classes for easy creation of a graphical user interface inside the render window.

5. SceneManager

Now that we have access to the Irrlicht game engine through our IrrlichtDevice, we are ready to start drawing. The device driver of IrrlichtDevice provides functionality to perform 2d and 3d graphics functions. All rendering and texture manipulation is done with this class. However, when building a game you will mostly interact with scene graphs and scene nodes, and use a SceneManager to take care of rendering. Add the following two lines of code to your main function to get the VideoDriver and SceneManager:

var:gb.video.VideoDriver driver=device.VideoDriver
var:GB.Scene.SceneManager smgr=device.SceneManager

6. Loading a model

The SceneManager takes care of handling meshes for us, as well as lighting and cameras. In the following code we will add a camera to the scene using the our SceneManager and then load the 'Warrior Princess' and add it to the scene. The Warrior model has built-in animation, so we will use the AnimatedMesh and AnimatedMeshSceneNode objects in the Scene namesapce. In this tutorial we do not have any lights, thus the Lighting material flag of the model must be turned to false. (Otherwise the model will be completely black.) Finally, we will set the camera's target to look at the models position. Add this code to your main function:

//add camera 
var:gb.scene.CameraSceneNode Camera= smgr.AddCameraSceneNode()
camera.Position=new gb.core.Vector3Df(10,30,-50)

//load model from relative path ..\media\warrior.x
var:gb.scene.AnimatedMesh WarriorMesh = smgr.GetMesh('..\media\warrior.x')
//add model to scene
var:gb.Scene.AnimatedMeshSceneNode Warrior
Warrior = smgr.AddAnimatedMeshSceneNode(WarriorMesh)

if(!isNull(Warrior)){
    Warrior.Scale = new gb.core.Vector3Df(20)
    Warrior.SetMaterialFlag(gb.video.MaterialFlag.Lighting, false)
    camera.Target = Warrior.Position + new gb.core.Vector3Df(0,20,0)
}

We defined the executable path as ".\game.exe" in our "RenderLoop.xml" file, so smgr.GetMesh in the above code will look for a "media" folder in the parent folder of where the "RenderLoop.xml" file is saved, and load the "warrior.x" model from that "media" folder. In step 8 when we run the program it will show our model as below. But first we need a render loop.

7. Render loop

The render loop runs continuously and redraws the scene. Redrawing the screen requires a call to the drivers BeginScene function. When we are done, we need to call EndScene so that the driver can update the screen. The SceneManager will handle rendering the scene graph for us. Add this code to your main function:

var:gb.video.Color background=new gb.video.Color(160, 160, 160)
while (device.Run()){
   driver.BeginScene(gb.video.ClearBufferFlag.All, background)
   smgr.DrawAll()
   driver.EndScene()
}

8. Running the program

A project can be run using the Project->Debug mode->Run menu or from its icon on the toolbar. (See compiling for details.)