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

永遠(yuǎn)也不完美的程序

不斷學(xué)習(xí),不斷實踐,不斷的重構(gòu)……

常用鏈接

統(tǒng)計

積分與排名

好友鏈接

最新評論

HLSL初級教程2

2.頂點著色器

頂點著色器vertex shader)是一個在顯卡的GPU上執(zhí)行的程序,它替換了固定功能管道fixed function pipeline)中的變換transformation)和光照lighting)階段(這不是百分之百的正確,因為頂點著色器可以被Direct3D運行時Direct3D runtime)以軟件模擬,如果硬件不支持頂點著色器的話)。圖2.1說明了管線中頂點著色器替換的部件。 

 

2.1

由于頂點著色器是我們(在HLSL中)寫的一個自定義程序,因此我們在圖形效果方面獲得了極大的自由性。我們不再受限于Direct3D的固定光照算法。此外,應(yīng)用程序操縱頂點位置的能力也有了多樣性,例如:布料仿真,粒子系統(tǒng)的點大小操縱,還有頂點混合/變形。此外,我們的頂點數(shù)據(jù)結(jié)構(gòu)更自由了,并且可以在可編程管線中包含比在固定功能管線中多的多的數(shù)據(jù)。

正如作者所在群的公告所說,“拍照不在于你對相機(jī)使用的熟練程度,而是在于你對藝術(shù)的把握。”之前的介紹使讀者對著色器的編寫和使用都有了一定的了解,下面我們將把重心從介紹如何使用著色器轉(zhuǎn)到如何實現(xiàn)更高級的渲染效果上來。


2.1可編程數(shù)據(jù)流模型

DirectX 8.0引入了數(shù)據(jù)流的概念,可以這樣理解數(shù)據(jù)流(圖2.2):

2.2

·       一個頂點由n個數(shù)據(jù)流組成。

·       一個數(shù)據(jù)流由m個元素組成。

·       一個元素是[位置、顏色、法向、紋理坐標(biāo)]。

程序中使用IDirect3DDevice9::SetStreamSource方法把一個頂點緩存綁定到一個設(shè)備數(shù)據(jù)流。


2.2頂點聲明

該小節(jié)對頂點聲明的描述絕大多數(shù)都取自翁云兵的《著色器和效果》,該文對頂點聲明的描述是我所見到最詳盡最透徹的,這里向作者表示敬意:)

到現(xiàn)在為止,我們已經(jīng)使用自由頂點格式(flexible vertex formatFVF)來描述頂點結(jié)構(gòu)中的各分量。但是,在可編程管線中,我們的頂點數(shù)據(jù)可以包含比用FVF所能表達(dá)的多的多的數(shù)據(jù)。因此,我們通常使用更具表達(dá)性的并且更強(qiáng)有力的頂點聲明(vertex declaration)。

注意:我們?nèi)匀豢梢栽诳删幊坦芫€中使用FVF——如果我們的頂點格式可以這樣描述。不管怎樣,這只是為了方便,因為FVF會在內(nèi)部被轉(zhuǎn)換為一個頂點聲明。

2.2.1 描述頂點聲明

我們將一個頂點聲明描述為一個D3DVERTEXELEMENT9結(jié)構(gòu)的數(shù)組。D3DVERTEXELEMENT9數(shù)組中的每個元素描述了一個頂點的分量。所以,如果你的頂點結(jié)構(gòu)有三個分量(例如:位置、法線、顏色),那么其相應(yīng)的頂點聲明將會被一個含3個元素的D3DVERTEXELEMENT9結(jié)構(gòu)數(shù)組描述。

D3DVERTEXELEMENT9結(jié)構(gòu)定義如下:

typedef struct _D3DVERTEXELEMENT9 {

     BYTE Stream;

     BYTE Offset;

     BYTE Type;

     BYTE Method;

     BYTE Usage;

     BYTE UsageIndex;

} D3DVERTEXELEMENT9;

²        Stream——指定關(guān)聯(lián)到頂點分量的流;

²        Offset——偏移,按字節(jié),相對于頂點結(jié)構(gòu)成員的頂點分量的開始。例如,如果頂點結(jié)構(gòu)是:

