




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【VisualC++】游戏开发笔记三十DirectX112D纹理映射知识全攻略【VisualC++】游戏开发笔记二十九一步一步教你用优雅的Direct3D11代码画一个三角形【VisualC++】游戏开发笔记二十八最精简的Direct3D11Demo筋骨脉络全攻略【VisualC++】游戏开发笔记二十七Direct3D11入门级知识介绍【VisualC++】游戏开发笔记二十六DirectX11各组件的介绍&第一个DirectX11Demo的创建【VisualC++】游戏开发笔记二十五最简化的DirectX11开发环境的配【VisualC++】游戏开发笔记二十四由DirectX的几个版本说【VisualC++】游戏开发笔记二十三游戏基础物理建模(五)粒子系统模拟(二)【VisualC++】游戏开发笔记二十二游戏基础物理建模(四)粒子系统模拟(一)【VisualC++】游戏开发笔记二十一游戏基础物理建模(三)摩擦力系统模拟【VisualC++】游戏开发笔记二十游戏基础物理建模(二)重力系统的模拟【VisualC++】游戏开发笔记十八游戏基础物理建模(一)匀速与加速运动。【VisualC++】游戏开发笔记十九DirectX与OpenGL的博弈【VisualC++】游戏开发笔记十七游戏基础算法(一)游戏随机系统初步【VisualC++】游戏开发笔记十八游戏基础物理建模(一)匀速与加速运动。【VisualC++】游戏开发笔记十六讲解一个完整的回合制游戏demo【VisualC++】游戏开发笔记十五游戏人工智能(一)运动型游戏AI【VisualC++】游戏开发笔记十二游戏输入消息处理(一)键盘消息处理【VisualC++】游戏开发笔记十四游戏画面绘图(四)华丽的CImage类【VisualC++】游戏开发笔记十三游戏输入消息处理(二)鼠标消息处理【VisualC++】游戏开发笔记十二游戏输入消息处理(一)键盘消息处理【VisualC++】游戏开发笔记之十一基础动画显示(四)排序贴图【VisualC++】游戏开发笔记之十基础动画显示(三)透明动画的实现【VisualC++】游戏开发笔记之九游戏地图制作(一)平面地图贴图【VisualC++】游戏开发笔记之八——基础动画显示(二)游戏循环的使用【VisualC++】游戏开发笔记之七——基础动画显示(一)定时器的使用【VisualC++】游戏开发笔记之六——游戏画面绘图(三)透明特效的制作方法【VisualC++】游戏开发笔记之四——游戏画面绘图(一)基本图形绘制【VisualC++】游戏开发笔记之五——游戏画面绘图(二)绘制位图【VisualC++】游戏开发笔记之一——API函数、DirectX的关键系【VisualC++】游戏开发笔记之二——最简单的DirectX,vc窗口的编写【VisualC++】游戏开发笔记之三——绘制图元【VisualC++】游戏开发笔记三十DirectX112D纹理映射知识全攻略本系列文章由zhmxy555(毛星云)编写,转载请注明出处。/zhmxy555/article/details/78017229作者:毛星云
邮箱:happylifemxy@
本节知识先是对DirectX11关于2D纹理映射方面基础知识的一个讲解,然后通过一个demo的创建过程来将学到的理论知识付诸实践。
一、引言
在之前我们提到过,纹理实际上就是映射到物体表面的数据。其实,纹理也可能是其他的一些信息片段,比如用于映射的常规映射值,用于控制透明度的alpha值,等等。通常情况下,纹理是通过一个叫做纹理映射的过程来映射一幅图像到表面上的颜色值,这种功能能显著地增加所绘制场景的细腻感和真实感。纹理和游戏开发中需要的其他数据一样,通常都是在运行时加载的。由于纹理是Direct3D重要的组成的部分,微软为我们提供了众多功能强大而丰富的Direct3D内建的函数,来处理纹理相关的操作。
二、基础知识讲解
1.纹理的加载
在Direct3D11中,我们通常使用D3DX11CreateTextureFromFile函数用于从硬盘文件中加载纹理。这个函数支持非常丰富的图像格式,比如BMP,PNG,以及DDS。D3DX11CreateTextureFromFile函数拥有六个变量,具有以下的函数原型:
[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函数的第一个的参数为ID3D11Device类型的指针变量。第二个参数pSrcFile为被加载文件的文件路径和文件名。第三个参数pLoadInfo为一个图形信息结构体。它为一个可选的参数,并允许我们通过指定CPU访问的标识、内部格式、宽度和高度来控制图像纹理的加载方式。第四个参数pPump用于多线程加载纹理时的异步处理。第五个参数ppTexture用是纹理对象被调用时这个函数创建出的地址。如果D3DX11CreateTextureFromFile函数调用成功,这个变量就会拥有一个现成的纹理供使用。最后一个参数pHResult是指向线程返回值的指针。
若此线程的参数不为空,pHResult必须为一个有效的内存地址。在Direct3D中我们能够使用很多函数载入各种琳琅满目的图像文件格式,下面我们对他们进行一个详细的列举:
WindowsBitmap(BMP)JointPhotographicExpertGroup—i.e.,JPEG(JPG)PortableNetworkGraphics(PNG)TaggedImageFormat(TIFF)GraphicsInterchangeFormat(GIF)DirectDrawSurface(DDS)WindowsMediaPlayer(WMP)
2.纹理接口
纹理接口通常用于管理一个特定类型的图像数据。目前Direct3D纹理接口主要有三种类型,他们分别是:ID3D11Texture1D——用于1D或者条形的纹理ID3D11Texture2D——用于2D数据,这也是最常用的纹理资源类型、ID3D11Texture3D——用于表示3D数据的纹理资源类型上述3种纹理资源类型都包含一个或者多个子资源。而游戏开发中使用的大多数纹理类型基本上都为二维的,他们都需要转化为ID3D11Texture2D型资源后再使用。而这些子资源代表了纹理中不同的
MIP等级。譬如Adobe’sPhotoshop这类的图像编辑器是创造2D纹理的最得力帮手。
3.纹理细节
在游戏开发的过程中,常常我们需要从加载的纹理中得到一些特定的信息,比如说维度或者像素格式。这时候隶属于ID3D11Texture2D中的GetDesc函数就可以派上用场了。这个函数的功能是为我们填充D3D11_TEXTURE2D_DESC结构体中的各种细节,从而通过这个结构体作为载体,有关的各类数据就一目了然了。
D3D11_TEXTURE2D_DESC是专用于2D纹理的纹理描述结构体家族中的一员。对于其他的两个维度,Direct3D11为我们准备了D3D11_TEXTURE1D_DESC用于1D纹理,D3D11_TEXTURE3D_DESC用于3D纹理。
作为最常见的纹理,二维的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的创建
这里,我们先介绍一下这个demo的组成结构:如图,头文件有Dx11DemoBase.h以及Texture2DDemo.h源文件有Dx11DemoBase.cpp,Texture2DDemo.h以及main.cpp
在之前的TriangleDemo的基础上,我们再添加一个叫做TextureDemo的类,以及添加一个叫做colorMap_的D3D11ShaderResourceView类型的着色器资源视图和一个D3D11SamplerState类型的唤做colorMapSampler_的采样状态。着色资源视图简单的来说是一个用于访问资源的对象。当我们加载纹理到内存中的时候,必须创建一个着色器资源视图来通过着色器获取数据,而这些数据会被绑定到输出程序集当中。着色器资源视图也有其他的作用,比如为DirectCompute提供异步运算时需要的数据,本节我们主要是介绍其在纹理方面的运用。ID3D11Texture2D代表数据的缓存,而着色器资源视图允许我们在着色器中查看这个缓存的各项数据。采样器声明(samplerstate)允许我们访问的纹理采样的状态信息。后面将对其做更多更详细的讲解。TextureDemo类的头文件代码书写风格如下:
代码段一
TextureDemo.h对TextureDemo类的轮廓书写
[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
由于我们正在执行纹理映射这项操作,我们需要对顶点结构体的代码进行更新,使其包含两个浮点型的变量。这项工作可由XMFLOAT2结构体来完成。
代码段二中展示了这个demo中顶点结构体,LoadContent,函数和UnloadContent函数的写法
代码段二
顶点结构体以及LoadContent和UnloadContent的书写
[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函数释放了新对象,而LoadContent函数进行了纹理图像的加载。我们可以使用Direct3D中的D3DX11CreateShaderResourceViewFromFile函数(这个函数名是不是略长啊,哈哈),来加载一个纹理然后在一个简单的调用之中创建着色器资源视图。这个函数在我们想毕其功于一役的时候,即希望加载一个纹理连着创建一个新的着色器资源视图一步到位的时候,非常的好用。D3DX11CreateShaderResourceViewFromFile函数的变量和D3DX11CreateTextureFromFile函数的相似度很高,这员大将有以下原型:
[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函数代码的最后一段完成的功能是采样器声明(samplerstate)的创建。为了创建一个采样器声明(samplerstate)的对象,很容易就可以通过功能联想到函数名——CreateSamplerState。这个函数以采样器描述作为其一个参数。而采样器描述拥有以下的声明:
[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;
为了渲染我们的几何纹理,我们必须添加纹理资源以及设置采样器描述。这两项特殊的任务分别分配给PSSetShaderResources函数以及PSSetSamplers函数来完成,设置这些数据到像素着色器之中。PSSetShaderResources函数具有以下原型:
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?void
PSSetShaderResources(
UINT
StartSlot,
UINT
NumViews,
ID3D11ShaderResourceView*
const*
ppShaderResourceViews
);
PSSetSamplers函数也以起始点StartSlot以及采样数量NumViews作为其参数。我们在之前demo里面关于Render的代码随着这节里面对这两个函数的加入,我们就可以看到更加出色的效果了。目前需要做的就是就修改着色器的渲染效果了。TextureMappingdemo类的Render函数如下代码段X
代码段三
TextureDemo
类的render函数的书写
[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
);
}
在着色器之中,如代码段四,我们拥有两个新的全局着色器对象,分别唤作colorMap_和colorSampler_。其中colorSampler_对象的类型为Texture2D,它可以用于2D纹理之中,而colorSampler_为HLSL(HighLevelShaderLanguage高级着色器语言)类型的采样器声明。
为了将这些对象绑定到我们在Render函数中提供的着色器当中,我们需要使用中HLSL(HighLevelShaderLanguage高级着色器语言)中的register关键字。绑定第一个纹理输出我们采用t0来表示,其中t代表texture这个单词,0代表数量的索引,即第几个。同理,对于采样器声明,s代表samplerstate这个词组,0代表第几个,则s0就代表第一个采样器。因为我们只有一种纹理和一种采样器声明,所以只需t0和s0即可。着色器当中的另一个需要注意的地方是,我们必须更新顶点着色器以及像素着色器的输入结构来方便地获取纹理坐标。顶点着色器将从顶点缓存中取得纹理坐标,然后将其传递给像素着色器,以便像素着色器方便地访问这些数据。之后,像素着色器会使用这些纹理坐标和纹理对象来读取颜色值。这一步可以调用HLSLTexture2D对象的Sample函数来完成。最后提一点,由于我们是从一个2D纹理中读取数据的,则纹理坐标需为float2类型。
在这里列出着色器的构成代码:
代码段四
纹理映射demo中着色器的构成代码
[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
);
}
到这一步,核心的代码都书写完毕了,为了观看的方便,浅墨在这里将最重头的Texture2DDemo.cpp贴出来(Texture2DDemo.h见代码段一):
代码段五Texture2DDemo.cpp实现代码
[cpp]
\o"viewplain"viewplain\o"copy"copy\o"print"print\o"?"?#include"Texture2DDemo.h"
#include<xnamath.h>
struct
VertexPos
//结构体
{
XMFLOAT3
pos;
XMFLOAT2
tex0;
};
TextureDemo::TextureDemo(
)
:
solidColorVS_(
0
),
solidColorPS_(
0
),
//构造函数
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(
"编译顶点着色器失败!"
);
return
false;
}
HRESULT
d3dResult;
d3dResult
=
d3dDevice_->CreateVertexShader(
vsBuffer->GetBufferPointer(
),
vsBuffer->GetBufferSize(
),
0,
&solidColorVS_
);
if(
FAILED(
d3dResult
)
)
{
DXTRACE_MSG(
"创建顶点着色器失败!"
);
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(
"创建输入布局失败!"
);
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(
"创建像素着色器失败!"
);
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(
"创建顶点缓存失败!"
);
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(
"创建颜色映射采样器声明失败!"
);
return
false;
}
return
true;
}
void
TextureDemo::UnloadContent(
)
//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;
}
void
TextureDemo::Update(
float
dt
)
{
//
无需进行更新
}
void
TextureDemo::Render(
)
//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(
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
);
}
下面依旧是像前面的几节中的demo一样,对Dx11DemoBase类进行修改,其修改后的代码也在这里列出来:
代码段六Dx11DemoBase.h实现代码
[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实现代码
[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(
"创建
Direct3D
设备失败!"
);
return
false;
}
ID3D11Texture2D*
backBufferTexture;
result
=
swapChain_->GetBuffer(
0,
__uuidof(
ID3D11Texture2D
),
(
LPVOID*
)&backBufferTexture
);
if(
FAILED(
result
)
)
{
DXTRACE_MSG(
"获取交换链后台缓存失败!"
);
return
false;
}
result
=
d3dDevice_->CreateRenderTargetView(
backBufferTexture,
0,
&backBufferTarget_
);
if(
backBufferTexture
)
backBufferTexture->Release(
);
if(
FAILED(
result
)
)
{
DXTRACE_MSG(
"创建渲染目标视图失败!"
);
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(
)
{
//重载,进行相关实现
return
true;
}
void
Dx11DemoBase::UnloadContent(
)
{
//重载,进行相关实现
}
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;
}
最后的压轴依旧是永远最重要的main函数,其实现代码如下代码段八:
代码段八
main.cpp实现代码
[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函数,程序入口点函数**************************************
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. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年配气机构:进排气门项目建议书
- 医院职工食堂建设合同范本
- 劳动合同法附合同范本
- 药店销售协议合同范本
- 个人 融资佣金合同范本
- 博物馆合同范例
- 劳务合同范本小时工
- 土地土地租赁合同范本
- 租凭吊车合同范本
- 冷凝机组采购合同范本
- 2025年徐州地铁集团有限公司招聘笔试参考题库含答案解析
- 6月26国际禁毒日防范青少年药物滥用禁毒宣传课件
- 老旧小区基础设施环境改造工程施工质量因素的分析及控制方法
- 伊斯兰教完整版本
- 华师版初中九年级数学HS下册教案(全一册)
- 2024年10月自考00107现代管理学试题及答案
- 2024解析:第十八章电功率-讲核心(解析版)
- 2024年新疆区公务员录用考试《行测》真题及答案解析
- 严重创伤患者紧急救治血液保障模式与输血策略中国专家共识(2024版)
- 【川教版】《生命 生态 安全》五下全册课件
- 英文在职证明模版
评论
0/150
提交评论