'CEGUI and Ogre'에 해당되는 글 1건

  1. 2010.03.27 기초 튜토리얼7
2010.03.27 17:27

입문자 튜토리얼  7: CEGUI and Ogre

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

Contents

*                               1 미리 알아두어야

*                               2 소개

*                               3 시작하기

*                                       3.1 초기 코드

*                                       3.2 코드 컴파일

*                                       3.3 간략한 소개

*                               4 오우거에 통합시키기

*                                       4.1 CEGUI 초기화

*                                       4.2 이벤트 넣기

*                                       4.3 마우스 이벤트 넣기&변환

*                               5 , 시트, 위젯

*                                       5.1 소개

*                                       5.2 시트 읽어들이기

*                                       5.3 수동으로 객체 생성하기

*                               6 이벤트

*                               7 텍스쳐 렌더링하기

*                               8 결론

*                                       8.1 대안으로 쓸만 것들

*                                       8.2 자세한 정보

 

미리 알아두어야

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

소개

이번 튜토리얼에서는 오우거에서 어떻게 CEGUI(내장형 GUI 시스템) 있는지 살펴봅니다. 튜토리얼이 끝날때 여러분은 CEGUI 기초적인 기능을 프로그램에 추가할 있게 것입니다. NOTE: 튜토리얼에서는 CEGUI 모든 기능을 가르쳐 주지 않습니다. 단지 시작할 있게 도와줄 뿐입니다. CEGUI 대한 질문이나 도움요청은 공식 CEGUI홈피(http://www.cegui.org.uk/wiki/index.php/Main_Page) 이용해 주세요.

튜토리얼에 대한 코드는 여기(http://www.ogre3d.org/wiki/index.php/BasicTutorial7Source) 찾을 있습니다. 코드를 천천히 입력하면서 나오는 결과물을 직접 눈으로 확인하세요.

 

시작하기

 

초기 코드

튜토리얼에서는 미리 작성된 코드로 부터 시작 것입니다. 지금까지 튜토리얼을 진행해 처럼 이러한 방식은 익숙하리라 생각합니다. 프로젝트를 생성하고 아래 소스코드를 입력하세요 :

#include "ExampleApplication.h"

#include <CEGUI/CEGUI.h>

#include <OIS/OIS.h>

#include <OgreCEGUIRenderer.h>

 

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

{

public:

    TutorialListener(RenderWindow* win, Camera* cam)

        : ExampleFrameListener(win, cam, true, true)

    {

       mContinue=true;

       mMouse->setEventCallback(this);

       mKeyboard->setEventCallback(this);

    } // CEGUIDemoListener

 

    bool frameStarted(const FrameEvent &evt)

    {

        mKeyboard->capture();

        mMouse->capture();

 

        return mContinue && !mKeyboard->isKeyDown(OIS::KC_ESCAPE);

    }

 

    bool quit(const CEGUI::EventArgs &e)

    {

        mContinue = false;

        return true;

    }

 

    // MouseListener

    bool mouseMoved(const OIS::MouseEvent &arg)

    {

        return true;

    }

 

    bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)

    {

        return true;

    }

 

    bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)

    {

        return true;

    }

 

    // KeyListener

    bool keyPressed(const OIS::KeyEvent &arg)

    {

        return true;

    }

 

    bool keyReleased(const OIS::KeyEvent &arg)

    {

        return true;

    }

 

private:

    bool mContinue;

};

 

 

class CEGUIDemoApplication : public ExampleApplication

{

public:

    CEGUIDemoApplication()

        : mSystem(0), mRenderer(0)

    {

    }

 

    ~CEGUIDemoApplication()

    {

        if (mSystem)

            delete mSystem;

 

        if (mRenderer)

            delete mRenderer;

    }

protected:

   CEGUI::System *mSystem;

   CEGUI::OgreCEGUIRenderer *mRenderer;

 

    void createScene(void)

    {

    }

 

    void createFrameListener(void)

    {

        mFrameListener= new TutorialListener(mWindow, mCamera);

        mFrameListener->showDebugOverlay(true);

        mRoot->addFrameListener(mFrameListener);

    }

 

};

 

