4.1.1 Direct3D Overview
DX9可以部分安装,DX11 就必须全部安装,因此使用某特性时,不再需要检查是不是安装对应模块。
4.1.2 COM
使用Component-Object Model.
Component Object Model (COM) is the technology that allows DirectX to be language independent and have backwards
compatibility. Direct3D programmers don’t need to know the details of COM and how it works; they need only to know how to
acquire COM interfaces and how to release them.
4.1.3 Textures and Data Resource Formats
DXGI_FORMAT_R8G8B8A8_TYPELESS 可以用typeless,表明并不存储特定格式的值
4.1.5 Depth Buffering
深度缓冲存了一张和屏幕像素一一对应的一张纹理,每个值范围0~1,0最近,1最远
Depth Texture
注意里面如果有用到Stencil,会附加到后面
4.1.6 Texture Resource Views
一张texture在使用之前,需要bind到对应的pipeline才能使用。
eg:use a texture as a render target and as a shader resource
需要先声明flag,D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE
然后创建对应的RS ,
a render target view (ID3D11RenderTargetView) and a shader resource view (ID3D11ShaderResourceView)
然后才能bind到pipeline。
Resource views essentially do two things: they tell Direct3D how the resource will be used (i.e., what stage of the pipeline you will bind it to), and if the resource format was specified as typeless at creation time, then we must now state the type when creating a view. Thus, with typeless formats, it is possible for the elements of a texture to be viewed as floating-point values in one pipeline stage and as integers in another
RS 主要做两件事,1.告诉Dx,这个资源会如何被使用,比如会用在pipeline哪个阶段,2.如果format被指定为typeless的,那创建view的时候,就必须确定好类型,因此,一个txture,就可以声明多个format的view
中间多一层view的目的是:“This allows validation and mapping in the runtime and driver to occur at view creation, minimizing type checking at bind-time.” 运行时和驱动中在view创建时才做,验证和对应, 最小化减少bind 时间。
4.1.7 Multisampling Theory
介绍MSAA和SSAA,这里介绍的比较简单
可以再参考 https://www.cnblogs.com/ghl_carmack/p/8245032.html
MSAA(多重采样反走样)
在前面提到的SSAA中,每个子采样点都要进行单独的着色,这样在片断(像素)着色器比较复杂的情况下还是很费的。那么能不能只计算每个像素的颜色,而对于那些子采样点只计算一个覆盖信息(coverage)和遮挡信息(occlusion)来把像素的颜色信息写到每个子采样点里面呢?最终根据子采样点里面的颜色值来通过某个重建过滤器来降采样生成目标图像。这就是MSAA的原理。注意这里有一个很重要的点,就是每个子像素都有自己的颜色、深度模板信息,并且每一个子采样点都是需要经过深度和模板测试才能决定最终是不是把像素的颜色得到到这个子采样点所在的位置,而不是简单的作一个覆盖测试就写入颜色。
MSAA跟SSAA不同的地方在于,SSAA对于所有子采样点着色,而MSAA只对当前像素覆盖掩码不为0的进行着色,顶点属性在像素的中心进行插值用于在片断程序中着色。这是MSAA相对于SSAA来说最大的好处。
虽然我们只对每个像素进行着色,但是并不意味着我们只需要存储一个颜色值,而是需要为每一个子采样点都存储颜色值,所以我们需要额外的空间来存储每个子采样点的颜色值。所以,颜色缓冲区的大小也为非MSAA下的n倍。当一个片断程序输出值时,只有地了覆盖测试和遮挡测试的子采样点才会被写入值。因此如果一个三角形覆盖了4倍采样方式的一半,那么一半的子采样点会接收到新的值。或者如果所有的子采样点都被覆盖,那么所有的都会接收到值。
这是引用的,目标文章里的,截到这里,方便看懂,不用来回跳
这里有一个要问题是,子像素点的颜色,虽然不用每个子像素点都走一遍着色过程,但是每个子像素点都是有自己的颜色的,子像素的颜色值直接用的像素中心颜色值?还是子像素位置的颜色插值?
MSAA Resolve(MSAA 解析)
像超采样一样,过采样的信号必须重新采样到指定的分辨率,这样我们才可以显示它。
这个过程叫解析(resolving)。在它最早的版本里,解析过程是在显卡的固定硬件里完成的。一般使用的采样方法就是一像素宽的box过滤器。这种过滤器对于完全覆盖的像素会产生跟没有使用MSAA一样的效果。好不好取决于怎么看它(好是因为你不会因为模糊而减少细节,坏是因为一个box过滤器会引入后走样(postaliasing))
4.1.8 Multisampling in Direct3D
如果使用MSAA,需要用DXGI_SAMPLE_DESC 结构体 ,back buffer 和depth buffer都需要注意
4.1.9 Feature Levels
用于检查 hardware的 capabilities
4.2 INITIALIZING DIRECT3D
步骤:
4.2.1 Create the Device and Context
The ID3D11Device interface is used to check feature support, and allocate resources.
The ID3D11DeviceContext interface is used to set render states, bind resources to the graphics pipeline, and issue rendering commands.
这里主要介绍 D3D11CreateDevice 方法和 各个参数
正如Note里说的, 注意这里创建的是 ID3D11DeviceContext* md3dImmediateContext;
也可以使用 ID3D11Device::CreateDeferredContext 创建用于多线程的context,这里就要用到 ID3D11CommandList,用于线程间的配合
4.2.3 Describe the Swap Chain
填充DXGI_SWAP_CHAIN_DESC结构体及子属性 DXGI_MODE_DESC BufferDesc 交换缓冲buffer。
如果运行时,改变multisample的设置,需要destroy并重新生成swap chain。
另外BufferDesc的Format使用 DXGI_FORMAT_R8G8B8A8_UNORM,这是因为一般显示器不支持超过24bit以上的颜色, 而且这里多余alpha的8bit,可以用于其他特殊的效果。
4.2.4 Create the Swap Chain
描述之后,进行创建,需要调用 IDXGIFactory::CreateSwapChain,但要得到Factory,不能使用 CreateDXGIFactory ,而是需要通过COM接口,获取当前device上已有的factory,否则重新创建的话,会报错
DXGI Warning: IDXGIFactory::CreateSwapChain: This function is being called with a device from a different
IDXGIFactory.
DXGI
DXGI是独立于 DirectX的接口,用于处理Graphics外相关的事情,比如swap chain,enum hardware 和switch full/window的等等,由于Direct2D等也有类似需求,因此抽象出来的单独的一部分。
4.2.5 Create the Render Target View
创建backBuffer的 renderTargetResourceView
ID3D11Device::CreateRenderTargetView 的第二个参数,是D3D11_RENDER_TARGET_VIEW_DESC,可以传0,是因为buffer的format的type已经声明过了,不是typeless的,如果是typeless的,就需要创建view前,专门指定 desc了
中间有一段关于经常ReleaseCOM的解释
比如,一般 IDXGISwapChain::GetBuffer increases the COM reference count to the back buffer ,get之后会增加一个reference,因此需要手动调用一下ReleaseCOM
4.2.6 Create the Depth/Stencil Buffer and View
创建深度和模板缓冲及对应view
创建Texture,首先填充D3D11_TEXTURE2D_DESC ,然后调用 ID3D11Device::CreateTexture2D。
D3D11_USAGE 和 CPUAccessFlags 配合使用
D3D11_USAGE_DEFAULT: Specify this usage if the GPU (graphics processing unit) will be reading and writing to the resource. The
CPU cannot read or write to a resource with this usage. For the depth/stencil buffer, we specify D3D11_USAGE_DEFAULT because
the GPU will be doing all the reading and writing to the depth/stencil buffer.
D3D11_USAGE_IMMUTABLE: Specify this usage if the contents of a resource does not ever change after creation. This allows for
some potential optimizations, as the resource will be read-only by the GPU. The CPU and GPU cannot write to an immutable
resource, except at creation time to initialize the resource. The CPU cannot read from an immutable resource.
D3D11_USAGE_DYNAMIC: Specify this usage if the application (CPU) needs to update the data contents of the resource frequently
(e.g., on a per frame basis). A resource with this usage can be read by the GPU and written to by the CPU. Updating a GPU
resource dynamically from the CPU incurs a performance hit, as the new data must be transferred over from CPU memory (i.e.,
system RAM) to GPU memory (i.e., video RAM); therefore, dynamic usage should be avoided unless necessary.
D3D11_USAGE_STAGING: Specify this usage if the application (CPU) needs to be able to read a copy of the resource (i.e., the
resource supports copying data from video memory to system memory). Copying from GPU to CPU memory is a slow operation and
should be avoided unless necessary.
D3D11_USAGE_DYNAMIC and D3D11_USAGE_STAGING 应该尽可能避免使用,因为这两个涉及到CPU,可能会引起性能瓶颈
4.2.7 Bind the Views to the Output Merger Stage
md3dImmediateContext->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);
4.2.8 Set the Viewport
md3dImmediateContext->RSSetViewports(1, &vp);
CodeSet Modification
除了基本的math库,需要修改一下创建view的函数,D3DX11CreateShaderResourceViewFromFile 已经被遗弃了,使用之前导入的 DDSTextureLoader 中的函数