【Visual C++】游戏开发笔记三十 DirectX11 2D纹理映射知识全攻略

本文主要是介绍【Visual C++】游戏开发笔记三十 DirectX11 2D纹理映射知识全攻略,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本节知识先是对DirectX11关于2D纹理映射方面基础知识的一个讲解,然后通过一个demo的创建过程来将学到的理论知识付诸实践。

 

 

 

一、引言

 

 

在之前我们提到过,纹理实际上就是映射到物体表面的数据。其实,纹理也可能是其他的一些信息片段,比如用于映射的常规映射值,用于控制透明度的alpha值,等等。

通常情况下,纹理是通过一个叫做纹理映射的过程来映射一幅图像到表面上的颜色值,这种功能能显著地增加所绘制场景的细腻感和真实感。

纹理和游戏开发中需要的其他数据一样,通常都是在运行时加载的。由于纹理是Direct3D重要的组成的部分,微软为我们提供了众多功能强大而丰富的Direct3D内建的函数,来处理纹理相关的操作。

 

 

 

 

二、基础知识讲解

 

 

 

 

1.纹理的加载

 

在Direct3D11中,我们通常使用D3DX11CreateTextureFromFile函数用于从硬盘文件中加载纹理。这个函数支持非常丰富的图像格式,比如BMP,PNG,以及DDS。D3DX11CreateTextureFromFile函数拥有六个变量,具有以下的函数原型:

 

 

[cpp] view plain copy print ?
  1. HRESULT D3DX11CreateTextureFromFile(  
  2.   
  3. ID3D11Device* pDevice,  
  4.   
  5. LPCTSTR pSrcFile,  
  6.   
  7. D3DX11_IMAGE_LOAD_INFO* pLoadInfo,  
  8.   
  9. ID3DX11ThreadPump* pPump,  
  10.   
  11. ID3D11Resource** ppTexture,  
  12.   
  13. HRESULT* pHResult  
  14.   
  15. );  


 

 

 

D3DX11CreateTextureFromFile函数的第一个的参数为ID3D11Device类型的指针变量。

第二个参数pSrcFile为被加载文件的文件路径和文件名。

第三个参数pLoadInfo为一个图形信息结构体。它为一个可选的参数,并允许我们通过指定CPU访问的标识、内部格式、宽度和高度来控制图像纹理的加载方式。

第四个参数pPump用于多线程加载纹理时的异步处理。

第五个参数ppTexture用是纹理对象被调用时这个函数创建出的地址。如果D3DX11CreateTextureFromFile函数调用成功,这个变量就会拥有一个现成的纹理供使用。

最后一个参数pHResult是指向线程返回值的指针。

 

 

若此线程的参数不为空,pHResult必须为一个有效的内存地址。在Direct3D中我们能够使用很多函数载入各种琳琅满目的图

像文件格式,下面我们对他们进行一个详细的列举:

 

Windows Bitmap (BMP)

Joint Photographic Expert Group—i.e., JPEG (JPG)

Portable Network Graphics (PNG)

Tagged Image Format (TIFF)

Graphics Interchange Format (GIF)

DirectDraw Surface (DDS)

Windows Media Player (WMP)

 

 

2.纹理接口

 

纹理接口通常用于管理一个特定类型的图像数据。目前Direct3D纹理接口主要有三种类型,他们分别是:

ID3D11Texture1D——用于1D或者条形的纹理

ID3D11Texture2D——用于2D数据,这也是最常用的纹理资源类型、

ID3D11Texture3D——用于表示3D数据的纹理资源类型

上述3种纹理资源类型都包含一个或者多个子资源。

而游戏开发中使用的大多数纹理类型基本上都为二维的,他们都需要转化为ID3D11Texture2D型资源后再使用。而这些子资源代表了纹理中不同的    MIP等级。

譬如Adobe’s Photoshop这类的图像编辑器是创造2D纹理的最得力帮手。

 

 

3. 纹理细节

 

在游戏开发的过程中,常常我们需要从加载的纹理中得到一些特定的信息,比如说维度或者像素格式。这时候隶属于ID3D11Texture2D中的GetDesc函数就可以派上用场了。这个函数的功能是为我们填充D3D11_TEXTURE2D_DESC结构体中的各种细节,从而通过这个结构体作为载体,有关的各类数据就一目了然了。

 

D3D11_TEXTURE2D_DESC是专用于2D纹理的纹理描述结构体家族中的一员。

对于其他的两个维度,Direct3D11为我们准备了D3D11_TEXTURE1D_DESC用于1D纹理,D3D11_TEXTURE3D_DESC用于3D纹理。

 

作为最常见的纹理,二维的D3D11_TEXTURE2D_DESC声明形式如下:

 

[cpp] view plain copy print ?
  1. typedef struct D3D11_TEXTURE2D_DESC {  
  2.   
  3. UINT Width;  
  4.   
  5. UINT Height;  
  6.   
  7. UINT MipLevels;  
  8.   
  9. UINT ArraySize;  
  10.   
  11. DXGI_FORMAT Format;  
  12.   
  13. DXGI_SAMPLE_DESC SampleDesc;  
  14.   
  15. D3D11_USAGE Usage;  
  16.   
  17. UINT BindFlags;  
  18.   
  19. UINT CPUAccessFlags;  
  20.   
  21. UINT MiscFlags;  
  22.   
  23. } D3D11_TEXTURE2D_DESC;  


 

 

 

 

 

三、DirectX11 2D纹理映射demo的创建 

 

 

 

 

这里,我们先介绍一下这个demo的组成结构:

如图,头文件有Dx11DemoBase.h以及Texture2DDemo.h

源文件有 Dx11DemoBase.cpp,Texture2DDemo.h以及main.cpp

 

 

 

 

 

 

在之前的TriangleDemo的基础上,我们再添加一个叫做TextureDemo的类,以及添加一个叫做colorMap_的D3D11ShaderResourceView类型的着色器资源视图和一个D3D11SamplerState类型的唤做colorMapSampler_ 的采样状态。