#if 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

    CEGUIDemoApplication app;

 

    try {

        app.go();

    } catch(Exception& e) {

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

        MessageBoxA(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;

}

 

 

코드 컴파일

지금 시점에서 컴파일하고 실행이 되는지 확인하세요. 검은화면밖에 보이지 않을 입니다(ESC키를 누르면 종료합니다). 컴파일시 Linker에러가 발생하면 CEGUIBase_d.lib OgreGUIRenderer_d.lib 파일을 Linker 추가하세요(디버그 모드의 경우임. 릴리즈 모드의 경우에는 _d 부분을 제거).

 

간략한 소개

CEGUI 오우거와 같은 3D 어플리케이션(물론 순수 DirectX OpenGL 완벽하게 지원합니다) 내장될 있는 강력한 GUI 전용 라이브러리 입니다. 오우거가 순수 그래픽 라이브러리인 점에서 많이 닮아 있습니다(사운드나 물리연산같은 다른 기능들을 포함하지 않습니다). CEGUI GUI 라이브러리일 입니다. 무슨 의미냐면 자기 스스로 출력하는 기능도 없을 뿐더러 마우스나 키보드 이벤트를 인지하지도 못합니다. CEGUI 출력되기 위해서는 Renderer 제공되어야 합니다(오우거에서는 OgreGUIRenderer 의미하며 SDK 포함되어 있습니다). 그리고 마우스와 키보드이벤트를 인식시키려면 해당시스템에 임의적으로 삽입시켜야 합니다. 처음부터 무척 힘들게 느껴질지도 모르겠군요. 하지만 실제로는 정말 약간의 코드만 필요로 뿐입니다. 일단 통합되기만 하면 GUI 출력과 입력에 대해서 완벽한 제어를 제공합니다. CEGUI자체만으로는 절대 그렇게 하지 못할 입니다.

CEGUI 다루게 되면 처음보는 희안한 코드들(다른 GUI시스템들을 접해봤다 하더라도) 접할 입니다. 진행하면서 나오는 부분마다 차근차근 설명해 드리겠습니다.

Trackback 0 : Comment 0

기초 튜토리얼 7-2

Ogre3D 삽질란/Basic Tutorial 7 2008/12/04 17:23

오우거에 통합시키기

CEGUI 초기화

지난 튜토리얼에서 CEGUI 구동시키는 법을 간략하게나마 배웠으므로 첫부분에 대한 내용은 넘어가도록 하겠습니다. createScene함수를 찾아서 다음 코드를 추가하세요 :

       mRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr);

       mSystem = new CEGUI::System(mRenderer);

CEGUI 초기화 되었습니다. 이제 사용할 스킨을 선택해야 합니다. GEGUI 높은 수준의 커스터마이징을 지원합니다. 프로그램의 스킨을 바꿔주면서 look and feel 설정할 있도록 지원해 줍니다. 스킨에 대한 내용은 다루지 않을 계획입니다. 많은 사용법을 배우고 싶다면 CEGUI 홈페이지를 방문하세요. 다음 코드는 스킨을 선택합니다 :

CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLookSkin.scheme");

오우거설치시 기본값으로는 아무런 스킨도 설치되지 않습니다. 하지만 CEGUI CEGUI 공식홈페이지를 통해서 설치하면 몇가지 선택가능한 스킨이 포함됩니다(직접 만들 있습니다). 다음작업은 기본 마우스커서와 기본 폰트를 설정 하는 입니다 :

 

mSystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");

       mSystem->setDefaultFont((CEGUI::utf8*)"BlueHighway-12");

튜토리얼 시리즈들에서는 GUI 라이브러리를 쓸일이 없더라도 모두 CEGUI 커서를 사용합니다. 다른 GUI 라이브러리를 사용해서 마우스커서를 그리거나 오우거만 이용해서 바로 그릴수 있습니다(후자 경우 복잡한 선택사항이 수도 있습니다). 만약 마우스커서 하나 때문에 CEGUI 써야 하고 메모리 사용량과 개발중인 게임의 용량이 커질까봐 걱정된다면 앞서 설명한 선택사항들을 CEGUI 바꾸는걸 고려해 있습니다.

