|
|

楼主 |
发表于 2005-11-25 14:01:00
|
显示全部楼层
Re:请问怎么在mfc窗口上面显示DX画的3D场景?
非常感谢楼上的啊...
但是这样笼统的说还不太能解决问题,大家是否有相关的代码?
事实上我这里有类似功能的代码但是我不知道怎么用...
// ======================================================================================
// 文件:main.cpp
// ======================================================================================
// ======================================================================================
// 定义预处理器
// ======================================================================================
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
#ifndef _AFX_ALL_WARNINGS
#define _AFX_ALL_WARNINGS
#endif
// ======================================================================================
// 标准包含文件
// ======================================================================================
#ifdef _DEBUG
#pragma comment(lib, "d3dx9d.lib")
#else
#pragma comment(lib, "d3dx9.lib")
#endif
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "winmm.lib")
#include <afxwin.h>
#include <d3dx9.h>
#pragma warning(disable: 4201)
#include <Mmsystem.h>
#pragma warning(default: 4201)
// ======================================================================================
// 宏定义
// ======================================================================================
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#ifdef _DEBUG
#define DECLARE_DUMP()
public:
virtual void AssertValid() const;
virtual void Dump(CDumpContext &dc) const;
#else
#define DECLARE_DUMP()
#endif
#ifdef _DEBUG
#define IMPLEMENT_DUMP(class_name, base_class_name)
void class_name::AssertValid() const {base_class_name::AssertValid();}
void class_name: ump(CDumpContext &dc) const {base_class_name::Dump(dc);}
#else
#define IMPLEMENT_DUMP(class_name, base_class_name)
#endif
// ======================================================================================
// Direct3D 封装类
// ======================================================================================
#define SafeRelease(pObject) if(pObject != NULL) {pObject->Release(); pObject = NULL;}
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
#define D3DUSAGE_NONE 0
#define D3DLOCK_NONE 0
struct CUSTOMVERTEX
{
FLOAT x, y, z;
DWORD diffuse;
};
// //////////////////////////////////////////////////////////////////////////////////////
// CDirect3D 类
class CDirect3D : public CObject
{
DECLARE_DYNAMIC(CDirect3D)
DECLARE_DUMP()
public:
CDirect3D();
virtual ~CDirect3D();
private:
static LPDIRECT3D9 m_pD3D;
static LPDIRECT3DDEVICE9 m_pD3DDevice;
protected:
BOOL CreateD3D();
VOID ReleaseD3D();
HRESULT CreateD3DDevice(HWND);
VOID ReleaseD3DDevice();
HRESULT CreateObject();
VOID ReleaseObject();
LPDIRECT3D9 GetD3D() const;
LPDIRECT3DDEVICE9 GetD3DDevice() const;
HRESULT SetRenderState(D3DRENDERSTATETYPE state, DWORD value);
HRESULT SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX * pMatrix);
HRESULT Clear(D3DCOLOR color, DWORD count = 0, const D3DRECT * pRects = NULL,
DWORD flags = D3DCLEAR_TARGET, FLOAT z = 1.0f, DWORD stencil = 0);
HRESULT BeginScene();
HRESULT EndScene();
HRESULT Present(const RECT * pSourceRect = NULL, const RECT * pDestRect = NULL,
HWND hDestWindowOverride = NULL, const RGNDATA * pDirtyRegion = NULL);
HRESULT SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9 * pStreamData,
UINT OffsetInBytes, UINT Stride);
HRESULT SetFVF(DWORD FVF);
HRESULT DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex,
UINT PrimitiveCount);
};
IMPLEMENT_DYNAMIC(CDirect3D, CObject)
IMPLEMENT_DUMP(CDirect3D, CObject)
LPDIRECT3D9 CDirect3D::m_pD3D = NULL;
LPDIRECT3DDEVICE9 CDirect3D::m_pD3DDevice = NULL;
CDirect3D::CDirect3D()
{
ASSERT(m_pD3D == NULL);
ASSERT(m_pD3DDevice == NULL);
}
CDirect3D::~CDirect3D()
{
if(m_pD3DDevice != NULL)
{
TRACE0("警告:使用 CDirect3D 析构函数释放 D3DDevice 接口\n");
ReleaseD3DDevice();
}
if(m_pD3D != NULL)
{
TRACE0("警告:使用 CDirect3D 析构函数释放 D3D 接口\n");
ReleaseD3D();
}
}
BOOL CDirect3D::CreateD3D()
{
if(NULL == (m_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return FALSE;
else
return TRUE;
}
VOID CDirect3D::ReleaseD3D()
{
SafeRelease(m_pD3D);
}
HRESULT CDirect3D::CreateD3DDevice(HWND hWnd)
{
ASSERT(IsWindow(hWnd));
ASSERT(m_pD3D != NULL);
HRESULT hr;
D3DDISPLAYMODE d3ddm;
hr = m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
if(FAILED(hr))
return hr;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
{
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
}
hr = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice);
return hr;
}
VOID CDirect3D::ReleaseD3DDevice()
{
SafeRelease(m_pD3DDevice);
}
inline LPDIRECT3D9 CDirect3D::GetD3D() const
{return m_pD3D;}
inline LPDIRECT3DDEVICE9 CDirect3D::GetD3DDevice() const
{return m_pD3DDevice;}
inline HRESULT CDirect3D::SetRenderState(D3DRENDERSTATETYPE state, DWORD value)
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice->SetRenderState(state, value);}
inline HRESULT CDirect3D::SetTransform(D3DTRANSFORMSTATETYPE state, const D3DMATRIX * pMatrix)
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice->SetTransform(state, pMatrix);}
inline HRESULT CDirect3D::Clear(D3DCOLOR color, DWORD count,
const D3DRECT * pRects, DWORD flags, FLOAT z, DWORD stencil)
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice->Clear(
count, pRects, flags, color, z, stencil);}
inline HRESULT CDirect3D::BeginScene()
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice->BeginScene();}
inline HRESULT CDirect3D::EndScene()
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice->EndScene();}
inline HRESULT CDirect3D: resent(const RECT * pSourceRect, const RECT * pDestRect ,
HWND hDestWindowOverride, const RGNDATA * pDirtyRegion)
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice-> resent(
pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);}
inline HRESULT CDirect3D::SetStreamSource(UINT StreamNumber, IDirect3DVertexBuffer9 * pStreamData,
UINT OffsetInBytes, UINT Stride)
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice->SetStreamSource(StreamNumber, pStreamData,
OffsetInBytes, Stride);}
inline HRESULT CDirect3D::SetFVF(DWORD FVF)
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice->SetFVF(FVF);}
inline HRESULT CDirect3D::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex,
UINT PrimitiveCount)
{ASSERT(m_pD3DDevice != NULL); return m_pD3DDevice->DrawPrimitive(
PrimitiveType, StartVertex, PrimitiveCount);}
// //////////////////////////////////////////////////////////////////////////////////////
// CGame 类
class CGame : public CDirect3D
{
DECLARE_DYNAMIC(CGame)
DECLARE_DUMP()
public:
CGame();
virtual ~CGame();
private:
LPDIRECT3DVERTEXBUFFER9 m_pD3DVertexBuffer;
HWND m_hWnd;
protected:
HRESULT CreateD3DVertexBuffer();
VOID ReleaseD3DVertexBuffer();
VOID SetupMatrices();
public:
HRESULT CreateGame(HWND);
VOID DistroyGame();
VOID Render();
};
IMPLEMENT_DYNAMIC(CGame, CDirect3D)
IMPLEMENT_DUMP(CGame, CDirect3D)
CGame::CGame()
{
m_pD3DVertexBuffer = NULL;
m_hWnd = NULL;
}
CGame::~CGame()
{
if(m_pD3DVertexBuffer != NULL)
{
TRACE0("警告:使用 CGame 析构函数释放 D3DVertexBuffer 接口\n");
ReleaseD3DVertexBuffer();
}
}
HRESULT CGame::CreateD3DVertexBuffer()
{
ASSERT(GetD3DDevice() != NULL);
HRESULT hr;
hr = GetD3DDevice()->CreateVertexBuffer(sizeof(CUSTOMVERTEX) * 14, D3DUSAGE_NONE,
D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &m_pD3DVertexBuffer, NULL);
if(FAILED(hr))
return hr;
ASSERT(m_pD3DVertexBuffer != NULL);
CUSTOMVERTEX vertices[] =
{
{-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, // 0
{-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB( 0, 255, 0),}, // 1
{ 5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB( 0, 0, 255),}, // 2
{ 5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(255, 255, 0),}, // 3
{ 5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, // 4
{-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB( 0, 255, 0),}, // 5
{-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB( 0, 0, 255),}, // 6
{-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, // 7
{-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB( 0, 255, 0),}, // 8
{ 5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB( 0, 0, 255),}, // 9
{ 5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255, 255, 0),}, // 10
{ 5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, // 11
{-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB( 0, 255, 0),}, // 12
{-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB( 0, 0, 255),}, // 13
};
VOID * pVertices = NULL;
hr = m_pD3DVertexBuffer->Lock(0, sizeof(CUSTOMVERTEX) * 14, &pVertices, D3DLOCK_NONE);
if(FAILED(hr))
return hr;
{
memcpy(pVertices, vertices, sizeof(CUSTOMVERTEX) * 14);
}
m_pD3DVertexBuffer->Unlock();
return S_OK;
}
VOID CGame::ReleaseD3DVertexBuffer()
{
SafeRelease(m_pD3DVertexBuffer);
}
VOID CGame::SetupMatrices()
{
{
FLOAT fAngle = timeGetTime() / 400.0f;
D3DXMATRIX matX, matY, matZ, matWorld;
D3DXMatrixRotationX(&matX, fAngle);
D3DXMatrixRotationY(&matY, fAngle);
D3DXMatrixRotationZ(&matZ, fAngle);
D3DXMatrixMultiply(&matWorld, &matX, &matY);
D3DXMatrixMultiply(&matWorld, &matWorld, &matZ);
SetTransform(D3DTS_WORLD, &matWorld);
};
{
D3DXVECTOR3 vEye(0.0f, 0.0f, -30.0f);
D3DXVECTOR3 vLookAt(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 vLookUp(0.0f, 1.0f, 0.0f);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &vEye, &vLookAt, &vLookUp);
SetTransform(D3DTS_VIEW, &matView);
};
{
FLOAT fovAngle = D3DX_PI / 4,
rate = 1.0f,
frontClipping = 1.0f,
backClipping = 500.0f;
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(
&matProj
,fovAngle
,rate
,frontClipping
,backClipping
);
SetTransform(D3DTS_PROJECTION, &matProj);
};
}
HRESULT CGame::CreateGame(HWND hWnd)
{
ASSERT(IsWindow(hWnd));
m_hWnd = hWnd;
if(!CreateD3D())
return E_FAIL;
HRESULT hr = CreateD3DDevice(m_hWnd);
if(FAILED(hr))
return hr;
{
SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
SetRenderState(D3DRS_LIGHTING, FALSE);
}
if(FAILED(CreateD3DVertexBuffer()))
return hr;
return S_OK;
}
VOID CGame::DistroyGame()
{
ReleaseD3DVertexBuffer();
ReleaseD3DDevice();
ReleaseD3D();
}
VOID CGame::Render()
{
if(GetD3DDevice() == NULL)
return;
Clear(D3DCOLOR_XRGB(100, 150, 100));
if(SUCCEEDED(BeginScene()))
{
{
SetupMatrices();
SetStreamSource(0, m_pD3DVertexBuffer, 0, sizeof(CUSTOMVERTEX));
SetFVF(D3DFVF_CUSTOMVERTEX);
DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 12);
}
EndScene();
}
Present();
}
// ======================================================================================
// 应用程序框架类
// ======================================================================================
// //////////////////////////////////////////////////////////////////////////////////////
// CChildView 类
class CChildView : public CWnd
{
DECLARE_DYNAMIC(CChildView)
DECLARE_MESSAGE_MAP()
DECLARE_DUMP()
public:
CChildView();
virtual ~CChildView();
protected:
//{{AFX_MSG(CChildView)
//}}AFX_MSG
};
IMPLEMENT_DYNAMIC(CChildView, CWnd)
BEGIN_MESSAGE_MAP(CChildView, CWnd)
//{{AFX_MSG_MAP(CChildView)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
IMPLEMENT_DUMP(CChildView, CWnd)
CChildView::CChildView() {}
CChildView::~CChildView() {}
// //////////////////////////////////////////////////////////////////////////////////////
// CMainFrame 类
class CMainFrame : public CFrameWnd
{
DECLARE_DYNAMIC(CMainFrame)
DECLARE_MESSAGE_MAP()
DECLARE_DUMP()
public:
CMainFrame();
virtual ~CMainFrame();
protected:
CChildView m_wndView;
CGame m_game;
public:
HRESULT CreateGame();
VOID Render();
protected:
//{{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
//}}AFX_MSG
};
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ERASEBKGND()
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
IMPLEMENT_DUMP(CMainFrame, CFrameWnd)
CMainFrame::CMainFrame() {}
CMainFrame::~CMainFrame() {}
inline HRESULT CMainFrame::CreateGame()
{return m_game.CreateGame(m_wndView.m_hWnd);}
inline VOID CMainFrame::Render()
{m_game.Render();}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if(CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if(!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), this,
AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("错误:未能创建 ChildView\n");
return -1;
}
return 0;
}
void CMainFrame::OnDestroy()
{
m_game.DistroyGame();
CFrameWnd::OnDestroy();
}
BOOL CMainFrame::OnEraseBkgnd(CDC *)
{
return TRUE;
}
void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);
if(nChar == VK_ESCAPE)
DestroyWindow();
}
// //////////////////////////////////////////////////////////////////////////////////////
// CDXDemoApp 类
class CDXDemoApp : public CWinApp
{
DECLARE_DYNAMIC(CDXDemoApp)
DECLARE_MESSAGE_MAP()
DECLARE_DUMP()
public:
CDXDemoApp(LPCTSTR lpszAppName = NULL);
virtual ~CDXDemoApp();
protected:
virtual BOOL InitInstance();
virtual BOOL ExitInstance();
virtual int Run();
protected:
//{{AFX_MSG(CDXDemoApp)
//}}AFX_MSG
};
IMPLEMENT_DYNAMIC(CDXDemoApp, CWinApp)
BEGIN_MESSAGE_MAP(CDXDemoApp, CWinApp)
//{{AFX_MSG_MAP(CDXDemoApp)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
IMPLEMENT_DUMP(CDXDemoApp, CWinApp)
CDXDemoApp::CDXDemoApp(LPCTSTR lpszAppName)
: CWinApp(lpszAppName) {}
CDXDemoApp::~CDXDemoApp() {}
BOOL CDXDemoApp::InitInstance()
{
CWinApp::InitInstance();
CMainFrame * pMainWnd = new CMainFrame;
CRect rect(100, 100, 100 + 400, 100 + 400);
ASSERT(pMainWnd != NULL);
if(!pMainWnd->Create(NULL, "DXDemo", WS_OVERLAPPEDWINDOW, rect))
return FALSE;
m_pMainWnd = pMainWnd;
pMainWnd->ShowWindow(SW_SHOWDEFAULT);
pMainWnd->UpdateWindow();
if(FAILED(pMainWnd->CreateGame()))
return FALSE;
return TRUE;
}
BOOL CDXDemoApp::ExitInstance()
{
return CWinApp::ExitInstance();
}
int CDXDemoApp::Run()
{
ASSERT(m_pMainWnd != NULL);
ASSERT_VALID(this);
_AFX_THREAD_STATE* pState = AfxGetThreadState();
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
for(;;)
{
if(::PeekMessage(&(pState->m_msgCur), NULL, NULL, NULL, PM_NOREMOVE))
{
if(!PumpMessage())
return ExitInstance();
if(bIdle == FALSE)
{
bIdle = TRUE;
lIdleCount = 0;
}
}
else
{
if(bIdle && !OnIdle(lIdleCount++))
bIdle = FALSE;
((CMainFrame *)m_pMainWnd)->Render();
}
}
}
// ======================================================================================
// 应用程序主对象
// ======================================================================================
CDXDemoApp theApp;
|
|