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

永遠也不完美的程序

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

常用鏈接

統計

積分與排名

好友鏈接

最新評論

零距離接觸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>
            欧美区日韩区| 亚洲欧美日韩区| 午夜精品久久久久久久久久久久久 | 亚洲国产成人精品久久久国产成人一区 | 久久激情综合| 久久久久国产一区二区| 久久久综合免费视频| 美女视频黄 久久| 欧美日韩不卡| 国产欧美一区二区在线观看| 国产一区二区欧美日韩| 在线观看欧美| 亚洲综合视频一区| 欧美freesex8一10精品| 亚洲精品午夜精品| 午夜在线视频一区二区区别| 久久午夜视频| 欧美天天视频| 在线看欧美视频| 亚洲一区二区三区午夜| 久久一综合视频| 一本久道久久综合婷婷鲸鱼| 欧美在线观看视频| 欧美日韩午夜激情| 影音先锋久久精品| 香蕉国产精品偷在线观看不卡| 麻豆成人综合网| 99精品欧美| 另类综合日韩欧美亚洲| 国产精品麻豆欧美日韩ww| 亚洲国产一区二区a毛片| 久久综合色综合88| 国产精品免费视频xxxx| 最新国产乱人伦偷精品免费网站| 亚洲欧美日韩一区在线| 巨乳诱惑日韩免费av| 99国产一区二区三精品乱码| 久久全国免费视频| 国产日韩欧美精品综合| 亚洲视频导航| 亚洲第一偷拍| 久久久久久久久久久久久9999| 国产精品夫妻自拍| 亚洲精品孕妇| 久久婷婷蜜乳一本欲蜜臀| 一区二区三区视频在线看| 欧美成人国产一区二区| 国产丝袜美腿一区二区三区| 亚洲在线1234| 99视频一区二区| 欧美日产一区二区三区在线观看| 亚洲成色www8888| 久久精品在线视频| 欧美一区二区国产| 国产精品日韩精品| 亚洲女爱视频在线| 9i看片成人免费高清| 欧美区亚洲区| 在线一区二区三区四区| 亚洲人成艺术| 欧美日韩高清在线一区| 一本久道综合久久精品| 亚洲黄色av| 欧美精品综合| 在线综合视频| 中国av一区| 国产香蕉97碰碰久久人人| 久久国产精品久久精品国产| 性欧美18~19sex高清播放| 国产日韩欧美在线一区| 久久亚洲国产精品日日av夜夜| 久久国产精品久久久久久| 国内精品久久久久久| 麻豆精品91| 欧美激情一区二区三区蜜桃视频 | 久久精品99国产精品日本| 国产亚洲一二三区| 免费欧美日韩| 欧美精品一区二区三区蜜桃| 中日韩男男gay无套 | 欧美成人免费在线视频| 妖精视频成人观看www| 在线午夜精品| 狠狠久久婷婷| 亚洲区一区二| 国产农村妇女精品一区二区| 在线观看亚洲专区| 欧美激情一区二区三级高清视频| 欧美巨乳波霸| 久久成人免费| 欧美成人乱码一区二区三区| 在线亚洲激情| 久久精品最新地址| 一本大道久久a久久精品综合| 亚洲欧美日韩电影| 亚洲精品在线视频观看| 亚洲一级在线观看| 亚洲高清久久网| 中日韩美女免费视频网址在线观看 | 国产精品免费网站在线观看| 久久久www免费人成黑人精品| 欧美1区2区3区| 久久国产精品72免费观看| 欧美精品乱码久久久久久按摩| 香蕉av福利精品导航| 欧美黄色成人网| 久久夜色精品国产亚洲aⅴ| 欧美激情亚洲综合一区| 久久久精品五月天| 国产精品v片在线观看不卡| 欧美国产日韩在线| 国语自产精品视频在线看抢先版结局 | 亚洲国产精品国自产拍av秋霞| 一区二区日韩精品| 日韩视频在线一区二区三区| 久久国产精品色婷婷| 亚洲欧美精品在线观看| 欧美久久99| 亚洲国产91| 91久久精品日日躁夜夜躁国产| 亚洲欧美在线视频观看| 亚洲综合社区| 国产精品黄色| 亚洲视频在线观看一区| 亚洲一区日本| 国产精品成人一区二区网站软件| 亚洲日本乱码在线观看| 91久久线看在观草草青青| 久久久久久日产精品| 久久精品国产综合精品| 国产性天天综合网| 欧美在线观看一区| 麻豆久久婷婷| 亚洲人成在线播放| 欧美国产综合| 亚洲美女精品成人在线视频| 99成人精品| 欧美视频一区在线观看| 99国产麻豆精品| 亚洲欧美国产毛片在线| 国产精品视频一区二区高潮| 亚洲一区二区少妇| 午夜精品一区二区三区在线| 国产精品久久777777毛茸茸| 亚洲天堂第二页| 欧美一区二区三区四区夜夜大片 | 欧美午夜精品理论片a级大开眼界 欧美午夜精品理论片a级按摩 | 看片网站欧美日韩| 免费观看欧美在线视频的网站| 韩国女主播一区二区三区| 久久久精品动漫| 欧美黄色免费网站| av成人老司机| 国产精品视频免费| 久久久亚洲午夜电影| 亚洲黄网站在线观看| 一区二区三区高清视频在线观看| 欧美日韩精品一区二区天天拍小说| 99av国产精品欲麻豆| 欧美一区二区三区久久精品茉莉花| 国产一区久久久| 麻豆91精品91久久久的内涵| 亚洲另类在线一区| 久久精品国产第一区二区三区| 在线欧美电影| 欧美性大战久久久久久久蜜臀| 亚洲欧美区自拍先锋| 欧美国产精品久久| 亚洲欧美日韩在线一区| 在线精品在线| 国产精品一区二区三区成人| 免费在线播放第一区高清av| 中文在线不卡视频| 欧美高清视频www夜色资源网| 亚洲午夜一区二区| 亚洲第一成人在线| 国产精品入口尤物| 欧美韩国在线| 久久精品久久综合| 亚洲视频一起| 亚洲欧洲在线免费| 美女国内精品自产拍在线播放| 亚洲午夜一区二区| 亚洲精品久久在线| 黄色亚洲在线| 国产精品色在线| 欧美激情在线有限公司| 久久精品国产2020观看福利| 亚洲美女色禁图| 欧美成人免费在线观看| 久久国产精品久久精品国产| 在线视频一区二区| 亚洲人成网站在线播| 一区二区三区在线不卡| 国产乱码精品一区二区三区忘忧草 | 欧美大香线蕉线伊人久久国产精品| 亚洲一区影院| 一区二区激情视频| 亚洲精品国产拍免费91在线| 免费欧美视频|