青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

永遠也不完美的程序

不斷學習,不斷實踐,不斷的重構……

常用鏈接

統計

積分與排名

好友鏈接

最新評論

零距離接觸HLSL 一(轉載)

 

人一旦停下來不做事情,就會變得懶惰。自從停止寫《Direct3D 快速上手》后,就老不想寫東西,這些天一直都在想著要寫一些關于游戲引擎的文章,遲遲未敢動手,因為覺得這個主題實在比較大,自己水平有限,寫不好還要被人笑話。為了督促自己再次像個陀螺轉起來,開始寫一些關于HLSL以及Shader的東西,當然,我學這個也不久,只能講到一些膚淺的東西,意在拋磚引玉。

這里我假設你已經明白以寫有關流水線的基本得知識,以及明白為什么要使用Shader這之類的基本的問題,我就不多花時間介紹這些基本得知識,相關的知識大家可以在MSDN的網站上看到,以及很多有名的樹上都有詳細的介紹,例如《Microsoft DirectX 9 Programmable Graphics Pipeline

好那我們就開始。這里我不再使用C#作為編寫程序的語言,雖然我很喜歡它,但是考慮到用Shader的目的就是為了效率,那在語言的選擇上自然選擇C++,編譯工具選用VC.Net

在以后的文章中,我或許會提到Cg這個語言,這個微軟和NVIDIA聯合開發的一門語言,其實和HLSL只不過是叫了2個不同的名字罷了,完全可以兼容運行。

作為第一章,還是弄一點比較簡單的例子,這個例子里面我們著重探討的是Vertex Shader以及PS的語法,以及怎么把它們運用到DirectX的程序中去,這個例子沒有任何的實用性,It is only a sample.

以下是運行圖例:


 

 

 

 

 

 


首先看看我們程序的結構:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void init(void); //初始化所有資源

void shutDown(void); //釋放資源

void render(void);   //渲染函數

void initShader( void ); //初始化Shader

很簡單對吧,其實也可以用微軟提供給我們的DX的框架,這個看個人的喜好了。

我們先來看看Vertex Shader

建立一個新的文件,存為vertex_shad.vsh,然后輸入:

float4x4 worldViewProj;

 

struct VS_INPUT

{

     float3 position : POSITION; //位置

     float4 color0    : COLOR0;    //顏色

     float2 texcoord0 : TEXCOORD0; //紋理坐標

};

 

struct VS_OUTPUT

{

     float4 hposition : POSITION;

     float4 color0    : COLOR0;

     float2 texcoord0 : TEXCOORD0;

};

 

VS_OUTPUT main( VS_INPUT IN ) //入口函數

{

     VS_OUTPUT OUT;

     float4 v = float4( IN.position.x,IN.position.y, IN.position.z,1.0f );

    OUT.hposition = mul( v, worldViewProj ); //矩陣變換

    OUT.color0    = IN.color0; //輸出的顏色=輸入的顏色

    OUT.texcoord0 = IN.texcoord0; //復制紋理坐標

 

    return OUT;

}

這里首先定義了2個結構,都分別定義了位置,顏色,和紋理坐標。這里我們看到程序里面使用了很多我們沒見過的數據類型,這是HLSL內置的數據結構,例如float4x4

我們注意下float4這個類型,它是一個有4個向量的浮點類型,你可以把它理解為一個浮點的數組,當然嚴格的說,這里應該是壓縮數組。

    float3 position : POSITION; //位置

這一句話聲明了一個float3的變量,變量的名字叫做position,這里我們看到在后面還有一個冒號和POSITION,這個冒號和其后的POSRITION叫做“語義”。語義的作用相當于在HLSL出現以前的Shader中用到的寄存器,這里我們指明了把position這個變量將與流水線的POSRITION寄存器相連接。在其后的COLOR0, TEXCOORD0也是一樣的意思。

我們看到Shader的入口函數main,這個函數有一個參數和一個返回值,都是我們在Shader的開頭定義的結構。

    OUT.hposition = mul( v, worldViewProj ); //矩陣變換

我們將向量和矩陣相乘,這樣得到的仍然是一個向量,這個向量就是經過我們的透視變換的向量。這里之所以要進行這個變換是為了讓所有的定點都在視區內并且在選轉的時候符合透視。

在將所有的返回值賦值完成后,程序返回。

接下來我們建立pixel_shader.psh文件,這是pixelShader文件:

struct VS_OUTPUT

{

     float4 hposition : POSITION;

     float4 color0    : COLOR0;

     float2 texcoord0 : TEXCOORD0;

};

