Sophie

Sophie

distrib > Mandriva > 2010.1 > x86_64 > media > contrib-release > by-pkgid > 58828b263d8f56d90ac336dea07a4586 > files > 749

irrlicht-doc-1.6.1-1mdv2010.1.x86_64.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Irrlicht Engine: Tutorial 18: Splitscreen</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<table class="irrlicht" >
  <tr valign="middle"> 
    <td><font size="2"><a class="qindex" href="index.html"><font color="#FFFFFF">Home</font></a> 
      | <a class="qindex" href="namespaces.html"><font color="#FFFFFF">Namespaces</font></a> 
      | <a class="qindex" href="hierarchy.html"><font color="#FFFFFF">Hierarchy</font></a> 
      | <a class="qindex" href="classes.html"><font color="#FFFFFF">Alphabetical 
      List</font></a> | <a class="qindex" href="annotated.html"><font color="#FFFFFF"> 
      Class list</font></a> | <a class="qindex" href="files.html"><font color="#FFFFFF">Files</font></a> 
      | <a class="qindex" href="namespacemembers.html"><font color="#FFFFFF"> 
      Namespace&nbsp;Members</font></a> | <a class="qindex" href="functions.html"><font color="#FFFFFF">Class 
      members</font></a> | <a class="qindex" href="globals.html"><font color="#FFFFFF">File 
      members</font></a> | <a class="qindex" href="pages.html"><font color="#FFFFFF">Tutorials</font></a></font> </td>
  </tr>
</table>
<!-- Generated by Doxygen 1.5.6 -->
<div class="contents">
<h1><a class="anchor" name="example018">Tutorial 18: Splitscreen </a></h1><div align="center">
<img src="018shot.jpg" alt="018shot.jpg">
</div>
 <p>
A tutorial by Max Winkel.<p>
In this tutorial we'll learn how to use splitscreen (e.g. for racing-games) with Irrlicht. We'll create a viewport divided into 4 parts, wtih 3 fixed cameras and one user-controlled.<p>
Ok, let's start with the headers (I think there's nothing to say about it) <div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>&gt;</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>

<span class="preprocessor">#ifdef _MSC_VER</span>
<span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, "Irrlicht.lib")</span>
<span class="preprocessor"></span><span class="preprocessor">#endif</span>
<span class="preprocessor"></span>
<span class="comment">//Namespaces for the engine</span>
<span class="keyword">using namespace </span>irr;
<span class="keyword">using namespace </span>core;
<span class="keyword">using namespace </span>video;
<span class="keyword">using namespace </span>scene;
</pre></div><p>
Now we'll define the resolution in a constant for use in initializing the device and setting up the viewport. In addition we set up a global variable saying splitscreen is active or not. <div class="fragment"><pre class="fragment"><span class="comment">//Resolution</span>
<span class="keyword">const</span> <span class="keywordtype">int</span> ResX=800;
<span class="keyword">const</span> <span class="keywordtype">int</span> ResY=600;
<span class="keyword">const</span> <span class="keywordtype">bool</span> fullScreen=<span class="keyword">false</span>;