着色资源视图简单的来说是一个用于访问资源的对象。当我们加载纹理到内存中的时候,必须创建一个着色器资源视图来通过着色器获取数据,而这些数据会被绑定到输出程序集当中。着色器资源视图也有其他的作用,比如为DirectCompute提供异步运算时需要的数据,本节我们主要是介绍其在纹理方面的运用。ID3D11Texture2D代表数据的缓存,而着色器资源视图允许我们在着色器中查看这个缓存的各项数据。

采样器声明(sampler state)允许我们访问的纹理采样的状态信息。后面将对其做更多更详细的讲解。

TextureDemo类的头文件代码书写风格如下:

 

 

代码段一  TextureDemo.h 对TextureDemo类的轮廓书写

 

[cpp] view plain copy print ?
  1. #ifndef _TEXTURE_2D_DEMO_H_  
  2. #define _TEXTURE_2D_DEMO_H_  
  3.   
  4. #include"Dx11DemoBase.h"  
  5.   
  6.   
  7. class TextureDemo : public Dx11DemoBase  
  8. {  
  9.     public:  
  10.         TextureDemo( );  
  11.         virtual ~TextureDemo( );  
  12.   
  13.         bool LoadContent( );  
  14.         void UnloadContent( );  
  15.   
  16.         void Update( float dt );  
  17.         void Render( );  
  18.   
  19.     private:  
  20.         ID3D11VertexShader* solidColorVS_;  
  21.         ID3D11PixelShader* solidColorPS_;  
  22.   
  23.         ID3D11InputLayout* inputLayout_;  
  24.         ID3D11Buffer* vertexBuffer_;  
  25.   
  26.         ID3D11ShaderResourceView* colorMap_;  
  27.         ID3D11SamplerState* colorMapSampler_;  
  28. };  
  29.   
  30. #endif  


 

 

 

由于我们正在执行纹理映射这项操作,我们需要对顶点结构体的代码进行更新,使其包含两个浮点型的变量。这项工作可由XMFLOAT2结构体来完成。

 

代码段二中展示了这个demo中顶点结构体,LoadContent,函数和 UnloadContent函数的写法

 

代码段二  顶点结构体以及 LoadContent和UnloadContent的书写

 

[cpp] view plain copy print ?
  1. struct VertexPos  
  2.   
  3. {  
  4.   
  5. XMFLOAT3 pos;  
  6.   
  7. XMFLOAT2 tex0;  
  8.   
  9. };  
  10.   
  11. bool TextureDemo::LoadContent( )  
  12.   
  13. {  
  14.   
  15. ... Load vertex Shader ...  
  16.   
  17. D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =  
  18.   
  19. {  
  20.   
  21. "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,  
  22.   
  23. 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },  
  24.   
  25. "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,  
  26.   
  27. 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }  
  28.   
  29. };  
  30.   
  31. unsigned int totalLayoutElements = ARRAYSIZE( solidColorLayout );  
  32.   
  33. d3dResult = d3dDevice_->CreateInputLayout( solidColorLayout,  
  34.   
  35. totalLayoutElements, vsBuffer->GetBufferPointer( ),  
  36.   
  37. vsBuffer->GetBufferSize( ), &inputLayout_ );  
  38.   
  39. ... Load Pixel Shader ...  
  40.   
  41. VertexPos vertices[] =  
  42.   
  43. {  
  44.   
  45. { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },  
  46.   
  47. { XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) },  
  48.   
  49. { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },  
  50.   
  51. { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },  
  52.   
  53. { XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },  
  54.   
  55. { XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },  
  56.   
  57. };  
  58.   
  59. ... Create Vertex Buffer ...  
  60.   
  61. d3dResult = D3DX11CreateShaderResourceViewFromFile( d3dDevice_,  
  62.   
  63. "decal.dds", 0, 0, &colorMap_, 0 );  
  64.   
  65. if( FAILED( d3dResult ) )  
  66.   
  67. {  
  68.   
  69. DXTRACE_MSG( "Failed to load the texture image!" );  
  70.   
  71. return false;  
  72.   
  73. }  
  74.   
  75. D3D11_SAMPLER_DESC colorMapDesc;  
  76.   
  77. ZeroMemory( &colorMapDesc, sizeof( colorMapDesc ) );  
  78.   
  79. colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;  
  80.   
  81. colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;  
  82.   
  83. colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;  
  84.   
  85. colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;  
  86.   
  87. colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;  
  88.   
  89. colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;  
  90.   
  91. d3dResult = d3dDevice_->CreateSamplerState( &colorMapDesc,  
  92.   
  93. &colorMapSampler_ );  
  94.   
  95. if( FAILED( d3dResult ) )  
  96.   
  97. {  
  98.   
  99. DXTRACE_MSG( "Failed to create color map sampler state!" );  
  100.   
  101. return false;  
  102.   
  103. }  
  104.   
  105. return true;  
  106.   
  107. }  
  108.   
  109. void TextureDemo::UnloadContent( )  
  110.   
  111. {  
  112.   
  113. if( colorMapSampler_ ) colorMapSampler_->Release( );  
  114.   
  115. if( colorMap_ ) colorMap_->Release( );  
  116.   
  117. if( solidColorVS_ ) solidColorVS_->Release( );  
  118.   
  119. if( solidColorPS_ ) solidColorPS_->Release( );  
  120.   
  121. if( inputLayout_ ) inputLayout_->Release( );  
  122.   
  123. if( vertexBuffer_ ) vertexBuffer_->Release( );  
  124.   
  125. colorMapSampler_ = 0;  
  126.   
  127. colorMap_ = 0;  
  128.   
  129. solidColorVS_ = 0;  
  130.   
  131. solidColorPS_ = 0;  
  132.   
  133. inputLayout_ = 0;  
  134.   
  135. vertexBuffer_ = 0;  
  136.   
  137. }  


 

UnloadContent函数释放了新对象,而LoadContent函数进行了纹理图像的加载。我们可以使用Direct3D中的D3DX11CreateShaderResourceViewFromFile函数(这个函数名是不是略长啊,哈哈),来加载一个纹理然后在一个简单的调用之中创建着色器资源视图。这个函数在我们想毕其功于一役的时候,即希望加载一个纹理连着创建一个新的着色器资源视图一步到位的时候,非常的好用。

