下面是我对模板缓存创建的理解:

1. 模板缓存是和深度缓存一起被创建的,将深度缓存的一部分作为模板缓存使用。

深度缓存和模板缓存是在Direct3D初始化时创建的,D3DPRESENT_PARAMETERS结构便包含了深度缓存和模板缓存的格式

typedef struct D3DPRESENT_PARAMETERS {
UINT BackBufferWidth;
UINT BackBufferHeight;
D3DFORMAT BackBufferFormat;
UINT BackBufferCount;
D3DMULTISAMPLE_TYPE MultiSampleType;
DWORD MultiSampleQuality;
D3DSWAPEFFECT SwapEffect;
HWND hDeviceWindow;
BOOL Windowed;
BOOL EnableAutoDepthStencil;
D3DFORMAT AutoDepthStencilFormat;
DWORD Flags;
UINT FullScreen_RefreshRateInHz;
UINT PresentationInterval;
} D3DPRESENT_PARAMETERS,*LPD3DPRESENT_PARAMETERS;

D3DFORMAT          AutoDepthStencilFormat;

可以有以下取值:

D3DFMT_D24S8    创建一个32位深度/模版缓存,其中24位为深度缓存,8位为模版缓存。

D3DFMT_D24X4S4    创建一个32位深度/模版缓存,其中24位为深度缓存,4位为模版缓存,还有4位留着不用。

D3DFMT_D15S1    创建一个16位深度/模版缓存,其中15位为深度缓存,1位为模版缓存。

2. 使用模板缓存前需要启用模板缓存

下面是启用和关闭模板缓存代码

Device->SetRenderState(D3DRS_STENCILENABLE, true);
... // do stencil work
Device->SetRenderState(D3DRS_STENCILENABLE, false);

使用IDirect3DDevice9::Clear方法来清除模板缓存并让其拥有默认值。

Device->Clear(, ,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL,
0xff000000, 1.0f, );

此时模板缓存中的模板值(Value)已被初始化为0

3. 模板缓存是用来阻止像素被写入后台缓存中的,如果像素不能被写入后台缓存,那么它也不能被写入深度缓存。

阻止像素被写入是通过模板测试来决定的,表达式为:

(ref & mask) ComparisonOperation (value & mask)

模版测试是对每个像素进行的,假设模版是被允许。将有两个操作:

  • 左手边操作数(LHS=ref&mask
  • 右手边操作数(RHS=value&mask

模版测试比较LHS和RHS,通过比较运算来指定。全部的运算都得到一个布尔值(true/false)。假如测试的结果是true,那么我们把像素写入后缓存。假如测试的结果是false,我们就阻止像素被写入后缓存。
设置渲染状态:

Device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
Device->SetRenderState(D3DRS_STENCILREF, 0x1);
Device->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);
Device->SetRenderState(D3DRS_STENCILWRITEMASK,0xffffffff);
Device->SetRenderState(D3DRS_STENCILZFAIL,D3DSTENCILOP_KEEP);
Device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
Device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);

设置模版比较运算为D3DCMP_ALWAYS,这就是说让所有模版测试都通过。

假如深度测试失败了,我们指定D3DSTENCILOP_KEEP,它表明不更新模版缓存入口,保存当前值。这样做的原因是假如深度测试失败了,那么就意味着像素被“模糊”了。我们不想渲染被“模糊”的反射像素。

同样假如模版测试失败了,我们也指定D3DSTENCILOP_KEEP。但是在这里这样做不是必须的,因为我们指定的是D3DCMP_ALWAYS,当然这样的测试也就永远不会失败。

假如深度测试和模版测试都通过了,我们就指定D3DSTENCILOP_REPLACE,更新模版缓存入口,设置模版参考值为0x1。

4. 更新模板缓存,因为测试总是通过,所以被渲染的部分替换为0x1,其他部分为0

更新模板缓存前,先阻止向深度缓存写入

 // 禁用向模板 深度(Z)缓冲区进行写
Device->SetRenderState(D3DRS_ZWRITEENABLE, false);
Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);

将源融合因子和目标融合因子分别指定为D3DBLEND_ZERO和D3DBLEND_ONE防止对后台缓存进行更新,

    //设置 源融合因子和 目标融合因子
Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);

将镜子写入模板缓存

