![Visual-C++游戲開(kāi)發(fā)筆記全集_第1頁(yè)](http://file4.renrendoc.com/view/1d3d0151d34db2912a906571bcfc9039/1d3d0151d34db2912a906571bcfc90391.gif)
![Visual-C++游戲開(kāi)發(fā)筆記全集_第2頁(yè)](http://file4.renrendoc.com/view/1d3d0151d34db2912a906571bcfc9039/1d3d0151d34db2912a906571bcfc90392.gif)
![Visual-C++游戲開(kāi)發(fā)筆記全集_第3頁(yè)](http://file4.renrendoc.com/view/1d3d0151d34db2912a906571bcfc9039/1d3d0151d34db2912a906571bcfc90393.gif)
![Visual-C++游戲開(kāi)發(fā)筆記全集_第4頁(yè)](http://file4.renrendoc.com/view/1d3d0151d34db2912a906571bcfc9039/1d3d0151d34db2912a906571bcfc90394.gif)
![Visual-C++游戲開(kāi)發(fā)筆記全集_第5頁(yè)](http://file4.renrendoc.com/view/1d3d0151d34db2912a906571bcfc9039/1d3d0151d34db2912a906571bcfc90395.gif)
版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【VisualC++】游戲開(kāi)發(fā)筆記三十DirectX112D紋理映射知識(shí)全攻略【VisualC++】游戲開(kāi)發(fā)筆記二十九一步一步教你用優(yōu)雅的Direct3D11代碼畫(huà)一個(gè)三角形【VisualC++】游戲開(kāi)發(fā)筆記二十八最精簡(jiǎn)的Direct3D11Demo筋骨脈絡(luò)全攻略【VisualC++】游戲開(kāi)發(fā)筆記二十七Direct3D11入門(mén)級(jí)知識(shí)介紹【VisualC++】游戲開(kāi)發(fā)筆記二十六DirectX11各組件的介紹&第一個(gè)DirectX11Demo的創(chuàng)建【VisualC++】游戲開(kāi)發(fā)筆記二十五最簡(jiǎn)化的DirectX11開(kāi)發(fā)環(huán)境的配【VisualC++】游戲開(kāi)發(fā)筆記二十四由DirectX的幾個(gè)版本說(shuō)【VisualC++】游戲開(kāi)發(fā)筆記二十三游戲基礎(chǔ)物理建模(五)粒子系統(tǒng)模擬(二)【VisualC++】游戲開(kāi)發(fā)筆記二十二游戲基礎(chǔ)物理建模(四)粒子系統(tǒng)模擬(一)【VisualC++】游戲開(kāi)發(fā)筆記二十一游戲基礎(chǔ)物理建模(三)摩擦力系統(tǒng)模擬【VisualC++】游戲開(kāi)發(fā)筆記二十游戲基礎(chǔ)物理建模(二)重力系統(tǒng)的模擬【VisualC++】游戲開(kāi)發(fā)筆記十八游戲基礎(chǔ)物理建模(一)勻速與加速運(yùn)動(dòng)?!綱isualC++】游戲開(kāi)發(fā)筆記十九DirectX與OpenGL的博弈【VisualC++】游戲開(kāi)發(fā)筆記十七游戲基礎(chǔ)算法(一)游戲隨機(jī)系統(tǒng)初步【VisualC++】游戲開(kāi)發(fā)筆記十八游戲基礎(chǔ)物理建模(一)勻速與加速運(yùn)動(dòng)?!綱isualC++】游戲開(kāi)發(fā)筆記十六講解一個(gè)完整的回合制游戲demo【VisualC++】游戲開(kāi)發(fā)筆記十五游戲人工智能(一)運(yùn)動(dòng)型游戲AI【VisualC++】游戲開(kāi)發(fā)筆記十二游戲輸入消息處理(一)鍵盤(pán)消息處理【VisualC++】游戲開(kāi)發(fā)筆記十四游戲畫(huà)面繪圖(四)華麗的CImage類(lèi)【VisualC++】游戲開(kāi)發(fā)筆記十三游戲輸入消息處理(二)鼠標(biāo)消息處理【VisualC++】游戲開(kāi)發(fā)筆記十二游戲輸入消息處理(一)鍵盤(pán)消息處理【VisualC++】游戲開(kāi)發(fā)筆記之十一基礎(chǔ)動(dòng)畫(huà)顯示(四)排序貼圖【VisualC++】游戲開(kāi)發(fā)筆記之十基礎(chǔ)動(dòng)畫(huà)顯示(三)透明動(dòng)畫(huà)的實(shí)現(xiàn)【VisualC++】游戲開(kāi)發(fā)筆記之九游戲地圖制作(一)平面地圖貼圖【VisualC++】游戲開(kāi)發(fā)筆記之八——基礎(chǔ)動(dòng)畫(huà)顯示(二)游戲循環(huán)的使用【VisualC++】游戲開(kāi)發(fā)筆記之七——基礎(chǔ)動(dòng)畫(huà)顯示(一)定時(shí)器的使用【VisualC++】游戲開(kāi)發(fā)筆記之六——游戲畫(huà)面繪圖(三)透明特效的制作方法【VisualC++】游戲開(kāi)發(fā)筆記之四——游戲畫(huà)面繪圖(一)基本圖形繪制【VisualC++】游戲開(kāi)發(fā)筆記之五——游戲畫(huà)面繪圖(二)繪制位圖【VisualC++】游戲開(kāi)發(fā)筆記之一——API函數(shù)、DirectX的關(guān)鍵系【VisualC++】游戲開(kāi)發(fā)筆記之二——最簡(jiǎn)單的DirectX,vc窗口的編寫(xiě)【VisualC++】游戲開(kāi)發(fā)筆記之三——繪制圖元【VisualC++】游戲開(kāi)發(fā)筆記三十DirectX112D紋理映射知識(shí)全攻略本系列文章由zhmxy555(毛星云)編寫(xiě),轉(zhuǎn)載請(qǐng)注明出處。/zhmxy555/article/details/78017229作者:毛星云
郵箱:happylifemxy@
本節(jié)知識(shí)先是對(duì)DirectX11關(guān)于2D紋理映射方面基礎(chǔ)知識(shí)的一個(gè)講解,然后通過(guò)一個(gè)demo的創(chuàng)建過(guò)程來(lái)將學(xué)到的理論知識(shí)付諸實(shí)踐。
一、引言
在之前我們提到過(guò),紋理實(shí)際上就是映射到物體表面的數(shù)據(jù)。其實(shí),紋理也可能是其他的一些信息片段,比如用于映射的常規(guī)映射值,用于控制透明度的alpha值,等等。通常情況下,紋理是通過(guò)一個(gè)叫做紋理映射的過(guò)程來(lái)映射一幅圖像到表面上的顏色值,這種功能能顯著地增加所繪制場(chǎng)景的細(xì)膩感和真實(shí)感。紋理和游戲開(kāi)發(fā)中需要的其他數(shù)據(jù)一樣,通常都是在運(yùn)行時(shí)加載的。由于紋理是Direct3D重要的組成的部分,微軟為我們提供了眾多功能強(qiáng)大而豐富的Direct3D內(nèi)建的函數(shù),來(lái)處理紋理相關(guān)的操作。
二、基礎(chǔ)知識(shí)講解
1.紋理的加載
在Direct3D11中,我們通常使用D3DX11CreateTextureFromFile函數(shù)用于從硬盤(pán)文件中加載紋理。這個(gè)函數(shù)支持非常豐富的圖像格式,比如BMP,PNG,以及DDS。D3DX11CreateTextureFromFile函數(shù)擁有六個(gè)變量,具有以下的函數(shù)原型:
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?HRESULT
D3DX11CreateTextureFromFile(
ID3D11Device*
pDevice,
LPCTSTR
pSrcFile,
D3DX11_IMAGE_LOAD_INFO*
pLoadInfo,
ID3DX11ThreadPump*
pPump,
ID3D11Resource**
ppTexture,
HRESULT*
pHResult
);
D3DX11CreateTextureFromFile函數(shù)的第一個(gè)的參數(shù)為ID3D11Device類(lèi)型的指針變量。第二個(gè)參數(shù)pSrcFile為被加載文件的文件路徑和文件名。第三個(gè)參數(shù)pLoadInfo為一個(gè)圖形信息結(jié)構(gòu)體。它為一個(gè)可選的參數(shù),并允許我們通過(guò)指定CPU訪問(wèn)的標(biāo)識(shí)、內(nèi)部格式、寬度和高度來(lái)控制圖像紋理的加載方式。第四個(gè)參數(shù)pPump用于多線程加載紋理時(shí)的異步處理。第五個(gè)參數(shù)ppTexture用是紋理對(duì)象被調(diào)用時(shí)這個(gè)函數(shù)創(chuàng)建出的地址。如果D3DX11CreateTextureFromFile函數(shù)調(diào)用成功,這個(gè)變量就會(huì)擁有一個(gè)現(xiàn)成的紋理供使用。最后一個(gè)參數(shù)pHResult是指向線程返回值的指針。
若此線程的參數(shù)不為空,pHResult必須為一個(gè)有效的內(nèi)存地址。在Direct3D中我們能夠使用很多函數(shù)載入各種琳瑯滿目的圖像文件格式,下面我們對(duì)他們進(jìn)行一個(gè)詳細(xì)的列舉:
WindowsBitmap(BMP)JointPhotographicExpertGroup—i.e.,JPEG(JPG)PortableNetworkGraphics(PNG)TaggedImageFormat(TIFF)GraphicsInterchangeFormat(GIF)DirectDrawSurface(DDS)WindowsMediaPlayer(WMP)
2.紋理接口
紋理接口通常用于管理一個(gè)特定類(lèi)型的圖像數(shù)據(jù)。目前Direct3D紋理接口主要有三種類(lèi)型,他們分別是:ID3D11Texture1D——用于1D或者條形的紋理ID3D11Texture2D——用于2D數(shù)據(jù),這也是最常用的紋理資源類(lèi)型、ID3D11Texture3D——用于表示3D數(shù)據(jù)的紋理資源類(lèi)型上述3種紋理資源類(lèi)型都包含一個(gè)或者多個(gè)子資源。而游戲開(kāi)發(fā)中使用的大多數(shù)紋理類(lèi)型基本上都為二維的,他們都需要轉(zhuǎn)化為ID3D11Texture2D型資源后再使用。而這些子資源代表了紋理中不同的
MIP等級(jí)。譬如Adobe’sPhotoshop這類(lèi)的圖像編輯器是創(chuàng)造2D紋理的最得力幫手。
3.紋理細(xì)節(jié)
在游戲開(kāi)發(fā)的過(guò)程中,常常我們需要從加載的紋理中得到一些特定的信息,比如說(shuō)維度或者像素格式。這時(shí)候隸屬于ID3D11Texture2D中的GetDesc函數(shù)就可以派上用場(chǎng)了。這個(gè)函數(shù)的功能是為我們填充D3D11_TEXTURE2D_DESC結(jié)構(gòu)體中的各種細(xì)節(jié),從而通過(guò)這個(gè)結(jié)構(gòu)體作為載體,有關(guān)的各類(lèi)數(shù)據(jù)就一目了然了。
D3D11_TEXTURE2D_DESC是專(zhuān)用于2D紋理的紋理描述結(jié)構(gòu)體家族中的一員。對(duì)于其他的兩個(gè)維度,Direct3D11為我們準(zhǔn)備了D3D11_TEXTURE1D_DESC用于1D紋理,D3D11_TEXTURE3D_DESC用于3D紋理。
作為最常見(jiàn)的紋理,二維的D3D11_TEXTURE2D_DESC聲明形式如下:
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?typedef
struct
D3D11_TEXTURE2D_DESC
{
UINT
Width;
UINT
Height;
UINT
MipLevels;
UINT
ArraySize;
DXGI_FORMAT
Format;
DXGI_SAMPLE_DESC
SampleDesc;
D3D11_USAGE
Usage;
UINT
BindFlags;
UINT
CPUAccessFlags;
UINT
MiscFlags;
}
D3D11_TEXTURE2D_DESC;
三、DirectX112D紋理映射demo的創(chuàng)建
這里,我們先介紹一下這個(gè)demo的組成結(jié)構(gòu):如圖,頭文件有Dx11DemoBase.h以及Texture2DDemo.h源文件有Dx11DemoBase.cpp,Texture2DDemo.h以及main.cpp
在之前的TriangleDemo的基礎(chǔ)上,我們?cè)偬砑右粋€(gè)叫做TextureDemo的類(lèi),以及添加一個(gè)叫做colorMap_的D3D11ShaderResourceView類(lèi)型的著色器資源視圖和一個(gè)D3D11SamplerState類(lèi)型的喚做colorMapSampler_的采樣狀態(tài)。著色資源視圖簡(jiǎn)單的來(lái)說(shuō)是一個(gè)用于訪問(wèn)資源的對(duì)象。當(dāng)我們加載紋理到內(nèi)存中的時(shí)候,必須創(chuàng)建一個(gè)著色器資源視圖來(lái)通過(guò)著色器獲取數(shù)據(jù),而這些數(shù)據(jù)會(huì)被綁定到輸出程序集當(dāng)中。著色器資源視圖也有其他的作用,比如為DirectCompute提供異步運(yùn)算時(shí)需要的數(shù)據(jù),本節(jié)我們主要是介紹其在紋理方面的運(yùn)用。ID3D11Texture2D代表數(shù)據(jù)的緩存,而著色器資源視圖允許我們?cè)谥髦胁榭催@個(gè)緩存的各項(xiàng)數(shù)據(jù)。采樣器聲明(samplerstate)允許我們?cè)L問(wèn)的紋理采樣的狀態(tài)信息。后面將對(duì)其做更多更詳細(xì)的講解。TextureDemo類(lèi)的頭文件代碼書(shū)寫(xiě)風(fēng)格如下:
代碼段一
TextureDemo.h對(duì)TextureDemo類(lèi)的輪廓書(shū)寫(xiě)
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?#ifndef
_TEXTURE_2D_DEMO_H_
#define
_TEXTURE_2D_DEMO_H_
#include"Dx11DemoBase.h"
class
TextureDemo
:
public
Dx11DemoBase
{
public:
TextureDemo(
);
virtual
~TextureDemo(
);
bool
LoadContent(
);
void
UnloadContent(
);
void
Update(
float
dt
);
void
Render(
);
private:
ID3D11VertexShader*
solidColorVS_;
ID3D11PixelShader*
solidColorPS_;
ID3D11InputLayout*
inputLayout_;
ID3D11Buffer*
vertexBuffer_;
ID3D11ShaderResourceView*
colorMap_;
ID3D11SamplerState*
colorMapSampler_;
};
#endif
由于我們正在執(zhí)行紋理映射這項(xiàng)操作,我們需要對(duì)頂點(diǎn)結(jié)構(gòu)體的代碼進(jìn)行更新,使其包含兩個(gè)浮點(diǎn)型的變量。這項(xiàng)工作可由XMFLOAT2結(jié)構(gòu)體來(lái)完成。
代碼段二中展示了這個(gè)demo中頂點(diǎn)結(jié)構(gòu)體,LoadContent,函數(shù)和UnloadContent函數(shù)的寫(xiě)法
代碼段二
頂點(diǎn)結(jié)構(gòu)體以及LoadContent和UnloadContent的書(shū)寫(xiě)
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?struct
VertexPos
{
XMFLOAT3
pos;
XMFLOAT2
tex0;
};
bool
TextureDemo::LoadContent(
)
{
...
Load
vertex
Shader
...
D3D11_INPUT_ELEMENT_DESC
solidColorLayout[]
=
{
{
"POSITION",
0,
DXGI_FORMAT_R32G32B32_FLOAT,
0,
0,
D3D11_INPUT_PER_VERTEX_DATA,
0
},
{
"TEXCOORD",
0,
DXGI_FORMAT_R32G32_FLOAT,
0,
12,
D3D11_INPUT_PER_VERTEX_DATA,
0
}
};
unsigned
int
totalLayoutElements
=
ARRAYSIZE(
solidColorLayout
);
d3dResult
=
d3dDevice_->CreateInputLayout(
solidColorLayout,
totalLayoutElements,
vsBuffer->GetBufferPointer(
),
vsBuffer->GetBufferSize(
),
&inputLayout_
);
...
Load
Pixel
Shader
...
VertexPos
vertices[]
=
{
{
XMFLOAT3(
1.0f,
1.0f,
1.0f
),
XMFLOAT2(
1.0f,
1.0f
)
},
{
XMFLOAT3(
1.0f,
-1.0f,
1.0f
),
XMFLOAT2(
1.0f,
0.0f
)
},
{
XMFLOAT3(
-1.0f,
-1.0f,
1.0f
),
XMFLOAT2(
0.0f,
0.0f
)
},
{
XMFLOAT3(
-1.0f,
-1.0f,
1.0f
),
XMFLOAT2(
0.0f,
0.0f
)
},
{
XMFLOAT3(
-1.0f,
1.0f,
1.0f
),
XMFLOAT2(
0.0f,
1.0f
)
},
{
XMFLOAT3(
1.0f,
1.0f,
1.0f
),
XMFLOAT2(
1.0f,
1.0f
)
},
};
...
Create
Vertex
Buffer
...
d3dResult
=
D3DX11CreateShaderResourceViewFromFile(
d3dDevice_,
"decal.dds",
0,
0,
&colorMap_,
0
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"Failed
to
load
the
texture
image!"
);
return
false;
}
D3D11_SAMPLER_DESC
colorMapDesc;
ZeroMemory(
&colorMapDesc,
sizeof(
colorMapDesc
)
);
colorMapDesc.AddressU
=
D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressV
=
D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressW
=
D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.ComparisonFunc
=
D3D11_COMPARISON_NEVER;
colorMapDesc.Filter
=
D3D11_FILTER_MIN_MAG_MIP_LINEAR;
colorMapDesc.MaxLOD
=
D3D11_FLOAT32_MAX;
d3dResult
=
d3dDevice_->CreateSamplerState(
&colorMapDesc,
&colorMapSampler_
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"Failed
to
create
color
map
sampler
state!"
);
return
false;
}
return
true;
}
void
TextureDemo::UnloadContent(
)
{
if(
colorMapSampler_
)
colorMapSampler_->Release(
);
if(
colorMap_
)
colorMap_->Release(
);
if(
solidColorVS_
)
solidColorVS_->Release(
);
if(
solidColorPS_
)
solidColorPS_->Release(
);
if(
inputLayout_
)
inputLayout_->Release(
);
if(
vertexBuffer_
)
vertexBuffer_->Release(
);
colorMapSampler_
=
0;
colorMap_
=
0;
solidColorVS_
=
0;
solidColorPS_
=
0;
inputLayout_
=
0;
vertexBuffer_
=
0;
}
UnloadContent函數(shù)釋放了新對(duì)象,而LoadContent函數(shù)進(jìn)行了紋理圖像的加載。我們可以使用Direct3D中的D3DX11CreateShaderResourceViewFromFile函數(shù)(這個(gè)函數(shù)名是不是略長(zhǎng)啊,哈哈),來(lái)加載一個(gè)紋理然后在一個(gè)簡(jiǎn)單的調(diào)用之中創(chuàng)建著色器資源視圖。這個(gè)函數(shù)在我們想畢其功于一役的時(shí)候,即希望加載一個(gè)紋理連著創(chuàng)建一個(gè)新的著色器資源視圖一步到位的時(shí)候,非常的好用。D3DX11CreateShaderResourceViewFromFile函數(shù)的變量和D3DX11CreateTextureFromFile函數(shù)的相似度很高,這員大將有以下原型:
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?HRESULT
D3DX11CreateShaderResourceViewFromFile(
ID3D11Device*
pDevice,
LPCTSTR
pSrcFile,
D3DX11_IMAGE_LOAD_INFO*
pLoadInfo,
ID3DX11ThreadPump*
pPump,
ID3D11ShaderResourceView**
ppShaderResourceView,
HRESULT*
pHResult
);
LoadContent函數(shù)代碼的最后一段完成的功能是采樣器聲明(samplerstate)的創(chuàng)建。為了創(chuàng)建一個(gè)采樣器聲明(samplerstate)的對(duì)象,很容易就可以通過(guò)功能聯(lián)想到函數(shù)名——CreateSamplerState。這個(gè)函數(shù)以采樣器描述作為其一個(gè)參數(shù)。而采樣器描述擁有以下的聲明:
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?typedef
struct
D3D11_SAMPLER_DESC
{
D3D11_FILTER
Filter;
D3D11_TEXTURE_ADDRESS_MODE
AddressU;
D3D11_TEXTURE_ADDRESS_MODE
AddressV;
D3D11_TEXTURE_ADDRESS_MODE
AddressW;
FLOAT
MipLODBias;
UINT
MaxAnisotropy;
D3D11_COMPARISON_FUNC
ComparisonFunc;
FLOAT
BorderColor[4];
FLOAT
MinLOD;
FLOAT
MaxLOD;
}
D3D11_SAMPLER_DESC;
為了渲染我們的幾何紋理,我們必須添加紋理資源以及設(shè)置采樣器描述。這兩項(xiàng)特殊的任務(wù)分別分配給PSSetShaderResources函數(shù)以及PSSetSamplers函數(shù)來(lái)完成,設(shè)置這些數(shù)據(jù)到像素著色器之中。PSSetShaderResources函數(shù)具有以下原型:
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?void
PSSetShaderResources(
UINT
StartSlot,
UINT
NumViews,
ID3D11ShaderResourceView*
const*
ppShaderResourceViews
);
PSSetSamplers函數(shù)也以起始點(diǎn)StartSlot以及采樣數(shù)量NumViews作為其參數(shù)。我們?cè)谥癲emo里面關(guān)于Render的代碼隨著這節(jié)里面對(duì)這兩個(gè)函數(shù)的加入,我們就可以看到更加出色的效果了。目前需要做的就是就修改著色器的渲染效果了。TextureMappingdemo類(lèi)的Render函數(shù)如下代碼段X
代碼段三
TextureDemo
類(lèi)的render函數(shù)的書(shū)寫(xiě)
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?void
TextureDemo::Render(
)
{
if(
d3dContext_
==
0
)
return;
float
clearColor[4]
=
{
0.0f,
0.0f,
0.25f,
1.0f
};
d3dContext_->ClearRenderTargetView(
backBufferTarget_,
clearColor
);
unsigned
int
stride
=
sizeof(
VertexPos
);
unsigned
int
offset
=
0;
d3dContext_->IASetInputLayout(
inputLayout_
);
d3dContext_->IASetVertexBuffers(
0,
1,
&vertexBuffer_,
&stride,
&offset
);
d3dContext_->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_
TRIANGLELIST
);
d3dContext_->VSSetShader(
colorMapVS_,
0,
0
);
d3dContext_->PSSetShader(
colorMapPS_,
0,
0
);
d3dContext_->PSSetShaderResources(
0,
1,
&colorMap_
);
d3dContext_->PSSetSamplers(
0,
1,
&colorMapSampler_
);
d3dContext_->Draw(
6,
0
);
swapChain_->Present(
0,
0
);
}
在著色器之中,如代碼段四,我們擁有兩個(gè)新的全局著色器對(duì)象,分別喚作colorMap_和colorSampler_。其中colorSampler_對(duì)象的類(lèi)型為T(mén)exture2D,它可以用于2D紋理之中,而colorSampler_為HLSL(HighLevelShaderLanguage高級(jí)著色器語(yǔ)言)類(lèi)型的采樣器聲明。
為了將這些對(duì)象綁定到我們?cè)赗ender函數(shù)中提供的著色器當(dāng)中,我們需要使用中HLSL(HighLevelShaderLanguage高級(jí)著色器語(yǔ)言)中的register關(guān)鍵字。綁定第一個(gè)紋理輸出我們采用t0來(lái)表示,其中t代表texture這個(gè)單詞,0代表數(shù)量的索引,即第幾個(gè)。同理,對(duì)于采樣器聲明,s代表samplerstate這個(gè)詞組,0代表第幾個(gè),則s0就代表第一個(gè)采樣器。因?yàn)槲覀冎挥幸环N紋理和一種采樣器聲明,所以只需t0和s0即可。著色器當(dāng)中的另一個(gè)需要注意的地方是,我們必須更新頂點(diǎn)著色器以及像素著色器的輸入結(jié)構(gòu)來(lái)方便地獲取紋理坐標(biāo)。頂點(diǎn)著色器將從頂點(diǎn)緩存中取得紋理坐標(biāo),然后將其傳遞給像素著色器,以便像素著色器方便地訪問(wèn)這些數(shù)據(jù)。之后,像素著色器會(huì)使用這些紋理坐標(biāo)和紋理對(duì)象來(lái)讀取顏色值。這一步可以調(diào)用HLSLTexture2D對(duì)象的Sample函數(shù)來(lái)完成。最后提一點(diǎn),由于我們是從一個(gè)2D紋理中讀取數(shù)據(jù)的,則紋理坐標(biāo)需為float2類(lèi)型。
在這里列出著色器的構(gòu)成代碼:
代碼段四
紋理映射demo中著色器的構(gòu)成代碼
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?Texture2D
colorMap_
:
register(
t0
);
SamplerState
colorSampler_
:
register(
s0
);
struct
VS_Input
{
float4
pos
:
POSITION;
float2
tex0
:
TEXCOORD0;
};
struct
PS_Input
{
float4
pos
:
SV_POSITION;
float2
tex0
:
TEXCOORD0;
};
PS_Input
VS_Main(
VS_Input
vertex
)
{
PS_Input
vsOut
=
(
PS_Input
)0;
vsOut.pos
=
vertex.pos;
vsOut.tex0
=
vertex.tex0;
return
vsOut;
}
float4
PS_Main(
PS_Input
frag
)
:
SV_TARGET
{
return
colorMap_.Sample(
colorSampler_,
frag.tex0
);
}
到這一步,核心的代碼都書(shū)寫(xiě)完畢了,為了觀看的方便,淺墨在這里將最重頭的Texture2DDemo.cpp貼出來(lái)(Texture2DDemo.h見(jiàn)代碼段一):
代碼段五Texture2DDemo.cpp實(shí)現(xiàn)代碼
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?#include"Texture2DDemo.h"
#include<xnamath.h>
struct
VertexPos
//結(jié)構(gòu)體
{
XMFLOAT3
pos;
XMFLOAT2
tex0;
};
TextureDemo::TextureDemo(
)
:
solidColorVS_(
0
),
solidColorPS_(
0
),
//構(gòu)造函數(shù)
inputLayout_(
0
),
vertexBuffer_(
0
),
colorMap_(
0
),
colorMapSampler_(
0
)
{
}
TextureDemo::~TextureDemo(
)
{
}
bool
TextureDemo::LoadContent(
)
{
ID3DBlob*
vsBuffer
=
0;
bool
compileResult
=
CompileD3DShader(
"TextureMap.fx",
"VS_Main",
"vs_4_0",
&vsBuffer
);
if(
compileResult
==
false
)
{
DXTRACE_MSG(
"編譯頂點(diǎn)著色器失敗!"
);
return
false;
}
HRESULT
d3dResult;
d3dResult
=
d3dDevice_->CreateVertexShader(
vsBuffer->GetBufferPointer(
),
vsBuffer->GetBufferSize(
),
0,
&solidColorVS_
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"創(chuàng)建頂點(diǎn)著色器失敗!"
);
if(
vsBuffer
)
vsBuffer->Release(
);
return
false;
}
D3D11_INPUT_ELEMENT_DESC
solidColorLayout[]
=
{
{
"POSITION",
0,
DXGI_FORMAT_R32G32B32_FLOAT,
0,
0,
D3D11_INPUT_PER_VERTEX_DATA,
0
},
{
"TEXCOORD",
0,
DXGI_FORMAT_R32G32_FLOAT,
0,
12,
D3D11_INPUT_PER_VERTEX_DATA,
0
}
};
unsigned
int
totalLayoutElements
=
ARRAYSIZE(
solidColorLayout
);
d3dResult
=
d3dDevice_->CreateInputLayout(
solidColorLayout,
totalLayoutElements,
vsBuffer->GetBufferPointer(
),
vsBuffer->GetBufferSize(
),
&inputLayout_
);
vsBuffer->Release(
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"創(chuàng)建輸入布局失敗!"
);
return
false;
}
ID3DBlob*
psBuffer
=
0;
compileResult
=
CompileD3DShader(
"TextureMap.fx",
"PS_Main",
"ps_4_0",
&psBuffer
);
if(
compileResult
==
false
)
{
DXTRACE_MSG(
"像素著色器編譯失敗!"
);
return
false;
}
d3dResult
=
d3dDevice_->CreatePixelShader(
psBuffer->GetBufferPointer(
),
psBuffer->GetBufferSize(
),
0,
&solidColorPS_
);
psBuffer->Release(
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"創(chuàng)建像素著色器失敗!"
);
return
false;
}
VertexPos
vertices[]
=
{
{
XMFLOAT3(
1.0f,
1.0f,
1.0f
),
XMFLOAT2(
1.0f,
1.0f
)
},
{
XMFLOAT3(
1.0f,
-1.0f,
1.0f
),
XMFLOAT2(
1.0f,
0.0f
)
},
{
XMFLOAT3(
-1.0f,
-1.0f,
1.0f
),
XMFLOAT2(
0.0f,
0.0f
)
},
{
XMFLOAT3(
-1.0f,
-1.0f,
1.0f
),
XMFLOAT2(
0.0f,
0.0f
)
},
{
XMFLOAT3(
-1.0f,
1.0f,
1.0f
),
XMFLOAT2(
0.0f,
1.0f
)
},
{
XMFLOAT3(
1.0f,
1.0f,
1.0f
),
XMFLOAT2(
1.0f,
1.0f
)
},
};
D3D11_BUFFER_DESC
vertexDesc;
ZeroMemory(
&vertexDesc,
sizeof(
vertexDesc
)
);
vertexDesc.Usage
=
D3D11_USAGE_DEFAULT;
vertexDesc.BindFlags
=
D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth
=
sizeof(
VertexPos
)
*
6;
D3D11_SUBRESOURCE_DATA
resourceData;
ZeroMemory(
&resourceData,
sizeof(
resourceData
)
);
resourceData.pSysMem
=
vertices;
d3dResult
=
d3dDevice_->CreateBuffer(
&vertexDesc,
&resourceData,
&vertexBuffer_
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"創(chuàng)建頂點(diǎn)緩存失敗!"
);
return
false;
}
d3dResult
=
D3DX11CreateShaderResourceViewFromFile(
d3dDevice_,
"decal.dds",
0,
0,
&colorMap_,
0
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"讀取紋理圖像失敗!"
);
return
false;
}
D3D11_SAMPLER_DESC
colorMapDesc;
ZeroMemory(
&colorMapDesc,
sizeof(
colorMapDesc
)
);
colorMapDesc.AddressU
=
D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressV
=
D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.AddressW
=
D3D11_TEXTURE_ADDRESS_WRAP;
colorMapDesc.ComparisonFunc
=
D3D11_COMPARISON_NEVER;
colorMapDesc.Filter
=
D3D11_FILTER_MIN_MAG_MIP_LINEAR;
colorMapDesc.MaxLOD
=
D3D11_FLOAT32_MAX;
d3dResult
=
d3dDevice_->CreateSamplerState(
&colorMapDesc,
&colorMapSampler_
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"創(chuàng)建顏色映射采樣器聲明失敗!"
);
return
false;
}
return
true;
}
void
TextureDemo::UnloadContent(
)
//UnloadContent函數(shù)的書(shū)寫(xiě)
{
if(
colorMapSampler_
)
colorMapSampler_->Release(
);
if(
colorMap_
)
colorMap_->Release(
);
if(
solidColorVS_
)
solidColorVS_->Release(
);
if(
solidColorPS_
)
solidColorPS_->Release(
);
if(
inputLayout_
)
inputLayout_->Release(
);
if(
vertexBuffer_
)
vertexBuffer_->Release(
);
colorMapSampler_
=
0;
colorMap_
=
0;
solidColorVS_
=
0;
solidColorPS_
=
0;
inputLayout_
=
0;
vertexBuffer_
=
0;
}
void
TextureDemo::Update(
float
dt
)
{
//
無(wú)需進(jìn)行更新
}
void
TextureDemo::Render(
)
//Render函數(shù)的書(shū)寫(xiě)
{
if(
d3dContext_
==
0
)
return;
float
clearColor[4]
=
{
0.0f,
0.0f,
0.25f,
1.0f
};
d3dContext_->ClearRenderTargetView(
backBufferTarget_,
clearColor
);
unsigned
int
stride
=
sizeof(
VertexPos
);
unsigned
int
offset
=
0;
d3dContext_->IASetInputLayout(
inputLayout_
);
d3dContext_->IASetVertexBuffers(
0,
1,
&vertexBuffer_,
&stride,
&offset
);
d3dContext_->IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
);
d3dContext_->VSSetShader(
solidColorVS_,
0,
0
);
d3dContext_->PSSetShader(
solidColorPS_,
0,
0
);
d3dContext_->PSSetShaderResources(
0,
1,
&colorMap_
);
d3dContext_->PSSetSamplers(
0,
1,
&colorMapSampler_
);
d3dContext_->Draw(
6,
0
);
swapChain_->Present(
0,
0
);
}
下面依舊是像前面的幾節(jié)中的demo一樣,對(duì)Dx11DemoBase類(lèi)進(jìn)行修改,其修改后的代碼也在這里列出來(lái):
代碼段六Dx11DemoBase.h實(shí)現(xiàn)代碼
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?#ifndef
_DEMO_BASE_H_
#define
_DEMO_BASE_H_
#include<d3d11.h>
#include<d3dx11.h>
#include<DxErr.h>
class
Dx11DemoBase
{
public:
Dx11DemoBase();
virtual
~Dx11DemoBase();
bool
Initialize(
HINSTANCE
hInstance,
HWND
hwnd
);
void
Shutdown(
);
bool
CompileD3DShader(
char*
filePath,
char*
entry,
char*
shaderModel,
ID3DBlob**
buffer
);
virtual
bool
LoadContent(
);
virtual
void
UnloadContent(
);
virtual
void
Update(
float
dt
)
=
0;
virtual
void
Render(
)
=
0;
protected:
HINSTANCE
hInstance_;
HWND
hwnd_;
D3D_DRIVER_TYPE
driverType_;
D3D_FEATURE_LEVEL
featureLevel_;
ID3D11Device*
d3dDevice_;
ID3D11DeviceContext*
d3dContext_;
IDXGISwapChain*
swapChain_;
ID3D11RenderTargetView*
backBufferTarget_;
};
#endif
代碼段七Dx11DemoBase.cpp實(shí)現(xiàn)代碼
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?#include"Dx11DemoBase.h"
#include<D3Dcompiler.h>
Dx11DemoBase::Dx11DemoBase(
)
:
driverType_(
D3D_DRIVER_TYPE_NULL
),
featureLevel_(
D3D_FEATURE_LEVEL_11_0
),
d3dDevice_(
0
),
d3dContext_(
0
),
swapChain_(
0
),
backBufferTarget_(
0
)
{
}
Dx11DemoBase::~Dx11DemoBase(
)
{
Shutdown(
);
}
bool
Dx11DemoBase::Initialize(
HINSTANCE
hInstance,
HWND
hwnd
)
{
hInstance_
=
hInstance;
hwnd_
=
hwnd;
RECT
dimensions;
GetClientRect(
hwnd,
&dimensions
);
unsigned
int
width
=
dimensions.right
-
dimensions.left;
unsigned
int
height
=
dimensions.bottom
-
dimensions.top;
D3D_DRIVER_TYPE
driverTypes[]
=
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_SOFTWARE
};
unsigned
int
totalDriverTypes
=
ARRAYSIZE(
driverTypes
);
D3D_FEATURE_LEVEL
featureLevels[]
=
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0
};
unsigned
int
totalFeatureLevels
=
ARRAYSIZE(
featureLevels
);
DXGI_SWAP_CHAIN_DESC
swapChainDesc;
ZeroMemory(
&swapChainDesc,
sizeof(
swapChainDesc
)
);
swapChainDesc.BufferCount
=
1;
swapChainDesc.BufferDesc.Width
=
width;
swapChainDesc.BufferDesc.Height
=
height;
swapChainDesc.BufferDesc.Format
=
DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator
=
60;
swapChainDesc.BufferDesc.RefreshRate.Denominator
=
1;
swapChainDesc.BufferUsage
=
DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.OutputWindow
=
hwnd;
swapChainDesc.Windowed
=
true;
swapChainDesc.SampleDesc.Count
=
1;
swapChainDesc.SampleDesc.Quality
=
0;
unsigned
int
creationFlags
=
0;
#ifdef
_DEBUG
creationFlags
|=
D3D11_CREATE_DEVICE_DEBUG;
#endif
HRESULT
result;
unsigned
int
driver
=
0;
for(
driver
=
0;
driver
<
totalDriverTypes;
++driver
)
{
result
=
D3D11CreateDeviceAndSwapChain(
0,
driverTypes[driver],
0,
creationFlags,
featureLevels,
totalFeatureLevels,
D3D11_SDK_VERSION,
&swapChainDesc,
&swapChain_,
&d3dDevice_,
&featureLevel_,
&d3dContext_
);
if(
SUCCEEDED(
result
)
)
{
driverType_
=
driverTypes[driver];
break;
}
}
if(
FAILED(
result
)
)
{
DXTRACE_MSG(
"創(chuàng)建
Direct3D
設(shè)備失敗!"
);
return
false;
}
ID3D11Texture2D*
backBufferTexture;
result
=
swapChain_->GetBuffer(
0,
__uuidof(
ID3D11Texture2D
),
(
LPVOID*
)&backBufferTexture
);
if(
FAILED(
result
)
)
{
DXTRACE_MSG(
"獲取交換鏈后臺(tái)緩存失敗!"
);
return
false;
}
result
=
d3dDevice_->CreateRenderTargetView(
backBufferTexture,
0,
&backBufferTarget_
);
if(
backBufferTexture
)
backBufferTexture->Release(
);
if(
FAILED(
result
)
)
{
DXTRACE_MSG(
"創(chuàng)建渲染目標(biāo)視圖失敗!"
);
return
false;
}
d3dContext_->OMSetRenderTargets(
1,
&backBufferTarget_,
0
);
D3D11_VIEWPORT
viewport;
viewport.Width
=
static_cast<float>(width);
viewport.Height
=
static_cast<float>(height);
viewport.MinDepth
=
0.0f;
viewport.MaxDepth
=
1.0f;
viewport.TopLeftX
=
0.0f;
viewport.TopLeftY
=
0.0f;
d3dContext_->RSSetViewports(
1,
&viewport
);
return
LoadContent(
);
}
bool
Dx11DemoBase::CompileD3DShader(
char*
filePath,
char*
entry,
char*
shaderModel,
ID3DBlob**
buffer
)
{
DWORD
shaderFlags
=
D3DCOMPILE_ENABLE_STRICTNESS;
#if
defined(
DEBUG
)
||
defined(
_DEBUG
)
shaderFlags
|=
D3DCOMPILE_DEBUG;
#endif
ID3DBlob*
errorBuffer
=
0;
HRESULT
result;
result
=
D3DX11CompileFromFile(
filePath,
0,
0,
entry,
shaderModel,
shaderFlags,
0,
0,
buffer,
&errorBuffer,
0
);
if(
FAILED(
result
)
)
{
if(
errorBuffer
!=
0
)
{
OutputDebugStringA(
(
char*
)errorBuffer->GetBufferPointer(
)
);
errorBuffer->Release(
);
}
return
false;
}
if(
errorBuffer
!=
0
)
errorBuffer->Release(
);
return
true;
}
bool
Dx11DemoBase::LoadContent(
)
{
//重載,進(jìn)行相關(guān)實(shí)現(xiàn)
return
true;
}
void
Dx11DemoBase::UnloadContent(
)
{
//重載,進(jìn)行相關(guān)實(shí)現(xiàn)
}
void
Dx11DemoBase::Shutdown(
)
{
UnloadContent(
);
if(
backBufferTarget_
)
backBufferTarget_->Release(
);
if(
swapChain_
)
swapChain_->Release(
);
if(
d3dContext_
)
d3dContext_->Release(
);
if(
d3dDevice_
)
d3dDevice_->Release(
);
backBufferTarget_
=
0;
swapChain_
=
0;
d3dContext_
=
0;
d3dDevice_
=
0;
}
最后的壓軸依舊是永遠(yuǎn)最重要的main函數(shù),其實(shí)現(xiàn)代碼如下代碼段八:
代碼段八
main.cpp實(shí)現(xiàn)代碼
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?#include<Windows.h>
#include<memory>
#include"Texture2DDemo.h"
LRESULT
CALLBACK
WndProc(
HWND
hwnd,
UINT
message,
WPARAM
wParam,
LPARAM
lParam
);
//****wWinMain函數(shù),程序入口點(diǎn)函數(shù)**************************************
int
WINAPI
wWinMain(
HINSTANCE
hInstance,
HINSTANCE
prevInstance,
LPWSTR
cmdLine,
int
cmdShow
)
{
UNREFERENCED_PARAMETER(
prevInstance
);
UNREFERENCED_PARAMETER(
cmdLine
);
WNDCLASSEX
wndClass
=
{
0
};
wndClass.cbSize
=
sizeof(
WNDCLASSEX
)
;
wndClass.style
=
CS_HREDRAW
|
CS_VREDRAW;
wndClass.lpfnWndProc
=
WndProc;
wndClass.hInstance
=
hInstance;
wndClass.hCursor
=
LoadCursor(
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 現(xiàn)代辦公環(huán)境下的技術(shù)趨勢(shì)分析報(bào)告
- 生態(tài)修復(fù)技術(shù)在水域生態(tài)保護(hù)中的作用
- 2 認(rèn)識(shí)幾種常見(jiàn)的巖石(說(shuō)課稿)-2023-2024學(xué)年科學(xué)四年級(jí)下冊(cè)教科版
- 2024-2025學(xué)年高中化學(xué) 化學(xué)實(shí)驗(yàn)基本方法說(shuō)課稿 新人教版必修1
- Unit 1 Lesson 1 At the Airport(說(shuō)課稿)-2024-2025學(xué)年冀教版(三起)英語(yǔ)六年級(jí)上冊(cè)
- 2024-2025學(xué)年高中物理 第10章 熱力學(xué)定律 1 功和內(nèi)能說(shuō)課稿 新人教版選修3-3
- 2023八年級(jí)道德與法治上冊(cè) 第二單元 遵守社會(huì)規(guī)則 第五課 做守法的公民 第2框 預(yù)防犯罪說(shuō)課稿 新人教版
- Unit 2 Ways to school Part A Let's learn (說(shuō)課稿)-2024-2025學(xué)年人教PEP版英語(yǔ)六年級(jí)上冊(cè)001
- 10的再認(rèn)識(shí)(說(shuō)課稿)-2024-2025學(xué)年一年級(jí)上冊(cè)數(shù)學(xué)人教版
- 2 時(shí)、分、秒(說(shuō)課稿)-2023-2024學(xué)年二年級(jí)下冊(cè)數(shù)學(xué)蘇教版
- 2024年中考語(yǔ)文試題分類(lèi)匯編:散文、小說(shuō)閱讀(第03期)含答案及解析
- 《宮頸癌篩查》課件
- 2024年聯(lián)勤保障部隊(duì)第九四〇醫(yī)院社會(huì)招聘考試真題
- 第二章《有理數(shù)的運(yùn)算》單元備課教學(xué)實(shí)錄2024-2025學(xué)年人教版數(shù)學(xué)七年級(jí)上冊(cè)
- DB31-T 596-2021 城市軌道交通合理通風(fēng)技術(shù)管理要求
- 華為智慧園區(qū)解決方案介紹
- 2022年江西省公務(wù)員錄用考試《申論》真題(縣鄉(xiāng)卷)及答案解析
- 人教版八年級(jí)英語(yǔ)上冊(cè)期末專(zhuān)項(xiàng)復(fù)習(xí)-完形填空和閱讀理解(含答案)
- 帕金森病(英文版)課件
- 大學(xué)普通化學(xué)(第七版)課后答案
- 化工企業(yè)三違清單不安全安全行為清單
評(píng)論
0/150
提交評(píng)論