D3DX11CreateShaderResourceViewFromFile函数的变量和D3DX11CreateTextureFromFile函数的相似度很高,这员大将有以下原型:

 

 

[cpp] view plain copy print ?
  1. HRESULT D3DX11CreateShaderResourceViewFromFile(  
  2.   
  3. ID3D11Device* pDevice,  
  4.   
  5. LPCTSTR pSrcFile,  
  6.   
  7. D3DX11_IMAGE_LOAD_INFO* pLoadInfo,  
  8.   
  9. ID3DX11ThreadPump* pPump,  
  10.   
  11. ID3D11ShaderResourceView** ppShaderResourceView,  
  12.   
  13. HRESULT* pHResult  
  14.   
  15. );  


 

LoadContent函数代码的最后一段完成的功能是采样器声明(sampler state)的创建。为了创建一个采样器声明(sampler state)的对象,很容易就可以通过功能联想到函数名——CreateSamplerState。这个函数以采样器描述作为其一个参数。 而采样器描述拥有以下的声明:

 

[cpp] view plain copy print ?
  1. typedef struct D3D11_SAMPLER_DESC {  
  2.   
  3. D3D11_FILTER Filter;  
  4.   
  5. D3D11_TEXTURE_ADDRESS_MODE AddressU;  
  6.   
  7. D3D11_TEXTURE_ADDRESS_MODE AddressV;  
  8.   
  9. D3D11_TEXTURE_ADDRESS_MODE AddressW;  
  10.   
  11. FLOAT MipLODBias;  
  12.   
  13. UINT MaxAnisotropy;  
  14.   
  15. D3D11_COMPARISON_FUNC ComparisonFunc;  
  16.   
  17. FLOAT BorderColor[4];  
  18.   
  19. FLOAT MinLOD;  
  20.   
  21. FLOAT MaxLOD;  
  22.   
  23. } D3D11_SAMPLER_DESC;  


 

为了渲染我们的几何纹理,我们必须添加纹理资源以及设置采样器描述。这两项特殊的任务分别分配给PSSetShaderResources函数 以及 PSSetSamplers函数来完成,设置这些数据到像素着色器之中。PSSetShaderResources函数具有以下原型:

 

[cpp] view plain copy print ?
  1. void PSSetShaderResources(  
  2.   
  3. UINT StartSlot,  
  4.   
  5. UINT NumViews,  
  6.   
  7. ID3D11ShaderResourceView* const* ppShaderResourceViews  
  8.   
  9.     
  10.   
  11. );  


 

PSSetSamplers函数也以起始点StartSlot以及采样数量NumViews作为其参数。我们在之前demo里面关于Render的代码随着这节里面对这两个函数的加入,我们就可以看到更加出色的效果了。目前需要做的就是就修改着色器的渲染效果了。Texture Mappingdemo类的Render函数如下代码段X

 

代码段三 TextureDemo 类的render函数的书写

 

[cpp] view plain copy print ?
  1. void TextureDemo::Render( )  
  2.   
  3. {  
  4.   
  5. if( d3dContext_ == 0 )  
  6.   
  7. return;  
  8.   
  9. float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };  
  10.   
  11. d3dContext_->ClearRenderTargetView( backBufferTarget_, clearColor );  
  12.   
  13. unsigned int stride = sizeof( VertexPos );  
  14.   
  15. unsigned int offset = 0;  
  16.   
  17. d3dContext_->IASetInputLayout( inputLayout_ );  
  18.   
  19. d3dContext_->IASetVertexBuffers( 0, 1, &vertexBuffer_, &stride, &offset );  
  20.   
  21. d3dContext_->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_  
  22.   
  23. TRIANGLELIST );  
  24.   
  25. d3dContext_->VSSetShader( colorMapVS_, 0, 0 );  
  26.   
  27. d3dContext_->PSSetShader( colorMapPS_, 0, 0 );  
  28.   
  29. d3dContext_->PSSetShaderResources( 0, 1, &colorMap_ );  
  30.   
  31. d3dContext_->PSSetSamplers( 0, 1, &colorMapSampler_ );  
  32.   
  33. d3dContext_->Draw( 6, 0 );  
  34.   
  35. swapChain_->Present( 0, 0 );  
  36.   
  37. }  


 

在着色器之中,如代码段四,我们拥有两个新的全局着色器对象,分别唤作colorMap_和colorSampler_。其中colorSampler_对象的类型为Texture2D,它可以用于2D 纹理之中,而colorSampler_为HLSL(High Level Shader Language高级着色器语言)类型的采样器声明。

 

为了将这些对象绑定到我们在Render函数中提供的着色器当中,我们需要使用中HLSL(High Level Shader Language高级着色器语言)中的register关键字。绑定第一个纹理输出我们采用t0来表示,其中t代表texture这个单词,0代表数量的索引,即第几个。同理,对于采样器声明,s代表sampler state这个词组,0代表第几个,则s0就代表第一个采样器。因为我们只有一种纹理和一种采样器声明,所以只需t0和s0即可。

着色器当中的另一个需要注意的地方是,我们必须更新顶点着色器以及像素着色器的输入结构来方便地获取纹理坐标。顶点着色器将从顶点缓存中取得纹理坐标,然后将其传递给像素着色器,以便像素着色器方便地访问这些数据。

之后,像素着色器会使用这些纹理坐标和纹理对象来读取颜色值。这一步可以调用HLSL Texture2D对象的Sample函数来完成。

最后提一点,由于我们是从一个2D纹理中读取数据的,则纹理坐标需为float2类型。

 

 

在这里列出着色器的构成代码:

 

代码段四  纹理映射demo中着色器的构成代码

 