struct Vertex

{

     D3DXVECTOR3 pos;

     D3DXVECTOR3 normal;

};

……pos分量的偏移是0,因為它是第一個分量;normal分量的偏移是12,因為sizeof(pos) == 12。換句話說,normal分量以Vertex的第12個字節(jié)為開始。

²        Type——指定數(shù)據(jù)類型。它可以是D3DDECLTYPE枚舉類型的任意成員;完整列表請參見文檔。常用類型如下:

D3DDECLTYPE_FLOAT1——浮點數(shù)值

D3DDECLTYPE_FLOAT2——2D浮點向量

D3DDECLTYPE_FLOAT3——3D浮點向量

D3DDECLTYPE_FLOAT4——4D浮點向量

D3DDECLTYPE_D3DCOLOR—D3DCOLOR類型,它擴(kuò)展為RGBA浮點顏色向量(r, g, b, a),其每一分量都是歸一化到區(qū)間[0, 1]了的。

²        Method——指定網(wǎng)格化方法。我們認(rèn)為這個參數(shù)是高級的,因此我們使用默認(rèn)值,標(biāo)識為D3DDECLMETHOD_DEFAULT

²        Usage——指定已計劃的對頂點分量的使用。例如,它是否準(zhǔn)備用于一個位置向量、法線向量、紋理坐標(biāo)等,有效的用途標(biāo)識符(usage identifier)是D3DDECLUSAGE枚舉類型的:

typedef enum _D3DDECLUSAGE {

     D3DDECLUSAGE_POSITION     = 0, // Position.

     D3DDECLUSAGE_BLENDWEIGHTS = 1, // Blending weights.

     D3DDECLUSAGE_BLENDINDICES = 2, // Blending indices.

     D3DDECLUSAGE_NORMAL       = 3, // Normal vector.

     D3DDECLUSAGE_PSIZE        = 4, // Vertex point size.

     D3DDECLUSAGE_TEXCOORD     = 5, // Texture coordinates.

     D3DDECLUSAGE_TANGENT      = 6, // Tangent vector.

     D3DDECLUSAGE_BINORMAL     = 7, // Binormal vector.

     D3DDECLUSAGE_TESSFACTOR   = 8, // Tessellation factor.

     D3DDECLUSAGE_POSITIONT    = 9, // Transformed position.

     D3DDECLUSAGE_COLOR        = 10, // Color.

     D3DDECLUSAGE_FOG          = 11, // Fog blend value.

     D3DDECLUSAGE_DEPTH        = 12, // Depth value.

     D3DDECLUSAGE_SAMPLE       = 13 // Sampler data.

} D3DDECLUSAGE;

其中,D3DDECLUSAGE_PSIZE類型用于指定一個頂點的點的大小。它用于點精靈,因此我們可以基于每個頂點控制其大小。一個D3DDECLUSAGE_POSITION成員的頂點聲明意味著這個頂點已經(jīng)被變換,它通知圖形卡不要把這個頂點送到頂點處理階段(變形和光照)。

²        UsageIndex——用于標(biāo)識多個相同用途的頂點分量。這個用途索引是位于區(qū)間[0, 15]間的一個整數(shù)。例如,假設(shè)我們有三個用途為D3DDECLUSAGE_NORMAL的頂點分量。我們可以為第一個指定用途索引為0,為第二個指定用途索引為1,并且為第三個指定用途索引為2。按這種方式,我們可以通過其用途索引標(biāo)識每個特定的法線。

 

例:假設(shè)我們想要描述的頂點格式由兩個數(shù)據(jù)流組成,第一個數(shù)據(jù)流包含位置、法線、紋理坐標(biāo)3個分量,第二個數(shù)據(jù)流包含位置和紋理坐標(biāo)2個分量,頂點聲明可以指定如下:

D3DVERTEXELEMENT9 decl[] =

{

//第一個數(shù)據(jù)流,包含分量位置、法線、紋理坐標(biāo)

{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_

POSITION, 0 },

{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_

NORMAL, 0 },

{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_

TEXCOORD, 0 },

 

//第一個數(shù)據(jù)流,包含分量位置、紋理坐標(biāo)

{ 1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_

POSITION, 1 },

{ 1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_

NORMAL, 1 },

D3DDECL_END()

};