마지막에서 작성된 코드는 마우스커서를 설정했습니다. 그러나 나중에 있을 튜토리얼들과는 다르게 MouseCursor::setImage함수를 써서 직접적으로 마우스 커서를 설정하지 않았습니다. 튜토리얼에서는 CEGUI 윈도우의 종류(보이진 않습니다) 항상 화면상에 상주할 것이기 때문입니다. 결과적으로 디폴트 커서로 설정한 이미지로 마우스 커서가 만들어 것입니다. 만약 마우스커서를 직접 설정하고 디폴트값은 설정하지 않는다면 CEGUI 윈도우를 시간 통과하면서 보이지 않는 마우스커서가 것입니다( 튜토리얼에서는 절대 보이지 않게 겁니다). 반면에 아무런 CEGUI 윈도우를 출력하지 않는다면 디폴트 마우스 커서는 아무런 효과가 없습니다. 추후 이런 상황을 보게 것입니다. 이런 상황에서는 MouseCursor::setImage 함수를 써서 화면에 어플리케이션용 커서를 출력할 있습니다. 예제 입니다 :

CEGUI::MouseCursor::getSingleton().setImage(CEGUI::System::getSingleton().getDefaultMouseCursor());

 

이벤트 넣기

CEGUI 입력기능이 전혀 없습니다. 마우스의 움직임이나 키보드의 입력을 읽어내지 못합니다. 대신에 사용자로 하여금 입력과 마우스 이벤트를 시스템에 입력시키는 것에 의존합니다. 이제 이벤트를 다룰 차례입니다. CEGUI 쓰려면 버퍼방식 입력을 사용해야 합니다. 그래야만 이벤트가 발생하는 즉시 입력할 있습니다. KeyPressed 함수를 찾아서 다음 코드를 추가하세요 :

       CEGUI::System *sys = CEGUI::System::getSingletonPtr();

       sys->injectKeyDown(arg.key);

       sys->injectChar(arg.text);

시스템 객체를 얻은 이후 2가지 일들이 있습니다. 첫번째는 키가 눌려졌다는 이벤트를 CEGUI 입력하는것이고 두번째는 실제로 눌려진 키를 입력하는 입니다. Non-English 키보드일 경우 key down 이벤트 자체만으로는 항상 올바른 결과값을 가져다 주지 않으므로 눌려진 실제 키값을 입력시키는건 필수적 입니다. injectChar 유니코드를 고려해서 디자인 되었습니다.

이제는 키가 떨어졌을때의 상황처리를 해야 합니다. keyReleased함수를 찾아서 다음 코드를 추가하세요 :

CEGUI::System::getSingleton().injectKeyUp(arg.key);

키가 떨어졌을때는 키값을 입력해 필요가 없습니다. 키가 떨어졌다는 이벤트만 필요할 입니다.

 

마우스 이벤트 넣기&변환

키보드로 입력받는 작업은 모두 끝냈습니다. 이제 마우스 입력차례 입니다. 여기서 작은 문제점이 있습니다. 키가 눌려지고 떨어질때 CEGUI 입력시 변환작업은 없었습니다. OIS CEGUI 키보드에 대해서 같은 코드를 사용합니다. 하지만 마우스의 경우는 경우가 다릅니다. CEGUI 마우스버튼이 눌려졌다는 이벤트를 입력하기 전에 OIS 버튼ID로부터 CEGUI 버튼ID 변환시켜주는 함수를 작성해야 합니다. 다음 코드를 소스코드의 거의 최상단, TutorialListener클래스이전 부분에 추가하세요 :

CEGUI::MouseButton convertButton(OIS::MouseButtonID buttonID)

{

    switch (buttonID)

    {

    case OIS::MB_Left:

        return CEGUI::LeftButton;

 

    case OIS::MB_Right:

        return CEGUI::RightButton;

 

    case OIS::MB_Middle:

        return CEGUI::MiddleButton;

 

    default:

        return CEGUI::LeftButton;

    }

}