[cpp] view plain copy print ?
  1. Texture2D colorMap_ : register( t0 );  
  2.   
  3. SamplerState colorSampler_ : register( s0 );  
  4.   
  5. struct VS_Input  
  6.   
  7. {  
  8.   
  9. float4 pos : POSITION;  
  10.   
  11. float2 tex0 : TEXCOORD0;  
  12.   
  13. };  
  14.   
  15. struct PS_Input  
  16.   
  17. {  
  18.   
  19. float4 pos : SV_POSITION;  
  20.   
  21. float2 tex0 : TEXCOORD0;  
  22.   
  23. };  
  24.   
  25. PS_Input VS_Main( VS_Input vertex )  
  26.   
  27. {  
  28.   
  29. PS_Input vsOut = ( PS_Input )0;  
  30.   
  31. vsOut.pos = vertex.pos;  
  32.   
  33. vsOut.tex0 = vertex.tex0;  
  34.   
  35. return vsOut;  
  36.   
  37. }  
  38.   
  39. float4 PS_Main( PS_Input frag ) : SV_TARGET  
  40.   
  41. {  
  42.   
  43. return colorMap_.Sample( colorSampler_, frag.tex0 );  
  44.   
  45. }  
  46.   
  47.    


 

 

 

到这一步,核心的代码都书写完毕了,为了观看的方便,浅墨在这里将最重头的Texture2DDemo.cpp贴出来(Texture2DDemo.h见代码段一):

 

 

代码段五 Texture2DDemo.cpp实现代码

 

  

[cpp] view plain copy print ?
  1. #include"Texture2DDemo.h"  
  2. #include<xnamath.h>  
  3.   
  4.   
  5. struct VertexPos               //结构体  
  6. {  
  7.     XMFLOAT3 pos;  
  8.     XMFLOAT2 tex0;  
  9. };  
  10.   
  11.   
  12. TextureDemo::TextureDemo( ) : solidColorVS_( 0 ), solidColorPS_( 0 ),      //构造函数  
  13.                               inputLayout_( 0 ), vertexBuffer_( 0 ),  
  14.                               colorMap_( 0 ), colorMapSampler_( 0 )  
  15. {  
  16.   
  17. }  
  18.   
  19.   
  20. TextureDemo::~TextureDemo( )  
  21. {  
  22.   
  23. }  
  24.   
  25.   
  26. bool TextureDemo::LoadContent( )  
  27. {  
  28.     ID3DBlob* vsBuffer = 0;  
  29.   
  30.     bool compileResult = CompileD3DShader( "TextureMap.fx""VS_Main""vs_4_0", &vsBuffer );  
  31.   
  32.     if( compileResult == false )  
  33.     {  
  34.         DXTRACE_MSG( "编译顶点着色器失败!" );  
  35.         return false;  
  36.     }  
  37.   
  38.     HRESULT d3dResult;  
  39.   
  40.     d3dResult = d3dDevice_->CreateVertexShader( vsBuffer->GetBufferPointer( ),  
  41.         vsBuffer->GetBufferSize( ), 0, &solidColorVS_ );  
  42.   
  43.     if( FAILED( d3dResult ) )  
  44.     {  
  45.         DXTRACE_MSG( "创建顶点着色器失败!" );  
  46.   
  47.         if( vsBuffer )  
  48.             vsBuffer->Release( );  
  49.   
  50.         return false;  
  51.     }  
  52.   
  53.     D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =  
  54.     {  
  55.         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },  
  56.         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }  
  57.     };  
  58.   
  59.     unsigned int totalLayoutElements = ARRAYSIZE( solidColorLayout );  
  60.   
  61.     d3dResult = d3dDevice_->CreateInputLayout( solidColorLayout, totalLayoutElements,  
  62.         vsBuffer->GetBufferPointer( ), vsBuffer->GetBufferSize( ), &inputLayout_ );  
  63.   
  64.     vsBuffer->Release( );  
  65.   
  66.     if( FAILED( d3dResult ) )  
  67.     {  
  68.         DXTRACE_MSG( "创建输入布局失败!" );  
  69.         return false;  
  70.     }  
  71.   
  72.     ID3DBlob* psBuffer = 0;  
  73.   
  74.     compileResult = CompileD3DShader( "TextureMap.fx""PS_Main""ps_4_0", &psBuffer );  
  75.   
  76.     if( compileResult == false )  
  77.     {  
  78.         DXTRACE_MSG( "像素着色器编译失败!" );  
  79.         return false;  
  80.     }  
  81.   
  82.     d3dResult = d3dDevice_->CreatePixelShader( psBuffer->GetBufferPointer( ),  
  83.         psBuffer->GetBufferSize( ), 0, &solidColorPS_ );  
  84.   
  85.     psBuffer->Release( );  
  86.   
  87.     if( FAILED( d3dResult ) )  
  88.     {  
  89.         DXTRACE_MSG( "创建像素着色器失败!" );  
  90.         return false;  
  91.     }  
  92.   
  93.     VertexPos vertices[] =  
  94.     {  
  95.         { XMFLOAT3(  1.0f,  1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },  
  96.         { XMFLOAT3(  1.0f, -1.0f, 1.0f ), XMFLOAT2( 1.0f, 0.0f ) },  
  97.         { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },  
  98.   
  99.         { XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT2( 0.0f, 0.0f ) },  
  100.         { XMFLOAT3( -1.0f,  1.0f, 1.0f ), XMFLOAT2( 0.0f, 1.0f ) },  
  101.         { XMFLOAT3(  1.0f,  1.0f, 1.0f ), XMFLOAT2( 1.0f, 1.0f ) },  
  102.     };  
  103.   
  104.     D3D11_BUFFER_DESC vertexDesc;  
  105.     ZeroMemory( &vertexDesc, sizeof( vertexDesc ) );  
  106.     vertexDesc.Usage = D3D11_USAGE_DEFAULT;  
  107.     vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;  
  108.     vertexDesc.ByteWidth = sizeof( VertexPos ) * 6;  
  109.   
  110.     D3D11_SUBRESOURCE_DATA resourceData;  
  111.     ZeroMemory( &resourceData, sizeof( resourceData ) );  
  112.     resourceData.pSysMem = vertices;  
  113.   
  114.     d3dResult = d3dDevice_->CreateBuffer( &vertexDesc, &resourceData, &vertexBuffer_ );  
  115.   
  116.     if( FAILED( d3dResult ) )  
  117.     {  
  118.         DXTRACE_MSG( "创建顶点缓存失败!" );  
  119.         return false;  
  120.     }  
  121.   
  122.     d3dResult = D3DX11CreateShaderResourceViewFromFile( d3dDevice_,  
  123.         "decal.dds", 0, 0, &colorMap_, 0 );  
  124.   
  125.     if( FAILED( d3dResult ) )  
  126.     {  
  127.         DXTRACE_MSG( "读取纹理图像失败!" );  
  128.         return false;  
  129.     }  
  130.   
  131.     D3D11_SAMPLER_DESC colorMapDesc;  
  132.     ZeroMemory( &colorMapDesc, sizeof( colorMapDesc ) );  
  133.     colorMapDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;  
  134.     colorMapDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;  
  135.     colorMapDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;  
  136.     colorMapDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;  
  137.     colorMapDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;  
  138.     colorMapDesc.MaxLOD = D3D11_FLOAT32_MAX;  
  139.   
  140.     d3dResult = d3dDevice_->CreateSamplerState( &colorMapDesc, &colorMapSampler_ );  
  141.   
  142.     if( FAILED( d3dResult ) )  
  143.     {  
  144.         DXTRACE_MSG( "创建颜色映射采样器声明失败!" );  
  145.         return false;  
  146.     }  
  147.   
  148.     return true;  
  149. }  
  150.   
  151.   
  152. void TextureDemo::UnloadContent( )       //UnloadContent函数的书写  
  153. {  
  154.     if( colorMapSampler_ ) colorMapSampler_->Release( );  
  155.     if( colorMap_ ) colorMap_->Release( );  
  156.     if( solidColorVS_ ) solidColorVS_->Release( );  
  157.     if( solidColorPS_ ) solidColorPS_->Release( );  
  158.     if( inputLayout_ ) inputLayout_->Release( );  
  159.     if( vertexBuffer_ ) vertexBuffer_->Release( );  
  160.   
  161.     colorMapSampler_ = 0;  
  162.     colorMap_ = 0;  
  163.     solidColorVS_ = 0;  
  164.     solidColorPS_ = 0;  
  165.     inputLayout_ = 0;  
  166.     vertexBuffer_ = 0;  
  167. }  
  168.   
  169.   
  170. void TextureDemo::Update( float dt )  
  171. {  
  172.     // 无需进行更新  
  173. }  
  174.   
  175.   
  176. void TextureDemo::Render( )       //Render函数的书写  
  177. {  
  178.     if( d3dContext_ == 0 )  
  179.         return;  
  180.   
  181.     float clearColor[4] = { 0.0f, 0.0f, 0.25f, 1.0f };    
  182.     d3dContext_->ClearRenderTargetView( backBufferTarget_, clearColor );  
  183.   
  184.     unsigned int stride = sizeof( VertexPos );        
  185.     unsigned int offset = 0;  
  186.   
  187.     d3dContext_->IASetInputLayout( inputLayout_ );  
  188.     d3dContext_->IASetVertexBuffers( 0, 1, &vertexBuffer_, &stride, &offset );  
  189.     d3dContext_->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );  
  190.   
  191.     d3dContext_->VSSetShader( solidColorVS_, 0, 0 );  
  192.     d3dContext_->PSSetShader( solidColorPS_, 0, 0 );  
  193.     d3dContext_->PSSetShaderResources( 0, 1, &colorMap_ );  
  194.     d3dContext_->PSSetSamplers( 0, 1, &colorMapSampler_ );  
  195.     d3dContext_->Draw( 6, 0 );  
  196.   
  197.     swapChain_->Present( 0, 0 );  
  198. }  



 


 

 

 

