51
Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 년년 년년년년년년년년

Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Embed Size (px)

Citation preview

Page 1: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Game Programming 04The Game Loop and Real-time

Simulation

2010 년 2 학기디지털콘텐츠전공

Page 2: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Time in Game

• Games:– Real-time, dynamic, interactive computer

simulation– Time plays an important role!– Different types of time in a game

• Real time• Game time• local timeline of an animation

Page 3: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Rendering Loop

• Real-time 3D Graphics is different from OS’s GUI– Redraw in Windows PC/Mac OS:

• Mostly static• Small portion of the screen is changing• Rectangle invalidation

– Redraw in a Game:• Entire contents of the screen is changing• Like a movie with a series of still images in rapid

succession• Succession requires a LOOP – the rendering loop

Page 4: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Rendering Loop

• Typical structure for a rendering loop:

while(!quit){

// Update camera transform based on // user input, or predefined scenarioupdateCamera();

// Update positions, orientations and// other visual states of the elementsupdateSceneElements();

// Render a still frame into the “back buffer”

renderScene();

// Swap the back buffer with the front bufferswapBuffers();

}

while(!quit){

// Update camera transform based on // user input, or predefined scenarioupdateCamera();

// Update positions, orientations and// other visual states of the elementsupdateSceneElements();

// Render a still frame into the “back buffer”

renderScene();

// Swap the back buffer with the front bufferswapBuffers();

}

Page 5: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Game Loop

• Game consists of many subsystems:– Device I/O– Rendering– Animation– Collision detection and resolution– Rigid body dynamic simulation (optional)– Multiplayer networking– Audio

• Need to be update periodically – Game Loop– Update rates can be different

• Rendering/animation: 30~60 Hz• Dynamic simulation: 120 Hz• AI: 2 Hz (twice per second)

Page 6: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Game Loop – A Simple Example• Pong (Atari arcade game)– A Legendary Game:

http://www.pong-story.com/arcade.htm – Simple but exciting!

http://www.youtube.com/watch?v=LPkUvfL8T1I

Page 7: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Pong Game Loopvoid main() // pong{

initGame();while(true) // Game Loop{

readInterfaceDevices();if(quitButtonPressed())

break;movePaddles();moveBall();collideAndBounceBall();if(ballImpactedSide(LEFT_PLAYER){

incrementScore(RIGHT_PLAYER);resetBall();

}if(ballImpactedSide(RIGHT_PLAYER){

incrementScore(LEFT_PLAYER);resetBall();

}renderPlayfield();

}}

void main() // pong{

initGame();while(true) // Game Loop{

readInterfaceDevices();if(quitButtonPressed())

break;movePaddles();moveBall();collideAndBounceBall();if(ballImpactedSide(LEFT_PLAYER){

incrementScore(RIGHT_PLAYER);resetBall();

}if(ballImpactedSide(RIGHT_PLAYER){

incrementScore(LEFT_PLAYER);resetBall();

}renderPlayfield();

}}

Page 8: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Game loop architectural styles1. Windows Message Pumps

2. Callback-Driven Frameworks

3. Even-based Updating

Page 9: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Windows Message Pumps

• Message Pump:– A routine for handling windows messages

• Games in a Windows OS must obey windows’ rule• Many messages from the OS cannot be ignored

// Message Pump – Typical Windows Routine

while (GetMessage(&msg, NULL, 0, 0)) {

TranslateMessage(&msg); DispatchMessage(&msg);

}

// Message Pump – Typical Windows Routine

while (GetMessage(&msg, NULL, 0, 0)) {

TranslateMessage(&msg); DispatchMessage(&msg);

}

Page 10: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Windows Message Pumps

• Message Pump for a game:– Modify the windows message pump with the

game loop// Message Pump for a gamewhile (true){

// Service all pending windows messageswhile (PeekMessage(&msg, NULL, 0, 0)>0) {

TranslateMessage(&msg); DispatchMessage(&msg);

}

// If no more windows messages, // run one iteration of the game loopRunOneIterationOfGameLoop();

}

// Message Pump for a gamewhile (true){

// Service all pending windows messageswhile (PeekMessage(&msg, NULL, 0, 0)>0) {

TranslateMessage(&msg); DispatchMessage(&msg);

}

// If no more windows messages, // run one iteration of the game loopRunOneIterationOfGameLoop();

}

Page 11: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Call-back Driven Framework

• Framework:– A partially-constructed application

• Encapsulating knowledge of how to use the low-level libraries

• Providing functions for the game flow • But functions are mostly empty

– Need to be completed by a programmer• Fill-in the missing details• Overide call-back functions

Page 12: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Call-back Driven Framework

• Example from Ogre3D’s game loop

while (true){

for (each frameListener){

frameListener.frameStarted();}

renderCurrentScene();

for (each frameListener){

frameListener.frameEnded();}

}

while (true){

for (each frameListener){

frameListener.frameStarted();}

renderCurrentScene();

for (each frameListener){

frameListener.frameEnded();}

}

Page 13: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Call-back Driven Framework

• Using Ogre’s FrameListenerClass GameFrameListener : public Ogre::FrameListener{public:

virtual void frameStarted(const FrameEvent &event){

// Do things happening before renderingpollJoypad(event);updatePlayerControls(events);updateDynamicSimulation(events);resolveCollisions(events);updateCamera(events);// etc.

}virtual void frameEnded(const FrameEvent &event){

// Do things after renderingdrawHud(events);

}}

Class GameFrameListener : public Ogre::FrameListener{public:

virtual void frameStarted(const FrameEvent &event){

// Do things happening before renderingpollJoypad(event);updatePlayerControls(events);updateDynamicSimulation(events);resolveCollisions(events);updateCamera(events);// etc.

}virtual void frameEnded(const FrameEvent &event){

// Do things after renderingdrawHud(events);

}}

Page 14: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Event-Driven Updating

• Event:– Any interesting change in the state of the

game– Examples:

• The player pressing a keyboard• The explosion going off• An enemy character spotting the player

Page 15: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Event-Driven Updating

• Event System– Similar to windows GUI– A subsystem of a game engine

• Register events of interests• Respond to the events when they occur

– Periodic services can be implemented by an event• Example: Posting a event for every 1/30 sec.• Using the event que for posting a event for the future

Page 16: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

MEASURING AND DEALING WITH TIME

Page 17: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Timelines

• Real Time– Actual time measured directly via the CPU

clock

• Game Time– Times measured or used in the game– Does not need to be coincide with the real time

• Slow/fast motion in the game • Temporarily pausing the game• When debugging, slow-down helps to figure out.

Page 18: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Timelines

• Local and Global timelines– Each animation clip or audio clip may have a

different timeline• Origin (t=0) defined to the start of the clip• Easy to speed up/down when playback• Easy to play backward

Playing a clipPlaying a clip Speed upSpeed up Play backwardPlay backward

Page 19: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Frame Rate and Time Deltas

• Frame Rate: f– How rapidly the sequence of still images

changes– Hertz (Hz) : number of cycles for second– Frames per Second (FPS) :

• Used in games and film. • Same with Hz • 30/60 in North America or Japan (NTSC)• 50 in Europe (PAL)

– Can be varying time to time!

• Time Delta: Δt– The amount of time between frames:

• Also known as Frame time, delta time• Inverse of the frame rate: 1/f• 30 FPS = 1/30 sec = 33.3 ms

Page 20: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

From Frame Rate to Speed

• Speed: v– Meters per second (or pixels per second)

• Make a spaceship move:– Change in position: Δx = v Δt

– With a current position x1, at next frame: x2 = x1 + v Δt

– Since the movement depends on Δt , how to determine it?

Page 21: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Old-days CPU-dependent Games• CPU-Dependent:– Do not use any Δt ! – Instead, specify the speed by the meters per frame

– With a good PC, will runs fast– With a bad PC, will runs slow– Provide a “Turbo” button to speed up in old-days

Page 22: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Updating based on Elapsed Time– To be CPU-independent: Measuring Δt

• Read CPU time twice: • Once at the beginning and once at the end of the frame• Most game do this!

– Is it accurate?• We are measuring the past Δt as an upcomming Δt

• “Past performance is not a guarantee of future results”

• Sudden drop in the frame rate: Frame-rate spike

Page 23: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Using a Running Average

• Averaging the frame-time over a few frames– Reduce the influence of a sudden change in

frame rate– Can adapt smoothly with a varying framerate

Page 24: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Governing the Frame Rate

• Frame Rate Governing:– Guarantee every frame’s duration to be 33.3

ms or 16.6 ms– Sleep if ends earlier otherwise “takes our lumps”

Page 25: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Measuring Real Time

• Querying system time:– The number of seconds since midnight, Jan 1, 1970– Not enough resolution

• High-Resolution Timer:– Count the number of CPU cycles since the last

power on/reset– For example:

• 3GHz processor increments 3 billion times per second• Resolution: 1/3 billion = 3.33 x 10-10 second =0.333 ns• Stored with 64 bit integer: 195 years of duration to

record

time();time();

QueryPerformanceCounter(); // read the counter (64bit integer)QueryPerformanceFrequency(); // cycles per secondQueryPerformanceCounter(); // read the counter (64bit integer)QueryPerformanceFrequency(); // cycles per second

Page 26: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Time to Back to OGRE3D

Page 27: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Basic of OGRE• Scene Manager:

– Managing everything appearing in the scene– Cameras, Objects, Planes, billboards, lights...and so

on

• 3 kinds of Scene Managers– Octree(8 진 트리 ) Scene Manager

• 기본 장면 관리자• 대부분의 장면에 사용 가능

– BSP(Binary Surface Partition) Scene Manager• 건물 내부와 같이 벽과 복도 등으로 구성된 장면에 최적화된

성능 .

– Terrain Scene Manager• 정적 지형을 가지는 비교적 소규모의 장면에 적합• 고해상도의 지형에 적합 mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC); mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);

Page 28: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Basic of OGRE

• Entity:– Objects to be rendered on the scene – 3D meshes: Character, robot, fish, terrain and

so on. – Cameras, lights, billboards are not entities.

3D Mesh

Page 29: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Basic of OGRE

• Scene Node:– Representing translation, rotation and scale

(transformation)– Not an actual object– An(or multiple) entity can be attached to.

NodeNode

Entity1

Entity1

Entity2

Entity2

Page 30: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Scene Manager, node and entity

rootroot

Node1Node1 Node2Node2

Entity1

Entity1

Entity2

Entity2

Entity3

Entity3

Node3Node3

Entity4

Entity4

Entity5

Entity5

Node4Node4

Entity6

Entity6

Page 31: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Hierarchical Modeling

• A hierarchical model is created by nesting the descriptions of subparts into one another to form a tree organization

Page 32: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Revisiting the code