D3DDECL_END宏用于初始化D3DVERTEXELEMENT9數(shù)組的最后一個頂點元素。

 

2.2.2創(chuàng)建頂點聲明

CreateVertexDeclaration函數(shù)用于創(chuàng)建頂點聲明,decl為指向上一小節(jié)定義的D3DVERTEXELEMENT9數(shù)組的指針,函數(shù)返回IDirect3DVertexDeclaration9指針g_Decl

IDirect3DVertexDeclaration9   *g_Decl = NULL;

g_pd3dDevice->CreateVertexDeclaration(decl ,&g_Decl);

2.2.3設(shè)置頂點聲明

       g_pd3dDevice->SetVertexDeclaration(g_Decl);

 

       至此,可編程數(shù)據(jù)流模型、頂點聲明介紹完畢,在下面的例子中讀者將會有更連貫的理解。


2.3用頂點著色器實現(xiàn)漸變動畫

2.3.1漸變動畫(Morphing

       Morphing漸變是20世紀(jì)90年代出現(xiàn)的一種革命性的計算機(jī)圖形技術(shù),該技術(shù)使得動畫序列平滑且易于處理,即使在低檔配置的計算機(jī)系統(tǒng)上也能正常運行。

       漸變是指隨時間的變化把一個形狀改變?yōu)榱硪粋€形狀。對我們而言,這些形狀就是Mesh網(wǎng)格模型。漸變網(wǎng)格模型的處理就是以時間軸為基準(zhǔn),逐漸地改變網(wǎng)格模型頂點的坐標(biāo),從一個網(wǎng)格模型的形狀漸變到另外一個。請看圖2.3

 

2.3

       我們在程序中使用兩個網(wǎng)格模型——源網(wǎng)格模型和目標(biāo)網(wǎng)格模型,設(shè)源網(wǎng)格模型中頂點1的坐標(biāo)為AAxAyAz),目標(biāo)網(wǎng)格模型中對應(yīng)頂點1的坐標(biāo)為BBxByBz),要計算漸變過程中時間點t所對應(yīng)的頂點1的坐標(biāo)CCxCyCz),我們使用如下方法:

       T為源網(wǎng)格模型到目標(biāo)網(wǎng)格模型漸變所花費的全部時間,得到時間點t占整個過程T的比例為:

       S = t / T

