一如往常,我们包含需要的头文件 (conio and curses for getting user input from the console), 和使用IrrLicht的命名空间。还有保存一个指向IrrLicht设备的指针,一个用于改变窗口坐标的计数变量,和一个列表框指针。
#include <irrlicht.h>
#include <iostream>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
IrrlichtDevice *device = 0;
s32 cnt = 0;
IGUIListBox* listbox = 0;
|
事件接收器不但可以接收键盘和鼠标的输入事件,还可以接收图形用户界面(gui)的事件。图形用户界面的事件包括:按钮点击,列表框的改变,组件的激活等。可以创建事件接收器响应这些事件。我们只处理对应id的gui事件和获取一个指向IGUIEnvironment的指针。
class MyEventReceiver : public IEventReceiver { public: virtual bool OnEvent(SEvent event) { if (event.EventType == EET_GUI_EVENT) { s32 id = event.GUIEvent.Caller->getID(); IGUIEnvironment* env = device->getGUIEnvironment();
switch(event.GUIEvent.EventType)
{
|
如果指定滚动栏(gui元id为104)的光标位置移动了,则改变全部gui元的透明度。这是一个十分简单的任务:把皮肤对象的各种颜色设置逐一记录到SColor对象,并用SColor对象的setAlpha()方法设置Alpha值,把皮肤的颜色设置设成修改后的SColor。
case EGET_SCROLL_BAR_CHANGED: if (id == 104) { s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos(); for (s32 i=0; i<EGDC_COUNT ; ++i) { SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i); col.setAlpha(pos); env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col); } } break;
|
如果点击按钮,是我们创建的三个按钮之一。如果是第一个(id为101)点击,则关闭引擎。 如果是第二个(id为102)点击,则创建一个带文本的小窗口。并在列表框中添加一个事件的记录。 如果是第三个(id为103)点击,则创建一个文件打开对话框,并在列表框中添加一个事件的记录。 下面是事件接收器的代码。
case EGET_BUTTON_CLICKED:
if (id == 101)
{
device->closeDevice();
return true;
}
if (id == 102)
{
listbox->addItem(L"Window created");
cnt += 30;
if (cnt > 200)
cnt = 0;
IGUIWindow* window = env->addWindow(
rect<s32>(100 + cnt, 100 + cnt, 300 + cnt, 200 + cnt), false, // modal?
L"Test window");
env->addStaticText(L"Please close me",
rect<s32>(35,35,140,50),
true, // border?,
false, // wordwrap?
window);
return true;
}
if (id == 103)
{
listbox->addItem(L"File open");
env->addFileOpenDialog(L"Please choose a file.");
return true;
}
break;
}
}
return false;
}
};
|
很好,接收是更有趣的部份。首先创建一个根据用户选定图形驱动的IrrLicht设备:
int main()
{
// ask user for driver
video::E_DRIVER_TYPE driverType;
printf("Please select the driver you want for this example:\n"\ " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\ " (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\ " (f) NullDevice\n (otherKey) exit\n\n");
char i; std::cin >> i;
switch(i) { case 'a': driverType = video::EDT_DIRECT3D9;break; case 'b': driverType = video::EDT_DIRECT3D8;break; case 'c': driverType = video::EDT_OPENGL; break; case 'd': driverType = video::EDT_SOFTWARE; break; case 'e': driverType = video::EDT_SOFTWARE2;break; case 'f': driverType = video::EDT_NULL; break; default: return 1; }
// create device and exit if creation failed
device = createDevice(driverType, core::dimension2d<s32>(640, 480));
if (device == 0)
return 1;
|
创建成功后,接着设置事件接收器并保存视频驱动(IVideoDriver)和图形用户界面环境(IGUIEnvironment)指针。
MyEventReceiver receiver;
device->setEventReceiver(&receiver);
device->setWindowCaption(L"Irrlicht Engine - User Inferface Demo");
video::IVideoDriver* driver = device->getVideoDriver();
IGUIEnvironment* env = device->getGUIEnvironment();
|
添加三个按钮。第一个是关闭引擎。第二个是创建一个窗口,第三个是创建一个文件打开对话框。第三个参数是设置创建按钮的id,通过这个值,我们可以容易地在事件接收器中识别各个按钮。
env->addButton(rect<s32>(10,210,100,240), 0, 101, L"Quit"); env->addButton(rect<s32>(10,250,100,290), 0, 102, L"New Window"); env->addButton(rect<s32>(10,300,100,340), 0, 103, L"File Open");
|
接着,我们添加一个静态文本框和一个修改全部gui元透明值的滚动栏。并设置滚动栏的最大值为255,因为这是颜色值支持的最大值。 并创建静态文本框和列表框。
env->addStaticText(L"Transparent Control:", rect<s32>(150,20,350,40), true); IGUIScrollBar* scrollbar = env->addScrollBar(true,
rect<s32>(150, 45, 350, 60), 0, 104); scrollbar->setMax(255);
env->addStaticText(L"Logging ListBox:", rect<s32>(50,80,250,100), true);
listbox = env->addListBox(rect<s32>(50, 110, 250, 180));
|
为了使字体更美观,我们在皮肤中加载并设置一种外部的字体。最后,我们在左上角放上一个漂亮的IrrLicht引擎标志。
IGUISkin* skin = env->getSkin(); IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp"); if (font) skin->setFont(font);
IGUIImage* img = env->addImage( driver->getTexture("../../media/irrlichtlogoalpha.tga"), position2d<int>(10,10));
|
就这样,现在只需把所有都绘制出来。
while(device->run() && driver) if (device->isWindowActive()) { driver->beginScene(true, true, SColor(0,122,65,171));
env->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
|
|