下面依旧是像前面的几节中的demo一样,对Dx11DemoBase类进行修改,其修改后的代码也在这里列出来:

 

代码段六 Dx11DemoBase.h实现代码

 

 

[cpp] view plain copy print ?
  1. #ifndef _DEMO_BASE_H_  
  2.   
  3. #define _DEMO_BASE_H_  
  4.   
  5.    
  6.   
  7. #include<d3d11.h>  
  8.   
  9. #include<d3dx11.h>  
  10.   
  11. #include<DxErr.h>  
  12.   
  13.    
  14.   
  15.    
  16.   
  17. class Dx11DemoBase  
  18.   
  19. {  
  20.   
  21.     public:  
  22.   
  23.         Dx11DemoBase();  
  24.   
  25.         virtual ~Dx11DemoBase();  
  26.   
  27.    
  28.   
  29.         bool Initialize( HINSTANCE hInstance, HWND hwnd );  
  30.   
  31.         void Shutdown( );  
  32.   
  33.    
  34.   
  35.         bool CompileD3DShader( char* filePath, char* entry,  
  36.   
  37.                                char* shaderModel, ID3DBlob** buffer );  
  38.   
  39.    
  40.   
  41.         virtual bool LoadContent( );  
  42.   
  43.         virtual void UnloadContent( );  
  44.   
  45.    
  46.   
  47.         virtual void Update( float dt ) = 0;  
  48.   
  49.         virtual void Render( ) = 0;  
  50.   
  51.    
  52.   
  53.     protected:  
  54.   
  55.         HINSTANCE hInstance_;  
  56.   
  57.         HWND hwnd_;  
  58.   
  59.    
  60.   
  61.         D3D_DRIVER_TYPE driverType_;  
  62.   
  63.         D3D_FEATURE_LEVEL featureLevel_;  
  64.   
  65.    
  66.   
  67.         ID3D11Device* d3dDevice_;  
  68.   
  69.         ID3D11DeviceContext* d3dContext_;  
  70.   
  71.         IDXGISwapChain* swapChain_;  
  72.   
  73.         ID3D11RenderTargetView* backBufferTarget_;  
  74.   
  75. };  
  76.   
  77.    
  78.   
  79. #endif  


 

 

 

 

 

代码段七 Dx11DemoBase.cpp实现代码

 

 