那么頂點1t時刻對應(yīng)的坐標(biāo)C為:

       C = A * (1-S+ B * S

       這樣,在渲染過程中我們根據(jù)時間不斷調(diào)整S的值,就得到了從源網(wǎng)格模型(形狀一)到目標(biāo)網(wǎng)格模型(形狀二)的平滑過渡。

       接下來將在程序里使用頂點著色器實現(xiàn)我們的漸變動畫。

 

2.3.2漸變動畫中的頂點聲明

       程序中,我們設(shè)定一個頂點對應(yīng)兩個數(shù)據(jù)流,這兩個數(shù)據(jù)流分別包含了源網(wǎng)格模型的數(shù)據(jù)和目標(biāo)網(wǎng)格模型的數(shù)據(jù)。渲染過程中,我們在著色器里根據(jù)兩個數(shù)據(jù)流中的頂點數(shù)據(jù)以及時間值確定最終的頂點信息。

個數(shù)據(jù)流包含分量如下:

源網(wǎng)格模型數(shù)據(jù)流:頂點位置、頂點法線、紋理坐標(biāo);

目標(biāo)網(wǎng)格模型數(shù)據(jù)流:頂點位置、頂點法線;

注意目標(biāo)網(wǎng)格模型數(shù)據(jù)流沒有包含紋理坐標(biāo),因為紋理對于兩個網(wǎng)格模型都是一樣的,所以僅使用源網(wǎng)格模型的紋理就可以了。

頂點聲明指定如下:

D3DVERTEXELEMENT9 decl[] =

{

//源網(wǎng)格模型數(shù)據(jù)流,包含分量位置、法線、紋理坐標(biāo)

{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_

POSITION, 0 },

{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_

NORMAL, 0 },

{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_

TEXCOORD, 0 },

 

//目標(biāo)網(wǎng)格模型數(shù)據(jù)流,包含分量位置、紋理坐標(biāo)

{ 1, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_

POSITION, 1 },

{ 1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_

NORMAL, 1 },

D3DDECL_END()

};

 

2.3.3漸變動畫中的頂點著色器

下面給出頂點著色器源碼,代碼存儲于vs.txt中,該頂點著色器根據(jù)源網(wǎng)格模型數(shù)據(jù)流和目標(biāo)網(wǎng)格模型數(shù)據(jù)流中的信息以及時間標(biāo)尺值計算出頂點最終位置信息,并對頂點做了坐標(biāo)變換和光照處理。代碼中給出了詳細(xì)的注釋,幫助讀者理解。

//全局變量

//世界矩陣、觀察矩陣、投影矩陣的合矩陣,用于頂點的坐標(biāo)變換

matrix WVPMatrix;

 

//光照方向

vector LightDirection;

//存儲2.3.1小節(jié)提到的公式S = t / T中的時間標(biāo)尺S

//注意到Scalar是一個vector類型,我們在Scalar.x中存儲了S值,Scalar.y中存儲的則是(1-S)值

vector Scalar;

 

//輸入

struct VS_INPUT

{

       //對應(yīng)源網(wǎng)格模型數(shù)據(jù)流中的頂點分量:位置、法線、紋理坐標(biāo)

    vector position : POSITION;

    vector normal   : NORMAL;

float2 uvCoords : TEXCOORD;

//對應(yīng)目標(biāo)網(wǎng)格模型數(shù)據(jù)流中的頂點分量:位置、法線

    vector position1 : POSITION1;

    vector normal1   : NORMAL1;

};

 

//輸出

struct VS_OUTPUT

{

    vector position : POSITION;

    vector diffuse : COLOR;

    float2 uvCoords : TEXCOORD;

};

 

//入口函數(shù)

VS_OUTPUT Main(VS_INPUT input)

{

    VS_OUTPUT output = (VS_OUTPUT)0;

   

       //頂點最終位置output.position取決于源網(wǎng)格模型數(shù)據(jù)流中位置信息input.position和目標(biāo)網(wǎng)格模型數(shù)據(jù)流中位置信息input.position1以及時間標(biāo)尺Scalar的值

       //對應(yīng)2.3.1小節(jié)中的公式C = A * (1-S+ B * S

    output.position = input.position*Scalar.x + input.position1*Scalar.y;

       //頂點坐標(biāo)變換操作

    output.position = mul(output.position, WVPMatrix);

   

       //計算頂點最終法線值

    vector normal = input.normal*Scalar.x + input.normal1*Scalar.y;

       //逆光方向與法線的點積,獲得漫射色彩

    output.diffuse = dot((-LightDirection), normal);

   

       //存儲紋理坐標(biāo)

    output.uvCoords = input.uvCoords;

   

    return output;

}

       以上是本例用到的頂點著色器,在接下來的應(yīng)用程序中,我們將給三個著色器全局變量賦值:

²        WVPMatrix;

世界矩陣、觀察矩陣、投影矩陣的合矩陣,用于頂點的坐標(biāo)變換;

²        LightDirection

光照方向;

²        Scalar

存儲2.3.1小節(jié)提到的公式S = t / T中的時間標(biāo)尺S值;

注意到Scalar是一個vector類型,我們在Scalar.x中存儲了S值,Scalar.y中存儲的則是(1-S)值;

 

2.3.4應(yīng)用程序

我們在應(yīng)用程序中執(zhí)行以下操作:

·         加載兩個兩個Mesh模型:源網(wǎng)格模型,目標(biāo)網(wǎng)格模型;

·         創(chuàng)建、設(shè)置頂點聲明;

·         創(chuàng)建、設(shè)置頂點著色器;

·         為著色器全局賦值;

·         把兩個Mesh模型數(shù)據(jù)分別綁定到兩個數(shù)據(jù)流中;

·         渲染Mesh模型;

下面是應(yīng)用程序代碼:

/*********************聲明變量*****************/

//兩個指向LPD3DXMESH的指針,分別用于存儲源網(wǎng)格模型和目標(biāo)網(wǎng)格模型;

LPD3DXMESH                      g_SourceMesh;

LPD3DXMESH                                    g_TargetMesh;

 

//頂點聲明指針

IDirect3DVertexDeclaration9   *g_Decl = NULL;

 

//頂點著色器

IDirect3DVertexShader9        *g_VS   = NULL;

//常量表

ID3DXConstantTable* ConstTable = NULL;

 

//常量句柄

D3DXHANDLE WVPMatrixHandle          = 0;

D3DXHANDLE ScalarHandle                  = 0;

D3DXHANDLE LightDirHandle                = 0;

/***************程序初始化*****************/

//加載源、目標(biāo)網(wǎng)格模型

Load_Meshes();

 

//頂點聲明

D3DVERTEXELEMENT9 MorphMeshDecl[] =

{

       //1st stream is for source mesh - position, normal, texcoord

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

       { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },

       { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },

 

       //2nd stream is for target mesh - position, normal

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

       { 1, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   1 },

       D3DDECL_END()

};

 

//創(chuàng)建頂點著色器

ID3DXBuffer* shader      = NULL;

ID3DXBuffer* errorBuffer  = NULL;

D3DXCompileShaderFromFile("vs.txt",

                                           0,

                                           0,

                                        "Main", // entry point function name

                                        "vs_1_1",

                                          D3DXSHADER_DEBUG,

                                         &shader,

                                           &errorBuffer,

                                         &ConstTable);

      

if(errorBuffer)

{

       ::MessageBox(0, (char*)errorBuffer->GetBufferPointer(), 0, 0);

       ReleaseCOM(errorBuffer);

}

 

//創(chuàng)建頂點著色器

g_pd3dDevice->CreateVertexShader((DWORD*)shader->GetBufferPointer(), &g_VS);

 

//創(chuàng)建頂點聲明

g_pd3dDevice->CreateVertexDeclaration(MorphMeshDecl ,&g_Decl);

 

//得到各常量句柄

WVPMatrixHandle = ConstTable->GetConstantByName(0, "WVPMatrix");

ScalarHandle = ConstTable->GetConstantByName(0, "Scalar");

LightDirHandle = ConstTable->GetConstantByName(0, "LightDirection");

 

//為著色器全局變量LightDirection賦值

ConstTable->SetVector(g_pd3dDevice, LightDirHandle, &D3DXVECTOR4(0.0f, -1.0f, 0.0f, 0.0f));

//設(shè)置各著色器變量為默認(rèn)值

ConstTable->SetDefaults(g_pd3dDevice);

/*******************渲染*******************/

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

D3DCOLOR_XRGB(153,153,153), 1.0f, 0 );