struct PS_OUTPUT

{

     float4 color : COLOR;

};

sampler testTexture; //樣本對象

 

PS_OUTPUT main( VS_OUTPUT IN )

{

     PS_OUTPUT OUT;

         OUT.color = tex2D( testTexture, IN.texcoord0 ) + IN.color0; // Add texel color to vertex color

 

     return OUT;

}

相對于VS來說PS的代碼簡單很多,程序聲明了一個樣本對象,然后在PS的入口程序中用到了tex2D函數,這個函數可以用制定的紋理坐標集存取不同類型的樣本并返回一個向量結果。

OUT.color = tex2D( testTexture, IN.texcoord0 ) + IN.color0; 的結果是把顏色疊加在原來紋理的地方。

 

我們該看看我們的主程序了,這里我只介紹最重要的initShader

void initShader( void )

{

     D3DXCreateTextureFromFile( g_pd3dDevice, "test.bmp", &g_pTexture );

     D3DVERTEXELEMENT9 declaration[] =

     {

         { 0, 0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },

         { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,    0 },

         { 0, 16, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },

         D3DDECL_END()

     };

 

     g_pd3dDevice->CreateVertexDeclaration( declaration, &g_pVertexDeclaration );

 

     HRESULT hr;

     LPD3DXBUFFER pCode;

     DWORD dwShaderFlags = 0;

     LPD3DXBUFFER pBufferErrors = NULL;

 

     // Assemble the vertex shader from the file

     hr = D3DXCompileShaderFromFile( "vertex_shader.vsh", NULL, NULL, "main",

         "vs_1_1", dwShaderFlags, &pCode,

         &pBufferErrors, &g_pConstantTableVS );

 

     if( FAILED(hr) )

     {

         LPVOID pCompilErrors = pBufferErrors->GetBufferPointer();

         MessageBox(NULL, (const char*)pCompilErrors, "Vertex Shader Compile Error",

              MB_OK|MB_ICONEXCLAMATION);

     }

 

     // Create the vertex shader

     g_pd3dDevice->CreateVertexShader( (DWORD*)pCode->GetBufferPointer(),

         &g_pVertexShader );

     pCode->Release();

 

     //

     // Create a HLSL based pixel shader.

     //

 

     // Assemble the vertex shader from the file

     hr = D3DXCompileShaderFromFile( "pixel_shader.psh", NULL, NULL, "main",

         "ps_1_1", dwShaderFlags, &pCode,

         &pBufferErrors, &g_pConstantTablePS );

 

     if( FAILED(hr) )

     {

         LPVOID pCompilErrors = pBufferErrors->GetBufferPointer();

         MessageBox(NULL, (const char*)pCompilErrors, "Pixel Shader Compile Error",

              MB_OK|MB_ICONEXCLAMATION);

     }

 

     // Create the vertex shader

     g_pd3dDevice->CreatePixelShader( (DWORD*)pCode->GetBufferPointer(),

         &g_pPixelShader );

     pCode->Release();

}

一開始我們定義了一個D3DVERTEXELEMENT9結構,這個結構的作用是描述頂點數據的用途等等屬性:

typedef struct _D3DVERTEXELEMENT9 {

    WORD Stream; //Stream number

   WORD Offset; //數據的偏移量

    BYTE Type;   //種類,也是一個結構,詳細情況查閱MSDN

    BYTE Method; //制定方格化的操作,為default時,值將被拷貝如寄存器

    BYTE Usage;   //用途

    BYTE UsageIndex; //修改用途,允許用戶指定多種用途

} D3DVERTEXELEMENT9

 

接下來,我們就要建立一個VertexDeclaration

HRESULT CreateVertexDeclaration( 
CONST D3DVERTEXELEMENT9* pVertexElements,
Direct3DVertexDeclaration9** ppDecl
);

然后我們從文件中讀入Shader的信息。PS的讀入和VS如出一轍。我們看看渲染的部分。

void render( void )

