代碼里面寫了詳盡的注釋!點擊這里下載工程(使用VS2003 + OCT 2006?DirectSDK 編譯) 請看考這里【轉貼】Render to Texture(渲染到紋理)

#include?
<
D3DX9.h
>
#include?
<
string
>
typedef?std::
string
?String;
#define
?SAFE_RELEASE(o)?{if(o){o->Release();o?=?0;}}
LPDIRECT3D9?g_pD3D?
=
?
0
;????????????????
//
?D3D?Driver
LPDIRECT3DDEVICE9?g_pd3dDevice?
=
?
0
;????
//
?D3D?設備
D3DCAPS9?g_Caps?
=
?
{(D3DDEVTYPE)
0
}
;????
//
?D3D?的帽子
LPD3DXMESH?g_pMeshTeapot?
=
?
0
;????
//
?茶壺頂點緩沖區
LPDIRECT3DVERTEXBUFFER9?g_pVB?
=
?
0
;????
//
?頂點緩沖區
LPDIRECT3DINDEXBUFFER9?g_pIB?
=
?
0
;????
//
?索引緩沖區
LPDIRECT3DTEXTURE9?g_pTexture?
=
?
0
;????
//
?貼圖
LPDIRECT3DTEXTURE9?g_pRenderTexture?
=
?
0
;????
//
?渲染到貼圖
LPDIRECT3DSURFACE9?g_pRenderSurface?
=
?
0
;????
//
?渲染到貼圖的表面
//
?頂點定義
#define
?D3DFVF_CUSTOMVERTEX?(D3DFVF_XYZ?|?D3DFVF_DIFFUSE?|?D3DFVF_TEX1)
struct
?CUSTOMVERTEX

{
????D3DXVECTOR3?position;
????D3DCOLOR?color;
????
float
?u?,?v;
}
;

//
?錯誤記錄
void
?D3DErr(String?strMsg)

{
????MessageBox(
0
?,?strMsg.c_str()?,?
"
錯誤
"
?,?MB_OK);
}
//
?初始化頂點緩沖區
HRESULT?InitVB()

{
????
//
?創建茶壺
????
if
(FAILED(D3DXCreateTeapot(g_pd3dDevice?,?
&
g_pMeshTeapot?,?
0
)))
????????
return
?E_FAIL;
????
//
?創建頂點緩沖區
????
if
(FAILED(g_pd3dDevice
->
CreateVertexBuffer(
4
?
*
?
sizeof
(CUSTOMVERTEX)?,?
0
?,?D3DFVF_CUSTOMVERTEX?,?D3DPOOL_DEFAULT?,?
&
g_pVB?,?
0
)))
????????
return
?E_FAIL;

????CUSTOMVERTEX?
*
pVertecies;
????
//
?鎖定緩沖區
????
if
(SUCCEEDED(g_pVB
->
Lock(
0
?,?
0
?,?(
void
**
)
&
pVertecies?,?
0
)))
 ????
{
????????pVertecies[
0
].position?
=
?D3DXVECTOR3(
-
1
?,?
1
?,?
0
);
????????pVertecies[
1
].position?
=
?D3DXVECTOR3(
-
1
?,?
-
1
?,?
0
);
????????pVertecies[
2
].position?
=
?D3DXVECTOR3(
1
?,?
1
?,?
0
);
????????pVertecies[
3
].position?
=
?D3DXVECTOR3(
1
?,?
-
1
?,?
0
);

????????pVertecies[
0
].u?
=
?
0
;
????????pVertecies[
0
].v?
=
?
0
;

????????pVertecies[
1
].u?
=
?
0
;
????????pVertecies[
1
].v?
=
?
1
;

????????pVertecies[
2
].u?
=
?
1
;
????????pVertecies[
2
].v?
=
?
0
;

????????pVertecies[
3
].u?
=
?
1
;
????????pVertecies[
3
].v?
=
?
1
;

????????pVertecies[
0
].color?
=
?
0xFFFFFFFF
;
????????pVertecies[
1
].color?
=
?
0xFFFFFFFF
;
????????pVertecies[
2
].color?
=
?
0xFFFFFFFF
;
????????pVertecies[
3
].color?
=
?
0xFFFFFFFF
;
????????g_pVB
->
Unlock();
????}
????
else
????
{
????????
return
?E_FAIL;
????}
????
//
?載入紋理
????
if
(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice?,?
"
..\\BRICE.JPG
"
?,?
&
g_pTexture)))
 ????
{
????????D3DErr(
"
無法載入紋理Brice.jpg
"
);
????????
return
?E_FAIL;
????}
????
//
?創建渲染到貼圖的表面
????
if
(FAILED(g_pd3dDevice
->
CreateTexture(
512
?,?
512
?,?
1
?,?D3DUSAGE_RENDERTARGET?,?D3DFMT_A8R8G8B8?,?D3DPOOL_DEFAULT?,?
&
g_pRenderTexture?,?
0
)))
 ????
{
????????D3DErr(
"
無法創建渲染貼圖
"
);
????????
return
?E_FAIL;
????}
????
//
?獲取貼圖的渲染表面
????
if
(FAILED(g_pRenderTexture
->
GetSurfaceLevel(
0
?,?
&
g_pRenderSurface)))
 ????
{
????????
return
?E_FAIL;
????}
????
return
?S_OK;
}
//
?初始化模型
HRESULT?InitGeometry()

