기초 튜토리얼 2-1

Ogre3D 삽질란/Basic Tutorial 2 2008. 11. 8. 17:14

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

입문자 튜토리얼 2: Cameras, Lights, and Shadows

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

Contents

*                                  1 미리 알아두어야

*                                  2 소개

*                                  3 시작하기

*                                  4 카메라

*                                          4.1 오우거에서의 카메라

*                                          4.2 카메라 생성

*                                  5 Viewports

*                                          5.1 Ogre Viewports

*                                          5.2 Viewport 생성

*                                  6 조명과 그림자

*                                          6.1 오우거에서 지원하는 그림자 타입들

*                                          6.2 오우거에서 그림자 사용하기

                                               6.2.1 문제점 해결

*                                          6.3 조명종류

*                                          6.4 조명 생성

*                                  7 해볼만 것들

*                                          7.1 다양한 그림자 타입들

*                                          7.2 감쇄

*                                          7.3 SceneManager::setAmbientLight

*                                          7.4 Viewport 배경색

*                                          7.5 Camera::setFarClipDistance

*                                          7.6 평면

*                                  8 Full Source

 

미리 알아두어야

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

 

소개

튜토리얼은 지금까지 배운것에 이어서 처럼 오우거 구성의 몇가지를 소개할 입니다. 빛을 중심으로 어떻게 그것들이 오우거에서 그림자를 생성하는지를 다룰 입니다. 카메라의 아주 기초적인 부분 역시도 다룰것 입니다.

튜토리얼을 진행하면서 독자는 진행단계에 맞추어서 천천히 코드를 스스로 입력하고 결과물을 지켜 필요성이 있습니다. 오우거엔진의 개념을 따라잡는대에는 이것만한 방법이 없습니다! 대충 눈으로 훑고 넘어가지 마세요.

 

시작하기

지난번 튜토리얼처럼 미리 작성된 코드를 기초로 시작할 입니다. TutorialApplication 클래스의 createViewport createCamera 함수를 추가할 입니다. 함수들은 기본 ExampleApplication 클래스 정의되어 있지만 튜토리얼에서는 어떻게 카메라와 뷰포트가 실제로 생성되고 쓰이는지를 살펴볼 입니다.

프로젝트를 생성하고 아래 소스코드를 입력하세요 :

#include "ExampleApplication.h"

 

class TutorialApplication : public ExampleApplication

{

protected:

public:

    TutorialApplication()

    {

    }

 

    ~TutorialApplication()

    {

    }

protected:

    virtual void createCamera(void)

    {

    }

 

    virtual void createViewports(void)

    {

    }

 

    void createScene(void)

    {

        Entity *ent;

        Light *light;

    }

};

 

#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 포럼에 문의하세요.

 

카메라

 

오우거에서의 카메라

카메라는 생성된 장면을 보는데 사용합니다. 카메라는 SceneNode 처럼 특수 객체로 취급됩니다. 카메라는 setPosition, yaw, roll, pitch 함수들을 가지고 있고 SceneNode attach 수도 있습니다. SceneNode 처럼 카메라의 위치는 부모객체에 상대적인 위치를 가집니다. (누가 생각 해 냈는지 기막힌 아이디어 입니다.) 모든 움직임과 회전은 기본적으로 카메라 - SceneNode 생각하면 됩니다.

오우거에서의 카메라는 기대하던것과는 달리 한번에 하나의 카메라만 사용되어야 합니다(일단 지금은 그렇습니다). 한 장면의 일부분을 위해서 1개의 카메라를 생성하고 또 다른 장면의 일부분을 위해 하나의 카메라를 따로 생성한 다음 보고싶은 부분을 보기 위해 카메라를 활성화/비활성화를 하지 않는다는 뜻 입니다. 그 대신에 SceneNode 생성해서 "카메라 거치대" 처럼 사용하는 방법으로 구현될 수 있습니다. 장면의 일부분을 표시할때 카메라는 알아서 해당되는 SceneNode 위치되어 유저가 보고 싶은 방향을 바라보게 됩니다. 기법은 FrameListener 튜토리얼에서 다시 보게 겁니다.

 

카메라 생성

ExampleApplication 에서 사용되는 카메라 생성 기본함수를 교체해 봅시다.

TutorialApplication::createCamera 멤버 함수로 갑시다. 가장 먼저 해야 일은 카메라 생성입니다. 카메라가 SceneManager 포함되어 있어서 SceneManager 객체를 통해서 생성해야 합니다. 다음 라인을 넣어서 카메라를 생성합니다 :

        // create the camera

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

명령은 "PlayerCam" 이라는 이름으로 카메라를 생성합니다. 참고로 카메라의 포인터를 따로 관리하지 않아도 SceneManager getCamera 함수를 이용해서 이름을 기준으로 카메라포인터를 리턴받을 있습니다.  

다음으로 해야 일은 카메라의 위치와 어디를 바라 지를 설정 하는 입니다.

원점 주위에 객체를 두게 것이기 때문에 카메라는 적당한 +z 방향에 두고 원점을 바라보게 입니다. 방금 코드 다음에 다음 라인을 추가하세요 :

        // set its position, direction 

        mCamera->setPosition(Vector3(0,10,500));

        mCamera->lookAt(Vector3(0,0,0));

lookAt 함수는 센스쟁이입니다. 카메라가 어디에 있던지 yaw, rotate, pitch 과정을 거치지 않고도 유저가 원하는 방향으로 바라보게 해줍니다. SceneNode 역시 함수를 가지고 있어서 Entity 바라보는 방향을 다양한 상황에서 손쉽게 원하는 방향으로 향하도록 있습니다.

마지막으로 가까운 클리핑 거리를 5유닛 으로 설정합니다. 카메라에서 클리핑 거리는 얼마나 가깝거나 멀어야 보이지 않는지를 의미합니다. 근접 클리핑 거리는 Entity 너무 가깝게 있을때 가로막는 객체를 꿰뚫어서 화면을 있도록 줍니다. 어떠한 상황에서 객체가 너무 가까이 있으면 화면을 꽉차게 가로막아서 화면의 아주 작은부분을 제외하고는 아무것도 없게 됩니다. 이것 말고도 원거리 클리핑거리도 설정 가능합니다. 수치는 일정한 거리를 넘어선 물체를 렌더링엔진이 그리는것을 중단시킵니다. 만약 화면상에서 매우 거리에 걸쳐서 많은양의 객체를 그려야 경우라면 원거리 클리핑 수치조절은 프레임성능을 올리는데 중요하게 쓰여질 입니다. 근접 클리핑 거리를 설정하기위해 다음 라인을 추가하세요 :

        mCamera->setNearClipDistance(5);

원거리 클리핑 영역 설정은 간단하게 setFarClipDistance 호출하면 됩니다(보통 스텐실 쉐도우와 같이 쓰면 안되지만 여기 튜토리얼에서는 쓰입니다).

: