Visual-C++游戏开发笔记全集_第1页
Visual-C++游戏开发笔记全集_第2页
Visual-C++游戏开发笔记全集_第3页
Visual-C++游戏开发笔记全集_第4页
Visual-C++游戏开发笔记全集_第5页
已阅读5页,还剩1039页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论