用directx实现shadowmap
先上图一个光围着转圈
很棒的效果。
理解这个东西需要那么点基础,
1.基本的编程语言c++
2.基本的directx图形绘制
3.基本的dxut框架
4.会那么一点点shader
好了开始撸
软件资源先行
我用3dmax创建了几个网格
1.文字
2.龙
3.狮子 老虎 豹子 狼
4.一个地板
然后呢 shader接着开始撸。
我就解释那么一下下。
//ShadowMap.fx
float4x4 g_matWorldView;
float4x4 g_matProjection;
float4x4 g_matViewToLightProj;
texture g_texMesh;
texture g_texShadow;
float3 g_vLightPos;
float3 g_vLightDir;
float g_fLightCosTheta;
float g_fLightEpsilon = 0.000005f;
float4 g_clrLightAmbient;
float4 g_clrLightDiffuse;
float4 g_clrMtrlAmbient;
float4 g_clrMtrlDiffuse;
float g_fShadowWidth;
float g_fShadowHeight;
sampler ShadowSampler = sampler_state
{
Texture = <g_texShadow>;
MagFilter = Point;
MinFilter = Point;
MipFilter = Point;
AddressU = Clamp;
AddressV = Clamp;
};
sampler MeshSampler = sampler_state
{
Texture = <g_texMesh>;
MagFilter = Linear;
MinFilter = Linear;
MipFilter = Linear;
};
//render shadow
struct ShadowVSInput
{
float4 vPos:POSITION;
float2 vTex:TEXCOORD0;
};
struct ShadowVSOutput
{
float4 vPos:POSITION;
float2 vTex:TEXCOORD0;
};
ShadowVSOutput ShadowVSRender(ShadowVSInput input)
{
ShadowVSOutput output;
output.vPos = mul(input.vPos, g_matWorldView);
output.vPos = mul(output.vPos, g_matProjection);
output.vTex.xy = output.vPos.zw;
return output;
}
struct ShadowPSOutput
{
float4 vColor:COLOR0;
};
ShadowPSOutput ShadowPSRender(ShadowVSOutput input)
{
ShadowPSOutput output;
output.vColor = input.vTex.x / input.vTex.y;
return output;
}
technique RenderShadow
{
pass p0
{
VertexShader = compile vs_2_0 ShadowVSRender();
PixelShader = compile ps_2_0 ShadowPSRender();
}
}
//render mesh
struct MeshVSInput
{
float4 vPos:POSITION;
float3 vNormal:NORMAL;
float2 vTex:TEXCOORD0;
};
struct MeshVSOutput
{
float4 vPos:POSITION;
float2 vTex:TEXCOORD0;
float4 vPosInView:TEXCOORD1;
float3 vNormalInView:TEXCOORD2;
float4 vPosInLightProj:TEXCOORD3;
};
MeshVSOutput MeshVSRender(MeshVSInput input)
{
MeshVSOutput output;
output.vPosInView = mul(input.vPos, g_matWorldView);
output.vPos = mul(output.vPosInView, g_matProjection);
output.vTex = input.vTex;
output.vNormalInView = mul(input.vNormal, (float3x3)g_matWorldView);
output.vPosInLightProj = mul(output.vPosInView, g_matViewToLightProj);
return output;
}
struct MeshPSOutput
{
float4 vColor:COLOR0;
};
MeshPSOutput MeshPSRender(MeshVSOutput input)
{
MeshPSOutput output;
output.vColor = g_clrLightAmbient * g_clrMtrlAmbient + g_clrLightAmbient * g_clrMtrlDiffuse;
float3 vLightToPos = float3(input.vPosInView - g_vLightPos);
if(dot(vLightToPos, g_vLightDir) > 0.0f)
{
float2 vTexPos = 0.5f * input.vPosInLightProj.xy / input.vPosInLightProj.w + float2(0.5f, 0.5f);
vTexPos.y = 1.0f - vTexPos.y;
float2 vTexSpacePos = float2(vTexPos.x * g_fShadowWidth, vTexPos.y * g_fShadowHeight);
float2 lerps = frac(vTexSpacePos);
float sourcevals[4];
sourcevals[0] = ((tex2D(ShadowSampler, vTexPos) + g_fLightEpsilon) < input.vPosInLightProj.z / input.vPosInLightProj.w) ? 0.0f : 1.0f;
sourcevals[1] = ((tex2D(ShadowSampler, vTexPos + float2(1.0f / g_fShadowWidth, 0.0f)) + g_fLightEpsilon) < input.vPosInLightProj.z / input.vPosInLightProj.w) ? 0.0f : 1.0f;
sourcevals[2] = ((tex2D(ShadowSampler, vTexPos + float2(0.0f, 1.0f / g_fShadowHeight)) + g_fLightEpsilon) < input.vPosInLightProj.z / input.vPosInLightProj.w) ? 0.0f : 1.0f;
sourcevals[3] = ((tex2D(ShadowSampler, vTexPos + float2(1.0f / g_fShadowWidth, 1.0f / g_fShadowHeight)) + g_fLightEpsilon) < input.vPosInLightProj.z / input.vPosInLightProj.w) ? 0.0f : 1.0f;
float lightamount = lerp(lerp(sourcevals[0], sourcevals[1], lerps.x),lerp(sourcevals[2], sourcevals[3], lerps.x), lerps.y);
float4 lightcolor = max(0.0f, dot(-vLightToPos, input.vNormalInView)) * lightamount * g_clrLightDiffuse;
output.vColor = saturate(lightcolor * g_clrMtrlAmbient + lightcolor * g_clrMtrlDiffuse + output.vColor);
}
output.vColor = output.vColor * tex2D(MeshSampler, input.vTex);
return output;
}
technique RenderMesh
{
pass p0
{
VertexShader = compile vs_2_0 MeshVSRender();
PixelShader = compile ps_2_0 MeshPSRender();
}
}
几乎就是抄的微软的例子,不过核心的光照计算我修改了那么一下下。
没有光照是 光的环境光 * 材质的环境光 + 光的环境光 * 材质的漫反射光
有光照是 光照量材质漫反射 + 光照量 材质环境光 + 没有光照的颜色。
最后就是纹理采样了。
我稍微的修改了一下光的漫反射 看着很有氛围呀
这个不是屎黄色吧
dxut的框架需要深刻理解那么十来个函数
是否接受硬件配置
改变硬件配置
创建设备
销毁设备
丢失设备
重置设备
鼠标事件处理
键盘事件处理
系统消息处理
帧移动
渲染
然后就是主函数了
我把代码糊上
//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "DXUT.h"
#include "DXUTcamera.h"
#include "SDKmisc.h"
#include "DXUTmisc.h"
#include "SDKmesh.h"
#include <vector>
D3DVERTEXELEMENT9 g_aVertDecl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
D3DDECL_END()
};
ID3DXEffect* g_pEffect = NULL;
LPDIRECT3DVERTEXDECLARATION9 g_pMeshVertexDeclaration = NULL;
LPDIRECT3DTEXTURE9 g_pDefaultMeshTexture = NULL;
std::vector<CDXUTXFileMesh*> g_Meshs;
std::vector<D3DXMATRIX> g_MeshMatWorld;
LPDIRECT3DTEXTURE9 g_pShadowMap = NULL;
LPDIRECT3DSURFACE9 g_pShadowMapDepthStencil = NULL;
CFirstPersonCamera g_ViewCamera;
CFirstPersonCamera g_LightCamera;
D3DLIGHT9 g_Light;
bool InitApp()
{
g_Light.Diffuse = D3DXCOLOR(0.0f, 1.0f, 1.0f, 1.0f);
g_Light.Ambient = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);
g_Light.Theta = D3DX_PI/4.0f;
D3DXVECTOR3 vViewEye(0.0f, 120.0f, -150.0f);
D3DXVECTOR3 vViewLookAt(0.0f, 20.0f, 0.0f);
g_ViewCamera.SetViewParams(&vViewEye, &vViewLookAt);
g_ViewCamera.SetRotateButtons( true, false, false );
g_ViewCamera.SetScalers( 0.01f, 15.0f );
D3DXVECTOR3 vLightEye(-100.0f, 100.0f, -150.0f);
D3DXVECTOR3 vLightLookAt(0.0f, 0.0f, 0.0f);
g_LightCamera.SetViewParams(&vLightEye, &vLightEye);
return true;
}
void CleanUp()
{
for (unsigned int idx= 0; idx < g_Meshs.size(); idx++)
{
delete g_Meshs[idx];
}
g_Meshs.clear();
}
//--------------------------------------------------------------------------------------
// Rejects any D3D9 devices that aren't acceptable to the app by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
bool bWindowed, void* pUserContext )
{
// Typically want to skip back buffer formats that don't support alpha blending
IDirect3D9* pD3D = DXUTGetD3D9Object();
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
return false;
if (pCaps->PixelShaderVersion < D3DPS_VERSION(2, 0))
{
return false;
}
if (FAILED(pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE, D3DFMT_A8R8G8B8)))
{
return false;
}
if (FAILED(pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE, D3DFMT_R32F)))
{
return false;
}
return true;
}
//--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )
{
return true;
}
HRESULT InsertMesh(IDirect3DDevice9* pd3dDevice ,LPCWSTR fileName)
{
HRESULT hr = S_OK;
WCHAR szTemp[MAX_PATH] = {0};
V_RETURN(DXUTFindDXSDKMediaFileCch(szTemp, MAX_PATH,fileName));
CDXUTXFileMesh* pTemp = new CDXUTXFileMesh();
pTemp->Create(pd3dDevice, szTemp);
pTemp->SetVertexDecl(pd3dDevice, g_aVertDecl);
g_Meshs.push_back(pTemp);
return S_OK;
}
HRESULT InsertMatrix(D3DXVECTOR3 vPos, D3DXVECTOR3 scale)
{
HRESULT hr = S_OK;
D3DXMATRIX matWorld;
D3DXMATRIX matScale;
D3DXMATRIX matMove;
D3DXMatrixScaling(&matScale, scale.x, scale.y, scale.z);
D3DXMatrixTranslation(&matMove, vPos.x, vPos.y, vPos.z);
D3DXMatrixMultiply(&matWorld, &matScale, &matMove);
g_MeshMatWorld.push_back(matWorld);
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)
// and aren't tied to the back buffer size
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
HRESULT hr = S_OK;
WCHAR szTemp[MAX_PATH] = {0};
V_RETURN(DXUTFindDXSDKMediaFileCch(szTemp, MAX_PATH, L"ShadowMap.fx"));
DWORD dwEffectFlags = D3DXFX_NOT_CLONEABLE;
V_RETURN(D3DXCreateEffectFromFile(pd3dDevice, szTemp, NULL, NULL, dwEffectFlags, NULL, &g_pEffect, NULL));
V_RETURN(pd3dDevice->CreateVertexDeclaration(g_aVertDecl, &g_pMeshVertexDeclaration));
V_RETURN(InsertMesh(pd3dDevice, L"wenben.X"));
V_RETURN(InsertMatrix(D3DXVECTOR3(0.0f, 50.0f, 0.0f), D3DXVECTOR3(0.5f, 0.5f, 0.5f)));
V_RETURN(InsertMesh(pd3dDevice, L"long.X"));
V_RETURN(InsertMatrix(D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(1.0f, 1.0f, 1.0f)));
V_RETURN(InsertMesh(pd3dDevice, L"laohu.X"));
V_RETURN(InsertMatrix(D3DXVECTOR3(-40.0f, 0.0f, 0.0f), D3DXVECTOR3(1.0f, 1.0f, 1.0f)));
V_RETURN(InsertMesh(pd3dDevice, L"baozi.X"));
V_RETURN(InsertMatrix(D3DXVECTOR3(0.0f, 0.0f, 40.0f), D3DXVECTOR3(1.0f, 1.0f, 1.0f)));
V_RETURN(InsertMesh(pd3dDevice, L"shizi.X"));
V_RETURN(InsertMatrix(D3DXVECTOR3(40.0f, 0.0f, 0.0f), D3DXVECTOR3(1.0f, 1.0f, 1.0f)));
V_RETURN(InsertMesh(pd3dDevice, L"lang.X"));
V_RETURN(InsertMatrix(D3DXVECTOR3(0.0f, 0.0f, -40.0f), D3DXVECTOR3(1.0f, 1.0f, 1.0f)));
V_RETURN(InsertMesh(pd3dDevice, L"diban.X"));
V_RETURN(InsertMatrix(D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(1.0f, 1.0f, 1.0f)));
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT)
// or that are tied to the back buffer size
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
HRESULT hr = S_OK;
V_RETURN(g_pEffect->OnResetDevice());
for (unsigned int idx = 0; idx < g_Meshs.size(); idx++)
{
V_RETURN(g_Meshs[idx]->RestoreDeviceObjects(pd3dDevice));
}
DXUTDeviceSettings setting = DXUTGetDeviceSettings();
V_RETURN(pd3dDevice->CreateTexture(1,1,1,D3DUSAGE_DYNAMIC,
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pDefaultMeshTexture, NULL));
D3DLOCKED_RECT lr;
V_RETURN(g_pDefaultMeshTexture->LockRect(0, &lr, NULL, 0));
*(LPDWORD)lr.pBits = D3DCOLOR_ARGB(255,255,255,255);
V_RETURN(g_pDefaultMeshTexture->UnlockRect(0));
V_RETURN(pd3dDevice->CreateTexture(pBackBufferSurfaceDesc->Width,
pBackBufferSurfaceDesc->Height, 1, D3DUSAGE_RENDERTARGET,
D3DFMT_R32F, D3DPOOL_DEFAULT, &g_pShadowMap, NULL));
V_RETURN(pd3dDevice->CreateDepthStencilSurface(pBackBufferSurfaceDesc->Width,
pBackBufferSurfaceDesc->Height,setting.d3d9.pp.AutoDepthStencilFormat, D3DMULTISAMPLE_NONE,
0, TRUE, &g_pShadowMapDepthStencil,NULL ));
g_ViewCamera.SetProjParams(D3DX_PI/4.0f, pBackBufferSurfaceDesc->Width/(float)pBackBufferSurfaceDesc->Height, 0.1f, 500.0f);
g_LightCamera.SetProjParams(D3DX_PI/4.0f, pBackBufferSurfaceDesc->Width/(float)pBackBufferSurfaceDesc->Height, 0.1f, 500.0f);
V_RETURN(g_pEffect->SetValue("g_clrLightAmbient", &g_Light.Ambient, sizeof(D3DXCOLOR)));
V_RETURN(g_pEffect->SetValue("g_clrLightDiffuse", &g_Light.Diffuse, sizeof(D3DXCOLOR)));
V_RETURN(g_pEffect->SetFloat("g_fShadowWidth", (float)pBackBufferSurfaceDesc->Width));
V_RETURN(g_pEffect->SetFloat("g_fShadowHeight", (float)pBackBufferSurfaceDesc->Height));
V_RETURN(g_pEffect->SetFloat("g_fLightCosTheta", cosf(g_Light.Theta)));
return S_OK;
}
//--------------------------------------------------------------------------------------
// Handle updates to the scene. This is called regardless of which D3D API is used
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
D3DXVECTOR3 vEye(200.0f * cosf(fTime), 100.0f, 200.0f * sinf(fTime));
D3DXVECTOR3 vAt(0.0f, 0.0f, 0.0f);
g_LightCamera.SetViewParams(&vEye, &vAt);
g_ViewCamera.FrameMove(fElapsedTime);
g_LightCamera.FrameMove(fElapsedTime);
}
HRESULT RenderMesh(const D3DXMATRIX* pMatView)
{
HRESULT hr = S_OK;
for (unsigned int idx = 0; idx < g_Meshs.size(); idx++)
{
D3DXMATRIX matWorldView;
D3DXMatrixMultiply(&matWorldView, &g_MeshMatWorld[idx], pMatView);
V_RETURN(g_pEffect->SetMatrix("g_matWorldView", &matWorldView));
unsigned int cPass;
V_RETURN(g_pEffect->Begin(&cPass, 0));
for (unsigned int iPass= 0; iPass < cPass; iPass++)
{
V_RETURN(g_pEffect->BeginPass(iPass));
for (unsigned int iMtrl = 0; iMtrl < g_Meshs[idx]->m_dwNumMaterials; iMtrl++)
{
V_RETURN(g_pEffect->SetValue("g_clrMtrlAmbient", &g_Meshs[idx]->m_pMaterials[iMtrl].Ambient, sizeof(D3DXVECTOR4)));
V_RETURN(g_pEffect->SetValue("g_clrMtrlDiffuse", &g_Meshs[idx]->m_pMaterials[iMtrl].Diffuse, sizeof(D3DXVECTOR4)));
if (g_Meshs[idx]->m_pTextures[iMtrl])
{
V_RETURN(g_pEffect->SetTexture("g_texMesh", g_Meshs[idx]->m_pTextures[iMtrl]));
}
else
{
V_RETURN(g_pEffect->SetTexture("g_texMesh", g_pDefaultMeshTexture));
}
V_RETURN(g_pEffect->CommitChanges());
V_RETURN(g_Meshs[idx]->GetMesh()->DrawSubset(iMtrl));
}
V_RETURN(g_pEffect->EndPass());
}
V_RETURN(g_pEffect->End());
}
return S_OK;
}
HRESULT RenderScene(IDirect3DDevice9* pD3DDevice, bool bRenderShadow, const D3DXMATRIX* pMatView, const D3DXMATRIX* pMatProj)
{
HRESULT hr = S_OK;
V(g_pEffect->SetMatrix("g_matProjection", pMatProj));
D3DXVECTOR3 v3 = *g_LightCamera.GetEyePt();
D3DXVECTOR4 v4;
D3DXVec3Transform(&v4, &v3, pMatView);
V(g_pEffect->SetVector("g_vLightPos", &v4));
*(D3DXVECTOR3*)&v4 = *g_LightCamera.GetWorldAhead();
v4.w = 0.0f;
D3DXVec4Transform(&v4, &v4, pMatView);
D3DXVec3Normalize((D3DXVECTOR3*)&v4, (D3DXVECTOR3*)&v4 );
V(g_pEffect->SetVector("g_vLightDir", &v4));
V_RETURN( pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 0, 0, 170 ), 1.0f, 0 ) );
if (SUCCEEDED(pD3DDevice->BeginScene()))
{
if (bRenderShadow)
{
V_RETURN(g_pEffect->SetTechnique("RenderShadow"));
V_RETURN(RenderMesh(pMatView));
}
else
{
V_RETURN(g_pEffect->SetTechnique("RenderMesh"));
V_RETURN(RenderMesh(pMatView));
}
V_RETURN(pD3DDevice->EndScene());
}
return S_OK;
}
//--------------------------------------------------------------------------------------
// Render the scene using the D3D9 device
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
HRESULT hr = S_OK;
//=======================渲染影子==================
LPDIRECT3DSURFACE9 pOldRT = NULL;
V(pd3dDevice->GetRenderTarget(0, &pOldRT));
LPDIRECT3DSURFACE9 pOldDS = NULL;
V(pd3dDevice->GetDepthStencilSurface(&pOldDS));
LPDIRECT3DSURFACE9 pShadowSurface = NULL;
if (SUCCEEDED(g_pShadowMap->GetSurfaceLevel(0, &pShadowSurface)))
{
V(pd3dDevice->SetRenderTarget(0, pShadowSurface));
SAFE_RELEASE(pShadowSurface);
}
V(pd3dDevice->SetDepthStencilSurface(g_pShadowMapDepthStencil));
const D3DXMATRIX* pMatlLightView = g_LightCamera.GetViewMatrix();
V(RenderScene(pd3dDevice, true, pMatlLightView, g_LightCamera.GetProjMatrix()));
//=========================渲染网格=====================
V(pd3dDevice->SetRenderTarget(0, pOldRT));
SAFE_RELEASE(pOldRT);
V(pd3dDevice->SetDepthStencilSurface(pOldDS));
SAFE_RELEASE(pOldDS);
V(g_pEffect->SetTexture("g_texShadow", g_pShadowMap));
const D3DXMATRIX* pMatView = g_ViewCamera.GetViewMatrix();
D3DXMATRIX matViewToLightProj = *pMatView;
D3DXMatrixInverse(&matViewToLightProj, NULL, &matViewToLightProj);
D3DXMatrixMultiply(&matViewToLightProj, &matViewToLightProj, pMatlLightView);
D3DXMatrixMultiply(&matViewToLightProj, &matViewToLightProj, g_LightCamera.GetProjMatrix());
V(g_pEffect->SetMatrix("g_matViewToLightProj", &matViewToLightProj));
V(RenderScene(pd3dDevice, false, pMatView, g_ViewCamera.GetProjMatrix()));
}
//--------------------------------------------------------------------------------------
// Handle messages to the application
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool* pbNoFurtherProcessing, void* pUserContext )
{
g_ViewCamera.HandleMessages( hWnd, uMsg, wParam, lParam );
return 0;
}
//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9ResetDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
HRESULT hr = S_OK;
if (g_pEffect)
{
V(g_pEffect->OnLostDevice());
}
for (unsigned int idx = 0; idx < g_Meshs.size(); idx++)
{
g_Meshs[idx]->InvalidateDeviceObjects();
}
SAFE_RELEASE(g_pShadowMap);
SAFE_RELEASE(g_pShadowMapDepthStencil);
SAFE_RELEASE(g_pDefaultMeshTexture);
}
//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9CreateDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
SAFE_RELEASE(g_pEffect);
for (unsigned int idx = 0; idx < g_Meshs.size(); idx++)
{
g_Meshs[idx]->Destroy();
}
SAFE_RELEASE(g_pMeshVertexDeclaration);
}
//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
// Set the callback functions
DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );
DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );
DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackFrameMove( OnFrameMove );
// TODO: Perform any application-level initialization here
if (!InitApp())
{
return -1;
}
// Initialize DXUT and create the desired Win32 window and Direct3D device for the application
DXUTInit( true, true ); // Parse the command line and show msgboxes
DXUTSetHotkeyHandling( true, true, true ); // handle the default hotkeys
DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
DXUTCreateWindow( L"EmptyProject" );
DXUTCreateDevice( true, 640, 480 );
// Start the render loop
DXUTMainLoop();
// TODO: Perform any application-level cleanup here
CleanUp();
return DXUTGetExitCode();
}
这个例子全靠来回抄。
这下就好啦。我会把工程压缩那么一下下上传。
纯属在这里扯淡 我写这个就是为了记录自己学过他,当然交流更好啦。
至于工程配置什么的 就用dx例子里面的empty来搞最合适了,不然还得搭建框架,费力不讨好。
有什么不懂得可以联系某 某对这个例子基本上是都理解了。呵呵包会~~
最后 没有美女的博客怎么叫博客呢