이제 마우스 이벤트를 입력시킬 준비가 되었습니다. mousePressed함수에 다음 코드를 추가하세요 :

CEGUI::System::getSingleton().injectMouseButtonDown(convertButton(id));

설명이 필요 없는 코드입니다. 입력받은 버튼ID 변환시켜서 CEGUI 전달합니다. MouseReleased함수에 다음 코드를 추가하세요 :

CEGUI::System::getSingleton().injectMouseButtonUp(convertButton(id));

마지막으로 마우스가 움직였을때 CEGUI 입력하기 입니다. CEGUI::System객체는 injectMouseMove함수를 가지고 있는데 마우스의 상대적 움직임거리를 입력받습니다. OIS::mouseMoved핸들러가 그에 연관된 움직임거리 state.X.rel state.Y.rel변수들을 제공합니다. MouseMoved함수에 다음 코드를 추가하세요 :

CEGUI::System::getSingleton().injectMouseMove(arg.state.X.rel, arg.state.Y.rel);

완성입니다. 이제 CEGUI 마우스와 키보드 입력에대한 모든 설정을 끝마쳤습니다.

Trackback 0 : Comment 0

기초 튜토리얼 7-3 (마지막)

Ogre3D 삽질란/Basic Tutorial 7 2008/12/04 17:22

윈도우, 시트, 위젯

소개

CEGUI 다른 GUI시스템들에 비해서 독특합니다. CEGUI 있어서 출력되는 모든 것들은 CEGUI::Window클래스의 상속된 형태이며 하나의 윈도우는 여러개의 자식 윈도우들을 가질 있습니다. 말은 여러개의 버튼을 포함하는 하나의 프레임을 만든다면 프레임이 윈도우라는 의미입니다. 이런 특징으로 이상한 현상을 유발할 수도 있습니다. 실제로는 절대 쓰이지 않겠지만 버튼 속에 다른 버튼을 배치할 수도 있습니다. 이런 사항들을 언급하냐면 만약에 어떤 위젯을 프로그램에 배치시킨 상황에서 나중에 포인터를 다시 찾고 싶을때가 있을 입니다. 모든 위젯들은 윈도우들에 의해 호출되어 집니다. 그리고 호출했던 윈도우의 함수를 사용함으로써 접근이 가능합니다.

CEGUI 사용하는 대부분의 경우 각각의 객체들을 코드로 생성하지는 않을 입니다. 대신에 CEGUI 레이아웃 에디터같은 툴을 사용해서 프로그램에서 필요로 하는 GUI 레이아웃을 작성합니다. 모든 윈도우, 버튼, 위젯을 화면상에 배치시킨 다음 레이아웃을 텍스트파일로 저장합니다. 나중에 CEGUI GUI시트(이것역시 CEGUI::Window에서 상속받은 형태) 로드시킬 있습니다.

마지막으로 알아두실 것은 CEGUI 정말 많은 위젯들을 포함하고 있씁니다. 모든것들을 튜토리얼안에서 다룰 수는 없으므로 CEGUI 사용하기로 마음먹었으면 꾸미기위해 CEGUI공식 홈페이지를 방문하셔서 많은 정보를 얻으시길 바랍니다.

 

시트 읽어들이기

CEGUI에서 시트를 읽는 작업은 무척 쉽습니다. WindowManager클래스가 제공하는 “loadWindowLayout” 함수로 시트를 읽어들이고 CEGUI::Window객체에 넣을 있습니다. 그런 다음 CEGUI::System::setGUISheet함수로 출력할 있습니다만 튜토리얼에서는 사용하지 않을 입니다. 하지만 적어도 어떻게 쓰는지 예제라도 보여드려야 죄책감이 들지 않을것 같군요. 튜토리얼용 코드에 추가하지 마세요(만약에 추가했다면 결과를 확인하고 해당 코드를 삭제해 주세요) :

       // Do not add this to the program

       CEGUI::Window* sheet = CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)"ogregui.layout");

       mSystem->setGUISheet(sheet);