[cpp] view plain copy print ?
  1. #include"Dx11DemoBase.h"  
  2.   
  3. #include<D3Dcompiler.h>  
  4.   
  5.    
  6.   
  7.    
  8.   
  9. Dx11DemoBase::Dx11DemoBase( ) : driverType_( D3D_DRIVER_TYPE_NULL ), featureLevel_( D3D_FEATURE_LEVEL_11_0 ),  
  10.   
  11.                                 d3dDevice_( 0 ), d3dContext_( 0 ), swapChain_( 0 ), backBufferTarget_( 0 )  
  12.   
  13. {  
  14.   
  15.    
  16.   
  17. }  
  18.   
  19.    
  20.   
  21.    
  22.   
  23. Dx11DemoBase::~Dx11DemoBase( )  
  24.   
  25. {  
  26.   
  27.     Shutdown( );  
  28.   
  29. }  
  30.   
  31.    
  32.   
  33.    
  34.   
  35. bool Dx11DemoBase::Initialize( HINSTANCE hInstance, HWND hwnd )  
  36.   
  37. {  
  38.   
  39.     hInstance_ = hInstance;  
  40.   
  41.     hwnd_ = hwnd;  
  42.   
  43.    
  44.   
  45.     RECT dimensions;  
  46.   
  47.     GetClientRect( hwnd, &dimensions );  
  48.   
  49.    
  50.   
  51.     unsigned int width = dimensions.right - dimensions.left;  
  52.   
  53.     unsigned int height = dimensions.bottom - dimensions.top;  
  54.   
  55.    
  56.   
  57.     D3D_DRIVER_TYPE driverTypes[] =  
  58.   
  59.     {  
  60.   
  61.         D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_SOFTWARE  
  62.   
  63.     };  
  64.   
  65.    
  66.   
  67.     unsigned int totalDriverTypes = ARRAYSIZE( driverTypes );  
  68.   
  69.    
  70.   
  71.     D3D_FEATURE_LEVEL featureLevels[] =  
  72.   
  73.     {  
  74.   
  75.         D3D_FEATURE_LEVEL_11_0,  
  76.   
  77.         D3D_FEATURE_LEVEL_10_1,  
  78.   
  79.         D3D_FEATURE_LEVEL_10_0  
  80.   
  81.     };  
  82.   
  83.    
  84.   
  85.     unsigned int totalFeatureLevels = ARRAYSIZE( featureLevels );  
  86.   
  87.    
  88.   
  89.     DXGI_SWAP_CHAIN_DESC swapChainDesc;  
  90.   
  91.     ZeroMemory( &swapChainDesc, sizeof( swapChainDesc ) );  
  92.   
  93.     swapChainDesc.BufferCount = 1;  
  94.   
  95.     swapChainDesc.BufferDesc.Width = width;  
  96.   
  97.     swapChainDesc.BufferDesc.Height = height;  
  98.   
  99.     swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;  
  100.   
  101.     swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;  
  102.   
  103.     swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;  
  104.   
  105.     swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;  
  106.   
  107.     swapChainDesc.OutputWindow = hwnd;  
  108.   
  109.     swapChainDesc.Windowed = true;  
  110.   
  111.     swapChainDesc.SampleDesc.Count = 1;  
  112.   
  113.     swapChainDesc.SampleDesc.Quality = 0;  
  114.   
  115.    
  116.   
  117.     unsigned int creationFlags = 0;  
  118.   
  119.    
  120.   
  121. #ifdef _DEBUG  
  122.   
  123.     creationFlags |= D3D11_CREATE_DEVICE_DEBUG;  
  124.   
  125. #endif  
  126.   
  127.    
  128.   
  129.     HRESULT result;  
  130.   
  131.     unsigned int driver = 0;  
  132.   
  133.    
  134.   
  135.     for( driver = 0; driver < totalDriverTypes; ++driver )  
  136.   
  137.     {  
  138.   
  139.         result = D3D11CreateDeviceAndSwapChain( 0, driverTypes[driver], 0, creationFlags,  
  140.   
  141.                                                 featureLevels, totalFeatureLevels,  
  142.   
  143.                                                 D3D11_SDK_VERSION, &swapChainDesc, &swapChain_,  
  144.   
  145.                                                 &d3dDevice_, &featureLevel_, &d3dContext_ );  
  146.   
  147.    
  148.   
  149.         if( SUCCEEDED( result ) )  
  150.   
  151.         {  
  152.   
  153.             driverType_ = driverTypes[driver];  
  154.   
  155.             break;  
  156.   
  157.         }  
  158.   
  159.     }  
  160.   
  161.    
  162.   
  163.     if( FAILED( result ) )  
  164.   
  165.     {  
  166.   
  167.         DXTRACE_MSG( "创建 Direct3D 设备失败!" );  
  168.   
  169.         return false;  
  170.   
  171.     }  
  172.   
  173.    
  174.   
  175.     ID3D11Texture2D* backBufferTexture;  
  176.   
  177.    
  178.   
  179.     result = swapChain_->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&backBufferTexture );  
  180.   
  181.    
  182.   
  183.     if( FAILED( result ) )  
  184.   
  185.     {  
  186.   
  187.         DXTRACE_MSG( "获取交换链后台缓存失败!" );  
  188.   
  189.         return false;  
  190.   
  191.     }  
  192.   
  193.    
  194.   
  195.     result = d3dDevice_->CreateRenderTargetView( backBufferTexture, 0, &backBufferTarget_ );  
  196.   
  197.    
  198.   
  199.     if( backBufferTexture )  
  200.   
  201.         backBufferTexture->Release( );  
  202.   
  203.    
  204.   
  205.     if( FAILED( result ) )  
  206.   
  207.     {  
  208.   
  209.         DXTRACE_MSG( "创建渲染目标视图失败!" );  
  210.   
  211.         return false;  
  212.   
  213.     }  
  214.   
  215.    
  216.   
  217.     d3dContext_->OMSetRenderTargets( 1, &backBufferTarget_, 0 );  
  218.   
  219.    
  220.   
  221.     D3D11_VIEWPORT viewport;  
  222.   
  223.     viewport.Width = static_cast<float>(width);  
  224.   
  225.     viewport.Height = static_cast<float>(height);  
  226.   
  227.     viewport.MinDepth = 0.0f;  
  228.   
  229.     viewport.MaxDepth = 1.0f;  
  230.   
  231.     viewport.TopLeftX = 0.0f;  
  232.   
  233.     viewport.TopLeftY = 0.0f;  
  234.   
  235.    
  236.   
  237.     d3dContext_->RSSetViewports( 1, &viewport );  
  238.   
  239.    
  240.   
  241.     return LoadContent( );  
  242.   
  243. }  
  244.   
  245.    
  246.   
  247.    
  248.   
  249. bool Dx11DemoBase::CompileD3DShader( char* filePath, char* entry, char* shaderModel, ID3DBlob** buffer )  
  250.   
  251. {  
  252.   
  253.     DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;  
  254.   
  255.    
  256.   
  257. #if defined( DEBUG ) || defined( _DEBUG )  
  258.   
  259.     shaderFlags |= D3DCOMPILE_DEBUG;  
  260.   
  261. #endif  
  262.   
  263.    
  264.   
  265.     ID3DBlob* errorBuffer = 0;  
  266.   
  267.     HRESULT result;  
  268.   
  269.    
  270.   
  271.     result = D3DX11CompileFromFile( filePath, 0, 0, entry, shaderModel,  
  272.   
  273.         shaderFlags, 0, 0, buffer, &errorBuffer, 0 );  
  274.   
  275.    
  276.   
  277.     if( FAILED( result ) )  
  278.   
  279.     {  
  280.   
  281.         if( errorBuffer != 0 )  
  282.   
  283.         {  
  284.   
  285.             OutputDebugStringA( ( char* )errorBuffer->GetBufferPointer( ) );  
  286.   
  287.             errorBuffer->Release( );  
  288.   
  289.         }  
  290.   
  291.    
  292.   
  293.         return false;  
  294.   
  295.     }  
  296.   
  297.       
  298.   
  299.     if( errorBuffer != 0 )  
  300.   
  301.         errorBuffer->Release( );  
  302.   
  303.    
  304.   
  305.     return true;  
  306.   
  307. }  
  308.   
  309.    
  310.   
  311.    
  312.   
  313. bool Dx11DemoBase::LoadContent( )  
  314.   
  315. {  
  316.   
  317.     //重载,进行相关实现  
  318.   
  319.     return true;  
  320.   
  321. }  
  322.   
  323.    
  324.   
  325.    
  326.   
  327. void Dx11DemoBase::UnloadContent( )  
  328.   
  329. {  
  330.   
  331.     //重载,进行相关实现  
  332.   
  333. }  
  334.   
  335.    
  336.   
  337.    
  338.   
  339. void Dx11DemoBase::Shutdown( )  
  340.   
  341. {  
  342.   
  343.     UnloadContent( );  
  344.   
  345.    
  346.   
  347.     if( backBufferTarget_ ) backBufferTarget_->Release( );  
  348.   
  349.     if( swapChain_ ) swapChain_->Release( );  
  350.   
  351.     if( d3dContext_ ) d3dContext_->Release( );  
  352.   
  353.     if( d3dDevice_ ) d3dDevice_->Release( );      
  354.   
  355.    
  356.   
  357.     backBufferTarget_ = 0;  
  358.   
  359.     swapChain_ = 0;  
  360.   
  361.     d3dContext_ = 0;  
  362.   
  363.     d3dDevice_ = 0;  
  364.   
  365. }  


 

 

 

 

 

 

