Irrlicht: Creating a Basic Template Application

Exclusive offer: get 50% off this eBook here
Irrlicht 1.7 Realtime 3D Engine Beginner's Guide

Irrlicht 1.7 Realtime 3D Engine Beginner's Guide — Save 50%

Create complete 2D and 3D applications with this cross-platform, high performance engine with this book and ebook

$26.99    $13.50
by Aung Sithu Kyaw Johannes Stein | November 2011 | Beginner's Guides Open Source

Irrlicht is an open source technology that is used to create 2D and 3D applications.

In this article by Aung Sithu Kyaw and Johannes Stein, authors of Irrlicht 1.7 Realtime 3D Engine, we will:

  • Create a new empty project
  • Explain the use of an Irrlicht device
  • Use the "game loop"

So let's get on with it...

(For more resources related to this topic, see here.)

Creating a new empty project

Let's get started by creating a new project from scratch. Follow the steps that are given for the IDE and operating system of your choice.

Visual Studio

Open Visual Studio and select File | New | Project from the menu. Expand the Visual C++ item and select Win32 Console Application. Click on OK to continue:

In the project wizard click on Next to edit the Application Settings. Make sure Empty project is checked. Whether Windows application or Console application is selected will not matter. Click on Finish and your new project will be created:

Let's add a main source file to the project. Right-click on Source Files and select Add New Item...|. Choose C++ File(.cpp) and call the file main.cpp:

CodeBlocks

Use the CodeBlocks project wizard to create a new project as described in the last chapter. Now double-click on main.cpp to open this file and delete its contents. Your main source file should now be blank.

Linux and the command line

Copy the make file of one of the examples from the Irrlicht examples folder to where you wish to create your new project. Open the make file with a text editor of your choice and change, in line 6, the target name to what you wish your project to be called.

Additionally, change, in line 10, the variable IrrlichtHome to where you extracted your Irrlicht folder. Now create a new empty file called main.cpp.

Xcode

Open Xcode and select File | New Project. Select Command Line Tool from Application. Make sure the type of the application is set to C++ stdc++:

When your new project is created, change Active Architecture to i386 if you are using an Intel Mac, or ppc if you are using a PowerPC Mac.

Create a new target by right-clicking on Targets, select Application and click on Next. Target Name represents the name of the compiled executable and application bundle:

The target info window will show up. Fill in the location of the include folder of your extracted Irrlicht package in the field Header Search Path and make sure the field GCC_ PREFIX_HEADER is empty:

Right-click on the project file and add the following frameworks by selecting Add Existing Frameworks...|:

  • Cocoa.framework
  • Carbon.framework
  • IOKit.framework
  • OpenGL.framework

Now, we have to add the static library named libIrrlicht.a that we compiled in Chapter 1, Installing Irrlicht. Right-click on the project file and click on Add | Existing Frameworks.... Now click on the button Add Other... and select the static library.

Delete the original compile target and delete the contents of main.cpp.

Time for action – creating the main entry point

Now that our main file is completely empty, we need a main entry point. We don't need any command-line parameters, so just go ahead and add an empty main() method as follows:

int main()
{
return 0;
}

If you are using Visual Studio, you need to link against the Irrlicht library. You can link from code by adding the following line of code:

#pragma comment(lib, "Irrlicht.lib")

This line should be placed between your include statements and your main() function.

If you are planning to use the same codebase for compiling on different platforms, you should use a compiler-specific define statement, so that this line will only be active when compiling the application with Visual Studio.

#if defined(_MSC_VER)
#pragma comment(lib, "Irrlicht.lib")
#endif

Irrlicht 1.7 Realtime 3D Engine Beginner's Guide Create complete 2D and 3D applications with this cross-platform, high performance engine with this book and ebook
Published: October 2011
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

(For more resources related to this topic, see here.)

Using Irrlicht namespaces

The Irrlicht 3D graphics engine is structured into different namespaces. Let's take a look at them:

Namespace

Description

irr

Everything in the Irrlicht 3D graphics engine is to be found in the irr namespace.

core

The irr::core namespace contains basic data types like vectors, lists, and arrays.

scene

The scene namespace-as the name suggests-covers everything that has to do with scene management.

video

Anything that has to do with 2D and 3D rendering or accessing the video driver is found in the video namespace.

io

If you would need to load or save data from files such as XMLs or packaged archives from your local hard drive, you would need to use methods from the io namespace.

Make sure to add: #include at the top of your main source file.

And to make the function calls shorter, we'll add the following using directives to the previously mentioned namespaces. This way we don't need to specify the namespace whenever we want to call a function from that namespace:

using namespace irr;
using namespace core;
using namespace video;

But you should be aware that using such a using namespace is considered bad practice according to some coding standards. Because exposing all the names from the root namespace can cause some confusions, for example, what if two different namespaces contain a function with the same name? That's why using only the top-level namespace is encouraged and the low-level namespace developers should use the full qualified name. But in this chapter, we'll just use this way to make our code shorter.

Irrlicht device