코드는 지금 보여질 시트를 선택합니다. 나중에 시트의 포인터는 System::getGUISheet함수를 통해서 다시 구할 있습니다. 그리고 GUI시트를 다른 어떤 시트와도 setGUISheet함수를 통해서 매끄럽게 교체할 수도 있습니다(나중에 현재의 시트를 다시 복구하고 싶다면 포인터를 저장해 두세요).

 

수동으로 객체 생성하기

앞서 얘기한 대로 CEGUI 쓰면서 GUI시트는 에디터를 써서 만들게 될겁니다. 하지만 가끔씩은 수동으로 위젯을 화면상에 올릴 필요도 있습니다. 예를 들어서 나중에 기능을 추가시킬 Quit 버튼을 추가할 겁니다. 튜토리얼을 진행하면서 Quit버튼 밖에도 많은 것들을 추가할 계획이고 최초로 생성될 디폴트 CEGUI::Window 앞으로 만들어질 모든 위젯들을 포함할 입니다. 다음 코드를 createScene함수에 추가하세요 :

       CEGUI::WindowManager *win = CEGUI::WindowManager::getSingletonPtr();

       CEGUI::Window *sheet = win->createWindow("DefaultGUISheet", "CEGUIDemo/Sheet");

코드는 WindowManager 사용해서 "CEGUIDemo/Sheet"라는 이름을 가진 "DefaultGUISheet" 생성합니다. 시트이름은 마음대로 지을 있습니다. 게다가 이렇게 "SomeApp/MainMenu/Submenu3/CancelButton"처럼 계층적방식으로 위젯 이름을 짓는것은 매우 흔한(그리고 추천되는) 방식입니다. 다음으로 해야 일은 Quit버튼을 생성하고 크기를 설정하는 입니다 :

       CEGUI::Window *quit = win->createWindow("TaharezLook/Button", "CEGUIDemo/QuitButton");

       quit->setText("Quit");

       quit->setSize(CEGUI::UVector2(CEGUI::UDim(0.15, 0), CEGUI::UDim(0.05, 0)));

무슨 암호문을 놓은것 처럼 보이는군요. CEGUI 크기와 위치에 대해서 "unified dimension" 시스템을 사용합니다. 크기를 설정할때는 반드시 UDim객체를 만들어서 원하는 크기를 설정한다음 생성될 객체에게 알려줘야 합니다. 첫번째 매개변수는 부모객체에대한 상대적인 크기입니다. 두번째 매개변수는 절대적인 객체크기(필셀단위)입니다. 중요한게 하나 있는데 두개의 매개변수들 반드시 한가지 매개변수만 설정해야 합니다. 설정하지 않은 매개변수는 반드시 0 되어야 합니다. 그래서 코드의 경우는 부모객체크기의 15%가로길이와 5% 세로길이를 가집니다. 만약 20x5픽셀크기로 설정하고 싶다면 2가지 UDim객체들의 두번째 매개변수를 20 5 각각 설정하면 됩니다.

마지막으로 해야 일은 시트에 Quit버튼을 attach하는 입니다. 다음 현재 GUI시트를 시스템에 적용 시킵니다 :

       sheet->addChildWindow(quit);

       mSystem->setGUISheet(sheet);

이제 실행시켜보면 화면의 좌측 상단에 Quit버튼이 자리잡고 있음을 확인할 있을겁니다. 그러나 아직까지는 클릭해도 아무런 변화가 없습니다.

이벤트

CEGUI에서 이벤트는 유연한 성질을 가지고 있습니다. 이벤트를 받기위해 인터페이스를 사용하는것 대신에 콜백 방식을 이용해서 사용자가 원하는 public 함수(특정한 함수형태를 만족하는) 바인딩 시켜서 이벤트를 다룰 있습니다. 아쉽게도 이벤트를 등록시키는 작업은 오우거의 경우보다 약간 복잡한 절차를 가집니다. 이제 Quit버튼의 클릭이벤트에 프로그램 종료기능을 등록해 봅시다. 그러기 위해서 이전 섹션에서 만든 Quit버튼의 포인터가 필요합니다. TutorialListener생성자로 가서 다음 코드를 추가하세요 :

       CEGUI::WindowManager *wmgr = CEGUI::WindowManager::getSingletonPtr();

       CEGUI::Window *quit = wmgr->getWindow((CEGUI::utf8*)"CEGUIDemo/QuitButton");

