[DirectX] IMGUI - CameraUI


지난 포스트에 이어서 UI를 구성해보자.

CameraUI 클래스의 구성


// 헤더파일

#pragma once
#include "ComponentUI.h"
class CameraUI :
    public ComponentUI
{

public:
    virtual int render_update() override;

public:
    CameraUI();
    ~CameraUI();
};


// cpp 파일

#include "pch.h"
#include "CameraUI.h"


CameraUI::CameraUI()
    : ComponentUI("##Camera", COMPONENT_TYPE::CAMERA)
{
    SetName("Camera");
}

CameraUI::~CameraUI()
{
}

int CameraUI::render_update()
{
    if (FALSE == ComponentUI::render_update())
        return FALSE;

    return TRUE;
}


Editor Camera의 구현


// CRenderMgr.h 중에서

void RegisterEditorCamera(CCamera* _Cam) { m_pEditorCam = _Cam; }

렌더 매니저에서 에디터 카메라에 대한 변수를 추가해준다.

// CEditorObjMgr.h 중에서

#pragma once

class CGameObjectEx;

class CEditorObjMgr
	: public CSingleton<CEditorObjMgr>
{
	SINGLE(CEditorObjMgr);
private:
	vector<CGameObjectEx*>	m_vecEditorObj;

	CGameObjectEx*			m_DebugShape[(UINT)SHAPE_TYPE::END];
	vector<tDebugShapeInfo> m_DebugShapeInfo;

public:
	void init();
	void progress();

private:
	void tick();
	void render();
};


// CEditorObjMgr.cpp 중에서

	// EditorObject 생성
	CGameObjectEx* pEditorCamObj = new CGameObjectEx;
	pEditorCamObj->AddComponent(new CTransform);
	pEditorCamObj->AddComponent(new CCamera);
	pEditorCamObj->AddComponent(new CCameraMoveScript);

	pEditorCamObj->Camera()->SetLayerMaskAll(true);

	m_vecEditorObj.push_back(pEditorCamObj);
	CRenderMgr::GetInst()->RegisterEditorCamera(pEditorCamObj->Camera());
// CRenderMgr.cpp 중에서 두 함수

void CRenderMgr::render_play()
{
    // 카메라 기준 렌더링
    for (size_t i = 0; i < m_vecCam.size(); ++i)
    {
        if (nullptr == m_vecCam[i])
            continue;

        m_vecCam[i]->SortObject();
        m_vecCam[i]->render();
    }
}

void CRenderMgr::render_editor()
{
    m_pEditorCam->SortObject();
    m_pEditorCam->render();    
}

렌더 매니저에서 렌더링 상황 두 종류를 만들어준다(Play, Editor)
이때 render_play는 메인 카메라 기준으로 렌더링하는 것이고,
render_editor는 에디터 카메라를 통해서 렌더링이 되는 것이다.

어떤 카메라로 렌더링을 할 지는 레벨의 상태에 따라서 결정이 되는 것이다.

// CRenderMgr.cpp 중에서 render 함수

void CRenderMgr::render()
{
    // 렌더링 시작
    float arrColor[4] = { 0.f, 0.f, 0.f, 1.f };
    CDevice::GetInst()->ClearTarget(arrColor);

    // 출력 타겟 지정    
    CDevice::GetInst()->OMSet();

    // 광원 및 전역 데이터 업데이트 및 바인딩
    UpdateData();

    // 렌더 함수 호출
    (this->*RENDER_FUNC)();
    
    // 광원 해제
    Clear();
}

상태 변수는 define.h에다가 선언해준다.

// define.h 중에서

enum class LEVEL_STATE
{
    PLAY,
    PAUSE,
    STOP
}


CLevel Class의 재구성


그리고 레벨의 상태를 변경할 수 있도록한다.

생성자를 통해 기본 상태는 STOP으로 결정해주고, ChangeState함수를 통해서 레벨을 바꿀 수 있도록 조작한다.

// CLevel.cpp 중에서

void CLevel::ChangeState(LEVEL_STATE _State)
{	
	m_State = _State;

	if (LEVEL_STATE::PLAY == m_State)
	{
		CRenderMgr::GetInst()->SetRenderFunc(true);
	}
	else
	{
		CRenderMgr::GetInst()->SetRenderFunc(false);
	}
}

그리고 멤버함수 포인터를 조작하는 함수를 CRenderMgr에다가 만들어준다.

// CRenderMgr.cpp 중에서 SetRenderFunc 함수

void CRenderMgr::SetRenderFunc(bool _IsPlay)
{
    if(_IsPlay)
        RENDER_FUNC = &CRenderMgr::render_play;
    else
        RENDER_FUNC = &CRenderMgr::render_editor;
}


Stop 상태에서 레벨을 멈추기


정지 상태라면 레벨이 멈춰야할 것이다.

CLevelMgr에서 조건을 달아줘서 이를 조절할 수 있다.

레벨의 상태가 stop이면 tick이 돌지 않도록 만드는 것이다.

// CLevelMgr.cpp 중에서 tick함수의 수정

void CLevelMgr::tick()
{
	m_pCurLevel->clear();

	if (LEVEL_STATE::PLAY == m_pCurLevel->GetState())
	{
		m_pCurLevel->tick();		
	}	

	m_pCurLevel->finaltick();
}

사실 지금 상태는 Stop상태보단 Pause 상태를 구현한 것에 더 가깝다.

그리고 Pause 상태면 이어서 동작할 수 있도록 구현해야하지만, Stop이면 Play하기 이전의 원 상태로 복귀시켜야한다.

이를 어떻게 구현할 수 있을까?

초기 레벨을 복사해놓으면 된다.

이를 위해선 레벨을 저장하고 로드하는 기능을 구현해야한다.

그 과정은 나중에 진행하기로 한다.


© 2022.07. by Wookey_Kim

Powered by Hydejack v7.5.2