Ogre3D 삽질란/Basic Tutorial 5

기초 튜토리얼 5-1

n_Sys 2008. 11. 24. 09:28

기초 튜토리얼 5 (번역 : n_Sys)

입문자 튜토리얼 5: Buffered Input

튜토리얼 진행중 문제가 발생한다면 Help 포럼 문의하세요.

 

Contents

                               1 미리 알아두어야

                               2 소개

                               3 시작하기

                               4 Buffered Input 알아보기

                                       4.1 소개

                                       4.2 KeyListener 인터페이스

                                       4.3 MouseListener 인터페이스

                               5 소스코드

                                       5.1 TutorialFrameListener 생성자 시작

                                       5.2 사용되는 변수들

                                       5.3 TutorialFrameListener 생성자 내용

                                       5.4 Key 바인딩

                                       5.5 Mouse 바인딩

                               6 다른종류의 입력 시스템들

 

미리 알아두어야

튜토리얼은 독자가 C++ 프로그래밍이 가능하고 오우거 어플리케이션 설정 컴파일이 가능하다는 가정하에 진행됩니다. 튜토리얼은 이전 튜토리얼을 기초로 작성되었으며 독자는 이전 튜토리얼들을 거쳐왔다고 가정합니다.

 

소개

이번 튜토리얼에서는 지난 튜토리얼에서 타루었던 (unbuffered)비버퍼입력방식과 상반되는 OIS (buffered)버퍼입력방식을 다룹니다. 지난번 튜토리얼과는 다르게 이번에는 프레임마다 한번씩 체크하는 방식이 아니라 키보드 마우스의 이벤트 호출이 발생될 것입니다. 참고로 튜토리얼은 버퍼방식 입력에 대한 간단한  튜토리얼이지 OIS사용법에 대한 완벽한 튜토리얼이 아닙니다. OIS 대한 자세한 정보가 필요하시다면 OIS사용하기(http://www.ogre3d.org/wiki/index.php/Using_OIS) 참고하세요.

튜토리얼에 관련된 코드는 여기(http://www.ogre3d.org/wiki/index.php/BasicTutorial5Source) 찾으실 있습니다. 튜토리얼을 천천히 진행함에 따라 프로젝트에 코드를 직접 입력하고 중간중간 생성되는 결과를 확인하세요.

 

시작하기

튜토리얼은 지난번 튜토리얼을 기초로 작성되었습니다. 다만 이번에는 입력방식이 다를겁니다. 기본적으로 기능은 똑같으므로 동일한 TutorialApplication 클래스를 사용합니다. TutorialFrameListener 클래스 부터 살펴 봅시다. 프로젝트를 생성하고 아래 소스코드를 입력하세요 :

#include "ExampleApplication.h"

 

class TutorialFrameListener : public ExampleFrameListener, public OIS::MouseListener, public OIS::KeyListener

{

public:

    TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr)

        : ExampleFrameListener(win, cam, true, true)

    {

    }

 

    bool frameStarted(const FrameEvent &evt)

    {

        if(mMouse)

            mMouse->capture();

        if(mKeyboard)

            mKeyboard->capture();

        return mContinue;

    }

 

    // MouseListener

    bool mouseMoved(const OIS::MouseEvent &e) { return true; }

    bool mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }

    bool mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id) { return true; }

 

    // KeyListener

    bool keyPressed(const OIS::KeyEvent &e) { return true; }

    bool keyReleased(const OIS::KeyEvent &e) { return true; }

protected:

    Real mRotate;          // The rotate constant

    Real mMove;            // The movement constant

 

    SceneManager *mSceneMgr;   // The current SceneManager

    SceneNode *mCamNode;   // The SceneNode the camera is currently attached to

 

    bool mContinue;        // Whether to continue rendering or not

    Vector3 mDirection;     // Value to move in the correct direction

};

 

class TutorialApplication : public ExampleApplication

{

public:

    void createCamera(void)

    {

        // create camera, but leave at default position

        mCamera = mSceneMgr->createCamera("PlayerCam");

        mCamera->setNearClipDistance(5);

    }

 

    void createScene(void)

    {

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

 

        // add the ninja

        Entity *ent = mSceneMgr->createEntity("Ninja", "ninja.mesh");

        SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaNode");

        node->attachObject(ent);

 

        // create the light

        Light *light = mSceneMgr->createLight("Light1");

        light->setType(Light::LT_POINT);

        light->setPosition(Vector3(250, 150, 250));

        light->setDiffuseColour(ColourValue::White);

        light->setSpecularColour(ColourValue::White);

 

        // Create the scene node

        node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode1", Vector3(-400, 200, 400));

 

        // Make it look towards the ninja

        node->yaw(Degree(-45));

 

        // Create the pitch node

        node = node->createChildSceneNode("PitchNode1");

        node->attachObject(mCamera);

 

        // create the second camera node/pitch node

        node = mSceneMgr->getRootSceneNode()->createChildSceneNode("CamNode2", Vector3(0, 200, 400));

        node = node->createChildSceneNode("PitchNode2");

    }

 

    void createFrameListener(void)

    {

        // Create the FrameListener

        mFrameListener = new TutorialFrameListener(mWindow, mCamera, mSceneMgr);

        mRoot->addFrameListener(mFrameListener);

 

        // Show the frame stats overlay

        mFrameListener->showDebugOverlay(true);

    }

};

 

#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32

#define WIN32_LEAN_AND_MEAN

#include "windows.h"

 

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)

#else

int main(int argc, char **argv)

#endif

{

    // Create application object

    TutorialApplication app;

 

    try {

        app.go();

    } catch(Exception& e) {

#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32

        MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);

#else

        fprintf(stderr, "An exception has occurred: %s\n",

            e.getFullDescription().c_str());

#endif

    }

 

    return 0;

}

만약 오우거SDK Windows 에서 사용한다면 "[OgreSDK_DIRECTORY]\samples\include" 디렉토리 (ExampleApplication.h 파일이 있는곳) include 가능하도록 프로젝트에 추가해 주세요. 만약 오우거엔진 소스를 직접 사용하신다면 [OgreSource_DIRECTORY]\Samples\Common\include" 추가해 주세요. 다음 진행을 위해서 컴파일이 에러없이 되도록 해두세요. 그러나 실행은 하지마세요! 나중에 코드에 추가할 계획입니다. 만약 컴파일에 문제가 생긴다면 Wiki 페이지에서 컴파일러별 설정 정보를 찾아보시고 문제가 지속된다면 Help 포럼에 문의하세요.

참고 : 만약 컴파일러가 ANSI C++ 지원하지 않거나 MessageBox 에러가 발생된다면 MessageBox MessageBoxA 바꿔주세요.

지난번튜토리얼 결과물과 똑같은 기능을 가지게 것입니다.