mirror of
https://github.com/minetest/irrlicht.git
synced 2024-11-14 06:20:26 +01:00
1044 lines
78 KiB
HTML
1044 lines
78 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||
|
<title>Irrlicht 3D Engine: Tutorial 9: Mesh Viewer</title>
|
||
|
|
||
|
<link href="tabs.css" rel="stylesheet" type="text/css"/>
|
||
|
<link href="doxygen.css" rel="stylesheet" type="text/css" />
|
||
|
<link href="navtree.css" rel="stylesheet" type="text/css"/>
|
||
|
<script type="text/javascript" src="jquery.js"></script>
|
||
|
<script type="text/javascript" src="resize.js"></script>
|
||
|
<script type="text/javascript" src="navtree.js"></script>
|
||
|
<script type="text/javascript">
|
||
|
$(document).ready(initResizable);
|
||
|
</script>
|
||
|
<link href="search/search.css" rel="stylesheet" type="text/css"/>
|
||
|
<script type="text/javascript" src="search/search.js"></script>
|
||
|
<script type="text/javascript">
|
||
|
$(document).ready(function() { searchBox.OnSelectItem(0); });
|
||
|
</script>
|
||
|
|
||
|
</head>
|
||
|
<body>
|
||
|
<div id="top"><!-- do not remove this div! -->
|
||
|
|
||
|
|
||
|
<div id="titlearea">
|
||
|
<table cellspacing="0" cellpadding="0">
|
||
|
<tbody>
|
||
|
<tr style="height: 56px;">
|
||
|
|
||
|
<td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td>
|
||
|
|
||
|
|
||
|
<td style="padding-left: 0.5em;">
|
||
|
<div id="projectname">Irrlicht 3D Engine
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</td>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
<td> <div id="MSearchBox" class="MSearchBoxInactive">
|
||
|
<span class="left">
|
||
|
<img id="MSearchSelect" src="search/mag_sel.png"
|
||
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
||
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
||
|
alt=""/>
|
||
|
<input type="text" id="MSearchField" value="Search" accesskey="S"
|
||
|
onfocus="searchBox.OnSearchFieldFocus(true)"
|
||
|
onblur="searchBox.OnSearchFieldFocus(false)"
|
||
|
onkeyup="searchBox.OnSearchFieldChange(event)"/>
|
||
|
</span><span class="right">
|
||
|
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
|
||
|
</span>
|
||
|
</div>
|
||
|
</td>
|
||
|
|
||
|
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</div>
|
||
|
|
||
|
<!-- Generated by Doxygen 1.7.5.1 -->
|
||
|
<script type="text/javascript">
|
||
|
var searchBox = new SearchBox("searchBox", "search",false,'Search');
|
||
|
</script>
|
||
|
<script type="text/javascript" src="dynsections.js"></script>
|
||
|
</div>
|
||
|
<div id="side-nav" class="ui-resizable side-nav-resizable">
|
||
|
<div id="nav-tree">
|
||
|
<div id="nav-tree-contents">
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="splitbar" style="-moz-user-select:none;"
|
||
|
class="ui-resizable-handle">
|
||
|
</div>
|
||
|
</div>
|
||
|
<script type="text/javascript">
|
||
|
initNavTree('example009.html','');
|
||
|
</script>
|
||
|
<div id="doc-content">
|
||
|
<div class="header">
|
||
|
<div class="headertitle">
|
||
|
<div class="title">Tutorial 9: Mesh Viewer </div> </div>
|
||
|
</div>
|
||
|
<div class="contents">
|
||
|
<div class="textblock"><div class="image">
|
||
|
<img src="009shot.jpg" alt="009shot.jpg"/>
|
||
|
</div>
|
||
|
<p>This tutorial show how to create a more complex application with the engine. We construct a simple mesh viewer using the user interface API and the scene management of Irrlicht. The tutorial show how to create and use Buttons, Windows, Toolbars, Menus, ComboBoxes, Tabcontrols, Editboxes, Images, MessageBoxes, SkyBoxes, and how to parse XML files with the integrated XML reader of the engine.</p>
|
||
|
<p>We start like in most other tutorials: Include all necessary header files, add a comment to let the engine be linked with the right .lib file in Visual Studio, and declare some global variables. We also add two 'using namespace' statements, so we do not need to write the whole names of all classes. In this tutorial, we use a lot stuff from the gui namespace. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="preprocessor">#include <<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>></span>
|
||
|
<span class="preprocessor">#include "<a class="code" href="driver_choice_8h.html">driverChoice.h</a>"</span>
|
||
|
|
||
|
<span class="keyword">using namespace </span>irr;
|
||
|
<span class="keyword">using namespace </span>gui;
|
||
|
|
||
|
<span class="preprocessor">#ifdef _MSC_VER</span>
|
||
|
<span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, "Irrlicht.lib")</span>
|
||
|
<span class="preprocessor">#endif</span>
|
||
|
</pre></div><p>Some global variables used later on </p>
|
||
|
<div class="fragment"><pre class="fragment">IrrlichtDevice *Device = 0;
|
||
|
<a class="code" href="namespaceirr_1_1core.html#ade1071a878633f2f6d8a75c5d11fec19" title="Typedef for character strings.">core::stringc</a> StartUpModelFile;
|
||
|
<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> MessageText;
|
||
|
<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> Caption;
|
||
|
scene::ISceneNode* Model = 0;
|
||
|
scene::ISceneNode* SkyBox = 0;
|
||
|
<span class="keywordtype">bool</span> Octree=<span class="keyword">false</span>;
|
||
|
<span class="keywordtype">bool</span> UseLight=<span class="keyword">false</span>;
|
||
|
|
||
|
scene::ICameraSceneNode* Camera[2] = {0, 0};
|
||
|
|
||
|
<span class="comment">// Values used to identify individual GUI elements</span>
|
||
|
<span class="keyword">enum</span>
|
||
|
{
|
||
|
GUI_ID_DIALOG_ROOT_WINDOW = 0x10000,
|
||
|
|
||
|
GUI_ID_X_SCALE,
|
||
|
GUI_ID_Y_SCALE,
|
||
|
GUI_ID_Z_SCALE,
|
||
|
|
||
|
GUI_ID_OPEN_MODEL,
|
||
|
GUI_ID_SET_MODEL_ARCHIVE,
|
||
|
GUI_ID_LOAD_AS_OCTREE,
|
||
|
|
||
|
GUI_ID_SKY_BOX_VISIBLE,
|
||
|
GUI_ID_TOGGLE_DEBUG_INFO,
|
||
|
|
||
|
GUI_ID_DEBUG_OFF,
|
||
|
GUI_ID_DEBUG_BOUNDING_BOX,
|
||
|
GUI_ID_DEBUG_NORMALS,
|
||
|
GUI_ID_DEBUG_SKELETON,
|
||
|
GUI_ID_DEBUG_WIRE_OVERLAY,
|
||
|
GUI_ID_DEBUG_HALF_TRANSPARENT,
|
||
|
GUI_ID_DEBUG_BUFFERS_BOUNDING_BOXES,
|
||
|
GUI_ID_DEBUG_ALL,
|
||
|
|
||
|
GUI_ID_MODEL_MATERIAL_SOLID,
|
||
|
GUI_ID_MODEL_MATERIAL_TRANSPARENT,
|
||
|
GUI_ID_MODEL_MATERIAL_REFLECTION,
|
||
|
|
||
|
GUI_ID_CAMERA_MAYA,
|
||
|
GUI_ID_CAMERA_FIRST_PERSON,
|
||
|
|
||
|
GUI_ID_POSITION_TEXT,
|
||
|
|
||
|
GUI_ID_ABOUT,
|
||
|
GUI_ID_QUIT,
|
||
|
|
||
|
GUI_ID_TEXTUREFILTER,
|
||
|
GUI_ID_SKIN_TRANSPARENCY,
|
||
|
GUI_ID_SKIN_ANIMATION_FPS,
|
||
|
|
||
|
GUI_ID_BUTTON_SET_SCALE,
|
||
|
GUI_ID_BUTTON_SCALE_MUL10,
|
||
|
GUI_ID_BUTTON_SCALE_DIV10,
|
||
|
GUI_ID_BUTTON_OPEN_MODEL,
|
||
|
GUI_ID_BUTTON_SHOW_ABOUT,
|
||
|
GUI_ID_BUTTON_SHOW_TOOLBOX,
|
||
|
GUI_ID_BUTTON_SELECT_ARCHIVE,
|
||
|
|
||
|
GUI_ID_ANIMATION_INFO,
|
||
|
|
||
|
<span class="comment">// And some magic numbers</span>
|
||
|
MAX_FRAMERATE = 80,
|
||
|
DEFAULT_FRAMERATE = 30
|
||
|
};
|
||
|
</pre></div><p>Toggle between various cameras </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> setActiveCamera(scene::ICameraSceneNode* newActive)
|
||
|
{
|
||
|
<span class="keywordflow">if</span> (0 == Device)
|
||
|
<span class="keywordflow">return</span>;
|
||
|
|
||
|
scene::ICameraSceneNode * active = Device->getSceneManager()->getActiveCamera();
|
||
|
active->setInputReceiverEnabled(<span class="keyword">false</span>);
|
||
|
|
||
|
newActive->setInputReceiverEnabled(<span class="keyword">true</span>);
|
||
|
Device->getSceneManager()->setActiveCamera(newActive);
|
||
|
}
|
||
|
</pre></div><p>Set the skin transparency by changing the alpha values of all skin-colors </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> setSkinTransparency(<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> alpha, <a class="code" href="classirr_1_1gui_1_1_i_g_u_i_skin.html" title="A skin modifies the look of the GUI elements.">irr::gui::IGUISkin</a> * skin)
|
||
|
{
|
||
|
<span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> i=0; i<<a class="code" href="namespaceirr_1_1gui.html#abd15860fde29833c48daff5f95d5467aaf340f49e2e0827c0f06fdf65098554af">irr::gui::EGDC_COUNT</a> ; ++i)
|
||
|
{
|
||
|
video::SColor col = skin-><a class="code" href="classirr_1_1gui_1_1_i_g_u_i_skin.html#ad1afa2e5e34c30e0cbfb85b1dee2dbe3" title="returns default color">getColor</a>((<a class="code" href="namespaceirr_1_1gui.html#abd15860fde29833c48daff5f95d5467a" title="Enumeration for skin colors.">EGUI_DEFAULT_COLOR</a>)i);
|
||
|
col.setAlpha(alpha);
|
||
|
skin-><a class="code" href="classirr_1_1gui_1_1_i_g_u_i_skin.html#ab9782296ba881872207a0915a81d7807" title="sets a default color">setColor</a>((<a class="code" href="namespaceirr_1_1gui.html#abd15860fde29833c48daff5f95d5467a" title="Enumeration for skin colors.">EGUI_DEFAULT_COLOR</a>)i, col);
|
||
|
}
|
||
|
}
|
||
|
</pre></div><p>Update the display of the model scaling </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> updateScaleInfo(scene::ISceneNode* model)
|
||
|
{
|
||
|
IGUIElement* toolboxWnd = Device->getGUIEnvironment()->getRootGUIElement()->getElementFromId(GUI_ID_DIALOG_ROOT_WINDOW, <span class="keyword">true</span>);
|
||
|
<span class="keywordflow">if</span> (!toolboxWnd)
|
||
|
<span class="keywordflow">return</span>;
|
||
|
<span class="keywordflow">if</span> (!model)
|
||
|
{
|
||
|
toolboxWnd->getElementFromId(GUI_ID_X_SCALE, <span class="keyword">true</span>)->setText( L<span class="stringliteral">"-"</span> );
|
||
|
toolboxWnd->getElementFromId(GUI_ID_Y_SCALE, <span class="keyword">true</span>)->setText( L<span class="stringliteral">"-"</span> );
|
||
|
toolboxWnd->getElementFromId(GUI_ID_Z_SCALE, <span class="keyword">true</span>)->setText( L<span class="stringliteral">"-"</span> );
|
||
|
}
|
||
|
<span class="keywordflow">else</span>
|
||
|
{
|
||
|
<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a> scale = model->getScale();
|
||
|
toolboxWnd->getElementFromId(GUI_ID_X_SCALE, <span class="keyword">true</span>)->setText( <a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(scale.X).c_str() );
|
||
|
toolboxWnd->getElementFromId(GUI_ID_Y_SCALE, <span class="keyword">true</span>)->setText( <a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(scale.Y).c_str() );
|
||
|
toolboxWnd->getElementFromId(GUI_ID_Z_SCALE, <span class="keyword">true</span>)->setText( <a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(scale.Z).c_str() );
|
||
|
}
|
||
|
}
|
||
|
</pre></div><p>Function showAboutText() displays a messagebox with a caption and a message text. The texts will be stored in the MessageText and Caption variables at startup. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> showAboutText()
|
||
|
{
|
||
|
<span class="comment">// create modal message box with the text</span>
|
||
|
<span class="comment">// loaded from the xml file.</span>
|
||
|
Device->getGUIEnvironment()->addMessageBox(
|
||
|
Caption.c_str(), MessageText.c_str());
|
||
|
}
|
||
|
</pre></div><p>Function loadModel() loads a model and displays it using an addAnimatedMeshSceneNode and the scene manager. Nothing difficult. It also displays a short message box, if the model could not be loaded. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> loadModel(<span class="keyword">const</span> <a class="code" href="namespaceirr.html#a9395eaea339bcb546b319e9c96bf7410" title="8 bit character variable.">c8</a>* fn)
|
||
|
{
|
||
|
<span class="comment">// modify the name if it a .pk3 file</span>
|
||
|
|
||
|
<a class="code" href="namespaceirr_1_1io.html#ab1bdc45edb3f94d8319c02bc0f840ee1" title="Type used for all file system related strings.">io::path</a> filename(fn);
|
||
|
|
||
|
<a class="code" href="namespaceirr_1_1io.html#ab1bdc45edb3f94d8319c02bc0f840ee1" title="Type used for all file system related strings.">io::path</a> extension;
|
||
|
<a class="code" href="namespaceirr_1_1core.html#abebbe8b229dc865ebeb9bb0fd367d6ea" title="get the filename extension from a file path">core::getFileNameExtension</a>(extension, filename);
|
||
|
extension.make_lower();
|
||
|
|
||
|
<span class="comment">// if a texture is loaded apply it to the current model..</span>
|
||
|
<span class="keywordflow">if</span> (extension == <span class="stringliteral">".jpg"</span> || extension == <span class="stringliteral">".pcx"</span> ||
|
||
|
extension == <span class="stringliteral">".png"</span> || extension == <span class="stringliteral">".ppm"</span> ||
|
||
|
extension == <span class="stringliteral">".pgm"</span> || extension == <span class="stringliteral">".pbm"</span> ||
|
||
|
extension == <span class="stringliteral">".psd"</span> || extension == <span class="stringliteral">".tga"</span> ||
|
||
|
extension == <span class="stringliteral">".bmp"</span> || extension == <span class="stringliteral">".wal"</span> ||
|
||
|
extension == <span class="stringliteral">".rgb"</span> || extension == <span class="stringliteral">".rgba"</span>)
|
||
|
{
|
||
|
video::ITexture * texture =
|
||
|
Device->getVideoDriver()->getTexture( filename );
|
||
|
<span class="keywordflow">if</span> ( texture && Model )
|
||
|
{
|
||
|
<span class="comment">// always reload texture</span>
|
||
|
Device->getVideoDriver()->removeTexture(texture);
|
||
|
texture = Device->getVideoDriver()->getTexture( filename );
|
||
|
|
||
|
Model->setMaterialTexture(0, texture);
|
||
|
}
|
||
|
<span class="keywordflow">return</span>;
|
||
|
}
|
||
|
<span class="comment">// if a archive is loaded add it to the FileArchive..</span>
|
||
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (extension == <span class="stringliteral">".pk3"</span> || extension == <span class="stringliteral">".zip"</span> || extension == <span class="stringliteral">".pak"</span> || extension == <span class="stringliteral">".npk"</span>)
|
||
|
{
|
||
|
Device->getFileSystem()->addFileArchive(filename.c_str());
|
||
|
<span class="keywordflow">return</span>;
|
||
|
}
|
||
|
|
||
|
<span class="comment">// load a model into the engine</span>
|
||
|
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->remove();
|
||
|
|
||
|
Model = 0;
|
||
|
|
||
|
<span class="keywordflow">if</span> (extension==<span class="stringliteral">".irr"</span>)
|
||
|
{
|
||
|
core::array<scene::ISceneNode*> outNodes;
|
||
|
Device->getSceneManager()->loadScene(filename);
|
||
|
Device->getSceneManager()->getSceneNodesFromType(<a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda073d7fe9dfd49f24cb13bfae56d8d3b6" title="Animated Mesh Scene Node.">scene::ESNT_ANIMATED_MESH</a>, outNodes);
|
||
|
<span class="keywordflow">if</span> (outNodes.size())
|
||
|
Model = outNodes[0];
|
||
|
<span class="keywordflow">return</span>;
|
||
|
}
|
||
|
|
||
|
scene::IAnimatedMesh* m = Device->getSceneManager()->getMesh( filename.c_str() );
|
||
|
|
||
|
<span class="keywordflow">if</span> (!m)
|
||
|
{
|
||
|
<span class="comment">// model could not be loaded</span>
|
||
|
|
||
|
<span class="keywordflow">if</span> (StartUpModelFile != filename)
|
||
|
Device->getGUIEnvironment()->addMessageBox(
|
||
|
Caption.c_str(), L<span class="stringliteral">"The model could not be loaded. "</span> \
|
||
|
L<span class="stringliteral">"Maybe it is not a supported file format."</span>);
|
||
|
<span class="keywordflow">return</span>;
|
||
|
}
|
||
|
|
||
|
<span class="comment">// set default material properties</span>
|
||
|
|
||
|
<span class="keywordflow">if</span> (Octree)
|
||
|
Model = Device->getSceneManager()->addOctreeSceneNode(m->getMesh(0));
|
||
|
<span class="keywordflow">else</span>
|
||
|
{
|
||
|
scene::IAnimatedMeshSceneNode* animModel = Device->getSceneManager()->addAnimatedMeshSceneNode(m);
|
||
|
animModel->setAnimationSpeed(30);
|
||
|
Model = animModel;
|
||
|
}
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, UseLight);
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3a3efe2d4921909a842adfc44dacc74520" title="Normalizes normals. Default: false.">video::EMF_NORMALIZE_NORMALS</a>, UseLight);
|
||
|
<span class="comment">// Model->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);</span>
|
||
|
Model->setDebugDataVisible(<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbea25111b15f03bee9a99498737286916dc" title="No Debug Data ( Default )">scene::EDS_OFF</a>);
|
||
|
|
||
|
<span class="comment">// we need to uncheck the menu entries. would be cool to fake a menu event, but</span>
|
||
|
<span class="comment">// that's not so simple. so we do it brute force</span>
|
||
|
gui::IGUIContextMenu* menu = (gui::IGUIContextMenu*)Device->getGUIEnvironment()->getRootGUIElement()->getElementFromId(GUI_ID_TOGGLE_DEBUG_INFO, <span class="keyword">true</span>);
|
||
|
<span class="keywordflow">if</span> (menu)
|
||
|
<span class="keywordflow">for</span>(<span class="keywordtype">int</span> item = 1; item < 6; ++item)
|
||
|
menu->setItemChecked(item, <span class="keyword">false</span>);
|
||
|
updateScaleInfo(Model);
|
||
|
}
|
||
|
</pre></div><p>Function createToolBox() creates a toolbox window. In this simple mesh viewer, this toolbox only contains a tab control with three edit boxes for changing the scale of the displayed model. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> createToolBox()
|
||
|
{
|
||
|
<span class="comment">// remove tool box if already there</span>
|
||
|
IGUIEnvironment* env = Device->getGUIEnvironment();
|
||
|
IGUIElement* root = env->getRootGUIElement();
|
||
|
IGUIElement* e = root->getElementFromId(GUI_ID_DIALOG_ROOT_WINDOW, <span class="keyword">true</span>);
|
||
|
<span class="keywordflow">if</span> (e)
|
||
|
e->remove();
|
||
|
|
||
|
<span class="comment">// create the toolbox window</span>
|
||
|
IGUIWindow* wnd = env->addWindow(core::rect<s32>(600,45,800,480),
|
||
|
<span class="keyword">false</span>, L<span class="stringliteral">"Toolset"</span>, 0, GUI_ID_DIALOG_ROOT_WINDOW);
|
||
|
|
||
|
<span class="comment">// create tab control and tabs</span>
|
||
|
IGUITabControl* tab = env->addTabControl(
|
||
|
core::rect<s32>(2,20,800-602,480-7), wnd, <span class="keyword">true</span>, <span class="keyword">true</span>);
|
||
|
|
||
|
IGUITab* t1 = tab->addTab(L<span class="stringliteral">"Config"</span>);
|
||
|
|
||
|
<span class="comment">// add some edit boxes and a button to tab one</span>
|
||
|
env->addStaticText(L<span class="stringliteral">"Scale:"</span>,
|
||
|
core::rect<s32>(10,20,60,45), <span class="keyword">false</span>, <span class="keyword">false</span>, t1);
|
||
|
env->addStaticText(L<span class="stringliteral">"X:"</span>, core::rect<s32>(22,48,40,66), <span class="keyword">false</span>, <span class="keyword">false</span>, t1);
|
||
|
env->addEditBox(L<span class="stringliteral">"1.0"</span>, core::rect<s32>(40,46,130,66), <span class="keyword">true</span>, t1, GUI_ID_X_SCALE);
|
||
|
env->addStaticText(L<span class="stringliteral">"Y:"</span>, core::rect<s32>(22,82,40,96), <span class="keyword">false</span>, <span class="keyword">false</span>, t1);
|
||
|
env->addEditBox(L<span class="stringliteral">"1.0"</span>, core::rect<s32>(40,76,130,96), <span class="keyword">true</span>, t1, GUI_ID_Y_SCALE);
|
||
|
env->addStaticText(L<span class="stringliteral">"Z:"</span>, core::rect<s32>(22,108,40,126), <span class="keyword">false</span>, <span class="keyword">false</span>, t1);
|
||
|
env->addEditBox(L<span class="stringliteral">"1.0"</span>, core::rect<s32>(40,106,130,126), <span class="keyword">true</span>, t1, GUI_ID_Z_SCALE);
|
||
|
|
||
|
env->addButton(core::rect<s32>(10,134,85,165), t1, GUI_ID_BUTTON_SET_SCALE, L<span class="stringliteral">"Set"</span>);
|
||
|
|
||
|
<span class="comment">// quick scale buttons</span>
|
||
|
env->addButton(core::rect<s32>(65,20,95,40), t1, GUI_ID_BUTTON_SCALE_MUL10, L<span class="stringliteral">"* 10"</span>);
|
||
|
env->addButton(core::rect<s32>(100,20,130,40), t1, GUI_ID_BUTTON_SCALE_DIV10, L<span class="stringliteral">"* 0.1"</span>);
|
||
|
|
||
|
updateScaleInfo(Model);
|
||
|
|
||
|
<span class="comment">// add transparency control</span>
|
||
|
env->addStaticText(L<span class="stringliteral">"GUI Transparency Control:"</span>,
|
||
|
core::rect<s32>(10,200,150,225), <span class="keyword">true</span>, <span class="keyword">false</span>, t1);
|
||
|
IGUIScrollBar* scrollbar = env->addScrollBar(<span class="keyword">true</span>,
|
||
|
core::rect<s32>(10,225,150,240), t1, GUI_ID_SKIN_TRANSPARENCY);
|
||
|
scrollbar->setMax(255);
|
||
|
scrollbar->setPos(255);
|
||
|
|
||
|
<span class="comment">// add framerate control</span>
|
||
|
env->addStaticText(L<span class="stringliteral">":"</span>, core::rect<s32>(10,240,150,265), <span class="keyword">true</span>, <span class="keyword">false</span>, t1);
|
||
|
env->addStaticText(L<span class="stringliteral">"Framerate:"</span>,
|
||
|
core::rect<s32>(12,240,75,265), <span class="keyword">false</span>, <span class="keyword">false</span>, t1);
|
||
|
<span class="comment">// current frame info</span>
|
||
|
env->addStaticText(L<span class="stringliteral">""</span>, core::rect<s32>(75,240,200,265), <span class="keyword">false</span>, <span class="keyword">false</span>, t1,
|
||
|
GUI_ID_ANIMATION_INFO);
|
||
|
scrollbar = env->addScrollBar(<span class="keyword">true</span>,
|
||
|
core::rect<s32>(10,265,150,280), t1, GUI_ID_SKIN_ANIMATION_FPS);
|
||
|
scrollbar->setMax(MAX_FRAMERATE);
|
||
|
scrollbar->setMin(-MAX_FRAMERATE);
|
||
|
scrollbar->setPos(DEFAULT_FRAMERATE);
|
||
|
scrollbar->setSmallStep(1);
|
||
|
}
|
||
|
</pre></div><p>Function updateToolBox() is called each frame to update dynamic information in the toolbox. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> updateToolBox()
|
||
|
{
|
||
|
IGUIEnvironment* env = Device->getGUIEnvironment();
|
||
|
IGUIElement* root = env->getRootGUIElement();
|
||
|
IGUIElement* dlg = root->getElementFromId(GUI_ID_DIALOG_ROOT_WINDOW, <span class="keyword">true</span>);
|
||
|
<span class="keywordflow">if</span> (!dlg )
|
||
|
<span class="keywordflow">return</span>;
|
||
|
|
||
|
<span class="comment">// update the info we have about the animation of the model</span>
|
||
|
IGUIStaticText * aniInfo = (IGUIStaticText *)(dlg->getElementFromId(GUI_ID_ANIMATION_INFO, <span class="keyword">true</span>));
|
||
|
<span class="keywordflow">if</span> (aniInfo)
|
||
|
{
|
||
|
<span class="keywordflow">if</span> ( Model && <a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda073d7fe9dfd49f24cb13bfae56d8d3b6" title="Animated Mesh Scene Node.">scene::ESNT_ANIMATED_MESH</a> == Model->getType() )
|
||
|
{
|
||
|
scene::IAnimatedMeshSceneNode* animatedModel = (scene::IAnimatedMeshSceneNode*)Model;
|
||
|
|
||
|
<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> str( (<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a>)<a class="code" href="namespaceirr_1_1core.html#a894a901069c34298987761c5f3d74f1f">core::round_</a>(animatedModel->getAnimationSpeed()) );
|
||
|
str += L<span class="stringliteral">" Frame: "</span>;
|
||
|
str += <a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>((<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a>)animatedModel->getFrameNr());
|
||
|
aniInfo->setText(str.c_str());
|
||
|
}
|
||
|
<span class="keywordflow">else</span>
|
||
|
aniInfo->setText(L<span class="stringliteral">""</span>);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
<span class="keywordtype">void</span> onKillFocus()
|
||
|
{
|
||
|
<span class="comment">// Avoid that the FPS-camera continues moving when the user presses alt-tab while </span>
|
||
|
<span class="comment">// moving the camera. </span>
|
||
|
<span class="keyword">const</span> core::list<scene::ISceneNodeAnimator*>& animators = Camera[1]->getAnimators();
|
||
|
core::list<irr::scene::ISceneNodeAnimator*>::ConstIterator iter = animators.begin();
|
||
|
<span class="keywordflow">while</span> ( iter != animators.end() )
|
||
|
{
|
||
|
<span class="keywordflow">if</span> ( (*iter)->getType() == <a class="code" href="namespaceirr_1_1scene.html#a327a1e43872705cf8f3f3342fb307d19ae40c836272ace5bf243baaca72dba55c" title="FPS camera animator.">scene::ESNAT_CAMERA_FPS</a> )
|
||
|
{
|
||
|
<span class="comment">// we send a key-down event for all keys used by this animator</span>
|
||
|
scene::ISceneNodeAnimatorCameraFPS * fpsAnimator = <span class="keyword">static_cast<</span>scene::ISceneNodeAnimatorCameraFPS*<span class="keyword">></span>(*iter);
|
||
|
<span class="keyword">const</span> core::array<SKeyMap>& keyMap = fpsAnimator->getKeyMap();
|
||
|
<span class="keywordflow">for</span> ( <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">irr::u32</a> i=0; i< keyMap.size(); ++i )
|
||
|
{
|
||
|
<a class="code" href="structirr_1_1_s_event.html" title="SEvents hold information about an event. See irr::IEventReceiver for details on event handling...">irr::SEvent</a> event;
|
||
|
<span class="keyword">event</span>.<a class="code" href="structirr_1_1_s_event.html#a8b48c016d5c20a9b0967b1ce0fb3ef15">EventType</a> = <a class="code" href="namespaceirr.html#ac9eed96e06e85ce3c86fcbbbe9e48a0ca6f90390f3147a1693e5e2e3422d6ca09" title="A key input event.">EET_KEY_INPUT_EVENT</a>;
|
||
|
<span class="keyword">event</span>.KeyInput.Key = keyMap[i].KeyCode;
|
||
|
<span class="keyword">event</span>.KeyInput.PressedDown = <span class="keyword">false</span>;
|
||
|
fpsAnimator->OnEvent(event);
|
||
|
}
|
||
|
}
|
||
|
++iter;
|
||
|
}
|
||
|
}
|
||
|
</pre></div><p>Function hasModalDialog() checks if we currently have a modal dialog open. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">bool</span> hasModalDialog()
|
||
|
{
|
||
|
<span class="keywordflow">if</span> ( !Device )
|
||
|
<span class="keywordflow">return</span> <span class="keyword">false</span>;
|
||
|
IGUIEnvironment* env = Device->getGUIEnvironment();
|
||
|
IGUIElement * focused = env->getFocus();
|
||
|
<span class="keywordflow">while</span> ( focused )
|
||
|
{
|
||
|
<span class="keywordflow">if</span> ( focused->isVisible() && focused->hasType(<a class="code" href="namespaceirr_1_1gui.html#ae4d66df0ecf4117cdbcf9f22404bd254aabc2c9519ef201dce8bd898d2566e53b" title="A modal screen.">EGUIET_MODAL_SCREEN</a>) )
|
||
|
<span class="keywordflow">return</span> <span class="keyword">true</span>;
|
||
|
focused = focused->getParent();
|
||
|
}
|
||
|
<span class="keywordflow">return</span> <span class="keyword">false</span>;
|
||
|
}
|
||
|
</pre></div><p>To get all the events sent by the GUI Elements, we need to create an event receiver. This one is really simple. If an event occurs, it checks the id of the caller and the event type, and starts an action based on these values. For example, if a menu item with id GUI_ID_OPEN_MODEL was selected, it opens a file-open-dialog. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>MyEventReceiver : <span class="keyword">public</span> IEventReceiver
|
||
|
{
|
||
|
<span class="keyword">public</span>:
|
||
|
<span class="keyword">virtual</span> <span class="keywordtype">bool</span> OnEvent(<span class="keyword">const</span> SEvent& event)
|
||
|
{
|
||
|
<span class="comment">// Escape swaps Camera Input</span>
|
||
|
<span class="keywordflow">if</span> (event.EventType == <a class="code" href="namespaceirr.html#ac9eed96e06e85ce3c86fcbbbe9e48a0ca6f90390f3147a1693e5e2e3422d6ca09" title="A key input event.">EET_KEY_INPUT_EVENT</a> &&
|
||
|
event.KeyInput.PressedDown == <span class="keyword">false</span>)
|
||
|
{
|
||
|
<span class="keywordflow">if</span> ( OnKeyUp(event.KeyInput.Key) )
|
||
|
<span class="keywordflow">return</span> <span class="keyword">true</span>;
|
||
|
}
|
||
|
|
||
|
<span class="keywordflow">if</span> (event.EventType == <a class="code" href="namespaceirr.html#ac9eed96e06e85ce3c86fcbbbe9e48a0cae85bb44dd09a29c879d64a05047fc1d2" title="An event of the graphical user interface.">EET_GUI_EVENT</a>)
|
||
|
{
|
||
|
<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> <span class="keywordtype">id</span> = <span class="keyword">event</span>.GUIEvent.Caller->getID();
|
||
|
IGUIEnvironment* env = Device->getGUIEnvironment();
|
||
|
|
||
|
<span class="keywordflow">switch</span>(event.GUIEvent.EventType)
|
||
|
{
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1gui.html#aeac71ad17341a4b6e9026ae11d576808a90e8bebdd49f2a2e451b1105a87ee7ef" title="A menu item was selected in a (context) menu.">EGET_MENU_ITEM_SELECTED</a>:
|
||
|
<span class="comment">// a menu item was clicked</span>
|
||
|
OnMenuItemSelected( (IGUIContextMenu*)event.GUIEvent.Caller );
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1gui.html#aeac71ad17341a4b6e9026ae11d576808a5b6504cf6b541d5ad95407c384632873" title="A file has been selected in the file dialog.">EGET_FILE_SELECTED</a>:
|
||
|
{
|
||
|
<span class="comment">// load the model file, selected in the file open dialog</span>
|
||
|
IGUIFileOpenDialog* dialog =
|
||
|
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
|
||
|
loadModel(<a class="code" href="namespaceirr_1_1core.html#ade1071a878633f2f6d8a75c5d11fec19" title="Typedef for character strings.">core::stringc</a>(dialog->getFileName()).c_str());
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1gui.html#aeac71ad17341a4b6e9026ae11d576808a2eea536494edcde2bb2608bda9d352b2" title="A scrollbar has changed its position.">EGET_SCROLL_BAR_CHANGED</a>:
|
||
|
|
||
|
<span class="comment">// control skin transparency</span>
|
||
|
<span class="keywordflow">if</span> (<span class="keywordtype">id</span> == GUI_ID_SKIN_TRANSPARENCY)
|
||
|
{
|
||
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
|
||
|
setSkinTransparency(pos, env->getSkin());
|
||
|
}
|
||
|
<span class="comment">// control animation speed</span>
|
||
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (<span class="keywordtype">id</span> == GUI_ID_SKIN_ANIMATION_FPS)
|
||
|
{
|
||
|
<span class="keyword">const</span> <a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
|
||
|
<span class="keywordflow">if</span> (<a class="code" href="namespaceirr_1_1scene.html#acad3d7ef92a9807d391ba29120f3b7bda073d7fe9dfd49f24cb13bfae56d8d3b6" title="Animated Mesh Scene Node.">scene::ESNT_ANIMATED_MESH</a> == Model->getType())
|
||
|
((scene::IAnimatedMeshSceneNode*)Model)->setAnimationSpeed((<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)pos);
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1gui.html#aeac71ad17341a4b6e9026ae11d576808aef7f9081622a71160e161c80eb07d436" title="The selection in a combo box has been changed.">EGET_COMBO_BOX_CHANGED</a>:
|
||
|
|
||
|
<span class="comment">// control anti-aliasing/filtering</span>
|
||
|
<span class="keywordflow">if</span> (<span class="keywordtype">id</span> == GUI_ID_TEXTUREFILTER)
|
||
|
{
|
||
|
OnTextureFilterSelected( (IGUIComboBox*)event.GUIEvent.Caller );
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1gui.html#aeac71ad17341a4b6e9026ae11d576808a308ee345c92444931f83e48354072d98" title="A button was clicked.">EGET_BUTTON_CLICKED</a>:
|
||
|
|
||
|
<span class="keywordflow">switch</span>(<span class="keywordtype">id</span>)
|
||
|
{
|
||
|
<span class="keywordflow">case</span> GUI_ID_BUTTON_SET_SCALE:
|
||
|
{
|
||
|
<span class="comment">// set scale</span>
|
||
|
gui::IGUIElement* root = env->getRootGUIElement();
|
||
|
<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a> scale;
|
||
|
<a class="code" href="namespaceirr_1_1core.html#ade1071a878633f2f6d8a75c5d11fec19" title="Typedef for character strings.">core::stringc</a> s;
|
||
|
|
||
|
s = root->getElementFromId(GUI_ID_X_SCALE, <span class="keyword">true</span>)->getText();
|
||
|
scale.X = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)atof(s.c_str());
|
||
|
s = root->getElementFromId(GUI_ID_Y_SCALE, <span class="keyword">true</span>)->getText();
|
||
|
scale.Y = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)atof(s.c_str());
|
||
|
s = root->getElementFromId(GUI_ID_Z_SCALE, <span class="keyword">true</span>)->getText();
|
||
|
scale.Z = (<a class="code" href="namespaceirr.html#a0277be98d67dc26ff93b1a6a1d086b07" title="32 bit floating point variable.">f32</a>)atof(s.c_str());
|
||
|
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setScale(scale);
|
||
|
updateScaleInfo(Model);
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_BUTTON_SCALE_MUL10:
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setScale(Model->getScale()*10.f);
|
||
|
updateScaleInfo(Model);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_BUTTON_SCALE_DIV10:
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setScale(Model->getScale()*0.1f);
|
||
|
updateScaleInfo(Model);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_BUTTON_OPEN_MODEL:
|
||
|
env->addFileOpenDialog(L<span class="stringliteral">"Please select a model file to open"</span>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_BUTTON_SHOW_ABOUT:
|
||
|
showAboutText();
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_BUTTON_SHOW_TOOLBOX:
|
||
|
createToolBox();
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_BUTTON_SELECT_ARCHIVE:
|
||
|
env->addFileOpenDialog(L<span class="stringliteral">"Please select your game archive/directory"</span>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
}
|
||
|
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">default</span>:
|
||
|
<span class="keywordflow">break</span>;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
<span class="keywordflow">return</span> <span class="keyword">false</span>;
|
||
|
}
|
||
|
</pre></div><p>Handle key-up events </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="keywordtype">bool</span> OnKeyUp(<a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3">irr::EKEY_CODE</a> keyCode)
|
||
|
{
|
||
|
<span class="comment">// Don't handle keys if we have a modal dialog open as it would lead </span>
|
||
|
<span class="comment">// to unexpected application behaviour for the user.</span>
|
||
|
<span class="keywordflow">if</span> ( hasModalDialog() )
|
||
|
<span class="keywordflow">return</span> <span class="keyword">false</span>;
|
||
|
|
||
|
<span class="keywordflow">if</span> (keyCode == <a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3aab32bfc194f119e5d5b9b39527bbcd61">irr::KEY_ESCAPE</a>)
|
||
|
{
|
||
|
<span class="keywordflow">if</span> (Device)
|
||
|
{
|
||
|
scene::ICameraSceneNode * camera =
|
||
|
Device->getSceneManager()->getActiveCamera();
|
||
|
<span class="keywordflow">if</span> (camera)
|
||
|
{
|
||
|
camera->setInputReceiverEnabled( !camera->isInputReceiverEnabled() );
|
||
|
}
|
||
|
<span class="keywordflow">return</span> <span class="keyword">true</span>;
|
||
|
}
|
||
|
}
|
||
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (keyCode == <a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a5427274e34fd5587155fe8b3b12d96a8">irr::KEY_F1</a>)
|
||
|
{
|
||
|
<span class="keywordflow">if</span> (Device)
|
||
|
{
|
||
|
IGUIElement* elem = Device->getGUIEnvironment()->getRootGUIElement()->getElementFromId(GUI_ID_POSITION_TEXT);
|
||
|
<span class="keywordflow">if</span> (elem)
|
||
|
elem->setVisible(!elem->isVisible());
|
||
|
}
|
||
|
}
|
||
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (keyCode == <a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3a864770d5fa3f9713dc7a37f66f6b84fc">irr::KEY_KEY_M</a>)
|
||
|
{
|
||
|
<span class="keywordflow">if</span> (Device)
|
||
|
Device->minimizeWindow();
|
||
|
}
|
||
|
<span class="keywordflow">else</span> <span class="keywordflow">if</span> (keyCode == <a class="code" href="namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3ae1f51392abd7c04d8129d2c85dbd391c">irr::KEY_KEY_L</a>)
|
||
|
{
|
||
|
UseLight=!UseLight;
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
{
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, UseLight);
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3a3efe2d4921909a842adfc44dacc74520" title="Normalizes normals. Default: false.">video::EMF_NORMALIZE_NORMALS</a>, UseLight);
|
||
|
}
|
||
|
}
|
||
|
<span class="keywordflow">return</span> <span class="keyword">false</span>;
|
||
|
}
|
||
|
</pre></div><p>Handle "menu item clicked" events. </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="keywordtype">void</span> OnMenuItemSelected( IGUIContextMenu* menu )
|
||
|
{
|
||
|
<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> <span class="keywordtype">id</span> = menu->getItemCommandId(menu->getSelectedItem());
|
||
|
IGUIEnvironment* env = Device->getGUIEnvironment();
|
||
|
|
||
|
<span class="keywordflow">switch</span>(<span class="keywordtype">id</span>)
|
||
|
{
|
||
|
<span class="keywordflow">case</span> GUI_ID_OPEN_MODEL: <span class="comment">// FilOnButtonSetScalinge -> Open Model</span>
|
||
|
env->addFileOpenDialog(L<span class="stringliteral">"Please select a model file to open"</span>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_SET_MODEL_ARCHIVE: <span class="comment">// File -> Set Model Archive</span>
|
||
|
env->addFileOpenDialog(L<span class="stringliteral">"Please select your game archive/directory"</span>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_LOAD_AS_OCTREE: <span class="comment">// File -> LoadAsOctree</span>
|
||
|
Octree = !Octree;
|
||
|
menu->setItemChecked(menu->getSelectedItem(), Octree);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_QUIT: <span class="comment">// File -> Quit</span>
|
||
|
Device->closeDevice();
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_SKY_BOX_VISIBLE: <span class="comment">// View -> Skybox</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem(), !menu->isItemChecked(menu->getSelectedItem()));
|
||
|
SkyBox->setVisible(!SkyBox->isVisible());
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_DEBUG_OFF: <span class="comment">// View -> Debug Information</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem()+1, <span class="keyword">false</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()+2, <span class="keyword">false</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()+3, <span class="keyword">false</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()+4, <span class="keyword">false</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()+5, <span class="keyword">false</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()+6, <span class="keyword">false</span>);
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setDebugDataVisible(<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbea25111b15f03bee9a99498737286916dc" title="No Debug Data ( Default )">scene::EDS_OFF</a>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_DEBUG_BOUNDING_BOX: <span class="comment">// View -> Debug Information</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem(), !menu->isItemChecked(menu->getSelectedItem()));
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setDebugDataVisible((<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbe" title="An enumeration for all types of debug data for built-in scene nodes (flags)">scene::E_DEBUG_SCENE_TYPE</a>)(Model->isDebugDataVisible()^<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbea19e56bb3d3b18134fa63e0529629b427" title="Show Bounding Boxes of SceneNode.">scene::EDS_BBOX</a>));
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_DEBUG_NORMALS: <span class="comment">// View -> Debug Information</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem(), !menu->isItemChecked(menu->getSelectedItem()));
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setDebugDataVisible((<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbe" title="An enumeration for all types of debug data for built-in scene nodes (flags)">scene::E_DEBUG_SCENE_TYPE</a>)(Model->isDebugDataVisible()^<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbea2713e470ee18ec9bfe40fdfb502f8b05" title="Show Vertex Normals.">scene::EDS_NORMALS</a>));
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_DEBUG_SKELETON: <span class="comment">// View -> Debug Information</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem(), !menu->isItemChecked(menu->getSelectedItem()));
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setDebugDataVisible((<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbe" title="An enumeration for all types of debug data for built-in scene nodes (flags)">scene::E_DEBUG_SCENE_TYPE</a>)(Model->isDebugDataVisible()^<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbeaa7664e189b8641ac54cf27f70f6d8144" title="Shows Skeleton/Tags.">scene::EDS_SKELETON</a>));
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_DEBUG_WIRE_OVERLAY: <span class="comment">// View -> Debug Information</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem(), !menu->isItemChecked(menu->getSelectedItem()));
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setDebugDataVisible((<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbe" title="An enumeration for all types of debug data for built-in scene nodes (flags)">scene::E_DEBUG_SCENE_TYPE</a>)(Model->isDebugDataVisible()^<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbea349b086537ac770f09935af4e31d3f3e" title="Overlays Mesh Wireframe.">scene::EDS_MESH_WIRE_OVERLAY</a>));
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_DEBUG_HALF_TRANSPARENT: <span class="comment">// View -> Debug Information</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem(), !menu->isItemChecked(menu->getSelectedItem()));
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setDebugDataVisible((<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbe" title="An enumeration for all types of debug data for built-in scene nodes (flags)">scene::E_DEBUG_SCENE_TYPE</a>)(Model->isDebugDataVisible()^<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbea1def9e1b7d86e286b07a4b7179e6ed85" title="Temporary use transparency Material Type.">scene::EDS_HALF_TRANSPARENCY</a>));
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_DEBUG_BUFFERS_BOUNDING_BOXES: <span class="comment">// View -> Debug Information</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem(), !menu->isItemChecked(menu->getSelectedItem()));
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setDebugDataVisible((<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbe" title="An enumeration for all types of debug data for built-in scene nodes (flags)">scene::E_DEBUG_SCENE_TYPE</a>)(Model->isDebugDataVisible()^<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbea0179a3df80ac09143dfffed0bd9e99d1" title="Show Bounding Boxes of all MeshBuffers.">scene::EDS_BBOX_BUFFERS</a>));
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_DEBUG_ALL: <span class="comment">// View -> Debug Information</span>
|
||
|
menu->setItemChecked(menu->getSelectedItem()-1, <span class="keyword">true</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()-2, <span class="keyword">true</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()-3, <span class="keyword">true</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()-4, <span class="keyword">true</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()-5, <span class="keyword">true</span>);
|
||
|
menu->setItemChecked(menu->getSelectedItem()-6, <span class="keyword">true</span>);
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setDebugDataVisible(<a class="code" href="namespaceirr_1_1scene.html#a52b664c4c988113735042b168fc32dbea24ffe5e6e99d589b3c80181e7c7dd4e2" title="Show all debug infos.">scene::EDS_FULL</a>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_ABOUT: <span class="comment">// Help->About</span>
|
||
|
showAboutText();
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_MODEL_MATERIAL_SOLID: <span class="comment">// View -> Material -> Solid</span>
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setMaterialType(<a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1a9bc471b9c18c9e2d20496004d2a2e803" title="Standard solid material.">video::EMT_SOLID</a>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_MODEL_MATERIAL_TRANSPARENT: <span class="comment">// View -> Material -> Transparent</span>
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setMaterialType(<a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1a1b5a814c4466aca2943ff056003a50d1" title="A transparent material.">video::EMT_TRANSPARENT_ADD_COLOR</a>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_MODEL_MATERIAL_REFLECTION: <span class="comment">// View -> Material -> Reflection</span>
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
Model->setMaterialType(<a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1a42a8b6f5c933864ca104b3d46692c43b" title="Look like a reflection of the environment around it.">video::EMT_SPHERE_MAP</a>);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
|
||
|
<span class="keywordflow">case</span> GUI_ID_CAMERA_MAYA:
|
||
|
setActiveCamera(Camera[0]);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> GUI_ID_CAMERA_FIRST_PERSON:
|
||
|
setActiveCamera(Camera[1]);
|
||
|
<span class="keywordflow">break</span>;
|
||
|
}
|
||
|
}
|
||
|
</pre></div><p>Handle the event that one of the texture-filters was selected in the corresponding combobox. </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="keywordtype">void</span> OnTextureFilterSelected( IGUIComboBox* combo )
|
||
|
{
|
||
|
<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> pos = combo->getSelected();
|
||
|
<span class="keywordflow">switch</span> (pos)
|
||
|
{
|
||
|
<span class="keywordflow">case</span> 0:
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
{
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3afbf2b289d416e70466e4ab05e97b4934" title="Is bilinear filtering enabled? Default: true.">video::EMF_BILINEAR_FILTER</a>, <span class="keyword">false</span>);
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3a7a2ed21d879b182fbc767a4c20d72eef" title="Is trilinear filtering enabled? Default: false.">video::EMF_TRILINEAR_FILTER</a>, <span class="keyword">false</span>);
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3a941c0756b9dc3f987a183a401c6fd4ad" title="Is anisotropic filtering? Default: false.">video::EMF_ANISOTROPIC_FILTER</a>, <span class="keyword">false</span>);
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> 1:
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
{
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3afbf2b289d416e70466e4ab05e97b4934" title="Is bilinear filtering enabled? Default: true.">video::EMF_BILINEAR_FILTER</a>, <span class="keyword">true</span>);
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3a7a2ed21d879b182fbc767a4c20d72eef" title="Is trilinear filtering enabled? Default: false.">video::EMF_TRILINEAR_FILTER</a>, <span class="keyword">false</span>);
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> 2:
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
{
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3afbf2b289d416e70466e4ab05e97b4934" title="Is bilinear filtering enabled? Default: true.">video::EMF_BILINEAR_FILTER</a>, <span class="keyword">false</span>);
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3a7a2ed21d879b182fbc767a4c20d72eef" title="Is trilinear filtering enabled? Default: false.">video::EMF_TRILINEAR_FILTER</a>, <span class="keyword">true</span>);
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> 3:
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
{
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3a941c0756b9dc3f987a183a401c6fd4ad" title="Is anisotropic filtering? Default: false.">video::EMF_ANISOTROPIC_FILTER</a>, <span class="keyword">true</span>);
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> 4:
|
||
|
<span class="keywordflow">if</span> (Model)
|
||
|
{
|
||
|
Model->setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3a941c0756b9dc3f987a183a401c6fd4ad" title="Is anisotropic filtering? Default: false.">video::EMF_ANISOTROPIC_FILTER</a>, <span class="keyword">false</span>);
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
</pre></div><p>Most of the hard work is done. We only need to create the Irrlicht Engine device and all the buttons, menus and toolbars. We start up the engine as usual, using <a class="el" href="namespaceirr.html#abaf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.">createDevice()</a>. To make our application catch events, we set our eventreceiver as parameter. As you can see, there is also a call to IrrlichtDevice::setResizeable(). This makes the render window resizeable, which is quite useful for a mesh viewer. </p>
|
||
|
<div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span>* argv[])
|
||
|
{
|
||
|
<span class="comment">// ask user for driver</span>
|
||
|
<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType=driverChoiceConsole();
|
||
|
<span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0ae685cada50f8c100403134d932d0414c" title="No driver, just for counting the elements.">video::EDT_COUNT</a>)
|
||
|
<span class="keywordflow">return</span> 1;
|
||
|
|
||
|
<span class="comment">// create device and exit if creation failed</span>
|
||
|
MyEventReceiver receiver;
|
||
|
Device = <a class="code" href="namespaceirr.html#abaf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.">createDevice</a>(driverType, core::dimension2d<u32>(800, 600),
|
||
|
16, <span class="keyword">false</span>, <span class="keyword">false</span>, <span class="keyword">false</span>, &receiver);
|
||
|
|
||
|
<span class="keywordflow">if</span> (Device == 0)
|
||
|
<span class="keywordflow">return</span> 1; <span class="comment">// could not create selected driver.</span>
|
||
|
|
||
|
Device->setResizable(<span class="keyword">true</span>);
|
||
|
|
||
|
Device->setWindowCaption(L<span class="stringliteral">"Irrlicht Engine - Loading..."</span>);
|
||
|
|
||
|
video::IVideoDriver* driver = Device->getVideoDriver();
|
||
|
IGUIEnvironment* env = Device->getGUIEnvironment();
|
||
|
scene::ISceneManager* smgr = Device->getSceneManager();
|
||
|
smgr->getParameters()->setAttribute(<a class="code" href="namespaceirr_1_1scene.html#a157681b3ef101a801ce278e6f21de946" title="Name of the parameter specifying the COLLADA mesh loading mode.">scene::COLLADA_CREATE_SCENE_INSTANCES</a>, <span class="keyword">true</span>);
|
||
|
|
||
|
driver->setTextureCreationFlag(<a class="code" href="namespaceirr_1_1video.html#acaf6f7414534f7d62bff18c5bf11876fa20881e307a778c4a4fbb5327a60a93bb">video::ETCF_ALWAYS_32_BIT</a>, <span class="keyword">true</span>);
|
||
|
|
||
|
smgr->addLightSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(200,200,200),
|
||
|
video::SColorf(1.0f,1.0f,1.0f),2000);
|
||
|
smgr->setAmbientLight(video::SColorf(0.3f,0.3f,0.3f));
|
||
|
<span class="comment">// add our media directory as "search path"</span>
|
||
|
Device->getFileSystem()->addFileArchive(<span class="stringliteral">"../../media/"</span>);
|
||
|
</pre></div><p>The next step is to read the configuration file. It is stored in the xml format and looks a little bit like this:</p>
|
||
|
<div class="fragment"><pre class="fragment">
|
||
|
<?xml version="1.0"?>
|
||
|
<config>
|
||
|
<startUpModel file="some filename" />
|
||
|
<messageText caption="Irrlicht Engine Mesh Viewer">
|
||
|
Hello!
|
||
|
</messageText>
|
||
|
</config>
|
||
|
</pre></div><p>We need the data stored in there to be written into the global variables StartUpModelFile, MessageText and Caption. This is now done using the Irrlicht Engine integrated XML parser: </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="comment">// read configuration from xml file</span>
|
||
|
|
||
|
<a class="code" href="namespaceirr_1_1io.html#a9dc6291fb7e4c73155a3e3c8339f9bff" title="An xml reader for wide characters, derived from IReferenceCounted.">io::IXMLReader</a>* xml = Device->getFileSystem()->createXMLReader( L<span class="stringliteral">"config.xml"</span>);
|
||
|
|
||
|
<span class="keywordflow">while</span>(xml && xml->read())
|
||
|
{
|
||
|
<span class="keywordflow">switch</span>(xml->getNodeType())
|
||
|
{
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1io.html#a86a02676c9cbb822e04d60c81b4f33eda0edf973f8ca0f6097f69369539d432a4">io::EXN_TEXT</a>:
|
||
|
<span class="comment">// in this xml file, the only text which occurs is the</span>
|
||
|
<span class="comment">// messageText</span>
|
||
|
MessageText = xml->getNodeData();
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">case</span> <a class="code" href="namespaceirr_1_1io.html#a86a02676c9cbb822e04d60c81b4f33eda9df4f5baccc23a0ad1f6fa64d8de2fc0" title="An xml element such as <foo>.">io::EXN_ELEMENT</a>:
|
||
|
{
|
||
|
<span class="keywordflow">if</span> (<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(<span class="stringliteral">"startUpModel"</span>) == xml->getNodeName())
|
||
|
StartUpModelFile = xml->getAttributeValue(L<span class="stringliteral">"file"</span>);
|
||
|
<span class="keywordflow">else</span>
|
||
|
<span class="keywordflow">if</span> (<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(<span class="stringliteral">"messageText"</span>) == xml->getNodeName())
|
||
|
Caption = xml->getAttributeValue(L<span class="stringliteral">"caption"</span>);
|
||
|
}
|
||
|
<span class="keywordflow">break</span>;
|
||
|
<span class="keywordflow">default</span>:
|
||
|
<span class="keywordflow">break</span>;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
<span class="keywordflow">if</span> (xml)
|
||
|
xml->drop(); <span class="comment">// don't forget to delete the xml reader</span>
|
||
|
|
||
|
<span class="keywordflow">if</span> (argc > 1)
|
||
|
StartUpModelFile = argv[1];
|
||
|
</pre></div><p>That wasn't difficult. Now we'll set a nicer font and create the Menu. It is possible to create submenus for every menu item. The call menu->addItem(L"File", -1, true, true); for example adds a new menu Item with the name "File" and the id -1. The following parameter says that the menu item should be enabled, and the last one says, that there should be a submenu. The submenu can now be accessed with menu->getSubMenu(0), because the "File" entry is the menu item with index 0. </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="comment">// set a nicer font</span>
|
||
|
|
||
|
IGUISkin* skin = env->getSkin();
|
||
|
IGUIFont* font = env-><a class="code" href="classirr_1_1gui_1_1_i_g_u_i_skin.html#ab1b2623d04688c4dfe106ca407171d6e" title="returns the default font">getFont</a>(<span class="stringliteral">"fonthaettenschweiler.bmp"</span>);
|
||
|
<span class="keywordflow">if</span> (font)
|
||
|
skin->setFont(font);
|
||
|
|
||
|
<span class="comment">// create menu</span>
|
||
|
gui::IGUIContextMenu* menu = env->addMenu();
|
||
|
menu->addItem(L<span class="stringliteral">"File"</span>, -1, <span class="keyword">true</span>, <span class="keyword">true</span>);
|
||
|
menu->addItem(L<span class="stringliteral">"View"</span>, -1, <span class="keyword">true</span>, <span class="keyword">true</span>);
|
||
|
menu->addItem(L<span class="stringliteral">"Camera"</span>, -1, <span class="keyword">true</span>, <span class="keyword">true</span>);
|
||
|
menu->addItem(L<span class="stringliteral">"Help"</span>, -1, <span class="keyword">true</span>, <span class="keyword">true</span>);
|
||
|
|
||
|
gui::IGUIContextMenu* submenu;
|
||
|
submenu = menu->getSubMenu(0);
|
||
|
submenu->addItem(L<span class="stringliteral">"Open Model File & Texture..."</span>, GUI_ID_OPEN_MODEL);
|
||
|
submenu->addItem(L<span class="stringliteral">"Set Model Archive..."</span>, GUI_ID_SET_MODEL_ARCHIVE);
|
||
|
submenu->addItem(L<span class="stringliteral">"Load as Octree"</span>, GUI_ID_LOAD_AS_OCTREE);
|
||
|
submenu->addSeparator();
|
||
|
submenu->addItem(L<span class="stringliteral">"Quit"</span>, GUI_ID_QUIT);
|
||
|
|
||
|
submenu = menu->getSubMenu(1);
|
||
|
submenu->addItem(L<span class="stringliteral">"sky box visible"</span>, GUI_ID_SKY_BOX_VISIBLE, <span class="keyword">true</span>, <span class="keyword">false</span>, <span class="keyword">true</span>);
|
||
|
submenu->addItem(L<span class="stringliteral">"toggle model debug information"</span>, GUI_ID_TOGGLE_DEBUG_INFO, <span class="keyword">true</span>, <span class="keyword">true</span>);
|
||
|
submenu->addItem(L<span class="stringliteral">"model material"</span>, -1, <span class="keyword">true</span>, <span class="keyword">true</span> );
|
||
|
|
||
|
submenu = submenu->getSubMenu(1);
|
||
|
submenu->addItem(L<span class="stringliteral">"Off"</span>, GUI_ID_DEBUG_OFF);
|
||
|
submenu->addItem(L<span class="stringliteral">"Bounding Box"</span>, GUI_ID_DEBUG_BOUNDING_BOX);
|
||
|
submenu->addItem(L<span class="stringliteral">"Normals"</span>, GUI_ID_DEBUG_NORMALS);
|
||
|
submenu->addItem(L<span class="stringliteral">"Skeleton"</span>, GUI_ID_DEBUG_SKELETON);
|
||
|
submenu->addItem(L<span class="stringliteral">"Wire overlay"</span>, GUI_ID_DEBUG_WIRE_OVERLAY);
|
||
|
submenu->addItem(L<span class="stringliteral">"Half-Transparent"</span>, GUI_ID_DEBUG_HALF_TRANSPARENT);
|
||
|
submenu->addItem(L<span class="stringliteral">"Buffers bounding boxes"</span>, GUI_ID_DEBUG_BUFFERS_BOUNDING_BOXES);
|
||
|
submenu->addItem(L<span class="stringliteral">"All"</span>, GUI_ID_DEBUG_ALL);
|
||
|
|
||
|
submenu = menu->getSubMenu(1)->getSubMenu(2);
|
||
|
submenu->addItem(L<span class="stringliteral">"Solid"</span>, GUI_ID_MODEL_MATERIAL_SOLID);
|
||
|
submenu->addItem(L<span class="stringliteral">"Transparent"</span>, GUI_ID_MODEL_MATERIAL_TRANSPARENT);
|
||
|
submenu->addItem(L<span class="stringliteral">"Reflection"</span>, GUI_ID_MODEL_MATERIAL_REFLECTION);
|
||
|
|
||
|
submenu = menu->getSubMenu(2);
|
||
|
submenu->addItem(L<span class="stringliteral">"Maya Style"</span>, GUI_ID_CAMERA_MAYA);
|
||
|
submenu->addItem(L<span class="stringliteral">"First Person"</span>, GUI_ID_CAMERA_FIRST_PERSON);
|
||
|
|
||
|
submenu = menu->getSubMenu(3);
|
||
|
submenu->addItem(L<span class="stringliteral">"About"</span>, GUI_ID_ABOUT);
|
||
|
</pre></div><p>Below the menu we want a toolbar, onto which we can place colored buttons and important looking stuff like a senseless combobox. </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="comment">// create toolbar</span>
|
||
|
|
||
|
gui::IGUIToolBar* bar = env->addToolBar();
|
||
|
|
||
|
video::ITexture* image = driver->getTexture(<span class="stringliteral">"open.png"</span>);
|
||
|
bar->addButton(GUI_ID_BUTTON_OPEN_MODEL, 0, L<span class="stringliteral">"Open a model"</span>,image, 0, <span class="keyword">false</span>, <span class="keyword">true</span>);
|
||
|
|
||
|
image = driver->getTexture(<span class="stringliteral">"tools.png"</span>);
|
||
|
bar->addButton(GUI_ID_BUTTON_SHOW_TOOLBOX, 0, L<span class="stringliteral">"Open Toolset"</span>,image, 0, <span class="keyword">false</span>, <span class="keyword">true</span>);
|
||
|
|
||
|
image = driver->getTexture(<span class="stringliteral">"zip.png"</span>);
|
||
|
bar->addButton(GUI_ID_BUTTON_SELECT_ARCHIVE, 0, L<span class="stringliteral">"Set Model Archive"</span>,image, 0, <span class="keyword">false</span>, <span class="keyword">true</span>);
|
||
|
|
||
|
image = driver->getTexture(<span class="stringliteral">"help.png"</span>);
|
||
|
bar->addButton(GUI_ID_BUTTON_SHOW_ABOUT, 0, L<span class="stringliteral">"Open Help"</span>, image, 0, <span class="keyword">false</span>, <span class="keyword">true</span>);
|
||
|
|
||
|
<span class="comment">// create a combobox for texture filters</span>
|
||
|
|
||
|
gui::IGUIComboBox* box = env->addComboBox(core::rect<s32>(250,4,350,23), bar, GUI_ID_TEXTUREFILTER);
|
||
|
box->addItem(L<span class="stringliteral">"No filtering"</span>);
|
||
|
box->addItem(L<span class="stringliteral">"Bilinear"</span>);
|
||
|
box->addItem(L<span class="stringliteral">"Trilinear"</span>);
|
||
|
box->addItem(L<span class="stringliteral">"Anisotropic"</span>);
|
||
|
box->addItem(L<span class="stringliteral">"Isotropic"</span>);
|
||
|
</pre></div><p>To make the editor look a little bit better, we disable transparent gui elements, and add an Irrlicht Engine logo. In addition, a text showing the current frames per second value is created and the window caption is changed. </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="comment">// disable alpha</span>
|
||
|
|
||
|
<span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> i=0; i<<a class="code" href="namespaceirr_1_1gui.html#abd15860fde29833c48daff5f95d5467aaf340f49e2e0827c0f06fdf65098554af">gui::EGDC_COUNT</a> ; ++i)
|
||
|
{
|
||
|
video::SColor col = env->getSkin()->getColor((<a class="code" href="namespaceirr_1_1gui.html#abd15860fde29833c48daff5f95d5467a" title="Enumeration for skin colors.">gui::EGUI_DEFAULT_COLOR</a>)i);
|
||
|
col.setAlpha(255);
|
||
|
env->getSkin()->setColor((<a class="code" href="namespaceirr_1_1gui.html#abd15860fde29833c48daff5f95d5467a" title="Enumeration for skin colors.">gui::EGUI_DEFAULT_COLOR</a>)i, col);
|
||
|
}
|
||
|
|
||
|
<span class="comment">// add a tabcontrol</span>
|
||
|
|
||
|
createToolBox();
|
||
|
|
||
|
<span class="comment">// create fps text</span>
|
||
|
|
||
|
IGUIStaticText* fpstext = env->addStaticText(L<span class="stringliteral">""</span>,
|
||
|
core::rect<s32>(400,4,570,23), <span class="keyword">true</span>, <span class="keyword">false</span>, bar);
|
||
|
|
||
|
IGUIStaticText* postext = env->addStaticText(L<span class="stringliteral">""</span>,
|
||
|
core::rect<s32>(10,50,470,80),<span class="keyword">false</span>, <span class="keyword">false</span>, 0, GUI_ID_POSITION_TEXT);
|
||
|
postext->setVisible(<span class="keyword">false</span>);
|
||
|
|
||
|
<span class="comment">// set window caption</span>
|
||
|
|
||
|
Caption += <span class="stringliteral">" - ["</span>;
|
||
|
Caption += driver->getName();
|
||
|
Caption += <span class="stringliteral">"]"</span>;
|
||
|
Device->setWindowCaption(Caption.c_str());
|
||
|
</pre></div><p>That's nearly the whole application. We simply show the about message box at start up, and load the first model. To make everything look better, a skybox is created and a user controlled camera, to make the application a little bit more interactive. Finally, everything is drawn in a standard drawing loop. </p>
|
||
|
<div class="fragment"><pre class="fragment"> <span class="comment">// show about message box and load default model</span>
|
||
|
<span class="keywordflow">if</span> (argc==1)
|
||
|
showAboutText();
|
||
|
loadModel(StartUpModelFile.c_str());
|
||
|
|
||
|
<span class="comment">// add skybox</span>
|
||
|
|
||
|
SkyBox = smgr->addSkyBoxSceneNode(
|
||
|
driver->getTexture(<span class="stringliteral">"irrlicht2_up.jpg"</span>),
|
||
|
driver->getTexture(<span class="stringliteral">"irrlicht2_dn.jpg"</span>),
|
||
|
driver->getTexture(<span class="stringliteral">"irrlicht2_lf.jpg"</span>),
|
||
|
driver->getTexture(<span class="stringliteral">"irrlicht2_rt.jpg"</span>),
|
||
|
driver->getTexture(<span class="stringliteral">"irrlicht2_ft.jpg"</span>),
|
||
|
driver->getTexture(<span class="stringliteral">"irrlicht2_bk.jpg"</span>));
|
||
|
|
||
|
<span class="comment">// add a camera scene node</span>
|
||
|
Camera[0] = smgr->addCameraSceneNodeMaya();
|
||
|
Camera[0]->setFarValue(20000.f);
|
||
|
<span class="comment">// Maya cameras reposition themselves relative to their target, so target the location</span>
|
||
|
<span class="comment">// where the mesh scene node is placed.</span>
|
||
|
Camera[0]->setTarget(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,30,0));
|
||
|
|
||
|
Camera[1] = smgr->addCameraSceneNodeFPS();
|
||
|
Camera[1]->setFarValue(20000.f);
|
||
|
Camera[1]->setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0,-70));
|
||
|
Camera[1]->setTarget(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,30,0));
|
||
|
|
||
|
setActiveCamera(Camera[0]);
|
||
|
|
||
|
<span class="comment">// load the irrlicht engine logo</span>
|
||
|
IGUIImage *img =
|
||
|
env->addImage(driver->getTexture(<span class="stringliteral">"irrlichtlogo2.png"</span>),
|
||
|
core::position2d<s32>(10, driver->getScreenSize().Height - 128));
|
||
|
|
||
|
<span class="comment">// lock the logo's edges to the bottom left corner of the screen</span>
|
||
|
img->setAlignment(<a class="code" href="namespaceirr_1_1gui.html#a19eb5fb40e67f108cb16aba922ddaa2da4bb8a01452727274e18047a872da1809" title="Aligned to parent's top or left side (default)">EGUIA_UPPERLEFT</a>, <a class="code" href="namespaceirr_1_1gui.html#a19eb5fb40e67f108cb16aba922ddaa2da4bb8a01452727274e18047a872da1809" title="Aligned to parent's top or left side (default)">EGUIA_UPPERLEFT</a>,
|
||
|
<a class="code" href="namespaceirr_1_1gui.html#a19eb5fb40e67f108cb16aba922ddaa2da48b4d042b2d6cd63b876cef62c9cfb97" title="Aligned to parent's bottom or right side.">EGUIA_LOWERRIGHT</a>, <a class="code" href="namespaceirr_1_1gui.html#a19eb5fb40e67f108cb16aba922ddaa2da48b4d042b2d6cd63b876cef62c9cfb97" title="Aligned to parent's bottom or right side.">EGUIA_LOWERRIGHT</a>);
|
||
|
|
||
|
<span class="comment">// remember state so we notice when the window does lose the focus</span>
|
||
|
<span class="keywordtype">bool</span> hasFocus = Device->isWindowFocused();
|
||
|
|
||
|
<span class="comment">// draw everything</span>
|
||
|
|
||
|
<span class="keywordflow">while</span>(Device->run() && driver)
|
||
|
{
|
||
|
<span class="comment">// Catch focus changes (workaround until Irrlicht has events for this)</span>
|
||
|
<span class="keywordtype">bool</span> focused = Device->isWindowFocused();
|
||
|
<span class="keywordflow">if</span> ( hasFocus && !focused )
|
||
|
onKillFocus();
|
||
|
hasFocus = focused;
|
||
|
|
||
|
<span class="keywordflow">if</span> (Device->isWindowActive())
|
||
|
{
|
||
|
driver->beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, video::SColor(150,50,50,50));
|
||
|
|
||
|
smgr->drawAll();
|
||
|
env->drawAll();
|
||
|
|
||
|
driver->endScene();
|
||
|
|
||
|
<span class="comment">// update information about current frame-rate</span>
|
||
|
<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> str(L<span class="stringliteral">"FPS: "</span>);
|
||
|
str.append(<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(driver->getFPS()));
|
||
|
str += L<span class="stringliteral">" Tris: "</span>;
|
||
|
str.append(<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(driver->getPrimitiveCountDrawn()));
|
||
|
fpstext->setText(str.c_str());
|
||
|
|
||
|
<span class="comment">// update information about the active camera</span>
|
||
|
scene::ICameraSceneNode* cam = Device->getSceneManager()->getActiveCamera();
|
||
|
str = L<span class="stringliteral">"Pos: "</span>;
|
||
|
str.append(<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(cam->getPosition().X));
|
||
|
str += L<span class="stringliteral">" "</span>;
|
||
|
str.append(<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(cam->getPosition().Y));
|
||
|
str += L<span class="stringliteral">" "</span>;
|
||
|
str.append(<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(cam->getPosition().Z));
|
||
|
str += L<span class="stringliteral">" Tgt: "</span>;
|
||
|
str.append(<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(cam->getTarget().X));
|
||
|
str += L<span class="stringliteral">" "</span>;
|
||
|
str.append(<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(cam->getTarget().Y));
|
||
|
str += L<span class="stringliteral">" "</span>;
|
||
|
str.append(<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a>(cam->getTarget().Z));
|
||
|
postext->setText(str.c_str());
|
||
|
|
||
|
<span class="comment">// update the tool dialog</span>
|
||
|
updateToolBox();
|
||
|
}
|
||
|
<span class="keywordflow">else</span>
|
||
|
Device->yield();
|
||
|
}
|
||
|
|
||
|
Device->drop();
|
||
|
<span class="keywordflow">return</span> 0;
|
||
|
}
|
||
|
</pre></div> </div></div>
|
||
|
</div>
|
||
|
<div id="nav-path" class="navpath">
|
||
|
<ul>
|
||
|
<!-- window showing the filter options -->
|
||
|
<div id="MSearchSelectWindow"
|
||
|
onmouseover="return searchBox.OnSearchSelectShow()"
|
||
|
onmouseout="return searchBox.OnSearchSelectHide()"
|
||
|
onkeydown="return searchBox.OnSearchSelectKey(event)">
|
||
|
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark"> </span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark"> </span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark"> </span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark"> </span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark"> </span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark"> </span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark"> </span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark"> </span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark"> </span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark"> </span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark"> </span>Defines</a></div>
|
||
|
|
||
|
<!-- iframe showing the search results (closed by default) -->
|
||
|
<div id="MSearchResultsWindow">
|
||
|
<iframe src="javascript:void(0)" frameborder="0"
|
||
|
name="MSearchResults" id="MSearchResults">
|
||
|
</iframe>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<li class="footer">
|
||
|
<a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht
|
||
|
Engine</a> Documentation © 2003-2012 by Nikolaus Gebhardt. Generated on Tue Jan 19 2016 16:08:47 for Irrlicht 3D Engine by
|
||
|
<a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
</body>
|
||
|
</html>
|