05/29/2020
06/02/2020 后续补充-练习题
//引用库文件来编译hlsl文件
pragma comment(lib,"D3DCompiler.lib") //着色器编译器
编译着色器文件(.hlsl的文件)
运行期间编译着色器,生成字节码
HRESULT D3DCompileFromFile(
LPCWSTR pFileName,
CONST D3D_SHADER_MACRO* pDefines,
ID3DInclude* pInclude, //是否允许hlsl文件添加include
LPCSTR pEntrypoint, //入口函数名,比如"VS","PS","CS",表示
LPCSTR pTarget, //使用着色器模型,比如"vs_5_)"
UINT Flags1,
UINT Flags2,
ID3DBlob** ppCode, //获得着色器二进制块
ID3DBlob** ppErrorMsgs //错误信息的二级制块
);
- 入口函数名与hlsl文件中的着色器名字必须保持一致
//Triangle.hlsl
VertexOut VS(VertexIn vIn){
...} // 函数名与入口名字保持一致
- 着色器模型:如果显卡支持特性等级是11.0,使用Shader Model 5.0
- ppCode 表示返回的二级制文件
//运行期编译.hlsl文件
ID3DBlob** ppBlobOut; //返回的二进制文件
ID3DBlob* errorBlob;//错误的Blob
hr = D3DCompileFromFile("Triangle_VS.hlsl",nullptr,D3D_COMPILE_STANDARD_FILE_INCLUDE,
"VS",dwShaderFlags,0,ppBlobOut,&errorBlob); //获得一个编译好的着色器文件(.cso)
编译器产生对象,并在运行期加载(.cso文件)
visual studio 2017 自带hlsl的编译器,可以在编译的时候生成cso文件,然后再运行期加载
//运行期加载函数
HRESULT = S_OK;
//传递一个编译好的hlsl文件,文件名以(.cso)结尾
ID3DBlob** ppBlobOut; //返回的二进制文件
D3DReadFileBlob(cosFileNameInOut,ppBlobOut) == S_OK;
Device设备
创建着色器
HRESULT ID3D11Device::CreateVertexShader(
const void *pShaderBytecode, //着色器字节码
SIZE_T BytecodeLength, //字节码长度
ID3D11ClassLinkage* pClassLinkage, //
ID3D11VertexShader **ppVertexShader //获取顶点着色器
);
ComPtr<ID3DBlob> blob;
ComPtr<ID3D11VertexBuffer> mVertexShader;
md3dDevice->CreateVertexShader(blob->GetBufferPointer(),blob->GetBufferSize(),
nullptr,mVertexShader.GetAddressOf());
绑定输入布局
在HLSL中,用于输入结构体为:
//着色器文件HLSL
struct Vertexin
{
float3 pos:POSITION;
float4 color:COLOR;
};
#include <directxmath.h> //XMFLOAT3 数学库
//C++文件中
struct VertexPosColor
{
DirectX::XMFLOAT3 pos;
DirectX::XMFLOAT4 colr;
static const D3D11_INPUT_ELEMENT_DESC inputLayer[2]; //静态资源,可以提前赋值
};
如何建立对应关系
顶点缓冲区是二进制文件(Blob),为了建立C++结构体与HLSL结构体的对应关系,需要使用ID3D11InputLayer
- 输入布局来描述每一个成员的用途,语义,大小等信息
- C++的static const D3D11_INPUT_ELEMENT_DESC inputLayer[2]不属于结构体的成员,是为了方便描述布局关系的
描述输入布局
typedef struct D3D11_INPUT_ELEMENT_DESC
{
LPCSTR SemanticName; //语义名
UINT SemanticIndex; //语义索引
DXGI_FORMAT Format; //数据格式
UINT InputSlot; //输入槽索引(0-15)
UIINT AlignedByteOffset;//初始位置
D3D11_INPUT_CLASSIFICATION InputSlotClass; //输入类型
UINT InstanceDataStepRate; //忽略
} D3D11_INPUT_ELEMENT_DESC;
inputLayer[0] =
{
{
"POSITION", //看一下HLSL结构体
0,
DXGI_FORMAT_R32G32B32_FLOAT, //数据存储方式,3个Float的类型值
0,
0,
D3D11_INPUT_PER_VERTEX_DATA,
0
},
}
inputLayer[1] =
{
{
"COLOR",
0,
DXGI_FORMAT_R32G32B32A32_FLOAT, //4个Float的类型
0,
12, //初始位置 字节偏移量
D3D11_INPUT_PER_VERTEX_DATA,
0
},
}
创建输入布局 CreateInputLayer
HRESULT ID3D11Device::CreateInputLayer(
const D3D11_INPUT_ELEMENT_DESC* pInputElementDescs, //输入布局描述
UINT NumElements, //上述数组元素个数,2个
const void* pShaderBytecodeWithInputSignature, //着色器字节码
ID3D11InputLayer** ppInputLayout //获取输入布局
);
顶点缓冲区(Vertex Buffer)
- 顶点缓冲区把顶点数组以ID3D11Buffe