이제 Quit버튼 포인터를 얻었습니다. 이제는 클릭이벤트를 작성해 봅시다. 모든 CEGUI 위젯들은 사용가능한 이벤트셋트를 가지고 있으며 "Event"라는 이름으로 시작합니다. 이것이 클릭이벤트를 기술하는 코드입니다 :

       quit->subscribeEvent(CEGUI::PushButton::EventClicked,

           CEGUI::Event::Subscriber(&TutorialListener::quit, this));

subscribeEvent 첫번째 매개변수는 자기 자신에 대한 이벤트입니다. 두번째 매개변수는 Event::Subscriber객체입니다. Subcriber 생성될때 첫번째로 넘겨주는 값은 이벤트를 다루게 함수입니다(& 기호는 함수의 포인터를 가져다 줍니다). 두번째로 넘겨주는 값은 이벤트를 다룰 TutorialListener 객체입니다(이번 경우는 "this" 객체). 완성입니다! TutorialListener::quit함수(미리 작성되어진) 마우스클릭이벤트를 다루며 프로그램을 종료시킵니다.

컴파일 실행시켜서 테스트해 보세요.

 

CEGUI에서 이벤트를 다루는 함수들의 생성횟수에는 아무런 제약이 없습니다. 한가지 제약사항은 반드시 불리언타입의 결과값을 리턴해야 하며 1개의 "const CEGUI::EventArgs &" 방식의 매개변수만을 취해야 한다는 입니다. 이벤트들에 대해서 알고 싶은게 있다면(그리고 어떻게 이벤트등록을 취소시키는지) CEGUI 공식홈페이지를 참고하세요.

텍스쳐에 렌더링하기

CEGUI 있는 흥미로운 작업중 하나는 Render To Texture 윈도우를 생성하는 입니다(RTT 튜토리얼- http://www.ogre3d.org/wiki/index.php/RTT). RTT 이용하면 CEGUI위젯으로 직접적으로 그려지는 또다른 뷰포트를 생성할 있게 됩니다. 먼저 해야 일은 바라볼 장면을 설정해야 합니다. 다음 코드를 createScene 하단에 추가하세요 :

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

       mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8);

       Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");

       SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0, 0, -300));

       headNode->attachObject(ogreHead);

이제 RenderTexture 생성해야 합니다. RenderSystem객체는 텍스쳐에 렌더링하는 기능을 제공합니다. 일단 TextureManager::createManual함수를 이용해서 텍스쳐를 하나 생성합니다. 프로그램에서는 512 x 512크기의 텍스쳐를 사용할 계획입니다 :

       RenderTexture *tex= mRoot->getTextureManager()->createManual

                                  ("R2TTex", "Default", TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET)

                                   ->getBuffer()->getRenderTarget();

함수에 대한 자세한 정보는 API 레퍼런스를 참고하세요. 다음으로 해야 일은 카메라와 앞서 작성된 장면을 바라보는데 쓰일 뷰포트를 생성하는 입니다. Overlay 끈것을 포함해서 뷰포트 옵션들 2개가 바뀐것에 유의하세요. 것은 매우 중요합니다. 그렇지 않으면 CEGUI 얻고 작은 윈도우안에 오우거 Overlay 표시하게 겁니다.

       Camera *cam = mSceneMgr->createCamera("R2TCam");

       cam->setPosition(100, -100, -400);

       cam->lookAt(0, 0, -300);

 

       Viewport *v = tex->addViewport(cam);

       v->setOverlaysEnabled(false);

       v->setClearEveryFrame(true);

       v->setBackgroundColour(ColourValue::Black);