最后的压轴依旧是永远最重要的main函数,其实现代码如下代码段八:

 

代码段八  main.cpp实现代码

 

[cpp] view plain copy print ?
  1. #include<Windows.h>  
  2.   
  3. #include<memory>  
  4.   
  5. #include"Texture2DDemo.h"  
  6.   
  7.    
  8.   
  9.    
  10.   
  11. LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );  
  12.   
  13.    
  14.   
  15. //****wWinMain函数,程序入口点函数**************************************   
  16.   
  17.    
  18.   
  19. int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow )  
  20.   
  21. {  
  22.   
  23.     UNREFERENCED_PARAMETER( prevInstance );  
  24.   
  25.     UNREFERENCED_PARAMETER( cmdLine );  
  26.   
  27.    
  28.   
  29.     WNDCLASSEX wndClass = { 0 };  
  30.   
  31.     wndClass.cbSize = sizeof( WNDCLASSEX ) ;  
  32.   
  33.     wndClass.style = CS_HREDRAW | CS_VREDRAW;  
  34.   
  35.     wndClass.lpfnWndProc = WndProc;  
  36.   
  37.     wndClass.hInstance = hInstance;  
  38.   
  39.     wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );  
  40.   
  41.     wndClass.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );  
  42.   
  43.     wndClass.lpszMenuName = NULL;  
  44.   
  45.     wndClass.lpszClassName = "DX11BookWindowClass";  
  46.   
  47.    
  48.   
  49.     if( !RegisterClassEx( &wndClass ) )  
  50.   
  51.         return -1;  
  52.   
  53.    
  54.   
  55.     RECT rc = { 0, 0, 640, 480 };  
  56.   
  57.     AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );  
  58.   
  59.    
  60.   
  61.     HWND hwnd = CreateWindowA( "DX11BookWindowClass""2D纹理映射演示demo", WS_OVERLAPPEDWINDOW,  
  62.   
  63.                                 CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,  
  64.   
  65.                                 NULL, NULL, hInstance, NULL );  
  66.   
  67.    
  68.   
  69.     if( !hwnd )  
  70.   
  71.         return -1;  
  72.   
  73.    
  74.   
  75.     ShowWindow( hwnd, cmdShow );  
  76.   
  77.    
  78.   
  79.     TextureDemo demo;  
  80.   
  81.    
  82.   
  83.     // Demo的初始化  
  84.   
  85.     bool result = demo.Initialize( hInstance, hwnd );  
  86.   
  87.    
  88.   
  89.     if( result == false )  
  90.   
  91.         return -1;  
  92.   
  93.    
  94.   
  95.     MSG msg = { 0 };  
  96.   
  97.    
  98.   
  99.     while( msg.message != WM_QUIT )  
  100.   
  101.     {  
  102.   
  103.         if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )  
  104.   
  105.         {  
  106.   
  107.             TranslateMessage( &msg );  
  108.   
  109.             DispatchMessage( &msg );  
  110.   
  111.         }  
  112.   
  113.    
  114.   
  115.         // 更新以及绘制  
  116.   
  117.         demo.Update( 0.0f );  
  118.   
  119.         demo.Render( );  
  120.   
  121.     }  
  122.   
  123.    
  124.   
  125.     // Demo善后工作  
  126.   
  127.     demo.Shutdown( );  
  128.   
  129.    
  130.   
  131.     return static_cast<int>( msg.wParam );  
  132.   
  133. }  
  134.   
  135.    
  136.   
  137.    
  138.   
  139. //****消息处理函数***********************************   
  140.   
  141. LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )  
  142.   
  143. {  
  144.   
  145.     PAINTSTRUCT paintStruct;  
  146.   
  147.     HDC hDC;  
  148.   
  149.    
  150.   
  151.     switch( message )  
  152.   
  153.     {  
  154.   
  155.         case WM_PAINT:  
  156.   
  157.             hDC = BeginPaint( hwnd, &paintStruct );  
  158.   
  159.             EndPaint( hwnd, &paintStruct );  
  160.   
  161.             break;  
  162.   
  163.    
  164.   
  165.         case WM_DESTROY:  
  166.   
  167.             PostQuitMessage( 0 );  
  168.   
  169.             break;  
  170.   
  171.    
  172.   
  173.         default:  
  174.   
  175.             return DefWindowProc( hwnd, message, wParam, lParam );  
  176.   
  177.     }  
  178.   
  179.    
  180.   
  181.     return 0;  
  182.   
  183. }  


 

 

 

