MFC 기반의 Direct3DX Window

Dev.Write 2010. 1. 15. 05:28 Posted by zetz
CWnd를 상속받아 구현한 DXWnd.
Render() 부분을 어떻게 처리하는게 좋을까?
1. 함수포인터?
2. 상속?
3. 그냥 파일 복사해서 직접 수정해!!!


CD3DX9Wnd.h
#pragma once
#include "afxwin.h"

#include 
#include 

#pragma comment( lib, "d3d9" )
#pragma comment( lib, "d3dx9" )
#pragma comment( lib, "winmm" )


#include 

#define D3DX9WND_CLASSNAME		_T("MFCD3dx9Window")

class CD3DX9Wnd :
	public CWnd
{
public:
	CD3DX9Wnd(void);
	~CD3DX9Wnd(void);

	LPDIRECT3DDEVICE9	GetD3DDevice() {	return m_pd3dDevice;	}

	BOOL		InitD3dx9();
	void		KillD3dx9();
	void		Render();

	DECLARE_MESSAGE_MAP()
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnPaint();

private:
	LPDIRECT3D9				m_pD3d;
	LPDIRECT3DDEVICE9		m_pd3dDevice;
};


CD3DX9Wnd.cpp
#include "StdAfx.h"
#include "D3DX9Wnd.h"


BOOL	RegisterWindowClass()
{
	WNDCLASS	wndcls;
	HINSTANCE	hInst = AfxGetInstanceHandle();

	if ( !(::GetClassInfo(hInst, D3DX9WND_CLASSNAME, &wndcls)) )
	{
		wndcls.style            = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
		wndcls.lpfnWndProc      = ::DefWindowProc;
		wndcls.cbClsExtra       = wndcls.cbWndExtra = 0;
		wndcls.hInstance        = hInst;
		wndcls.hIcon            = NULL;
		wndcls.hCursor          = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
		wndcls.hbrBackground    = (HBRUSH) (COLOR_3DFACE + 1);
		wndcls.lpszMenuName     = NULL;
		wndcls.lpszClassName    = D3DX9WND_CLASSNAME;

		if (!AfxRegisterClass(&wndcls))
		{
			AfxThrowResourceException();
			return FALSE;
		}
	}
	return TRUE;
}


CD3DX9Wnd::CD3DX9Wnd(void)
:m_pD3d(NULL), m_pd3dDevice(NULL)
{
	RegisterWindowClass();	
}

CD3DX9Wnd::~CD3DX9Wnd(void)
{
	KillD3dx9();
}


void	CD3DX9Wnd::Render()
{
	m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, RGB(255, 0, 0), 1.0f, 0 );


	if ( m_pd3dDevice->BeginScene() )
	{
		m_pd3dDevice->EndScene();
		m_pd3dDevice->Present(NULL, NULL, NULL, NULL);		
	}
}

BOOL	CD3DX9Wnd::InitD3dx9()
{
	HWND	hWnd = GetSafeHwnd();
	BOOL	bSuccess = TRUE;
	CRect	rt;
	GetClientRect(&rt);
	
	try
	{
		//create Direct3D object	
		if( (m_pD3d = Direct3DCreate9(D3D_SDK_VERSION)) == NULL )
		{
			throw std::string("Direct3DCreate9() failed");
			//::MessageBox( m_hWnd, L"Direct3DCreate9() failed!", L"InitD3D()",MB_OK);
			//return FALSE;
		}

		D3DCAPS9 d3dCaps;
		if( FAILED( m_pD3d->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps ) ) )
		{
			throw std::string("GetDeviceCaps() failed!");
			//::MessageBox(hWnd, L"GetDeviceCaps() failed!", L"InitD3dx9()",MB_OK);
			//return FALSE;
		}

		DWORD dwBehaviorFlags = 0;

		if( d3dCaps.VertexProcessingCaps != 0 )
			dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
		else
			dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;


		D3DPRESENT_PARAMETERS	PresentParameters;
		ZeroMemory(&PresentParameters, sizeof(PresentParameters));
		PresentParameters.Windowed = true;
		PresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
		PresentParameters.EnableAutoDepthStencil = true;
		PresentParameters.AutoDepthStencilFormat = D3DFMT_D16;
		PresentParameters.hDeviceWindow = hWnd;
		PresentParameters.BackBufferWidth = rt.Width();
		PresentParameters.BackBufferHeight = rt.Height();
		PresentParameters.BackBufferFormat = D3DFMT_X8R8G8B8;	
		PresentParameters.MultiSampleType = D3DMULTISAMPLE_NONE ;
		
		if ( FAILED ( m_pD3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, dwBehaviorFlags,
			&PresentParameters, &m_pd3dDevice) ) )
		{
			throw std::string("CreateDevice() failed! in InitD3D");
			//::MessageBox(hWnd, L"CreateDevice() failed!", L"InitD3D()",MB_OK);
			//return FALSE;
		}
	}
	catch (const std::string& str) 
	{
		::MessageBoxA(hWnd, str.c_str(), "InitD3D", MB_OK);
		bSuccess = false;
	}
	

	return bSuccess;

}
void	CD3DX9Wnd::KillD3dx9()
{
	if (m_pd3dDevice != NULL)
	{
		m_pd3dDevice->Release();
		m_pd3dDevice = NULL;
	}

	if (m_pD3d != NULL)
	{
		m_pD3d->Release();
		m_pD3d	= NULL;
	}

}
BEGIN_MESSAGE_MAP(CD3DX9Wnd, CWnd)
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
END_MESSAGE_MAP()

BOOL CD3DX9Wnd::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
	return TRUE;

	//return CWnd::OnEraseBkgnd(pDC);
}

void CD3DX9Wnd::OnPaint()
{
	Render();
	//CPaintDC dc(this); // device context for painting
	// TODO: 여기에 메시지 처리기 코드를 추가합니다.
	// 그리기 메시지에 대해서는 CWnd::OnPaint()을(를) 호출하지 마십시오.
}


'Dev.Write' 카테고리의 다른 글

높이 맵 제작 툴 만들기(2)  (0) 2010.01.20
높이 맵 제작 툴 만들기 (1)  (0) 2010.01.18
MFC Custom_Control 연습  (0) 2010.01.15
DX로 만든 첫번째 게임 프로젝트  (0) 2010.01.08
물리 프레임의 기본 - 충돌(1)  (0) 2010.01.06