이전에 올린 포스트 대로 리뉴얼을 진행 중입니다. 말이 리뉴얼이지 거의 새로 코딩하다 시피하고 있습니다. 이전 코드를 참고 하다 보니 "어떤놈이 이딴 식으로 코딩해놓은거야?? 버럭!!", "너 잖아!!!" 같은 코드가 많이 보이네요.

일단 이왕 리뉴얼 하는거 초반에는 간략하게 넘어간 C# 기반으로 제작한 부분을 좀 자세하게 포스팅 해볼까 합니다. 기본적인 내용은 밑의 링크를 참고하시고 미리 읽어보시면 본내용이 쉽게 이해 가실겁니다.

일단 프로젝트를 만듭니다. 총 3개의 프로젝트가 필요합니다. 밑의 스샷은 현재 제 프로젝트 모습입니다. 여기서 처음 밝히는데 프로젝트 이름은 EVE입니다. Evolution V Engine 이라는 되도 않는 이름을 붙여놓은 개인 프로젝트지요. 그 동안 부끄러워서 가려뒀었는데... 역시 부끄럽네요. ( 주: TestClient의 경우 C#과는 무관한 Win32으로 직접 실행을 위한 프로젝트입니다 )


여기서 주의해야 할 점은 빌드 순서입니다. 정확히 Lib -> DLL -> C# 순으로 빌드가 이루어져야 합니다. 이를 위해서 [ 솔루션 속성 페이지 ] -> [ 프로젝트 종속성 ] 란에 가셔서 EVEToolDLL은 EVE에 종속, EVEToolSet은 EVEToolDLL에 종속 식으로 종속성을 설정해주어야 전체 빌드를 수행할때 순서대로 빌드가 진행됩니다.

프로젝트 설정이 끝나면 이제 윈폼을 이용해 프로그램이 실행될 윈도우를 이쁘게 만들어 주어야합니다. C#의 강력한 장점 중 하나인 윈폼은 드래그 & 드랍으로 윈도우를 손쉽게 이쁘게 만들수 있습니다. ( MFC와는 다르다!! MFC 와는!! )


뚝딱뚝딱~ 만들어 줍니다. 위에 빨간색으로 체크해둔 컨트롤은 PictureBox인데 이 컨트롤을 이용해 DirectX로 렌더링 할 부분을 설정 할 수 있습니다. Win32 API로 직접 윈도우를 제작하는 것이 아닌 만큼 DirectX에 렌더링 할 곳을 지정 해주어야 하는데 PictureBox 컨트롤의 핸들을 넘겨주어 이 부분을 쉽게 설정할 수 있습니다.

다음은 C#의 실행 부분을 다음과 같이 수정해줍니다.

// Program.cs
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    // 이전 실행 코드
    //Application.Run(new MainWindow());

    // 새로운 실행 코드
    MainWindow pForm = new MainWindow();
    pForm.Show();
    pForm.Focus();
    pForm.Initialize();
}

그리고 메인 윈도우 CS 부분에 Initialize 함수에서 EVEToolDLL의 어플리케이션을 초기화해주는 코드를 집어넣으면 되죠. 이제 EVEToolDLL 부분을 보도록 하죠. 이쪽 부분은 단지 환경이 공용 언어랄 뿐이지 기존 Win32에서 DirectX를 이용한 코딩을 하는 것과 별반 다를게 없습니다.

먼저 Tool 제작에 필요한 엔진 라이브러리 헤더와 Lib 파일 설정을 Pre-compile 헤더에 설정해둡니다. Pre-compile 설정은 밑의 링크를 참조 해주세요.

// Precompiled.h
// EVE 헤더 포함
#include "Renderer/evRenderer.h"
#include "Renderer/evRendererDX9Deferred.h"

// EVE 정적 라이브러리 로드
#ifdef _DEBUG
#pragma comment ( lib, "EVE_d.lib" )
#else
#pragma comment ( lib, "EVE.lib")
#endif


이제 EVEToolDLL 에서 엔진 API를 사용 가능합니다. 초기화 함수, 메인 루프 함수, 메시지 프로시저 함수 등등~ 코딩을 합니다. 이 부분들은 각종 오픈 소스 엔진이나 게임 실행 부분등을 참고하시면 됩니다. CLR 환경이지만 그냥 Win32/C++ 코딩 하듯이 쭉쭉~ 코딩 해주시면 됩니다.

void CEVEToolAppliction::Run( IntPtr hRenderView )
{
	m_pRenderer = (ev_IRenderer*)new ev_CRendererDX9Deferred();
	m_pRenderer->Initialize( (HWND)hRenderView.ToPointer() );

	MainLoop();

	Safe_Delete( m_pRenderer );
}

초기화 부분은 대충 위와 같이 코딩했다고 칩니다.

void CEVEToolAppliction::MainLoop( void )
{
	// 메시지 루프
	MSG msg;
	ZeroMemory( &msg, sizeof(msg) );
	while( WM_QUIT != msg.message )
	{
		// 종료 플래그 검사
		if( m_bExitFlag )
			break;

		// 메시지큐에 메시지가 있으면 메시지 처리
		if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			m_pRenderer->Render();
		}
	}
}
메인 루프 부분은 대충 이런 모양이겠죠. 이제 거의 끝나갑니다. 이제 이것을 C#과 연결 시켜줘야 합니다. 


일단 EVEToolDLL을 빌드하여 DLL 파일로 만들고, C# 프로젝트 부분에 참조 카테고리에서 마우스 오른쪽 클릭을 하여 [ 참조 추가 ]를 통해 빌드한 DLL을 추가합니다. 이것으로 EVEToolDLL의 클래스들을 사용할 수 있습니다. 참 쉽죠~?

private CEVEToolAppliction m_EVEToolApp;
public void Initialize()
{
    m_EVEToolApp = new CEVEToolAppliction();
    m_EVEToolApp.Run(this.Handle, RenderView.Handle);
}
protected override void WndProc(ref Message m)
{
    if (m_EVEToolApp != null)
        m_EVEToolApp.MessageProc(this.Handle, m.Msg, m.WParam, m.LParam);

    base.WndProc(ref m);
}

참조 추가를 한 후에 위와 같이 EVEToolDLL에서 작성한 클래스를 사용하는 모습니다. 맨 밑의 함수를 잘 보시면 윈도우 메시지를 처리하는 부분이 있습니다. C#의 윈폼을 통해 프로그램을 실행하는 만큼 윈폼의 윈도우 메시지를 받아내야 할 필요가 있습니다. 이 부분은 DLL에서 자체적으로 해결할수 있는 부분이 아닌 만큼 윈폼의 윈도우 프로시저 함수를 오버라이드 하여 메시지를 DLL 쪽에 직접 뿌려줘야 합니다.

다시 EVEToolDLL쪽으로 가서 메시지를 처리할 함수를 만들어줍니다.

bool CEVEToolAppliction::MessageProc( IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam )
{
	switch (uMsg)
	{
	case WM_DESTROY:
		{
			PostQuitMessage(0);
			return false;
		}
	case WM_KEYUP:
		{
			switch( (WPARAM)wParam.ToPointer() )
			{
			case VK_ESCAPE:
				{
					m_bExitFlag = true;
					break;
				}
			}
		}
		break;
	}

	return true;
}
이제 모든 기본적인 설정이 끝났습니다. ToolSet을 실행 해보면 윈폼에 이쁘게 렌더링 되는 모습을 보실 수 있습니다.


+ Recent posts