irrlicht v1.6 例程18 Splitscreen
/** Example 018 Splitscreen, U( a# q, @( S' f1 ]( p
作者:Max Winkel." `9 ?( W; K' V1 x8 \
譯:小時(shí)候可靚了(履霜堅(jiān)冰)2 m! C! N# J2 i6 a2 Z! Q
0 U2 D4 U: U% J1 E5 N! a0 L4 q& x
這個(gè)例程中我們將學(xué)習(xí)怎么使用irrlicht中的分屏(比如在賽車類游戲中)& ~$ M; ]8 f. _4 {
我們將創(chuàng)建一個(gè)被分為4個(gè)部分的視口,有3個(gè)固定攝相機(jī)和一個(gè)用戶可以控制的攝相機(jī)4 N% L! s9 [( l# n
好,讓們從頭文件開始吧(我想沒有再多說(shuō)的必要了)3 C9 |* C8 P! X
*/
#include <irrlicht.h>
#include <iostream>
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
) h- x" R- L6 B4 b6 L
//引擎命名空間! [" B6 k9 Y2 J1 @/ K& {
using namespace irr;
using namespace core;
using namespace video;6 n$ L6 u6 X???: {0 M+ Z
using namespace scene;, z+ I& c, e- O- n# `4 n??z
/*& N' H5 g8 W) U
現(xiàn)在我們將定義用于初始化設(shè)備分辨率常量,另外我們設(shè)置一個(gè)全局變量用于決定分屏是否激活
*/6 ~% ~+ ]& M. k! o??F) C
const int ResX=800;
const int ResY=600;3 U- b& o1 j$ c1 G- D! C$ B& ~
const bool fullScreen=false;
@6 A
//是否使用分屏
bool SplitScreen=true;# p: x* k' {* s
% A% x/ d* j5 k2 j* ~& G7 ?8 y
/*
現(xiàn)在我們需要4個(gè)點(diǎn)來(lái)設(shè)定即將要?jiǎng)?chuàng)建攝相機(jī)的位置。( s" N??n( |; y
*/
//攝相機(jī)
ICameraSceneNode *camera[4]={0,0,0,0};4 L/ N7 C" \1 V. Z& u5 i# r??L
/*
在我們的事件接收器中,當(dāng)用戶按下S鍵的時(shí)候,我們切換分屏變量,所有的其它事件則交給FPS攝相機(jī)。1 j3 Y/ v. l' T- e; L+ o! |, @
*/
class MyEventReceiver : public IEventReceiver
{6 K/ S* |" k8 x( ~% D2 M
? ? ? ? public:- n7 V0 Y8 b! x??@8 m6 _
? ? ? ? ? ? ? ? virtual bool OnEvent(const SEvent& event)- w$ y# T. E8 T3 Q( {??k& H, W
? ? ? ? ? ? ? ? {! I" S% Z$ C( o, R8 \7 a
????????????????????????
?? //S鍵? ?啟用/禁用分屏
?? if (event.EventType == irr::EET_KEY_INPUT_EVENT &&
? event.KeyInput.Key == KEY_KEY_S && event.KeyInput.PressedDown)6 I- U6 C) b+ g- W9 X5 J
? ? ? ? ? ? ? ? ? ? ? ? {
????????????????????????? SplitScreen = !SplitScreen;
?????????????????????????????? return true;) {8 R7 A+ e. t4 W: B* [% _4 ???O
? ? ? ? ? ? ? ? ? ? ? ? }??????????????????? 5 X) j" _: i) a& h# [% L7 j
? ? ? ? ? ? ? ? ? ? ? ? //發(fā)送其它所有的事件給第4個(gè)攝相機(jī)! F; ?# r8 W; f! F
? ? ? ? ? ? ? ? ? ? ? ? if (camera[3])# p& Q7 j??h+ z+ Y% D2 N' c
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return camera[3]->OnEvent(event);
????????????????? return false;
??????????? }2 z6 G- w+ `$ ?3 _& z( H4 y
};
F8 H
/*
好,現(xiàn)在看Main函數(shù)
首先,我們初始化設(shè)備,取得資源管理器和圖形驅(qū)動(dòng)。從md2中加載一個(gè)動(dòng)畫模型,; K6 F* ^9 F% a7 K5 `??z5 [
從pk3中加載一個(gè)地圖。因?yàn)檫@是先前使用過的東西,我就不逐步解釋了。
只關(guān)心地圖的位置
*// u0 X6 N; b) L8 ?& T8 q??d
int main()5 l& p* P3 m+ i+ s* D
{
??? video::E_DRIVER_TYPE driverType;, j! ]2 a8 ?# y; q
1 _% O( A/ n- F
? ? ? ? printf("Please select the driver you want for this example:\n"\6 T??a* Y. ~& B! P+ w8 x??X
? ? ? ? ? ? ? ? " (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
?????????? " (d) Software Renderer\n (e) Burning's Software Renderer\n"\
???????? " (f) NullDevice\n (otherKey) exit\n\n");% m5 @2 @) }! [& a! e
??????? char i;+ w- b/ X6 l, q/ J
? ? ? ? std::cin >> i;$ P' `* _; @$ y% h$ G??M??{
??h: H0 y/ f' _! Y/ L8 T
? ? ? ? switch(i)2 Q8 ^& t5 h) x, {, e
? ? ? ? {* U5 `: B1 y" h/ K* O1 a# Y) }
? ? ? ? ? ? ? ? case 'a': driverType = video::EDT_DIRECT3D9;break;
???????????? ?? case 'b': driverType = video::EDT_DIRECT3D8;break;4 Q, {' \5 B1 a9 d3 U0 l4 u* q
? ? ? ? ? ? ? ? case 'c': driverType = video::EDT_OPENGL;? ?break;9 D8 t9 P2 U; _/ S6 ~1 Z7 e
? ? ? ? ? ? ? ? case 'd': driverType = video::EDT_SOFTWARE; break;
?????????????? case 'e': driverType = video::EDT_BURNINGSVIDEO;break;" ^7 W# ^, u( p
? ? ? ? ? ? ? ? case 'f': driverType = video::EDT_NULL;? ???break;
??????????? default: return 1;
????? ?? }
m0 I: K5 O" ]8 w
????????
???? //實(shí)例化事件接收器1 i, i# a# j/ Y! f3 ?
? ? ? ? MyEventReceiver receiver;$ y/ I7 ]* Z! R9 _8 x
???? //初始化引擎
??? IrrlichtDevice *device = createDevice(driverType,1 O- Y# K% x- s6 u
? ? ? ? ? ? ? ? ? ? ? ? dimension2du(ResX,ResY), 32, fullScreen,
????????????????????? false, false, &receiver);
??? if (!device)
????????? return 1;
- i- c
? ? ? ? ISceneManager *smgr = device->getSceneManager();
???? IVideoDriver *driver = device->getVideoDriver();
???? //加載模型
????? IAnimatedMesh *model = smgr->getMesh("../../media/sydney.md2");
???? if (!model)
????????????? return 1;: }' k2 L5 J, c6 F7 O% ]8 i0 ]
? ? ? ? IAnimatedMeshSceneNode *model_node = smgr->addAnimatedMeshSceneNode(model);
?????? //加載紋理
???? if (model_node): H0 m7 `2 H" V
? ? ? ? {
??????????? ITexture *texture = driver->getTexture("../../media/sydney.bmp");2 _2 O% I7 [$ R??k??V3 P2 w1 f
? ? ? ? ? ? ? ? model_node->setMaterialTexture(0,texture);' G" R+ T6 c" o1 m+ i! w+ v
? ? ? ? ? ? ? ? model_node->setMD2Animation(scene::EMAT_RUN);
??????????? //禁用光照. W/ B- {; T$ @
? ? ? ? ? ? ? ? model_node->setMaterialFlag(EMF_LIGHTING,false);
?????? }
+ A??I5 H
? ? ? ? //加載地圖/ n. Y1 n. e??f& e+ F
? ? ? ? device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");# R* @8 U1 U" t' ]' r$ `
? ? ? ? IAnimatedMesh *map = smgr->getMesh("20kdm2.bsp");; N8 o* Q??l# `$ s/ [
? ? ? ? if (map)
????? {
??????????? ISceneNode *map_node = smgr->addOctTreeSceneNode(map->getMesh(0));
???????????? //設(shè)置位置
??????????? map_node->setPosition(vector3df(-850,-220,-850));
?????? }+ o7 A! v% `, w% |9 S5 t, i- C& O
8 a; x/ ?7 u1 ~/ s& D+ d
/*??D: g' p+ ?2 O4 A) Y9 y
現(xiàn)在我們建倉(cāng)我們的4個(gè)攝相機(jī),一個(gè)用于從前面看模型,
一個(gè)用于從上往下看模型,另一個(gè)從側(cè)面看。! l* S: q3 c- }0 `" f! `* O* T+ O
另外,我們還創(chuàng)建一個(gè)FPS攝相機(jī),用來(lái)讓用戶操作# a. B1 p??@2 V5 V
*/7 ]* h# T% z" {- ?
? ? ? ? //創(chuàng)建3個(gè)固定的攝相機(jī)
????? //前% T' P) p7 n! E( z6 O5 v3 V" Q
? ? ? ? camera[0] = smgr->addCameraSceneNode(0, vector3df(50,0,0), vector3df(0,0,0));
?????? //上
?????? camera[1] = smgr->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0));
?????? //左0 p7 W# @9 D% _+ z9 g
? ? ? ? camera[2] = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0));8 \% N* b4 a* Z$ ~# b! b
? ? ? ? //用戶控制的
??????? camera[3] = smgr->addCameraSceneNodeFPS();$ M) P* {* q7 ?/ `$ M0 \' M
? ? ? ? //不要在sydney的位置開始' {* T" B9 d8 _) `
? ? ? ? if (camera[3])
?????????????? camera[3]->setPosition(core::vector3df(-50,0,-50));( d' z% ]# M$ `) T8 n: w+ \
! Z- G" d! p??u, ?0 Q) X
/*7 {* g9 ]6 F% `/ n
//創(chuàng)建用于記錄幀數(shù)的變量和隱藏鼠標(biāo)4 |9 _. ?. |4 G??Y" h
*/% O, d( U+ j! w7 G0 i' F
? ? ? ? //隱藏鼠標(biāo)
??????? device->getCursorControl()->setVisible(false);
?????? //幀數(shù)記錄
??????? int lastFPS = -1;
/*! R2 c4 u6 B2 [! @
到現(xiàn)在還沒出現(xiàn)什么新的內(nèi)容
僅是定義我們的4個(gè)攝相機(jī),那游戲畫面不會(huì)出現(xiàn)分屏效果。
為了實(shí)現(xiàn)這個(gè)目標(biāo),你需要以下幾步; r' S: p: j4 i, a/ A6 w
? ?? ? 設(shè)置整個(gè)屏幕的視口
???????? 開始一個(gè)新的場(chǎng)景(清除屏幕)
???????? 以下3步是分屏中的每個(gè)視口都要重復(fù)的7 r* N# Y( k* _& h7 q% b. J. F
? ? ? ?? ?? ? 設(shè)置視口到你想看的區(qū)域
???????????????激活攝相機(jī),使它和視口“連接”& P8 i8 j; D; l( I/ P
? ? ? ? ? ? ? ?? ?渲染所有物體2 Z5 [3 X( `9 D6 C
???如果你有一個(gè)GUI. R# h+ N$ U# ]0 m* y8 m
? ?? ?設(shè)置視口到整個(gè)屏幕5 F7 |4 G$ h2 C; `% }
? ? ? ?? ?顯示GUI& ]6 J9 N8 Z- d9 E6 V
??結(jié)束場(chǎng)景
?z" E0 v+ R5 g9 q8 k
聽起來(lái)好像有點(diǎn)復(fù)雜,但你看了就明白了
*/
?????? while(device->run())
?????? {
?????????????? //設(shè)置整個(gè)場(chǎng)景的視口并開始繪制
??????????? driver->setViewPort(rect<s32>(0,0,ResX,ResY));
????????????? driver->beginScene(true,true,SColor(255,100,100,100));& J- i$ o; T. w: m' \# [
? ? ? ? ? ? ? ? //如果分屏被啟動(dòng)
??????????? if (SplitScreen) //還記得這個(gè)變量嗎?前面定義過的; K/ y2 c& y' C( }/ Y, U9 }
? ? ? ? ? ? ? ? {) h7 P* c( C2 }) y
? ? ? ? ? ? ? ? ? ? ? ? //Activate camera1+ w: V3 }3 Q* ?! `: v
? ? ? ? ? ? ? ? ? ? ? ? //激活1號(hào)攝相機(jī)2 e8 V' M' f8 k6 l
? ? ? ? ? ? ? ? ? ? ? ? smgr->setActiveCamera(camera[0]);
???????????????????? //Set viewpoint to the first quarter (left top)
?????????????????????? //設(shè)置視口到左上角
??????????????????? driver->setViewPort(rect<s32>(0,0,ResX/2,ResY/2));) K: ?. W# x+ ~9 i! ^
? ? ? ? ? ? ? ? ? ? ? ? //Draw scene
?????????????????? //繪制場(chǎng)景
????????????????????? smgr->drawAll();2 l% L, Z% V1 b' W+ x
? ? ? ? ? ? ? ? ? ? ? ? //Activate camera22 V??\; o: @7 M: g* X
? ? ? ? ? ? ? ? ? ? ? ? //激活2號(hào)攝相機(jī)
????????????????? smgr->setActiveCamera(camera[1]);
???????????????????? //Set viewpoint to the second quarter (right top)
???????????????????? //設(shè)置視口到右上角% g' N1 d! x3 N$ f7 o+ C- }
? ? ? ? ? ? ? ? ? ? ? ? driver->setViewPort(rect<s32>(ResX/2,0,ResX,ResY/2));
???????????????????? //Draw scene
??????????????????? //繪制場(chǎng)景5 x7 L: `6 k& E; x, ?' k" u
? ? ? ? ? ? ? ? ? ? ? ? smgr->drawAll();
????????????????????? //Activate camera3
????????????????????? //激活3號(hào)攝相機(jī)' x% S( E( B$ f5 H# Y4 o& l
? ? ? ? ? ? ? ? ? ? ? ? smgr->setActiveCamera(camera[2]);! c# c0 u& v% O??I1 ^& F
? ? ? ? ? ? ? ? ? ? ? ? //Set viewpoint to the third quarter (left bottom)' O3 M, t5 u. O3 ^8 g" O8 G% z
? ? ? ? ? ? ? ? ? ? ? ? //設(shè)置視口到左下角
????????????????????? driver->setViewPort(rect<s32>(0,ResY/2,ResX/2,ResY));
??????????????????? //Draw scene/ q+ B3 [7 Y+ M
? ? ? ? ? ? ? ? ? ? ? ? //繪制場(chǎng)景' l; ~$ w' b7 t. x
? ? ? ? ? ? ? ? ? ? ? ? smgr->drawAll();6 y( k3 G% B1 M5 K
? ? ? ? ? ? ? ? ? ? ? ? //Set viewport the last quarter (right bottom)
????????????????????? //設(shè)置視口到右下角6 W% h/ |" l' Q( Z: l
? ? ? ? ? ? ? ? ? ? ? ? driver->setViewPort(rect<s32>(ResX/2,ResY/2,ResX,ResY));
?????????????? }
????????????? //Activate camera46 ~3 I5 O7 o! A0 k, R
? ? ? ? ? ? ? ? //激活4號(hào)攝相機(jī)$ g: O+ R2 j% |' w. y5 g
? ? ? ? ? ? ? ? smgr->setActiveCamera(camera[3]);
????????????? //Draw scene1 L( a4 x: I??C- A; q8 K9 R2 d
? ? ? ? ? ? ? ? //繪制場(chǎng)景: j. f0 H" B! Z2 J0 S+ Q
? ? ? ? ? ? ? ? smgr->drawAll();! G- \$ Y7 p% `: B# p# P
? ? ? ? ? ? ? ? driver->endScene();
/*3 A3 l??a+ C5 N/ q: r( [& T
? ? ? ? ? ? ? ? 你大概已經(jīng)看到了,這幅圖片被每個(gè)視口分別渲染,那意味著你要損失許多性能(畢竟同樣的場(chǎng)景繪了四次)
?????????????? 好,如果你問;“我這樣做有必要嗎?”不要慌,它真的很簡(jiǎn)單:在區(qū)域函數(shù)中,我們定義了4個(gè)坐標(biāo): R??m7 T% B% \# t0 o
? ? ? ? ? ? ? ? (0,0)左上角坐標(biāo),(X,Y)右下角坐標(biāo)* U; L4 T! u$ f; V2 k: p
????????????? 這意味著,如果你想要把屏幕分割成兩部分,你需要給出如下的坐標(biāo)
????????????? 1號(hào)視口: 0,0,ResX/2,ResY
???????????? 2號(hào)視口:ResX/2,0,ResX,ResY
?M5 V- ~3 n0 Q9 i
? ? ? ? ? ? ? ? 如果你沒有完全明白,只需要修改示例程序的值,看發(fā)生了什么。
G* l3 ?! M) q4 s
? ? ? ? ? ? ? ? 現(xiàn)在我們只需要顯示FPS和在用戶要離開的時(shí)候銷毀引擎即可. _; ~+ H' ~6 y, M: ]+ E
*/
?????????????? //取得并顯示幀率8 x??W: e( ?7 |# g9 s7 T3 Z/ d
? ? ? ? ? ? ? ? if (driver->getFPS() != lastFPS)
??????????? {' G7 _0 E) E: l" m+ `& |% \
? ? ? ? ? ? ? ? ? ? ? ? lastFPS = driver->getFPS();* V- ~+ D& x??R3 }4 c
? ? ? ? ? ? ? ? ? ? ? ? core::stringw tmp = L"Irrlicht SplitScreen-Example (FPS: ";6 G5 h9 x# a! G0 w, S# V
? ? ? ? ? ? ? ? ? ? ? ? tmp += lastFPS;) Q- h" x# j0 g5 T
? ? ? ? ? ? ? ? ? ? ? ? tmp += ")";
????????????????????? device->setWindowCaption(tmp.c_str());% S1 `3 f6 {% R0 `
? ? ? ? ? ? ? ? }
l' X' R
? ? ? ? //銷毀設(shè)備# T??t% w$ o' ?# [
? ? ? ? device->drop();
?????? return 0;
}
/*( P: F4 J, T6 l$ c8 u1 P! H* i: ]
全部結(jié)束,只需要編譯就可以玩了
?注意:用S鍵你可以控制是否分屏
*/" f9 |% Q# F- U9 E8 \7 Q1 F
發(fā)表于: irrlicht3d中文官方論壇(3D網(wǎng)游開發(fā)論壇) http://www.irrlicht3d.cn
轉(zhuǎn)載于:https://www.cnblogs.com/qilinzi/archive/2010/04/26/1940506.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的irrlicht v1.6 例程18 Splitscreen的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL Cookbook:二、查询结果排
- 下一篇: Intent 的用法