{
????
//
?創建頂點緩沖區
????
if
(FAILED(InitVB()))
????????
return
?E_FAIL;
????
return
?S_OK;
}
//
?設置矩陣變換
void
?SetTransform()

{

????
//
?世界變換
????D3DXMATRIX?matWorld;
????D3DXMatrixIdentity(
&
matWorld);
????
//
?設置世界矩陣
????g_pd3dDevice
->
SetTransform(D3DTS_WORLD?,?
&
matWorld);
????
//
?Set?up?our?view?matrix.?A?view?matrix?can?be?defined?given?an?eye?point,
????
//
?a?point?to?lookat,?and?a?direction?for?which?way?is?up.?Here,?we?set?the
????
//
?eye?five?units?back?along?the?z-axis?and?up?three?units,?look?at?the
????
//
?origin,?and?define?"up"?to?be?in?the?y-direction.
????
//
?視口變換
????D3DXMATRIX?matView;
????D3DXMatrixLookAtLH(
&
matView?,?
&
D3DXVECTOR3(
0
?,?
0
?,?
-
5
)
????????,?
&
D3DXVECTOR3(
0
?,?
0
?,?
0
)?
????????,?
&
D3DXVECTOR3(
0
?,?
1
?,?
0
));
????g_pd3dDevice
->
SetTransform(D3DTS_VIEW?,?
&
matView);
????
//
?For?the?projection?matrix,?we?set?up?a?perspective?transform?(which
????
//
?transforms?geometry?from?3D?view?space?to?2D?viewport?space,?with
????
//
?a?perspective?divide?making?objects?smaller?in?the?distance).?To?build
????
//
?a?perpsective?transform,?we?need?the?field?of?view?(1/4?pi?is?common),
????
//
?the?aspect?ratio,?and?the?near?and?far?clipping?planes?(which?define?at
????
//
?what?distances?geometry?should?be?no?longer?be?rendered).
????D3DXMATRIXA16?matProj;
????D3DXMatrixPerspectiveFovLH(?
&
matProj,?D3DX_PI
/
4
,?
800.0f
?
/
?
600.0f
,?
1.0f
,?
100.0f
?);
????g_pd3dDevice
->
SetTransform(?D3DTS_PROJECTION,?
&
matProj?);


}
//
?渲染場景
void
?Render()

