文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>顶点着色器例子——Diffuse Lighting(《龙书》)

顶点着色器例子——Diffuse Lighting(《龙书》)

时间:2011-02-07  来源:斯芬克斯

#include "d3dUtility.h"

//
// Globals
//

IDirect3DDevice9* Device = 0; 

const int Width  = 640;
const int Height = 480;

IDirect3DVertexShader9* DiffuseShader = 0;                      //顶点着色器
ID3DXConstantTable* DiffuseConstTable = 0;                      //shader的常量表

ID3DXMesh* Teapot            = 0;

//常量表中shader变量句柄,用于设置shader中对应变量的值
D3DXHANDLE ViewMatrixHandle     = 0;
D3DXHANDLE ViewProjMatrixHandle = 0;
D3DXHANDLE AmbientMtrlHandle    = 0;
D3DXHANDLE DiffuseMtrlHandle    = 0;
D3DXHANDLE LightDirHandle       = 0;

D3DXMATRIX Proj;

//
// Framework functions
//
bool Setup()
{
        HRESULT hr = 0;

        //
        // Create geometry:
        //

        D3DXCreateTeapot(Device, &Teapot, 0);

        //
        // 编译着色器
        //

        ID3DXBuffer* shader      = 0;
        ID3DXBuffer* errorBuffer = 0;

        hr = D3DXCompileShaderFromFile(
                "diffuse.txt",//shader文件名
                0,
                0,
                "Main", // entry point function name
                "vs_1_1",
                D3DXSHADER_DEBUG | D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY, 
                &shader,//编译后的着色器代码
                &errorBuffer,//存储错误代码
                &DiffuseConstTable);//获取常量表

        // output any error messages
        if( errorBuffer )
        {
                ::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);
                d3d::Release<ID3DXBuffer*>(errorBuffer);
        }

        if(FAILED(hr))
        {
                ::MessageBox(0, "D3DXCompileShaderFromFile() - FAILED", 0, 0);
                return false;
        }

        //
        // 创建着色器
        //

        hr = Device->CreateVertexShader(
                (DWORD*)shader->GetBufferPointer(),//前面得到的编译后的着色器代码
                &DiffuseShader);//创建的着色器

        if(FAILED(hr))
        {
                ::MessageBox(0, "CreateVertexShader - FAILED", 0, 0);
                return false;
        }

        d3d::Release<ID3DXBuffer*>(shader);


        // 
        // Get Handles,根据shader变量名获取句柄(关联变量,以便于外部设置shader变量的值)
        //

        ViewMatrixHandle    = DiffuseConstTable->GetConstantByName(0, "ViewMatrix");
        ViewProjMatrixHandle= DiffuseConstTable->GetConstantByName(0, "ViewProjMatrix");
        AmbientMtrlHandle   = DiffuseConstTable->GetConstantByName(0, "AmbientMtrl");
        DiffuseMtrlHandle   = DiffuseConstTable->GetConstantByName(0, "DiffuseMtrl");
        LightDirHandle      = DiffuseConstTable->GetConstantByName(0, "LightDirection");

        //
        // Set shader constants:(设置shader变量的值,有些shader变量需要在C++代码中初始化,即外部初始化)
        //

        // Light direction:
        D3DXVECTOR4 directionToLight(-0.57f, 0.57f, -0.57f, 0.0f);
        DiffuseConstTable->SetVector(Device, LightDirHandle, &directionToLight);

        // Materials:
        D3DXVECTOR4 ambientMtrl(0.0f, 0.0f, 1.0f, 1.0f);
        D3DXVECTOR4 diffuseMtrl(0.0f, 0.0f, 1.0f, 1.0f);

        DiffuseConstTable->SetVector(Device,AmbientMtrlHandle,&ambientMtrl);
        DiffuseConstTable->SetVector(Device,DiffuseMtrlHandle,&diffuseMtrl);
        DiffuseConstTable->SetDefaults(Device);                              //此方法在应用程序的设置用应调用一次,设置常量的默认值

        // Compute projection matrix.计算投影矩阵
        D3DXMatrixPerspectiveFovLH(
                &Proj,      D3DX_PI * 0.25f, 
                (float)Width / (float)Height, 1.0f, 1000.0f);
        //固定管线:Device->SetTransform(D3DTS_PROJECTION, &Proj);


        return true;
}

void Cleanup()
{
        d3d::Release<ID3DXMesh*>(Teapot);
        d3d::Release<IDirect3DVertexShader9*>(DiffuseShader);
        d3d::Release<ID3DXConstantTable*>(DiffuseConstTable);
}