{

    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,

                         D3DCOLOR_COLORVALUE(0.0f,1.0f,0.0f,1.0f), 1.0f, 0 );

    g_pd3dDevice->BeginScene();

     D3DXMATRIX matTrans;

     D3DXMATRIX matRot;

 

     D3DXMatrixTranslation( &matTrans, 0.0f, 0.0f, 4.0f );

     D3DXMatrixRotationYawPitchRoll( &matRot,

         D3DXToRadian(g_fSpinX),

         D3DXToRadian(g_fSpinY),

         0.0f );

     g_matWorld = matRot * matTrans;

 

     D3DXMatrixIdentity( &g_matView );

 

     if( g_bUseShaders == true )

     {

         //

         // Use vertex and pixel shaders...

         //

 

         D3DXMATRIX worldViewProjection = g_matWorld * g_matView * g_matProj;

         g_pConstantTableVS->SetMatrix( g_pd3dDevice, "worldViewProj", &worldViewProjection );

 

         g_pd3dDevice->SetVertexDeclaration( g_pVertexDeclaration );

         g_pd3dDevice->SetVertexShader( g_pVertexShader );

 

        

         g_pd3dDevice->SetTexture( 0, g_pTexture );

         g_pd3dDevice->SetPixelShader( g_pPixelShader );

 

         g_pd3dDevice->SetFVF( Vertex::FVF_Flags );

         g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0,sizeof(Vertex) );

         g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

 

         g_pd3dDevice->SetVertexShader( NULL );

         g_pd3dDevice->SetPixelShader( NULL );

     }

     else

     {

         //

         // Render the normal way...

         //

 

         g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld );

 

         g_pd3dDevice->SetTexture( 0, g_pTexture );

         g_pd3dDevice->SetFVF( Vertex::FVF_Flags );

         g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0,sizeof(Vertex) );

         g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

     }

 

 

    g_pd3dDevice->EndScene();

 

    g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

}

 

g_pConstantTableVS->SetMatrix( g_pd3dDevice, "worldViewProj", &worldViewProjection );

這一句將視覺矩陣和我們在Vertex Shader中定義的矩陣關聯起來。然后我們通過

g_pd3dDevice->SetVertexDeclaration( g_pVertexDeclaration );

         g_pd3dDevice->SetVertexShader( g_pVertexShader );

來通知程序,所有的頂點的處理都要由我們的頂點Shader來處理,頂點Shader中用到的所有頂點的一些屬性都在VertexDeclaration中聲明了。然后建立頂點的Shader

在建立完VS,紋理,PS后,執行畫圖指令,最后我們需要釋放Shader,恢復固定流水線的功能。g_pd3dDevice->SetVertexShader( NULL );g_pd3dDevice->SetPixelShader( NULL );

 

好了,這里我們的程序就完成了,接下來的日子里面,我將盡力為大家講解一些Shader的有用的特性,呵呵呵,當然,這里我沒有說,不是所有的顯卡都支持Shader的,所以你需要在程序中判斷你顯卡所支持的類型,這里我不再多些,2句話就可以搞定。

By sssa2000

5/15/2005