{
????
if
(g_pd3dDevice)
 ????
{
????????LPDIRECT3DSURFACE9?pRenderTarget;
????????
//
?保存渲染表面
????????g_pd3dDevice
->
GetRenderTarget(
0
?,?
&
pRenderTarget);
????????
//
?設置我們的貼圖表面
????????g_pd3dDevice
->
SetRenderTarget(
0
?,?g_pRenderSurface);
????????
//
?清空場景,渲染到貼圖的背景是藍色的
????????g_pd3dDevice
->
Clear(
0
?,?
0
?,?D3DCLEAR_TARGET?
|
?D3DCLEAR_ZBUFFER?,?D3DCOLOR_XRGB(
0
?,?
0
?,?
0xFF
)?,?
1
?,?
0
);
????????
//
?開始渲染到貼圖
????????
if
(SUCCEEDED(g_pd3dDevice
->
BeginScene()))
 ????????
{
????????????
//
?設置通常的矩陣
????????????SetTransform();
????????????D3DXMATRIX?matWorld;
????????????
//
?旋轉茶壺
????????????D3DXMatrixRotationAxis(
&
matWorld?,?
&
D3DXVECTOR3(
1
?,?
0
?,
1
)?,?D3DX_PI?
*
?
2.0f
?
*
?(timeGetTime()?
%
?
5000
)?
/
?
5000.0f
);
????????????g_pd3dDevice
->
SetTransform(D3DTS_WORLD?,?
&
matWorld);

????????????
//
?設置渲染到表面的投影矩陣(這里可有可無,因為我們的窗口創建是512×512的)
????????????D3DXMATRIXA16?matProj;
????????????D3DXMatrixPerspectiveFovLH(?
&
matProj,?D3DX_PI
/
4
,?
1.0f
,?
1.0f
,?
100.0f
?);
????????????g_pd3dDevice
->
SetTransform(?D3DTS_PROJECTION,?
&
matProj?);

????????????
//
?設置貼圖
????????????g_pd3dDevice
->
SetTexture(
0
?,?g_pTexture);
????????????g_pd3dDevice
->
SetSamplerState(
0
?,?D3DSAMP_ADDRESSU?,?D3DTADDRESS_MIRROR);
????????????g_pd3dDevice
->
SetSamplerState(
0
?,?D3DSAMP_ADDRESSV?,?D3DTADDRESS_MIRROR);
????????????
//
?自動生成紋理坐標
????????????g_pd3dDevice
->
SetTextureStageState(
0
,?D3DTSS_TEXTURETRANSFORMFLAGS,?D3DTTFF_COUNT2);
????????????g_pd3dDevice
->
SetTextureStageState(
0
,?D3DTSS_TEXCOORDINDEX,?D3DTSS_TCI_SPHEREMAP);
????????????g_pd3dDevice
->
SetRenderState(D3DRS_LIGHTING?,?FALSE);
????????????
//
?渲染茶壺
????????????g_pMeshTeapot
->
DrawSubset(
0
);
????????????g_pd3dDevice
->
EndScene();
????????}
????????
//
?恢復渲染表面為顯示器
????????g_pd3dDevice
->
SetRenderTarget(
0
?,?pRenderTarget);

????????
//
?清空場景,真實場景是紅色背景的
????????g_pd3dDevice
->
Clear(
0
?,?
0
?,?D3DCLEAR_TARGET?
|
?D3DCLEAR_ZBUFFER?,?D3DCOLOR_XRGB(
0xFF
?,?
0xFF
?,?
0
)?,?
1
?,?
0
);
????????
//
?開始渲染真實場景
????????
if
(SUCCEEDED(g_pd3dDevice
->
BeginScene()))
 ????????
{
????????????SetTransform();
????????????D3DXMATRIX?matWorld;
????????????
//
?旋轉表面
????????????D3DXMatrixRotationAxis(
&
matWorld?,?
&
D3DXVECTOR3(
1
?,?
1
?,
0
)?,?sinf(D3DX_PI?
*
?
2.0f
?
*
?(timeGetTime()?
%
?
5000
)?
/
?
5000.0f
));
????????????
//
?設置世界矩陣
????????????g_pd3dDevice
->
SetTransform(D3DTS_WORLD?,?
&
matWorld);
????????????
//
?設置已經渲染到表面的貼圖
????????????g_pd3dDevice
->
SetTexture(
0
?,?g_pRenderTexture);
????????????g_pd3dDevice
->
SetTextureStageState(
0
,?D3DTSS_TEXTURETRANSFORMFLAGS,?D3DTTFF_COUNT2);
????????????g_pd3dDevice
->
SetTextureStageState(
0
,?D3DTSS_TEXCOORDINDEX,?
0
);

????????????g_pd3dDevice
->
SetSamplerState(
0
?,?D3DSAMP_ADDRESSU?,?D3DTADDRESS_MIRROR);
????????????g_pd3dDevice
->
SetSamplerState(
0
?,?D3DSAMP_ADDRESSV?,?D3DTADDRESS_MIRROR);
????????????g_pd3dDevice
->
SetRenderState(D3DRS_LIGHTING?,?FALSE);
????????????
//
g_pd3dDevice->SetRenderState(D3DRS_FILLMODE?,?D3DFILL_WIREFRAME);
????????????g_pd3dDevice
->
SetStreamSource(
0
?,?g_pVB?,?
0
?,?
sizeof
(CUSTOMVERTEX));
????????????g_pd3dDevice
->
SetFVF(D3DFVF_CUSTOMVERTEX);
????????????g_pd3dDevice
->
DrawPrimitive(D3DPT_TRIANGLESTRIP?,?
0
?,?
2
);
????????????g_pd3dDevice
->
EndScene();
????????}
????????
//
?顯示
????????g_pd3dDevice
->
Present(
0
?,?
0
?,?
0
?,?
0
);
????}
}
//
?初始化?D3D?設備
HRESULT?InitD3D(HWND?hWnd)

