1
/** Example 018 Splitscreen
3
A tutorial by Max Winkel.
5
In this tutorial we'll learn how to use splitscreen (e.g. for racing-games)
6
with Irrlicht. We'll create a viewport divided
7
into 4 parts, wtih 3 fixed cameras and one user-controlled.
9
Ok, let's start with the headers (I think there's
10
nothing to say about it)
14
#include "driverChoice.h"
17
#pragma comment(lib, "Irrlicht.lib")
20
//Namespaces for the engine
23
using namespace video;
24
using namespace scene;
27
Now we'll define the resolution in a constant for use in
28
initializing the device and setting up the viewport. In addition
29
we set up a global variable saying splitscreen is active or not.
34
const bool fullScreen=false;
37
bool SplitScreen=true;
40
Now we need four pointers to our cameras which are created later:
43
ICameraSceneNode *camera[4]={0,0,0,0};
45
In our event-receiver we switch the SplitScreen-variable,
46
whenever the user press the S-key. All other events are sent
50
class MyEventReceiver : public IEventReceiver
53
virtual bool OnEvent(const SEvent& event)
55
//Key S enables/disables SplitScreen
56
if (event.EventType == irr::EET_KEY_INPUT_EVENT &&
57
event.KeyInput.Key == KEY_KEY_S && event.KeyInput.PressedDown)
59
SplitScreen = !SplitScreen;
62
//Send all other events to camera4
64
return camera[3]->OnEvent(event);
70
Ok, now the main-function:
71
First, we initialize the device, get the SourceManager and
72
VideoDriver, load an animated mesh from .md2 and a map from
73
.pk3. Because that's old stuff, I won't explain every step.
74
Just take care of the maps position.
78
// ask user for driver
79
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
80
if (driverType==video::EDT_COUNT)
83
//Instance of the EventReceiver
84
MyEventReceiver receiver;
86
//Initialise the engine
87
IrrlichtDevice *device = createDevice(driverType,
88
dimension2du(ResX,ResY), 32, fullScreen,
89
false, false, &receiver);
93
ISceneManager *smgr = device->getSceneManager();
94
IVideoDriver *driver = device->getVideoDriver();
97
IAnimatedMesh *model = smgr->getMesh("../../media/sydney.md2");
100
IAnimatedMeshSceneNode *model_node = smgr->addAnimatedMeshSceneNode(model);
104
ITexture *texture = driver->getTexture("../../media/sydney.bmp");
105
model_node->setMaterialTexture(0,texture);
106
model_node->setMD2Animation(scene::EMAT_RUN);
107
//Disable lighting (we've got no light)
108
model_node->setMaterialFlag(EMF_LIGHTING,false);
112
device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
113
IAnimatedMesh *map = smgr->getMesh("20kdm2.bsp");
116
ISceneNode *map_node = smgr->addOctreeSceneNode(map->getMesh(0));
118
map_node->setPosition(vector3df(-850,-220,-850));
122
Now we create our four cameras. One is looking at the model
123
from the front, one from the top and one from the side. In
124
addition there's a FPS-camera which can be controlled by the
127
// Create 3 fixed and one user-controlled cameras
129
camera[0] = smgr->addCameraSceneNode(0, vector3df(50,0,0), vector3df(0,0,0));
131
camera[1] = smgr->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0));
133
camera[2] = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0));
135
camera[3] = smgr->addCameraSceneNodeFPS();
136
// don't start at sydney's position
138
camera[3]->setPosition(core::vector3df(-50,0,-50));
141
Create a variable for counting the fps and hide the mouse:
144
device->getCursorControl()->setVisible(false);
145
//We want to count the fps
149
There wasn't much new stuff - till now!
150
Only by defining four cameras, the game won't be splitscreen.
151
To do this you need several steps:
152
- Set the viewport to the whole screen
153
- Begin a new scene (Clear screen)
155
- The following 3 steps are repeated for every viewport in the splitscreen
156
- Set the viewport to the area you wish
157
- Activate the camera which should be "linked" with the viewport
161
- Set the viewport the whole screen
165
Sounds a little complicated, but you'll see it isn't:
170
//Set the viewpoint to the whole screen and begin scene
171
driver->setViewPort(rect<s32>(0,0,ResX,ResY));
172
driver->beginScene(true,true,SColor(255,100,100,100));
173
//If SplitScreen is used
177
smgr->setActiveCamera(camera[0]);
178
//Set viewpoint to the first quarter (left top)
179
driver->setViewPort(rect<s32>(0,0,ResX/2,ResY/2));
183
smgr->setActiveCamera(camera[1]);
184
//Set viewpoint to the second quarter (right top)
185
driver->setViewPort(rect<s32>(ResX/2,0,ResX,ResY/2));
189
smgr->setActiveCamera(camera[2]);
190
//Set viewpoint to the third quarter (left bottom)
191
driver->setViewPort(rect<s32>(0,ResY/2,ResX/2,ResY));
194
//Set viewport the last quarter (right bottom)
195
driver->setViewPort(rect<s32>(ResX/2,ResY/2,ResX,ResY));
198
smgr->setActiveCamera(camera[3]);
204
As you can probably see, the image is rendered for every
205
viewport seperately. That means, that you'll loose much performance.
206
Ok, if you're aksing "How do I have to set the viewport
207
to get this or that screen?", don't panic. It's really
208
easy: In the rect-function you define 4 coordinates:
209
- X-coordinate of the corner left top
210
- Y-coordinate of the corner left top
211
- X-coordinate of the corner right bottom
212
- Y-coordinate of the corner right bottom
214
That means, if you want to split the screen into 2 viewports
215
you would give the following coordinates:
216
- 1st viewport: 0,0,ResX/2,ResY
217
- 2nd viewport: ResX/2,0,ResX,ResY
219
If you didn't fully understand, just play arround with the example
220
to check out what happens.
222
Now we just view the current fps and shut down the engine,
223
when the user wants to:
226
if (driver->getFPS() != lastFPS)
228
lastFPS = driver->getFPS();
229
core::stringw tmp = L"Irrlicht SplitScreen-Example (FPS: ";
232
device->setWindowCaption(tmp.c_str());
240
That's it! Just compile and play around with the program.
241
Note: With the S-Key you can switch between using splitscreen