g_pd3dDevice->BeginScene();

 

//為著色器全局變量WVPMatrix賦值

D3DXMATRIX matWorld, matView, matProj;

g_pd3dDevice->GetTransform(D3DTS_WORLD, &matWorld);

g_pd3dDevice->GetTransform(D3DTS_VIEW, &matView);

g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &matProj);

D3DXMATRIX matWVP;

matWVP = matWorld * matView * matProj;

 

ConstTable->SetMatrix(g_pd3dDevice, WVPMatrixHandle, &matWVP);

 

//為著色器全局變量Scalar賦值,注意程序中獲取時間標(biāo)尺值Scalar的方法

float DolphinTimeFactor = (float)(timeGetTime() % 501) / 250.0f;

float Scalar =

(DolphinTimeFactor<=1.0f)?DolphinTimeFactor:(2.0f-DolphinTimeFactor);

ConstTable->SetVector(g_pd3dDevice,ScalarHandle,&D3DXVECTOR4(1.0f-Scalar, Scalar, 0.0f, 0.0f));

 

//設(shè)置頂點著色器和頂點聲明

g_pd3dDevice->SetVertexShader(g_VS);

g_pd3dDevice->SetVertexDeclaration(g_Decl);

 

//綁定目標(biāo)網(wǎng)格模型的定點緩存到第二個數(shù)據(jù)流中

