<@乌龟:>第一个可以运行HLSL的DirectX程序

  之后的一段时间准备学习一下DirectXShader相关的文章.

  为了能够运行Shader,得先写个小程序.这里我选择了DirectX(其实我个人觉得,如果只是想学习Shader的话,XNA是个不错的选择)

  看了几天的文档,重点看了一下DirectX Sample里面的Basic HLSL,可能是微软为了把一些控件集成进去,方便大家观察效果的原因吧,微软使用了DXUT这个框架,对我等c++windows编程的初学者来说特别的不爽,所以我决定脱离DXUT框架来写一下

  首先打开Sample里面的D3DX9 Create Device.我们就往这个程序里面添加代码.

1. 我们添加一个LoadMesh函数: 导入.X文件

  

Code
HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh )
{
    ID3DXMesh
* pMesh = NULL;
    WCHAR str[MAX_PATH];
    HRESULT hr;

    
//调用D3DXLoadMeshFromX从文件中读取.X文件
    D3DXLoadMeshFromX(strFileName, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh);

    DWORD 
*rgdwAdjacency = NULL;

    
//确定Mesh具有法线向量,如果没有的话就调用D3DXComputeNormals来进行计算.
    if!(pMesh->GetFVF() & D3DFVF_NORMAL) )
    {
        ID3DXMesh
* pTempMesh;
        pMesh
->CloneMeshFVF( pMesh->GetOptions(), 
                                  pMesh
->GetFVF() | D3DFVF_NORMAL, 
                                  pd3dDevice, 
&pTempMesh );
        D3DXComputeNormals( pTempMesh, NULL);
        pMesh 
= pTempMesh;
    }

    
*ppMesh = pMesh;

    
return S_OK;
}

 

2.我们添加OnCreateDevice函数,在显卡初始化完成后,可以进行一些处理操作:

 