The Irrlicht device is the core object that we need to interact with the Irrlicht engine. It is created using the device driver of choice such as Direct3D, OpenGL, and so on. Basically, it's an interface to the actual underlying graphics hardware. So, we need to create a device first to be able to draw anything on the screen.

Time for action – creating an Irrlicht device

Creating a device in Irrlicht is as easy as calling a single function. If you have prior experience with graphics APIs such as Direct3D or OpenGL, you will know there's a lot of code involved to set up and create a device. So let's create an Irrlicht device.

  1. Go into your main() function.
  2. Define a variable called device by writing IrrlichtDevice* device.
  3. Create our Irrlicht device by calling:

    createDevice(EDT_OPENGL, dimension<u32>(640, 480), 16, false,
    false, false, 0);

  4. Add the condition if (!device) return 1; immediately after that.
  5. Finally we need to release our device with device->drop();.
  6. #include <irrlicht.h>

    using namespace irr;
    using namespace core;
    using namespace video;

    #if defined(_MSC_VER)
    #pragma comment(lib, "Irrlicht.lib")
    #endif

    int main()
    {
    IrrlichtDevice* device = createDevice(EDT_OPENGL,
    dimension2d<u32>
    (640, 480), 16,
    false, false, false, 0);
    if (!device)
    return 1;

    device->drop();

    return 0;
    }

What just happened?

At the moment, a new window with the specified parameters of createDevice will be created, but will be instantly closed. If there is a problem with the created device, the application will receive the return 1 code.

The Irrlicht device handles everything that has to do with creating and using the window that we need to draw anything on the screen.

The createDevice method

The createDevice has seven parameters. The first one is the renderer that we will be using. Because we want our application to be platform-independent, we are going to use OpenGL, which is available for Windows, Linux, and Mac OS X.

You can also use the DirectX 8 renderer with EDT_DIRECT3D8 or the DirectX 9 renderer with EDT_DIRECT3D9 on Windows. Irrlicht also provides two software renderers that are EDT_ SOFTWARE and EDT_BURNINGSVIDEO. If the first parameter is set to EDT_NULL, there won't be any window created.

The second parameter sets the window size, while the third parameter sets the color depth, which should be set to either 16 bit or 32 bit. If the application is going to be run in windowed mode, this parameter might be ignored and the color depth of the created window will be set to the depth of the desktop.

The fourth parameter determines whether or not the application should run in windowed or fullscreen mode. If the parameter is set to true the application will launch in fullscreen mode. If this is the case the sixth parameter is a boolean flag that can switch vertical synchronization (vsync) on or off.

The fifth parameter specifies whether to use the stencil buffer or not. If we would need to draw shadows, we need to set this parameter to true, but for now, we can leave this to false.

The seventh parameter should be used if we are going to use an event receiver; that does not interest us yet.

The "game loop"

You already know while and for loops, so what's the deal with this alleged "game loop"? In game development, we usually have a scene that needs to be updated in every frame. We would need to check for game logic events, like checking for collisions or if the player has won or lost the game then update the scene accordingly. The Irrlicht 3D graphics engine uses the same approach. Assume your application is like an interactive movie, each frame redraws the complete screen.

Time for action – creating the "game loop"

Let's create our game loop:

  1. The "game loop" is a simple while loop. We will have to redraw each frame as long as the device is running.
  2. Define the variable IVideoDriver* driver and allocate device- >getVideoDriver().
  3. Now jump to the "game loop".
  4. Add driver->beginScene(true, true, SColor(255, 255, 255, 255)); at the beginning of the loop.
  5. Add driver->endScene(); at the end of the loop.
    Your source code should look something like this:

    #include <irrlicht.h>

    using namespace irr;
    using namespace core;
    using namespace video;

    #if defined(_MSC_VER)
    #pragma comment(lib, "Irrlicht.lib")
    #endif

    int main()
    {
    IrrlichtDevice* device = createDevice(EDT_OPENGL,
    dimension2d<u32>
    (640, 480), 16,
    false, false,
    false, 0);
    if (!device)
    return 1;

    IVideoDriver* driver = device->getVideoDriver();

    while (device->run())
    {
    driver->beginScene(true, true, SColor(255, 255, 255,
    255));
    driver->endScene();
    }

    device->drop();

    return 0;
    }

    You should see a blank window created as follows, if it runs successfully:

What just happened?

We just succeeded in creating our first application with Irrlicht that displays a window with a plain white background. To be able to draw within our "game loop", we need to get information about the video driver we are using. To save us some work, by not having to write device->getVideoDriver() each time, we would need something from the video driver; we define a variable that gets an instance from the video driver. You may have noticed the I in front of the type IVideoDriver tells you that this type is an interface. Irrlicht relies heavily on interfaces to be able to use different renderers under a common API.

beginScene

Drawing graphics to the display screen directly, every time, can cause the flickering artifact. To avoid this problem a method called double buffering is widely used. The idea is to use a secondary back buffer before drawing to the actual screen. So the renderer will draw on that back buffer first. Only once the drawing is finished, it'll flip the back buffer with the front buffer. The first parameter of beginScene method specifies if the back buffer should be cleared and set to true by default. The second parameter specifies whether to clear the Z buffer.