void TutorialApplication::createScene(void){ // create your scene here :)

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh"); Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); headNode->attachObject(ogreHead); // Set ambient light mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5)); // Create a light Ogre::Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20,80,50);}

void TutorialApplication::createScene(void){ // create your scene here :)

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh"); Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); headNode->attachObject(ogreHead); // Set ambient light mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5)); // Create a light Ogre::Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20,80,50);}

Page 33: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Adding One More Node

void TutorialApplication::createScene(void){ // create your scene here :)

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh"); Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); headNode->attachObject(ogreHead); Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" ); Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode ( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) ); headNode2->attachObject( ogreHead2 );

// Set ambient light mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5)); // Create a light Ogre::Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20,80,50);}

void TutorialApplication::createScene(void){ // create your scene here :)

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh"); Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); headNode->attachObject(ogreHead); Ogre::Entity* ogreHead2 = mSceneMgr->createEntity( "Head2", "ogrehead.mesh" ); Ogre::SceneNode* headNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode ( "HeadNode2", Ogre::Vector3( 100, 0, 0 ) ); headNode2->attachObject( ogreHead2 );

// Set ambient light mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5)); // Create a light Ogre::Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20,80,50);}

Page 34: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Node Transformation

• Translate:– SceneNode::translate ( Ogre::Vector3(..) );

• Rotate:– SceneNode::yaw(Degree(..));– SceneNode::pitch ( );– SceneNode::roll ( );

• Scale– SceneNode::scale ( x, y, z );

Page 35: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Cool ninja without hassle

• Replace the CreateScene function with the one in our homepage!

Page 36: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

정리• OGRE 3D 의 rendering process:– 시스템 초기화

• Root 개체 생성• Configuration 설정• Render Window 생성• Resource 위치 설정• Frame Listener 생성

– 씬 생성• Scene Manager 생성• Camera 및 viewport 생성• Light 생성• Entity 생성• Scene node 생성

– 렌더링

Page 37: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Frame Listener

• 한 장면이 화면에 렌더링되기 직전 /직후에 해야 할 일을 정의하고 있는 객체

• 추가 작업을 위해서는 frame listener 를 추가 생성하고 , 이를 root 에 등록시켜 사용

• 여러 개의 frame listener 가 존재할 수 있다 .

Page 38: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Frame Listener 의 맴버함수

frameStarted Called just before a frame is rendered.

frameRenderingQueued

Called after all render targets have had their rendering commands issued, but beforethe render windows have been asked to flip their buffers over

frameEnded Called just after a frame has been rendered.

virtual bool frameStarted(const FrameEvent& evt); virtual bool frameRenderingQueued(const FrameEvent& evt); virtual bool frameEnded(const FrameEvent& evt)

virtual bool frameStarted(const FrameEvent& evt); virtual bool frameRenderingQueued(const FrameEvent& evt); virtual bool frameEnded(const FrameEvent& evt)

FrameEvent structure: Real timeSinceLastEvent, Real timeSinceLastFrame 값을 기억하는 구조체

Page 39: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Frame Listener 의 호출• Root 객체의 rendering loop 내에서 호출

bool Root::renderOneFrame(void){ if(!_fireFrameStarted()) return false; if (!_updateAllRenderTargets()) return false; return _fireFrameEnded();}

bool Root::renderOneFrame(void){ if(!_fireFrameStarted()) return false; if (!_updateAllRenderTargets()) return false; return _fireFrameEnded();}

Page 40: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Ogre Engine 의 Rendering Loop• Root::startRendering() 함수에서 이뤄짐• Redering Loop 실행

– 매 프레임 마다 renderOneFrame 실행 :

• Loop 의 중단– FrameStarted, frameRenderingQueued, FrameEnded 에서

하나라도 false 를 return 할 경우

1. Frame Listener 들의 FrameStarted() 함수 호출1. Frame Listener 들의 FrameStarted() 함수 호출

3. Frame Listener 들의 FrameEnded() 함수 호출3. Frame Listener 들의 FrameEnded() 함수 호출

Frame Listener 들의 frameRenderingQueued() 함수 호출Frame Listener 들의 frameRenderingQueued() 함수 호출

2. 한 프레임 렌더링2. 한 프레임 렌더링

Page 41: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Input Handling

• Types of input handling– Unbuffered Input

• Testing states of Mouse/Keyboard every frame• Do action if necessary

– Buffered Input• Event(message)-driven• Event is queued into a buffer• Call message pump routines per frame

Page 42: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Ninja 움직이기• Add two functions in Application class:

class OgreApp : public BaseApplication{public: BasicTutorial4(void); virtual ~BasicTutorial4(void);protected: virtual void createScene(void); virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);private: bool processUnbufferedInput(const Ogre::FrameEvent& evt);}

class OgreApp : public BaseApplication{public: BasicTutorial4(void); virtual ~BasicTutorial4(void);protected: virtual void createScene(void); virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);private: bool processUnbufferedInput(const Ogre::FrameEvent& evt);}

Page 43: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Ninja 움직이기• Add two functions in Application class:

class OgreApp : public BaseApplication{public: BasicTutorial4(void); virtual ~BasicTutorial4(void);protected: virtual void createScene(void); virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);private: bool processUnbufferedInput(const Ogre::FrameEvent& evt);}