IDirect3DVertexBuffer9 *pVB = NULL;

g_TargetMesh->GetVertexBuffer(&pVB);

g_pd3dDevice->SetStreamSource(1, pVB, 0,

D3DXGetFVFVertexSize(g_TargetMesh->GetFVF()));

ReleaseCOM(pVB);

 

//綁定源網(wǎng)格模型的頂點緩存到第一個數(shù)據(jù)流中

g_SourceMesh->GetVertexBuffer(&pVB);

g_pd3dDevice->SetStreamSource(0, pVB, 0,

D3DXGetFVFVertexSize(g_TargetMesh->GetFVF()));

ReleaseCOM(pVB);

 

//繪制Mesh網(wǎng)格模型

DrawMesh(g_SourceMesh, g_pMeshTextures0, g_VS, g_Decl);

 

g_pd3dDevice->EndScene();

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

 

2.3.5對應(yīng)用程序的一點說明

程序中我們使用SetStreamSource方法把源網(wǎng)格模型和目標(biāo)網(wǎng)格模型中的頂點緩存分別綁定到兩個設(shè)備數(shù)據(jù)流,但是Direct3D對數(shù)據(jù)流中的數(shù)據(jù)的真正引用只有在調(diào)用諸如DrawPrimitiveDrawIndexedPrimitive之類的繪制方法時才發(fā)生,因此在繪制Mesh網(wǎng)格模型時我們不能再使用傳統(tǒng)的DrawSubmit方法,而是使用了DrawIndexedPrimitive,下面就如何調(diào)用DrawIndexedPrimitive繪制Mesh模型進(jìn)行說明,該部分內(nèi)容和HLSL著色器關(guān)系不大,在這里列出僅僅是為了大家理解程序的完整性,讀者完全可以跳過本節(jié)不看。

       使用DrawIndexedPrimitive繪制Mesh模型的步驟如下:

       1. 加載網(wǎng)格模型后使用OptimizeInPlace方法對Mesh進(jìn)行優(yōu)化;

       2. 一旦優(yōu)化了網(wǎng)格模型,你就可以查詢ID3DXMesh對象,得到一個D3DXATTRIBUTERANGE數(shù)據(jù)類型的數(shù)組,我們稱之為屬性列表,該數(shù)據(jù)類型被定義如下:

              typedef struct_D3DXATTRIBUTERANGE{

                     DWORD AttribId; //子集編號

                     DWORD FaceStart; //這兩個變量用于圈定本子集中的多邊形

                     DWORD FaceCount;

                     DWORD VertexStart; //這兩個變量用于圈定本子集中的頂點

                     DWORD VertexCount;

              } D3DXATTRIBUTERANGE;

              我們屬性列表中的每一項都代表一個被優(yōu)化后Mesh的一個子集,D3DXATTRIBUTERANGE結(jié)構(gòu)的各字段描述了該子集的信息。

1.       得到屬性數(shù)據(jù)后,我們就調(diào)用DrawIndexedPrimitive方法可以精美地渲染子集了。

 

       下面是繪制Mesh模型的程序代碼:

       Load_Meshes()函數(shù)的最后,我們使用OptimizeInPlace方法對源網(wǎng)格模型和目標(biāo)網(wǎng)格模型進(jìn)行優(yōu)化,其他加載材質(zhì)和紋理的操作和之前一樣,相信大家能夠理解:

      

       //優(yōu)化源網(wǎng)格模型

       g_SourceMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL);

      

       //優(yōu)化目標(biāo)網(wǎng)格模型

