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

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. hdu(1171)多重背包

    hdu(1171) Big Event in HDU Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (J ...

  2. uva 11178 - Morley's Theorem

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  3. ligerui+json_001_实现表格(grid)的后台数据显示、分页

    代码下载地址: http://download.csdn.net/detail/poiuy1991719/8556841 效果: 需要导入的包: 01:编写界面:index.jsp <%@ pa ...

  4. 部署ganglia3.7

    环境 centOS6.6 gmetad节点关闭iptable gmetad和httpd只需要在一台节点安装,gmond需要在每台节点上安装. 一.安装epel源 sudo wget http://do ...

  5. 3D语音天气球(源码分享)——通过天气服务动态创建3D球

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 开篇废话: 这个项目准备分四部分介绍: 一:创建可旋转的"3D球":3 ...

  6. JS获取项目根目录

    function getRootPath(){ //获取当前网址,如: http://localhost:8088/test/test.jsp var curPath=window.document. ...

  7. 17---Net基础加强

    更新中,敬请期待............ 复习 将xml显示到treeview 修改增加 删除 foreach原理 深拷贝与浅拷贝 模拟数据库及登陆 复习总结

  8. logstash的性能测试

    logstash有简单的批量生成插件.generator.详情见官网:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-g ...

  9. DB2 Unload 的时候遇到B37-04

    B37-04的问题是每个Mainframer首先会遇到的问题,在Unload的时候最大的可能性是Extend次数到16次了,这时候只要加大primary或secondary就可以了,我最常用的是pri ...

  10. scala匿名函数

    package com.ming.test import scala.math._ object AnonymousFunc { def valueAtOneQuarter(f:(Double)=&g ...