Code
HRESULT OnCreateDevice()
{
    HRESULT hr;

    D3DXVECTOR3
* pData; 

    
//.fx文件的文件名
    WCHAR str[MAX_PATH];

    
//设置ShaderFlags
    DWORD dwShaderFlags = 0;
    dwShaderFlags 
|= D3DXSHADER_NO_PRESHADER;
    
    
//读取.fx文件
    D3DXCreateEffectFromFile( g_pd3dDevice, L"BasicHLSL.fx", NULL, NULL, dwShaderFlags, NULL, &g_pEffect, NULL );

    
//读取贴图文件
    D3DXCreateTextureFromFileEx( g_pd3dDevice, L"Tiny_skin.dds", D3DX_DEFAULT, D3DX_DEFAULT, 
                                       D3DX_DEFAULT, 
0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, 
                                       D3DX_DEFAULT, D3DX_DEFAULT, 
0
                                       NULL, NULL, 
&g_pMeshTexture );

    
//设置Shader的参数
    D3DXCOLOR colorMtrlDiffuse(1.0f1.0f1.0f1.0f);
    D3DXCOLOR colorMtrlAmbient(
0.35f0.35f0.35f0);

    g_pEffect
->SetValue("g_MaterialAmbientColor"&colorMtrlAmbient, sizeof(D3DXCOLOR));
    g_pEffect
->SetValue("g_MaterialDiffuseColor"&colorMtrlDiffuse, sizeof(D3DXCOLOR));    
    g_pEffect
->SetTexture("g_MeshTexture", g_pMeshTexture);

    
//设置View Matrix
    D3DXVECTOR3 vEyePt  (  0.0f500.0f500.0f);
    D3DXVECTOR3 vLookatPt( 
0.0f0.0f0.0f );
    D3DXVECTOR3 vUpVec   ( 
0.0f1.0f0.0f );
    D3DXMatrixLookAtLH( 
&g_view, &vEyePt, &vLookatPt, &vUpVec );
    g_pd3dDevice
->SetTransform( D3DTS_VIEW, &g_view );
    
    
//设置Projection Matrix
    D3DXMatrixPerspectiveFovLH( &g_proj, D3DX_PI/41.0f1.0f10000.0f );
    g_pd3dDevice
->SetTransform( D3DTS_PROJECTION, &g_proj );

    
//设置World Matrix
    D3DXMatrixRotationY( &g_world, timeGetTime()/150.0f );
    g_pd3dDevice
->SetTransform( D3DTS_WORLD, &g_world );

    
//设置灯光
    g_vLightDir[0= D3DXVECTOR3(1.0f,0.0f,0.0f);
    g_vLightDir[
1= D3DXVECTOR3(0.0f,1.0f,0.0f);
    g_vLightDir[
2= D3DXVECTOR3(0.0f,0.0f,1.0f);
    g_vLightDiffuse[
0= D3DXCOLOR(1,1,1,1);
    g_vLightDiffuse[
1= D3DXCOLOR(1,1,1,1);
    g_vLightDiffuse[
2= D3DXCOLOR(1,1,1,1);

    
return S_OK;
}

 

3.我们开始渲染:

 

Code
VOID Render()
{
    HRESULT hr;
    D3DXMATRIXA16 mWorldViewProjection;
    UINT iPass, cPasses;
   
    
//清除Render Target和Z缓冲
    g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DXCOLOR(0.0f,0.25f,0.25f,0.55f), 1.0f0);

    
//开始渲染场景
    if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
    {
        
//计算WVP矩阵
        mWorldViewProjection = g_world * g_view * g_proj;
        
        D3DXCOLOR vWhite 
= D3DXCOLOR(1,1,1,1);

        
//设置Shader参数
        g_pEffect->SetValue( "g_LightDir", g_vLightDir, sizeof(D3DXVECTOR3)*MAX_LIGHTS );
        g_pEffect
->SetValue( "g_LightDiffuse", g_vLightDiffuse, sizeof(D3DXVECTOR4)*MAX_LIGHTS );
        g_pEffect
->SetMatrix( "g_mWorldViewProjection"&mWorldViewProjection);
        g_pEffect
->SetMatrix( "g_mWorld"&g_world );
        g_pEffect
->SetValue("g_MaterialDiffuseColor"&vWhite, sizeof(D3DXCOLOR));
        g_pEffect
->SetFloat( "g_fTime"1.0f);          
        
        
//设置渲染时候的Technique
        g_pEffect->SetTechnique("RenderSceneWithTexture3Light");

        
//开始执行Shader进行渲染
        g_pEffect->Begin(&cPasses, 0);

        
for (iPass = 0; iPass < cPasses; iPass++)
        {
            g_pEffect
->BeginPass(iPass);

            
//绘制模型
            g_pMesh->DrawSubset(0);

            g_pEffect
->EndPass();
        }
        g_pEffect
->End();
        g_pd3dDevice
->EndScene();
    }
    
//显示渲染结果
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

 

4.完成程序退出后的释放操作:

 

Code
VOID Cleanup()
{
    
if( g_pMesh != NULL )
        g_pMesh
->Release();
    
    
if( g_pd3dDevice != NULL )
        g_pd3dDevice
->Release();

    
if( g_pD3D != NULL )
        g_pD3D
->Release();
}

 

5.修改wWinMain函数,使得中间一段看起来这样:

Code
    //
    
// Initialize Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    { 
        
// Create the scene geometry
        if( SUCCEEDED( LoadMesh(g_pd3dDevice,L"tiny.x",&g_pMesh) ) )
        {
            OnCreateDevice();
            
// Show the window
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );
     
//

 

6.添加头文件和全局变量:

Code
#include <Windows.h>
#include 
<mmsystem.h>
#include 
<d3dx9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning 
#include 
<strsafe.h>
#pragma warning( default : 4996 ) 

//--------------------------------------------------------------------------// Global variables
//--------------------------------------------------------------------------

LPDIRECT3D9             g_pD3D           
= NULL; // 用来建立D3DDevice
LPDIRECT3DDEVICE9       g_pd3dDevice     = NULL; // 我们的Device

D3DXMATRIXA16 g_world;
D3DXMATRIXA16 g_view;
D3DXMATRIXA16 g_proj;

ID3DXEffect
*            g_pEffect = NULL;       // D3DX特效接口
ID3DXMesh*              g_pMesh = NULL;         // 模型对象
IDirect3DTexture9*      g_pMeshTexture = NULL;  // 模型贴图

#define MAX_LIGHTS 3
float                g_fLightScale;
int                  g_nNumActiveLights = 3;
int                  g_nActiveLight;

D3DXVECTOR3 g_vLightDir[MAX_LIGHTS];
D3DXCOLOR   g_vLightDiffuse[MAX_LIGHTS];

 

7.将Tiny.X,Tiny_Skin.dds,BasicHLSL.fx放入项目的目录,并把BasicHLSL.fx添加进项目,就完成了我们第一个可以运行Shader的程序

posted on 2009-03-09 09:36  乌龟_毛驴  阅读(2572)  评论(4编辑  收藏  举报

导航