g_TargetMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL);

      

 

       Draw_Mesh()函數(shù)中,渲染模型,注意程序是如何配合屬性表調(diào)用DrawIndexedPrimitive方法進(jìn)行繪制的:

      

      

       //分別得到指向Mesh模型頂點緩存區(qū)和索引緩存區(qū)的指針

       IDirect3DVertexBuffer9 *pVB = NULL;

       IDirect3DIndexBuffer9 *pIB = NULL;

       pMesh->GetVertexBuffer(&pVB);

       pMesh->GetIndexBuffer(&pIB);

 

       //得到Mesh模型的屬性列表

       DWORD NumAttributes;

       D3DXATTRIBUTERANGE *pAttributes = NULL;

       pMesh->GetAttributeTable(NULL, &NumAttributes);

       pAttributes = new D3DXATTRIBUTERANGE[NumAttributes];

       pMesh->GetAttributeTable(pAttributes, &NumAttributes);

 

       //設(shè)置頂點著色器和頂點聲明

       g_pd3dDevice->SetVertexShader(pShader);

       g_pd3dDevice->SetVertexDeclaration(pDecl);

 

       //設(shè)置數(shù)據(jù)流

       g_pd3dDevice->SetStreamSource(0, pVB, 0, D3DXGetFVFVertexSize(pMesh->GetFVF()));

       g_pd3dDevice->SetIndices(pIB);

 

       //遍歷屬性列表并配合其中的信息調(diào)用DrawIndexPrimitive繪制各個子集

       for(DWORD i=0;i<NumAttributes;i++)

       {

              if(pAttributes[i].FaceCount)

              {

                     //Get material number

                     DWORD MatNum = pAttributes[i].AttribId;

 

                     //Set texture

                     g_pd3dDevice->SetTexture(0, pTextures[MatNum]);

 

                     //Draw the mesh subset

                     g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,

                                                                              pAttributes[i].VertexStart,

                                                                              pAttributes[i].VertexCount,

                                                                              pAttributes[i].FaceStart * 3,

                                                                              pAttributes[i].FaceCount);

              }

       }

      

       //Free resources

       ReleaseCOM(pVB);

       ReleaseCOM(pIB);

       delete [] pAttributes;

 

      

 

       編譯運行程序,效果如圖2.4所示,你將看到屏幕上白色的海豚上下翻騰,同時感受到頂點著色器為渲染效果所帶來的巨大改善。

2.4

