diff options
Diffstat (limited to 'libraries/irrlicht-1.8/examples/18.SplitScreen/main.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/examples/18.SplitScreen/main.cpp | 244 |
1 files changed, 244 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/examples/18.SplitScreen/main.cpp b/libraries/irrlicht-1.8/examples/18.SplitScreen/main.cpp new file mode 100644 index 0000000..32266c5 --- /dev/null +++ b/libraries/irrlicht-1.8/examples/18.SplitScreen/main.cpp | |||
@@ -0,0 +1,244 @@ | |||
1 | /** Example 018 Splitscreen | ||
2 | |||
3 | A tutorial by Max Winkel. | ||
4 | |||
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, with 3 fixed cameras and one user-controlled. | ||
8 | |||
9 | Ok, let's start with the headers (I think there's | ||
10 | nothing to say about it) | ||
11 | */ | ||
12 | |||
13 | #include <irrlicht.h> | ||
14 | #include "driverChoice.h" | ||
15 | |||
16 | #ifdef _MSC_VER | ||
17 | #pragma comment(lib, "Irrlicht.lib") | ||
18 | #endif | ||
19 | |||
20 | //Namespaces for the engine | ||
21 | using namespace irr; | ||
22 | using namespace core; | ||
23 | using namespace video; | ||
24 | using namespace scene; | ||
25 | |||
26 | /* | ||
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. | ||
30 | */ | ||
31 | //Resolution | ||
32 | const int ResX=800; | ||
33 | const int ResY=600; | ||
34 | const bool fullScreen=false; | ||
35 | |||
36 | //Use SplitScreen? | ||
37 | bool SplitScreen=true; | ||
38 | |||
39 | /* | ||
40 | Now we need four pointers to our cameras which are created later: | ||
41 | */ | ||
42 | //cameras | ||
43 | ICameraSceneNode *camera[4]={0,0,0,0}; | ||
44 | /* | ||
45 | In our event-receiver we switch the SplitScreen-variable, | ||
46 | whenever the user press the S-key. All other events are sent | ||
47 | to the FPS camera. | ||
48 | */ | ||
49 | |||
50 | class MyEventReceiver : public IEventReceiver | ||
51 | { | ||
52 | public: | ||
53 | virtual bool OnEvent(const SEvent& event) | ||
54 | { | ||
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) | ||
58 | { | ||
59 | SplitScreen = !SplitScreen; | ||
60 | return true; | ||
61 | } | ||
62 | //Send all other events to camera4 | ||
63 | if (camera[3]) | ||
64 | return camera[3]->OnEvent(event); | ||
65 | return false; | ||
66 | } | ||
67 | }; | ||
68 | |||
69 | /* | ||
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. | ||
75 | */ | ||
76 | int main() | ||
77 | { | ||
78 | // ask user for driver | ||
79 | video::E_DRIVER_TYPE driverType=driverChoiceConsole(); | ||
80 | if (driverType==video::EDT_COUNT) | ||
81 | return 1; | ||
82 | |||
83 | //Instance of the EventReceiver | ||
84 | MyEventReceiver receiver; | ||
85 | |||
86 | //Initialise the engine | ||
87 | IrrlichtDevice *device = createDevice(driverType, | ||
88 | dimension2du(ResX,ResY), 32, fullScreen, | ||
89 | false, false, &receiver); | ||
90 | if (!device) | ||
91 | return 1; | ||
92 | |||
93 | ISceneManager *smgr = device->getSceneManager(); | ||
94 | IVideoDriver *driver = device->getVideoDriver(); | ||
95 | |||
96 | //Load model | ||
97 | IAnimatedMesh *model = smgr->getMesh("../../media/sydney.md2"); | ||
98 | if (!model) | ||
99 | return 1; | ||
100 | IAnimatedMeshSceneNode *model_node = smgr->addAnimatedMeshSceneNode(model); | ||
101 | //Load texture | ||
102 | if (model_node) | ||
103 | { | ||
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); | ||
109 | } | ||
110 | |||
111 | //Load map | ||
112 | device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3"); | ||
113 | IAnimatedMesh *map = smgr->getMesh("20kdm2.bsp"); | ||
114 | if (map) | ||
115 | { | ||
116 | ISceneNode *map_node = smgr->addOctreeSceneNode(map->getMesh(0)); | ||
117 | //Set position | ||
118 | map_node->setPosition(vector3df(-850,-220,-850)); | ||
119 | } | ||
120 | |||
121 | /* | ||
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 | ||
125 | user. | ||
126 | */ | ||
127 | // Create 3 fixed and one user-controlled cameras | ||
128 | //Front | ||
129 | camera[0] = smgr->addCameraSceneNode(0, vector3df(50,0,0), vector3df(0,0,0)); | ||
130 | //Top | ||
131 | camera[1] = smgr->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0)); | ||
132 | //Left | ||
133 | camera[2] = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0)); | ||
134 | //User-controlled | ||
135 | camera[3] = smgr->addCameraSceneNodeFPS(); | ||
136 | // don't start at sydney's position | ||
137 | if (camera[3]) | ||
138 | camera[3]->setPosition(core::vector3df(-50,0,-50)); | ||
139 | |||
140 | /* | ||
141 | Create a variable for counting the fps and hide the mouse: | ||
142 | */ | ||
143 | //Hide mouse | ||
144 | device->getCursorControl()->setVisible(false); | ||
145 | //We want to count the fps | ||
146 | int lastFPS = -1; | ||
147 | |||
148 | /* | ||
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) | ||
154 | |||
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 | ||
158 | - Render all objects | ||
159 | |||
160 | - If you have a GUI: | ||
161 | - Set the viewport the whole screen | ||
162 | - Display the GUI | ||
163 | - End scene | ||
164 | |||
165 | Sounds a little complicated, but you'll see it isn't: | ||
166 | */ | ||
167 | |||
168 | while(device->run()) | ||
169 | { | ||
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 | ||
174 | if (SplitScreen) | ||
175 | { | ||
176 | //Activate camera1 | ||
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)); | ||
180 | //Draw scene | ||
181 | smgr->drawAll(); | ||
182 | //Activate camera2 | ||
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)); | ||
186 | //Draw scene | ||
187 | smgr->drawAll(); | ||
188 | //Activate camera3 | ||
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)); | ||
192 | //Draw scene | ||
193 | smgr->drawAll(); | ||
194 | //Set viewport the last quarter (right bottom) | ||
195 | driver->setViewPort(rect<s32>(ResX/2,ResY/2,ResX,ResY)); | ||
196 | } | ||
197 | //Activate camera4 | ||
198 | smgr->setActiveCamera(camera[3]); | ||
199 | //Draw scene | ||
200 | smgr->drawAll(); | ||
201 | driver->endScene(); | ||
202 | |||
203 | /* | ||
204 | As you can probably see, the image is rendered for every | ||
205 | viewport separately. That means, that you'll loose much performance. | ||
206 | Ok, if you're asking "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 | ||
213 | |||
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 | ||
218 | |||
219 | If you didn't fully understand, just play around with the example | ||
220 | to check out what happens. | ||
221 | |||
222 | Now we just view the current fps and shut down the engine, | ||
223 | when the user wants to: | ||
224 | */ | ||
225 | //Get and show fps | ||
226 | if (driver->getFPS() != lastFPS) | ||
227 | { | ||
228 | lastFPS = driver->getFPS(); | ||
229 | core::stringw tmp = L"Irrlicht SplitScreen-Example (FPS: "; | ||
230 | tmp += lastFPS; | ||
231 | tmp += ")"; | ||
232 | device->setWindowCaption(tmp.c_str()); | ||
233 | } | ||
234 | } | ||
235 | //Delete device | ||
236 | device->drop(); | ||
237 | return 0; | ||
238 | } | ||
239 | /* | ||
240 | That's it! Just compile and play around with the program. | ||
241 | Note: With the S-Key you can switch between using splitscreen | ||
242 | and not. | ||
243 | **/ | ||
244 | |||