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

永遠也不完美的程序

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

常用鏈接

統計

積分與排名

好友鏈接

最新評論

零距離接觸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 狂爛球 閱讀(579) 評論(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>
            亚洲精品乱码久久久久久蜜桃91| 99国产精品国产精品久久| 国产精品美女在线观看| 久久久美女艺术照精彩视频福利播放 | 一区二区动漫| 亚洲免费观看高清在线观看| 欧美激情导航| 欧美肥婆bbw| 9久草视频在线视频精品| 一区二区欧美亚洲| 久久爱另类一区二区小说| 久久男人资源视频| 蜜乳av另类精品一区二区| 欧美日韩蜜桃| 国产在线播放一区二区三区| 国精品一区二区| 亚洲尤物在线| 亚洲激情校园春色| 99国产精品久久久久久久成人热| 午夜精品电影| 欧美日韩中文字幕在线视频| 黄色成人在线| 欧美影院精品一区| 夜色激情一区二区| 久久午夜电影| 伊人影院久久| 久久夜色精品国产欧美乱| 亚洲在线视频网站| 欧美午夜视频| 亚洲欧美日本日韩| 亚洲视频高清| 亚洲色图自拍| 欧美日韩精品免费观看视一区二区 | 欧美色道久久88综合亚洲精品| 国产精品视频99| 欧美一级久久久久久久大片| 99精品国产热久久91蜜凸| 欧美视频官网| 亚洲一区二区三区激情| 日韩亚洲在线| 国产精品日韩一区二区三区| 亚洲欧洲av一区二区| 欧美一区永久视频免费观看| 亚洲欧洲日韩综合二区| 91久久国产综合久久91精品网站| 欧美日韩国产bt| 欧美在线观看视频一区二区三区 | 亚洲国产成人久久综合| 美女精品网站| 先锋影音国产一区| 巨胸喷奶水www久久久免费动漫| 亚洲国产精品一区制服丝袜| 亚洲欧洲精品一区二区三区波多野1战4 | 影音先锋亚洲精品| 亚洲国产高清一区二区三区| 欧美性大战久久久久| 免费国产一区二区| 欧美视频专区一二在线观看| 久久久欧美精品| 国产精品爽爽爽| 99精品国产福利在线观看免费| 国产欧美一区二区视频| 狠狠色狠狠色综合日日91app| 亚洲第一在线综合网站| 国产欧美激情| 99热在这里有精品免费| 亚洲精品一品区二品区三品区| 久久国产精品亚洲77777| 亚洲线精品一区二区三区八戒| 蜜桃av噜噜一区| 亚洲国产精品va在看黑人| 怡红院精品视频| 久久久久久一区二区| 免费成年人欧美视频| 国产日产欧产精品推荐色| 亚洲自拍偷拍色片视频| 亚洲欧美中文日韩在线| 国产亚洲免费的视频看| 先锋影音一区二区三区| 美女国产一区| 亚洲深夜av| 国产精品午夜久久| 久久国产综合精品| 亚洲激情第一页| 亚洲欧美日韩专区| 激情另类综合| 欧美网站在线| 免费美女久久99| 亚洲欧美精品在线| 亚洲国产另类久久精品| 欧美一进一出视频| 一区二区欧美日韩视频| 激情欧美一区二区三区| 国产精品久久久久7777婷婷| 久久久久亚洲综合| 午夜精品视频网站| 99视频精品在线| 91久久精品美女| 欧美国产在线视频| 蜜桃av一区二区三区| 亚洲一区欧美二区| 精品999在线观看| 国产精品无码专区在线观看 | 毛片精品免费在线观看| 亚洲午夜av| 亚洲另类自拍| 亚洲麻豆av| 亚洲欧洲免费视频| 亚洲激情在线激情| 亚洲国产成人av| 影音先锋日韩精品| 亚洲日本成人| 亚洲人成高清| 夜夜夜精品看看| 日韩亚洲视频在线| 亚洲午夜久久久| 久久精品一区四区| 免费日韩成人| 日韩小视频在线观看| 一本色道久久综合狠狠躁篇怎么玩| 亚洲日本久久| 中文av一区二区| 欧美亚洲日本网站| 久久精彩视频| 欧美日本簧片| 国产区精品在线观看| 国产在线不卡精品| 亚洲黄色免费| 欧美一区二区在线免费观看| 另类av导航| 亚洲免费在线精品一区| 久久婷婷国产综合尤物精品 | 欧美大片91| 日韩视频在线观看| 久久精品国产亚洲aⅴ| 欧美日本免费| 亚洲二区免费| 久久午夜羞羞影院免费观看| 亚洲毛片一区二区| 久久久成人网| 日韩午夜免费| 欧美福利在线观看| 国内精品免费午夜毛片| 亚洲午夜视频| 亚洲国产一区二区视频| 久久精品国产久精国产爱| 国产欧美一区二区三区在线老狼| 亚洲欧洲一区二区三区| 欧美激情国产高清| 久久精品一区蜜桃臀影院| 国产视频亚洲| 久久久av水蜜桃| 欧美一区二区视频免费观看| 国产欧美在线看| 久久久精品五月天| 久久资源av| 亚洲精品美女免费| 99视频有精品| 韩日精品中文字幕| 欧美国产日韩a欧美在线观看| 欧美精品日本| 久久久99久久精品女同性| 久久人人爽人人爽爽久久| 在线精品一区| 亚洲综合欧美| 亚洲电影专区| 欧美一区二区三区四区在线观看| 在线看国产日韩| 亚洲午夜免费福利视频| 精品9999| 久久不射2019中文字幕| 亚洲美女毛片| 欧美亚洲一区二区三区| 亚洲精选一区| 性欧美超级视频| 亚洲卡通欧美制服中文| 香蕉精品999视频一区二区| 日韩视频免费看| 玖玖综合伊人| 欧美成人精品1314www| 国产欧美在线观看| 亚洲性视频网站| 亚洲桃花岛网站| 欧美日韩成人在线观看| 欧美成人自拍| 久久欧美肥婆一二区| 欧美少妇一区二区| 久久久综合精品| 国产精品色婷婷久久58| 亚洲高清不卡| 99精品视频一区| 狼人社综合社区| 久久婷婷综合激情| 狠狠色丁香婷婷综合影院| 亚洲欧美一区二区三区极速播放| 久久国产精品电影| 国精品一区二区| 欧美国产精品日韩| 亚洲第一成人在线| 999亚洲国产精|