DX11 渲染管线&六边形绘制
目录
题目&要求
• 练习:xjun 01/02 DirectX11 初始化的习题
• 真作业:用 DX 画一个等六边形
• 申请github账号,用Git管理以后的作业和周记,并上传仓库到Github(推荐使用vs上传),并且要写进文档中,文 档也是评分内容之一
问题描述&解决
-
可能存在一个运行问题
-
- 具体情况是一些警告:
- 文件包含在偏移0*93处开始的字符,该字符在当前原字符集中无效(代码页 65001)
- 我这边是处理完了,不过不知道传上去会不会又出现
- 处理方法:文件->高级保存选项->选择编码Unicode(初始化的时候已经选择Unicode字符集了)
- 不知道这个和错误是不是有关联
-
在这里简单说一下当时存在的问题
-
一、对看xjun师兄的初始化代码感到非常艰难_。
-
- 1、推荐先对Win32 API有基本了解再来学习dx11初始化。
- 2、多利用搜索引擎,不会就搜索(你有广大的网友),同时结合龙书一起看。
- 3、已经有了初步的了解。
-
二、窗口问题。
-
- 刚刚开始对图形变形感到不解。(师兄给出了解释),已明白。
- 不过现在只是改变窗口来保持图形,还暂时不知道怎样才能改变窗口,不改变图形。
-
三、图元拓扑
-
- 1、因为顺序的问题(背面消隐),经常什么都没有(师兄也说过)。
- 2、做六边形,只是出现三角形。
- 好像与这代码有关
m_pd3dImmediateContext->Draw(18, 0);
整体思路(渲染管线)
-
首先简单了解什么是设备和设备上下文
-
-
设备(Device)
ID3DllDevice 接口提供了许多方法来创建着色器程序对象、资源、状态对象和查询对象(等等)。它还提供了检查某些硬件特性的可用性的方法,以及许多与诊断和调试相关的方法。通常,可以将设备看作应用程序中使用的各种资源的提供者。
对应下面:
创建顶点着色器
创建顶点布局
创建像素着色器
创建一个顶点缓冲区
-
设备上下文(Device Context)
虽然设备(device) 用于创建管道使用的各种资源,但为了实际使用这些资源并操纵管道本身,我们将使用设备上下文(device context) 。设备上下文用于将创建的资源、着色器对象和状态对象绑定到管道。它们也被用来控制渲染和计算管道的执行。此外,它们还提供了操作设备创建的资源的方法。通常,设备上下文可以被看作是设备产生的资源的消费者,设备作为处理管道的接口。
设备上下文在ID3DllDeviceContext接口中实现。对应下面:
设置顶点缓冲区
设置图元类型
设定输入布局
着色器绑定到渲染管线
-
-
流程
-
- 顶点缓冲区的本质是二进制流,为了能够建立C++结构体与HLSL结构体的对应关系,需要使用
ID3D11InputLayout
输入布局来描述每一个成员的用途、语义、大小等信息。 - 1、那么来建立C++结构体与HLSL结构体的对应关系
- 顶点缓冲区的本质是二进制流,为了能够建立C++结构体与HLSL结构体的对应关系,需要使用
在HLSL中,用于输入的结构体为:
struct VertexIn
{
//POSITION(position)
//用作输入:对象空间中的顶点位置。
//用作输出:顶点在齐次空间中的位置。
//通过(x,y,z)除以w来计算在屏幕空间中的位置。
//每个(D3D9)顶点着色器都必须用这个语义写出一个参数。
//描述该变量是一个坐标点
float3 pos : POSITION;
//漫反射或镜面颜色。
float4 color : COLOR;
};
该项目与之对应的C++结构体为:
struct VertexPosColor
{
DirectX::XMFLOAT3 pos;
DirectX::XMFLOAT4 color;
static const D3D11_INPUT_ELEMENT_DESC inputLayout[2];
};
-
- D3D11_INPUT_ELEMENT_DESC inputLayout[2];是什么?
- 就是上面说的顶点缓冲区的本质是二进制流,为了能够建立C++结构体与HLSL结构体的对应关系,需要使用
ID3D11InputLayout
输入布局来描述每一个成员的用途、语义、大小等信息。
//input 基础元素
//使用D3D11_INPUT_ELEMENT_DESC结构体来描述待传入结构体中每个成员的具体信息
//(语义名,语义索引,数据格式,输入槽索引(0-15),初始位置(字节偏移量),输入类型,忽略)
//通过语义、数据类型和起始偏移量,我们就可以建立起C++顶点缓冲区数据和HLSL顶点之间的联系(1)
//D3D11_INPUT_PER_VERTEX_DATA为按每个顶点数据输入
//D3D11_INPUT_PER_INSTANCE_DATA则是按每个实例数据输入。
const D3D11_INPUT_ELEMENT_DESC GameApp::VertexPosColor::inputLayout[2] = {
{
"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{
"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
- 2、联系已经建立了,那是不是该创建输入布局,要不然怎么输入对不对?
//着色器或特效相关的初始化
bool GameApp::InitEffect(){
ComPtr<ID3DBlob> blob;
// 创建并绑定顶点布局(2)
// ([In]输入布局描述,[In]上述数组元素个数,[In]顶点着色器字节码,[In]顶点着色器字节码长度,[out]获取的输入布局)
// typedef T InterfaceType ;InterfaceType *ptr_;
HR(m_pd3dDevice->CreateInputLayout(VertexPosColor::inputLayout, ARRAYSIZE(VertexPosColor::inputLayout),
blob->GetBufferPointer(), blob->GetBufferSize(), m_pVertexLayout.GetAddressOf()));
}
//[out]获取的输入布局 上面和下面的联系
//然后是下面设备上下文那使用刚创建好的输入布局
void ID3D11DeviceContext::IASetInputLayout(
ID3D11InputLayout *pInputLayout); // [In]输入布局
m_pd3dImmediateContext->IASetInputLayout(m_pVertexLayout.Get());
-
3、顶点布局创建好了,那顺便顶点/像素着色器的也创建一下
-
从D3D设备可以创建出6种着色器:
方法 着色器类型 描述 ID3D11Device::CreateVertexShader ID3D11VertexShader 顶点着色器 ID3D11Device::CreateHullShader ID3D11HullShader 外壳着色器 ID3D11Device::CreateDomainShader ID3D11DomainShader 域着色器 ID3D11Device::CreateComputeShader ID3D11ComputeShader 计算着色器 ID3D11Device::CreateGeometryShader ID3D11GeometryShader 几何着色器 ID3D11Device::CreatePixelShader ID3D11PixelShader 像素着色器
//着色器或特效相关的初始化
bool GameApp::InitEffect()
{
ComPtr<ID3DBlob> blob;
// [In]csoFileNameInOut 编译好的着色器二进制文件(.cso),若有指定则优先寻找该文件并读取
// [In]hlslFileName 着色器代码,若未找到着色器二进制文件则编译着色器代码
// [In]entryPoint 入口点(指定开始的函数)
// [In]shaderModel 着色器模型,格式为"*s_5_0",*可以为c,d,g,h,p,v之一
// [Out]ppBlobOut 输出着色器二进制信息
// HR(x)错误原因追踪工具
HR(CreateShaderFromFile(L"HLSL\\Triangle_VS.cso", L"HLSL\\Triangle_VS.hlsl", "VS", "vs_5_0", blob.ReleaseAndGetAddressOf()));
// [Out]ppBlobOut 输出着色器二进制信息(上下两个联系)
// 创建顶点着色器(4)
//HRESULT ID3D11Device::CreateVertexShader(
//const void *pShaderBytecode, // [In]着色器字节码
//SIZE_T BytecodeLength, // [In]字节码长度
//ID3D11ClassLinkage *pClassLinkage, // [In_Opt]忽略
//ID3D11VertexShader **ppVertexShader); // [Out]获取顶点着色器
HR(m_pd3dDevice->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, m_pVertexShader.GetAddressOf()));
.....
// 创建像素着色器(4)
HR(CreateShaderFromFile(L"HLSL\\Triangle_PS.cso", L"HLSL\\Triangle_PS.hlsl", "PS", "ps_5_0", blob.ReleaseAndGetAddressOf()