The third parameter is the color that will be used to clear the back buffer. The color type consists of four values alpha, red, green, and blue ranging from 0 to 255.

This method has to be called first before any rendering occurs.

endScene

The endScene method flips the screen buffers and draws everything on the screen.

Have a go hero – creating the fade-in/fade-out effect

Now that we have set up our base application with a white background, let's try to integrate a fade-in and fade-out effect into our application. If the background is white, we want to slowly fade to a black background and vice versa. So basically, you'll have to play around with the color values inside your game loop.

You figured it out? Compare it with this approach:

#include <irrlicht.h>

using namespace irr;
using namespace core;
using namespace video;

#if defined(_MSC_VER)
#pragma comment(lib, "Irrlicht.lib")
#endif

int main()
{
IrrlichtDevice *device = createDevice(EDT_OPENGL,
dimension2d<u32>
(640, 480), 16, false,
false, false, 0);

if (!device)
return 1;

IVideoDriver* driver = device->getVideoDriver();

f32 bg_r = 255.0f;
f32 bg_g = 255.0f;
f32 bg_b = 255.0f;

bool fadeOut = true;

int lastFPS = -1;

u32 then = device->getTimer()->getTime();

const f32 fadeRate = 0.1f;

while(device->run())
{
const u32 now = device->getTimer()->getTime();
const f32 frameDeltaTime = (f32)(now - then);
then = now;

if (bg_r <= 0.0f) fadeOut = false;
else if (bg_r >= 255.0f) fadeOut = true;

if (fadeOut)
{
bg_r-= fadeRate * frameDeltaTime;
bg_g-= fadeRate * frameDeltaTime;
bg_b-= fadeRate * frameDeltaTime;
}
else
{
bg_r+= fadeRate * frameDeltaTime;
bg_g+= fadeRate * frameDeltaTime;
bg_b+= fadeRate * frameDeltaTime;
}

driver->beginScene(true, true, SColor(255, (u32)bg_r,
(u32)bg_g, (u32)bg_b));
driver->endScene();
}

device->drop();

return 0;
}

However, the preceding approach contains a new concept that is called frame independent update. Before starting any rendering, we calculate the total time (ticks) difference between each frame, and multiply that with the rate we want to use for fade-in, fade-out. This way we can achieve a smooth transition across different PCs. Otherwise, if you just use a constant value to subtract or add to the color values, your program will fade-in/out very fast on fast computers.

Summary

We set up our development environment and created our first application.

Specifically, we covered:

  • Creating an empty application using different platforms and IDEs
  • Irrlicht namespaces
  • Creating and using a device
  • Introduction of the frame independent update concept

Further resources on this subject:


Irrlicht 1.7 Realtime 3D Engine Beginner's Guide Create complete 2D and 3D applications with this cross-platform, high performance engine with this book and ebook
Published: October 2011
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Aung Sithu Kyaw

Aung Sithu Kyaw is originally from Myanmar, (Burma) and has over seven years of experience in the software industry. His main interests include game-play programming, startups, entrepreneurship, writing, and sharing knowledge. He holds a Master of Science degree from Nanyang Technological University (NTU), Singapore, majoring in Digital Media Technology. Over the past few years, he has worked as a Research Programmer at INSEAD, Sr. Game Programmer at Playware Studios Asia, Singapore, and lastly as a Research Associate at NTU. In 2011, Aung co-founded Rival Edge Pte Ltd., a Singapore-based interactive digital media company that provides a technical consultancy service to creative agencies and also produces social mobile games. Visit http://rivaledge.sg for more information. Aung is the co-author of Irrlicht 1.7 Realtime 3D Engine Beginner's Guide, Packt Publishing, and is also a visiting lecturer at NTU conducting workshops on game design and development using Unity3D.He can be followed on Twitter @aungsithu and by using his LinkedIn profile linkedin.com/in/aungsithu.

Johannes Stein

Johannes Stein has been interested in software and game development for the better half of his life. He has used a variety of technologies, programming languages, and platforms. In the last few years, he worked as a freelancer using web and mobile technologies for a number of different companies and startups, working on several iOS apps and games. Among the technologies he uses are Sparrow, Cocos2D, and UIKit. He co-authored the book Irrlicht 1.7 Realtime 3D Engine Beginner's Guide, which was published in 2011 by Packt Publishing. He can be followed on Twitter @Stoney-FD.

Books From Packt


Unity 3.x Game Development Essentials
Unity 3.x Game Development Essentials

Blender 2.5 HOTSHOT
Blender 2.5 HOTSHOT

iClone 4.31 3D Animation Beginner's Guide
iClone 4.31 3D Animation Beginner's Guide

Unity iOS Essentials
Unity iOS Essentials

Unity 3.x Game Development by Example Beginner's Guide
Unity 3.x Game Development by Example Beginner's Guide

OpenGL 4.0 Shading Language Cookbook book and eBook
OpenGL 4.0 Shading Language Cookbook book and eBook

Away3D 3.6 Essentials
Away3D 3.6 Essentials

Blender 2.5 Materials and Textures Cookbook
Blender 2.5 Materials and Textures Cookbook


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
R
r
m
i
t
G
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software