<span class="comment">//Use SplitScreen?</span>
<span class="keywordtype">bool</span> SplitScreen=<span class="keyword">true</span>;
</pre></div><p>
Now we need four pointers to our cameras which are created later: <div class="fragment"><pre class="fragment"><span class="comment">//cameras</span>
ICameraSceneNode *camera[4]={0,0,0,0};
</pre></div><p>
In our event-receiver we switch the SplitScreen-variable, whenever the user press the S-key. All other events are sent to the FPS camera. <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&amp; event)
                {
                        <span class="comment">//Key S enables/disables SplitScreen</span>
                        <span class="keywordflow">if</span> (event.EventType == <a class="code" href="namespaceirr.html#c9eed96e06e85ce3c86fcbbbe9e48a0c6f90390f3147a1693e5e2e3422d6ca09" title="A key input event.">irr::EET_KEY_INPUT_EVENT</a> &amp;&amp;
                                event.KeyInput.Key == <a class="code" href="namespaceirr.html#54da2a0e231901735e3da1b0edf72eb3e52bafc112fc6c52f6b49cea42fa246e">KEY_KEY_S</a> &amp;&amp; event.KeyInput.PressedDown)
                        {
                                SplitScreen = !SplitScreen;
                                <span class="keywordflow">return</span> <span class="keyword">true</span>;
                        }
                        <span class="comment">//Send all other events to camera4</span>
                        <span class="keywordflow">if</span> (camera[3])
                                <span class="keywordflow">return</span> camera[3]-&gt;OnEvent(event);
                        <span class="keywordflow">return</span> <span class="keyword">false</span>;
                }
};
</pre></div><p>
Ok, now the main-function: First, we initialize the device, get the SourceManager and VideoDriver, load an animated mesh from .md2 and a map from .pk3. Because that's old stuff, I won't explain every step. Just take care of the maps position. <div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main()
{
        <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType;

        printf(<span class="stringliteral">"Please select the driver you want for this example:\n"</span>\
                <span class="stringliteral">" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"</span>\
                <span class="stringliteral">" (d) Software Renderer\n (e) Burning's Software Renderer\n"</span>\
                <span class="stringliteral">" (f) NullDevice\n (otherKey) exit\n\n"</span>);

        <span class="keywordtype">char</span> i;
        std::cin &gt;&gt; i;

        <span class="keywordflow">switch</span>(i)
        {
                <span class="keywordflow">case</span> <span class="charliteral">'a'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d04691ca314f9018f508dcf2c57dcaacec" title="Direct3D 9 device, only available on Win32 platforms.">video::EDT_DIRECT3D9</a>;<span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'b'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d08cc3807f6f28404f3424ad7e31b3142f" title="Direct3D8 device, only available on Win32 platforms.">video::EDT_DIRECT3D8</a>;<span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'c'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d02715182a79f1cb8e2826fd68a8150a53" title="OpenGL device, available on most platforms.">video::EDT_OPENGL</a>;   <span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'d'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d01598cd235a1a6bd052e2011b559e8995" title="The Irrlicht Engine Software renderer.">video::EDT_SOFTWARE</a>; <span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'e'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d0e85481da26159b967191ccc6de1e4a05" title="The Burning&amp;#39;s Software Renderer, an alternative software renderer.">video::EDT_BURNINGSVIDEO</a>;<span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'f'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d0cfdbd476cbfd4d05e72f9adffcc42210" title="Null driver, useful for applications to run the engine without visualisation.">video::EDT_NULL</a>;     <span class="keywordflow">break</span>;
                <span class="keywordflow">default</span>: <span class="keywordflow">return</span> 1;
        }

        <span class="comment">//Instance of the EventReceiver</span>
        MyEventReceiver receiver;

        <span class="comment">//Initialise the engine</span>
        IrrlichtDevice *device = <a class="code" href="namespaceirr.html#baf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the...">createDevice</a>(driverType,
                        <a class="code" href="namespaceirr_1_1core.html#d2e562e3219072e2f7fc7c2bba0ef0cb" title="Typedef for an unsigned integer dimension.">dimension2du</a>(ResX,ResY), 32, fullScreen,
                        <span class="keyword">false</span>, <span class="keyword">false</span>, &amp;receiver);
        <span class="keywordflow">if</span> (!device)
                <span class="keywordflow">return</span> 1;

        ISceneManager *smgr = device-&gt;getSceneManager();
        IVideoDriver *driver = device-&gt;getVideoDriver();

        <span class="comment">//Load model</span>
        IAnimatedMesh *model = smgr-&gt;getMesh(<span class="stringliteral">"../../media/sydney.md2"</span>);
        <span class="keywordflow">if</span> (!model)
                <span class="keywordflow">return</span> 1;
        IAnimatedMeshSceneNode *model_node = smgr-&gt;addAnimatedMeshSceneNode(model);
        <span class="comment">//Load texture</span>
        <span class="keywordflow">if</span> (model_node)
        {
                ITexture *texture = driver-&gt;getTexture(<span class="stringliteral">"../../media/sydney.bmp"</span>);
                model_node-&gt;setMaterialTexture(0,texture);
                model_node-&gt;setMD2Animation(<a class="code" href="namespaceirr_1_1scene.html#08d4a84966e1d2886d0d57e4acbb4f19f240ef944e6e257ec369f87053c756e8">scene::EMAT_RUN</a>);
                <span class="comment">//Disable lighting (we've got no light)</span>
                model_node-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#8a3bc00ae8137535b9fbc5f40add70d3cea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">EMF_LIGHTING</a>,<span class="keyword">false</span>);
        }

        <span class="comment">//Load map</span>
        device-&gt;getFileSystem()-&gt;addZipFileArchive(<span class="stringliteral">"../../media/map-20kdm2.pk3"</span>);
        IAnimatedMesh *map = smgr-&gt;getMesh(<span class="stringliteral">"20kdm2.bsp"</span>);
        <span class="keywordflow">if</span> (map)
        {
                ISceneNode *map_node = smgr-&gt;addOctTreeSceneNode(map-&gt;getMesh(0));
                <span class="comment">//Set position</span>
                map_node-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(-850,-220,-850));
        }
