程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 可以運行HLSL的DirectX程序

可以運行HLSL的DirectX程序

編輯:關於.NET

之後的一段時間准備學習一下DirectX和Shader相關的文章.

為了能夠運行Shader,得先寫個小程序.這裡我選擇了DirectX(其實我個人覺得,如果只是想學習Shader 的話,XNA是個不錯的選擇)

看了幾天的文檔,重點看了一下DirectX Sample裡面的Basic HLSL,可能是微軟為了把一些控件集成進 去,方便大家觀察效果的原因吧,微軟使用了DXUT這個框架,對我等c++和windows編程的初學者來說特別的 不爽,所以我決定脫離DXUT框架來寫一下

首先打開Sample裡面的D3DX9 Create Device.我們就往這個程序裡面添加代碼.

1. 我們添加一個LoadMesh函數: 導入.X文件

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函數,在顯卡初始化完成後,可以進行一些處理操作:

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.0f, 1.0f, 1.0f, 1.0f);

    D3DXCOLOR colorMtrlAmbient(0.35f, 0.35f, 0.35f, 0);


    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.0f, 500.0f, 500.0f);

    D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );

    D3DXVECTOR3 vUpVec   ( 0.0f, 1.0f, 0.0f );

    D3DXMatrixLookAtLH( &g_view, &vEyePt, &vLookatPt, &vUpVec );

    g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_view );

    //設置Projection Matrix

    D3DXMatrixPerspectiveFovLH( &g_proj, D3DX_PI/4, 1.0f, 1.0f, 10000.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.我們開始渲染:

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.0f, 0);


    //開始渲染場景

    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.完成程序退出後的釋放操作:

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函數,使得中間一段看起來這樣:

    //

    // 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.添加頭文件和全局變量:

#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的程序

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved