forked from Mirrorlandia_minetest/irrlicht
226 lines
12 KiB
HTML
226 lines
12 KiB
HTML
|
<html>
|
||
|
<head>
|
||
|
<title>Irrlicht Engine Tutorial</title>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||
|
</head>
|
||
|
|
||
|
<body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0">
|
||
|
<br>
|
||
|
<table width="95%" border="0" cellspacing="0" cellpadding="2" align="center">
|
||
|
<tr>
|
||
|
<td bgcolor="#666699" width="10"><b><a href="http://irrlicht.sourceforge.net" target="_blank"><img src="../../media/irrlichtlogo.jpg" width="88" height="31" border="0"></a></b></td>
|
||
|
<td bgcolor="#666699" width="100%">
|
||
|
<div align="center">
|
||
|
<div align="center"></div>
|
||
|
<div align="left"><b><font color="#FFFFFF">Tutorial 5.User Interface</font></b></div>
|
||
|
</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr bgcolor="#eeeeff">
|
||
|
<td height="90" colspan="2">
|
||
|
<div align="left">
|
||
|
<p>This tutorial shows how to use the built in User Interface of the Irrlicht
|
||
|
Engine. It will give a brief overview and show how to create and use
|
||
|
windows, buttons, scroll bars, static texts and list boxes. </p>
|
||
|
<p>The program which is described here will look like this:</p>
|
||
|
<p align="center"><img src="../../media/005shot.jpg" width="259" height="204"><br>
|
||
|
</p>
|
||
|
</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<br>
|
||
|
<table width="95%" border="0" cellspacing="0" cellpadding="2" align="center">
|
||
|
<tr>
|
||
|
<td bgcolor="#666699"> <div align="center"><b><font color="#FFFFFF"></font></b></div>
|
||
|
<b><font color="#FFFFFF">Lets start!</font></b></td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td height="90" bgcolor="#eeeeff" valign="top"> <div align="left">
|
||
|
<p>As always, we include the header files (conio and curses for getting
|
||
|
user input from the console), and use the irrlicht namespaces. We also
|
||
|
store a pointer to the Irrlicht device, a counter variable for changing
|
||
|
the creation position of a window, and a pointer to a listbox.</p>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td> <pre>#include <irrlicht.h>
|
||
|
#include <iostream><br>
|
||
|
using namespace irr;</pre>
|
||
|
<pre>using namespace core;
|
||
|
using namespace scene;
|
||
|
using namespace video;
|
||
|
using namespace io;
|
||
|
using namespace gui;</pre>
|
||
|
<pre>#pragma comment(lib, "Irrlicht.lib")</pre>
|
||
|
<pre>IrrlichtDevice *device = 0;
|
||
|
s32 cnt = 0;
|
||
|
IGUIListBox* listbox = 0;
|
||
|
</pre></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p>The Event Receiver is not only capable of getting keyboard and mouse
|
||
|
input events, but also events of the graphical user interface (gui).
|
||
|
There are events for almost everything: Button click, Listbox selection
|
||
|
change, events that say that a element was hovered and so on. To be
|
||
|
able to react to some of these events, we create <br>
|
||
|
an event receiver. We only react to gui events, and if it's such an
|
||
|
event, we get the id of the caller (the gui element which caused the
|
||
|
event) and get the pointer to the gui environment. </p>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td> <pre>class MyEventReceiver : public IEventReceiver<br>{<br>public:<br> virtual bool OnEvent(const SEvent& event)<br> {<br> if (event.EventType == EET_GUI_EVENT)<br> {<br> s32 id = event.GUIEvent.Caller->getID();<br> IGUIEnvironment* env = device->getGUIEnvironment();</pre>
|
||
|
<pre> switch(event.GUIEvent.EventType)
|
||
|
{</pre>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p> If a scrollbar changed its scroll position, and it is 'our' scrollbar
|
||
|
(the one with id 104), then we change the <br>
|
||
|
transparency of all gui elements. This is a very easy task: There is
|
||
|
a skin object, in which all color settings are stored. We simply go
|
||
|
through all colors stored in the skin and change their alpha value.
|
||
|
</p>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td height="80"> <pre>case EGET_SCROLL_BAR_CHANGED:<br> if (id == 104)<br> {<br> s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();<br> <br> for (s32 i=0; i<EGDC_COUNT ; ++i)<br> {<br> SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);<br> col.setAlpha(pos);<br> env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);<br> }<br> }<br>break;</pre></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p>If a button was clicked, it could be one of 'our' three buttons. If
|
||
|
it is the first, we shut down the engine.<br>
|
||
|
If it is the second, we create a little window with some text on it.
|
||
|
We also add a string to the list box to log<br>
|
||
|
what happened. And if it is the third button, we create a file open
|
||
|
dialog, and add also this as string to the list box.<br>
|
||
|
That's all for the event receiver.</p>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td>
|
||
|
<pre> case EGET_BUTTON_CLICKED:
|
||
|
if (id == 101)
|
||
|
{
|
||
|
device->closeDevice();
|
||
|
return true;
|
||
|
}</pre>
|
||
|
<pre> if (id == 102)
|
||
|
{
|
||
|
listbox->addItem(L"Window created");
|
||
|
cnt += 30;
|
||
|
if (cnt > 200)
|
||
|
cnt = 0;</pre>
|
||
|
<pre> IGUIWindow* window = env->addWindow(
|
||
|
rect<s32>(100 + cnt, 100 + cnt, 300 + cnt, 200 + cnt), <br> false, // modal?
|
||
|
L"Test window");</pre>
|
||
|
<pre> env->addStaticText(L"Please close me",
|
||
|
rect<s32>(35,35,140,50),
|
||
|
true, // border?,
|
||
|
false, // wordwrap?
|
||
|
window);
|
||
|
|
||
|
return true;
|
||
|
}</pre>
|
||
|
<pre> if (id == 103)
|
||
|
{
|
||
|
listbox->addItem(L"File open");
|
||
|
env->addFileOpenDialog(L"Please choose a file.");
|
||
|
return true;
|
||
|
}</pre>
|
||
|
<pre> break;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
};</pre>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p>Ok, now for the more interesting part. First, create the Irrlicht device.
|
||
|
As in some examples before, we ask the user which driver he wants to
|
||
|
use for this example:</p>
|
||
|
</div>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td> <pre>int main()
|
||
|
{
|
||
|
// ask user for driver
|
||
|
video::E_DRIVER_TYPE driverType;
|
||
|
|
||
|
|
||
|
printf("Please select the driver you want for this example:\n"\<br> " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\<br> " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\<br> " (f) NullDevice\n (otherKey) exit\n\n");<br><br> char i;<br> std::cin >> i;<br>
|
||
|
switch(i)<br> {<br> case 'a': driverType = video::EDT_DIRECT3D9;break;<br> case 'b': driverType = video::EDT_DIRECT3D8;break;<br> case 'c': driverType = video::EDT_OPENGL; break;<br> case 'd': driverType = video::EDT_SOFTWARE; break;<br> case 'e': driverType = video::EDT_BURNINGSVIDEO;break;<br> case 'f': driverType = video::EDT_NULL; break;<br> default: return 1;<br> }
|
||
|
|
||
|
// create device and exit if creation failed
|
||
|
device = createDevice(driverType, core::dimension2d<s32>(640, 480));<br>
|
||
|
if (device == 0)
|
||
|
return 1;
|
||
|
</pre>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p>The creation was successful, now we set the event receiver and store
|
||
|
pointers to the driver and to the gui environment. </p>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td><pre>MyEventReceiver receiver;
|
||
|
device->setEventReceiver(&receiver);
|
||
|
device->setWindowCaption(L"Irrlicht Engine - User Inferface Demo");</pre>
|
||
|
<pre>video::IVideoDriver* driver = device->getVideoDriver();
|
||
|
IGUIEnvironment* env = device->getGUIEnvironment();
|
||
|
</pre>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p>We add three buttons. The first one closes the engine. The second creates
|
||
|
a window and the third opens a file open dialog. The third parameter is
|
||
|
the id of the button, with which we can easily identify the button in
|
||
|
the event receiver.</p>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td><pre>env->addButton(rect<s32>(10,240,100,270), 0, 101, L"Quit");<br>env->addButton(rect<s32>(10,280,100,320), 0, 102, L"New Window");<br>env->addButton(rect<s32>(10,330,100,370), 0, 103, L"File Open");</pre></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p> Now, we add a static text and a scrollbar, which modifies the transparency
|
||
|
of all gui elements. We set the maximum value of the scrollbar to 255,
|
||
|
because that's the maximal value for a color value.<br>
|
||
|
Then we create an other static text and a list box.</p>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td><pre>env->addStaticText(L"Transparent Control:", rect<s32>(150,20,350,40), true);<br>IGUIScrollBar* scrollbar = env->addScrollBar(true,
|
||
|
rect<s32>(150, 45, 350, 60), 0, 104);<br>scrollbar->setMax(255);</pre>
|
||
|
<pre>env->addStaticText(L"Logging ListBox:", rect<s32>(50,110,250,130), true);
|
||
|
listbox = env->addListBox(rect<s32>(50, 140, 250, 210));</pre></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<br>
|
||
|
To make the font a little bit nicer, we load an external font and set it
|
||
|
as new font in the skin. An at last, we create a nice Irrlicht Engine logo
|
||
|
in the top left corner. <br>
|
||
|
<br>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td> <pre>IGUISkin* skin = env->getSkin();<br>IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");<br>if (font)<br> skin->setFont(font);</pre>
|
||
|
<pre>IGUIImage* img = env->addImage(<br> driver->getTexture("../../media/irrlichtlogoalpha.tga"),<br> position2d<int>(10,10));</pre></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p>That's all, we only have to draw everything.</p>
|
||
|
<table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center">
|
||
|
<tr>
|
||
|
<td>
|
||
|
<pre> while(device->run() && driver)<br> if (device->isWindowActive()) <br> {<br> driver->beginScene(true, true, SColor(0,122,65,171));
|
||
|
env->drawAll();
|
||
|
driver->endScene();
|
||
|
}
|
||
|
|
||
|
device->drop();</pre>
|
||
|
<pre> return 0;
|
||
|
}</pre>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
|
||
|
</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
<p> </p>
|
||
|
</body>
|
||
|
</html>
|