</pre></div><p>
Now we create our four cameras. One is looking at the model from the front, one from the top and one from the side. In addition there's a FPS-camera which can be controlled by the user. <div class="fragment"><pre class="fragment">        <span class="comment">// Create 3 fixed and one user-controlled cameras</span>
        <span class="comment">//Front</span>
        camera[0] = smgr-&gt;addCameraSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(50,0,0), <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,0,0));
        <span class="comment">//Top</span>
        camera[1] = smgr-&gt;addCameraSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,50,0), <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,0,0));
        <span class="comment">//Left</span>
        camera[2] = smgr-&gt;addCameraSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,0,50), <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">vector3df</a>(0,0,0));
        <span class="comment">//User-controlled</span>
        camera[3] = smgr-&gt;addCameraSceneNodeFPS();
        <span class="comment">// don't start at sydney's position</span>
        <span class="keywordflow">if</span> (camera[3])
                camera[3]-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-50,0,-50));
</pre></div><p>
Create a variable for counting the fps and hide the mouse: <div class="fragment"><pre class="fragment">        <span class="comment">//Hide mouse</span>
        device-&gt;getCursorControl()-&gt;setVisible(<span class="keyword">false</span>);
        <span class="comment">//We want to count the fps</span>
        <span class="keywordtype">int</span> lastFPS = -1;