class OgreApp : public BaseApplication{public: BasicTutorial4(void); virtual ~BasicTutorial4(void);protected: virtual void createScene(void); virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);private: bool processUnbufferedInput(const Ogre::FrameEvent& evt);}

Page 44: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

CreateScene 수정• Ninja 를 포함하고 light 를 세팅

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.25, 0.25, 0.25));

Ogre::Entity* ninjaEntity = mSceneMgr->createEntity("Ninja", "ninja.mesh");Ogre::SceneNode *node = mSceneMgr->getRootSceneNode()

->createChildSceneNode("NinjaNode");node->attachObject(ninjaEntity);

Ogre::Light* pointLight = mSceneMgr->createLight("pointLight");pointLight->setType(Ogre::Light::LT_POINT);pointLight->setPosition(Ogre::Vector3(250, 150, 250));pointLight->setDiffuseColour(Ogre::ColourValue::White);pointLight->setSpecularColour(Ogre::ColourValue::White);

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.25, 0.25, 0.25));

Ogre::Entity* ninjaEntity = mSceneMgr->createEntity("Ninja", "ninja.mesh");Ogre::SceneNode *node = mSceneMgr->getRootSceneNode()

->createChildSceneNode("NinjaNode");node->attachObject(ninjaEntity);

Ogre::Light* pointLight = mSceneMgr->createLight("pointLight");pointLight->setType(Ogre::Light::LT_POINT);pointLight->setPosition(Ogre::Vector3(250, 150, 250));pointLight->setDiffuseColour(Ogre::ColourValue::White);pointLight->setSpecularColour(Ogre::ColourValue::White);

Page 45: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Frame Listner 수정• frameRenderingQueued 함수 override

bool OgreApp::frameRenderingQueued(const Ogre::FrameEvent& evt){ bool ret = BaseApplication::frameRenderingQueued(evt); if(!processUnbufferedInput(evt)) return false; return ret;}

bool OgreApp::frameRenderingQueued(const Ogre::FrameEvent& evt){ bool ret = BaseApplication::frameRenderingQueued(evt); if(!processUnbufferedInput(evt)) return false; return ret;}

Page 46: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Processing Input

