article search result of 'ToolFramwork' : 1

  1. 2014.03.26 [ToolFramewrok] 게임엔진과 툴을 연결하는 구조 1

[ToolFramewrok] 게임엔진과 툴을 연결하는 구조 1

최근 백수라 집에서 놀다보니, 여행을 가고 싶지만 여러여건상 이것도 쉽진 않군요( 언제나 갈 예정임 ㅋ)

 

뭐 여하튼!!

 

집에서 쉬다보니  컨디션도 꽤 좋아졌고 해서 예전에 KGC2011에서 강연했던 주제를 제대로 정리하고자 하는 시간을 갖으려 합니다. ㅎㅎ 오늘이 그 첫번째 시간이군요. 이게 총 몇개로 이루어질지는 모르겠지만 해보는데까지 해봅시다. 먼저 앞으로의 계획을 대략적으로 정리하자면 아래와 같습니다.

 

- 엔진과 툴의 이종간 연동을 위한 구조 설계( DLL Interop을 이용 C/S모델로 설계해서 C++과 C#을 적절히 사용 )

- WPF(C#) 에서 Navtive DirectX Rendering 하기 (엔진의 Rendering 기능을 연결해서 WPF 컨트롤러에 붙이는 거 )

- 툴 자체를 Plug-In 구조로 설계해서 각각의 기능을 독립적으로 묶고 관리 하며 무한한 기능확장(?) 구조 설계

- TCP/IP를 이용, 원격지에 있는 툴 조종 및 행동 반영

 

아.... 그냥 막 생각하려니까 좀 이상하군요 ㅎㅎ 조금 더 부연 설명을 하자면 별것들 아닌데

첫번째는 KGC2011에서 강연 했던 주요 내용이구요.

두번째도 강연에서 잠깐 나왔던 건데, 그때 당시에는 자세히 다루지 않았죠. (간단함..hWndHost를 이용하는 거)

세번째는 언젠가 설계했던 건데 당장은 잘 기억 안나므로 제대로 정리 할 수 있을까? 싶은 의문이 듬

네번째는 KGC 강연때 마지막에 "이러 이렇게 하면 이런게 된다!" 라고 말했던 걸 만들어서 정리해볼려고 함.

 

막상 이렇게 조금이라도 정리해보니 대단한 여정이 될꺼 같네요(?) 끝까지 갈 수 있을런지......ㅡ_ㅡ

 

먼저 왜 이러한 주제를 택했고 어디서 어떻게 시작이 되었는가를 잠깐 살펴보자면, 이거 한장으로 모든 설명이 끝날 것 같다.

 

 

 

현재에도 많은 게임 엔진을 C++로 만들고, 이 추세는 앞으로 꽤 지속 될꺼라 생각합니다. 다만 C++의 툴 생산성은 꽤나 좋지 못하다고 생각하는데, 그나마 대안이 될만한게 WPF이지 않을까 싶습니다. ㅎ

윈폼도 써보고 MFC도 써봤지만 (MFC는 오래전에 ㅎㅎ ) UI 구성부터 시작해서 제대로 View와 모델을 구분하지는 못한것 같고 가장 크게 다가오는 것은 UI  구성이 꽤나 어렵지요.

 

WPF는 기존 MVC나 MVP와는 좀 다른 MVVM 패턴이라는데 ( http://msdn.microsoft.com/ko-kr/magazine/dd419663.aspx / WPF의 MVVM 패턴 )

 

저도 MVVM이니 MVC 잘 모릅니다. ㅎㅎ 다만 핵심적인 것은 View 코드와 비즈니스로직 코드를 완전히 분리한다 라고 이해 하시면 될 것 같습니다. View코드라 하면 UI를 구성 짓는 코드이고, 비즈니스 코드는 실질적 기능 구현에 쓰이는 코드 입니다

 

자..자세한건 링크를... 저는 몇번 봐도 계속 까먹어서 ㅎㅎㅎ

 

Anyway 원래 주제로 돌아가서 C#으로 툴을 만드는 것 까지는 좋은데, 문젠 C++로 만들어져 있는 게임 엔진 기능을 쓰기가 참 애매합니다. 전통적인 방법 중 하나로 C++/CLI 가 있는데요. CLI 은 Common Language In.... 머시기인데요. C++과 C#의 "중간계" 정도로 보시면 됩니다. ㅎㅎ 물론 이 C++/CLI를 사용해서 연동을 해도 되구요 C/S 모델도 사용 할 수 있습니다. 다만 개인적으로 모호한 "중간계"를 사용하고 싶지 않네요. C++/CLI에서 가장 난해한 부분은 Native 메모리들을 Managed 영역으로 맞춰주는 작업인데 이게 햇갈리는 부분이 좀 있네요. 물론 인터페이스를 단순화 한다면 이러한 부분도 해결은 되겠죠.

 

또 개인적으로 C++/CLI은 거의 사용을 안해봐서 잘 모릅니다.

 

그래서 깔끔하게 순수 C Dll을 택했고, Dll Interop을 통해서 C#에서 함수들을 사용합니다.

 

간단하게 이 구조의 모습은 다음과 같습니다

 

 

밑에 화살표는 무시하고, 툴 <-> DLL( Engine DLL ) 요런 모습입니다.

 

 

이게 현재 Version 0.1ToolFramwork 솔루션 모습입니다. 이건 앞으로 연재를 해가면서 계속 발전 할겁니다. ㅎㅎ RenderingTool 프로젝트는 사실상 빈 깡통이구요. 각 설명을 하자면

 

- ClientLauncher : Client런처 입니다  exe이고 엔진을 lib 또는 dll로 링크 하고 있습니다. WinMain을 가지고 있고, 현재로썬 딱히 하는게 없어요. 엔진 초기화 해서 돌리는 게 전부 입니다. 실제로 게임 로직이 들어가진 않아요.

 

- FrameWork : 아주 옛날에 만들어 둔건데 ㅋㅋ 제 블로그 뒤지면 스샷도 나오죠(...) 이건 원래 두개로 쪼갤려고 했는데 (game 로직 / engine ) 너무 귀찮으니... 그냥 게임 엔진이라고 생각하시면 됩니다. ㅎㅎ 아 이게 언젠가 DirectX 11으로 간단한 렌더러로 바꿀 생각이에요. ㅋ 물론 언제 그런 날이 올진 모르겠군요. 일단 예제 샘플로 쓰기에 좋음

 

- ToolInterface : 실제로 위에 그림에서 "DLL" 기능이고 툴의 기능적 로직들( 게임 엔진을 사용해야 하는 기능들 )이 이곳에 모두 들어갑니다. 그리고 중요한 Dll 통신용 인터페이스들을 Export 하고 있죠. 물론 그외에 다른 함수는 일절 Export 하지 않습니다. 오직 통신에 쓰이는 인터페이스 몇개만 Export 합니다.

 

- RenderingTool : 앤 아직 깡통...

 

이렇게 보니까 매우 심플하죠? 아닌가요 ㅋ 실질적으로 빌드해서 나오는 것은 ToolInterface.dll / Framework.dll / RendringTool.exe 이 3개 입니다. ClientLauncher는 그냥 디버깅용(?)으로 넣어둔 거라 큰 의미는 없고 소스 배포 할 때에도 빼 버릴까 생각 중입니다. ㅎㅎ 괜히 혼란만 가중 시킬꺼 같아서...

 

이제 우리가 살펴봐야 할 것은 ToolInterface 부분이며, 가장 먼저 Export 하는 부분을 봅시당

 

ToolInterface의 파일 뷰

 

// DllExport.h

#pragma once

#define DLL_EXPORT __declspec(dllexport)

extern "C"
{
	// 툴 인터페이스 초기화
	DLL_EXPORT void* InitalizeWindow( ::HINSTANCE applicationInstance, ::HWND hWndParent, int screenWidth, int screenHeight, const char* pAssetPath );

	// 툴 인터페이스 해제
	DLL_EXPORT void Start();
	DLL_EXPORT void Stop();

	DLL_EXPORT bool Send( const char* pCommand, void* pData, unsigned int dataSize );
	DLL_EXPORT bool SendOutput( const char* pCommand, void* pData, unsigned int dataSize, void*& pOutputData, unsigned int& outputDataSize );
	
}

 

딱 정확히 5개의 함수만 익스포트 시킵니다. ㅎㅎ 저걸로 모든 툴의 기능을 다 만들 수 있고 나중에 더 재미난 기능들도 가능하죠. 그리고 이것들은 한번만 만들어두면 앞으로 거의 왠만해선 고칠 일이 없습니다.

여기서 짚고 넘어가야 할 부분은 Send 와 SendOutput 인데요. 사실 이 함수들은 ToolInterface.dll -> WPF(C#) 으로 데이터를 보내는 함수가 아닌, 반대로 WPF(C#) -> ToolInterface.dll 함수들 입니다.

 

이는 WPF 입장에서 봤을 때 Send이기 때문에 이렇게 이름 지은 거구요. ToolInterface.dll 입장에서 봤을 때는 Recv나 Get 정도의 의미입니당. 실제로 저 안에서 하는 일도 데이터를 받아와서 해당 Command로 넘겨주고 기능들을 처리 하는 일입니다.

 

아, 오늘은 여기까지 써야겠네요. 시간이 너무 늦어서 ㅎㅎ 나머진 내일...

칼루
나만의 강의 2014. 3. 26. 02:11
,
Powerd by Tistory, designed by criuce
rss