1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
|
<!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 14: Win32 Window</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('example014.html','');
</script>
<div id="doc-content">
<div class="header">
<div class="headertitle">
<div class="title">Tutorial 14: Win32 Window </div> </div>
</div>
<div class="contents">
<div class="textblock"><div class="image">
<img src="014shot.jpg" alt="014shot.jpg"/>
</div>
<p>This example only runs under MS Windows and demonstrates that Irrlicht can render inside a win32 window. MFC and .NET Windows.Forms windows are possible, too.</p>
<p>In the beginning, we create a windows window using the windows API. I'm not going to explain this code, because it is windows specific. See the MSDN or a windows book for details. </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">#ifndef _IRR_WINDOWS_</span>
<span class="preprocessor"></span><span class="preprocessor">#error Windows only example</span>
<span class="preprocessor"></span><span class="preprocessor">#else</span>
<span class="preprocessor"></span><span class="preprocessor">#include <windows.h></span> <span class="comment">// this example only runs with windows</span>
<span class="preprocessor">#include <iostream></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="preprocessor">#pragma comment(lib, "irrlicht.lib")</span>
<span class="preprocessor"></span>
HWND hOKButton;
HWND hWnd;
<span class="keyword">static</span> LRESULT CALLBACK CustomWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
<span class="keywordflow">switch</span> (message)
{
<span class="keywordflow">case</span> WM_COMMAND:
{
HWND hwndCtl = (HWND)lParam;
<span class="keywordtype">int</span> code = HIWORD(wParam);
<span class="keywordflow">if</span> (hwndCtl == hOKButton)
{
DestroyWindow(hWnd);
PostQuitMessage(0);
<span class="keywordflow">return</span> 0;
}
}
<span class="keywordflow">break</span>;
<span class="keywordflow">case</span> WM_DESTROY:
PostQuitMessage(0);
<span class="keywordflow">return</span> 0;
}
<span class="keywordflow">return</span> DefWindowProc(hWnd, message, wParam, lParam);
}
</pre></div><p>Now ask for the driver and create the Windows specific window. </p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main()
{
<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;
printf(<span class="stringliteral">"Select the render window (some dead window may exist too):\n"</span>\
<span class="stringliteral">" (a) Window with button (via CreationParam)\n"</span>\
<span class="stringliteral">" (b) Window with button (via beginScene)\n"</span>\
<span class="stringliteral">" (c) Own Irrlicht window (default behavior)\n"</span>\
<span class="stringliteral">" (otherKey) exit\n\n"</span>);
<span class="keywordtype">char</span> key;
std::cin >> key;
<span class="keywordflow">if</span> (key != <span class="charliteral">'a'</span> && key != <span class="charliteral">'b'</span> && key != <span class="charliteral">'c'</span>)
<span class="keywordflow">return</span> 1;
HINSTANCE hInstance = 0;
<span class="comment">// create dialog</span>
<span class="keyword">const</span> <span class="keywordtype">char</span>* Win32ClassName = <span class="stringliteral">"CIrrlichtWindowsTestDialog"</span>;
WNDCLASSEX wcex;
wcex.cbSize = <span class="keyword">sizeof</span>(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)CustomWndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = DLGWINDOWEXTRA;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wcex.lpszMenuName = 0;
wcex.lpszClassName = Win32ClassName;
wcex.hIconSm = 0;
RegisterClassEx(&wcex);
DWORD style = WS_SYSMENU | WS_BORDER | WS_CAPTION |
WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX;
<span class="keywordtype">int</span> windowWidth = 440;
<span class="keywordtype">int</span> windowHeight = 380;
hWnd = CreateWindow( Win32ClassName, <span class="stringliteral">"Irrlicht Win32 window example"</span>,
style, 100, 100, windowWidth, windowHeight,
NULL, NULL, hInstance, NULL);
RECT clientRect;
GetClientRect(hWnd, &clientRect);
windowWidth = clientRect.right;
windowHeight = clientRect.bottom;
<span class="comment">// create ok button</span>
hOKButton = CreateWindow(<span class="stringliteral">"BUTTON"</span>, <span class="stringliteral">"OK - Close"</span>, WS_CHILD | WS_VISIBLE | BS_TEXT,
windowWidth - 160, windowHeight - 40, 150, 30, hWnd, NULL, hInstance, NULL);
<span class="comment">// create some text</span>
CreateWindow(<span class="stringliteral">"STATIC"</span>, <span class="stringliteral">"This is Irrlicht running inside a standard Win32 window.\n"</span>\
<span class="stringliteral">"Also mixing with MFC and .NET Windows.Forms is possible."</span>,
WS_CHILD | WS_VISIBLE, 20, 20, 400, 40, hWnd, NULL, hInstance, NULL);
<span class="comment">// create window to put irrlicht in</span>
HWND hIrrlichtWindow = CreateWindow(<span class="stringliteral">"BUTTON"</span>, <span class="stringliteral">""</span>,
WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
50, 80, 320, 220, hWnd, NULL, hInstance, NULL);
video::SExposedVideoData videodata((key==<span class="charliteral">'b'</span>)?hIrrlichtWindow:0);
</pre></div><p>So now that we have some window, we can create an Irrlicht device inside of it. We use Irrlicht createEx() function for this. We only need the handle (HWND) to that window, set it as windowsID parameter and start up the engine as usual. That's it. </p>
<div class="fragment"><pre class="fragment"> <span class="comment">// create irrlicht device in the button window</span>
<a class="code" href="structirr_1_1_s_irrlicht_creation_parameters.html" title="Structure for holding Irrlicht Device creation parameters.">irr::SIrrlichtCreationParameters</a> param;
param.<a class="code" href="structirr_1_1_s_irrlicht_creation_parameters.html#a1ea2f50c3b3a8eed6602a1a86e1cdf82" title="Type of video driver used to render graphics.">DriverType</a> = driverType;
<span class="keywordflow">if</span> (key==<span class="charliteral">'a'</span>)
param.<a class="code" href="structirr_1_1_s_irrlicht_creation_parameters.html#af287810d910a23f8f7db98cef87b6eae" title="Window Id.">WindowId</a> = <span class="keyword">reinterpret_cast<</span><span class="keywordtype">void</span>*<span class="keyword">></span>(hIrrlichtWindow);
<a class="code" href="classirr_1_1_irrlicht_device.html" title="The Irrlicht device. You can create it with createDevice() or createDeviceEx().">irr::IrrlichtDevice</a>* device = <a class="code" href="namespaceirr.html#ac83a30d674204dcb94d70f849e9b4a62" title="Creates an Irrlicht device with the option to specify advanced parameters.">irr::createDeviceEx</a>(param);
<span class="keywordflow">if</span> (!device)
<span class="keywordflow">return</span> 1;
<span class="comment">// setup a simple 3d scene</span>
<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html" title="The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.">irr::scene::ISceneManager</a>* smgr = device-><a class="code" href="classirr_1_1_irrlicht_device.html#a891b503ff4d5041296d88f23f97d7b3d" title="Provides access to the scene manager.">getSceneManager</a>();
video::IVideoDriver* driver = device-><a class="code" href="classirr_1_1_irrlicht_device.html#ada90707ba5c645d47e000e4e0f87c4c4" title="Provides access to the video driver for drawing 3d and 2d geometry.">getVideoDriver</a>();
<span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0a2715182a79f1cb8e2826fd68a8150a53" title="OpenGL device, available on most platforms.">video::EDT_OPENGL</a>)
{
HDC HDc=GetDC(hIrrlichtWindow);
PIXELFORMATDESCRIPTOR pfd={0};
pfd.nSize=<span class="keyword">sizeof</span>(PIXELFORMATDESCRIPTOR);
<span class="keywordtype">int</span> pf = GetPixelFormat(HDc);
DescribePixelFormat(HDc, pf, <span class="keyword">sizeof</span>(PIXELFORMATDESCRIPTOR), &pfd);
pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.cDepthBits=16;
pf = ChoosePixelFormat(HDc, &pfd);
SetPixelFormat(HDc, pf, &pfd);
videodata.OpenGLWin32.HDc = HDc;
videodata.OpenGLWin32.HRc=wglCreateContext(HDc);
wglShareLists((HGLRC)driver->getExposedVideoData().OpenGLWin32.HRc, (HGLRC)videodata.OpenGLWin32.HRc);
}
scene::ICameraSceneNode* cam = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#afc3733849319078d5d22d94f58c7d1f2" title="Adds a camera scene node to the scene graph and sets it as active camera.">addCameraSceneNode</a>();
cam->setTarget(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0,0));
scene::ISceneNodeAnimator* anim =
smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a2e49ff49bc9e88e8ecf3d681354e1ab6" title="Creates a fly circle animator, which lets the attached scene node fly around a center.">createFlyCircleAnimator</a>(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,15,0), 30.0f);
cam->addAnimator(anim);
anim->drop();
scene::ISceneNode* cube = smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a23d1328c68b1585f613108f386fabc1c" title="Adds a cube scene node.">addCubeSceneNode</a>(20);
cube->setMaterialTexture(0, driver->getTexture(<span class="stringliteral">"../../media/wall.bmp"</span>));
cube->setMaterialTexture(1, driver->getTexture(<span class="stringliteral">"../../media/water.jpg"</span>));
cube->setMaterialFlag( <a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, <span class="keyword">false</span> );
cube->setMaterialType( <a class="code" href="namespaceirr_1_1video.html#ac8e9b6c66f7cebabd1a6d30cbc5430f1ad8574343353ed8ade6e78bc04d64b6ae" title="A reflecting material with an optional non reflecting texture layer.">video::EMT_REFLECTION_2_LAYER</a> );
smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a2b08b9f20ec62faeffc02b9fed9fd683" title="Adds a skybox scene node to the scene graph.">addSkyBoxSceneNode</a>(
driver->getTexture(<span class="stringliteral">"../../media/irrlicht2_up.jpg"</span>),
driver->getTexture(<span class="stringliteral">"../../media/irrlicht2_dn.jpg"</span>),
driver->getTexture(<span class="stringliteral">"../../media/irrlicht2_lf.jpg"</span>),
driver->getTexture(<span class="stringliteral">"../../media/irrlicht2_rt.jpg"</span>),
driver->getTexture(<span class="stringliteral">"../../media/irrlicht2_ft.jpg"</span>),
driver->getTexture(<span class="stringliteral">"../../media/irrlicht2_bk.jpg"</span>));
<span class="comment">// show and execute dialog</span>
ShowWindow(hWnd , SW_SHOW);
UpdateWindow(hWnd);
<span class="comment">// do message queue</span>
</pre></div><p>Now the only thing missing is the drawing loop using IrrlichtDevice::run(). We do this as usual. But instead of this, there is another possibility: You can also simply use your own message loop using GetMessage, DispatchMessage and whatever. Calling Device->run() will cause Irrlicht to dispatch messages internally too. You need not call Device->run() if you want to do your own message dispatching loop, but Irrlicht will not be able to fetch user input then and you have to do it on your own using the window messages, DirectInput, or whatever. </p>
<div class="fragment"><pre class="fragment"> <span class="keywordflow">while</span> (device-><a class="code" href="classirr_1_1_irrlicht_device.html#a0489f8151dc43f6f41503ffb5a160b35" title="Runs the device.">run</a>())
{
driver->beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, 0, videodata);
smgr-><a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a04240262904667c821bd9de5e5fd9b02" title="Draws all the scene nodes.">drawAll</a>();
driver->endScene();
}
</pre></div><p>The alternative, own message dispatching loop without Device->run() would look like this: </p>
<div class="fragment"><pre class="fragment"></pre></div><p> MSG msg; while (true) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg);</p>
<p>if (msg.message == WM_QUIT) break; }</p>
<p>advance virtual time device->getTimer()->tick();</p>
<p>draw engine picture driver->beginScene(true, true, 0, (key=='c')?hIrrlichtWindow:0); smgr->drawAll(); driver->endScene(); } </p>
<div class="fragment"><pre class="fragment"> device-><a class="code" href="classirr_1_1_irrlicht_device.html#a08c97937e0f60f98d443b397a7c60e18" title="Notifies the device that it should close itself.">closeDevice</a>();
device-><a class="code" href="classirr_1_1_i_reference_counted.html#afb169a857e0d2cdb96b8821cb9bff17a" title="Drops the object. Decrements the reference counter by one.">drop</a>();
<span class="keywordflow">return</span> 0;
}
<span class="preprocessor">#endif // if windows</span>
</pre></div><p>That's it, Irrlicht now runs in your own windows window. </p>
</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 Sun Nov 17 2013 20:18:41 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>
|