중급 튜토리얼 6-1

Ogre3D 삽질란/Intermediate Tutorial 6 2009. 1. 7. 13:58

중급 튜토리얼 6 (번역 : n_Sys)

중급 튜토리얼 6: 데칼 투영하기(Projective Decals)

튜토리얼 진행에 있어서 문제가 생긴다면 Help Forum 문의하세요.

목차

                               1 소개

                               2 시작하기

                                       2.1 스쳐

                                       2.2 코드

                               3 데칼 투영하기

                                       3.1 절두체

                                       3.2 재질 변경

                                       3.3 함수호출

                               4 뒷면투영현상 거하기

                                       4.1 소개

                                       4.2 하기

                                       4.3 재질 하기

                               5 하게 하기

                                       5.1

                                       5.2 Field of View 하기

                               6 마디

 

소개

이번 튜토리얼에서는 객체에 투영된 데칼을 장면속에 추가하는 방법을 다룹니다. 지면상의 표시점이나 조준점 또는 뭔가에 투영되어 표시되는 데칼을 표시해야 텍스쳐를 투영시키는 방법이 유용하게 쓰입니다(스플래팅처럼 목표객체가 영구히 바뀌지는 않습니다). 조준점이 투영된 오우거머리의 스크린 입니다 :



튜토리얼에 대한 코드는 여기 찾을 있습니다. 내용을 천천히 진행하면서 완성되어지는 결과물을 직접 확인하세요.

 

 

시작하기

새로운 텍스쳐

프로젝트를 시작하기전에 앞으로 사용하게될 2개의 이미지를 추가해야 합니다. 다음 2개의 그림파일 링크를 오른버튼 클릭으로 오우거가 참조할 있는 위치에 저장하세요 : decal.png decal_filter.png

제일 무난한 위치는 media/materials/textures 폴더입니다(대부분 사람들의 OgreSDK 포함되어 있을 입니다).

초기 코드

프로젝트에 cpp파일을 하나 생성하고 다음 코드를 추가하세요 :

#include "ExampleApplication.h"

 

// A FrameListener that gets passed our projector node and decal frustum so they can be animated

class ProjectiveDecalListener : public ExampleFrameListener

{

public:

    ProjectiveDecalListener(RenderWindow* win, Camera* cam, SceneNode *proj, Frustum *decal)

        : ExampleFrameListener(win, cam), mProjectorNode(proj), mDecalFrustum(decal), mAnim(0)

    {

    }

 

    bool frameStarted(const FrameEvent& evt)

    {

        return ExampleFrameListener::frameStarted(evt);

    }

 

protected:

    SceneNode *mProjectorNode;

    Frustum *mDecalFrustum;

    float mAnim;

};

 

class ProjectiveDecalApplication : public ExampleApplication

{

protected:

    SceneNode *mProjectorNode;

    Frustum *mDecalFrustum;

    Frustum *mFilterFrustum;

 

    void createScene()

    {

        // Set ambient light

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

 

        // Create a light

        Light* l = mSceneMgr->createLight("MainLight");

        l->setPosition(20,80,50);

 

        // Position the camera

        mCamera->setPosition(60, 200, 70);

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

 

        // Make 6 ogre heads (named head0, head1, etc.) arranged in a circle

        Entity *ent;

        for (int i = 0; i < 6; i++)

        {

            SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

            ent = mSceneMgr->createEntity("head" + StringConverter::toString(i), "ogrehead.mesh");

            headNode->attachObject(ent);

            Radian angle(i * Math::TWO_PI / 6);

            headNode->setPosition(75 * Math::Cos(angle), 0, 75 * Math::Sin(angle));

        }

    }

 

    // The function to create our decal projector

    void createProjector()

    {

    }

 

    // A function to take an existing material and make it receive the projected decal

    void makeMaterialReceiveDecal(const String &matName)

    {

    }

 

    // Create new frame listener

    void createFrameListener(void)

    {

        mFrameListener= new ProjectiveDecalListener(mWindow, mCamera, mProjectorNode, mDecalFrustum);

        mRoot->addFrameListener(mFrameListener);

    }

};

 

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

#define WIN32_LEAN_AND_MEAN

#include "windows.h"

#endif

 

#ifdef __cplusplus

extern "C" {

#endif

 

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

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

#else

    int main(int argc, char **argv)

#endif

    {

        // Create application object

        ProjectiveDecalApplication 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

            std::cerr << "An exception has occurred: " << e.getFullDescription();

#endif

        }

 

        return 0;

    }

 

#ifdef __cplusplus

}

#endif

컴파일 실행시켜보세요. 6개의 오우거머리가 보일것입니다.

 


: