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()));
HR(m_pd3dDevice->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), nullptr, m_pPixelShader.GetAddressOf()));
return true;
}
-
4、创建好了,那然后是不是输入数据呀?输入的数据是不是要创建呀?
-
1、顶点缓冲区的作用是,将顶点数组以缓冲区
ID3D11Buffer
的形式提供给输入装配阶段。 -
//看看这个 struct VertexPosColor//用于输入的结构体 { DirectX::XMFLOAT3 pos; DirectX::XMFLOAT4 color; //顶点缓冲区的本质是二进制流,为了能够建立C++结构体与HLSL结构体的对应关系, //需要使用ID3D11InputLayout输入布局来描述每一个成员的用途、语义、大小等信息 static const D3D11_INPUT_ELEMENT_DESC inputLayout[2]; }; // 设置三角形顶点 VertexPosColor vertices[] = { { XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }, { XMFLOAT3(sqrt(3.0) / 2.0f, 0.5f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f)}, { XMFLOAT3(-sqrt(3.0) / 2.0f, 0.5f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }, { XMFLOAT3(sqrt(3.0) / 2.0f, -0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }, { XMFLOAT3(-sqrt(3.0) /2.0f, -0.5f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) }, { XMFLOAT3(0.0f, -1.0f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) } }; // 要创建顶点缓冲区,首先需要填充好缓冲区描述D3D11_BUFFER_DESC(1) // 设置顶点缓冲区描述 D3D11_BUFFER_DESC vbd; ZeroMemory(&vbd, sizeof(vbd));//ZeroMemory其作用是用0来填充一块内存区域,将结构中所有字节置0,初始化重置,没有用的参数必须要设为零 vbd.Usage = D3D11_USAGE_IMMUTABLE;//CPU和GPU的读写权限相关 vbd.ByteWidth = sizeof vertices;//数据字节数 vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;//缓冲区类型的标志 vbd.CPUAccessFlags = 0;//CPU读写权限的指定 //还需要使用D3D11_SUBRESOURCE_DATA结构体来指定要用来初始化的数据(2) // 新建顶点缓冲区 D3D11_SUBRESOURCE_DATA InitData; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = vertices;//初始化数据 //顶点缓冲区的作用是,将顶点数组以缓冲区ID3D11Buffer的形式提供给输入装配阶段(3) //最后通过ID3D11Device::CreateBuffer来创建一个顶点缓冲区 //([In]顶点缓冲区描述,[In]子资源数据,[Out] 获取缓冲区) HR(m_pd3dDevice->CreateBuffer(&vbd, &InitData, m_pVertexBuffer.GetAddressOf()));
-
5、上面不是说创建数据吗,现在好了,那就可以在渲染管线输入装配阶段设置该顶点缓冲区了
-
看看上面的 [Out] 获取缓冲区 和下面的 [In]指向缓冲区数组的指针
-
// 输入装配阶段的顶点缓冲区设置 UINT stride = sizeof(VertexPosColor); // 跨越字节数 UINT offset = 0; // 起始偏移量 //创建好顶点缓冲区后,就可以在渲染管线输入装配阶段设置该顶点缓冲区了(4) //([In]输入槽索引,[In]缓冲区数目,[In]指向缓冲区数组的指针, // [In]一个数组,规定了对所有缓冲区每次读取的字节数分别是多少,[In]一个数组,规定了对所有缓冲区的初始字节偏移量) m_pd3dImmediateContext->IASetVertexBuffers(0, 1, m_pVertexBuffer.GetAddressOf(), &stride, &offset);
-
6、你都设置顶点缓冲区了,那是不是也告诉一下别人怎么装配吧
-
图元类型 含义 D3D11_PRIMITIVE_TOPOLOGY_POINTLIST 按一系列点进行装配 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP 按一系列线段进行装配,每相邻两个顶点(或索引数组相邻的两个索引对应的顶点)构成一条线段 D3D11_PRIMITIVE_TOPOLOGY_LINELIST 按一系列线段进行装配,每两个顶点(或索引数组每两个索引对应的顶点)构成一条线段 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP 按一系列三角形进行装配,每相邻三个顶点(或索引数组相邻的三个索引对应的顶点)构成一个三角形 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST 按一系列三角形进行装配,每三个顶点(或索引数组每三个索引对应的顶点)构成一个三角形 D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ 每4个顶点为一组,只绘制第2个顶点与第3个顶点的连线(或索引数组每4个索引为一组,只绘制索引模4余数为2和3的连线) D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ 绘制除了最开始和结尾的所有线段(或者索引数组不绘制索引0和1的连线,以及n-2和n-1的连线) D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ 每6个顶点为一组,只绘制第1、3、5个顶点构成的三角形(或索引数组每6个索引为一组,只绘制索引模6余数为0, 2, 4的三角形) D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ 抛弃所有索引模2为奇数的顶点或索引,剩余的进行Triangle Strip的绘制 -
// 设置图元类型(5) m_pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
-
7、好了,什么鬼形状ok了,那不得将着色器绑定到渲染管线
-
-
为什么呢?
-
顶点着色器
-
例如,想象您的顶点缓冲区指定了一种顶点颜色作为顶点属性,您的三角形有两个顶点指定为白色,一个顶点指定为黑色。顶点着色器将把这些顶点颜色传递到它的 输出,传递到管道中的以下块中。然后,一个与三角形中某个位置相对应的片段将收到一个具有一定灰度的颜色:白色顶点和黑色顶点颜色的插值。这种灰度对于接 近白色顶点的片段会更亮,对于接近黑色顶点的片段会更黑。
-
这些插入的未处理的片段【所谓未处理是指片段还不具有颜色】然后作为输入发送到片段着色器,后者使用该数据建立最终的像素颜色。
-
顶点着色器运作方式如下:当渲染一个顶点时,API会执行你在顶点着色器中所写的指令。依靠这种方法,你可以自己控制每个顶点,包括渲染,确定位置,是否显示在屏幕上
-
像素着色器
-
像顶点着色器一样,片段着色器也是在 GPU 上运行的小程序。从名称可以看出,像素着色器处理片段——它们负责输出每个呈现的三角形像素的最终像素颜色。
基本而言,它的工作原理如下:像素着色器以输入的形式收到顶点着色器通过管道传递的所有这些片段。如上所述,到达片段着色器的片段是顶点着色器的顶点属性输出的插入版本。
-
-
// 将着色器绑定到渲染管线(6) //给渲染管线某一着色阶段设置对应的着色器 //([In]顶点/像素着色器,[In_Opt]忽略,[In]忽略) m_pd3dImmediateContext->VSSetShader(m_pVertexShader.Get(), nullptr, 0); m_pd3dImmediateContext->PSSetShader(m_pPixelShader.Get(), nullptr, 0);
-
8、从输入装配阶段开始,该绘制的进行将会经历一次完整的渲染管线阶段,直到输出合并阶段为止
-
开始绘制了
-
void GameApp::DrawScene() { //assert主要用于程序的测试阶段 //当assert测试不满足条件时,程序会中断并退出,同时给出中断提示信息 //不像if,不满足的,则继续执行下面的代码 assert(m_pd3dImmediateContext); //设备上下文 assert(m_pSwapChain); //背景颜色创建 static float black[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; // RGBA = (0,0,0,255) m_pd3dImmediateContext->ClearRenderTargetView(m_pRenderTargetView.Get(), black); m_pd3dImmediateContext->ClearDepthStencilView(m_pDepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); // 绘制三角形([In]需要绘制的顶点数目(VertexCount),[In]起始顶点索引(StartVertexLocation)) //通过指定VertexCount和StartVertexLocation的值我们可以按顺序绘制从索引StartVertexLocation到StartVertexLocation + VertexCount - 1的顶点 m_pd3dImmediateContext->Draw(6, 0); HR(m_pSwapChain->Present(0, 0)); }
-
渲染管线
-
一、输入装配阶段
-
- 1、顶点
- 2、图元拓扑(该作业用这3个)
-
-
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP
-
按一系列三角形进行装配,每相邻三个顶点(或索引数组相邻的三个索引对应的顶点)构成一个三角形
-
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
-
按一系列三角形进行装配,每三个顶点(或索引数组每三个索引对应的顶点)构成一个三角形
-
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP
-
按一系列线段进行装配,每相邻两个顶点(或索引数组相邻的两个索引对应的顶点)构成一条线段
-
- 3、索引
二、顶点着色器阶段
- 三、光栅化阶段
-
- 1、视口变换
-
- x,y坐标将以像素为单位。z一般不变
- 2、背面消隐
-
- 顶点顺时针排列(存在法线一面)
- 3d物体为实心,朝前面会挡住朝后面
- 3、顶点插值
- 四、像素着色器阶段
-
- 1、输入插值后的顶点属性,然后计算出一个颜色
- 五、输出合并阶段
作业实现分析&代码
- 方法一
- D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP
- 按一系列三角形进行装配,每相邻三个顶点(或索引数组相邻的三个索引对应的顶点)构成一个三角形
// 绘制三角形
m_pd3dImmediateContext->Draw(6, 0);
// 设置三角形顶点
{ XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3.0) / 4.0f, 0.25f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f)},
{ XMFLOAT3((float)-sqrt(3.0) / 4.0f, 0.25f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3.0) / 4.0f, -0.25f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3.0) /4.0f, -0.25f, 0.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(0.0f, -0.5f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) }
// 设置图元类型,设定输入布局
m_pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
- 方法二
- D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST
- 按一系列三角形进行装配,每三个顶点(或索引数组每三个索引对应的顶点)构成一个三角形
// 绘制三角形
m_pd3dImmediateContext->Draw(18, 0);
// 设置三角形顶点
{ XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3( (float) - sqrt(3) / 6.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)},
{ XMFLOAT3((float)sqrt(3) / 6.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3) / 6.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3) / 3.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3) / 3.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3) / 6.0f, -0.5f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3) / 6, -0.5f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3) / 6, -0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3) / 6.0f, -0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3) / 3.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3) / 3.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3) / 6.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }
// 设置图元类型,设定输入布局
m_pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
- 方法三
- D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP
- 按一系列线段进行装配,每相邻两个顶点(或索引数组相邻的两个索引对应的顶点)构成一条线段
// 绘制三角形
m_pd3dImmediateContext->Draw(7, 0);
// 设置三角形顶点
{ XMFLOAT3( (float) - sqrt(3) / 6.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f)},
{ XMFLOAT3((float)sqrt(3) / 6.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3) / 3.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3((float)sqrt(3) / 6.0f, -0.5f, 0.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3) / 6, -0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3) / 3.0f, 0.0f, 0.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3((float)-sqrt(3) / 6.0f, 0.5f, 0.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) }
// 设置图元类型,设定输入布局
m_pd3dImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
思考&小结
- 对于dx11的学习,在刚刚开始看xjun师兄的博客,完全是一头雾水,代码都不知道从那里看起来,刚刚开始 看就像是看底层代码一样,头晕。不过呢,现在渐渐看的有点明白了。学习的路线是首先在哔哩哔哩上找Win32的教程,然后打开xjun师兄的代码,对着教程一句句分析xjun师兄的代码,然后将理解注释在代码上面,一步步探索初始化的整个流程,对一些其他的,则是上网去搜索,看明白,注释。或许到这里还是单单Win32的知识。
- 了解基本窗口后,则是对整个渲染管线的理解。这里呢,我是结合龙书一起看的,同时带上game101的知识,也是是一步步去理解整个流程,对每一个代码进行分析,知道它存在的作用,同时进行尝试修改运行,看自己是否真的了解其意义,当然,在我完全了解的情况下,会尝试着自己去初始化。
- 总的来说呢,或许这学习真的不用去着急,不要急的去看什么更难的东西,首先还是一步步来,否则就像我前几天一样,想跳过Win32去学习,结果呢是完全晕。现在好了,有了自己学习的方向,不在是那样的看也看不懂,放也不放弃,效率低。怎么说呢,万事开头难,可能后面更难,不过也没关系,像我上次说的那样,船到桥头自然直,只要不放弃,总会有办法的,不是吗?坚持就是胜利!!!