posted on 2008-08-04 12:30 狂爛球 閱讀(880) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   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>
            欧美 亚欧 日韩视频在线| 亚洲国产午夜| 亚洲一区二区三区三| 亚洲一区网站| 亚洲国内自拍| 亚洲午夜免费视频| 国产在线精品自拍| 亚洲国产小视频| 国产精品www| 久久亚洲精品一区| 欧美日韩免费网站| 久久免费视频观看| 欧美日韩国产一中文字不卡| 久久激情久久| 欧美日韩综合视频网址| 老司机久久99久久精品播放免费 | 欧美日韩一区二区在线| 久久精品av麻豆的观看方式 | 免费观看成人鲁鲁鲁鲁鲁视频 | 久久青草福利网站| 欧美网站在线| 亚洲第一精品在线| 精品999成人| 亚洲欧美日韩精品久久亚洲区| 在线看欧美日韩| 性视频1819p久久| 亚洲一区二区精品视频| 免费久久99精品国产| 久久精品一区二区三区中文字幕| 欧美日韩高清区| 欧美激情久久久久| 在线成人激情| 久久成人精品| 久久久精品一区| 国产视频精品xxxx| 亚洲综合视频一区| 亚洲你懂的在线视频| 欧美日韩免费高清| 亚洲精品日韩综合观看成人91| 亚洲国产精品久久久久秋霞影院| 欧美在线视频免费观看| 午夜精品免费视频| 国产精品成人播放| 亚洲精品日韩激情在线电影| 久久久久www| 欧美成人按摩| 免费av成人在线| 黄色欧美成人| 久久久久在线观看| 美腿丝袜亚洲色图| ●精品国产综合乱码久久久久| 欧美在线你懂的| 久久亚洲国产精品一区二区| 国内揄拍国内精品久久| 久久gogo国模啪啪人体图| 欧美综合二区| 国模精品一区二区三区| 欧美一区激情| 麻豆精品视频在线| 亚洲国产精品悠悠久久琪琪| 免费成人高清| 亚洲人成久久| 亚洲校园激情| 国产精品视频一区二区高潮| 亚洲欧美日韩久久精品| 久久久夜精品| 亚洲黄一区二区三区| 欧美精品日韩| 亚洲午夜在线| 久久婷婷av| 日韩午夜激情电影| 国产精品久久久一区二区| 欧美亚洲自偷自偷| 欧美mv日韩mv亚洲| 中国成人黄色视屏| 国产欧美日本| 久久人人97超碰精品888| 亚洲国产成人av在线| 亚洲午夜国产一区99re久久| 国产精品丝袜白浆摸在线| 久久精品av麻豆的观看方式| 亚洲国产日韩欧美综合久久| 亚洲一区999| 有坂深雪在线一区| 欧美日韩三区| 欧美在线高清| 亚洲欧洲综合| 久久精品午夜| av72成人在线| 国内精品视频久久| 欧美日韩一区成人| 久久久久九九视频| 一本色道久久88综合亚洲精品ⅰ| 久久九九99视频| 一区二区欧美在线观看| 国产综合视频在线观看| 欧美精品播放| 久久精品九九| 亚洲视频大全| 亚洲第一主播视频| 久久激情视频免费观看| 一本色道88久久加勒比精品| 国产在线观看一区| 欧美色视频在线| 免费精品99久久国产综合精品| 亚洲影音一区| 亚洲精品乱码久久久久久黑人| 久久久亚洲成人| 亚洲欧美国产三级| 亚洲免费电影在线观看| 韩国三级在线一区| 国产精品日本欧美一区二区三区| 久久尤物视频| 久久成人精品无人区| 亚洲天堂av在线免费观看| 欧美高清视频一区二区三区在线观看 | 国产一区二区在线观看免费播放| 裸体一区二区三区| 亚洲女优在线| 99精品欧美一区二区三区综合在线| 久久久亚洲午夜电影| 亚洲综合首页| 一本色道久久99精品综合| 尤物yw午夜国产精品视频| 国产欧美亚洲视频| 国产精品久久久久毛片大屁完整版 | 国产精品日韩久久久久| 欧美精品在线观看播放| 美女亚洲精品| 久久亚洲影院| 久久久久久久精| 欧美一区日韩一区| 亚洲欧美日韩一区二区三区在线观看| 亚洲精品综合精品自拍| 亚洲国产精品久久久久婷婷884| 葵司免费一区二区三区四区五区| 欧美一区二区三区电影在线观看| 亚洲一区二区三区乱码aⅴ| 亚洲无线视频| 亚洲欧美日韩精品一区二区| 亚洲免费视频成人| 欧美一级免费视频| 久久国产黑丝| 久久久久久一区二区三区| 久久精品欧洲| 麻豆91精品| 欧美顶级少妇做爰| 亚洲福利视频网站| 亚洲人屁股眼子交8| 99在线|亚洲一区二区| 在线视频精品一区| 亚洲欧美国产77777| 午夜视频在线观看一区二区| 久久国产黑丝| 久久只有精品| 欧美人交a欧美精品| 国产精品高潮在线| 国产一区二区黄色| 在线观看欧美视频| 亚洲欧洲日韩综合二区| 99亚洲精品| 亚洲欧美久久久久一区二区三区| 午夜精品久久久久久| 久久久久久尹人网香蕉| 欧美成人一区在线| 亚洲美女精品久久| 亚洲欧美日韩在线观看a三区| 欧美伊久线香蕉线新在线| 久久夜精品va视频免费观看| 欧美日韩p片| 国产欧美丝祙| 91久久精品美女| 亚洲欧美日韩在线不卡| 久久综合五月| 99精品国产高清一区二区| 午夜性色一区二区三区免费视频| 久久久亚洲国产美女国产盗摄| 欧美成人亚洲| 国产精品久久久久久久第一福利| 国产一区在线视频| 日韩视频三区| 久久成人资源| 91久久视频| 欧美一区综合| 欧美日韩色一区| 一区二区在线视频播放| 夜色激情一区二区| 久久蜜桃精品| 一区二区日韩欧美| 麻豆精品精华液| 国产精品自拍视频| 亚洲久久视频| 久久蜜桃精品| 欧美日韩视频在线观看一区二区三区| 国产精品大片免费观看| 在线看不卡av| 久久不射2019中文字幕| 亚洲国产婷婷香蕉久久久久久| 欧美一级专区免费大片| 欧美日韩精品不卡|