DirectX11笔记7:模板Stenciling

跟以前的一样,对于模板缓冲区,也是声明定义一系列的结构体,并在渲染的时候 打开/关闭 他们

在使用CreateRenderTargetView创建视图之后,声明定义深度模板缓冲区:

    ID3D11Texture2D *depthStencilBuffer(NULL);
    //测试多重采样抗锯齿等级
    UINT x4MsaaQuality;
    dev->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &x4MsaaQuality);
    printf("CheckMultisampleQualityLevels:%d\n", x4MsaaQuality);
    //
    D3D11_TEXTURE2D_DESC dsDesc;
    dsDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    dsDesc.Width = 1200;
    dsDesc.Height = 600;
    dsDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    dsDesc.MipLevels = 1;
    dsDesc.ArraySize = 1;
    dsDesc.CPUAccessFlags = 0;
    dsDesc.SampleDesc.Count = (x4MsaaQuality<1?1:4);
    dsDesc.SampleDesc.Quality = (x4MsaaQuality<1 ? 0 : x4MsaaQuality - 1);
    dsDesc.MiscFlags = 0;
    dsDesc.Usage = D3D11_USAGE_DEFAULT;
    hr = dev->CreateTexture2D(&dsDesc, 0, &depthStencilBuffer);
    if (FAILED(hr))
    {
        return false;
    }
    hr = dev->CreateDepthStencilView(depthStencilBuffer, 0, &depthStencilView);
    if (FAILED(hr))
    {
        return false;
    }
    devContext->OMSetRenderTargets(1, &backBuffer, depthStencilView);
    depthStencilBuffer->Release();

结构:CheckMultisampleQualityLevels验证多重采样抗锯齿的等级------CreateTexture2D创建2D贴图缓冲区------CreateDepthStencilView创建缓冲区视图------OMSetRenderTargets进行绑定。

主要记录一下

D3D11_TEXTURE2D_DESC这个结构:

typedef struct D3D11_TEXTURE2D_DESC {
  UINT             Width;
  UINT             Height;
  UINT             MipLevels;
  UINT             ArraySize;
  DXGI_FORMAT      Format;
  DXGI_SAMPLE_DESC SampleDesc;
  D3D11_USAGE      Usage;
  UINT             BindFlags;
  UINT             CPUAccessFlags;
  UINT             MiscFlags;
} D3D11_TEXTURE2D_DESC;

需要注意的元素:

Width与Height:贴图的高与宽,要与上面创建的视图缓冲区与下面的视窗大小相匹配。

BindFlags:这里我使用DXGI_FORMAT_D24_UNORM_S8_UINT,24位用于深度缓冲区,8位用于模板缓冲区。

SampleDesc:这是一个结构体

typedef struct DXGI_SAMPLE_DESC {
  UINT Count;
  UINT Quality;
} DXGI_SAMPLE_DESC;

MSDN有这样的解释:

The image quality level. The higher the quality, the lower the performance. The valid range is between zero and one less than the level returned by ID3D10Device::CheckMultisampleQualityLevels for Direct3D 10 or ID3D11Device::CheckMultisampleQualityLevels for Direct3D 11.

也可以见书中4.1.7关于多重采样的内容。

注意,这里的多重采样的元素设置错误,可能会导致无法绘制的BUG。

然后是设定模板测试:

代码

HRESULT DrawFunction::CreateStencilDesc(void)
{
    HRESULT hr = S_OK;//ret
    D3D11_DEPTH_STENCIL_DESC stencilDesc;
    ZeroMemory(&stencilDesc, sizeof(stencilDesc));
    stencilDesc.DepthEnable = FALSE;
    stencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
    stencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
    stencilDesc.StencilEnable = TRUE;
    stencilDesc.StencilReadMask = 0xff;
    stencilDesc.StencilWriteMask = 0xff;
    stencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
    stencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
    stencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
    stencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
    stencilDesc.BackFace = stencilDesc.FrontFace;

    hr = dev->CreateDepthStencilState(&stencilDesc, &pStencilReplace);
    stencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
    stencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL;
    stencilDesc.BackFace = stencilDesc.FrontFace;
    hr = dev->CreateDepthStencilState(&stencilDesc, &pStencilTest);

    return hr;
}

结构体:

typedef struct D3D11_DEPTH_STENCIL_DESC {
  BOOL                       DepthEnable;
  D3D11_DEPTH_WRITE_MASK     DepthWriteMask;
  D3D11_COMPARISON_FUNC      DepthFunc;
  BOOL                       StencilEnable;
  UINT8                      StencilReadMask;
  UINT8                      StencilWriteMask;
  D3D11_DEPTH_STENCILOP_DESC FrontFace;
  D3D11_DEPTH_STENCILOP_DESC BackFace;
} D3D11_DEPTH_STENCIL_DESC;

需要注意的元素:

掩码元素StencilReadMask与StencilWriteMask,就是指当读取/写入模板元素时,用数据与掩码进行AND与运算。代码中我设置为0xFF表示不做任何变化。

//模板未更新完,先放一个简单的demon,在之后学习的实例的时候再进行补充。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

工程文件

时间: 2025-01-31 20:07:36

