Irrlicht之05.UserInterface
这个例子告诉我们如何为Irr引擎创建一个用户图形界面。
/*
这个例子告诉我们如何为Irr引擎创建一个用户图形界面。
它将告诉我们如何去创建一个窗口,按钮,滚动条,静态字体和列表框。
象以往一样,包含头文件,说明命名空间,链接库。
我们全局变量中保存一个Irr设备指针,一个变量(用来存储新创建的窗口坐标数值)
一个ListBox的指针。
*/
#include <irrlicht.h>
#include <iostream>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
IrrlichtDevice *device = 0;
s32 cnt = 0;
IGUIListBox* listbox = 0;
/*
事件接收器不仅仅接受键盘和鼠标的输入消息,也处理GUI事件消息。
例如:按钮按下消息,列表选择消息等等。为了处理这些GUI消息,
我们在这里创建了一个事件接收器。
假如我们接收到一个GUI事件,我们先从中获得GUI控件的ID,
再获取GUI环境的指针,就可以进行处理了。
具体代码如下:
*/
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)
{
/*
如果一个滚动条移动了其位置,我们先判断此滚动条是否我们创建的,
if(id == 104),若是的话,则我们改变GUI环境的透明度。
改变GUI环境透明度实际上很容易做到:GUI环境有一个皮肤对象,
这个对象管理着所有的GUI环境的颜色设置,我们简单的遍历了皮肤
里的所有颜色,并改变他们的Alpha值。
注:控件的ID在创建时会需要传入。
*/
case EGET_SCROLL_BAR_CHANGED:
if (id == 104)
{
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
for (u32 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到底是哪个按钮。
若是ID为101的按纽,我们就关闭引擎。
若是ID为102的按钮,我们就创建一个小窗口,并且在ListBox中添加一行文字,
同时在窗口上加一个静态Label.
若是ID为103的按钮,我们就创建一个打开的文件对话框。
同时在ListBox中添加一行文字。
注:控件的ID在创建时会需要传入。
*/
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, //是否粗体字
false, // wordwrap?
window);
return true;
}
if (id == 103)
{
listbox->addItem(L"File open");
env->addFileOpenDialog(L"Please choose a file.");
return true;
}
break;
default:
break;
}
}
return false;
}
};
/*
好了,现在开始另外一块有意思的部分。
*/
int main()
{
// 让用户选择设备类型
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) Burning's 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_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
device = createDevice(driverType, core::dimension2d<s32>(640, 480));
if (device == 0)
return 1;
/*
Irr设备创建完了,现在我们设置事件处理器。同时保存下设备的GUI环境指针。
*/
MyEventReceiver receiver;
device->setEventReceiver(&receiver);
device->setWindowCaption(L"Irrlicht Engine - User Interface Demo");
video::IVideoDriver* driver = device->getVideoDriver();
IGUIEnvironment* env = device->getGUIEnvironment();
/*
为了使字体看起来更好看一些,我们读取一个外部的字体库,
并且将其设置为GUI环境皮肤的默认字体。
但是为了按钮看起来与众不同,所以我们将按钮上的文字特殊化,
使按钮上的文字依旧使用内嵌的标准字体。
*/
IGUISkin* skin = env->getSkin();
IGUIFont* font = env->getFont("../../media/fontcourier.bmp");
if (font)
skin->setFont(font);
skin->setFont(env->getBuiltInFont(), EGDF_BUTTON);
/*
我们增加三个按钮,第一个用来关闭引擎,第二个用来创建一个窗口,第三个用来打
开一个文件对话框。在这里设置Button的ID以便事件处理器的判别处理。
*/
env->addButton(rect<s32>(10,210,110,210 + 32), 0, 101, L"Quit", L"Exits Program");
env->addButton(rect<s32>(10,250,110,250 + 32), 0, 102, L"New Window", L"Launches a new Window");
env->addButton(rect<s32>(10,290,110,290 + 32), 0, 103, L"File Open", L"Opens a file");
/*
现在,我们增加一个静态文字Label个一个滚动条,用它来修改GUI环境的透明度。
我们设置好滚动条的最大值为255(最大色深值),之后我们再创建一个ListBox
*/
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);
// 设置滚动条位置
scrollbar->setPos(env->getSkin()->getColor(EGDC_WINDOW).getAlpha());
env->addStaticText(L"Logging ListBox:", rect<s32>(50,80,250,100), true);
listbox = env->addListBox(rect<s32>(50, 110, 250, 180));
env->addEditBox(L"Editable Text", rect<s32>(350, 80, 550, 100));
// 增加一个Irr引擎Logo
env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
position2d<int>(10,10));
/*
全部设置OK了,现在我们来进行绘制
*/
while(device->run() && driver)
if (device->isWindowActive())
{
driver->beginScene(true, true, SColor(0,200,200,200));
env->drawAll();
driver->endScene();
}
device->drop();
return 0;
}