Device->SetStreamSource(, VB, , sizeof(Vertex));
Device->SetFVF(Vertex::FVF);
Device->SetMaterial(&MirrorMtrl);
Device->SetTexture(, MirrorTex);
D3DXMATRIX I;
D3DXMatrixIdentity(&I);
Device->SetTransform(D3DTS_WORLD, &I);
Device->DrawPrimitive(D3DPT_TRIANGLELIST, , );

在模版缓存中,符合镜子可视像素的为0x1,其他像素为0

至此,模板缓存已创建完成。

......

D3D 模板缓存的创建过程的更多相关文章

  1. [ZZ] D3D中的模板缓存(3)

    http://www.cppblog.com/lovedday/archive/2008/03/25/45334.html http://www.cppblog.com/lovedday/ D3D中的 ...

  2. mybatis缓存创建过程

    带着 上篇 的问题,再来看看mybatis的创建过程 1.从SqlSessionFactoryBuilder解析mybatis-config.xml开始 对文件流解析 XMLConfigBuilder ...

  3. ASP.NET Web API 控制器创建过程(二)

    ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...

  4. ASP.NET Web API 控制器创建过程(一)

    ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内 ...

  5. .NET/ASP.NET MVC Controller 控制器(IController控制器的创建过程)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...

  6. IController控制器的创建过程

    .NET/ASP.NET MVC Controller 控制器(二:IController控制器的创建过程)   阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactor ...

  7. 三、ASP.NET MVC Controller 控制器(二:IController控制器的创建过程)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...

  8. spring的bean创建过程

    Spring的bean创建过程 步骤 执行过程 描述 1 ThreadLocal.set bean创建之前将beanName的一些属性放进ThreadLocal,避免多线程创建bean导致问题,并发创 ...

  9. 0003 - 基于xml的Spring Bean 的创建过程

    一.目录 前言 创建 Bean 容器 加载 Bean 定义 创建 Bean Spring Bean 创建过程中的设计模式 总结 二.前言 2.1 Spring 使用配置 ApplicationCont ...

随机推荐

  1. Java基础(5):试用Array类对数据进行操作(Sort和toString方法)

    Arrays 类是 Java 中提供的一个工具类,在 java.util 包中.该类中包含了一些方法用来直接操作数组,比如可直接实现数组的排序.搜索等 1. 排序 语法:  Arrays.sort(数 ...

  2. WOW: 宏

    1.常用的宏命令 1.1常用的宏命令 1.释放技能命令 /cast 释放一个或多个技能,可以加入一些条件判断,是最常用的命令 /castsequence 依次释放释放数个技能,同样可以加入一些条件判断 ...

  3. C++之路进阶——bzoj1455(罗马游戏)

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  gryz2016 Logout 捐赠本站 Notice:由于本OJ ...

  4. Android -- FragmentTabHost实现微信底部切换

    1,在商城类的项目中我们开始一个项目的时候经常出现这样的需求,如下图所示: 下面使用户可以切换的模块,上面是对应的模块的详细内容,实现这个效果有很多方式,可以使用radiobutton+fragmen ...

  5. po line received is canceled(恢复PO被取消的余量)

    1張PO已部分收貨,後來由于某種原因,將部分收貨的PO明行取消,現在要對已收料的這一部分進行退貨處理,要怎麼做才好呢? [@more@]DATA COLLECTED===============COL ...

  6. 关于Python中数据对象的可变性

    先贴上Python官网中对数据模型描述的几段话.(在python官网的 语言参考>>数据模型 那部分) Every object has an identity, a type and a ...

  7. 好用的调色软件 ColorSchemer Studio

    软件名叫:ColorSchemer Studio 这是windows平台下的软件

  8. MapReduce:详解Shuffle过程

    Shuffle过程是MapReduce的核心,也被称为奇迹发生的地方.要想理解MapReduce, Shuffle是必须要了解的.我看过很多相关的资料,但每次看完都云里雾里的绕着,很难理清大致的逻辑, ...

  9. 写sql语句分别按日,星期,月,季度,年统计

    --写sql语句分别按日,星期,月,季度,年统计销售额 --按日 ' group by day([date]) --按周quarter ' group by datename(week,[date]) ...

  10. JavaScript 闭包整合

    初遇闭包感觉很困惑,上网查看了些许介绍,有很多没看懂,就想先对能懂的东西整整 首先觉得要了解闭包,要先对一.JavaScript的变量作用域和作用域链有基本了解 1.变量的作用域分为:全局变量和局部变 ...