DirectX11笔记7:模板Stenciling的相关文章

C++ Primer 学习笔记_77_模板与泛型编程 --实例化

模板与泛型编程 --实例化 引言: 模板是一个蓝图,它本身不是类或函数.编译器使用模板产生指定的类或函数的特定版本号.产生模板的特定类型实例的过程称为实例化. 模板在使用时将进行实例化,类模板在引用实际模板类型时实例化,函数模板在调用它或用它对函数指针进行初始化或赋值时实例化. 1.类的实例化 当编写Queue<int>qi时,编译器自己主动创建名为Queue<int>的类.实际上,编译器通过又一次编写Queue模板,用类型int取代模板形參的每次出现而创建Queue<int

C++ Primer 学习笔记_81_模板与泛型编程 --类模板成员[续1]

模板与泛型编程 --类模板成员[续1] 二.非类型形参的模板实参 template <int hi,int wid> class Screen { public: Screen():screen(hi * wid,'#'), cursor(hi * wid),height(hi),width(wid) {} //.. private: std::string screen; std::string::size_type cursor; std::string::size_type height

C++ Primer 学习笔记_82_模板与泛型编程 --类模板成员[续2]

模板与泛型编程 --类模板成员[续2] 六.完整的Queue类 Queue的完整定义: template <typename Type> class Queue; template <typename Type> ostream &operator<<(ostream &,const Queue<Type> &); template <typename Type> class QueueItem { friend clas

C++ Primer 学习笔记_75_模板与泛型编程 --模板定义

模板与泛型编程 --模板定义 引言: 所谓泛型程序就是以独立于不论什么特定类型的方式编写代码.使用泛型程序时,我们须要提供详细程序实例所操作的类型或值. 模板是泛型编程的基础.使用模板时能够无须了解模板的定义. 泛型编程与面向对象编程一样,都依赖于某种形式的多态性.面向对象编程中的多态性在执行时应用于存在继承关系的类.我们能够编写使用这些类的代码,忽略基类与派生类之间类型上的差异.仅仅要使用基类的引用或指针,基类类型或派生类类型的对象就能够使用同样的代码. 在泛型编程中,我们所编写的类和函数能够

C++ Primer 学习笔记_84_模板与泛型编程 --模板特化

模板与泛型编程 --模板特化 引言: 我们并不总是能够写出对全部可能被实例化的类型都最合适的模板.某些情况下,通用模板定义对于某个类型可能是全然错误的,通用模板定义或许不能编译或者做错误的事情;另外一些情况下,能够利用关于类型的一些特殊知识,编写比从模板实例化来的函数更有效率的函数. compare函数和 Queue类都是这一问题的好样例:与C风格字符串一起使用进,它们都不能正确工作. compare函数模板: template <typename Type> int compare(cons

C++ Primer 学习笔记_83_模板与泛型编程 --一个泛型句柄类

模板与泛型编程 --一个泛型句柄类 引言: [小心地雷] 这个例子体现了C++相当复杂的语言应用,理解它需要很好地理解继承和模板.在熟悉了这些特性之后再研究这个例子也许会帮助.另一方面,这个例子还能很好地测试你对这些特性的理解程度. 前面示例的Sales_item和Query两个类的使用计数的实现是相同的.这类问题非常适合于泛型编程:可以定义类模板管理指针和进行使用计数.原本不相关的Sales_item类型和 Query类型,可通过使用该模板进行公共的使用计数工作而得以简化.至于是公开还是隐藏下

OpenCV 学习笔记(模板匹配)

OpenCV 学习笔记(模板匹配) 模板匹配是在一幅图像中寻找一个特定目标的方法之一.这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否"相似",当相似度足够高时,就认为找到了我们的目标. 在 OpenCV 中,提供了相应的函数完成这个操作. matchTemplate 函数:在模板和输入图像之间寻找匹配,获得匹配结果图像 minMaxLoc 函数:在给定的矩阵中寻找最大和最小值,并给出它们的位置 在具体介绍这两个函数之前呢,我们还要介绍一个概念,就是如何来评价两

C++ Primer 学习笔记_85_模板与泛型编程 --模板特化[续]

模板与泛型编程 --模板特化[续] 三.特化成员而不特化类 除了特化整个模板之外,还可以只特化push和pop成员.我们将特化push成员以复制字符数组,并且特化pop成员以释放该副本使用的内存: template<> void Queue<const char *>::push(const char *const &val) { char *new_item = new char[sizeof(val) + 1]; strncpy(new_item,val,sizeof(

C++ Primer 学习笔记_79_模板与泛型编程 --模板编译模型

模板与泛型编程 --模板编译模型 引言: 当编译器看到模板定义的时候,它不立即产生代码.只有在用到模板时,如果调用了函数模板或定义了模板的对象的时候,编译器才产生特定类型的模板实例. 一般而言,当调用函数时[不是模板],编译器只需看到函数的声明.类似的,定义类类型的对象时,类定义必须可用,但成员函数的定义不是必须存在的.因此,应该将类定义和函数声明放在头文件中,而普通函数和类成员函数的定义放在源文件中. 模板则不同:要进行实例化,编译器必须能够访问定义模板的源代码.当调用函数模板或类模板的成员函