bool OgreApp::processUnbufferedInput(const Ogre::FrameEvent& evt){ static bool mMouseDown = false; // If a mouse button is depressed static Ogre::Real mToggle = 0.0; // The time left until next toggle static Ogre::Real mRotate = 0.13; // The rotate constant static Ogre::Real mMove = 250; // The movement constant

bool OgreApp::processUnbufferedInput(const Ogre::FrameEvent& evt){ static bool mMouseDown = false; // If a mouse button is depressed static Ogre::Real mToggle = 0.0; // The time left until next toggle static Ogre::Real mRotate = 0.13; // The rotate constant static Ogre::Real mMove = 250; // The movement constant

Page 47: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Processing Input

• UnbufferedInput 구현– Mouse 와 keyboard 의 현재 상태를 얻어옴

(BaseApplication::frameRenderingQueued 에서 수행 )

• 다음과 같이 사용할 준비를 한다 . bool OgreApp::processUnbufferedInput(const Ogre::FrameEvent& evt){ static bool mMouseDown = false; // If a mouse button is depressed static Ogre::Real mToggle = 0.0; // The time left until next toggle static Ogre::Real mRotate = 0.13; // The rotate constant static Ogre::Real mMove = 250; // The movement constant

bool OgreApp::processUnbufferedInput(const Ogre::FrameEvent& evt){ static bool mMouseDown = false; // If a mouse button is depressed static Ogre::Real mToggle = 0.0; // The time left until next toggle static Ogre::Real mRotate = 0.13; // The rotate constant static Ogre::Real mMove = 250; // The movement constant

mMouse->capture(); mKeyboard->capture();mMouse->capture(); mKeyboard->capture();

Page 48: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Toggle 기능 구현• 현재 mouse 와 마지막 mouse 상태의 비교를

통해 구현

bool currMouse = mMouse->getMouseState().buttonDown(OIS::MB_Left);

if (currMouse && ! mMouseDown){ Ogre::Light* light = mSceneMgr->getLight("pointLight"); light->setVisible(! light->isVisible());}

mMouseDown = currMouse;

bool currMouse = mMouse->getMouseState().buttonDown(OIS::MB_Left);

if (currMouse && ! mMouseDown){ Ogre::Light* light = mSceneMgr->getLight("pointLight"); light->setVisible(! light->isVisible());}

mMouseDown = currMouse;

Page 49: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Delayed Toggle 구현• 눌린 시간을 기억하여 어느 일정시간이상

눌렸으면 실행

mToggle -= evt.timeSinceLastFrame;

if ((mToggle < 0.0f ) && mKeyboard->isKeyDown(OIS::KC_1)){ mToggle = 0.5; Ogre::Light* light = mSceneMgr->getLight("pointLight"); light->setVisible(! light->isVisible());}

mToggle -= evt.timeSinceLastFrame;

if ((mToggle < 0.0f ) && mKeyboard->isKeyDown(OIS::KC_1)){ mToggle = 0.5; Ogre::Light* light = mSceneMgr->getLight("pointLight"); light->setVisible(! light->isVisible());}

Page 50: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Keyboard 입력 구현• 키보드의 상태를 찾아내어 구현

Ogre::Vector3 transVector = Ogre::Vector3::ZERO;

if (mKeyboard->isKeyDown(OIS::KC_I)) // ForwardtransVector.z -= mMove;

if (mKeyboard->isKeyDown(OIS::KC_K)) // BackwardtransVector.z += mMove;

if (mKeyboard->isKeyDown(OIS::KC_U)) // UptransVector.y += mMove;

if (mKeyboard->isKeyDown(OIS::KC_O)) // DowntransVector.y -= mMove;

mSceneMgr->getSceneNode("NinjaNode")->translate(transVector * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);

Ogre::Vector3 transVector = Ogre::Vector3::ZERO;

if (mKeyboard->isKeyDown(OIS::KC_I)) // ForwardtransVector.z -= mMove;

if (mKeyboard->isKeyDown(OIS::KC_K)) // BackwardtransVector.z += mMove;

if (mKeyboard->isKeyDown(OIS::KC_U)) // UptransVector.y += mMove;

if (mKeyboard->isKeyDown(OIS::KC_O)) // DowntransVector.y -= mMove;

mSceneMgr->getSceneNode("NinjaNode")->translate(transVector * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);

Page 51: Game Programming 04 The Game Loop and Real-time Simulation 2010 년 2 학기 디지털콘텐츠전공

Rotate 구현• SHIFT 키와 조합하여 구현

if (mKeyboard->isKeyDown(OIS::KC_J)) // Left - yaw or strafe{ if(mKeyboard->isKeyDown( OIS::KC_LSHIFT )) { // Yaw left mSceneMgr->getSceneNode("NinjaNode")->yaw(Ogre::Degree(mRotate * 5)); } else { transVector.x -= mMove; // Strafe left }}if (mKeyboard->isKeyDown(OIS::KC_L)) // Right - yaw or strafe{ if(mKeyboard->isKeyDown( OIS::KC_LSHIFT )) { // Yaw right mSceneMgr->getSceneNode("NinjaNode")->yaw(Ogre::Degree(-mRotate * 5)); } else { transVector.x += mMove; // Strafe right }}

if (mKeyboard->isKeyDown(OIS::KC_J)) // Left - yaw or strafe{ if(mKeyboard->isKeyDown( OIS::KC_LSHIFT )) { // Yaw left mSceneMgr->getSceneNode("NinjaNode")->yaw(Ogre::Degree(mRotate * 5)); } else { transVector.x -= mMove; // Strafe left }}if (mKeyboard->isKeyDown(OIS::KC_L)) // Right - yaw or strafe{ if(mKeyboard->isKeyDown( OIS::KC_LSHIFT )) { // Yaw right mSceneMgr->getSceneNode("NinjaNode")->yaw(Ogre::Degree(-mRotate * 5)); } else { transVector.x += mMove; // Strafe right }}