{
????
//
?創建?D3D?Driver
????
if
(NULL?
==
?(g_pD3D?
=
?Direct3DCreate9(D3D_SDK_VERSION)))
 ????
{
????????D3DErr(
"
無法創建Direct3D9設備
"
);
????????
return
?E_FAIL;
????}
????
//
?獲取當前顯示模式
????D3DDISPLAYMODE?d3ddm;
????
if
(FAILED(g_pD3D
->
GetAdapterDisplayMode(D3DADAPTER_DEFAULT?,?
&
d3ddm)))
 ????
{
????????D3DErr(
"
無法獲取D3D顯示器模式
"
);
????????
return
?E_FAIL;
????}
????RECT?rect;
????::GetClientRect(hWnd?,?
&
rect);

????
//
?填充參數
????D3DPRESENT_PARAMETERS?d3dpp;
????memset(
&
d3dpp?,?
0
?,?
sizeof
(d3dpp));
????d3dpp.BackBufferFormat?
=
?d3ddm.Format;
????d3dpp.BackBufferWidth?
=
?rect.right;
????d3dpp.BackBufferHeight?
=
?rect.bottom;
????d3dpp.SwapEffect?
=
?D3DSWAPEFFECT_DISCARD;
????d3dpp.Windowed?
=
?
true
;
????d3dpp.AutoDepthStencilFormat?
=
?D3DFMT_D16;
????d3dpp.EnableAutoDepthStencil?
=
?TRUE;

????
//
?獲取帽子
????
if
(FAILED(g_pD3D
->
GetDeviceCaps(D3DADAPTER_DEFAULT?,?D3DDEVTYPE_HAL?,?
&
g_Caps)))
 ????
{
????????D3DErr(
"
獲取D3D?帽子時發生錯誤
"
);
????????
return
?E_FAIL;
????}
????
//
?創建D3D設備
????
if
(FAILED(g_pD3D
->
CreateDevice(D3DADAPTER_DEFAULT
????????,?D3DDEVTYPE_HAL
????????,?hWnd
????????
//
?檢查是否支持硬件頂點處理
????????,?g_Caps.DevCaps?
&
?D3DDEVCAPS_HWTRANSFORMANDLIGHT?
?
?D3DCREATE_HARDWARE_VERTEXPROCESSING?:?D3DCREATE_SOFTWARE_VERTEXPROCESSING
????????,?
&
d3dpp
????????,?
&
g_pd3dDevice
????????)
????????))
 ????
{
????????D3DErr(
"
創建D3D設備時發生錯誤
"
);
????????
return
?E_FAIL;
????}
????g_pd3dDevice
->
SetRenderState(?D3DRS_CULLMODE,?D3DCULL_NONE?);
????g_pd3dDevice
->
SetRenderState(?D3DRS_ZENABLE,?TRUE?);

????
if
(FAILED(InitGeometry()))
????????
return
?E_FAIL;
????
return
?S_OK;
}
//
?清空所有占用的資源
void
?CleanUp()

{
????SAFE_RELEASE(g_pTexture);
????SAFE_RELEASE(g_pIB);
????SAFE_RELEASE(g_pVB);
????SAFE_RELEASE(g_pd3dDevice);
????SAFE_RELEASE(g_pD3D);
}
//
?消息處理
LRESULT?WINAPI?MsgProc(HWND?hWnd?,?UINT?message?,?WPARAM?wParam?,?LPARAM?lParam)

{
????
switch
(message)
 ????
{
????
case
?WM_DESTROY:
????????CleanUp();
????????PostQuitMessage(
0
);
????????
break
;
????}
????
return
?::DefWindowProc(hWnd,?message?,?wParam?,?lParam);
}
//
?Windows?入口
int
?WINAPI?WinMain(IN?HINSTANCE?hInstance,?IN?HINSTANCE?hPrevInstance,?IN?LPSTR?lpCmdLine,?IN?
int
?nShowCmd?)

{
????WNDCLASS?wndClass;
????memset(
&
wndClass?,?
0
?,?
sizeof
(wndClass));
????wndClass.hInstance?
=
?hInstance;
????wndClass.lpszClassName?
=
?
"
渲染到紋理
"
;
????wndClass.lpfnWndProc?
=
?MsgProc;
????RegisterClass(
&
wndClass);

????
//
?創建窗口
????HWND?hWnd?
=
?CreateWindow(
"
渲染到紋理
"
?,?
"
渲染到紋理!
"
?
????????,?
0
?,?
0
?,?
0
?,?
640
?,
480
?,?GetDesktopWindow()
????????,?
0
?,?wndClass.hInstance?,?
0
);
????
//
?顯示窗口
????ShowWindow(hWnd?,?SW_SHOWDEFAULT);
????UpdateWindow(hWnd);

????
//
?初始化?D3D?設備
????
if
(SUCCEEDED(InitD3D(hWnd)))
 ????
{
????????
//
?消息處理循環
????????MSG?msg;
????????memset(
&
msg?,?
0
?,?
sizeof
(msg));
????????
while
(msg.message?
!=
?WM_QUIT)
 ????????
{
????????????
if
(PeekMessage(
&
msg?,?
0
?,?
0
?,?
0
?,?PM_REMOVE))
 ????????????
{
????????????????TranslateMessage(
&
msg);
????????????????DispatchMessage(
&
msg);
????????????}
????????????
else
????????????
{
????????????????Render();
????????????}
????????}
????}
????
//
?清空場景
????CleanUp();

????UnregisterClass(
"
渲染到紋理
"
?,?wndClass.hInstance);

????
return
?
0
;
}
|