</pre></div><p>
There wasn't much new stuff - till now! Only by defining four cameras, the game won't be splitscreen. To do this you need several steps:<ul>
<li>Set the viewport to the whole screen</li><li>Begin a new scene (Clear screen)</li></ul>
<p>
<ul>
<li>The following 3 steps are repeated for every viewport in the splitscreen<ul>
<li>Set the viewport to the area you wish</li><li>Activate the camera which should be "linked" with the viewport</li><li>Render all objects</li></ul>
</li></ul>
<p>
<ul>
<li>If you have a GUI:<ul>
<li>Set the viewport the whole screen</li><li>Display the GUI</li></ul>
</li><li>End scene</li></ul>
<p>
Sounds a little complicated, but you'll see it isn't: <div class="fragment"><pre class="fragment">        <span class="keywordflow">while</span>(device-&gt;run())
        {
                <span class="comment">//Set the viewpoint to the whole screen and begin scene</span>
                driver-&gt;setViewPort(rect&lt;s32&gt;(0,0,ResX,ResY));
                driver-&gt;beginScene(<span class="keyword">true</span>,<span class="keyword">true</span>,SColor(255,100,100,100));
                <span class="comment">//If SplitScreen is used</span>
                <span class="keywordflow">if</span> (SplitScreen)
                {
                        <span class="comment">//Activate camera1</span>
                        smgr-&gt;setActiveCamera(camera[0]);
                        <span class="comment">//Set viewpoint to the first quarter (left top)</span>
                        driver-&gt;setViewPort(rect&lt;s32&gt;(0,0,ResX/2,ResY/2));
                        <span class="comment">//Draw scene</span>
                        smgr-&gt;drawAll();
                        <span class="comment">//Activate camera2</span>
                        smgr-&gt;setActiveCamera(camera[1]);
                        <span class="comment">//Set viewpoint to the second quarter (right top)</span>
                        driver-&gt;setViewPort(rect&lt;s32&gt;(ResX/2,0,ResX,ResY/2));
                        <span class="comment">//Draw scene</span>
                        smgr-&gt;drawAll();
                        <span class="comment">//Activate camera3</span>
                        smgr-&gt;setActiveCamera(camera[2]);
                        <span class="comment">//Set viewpoint to the third quarter (left bottom)</span>
                        driver-&gt;setViewPort(rect&lt;s32&gt;(0,ResY/2,ResX/2,ResY));
                        <span class="comment">//Draw scene</span>
                        smgr-&gt;drawAll();
                        <span class="comment">//Set viewport the last quarter (right bottom)</span>
                        driver-&gt;setViewPort(rect&lt;s32&gt;(ResX/2,ResY/2,ResX,ResY));
                }
                <span class="comment">//Activate camera4</span>
                smgr-&gt;setActiveCamera(camera[3]);
                <span class="comment">//Draw scene</span>
                smgr-&gt;drawAll();
                driver-&gt;endScene();
</pre></div><p>
As you can probably see, the image is rendered for every viewport seperately. That means, that you'll loose much performance. Ok, if you're aksing "How do I have to set the viewport to get this or that screen?", don't panic. It's really easy: In the rect-function you define 4 coordinates:<ul>
<li>X-coordinate of the corner left top</li><li>Y-coordinate of the corner left top</li><li>X-coordinate of the corner right bottom</li><li>Y-coordinate of the corner right bottom</li></ul>
<p>
That means, if you want to split the screen into 2 viewports you would give the following coordinates:<ul>
<li>1st viewport: 0,0,ResX/2,ResY</li><li>2nd viewport: ResX/2,0,ResX,ResY</li></ul>
<p>
If you didn't fully understand, just play arround with the example to check out what happens.<p>
Now we just view the current fps and shut down the engine, when the user wants to: <div class="fragment"><pre class="fragment">                <span class="comment">//Get and show fps</span>
                <span class="keywordflow">if</span> (driver-&gt;getFPS() != lastFPS)
                {
                        lastFPS = driver-&gt;getFPS();
                        <a class="code" href="namespaceirr_1_1core.html#ef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> tmp = L<span class="stringliteral">"Irrlicht SplitScreen-Example (FPS: "</span>;
                        tmp += lastFPS;
                        tmp += <span class="stringliteral">")"</span>;
                        device-&gt;setWindowCaption(tmp.c_str());
                }
        }
        <span class="comment">//Delete device</span>
        device-&gt;drop();
        <span class="keywordflow">return</span> 0;
}
</pre></div><p>
That's it! Just compile and play around with the program. Note: With the S-Key you can switch between using splitscreen and not. </div>
<hr size="1">
<address style="align: right;">
<small> </small>
</address>
<table width="100%" border="0" cellspacing="0" cellpadding="2">
  <tr> 
    <td width="0"> <div align="left"><small><a href="http://irrlicht.sourceforge.net" target="_blank"><img src="irrlicht.png" alt="The Irrlicht Engine" align="middle" border=0 width=88 height=31></a></small></div></td>
    <td> <div align="left"><small><em><font size="2">The <a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht 
        Engine</a> Documentation &copy; 2003-2009 by Nikolaus Gebhardt. Generated 
        on Sun Jan 10 09:24:07 2010 by <a href="http://www.doxygen.org" target="_blank">Doxygen</a> 
        (1.5.6)</font></em></small></div></td>
  </tr>
</table>
<address style="align: right;">
</address>
</body>
</html>