ShadowMap实现

用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来搞最合适了,不然还得搭建框架,费力不讨好。

有什么不懂得可以联系某 某对这个例子基本上是都理解了。呵呵包会~~

最后 没有美女的博客怎么叫博客呢

柳岩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

当当小螳螂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值