다름아닌 텍스쳐 내부에 뷰포트를 추가했습니다(평상시 뷰포트를 추가하던 RenderWindow 경우와는 다릅니다). 여기까지 장면과 텍스쳐를 만들었습니다. 이제는 CEGUI안에 내장시킬 차례입니다. OgreCEGUIRenderer::createTexture함수를 사용해서 어떤 오우거 텍스쳐에서도 CEGUI::Texture 생성할 있습니다 :

       CEGUI::Texture *cTex = mRenderer->createTexture((CEGUI::utf8*)"R2TTex");

아쉽게도 복잡해지는 부분을 하나 언급하고자 합니다. CEGUI 사용하면서 1개의 텍스쳐나 1개의 이미지만을 사용할 수는 없습니다. CEGUI 개별 이미지들 대신에 이미지셋트를 사용합니다. 전체가 격자모양으로 구성된 이미지셋트는 스킨의 Look and Feel 구성할때 매우 유용하게 쓰입니다(예제로 SDK 포함된 media폴더안의 TaharezLook.tga파일을 열고 어떻게 구성되어 있는지 보세요). 하지만 비록 1 이미지만 사용해야 한다해도 전체 이미지셋트를 생성해야 합니다. 이렇게 해야 합니다 :

       CEGUI::Imageset *imageSet = CEGUI::ImagesetManager::getSingleton().createImageset((CEGUI::utf8*)"R2TImageset", cTex);

       imageSet->defineImage((CEGUI::utf8*)"R2TImage",

           CEGUI::Point(0.0f, 0.0f),

           CEGUI::Size(cTex->getWidth(), cTex->getHeight()),

           CEGUI::Point(0.0f,0.0f));

첫번째 라인에서 미리 제공한 텍스쳐로부터 이미지셋트("R2TImageset") 생성합니다. 다음라인(defineImage호출부분)에서는 첫부분이자 유일한 이미지 "R2Timage" 설정하고 크기를 전체 cTex텍스쳐와 동일하게 맞춰줍니다. 마지막으로 렌더텍스쳐를 표시할 StaticImage 위젯을 생성해야 합니다. 첫번째 부분은 다른 윈도우생성과 동일합니다 :

       CEGUI::Window *si = win->createWindow((CEGUI::utf8*)"TaharezLook/StaticImage", "R2TWindow");

       si->setSize(CEGUI::UVector2(CEGUI::UDim(0.5f, 0), CEGUI::UDim(0.4f, 0)));

       si->setPosition(CEGUI::UVector2(CEGUI::UDim(0.5f, 0), CEGUI::UDim(0, 0)));

이제 출력될 StaticImage위젯을 설정합니다. 다시 언급하자면 CEGUI 각각의 이미지들 대신에 이미지셋트를 다루므로 이미지가 출력되기 위해서는 전체 이미지셋트로부터 정확한 이미지이름을 추출해 줘야 합니다 :

       si->setProperty("Image", CEGUI::PropertyHelper::imageToString(&imageSet->getImage((CEGUI::utf8*)"R2TImage")));

만약에 한개의 이미지를 그냥 unpack시키기 위해서 이미지셋트로 pack시키는 작업처럼 보였다면 제대로 보신겁니다. CEGUI에서 이미지를 조작하는 작업은 쉽지 않은일 입니다. 마지막으로 해야 일은 StaticImage위젯을 미리 만들어 두었던 GUI시트에 추가하는 입니다 :

       sheet->addChildWindow(si);

이제 끝입니다. 컴파일 실행하세요.

결론

대안으로 쓸만 것들

CEGUI 희안하고 단점도 있습니다. 그리고 절대 모든 사용자를 위한 라이브러리도 아닙니다. 여기 CEGUI 대신에 쓸만한 대안들이 있습니다 :

*                   QuickGUI

*                   BetaGUI

*                   MyGUI

*                   Navi

*                   Right Brain Games GUI

 

자세한 정보

CEGUI 대해서 알고 싶다면 사이트들을 참고하세요.

*                   Practical Application - Something With A Bit More Meat - A more in-depth tutorial than the one here.

*                   CEGUI's Official Tutorials

*                   The CEGUI Website

 

출처 : http://begin.pe.kr/category/Ogre3D%20삽질란/Basic%20Tutorial%207

신고
Posted by 우엉 여왕님!! ghostkyow

티스토리 툴바