posted on 2008-08-07 17:59 狂爛球 閱讀(580) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜国产精品视频| 先锋资源久久| 欧美高清在线播放| 亚洲七七久久综合桃花剧情介绍| 开心色5月久久精品| 久久久国产精品一区二区中文| 国产在线视频不卡二| 久久夜色精品国产欧美乱| 久久久福利视频| 亚洲乱亚洲高清| 一区二区三区免费看| 国产日韩欧美视频| 免费看亚洲片| 欧美三区美女| 久久午夜电影| 欧美日本一区| 久久久无码精品亚洲日韩按摩| 久久天天躁狠狠躁夜夜av| 9久re热视频在线精品| 亚洲一区二区在线| 亚洲国产精品成人综合色在线婷婷| 欧美黄色影院| 国产精品你懂得| 欧美成人免费全部观看天天性色| 欧美日韩少妇| 久久综合色播五月| 欧美日韩另类视频| 久久野战av| 国产精品高清免费在线观看| 巨乳诱惑日韩免费av| 欧美片第一页| 久久综合久色欧美综合狠狠| 欧美日韩精品一本二本三本| 久久久久一区二区| 欧美午夜免费电影| 欧美韩日一区二区三区| 国产精品美女久久久久av超清 | 亚洲免费观看高清在线观看| 亚洲视频一区二区在线观看 | 国产精品成人在线观看| 久久影院午夜片一区| 欧美三级视频在线| 亚洲国产一区二区在线| 国产农村妇女精品一区二区| 亚洲日本在线视频观看| 国产一区在线视频| 亚洲色无码播放| 亚洲精品无人区| 久久久中精品2020中文| 性做久久久久久久免费看| 欧美激情视频网站| 欧美二区在线观看| 伊人成人在线视频| 先锋亚洲精品| 欧美一区二区三区在线观看视频| 欧美日韩高清在线一区| 欧美成人亚洲成人| 今天的高清视频免费播放成人| 亚洲亚洲精品三区日韩精品在线视频 | 99ri日韩精品视频| 亚洲美女毛片| 欧美69wwwcom| 欧美高清在线| 亚洲日本理论电影| 女人香蕉久久**毛片精品| 久久综合精品国产一区二区三区| 国产亚洲毛片在线| 欧美中文字幕不卡| 久久精品亚洲国产奇米99| 国产美女精品人人做人人爽| 亚洲性夜色噜噜噜7777| 亚洲欧美日韩精品久久久久| 欧美视频在线观看免费| 夜夜嗨网站十八久久| 亚洲手机在线| 国产精品外国| 久久精品在线免费观看| 美女爽到呻吟久久久久| 亚洲第一天堂av| 欧美大尺度在线| 亚洲精品社区| 亚洲欧美激情视频| 国产精品永久免费| 欧美在线视频免费| 模特精品在线| 亚洲无线视频| 国产欧美1区2区3区| 久久久999精品| 亚洲第一综合天堂另类专| 亚洲人成在线播放| 欧美性做爰毛片| 久久国产福利| 亚洲国产91精品在线观看| 一区二区三区欧美日韩| 国产欧美日韩亚洲一区二区三区| 久久国产精品久久久久久久久久| 欧美激情黄色片| 亚洲一区二区三区免费视频| 国产一区二区三区高清| 欧美多人爱爱视频网站| 亚洲无吗在线| 欧美国产综合视频| 午夜日韩视频| 亚洲精品国产视频| 国产欧美日韩视频在线观看 | 欧美aaaaaaaa牛牛影院| 国产精品99久久99久久久二8| 久久精品视频在线免费观看| 亚洲清纯自拍| 国产区精品视频| 欧美日本在线视频| 久久成人国产精品| 一本色道久久综合亚洲精品不卡 | 亚洲国产一区二区在线| 久久www成人_看片免费不卡| 最新日韩在线| 国产一区二区三区直播精品电影| 欧美韩日一区| 久久五月婷婷丁香社区| 亚洲综合视频1区| 亚洲人成毛片在线播放女女| 开心色5月久久精品| 亚洲欧美一区二区激情| 亚洲国产精品久久久久秋霞不卡| 国产精品午夜电影| 欧美日韩精品免费观看视一区二区| 欧美在线综合视频| 亚洲综合好骚| 亚洲视频www| 亚洲精品在线一区二区| 欧美成在线视频| 久久尤物视频| 久久―日本道色综合久久| 午夜精品久久久久久久久久久| 99国产精品99久久久久久| 在线精品观看| 尤物视频一区二区| 国产在线欧美日韩| 国产欧美三级| 国产亚洲a∨片在线观看| 国产精品久久久一区二区三区| 欧美精品免费播放| 欧美精品久久久久久久| 欧美高清在线观看| 欧美大片va欧美在线播放| 牛牛影视久久网| 欧美激情视频一区二区三区免费 | 国产精品美女久久福利网站| 欧美日在线观看| 欧美日韩在线播放三区| 欧美日韩在线观看一区二区| 欧美日韩国产一中文字不卡| 欧美区在线播放| 欧美视频在线免费| 国产精品日本一区二区| 国产欧美激情| 在线不卡中文字幕| 亚洲国产欧美精品| 日韩午夜激情| 亚洲一区美女视频在线观看免费| 亚洲一区免费看| 欧美一区二区视频在线| 久久一二三四| 欧美黄色免费| 亚洲最新视频在线| 亚洲欧美国产一区二区三区| 久久精品国产亚洲一区二区| 久久综合狠狠综合久久激情| 欧美成人免费小视频| 欧美日韩国产一区二区三区| 国产精品免费久久久久久| 国产日韩在线视频| 午夜激情一区| 一区二区三区四区蜜桃| 欧美无乱码久久久免费午夜一区 | 亚洲一区视频| 欧美性猛交一区二区三区精品| 中文精品一区二区三区| 亚洲国产婷婷| 宅男精品视频| 香蕉精品999视频一区二区| 狠狠综合久久| 国产精品99久久久久久人| 亚洲一区制服诱惑| 麻豆精品网站| 99这里只有精品| 久久精品国产一区二区三| 欧美精品三级| 国产综合色一区二区三区| 一区二区高清在线观看| 久久久青草婷婷精品综合日韩 | 91久久国产综合久久| 国产精品99久久不卡二区| 久久蜜桃资源一区二区老牛 | 欧美sm视频| 国产在线日韩| 亚洲伊人一本大道中文字幕| 欧美大片一区二区| 午夜一级在线看亚洲| 欧美日韩亚洲视频|