2007년 4월 19일 목요일

Using DirectX with MFC (2)

DirectX는 제대로 설치되어 있다고 가정한다.

SDI로 App 를 생성하고 Document/View Architecture 를 Uncheck 한다.
기타 원하는 대로 만든다.

프로젝트가 생성이 되면 ChildView.h 및 ChildView.cpp 를 삭제한다.
DirectX 프로그래밍에서는 별도의 View가 필요가 없다.

MainFrm.h 에서

#include "ChildView.h"

를 삭제한다. 그 다음

CMainFrame 내의

CChildView m_wndView;

도 삭제한다.

CMainFrame::OnCreate() 내의

// create a view to occupy the client area of the frame
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("Failed to create view window\n");
return -1;
}

부분을 삭제하고 대신

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;


/////////////////////////////////////////////////////////////////////
// 여기에DirectX의초기화를수행한다.
/////////////////////////////////////////////////////////////////////
HWND hDevice, hFocus;
HRESULT hr;

hDevice = GetSafeHwnd();
hFocus = GetTopLevelParent() ->GetSafeHwnd();

GetClientRect(&m_rectClient);

// Create Direct3D object
m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

D3DDISPLAYMODE d3ddm;
m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

// D3DPRESENT_PARAMETERS 구조체의설정
::ZeroMemory(&m_d3dpp, sizeof(m_d3dpp));
m_d3dpp.Windowed = TRUE;
m_d3dpp.BackBufferCount = 1;
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_d3dpp.EnableAutoDepthStencil = TRUE;
m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
m_d3dpp.hDeviceWindow = hDevice;
m_d3dpp.BackBufferWidth = m_rectClient.Width();
m_d3dpp.BackBufferHeight = m_rectClient.Height();
m_d3dpp.BackBufferFormat = d3ddm.Format;
m_d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;

// 디바이스작성
hr = m_pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hFocus,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&m_d3dpp,
&m_pd3dDevice
);

m_pd3dDevice->SetDialogBoxMode(TRUE);
m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

////////////////////////////////////////////////////////////////////
// 여기까지DirectX의초기화부분임
////////////////////////////////////////////////////////////////////

return 0;
}

와 같이 필요한 초기화를 수행한다.

CMainFrame::OnSetFocus() 함수를 삭제한다.
CMainFrame::OnCmdMsg() 함수를 삭제한다.



“stdafx.h” 에 다음 줄들을 추가한다.
그때 그때 필요한 부분을 알아서 추가해야 한다.

필요한 헤더 파일들과 링크할 라이브러리 파일들이다.

// Direct3D includes
#include
#include
#include

// DirectSound includes
#include
#include
#include

#pragma comment( lib, "dxerr.lib" )
#pragma comment( lib, "dxguid.lib" )
#if defined(DEBUG) defined(_DEBUG)
#pragma comment( lib, "d3dx9d.lib" )
#else
#pragma comment( lib, "d3dx9.lib" )
#endif
#pragma comment( lib, "d3d9.lib" )
#pragma comment( lib, "winmm.lib" )
#pragma comment( lib, "comctl32.lib" )


CMainFrame 의 헤더파일에 아래를 추가한다.

// Attributes
public:
CRect m_rectClient; // Client window size
IDirect3D9* m_pD3D; // The IDirect3D9 interface
IDirect3DDevice9* m_pd3dDevice; // D3D Device
D3DPRESENT_PARAMETERS m_d3dpp; // The present parameters.
bool m_bReady; // Is DX9 ready to render?

// Operations
public:
void Render(); // Render


Constructor에서 필요한 초기화를 수행한다.

CMainFrame::CMainFrame()
{
// 필요한초기화를수행한다.
m_pD3D = NULL;
m_pd3dDevice = NULL;
m_bReady = false;
}

ReleaseAllObject() 라는 함수를 하나 만들고 아래와 같이 추가한다.

void CMainFrame::ReleaseAllObject()
{
// DirectX가시동되었으면삭제
if ( m_pD3D != NULL )
{
if ( m_pd3dDevice != NULL)
{
m_pd3dDevice->Release();
m_pd3dDevice = NULL;
}
m_pD3D->Release();
m_pD3D = NULL;
}
}

WM_ACTIVATEAPP 의 Event handler 를 만들고 아래를 추가한다.

void CMainFrame::OnActivateApp(BOOL bActive, DWORD dwThreadID)
{
CFrameWnd::OnActivateApp(bActive, dwThreadID);

// 준비 완료
m_bReady = bActive;
}

WM_DESTROY 의 Event handler 를 만들어 주고 아래를 추가한다.

void CMainFrame::OnDestroy()
{
ReleaseAllObject();

CFrameWnd::OnDestroy();

// TODO: Add your message handler code here

}

당연히 Render() 함수도 구현해 준다.

void CMainFrame::Render()
{
m_pd3dDevice->Clear(
0,
NULL,
D3DCLEAR_TARGET D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0, 0, 0),
1.0f,
0
);

if(SUCCEEDED(m_pd3dDevice->BeginScene()))
{
m_pd3dDevice->EndScene();
}

m_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}

이제 Test 겸 다음과 같이 실행해 본다.

void CMainFrame::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
// Do not call CFrameWnd::OnPaint() for painting messages
Render();
}

검은 색 화면이 나오면 일단 성공한 것이다.

댓글 1개:

익명 :

What i don't realize is in fact how you are now not really a lot more neatly-liked than you may be right now. You're so intelligent.
You know therefore considerably in the case of this matter, made
me in my opinion believe it from numerous
numerous angles. Its like women and men don't seem to be involved unless it's something to
accomplish with Girl gaga! Your individual stuffs excellent.
All the time maintain it up!

Here is my web blog ... anti cellulite treatment