最后编译及运行,我们可以得到如下演示2D纹理映射的窗口:

 

 

 

 

 

本节到这里就结束了。

 

 

 

 

 本篇文章配套源代码请点击这里下载:【Visual C++】Note_Code_30

 

 

 

 

 

感谢一直支持【Visual C++】游戏开发笔记系列专栏的朋友们。

【Visual C++】游戏开发 系列文章才刚刚展开一点而已,因为游戏世界实在是太博大精深了~

但我们不能着急,得慢慢打好基础。做学问最忌好高骛远,不是吗?

 

浅墨希望看到大家的留言,希望与大家共同交流,希望得到睿智的评论(即使是批评)。

你们的支持是我写下去的动力~

 

精通游戏开发的路还很长很长,非常希望能和大家一起交流,共同学习,共同进步。

大家看过后觉得值得一看的话,可以顶一下这篇文章,你们的支持是我继续写下去的动力~

如果文章中有什么疏漏的地方,也请大家指正。也希望大家可以多留言来和我探讨相关的问题。

最后,谢谢你们一直的支持~~~

                                               

 

                                                  ——————————浅墨于2012年7月30日

这篇关于【Visual C++】游戏开发笔记三十 DirectX11 2D纹理映射知识全攻略的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/927499

相关文章

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

C++的模板(八):子系统

平常所见的大部分模板代码,模板所传的参数类型,到了模板里面,或实例化为对象,或嵌入模板内部结构中,或在模板内又派生了子类。不管怎样,最终他们在模板内,直接或间接,都实例化成对象了。 但这不是唯一的用法。试想一下。如果在模板内限制调用参数类型的构造函数会发生什么?参数类的对象在模板内无法构造。他们只能从模板的成员函数传入。模板不保存这些对象或者只保存他们的指针。因为构造函数被分离,这些指针在模板外

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

AssetBundle学习笔记

AssetBundle是unity自定义的资源格式,通过调用引擎的资源打包接口对资源进行打包成.assetbundle格式的资源包。本文介绍了AssetBundle的生成,使用,加载,卸载以及Unity资源更新的一个基本步骤。 目录 1.定义: 2.AssetBundle的生成: 1)设置AssetBundle包的属性——通过编辑器界面 补充:分组策略 2)调用引擎接口API

C++工程编译链接错误汇总VisualStudio

目录 一些小的知识点 make工具 可以使用windows下的事件查看器崩溃的地方 dumpbin工具查看dll是32位还是64位的 _MSC_VER .cc 和.cpp 【VC++目录中的包含目录】 vs 【C/C++常规中的附加包含目录】——头文件所在目录如何怎么添加,添加了以后搜索头文件就会到这些个路径下搜索了 include<> 和 include"" WinMain 和

C/C++的编译和链接过程

目录 从源文件生成可执行文件(书中第2章) 1.Preprocessing预处理——预处理器cpp 2.Compilation编译——编译器cll ps:vs中优化选项设置 3.Assembly汇编——汇编器as ps:vs中汇编输出文件设置 4.Linking链接——链接器ld 符号 模块,库 链接过程——链接器 链接过程 1.简单链接的例子 2.链接过程 3.地址和

C++必修:模版的入门到实践

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C++学习 贝蒂的主页:Betty’s blog 1. 泛型编程 首先让我们来思考一个问题,如何实现一个交换函数? void swap(int& x, int& y){int tmp = x;x = y;y = tmp;} 相信大家很快就能写出上面这段代码,但是如果要求这个交换函数支持字符型

《offer来了》第二章学习笔记

1.集合 Java四种集合:List、Queue、Set和Map 1.1.List:可重复 有序的Collection ArrayList: 基于数组实现,增删慢,查询快,线程不安全 Vector: 基于数组实现,增删慢,查询快,线程安全 LinkedList: 基于双向链实现,增删快,查询慢,线程不安全 1.2.Queue:队列 ArrayBlockingQueue:

[职场] 公务员的利弊分析 #知识分享#经验分享#其他

公务员的利弊分析     公务员作为一种稳定的职业选择,一直备受人们的关注。然而,就像任何其他职业一样,公务员职位也有其利与弊。本文将对公务员的利弊进行分析,帮助读者更好地了解这一职业的特点。 利: 1. 稳定的职业:公务员职位通常具有较高的稳定性,一旦进入公务员队伍,往往可以享受到稳定的工作环境和薪资待遇。这对于那些追求稳定的人来说,是一个很大的优势。 2. 薪资福利优厚:公务员的薪资和