bool Display(float timeDelta)
{
        if( Device )
        {
                // 
                // Update the scene: Allow user to rotate around scene.
                //
                
                static float angle  = (3.0f * D3DX_PI) / 2.0f;
                static float height = 3.0f;
        
                if( ::GetAsyncKeyState(VK_LEFT) & 0x8000f )
                        angle -= 0.5f * timeDelta;

                if( ::GetAsyncKeyState(VK_RIGHT) & 0x8000f )
                        angle += 0.5f * timeDelta;

                if( ::GetAsyncKeyState(VK_UP) & 0x8000f )
                        height += 5.0f * timeDelta;

                if( ::GetAsyncKeyState(VK_DOWN) & 0x8000f )
                        height -= 5.0f * timeDelta;

                D3DXVECTOR3 position( cosf(angle) * 7.0f, height, sinf(angle) * 7.0f );
                D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
                D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
                D3DXMATRIX V;
                D3DXMatrixLookAtLH(&V, &position, &target, &up);
                //固定管线:Device->SetTransform(D3DTS_VIEW, &V);//设置照相机的位置

                DiffuseConstTable->SetMatrix(Device, ViewMatrixHandle, &V);

                D3DXMATRIX ViewProj = V * Proj;
                DiffuseConstTable->SetMatrix(Device, ViewProjMatrixHandle, &ViewProj);

                //
                // Render
                //

                Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
                Device->BeginScene();

                //启用定点着色器
                //Device->SetVertexShader(DiffuseShader);

                Teapot->DrawSubset(0);
                
                Device->EndScene();
                Device->Present(0, 0, 0, 0);
        }
        return true;
}

//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
        switch( msg )
        {
        case WM_DESTROY:
                ::PostQuitMessage(0);
                break;
                
        case WM_KEYDOWN:
                if( wParam == VK_ESCAPE )
                        ::DestroyWindow(hwnd);

                break;
        }
        return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,
                                   HINSTANCE prevInstance, 
                                   PSTR cmdLine,
                                   int showCmd)
{
        if(!d3d::InitD3D(hinstance,
                Width, Height, true, D3DDEVTYPE_HAL, &Device))
        {
                ::MessageBox(0, "InitD3D() - FAILED", 0, 0);
                return 0;
        }
                
        if(!Setup())
        {
                ::MessageBox(0, "Setup() - FAILED", 0, 0);
                return 0;
        }

        d3d::EnterMsgLoop( Display );

        Cleanup();

        Device->Release();

        return 0;
}


// File: diffuse.txt
matrix ViewMatrix;

matrix ViewProjMatrix;

vector AmbientMtrl;

vector DiffuseMtrl

vector LightDirection;

vector DiffuseLightIntensity = {0.0f, 0.0f, 1.0f, 1.0f};

vector AmbientLightIntensity = {0.0f, 0.0f, 0.2f, 1.0f};

struct VS_INPUT

{   

   vector position : POSITION;   

   vector normal   : NORMAL;

};
struct VS_OUTPUT

{    

  vector position : POSITION;  

  vector diffuse  : COLOR;

};


VS_OUTPUT Main(VS_INPUT input)

{   

   VS_OUTPUT output = (VS_OUTPUT)0;

  // Transform position to homogeneous clip space(齐次裁剪空间)   

  // and store in the output.position member.     

  output.position = mul(input.position, ViewProjMatrix);


  // Transform lights and normals to view space(视口空间).  Set w    

  // componentes to zero since we're transforming vectors     

  // here and not points.        

  LightDirection.w = 0.0f;   

  input.normal.w   = 0.0f;    

  LightDirection   = mul(LightDirection, ViewMatrix);    

  input.normal     = mul(input.normal,   ViewMatrix);

 

  // Compute cosine of the angle between light and normal.     

  float s = dot(LightDirection, input.normal);

  if( s < 0.0f )        

    s = 0.0f;

  
    output.diffuse = (AmbientMtrl * AmbientLightIntensity) + (s * (DiffuseLightIntensity * DiffuseMtrl)); 

  return output;

}

相关阅读 更多 +
排行榜 更多 +
找茬脑洞的世界安卓版

找茬脑洞的世界安卓版

休闲益智 下载
滑板英雄跑酷2手游

滑板英雄跑酷2手游

休闲益智 下载
披萨对对看下载

披萨对对看下载

休闲益智 下载