当前位置: 首页 > news >正文

DX9中如何模拟DX10/11里的ConstantBuffer

今天,我的引擎的DX9 RenderApi插件终于可以跑起来了。虽然问题还很多。不过总算看到图像了。立碑纪念一下。

一开始基于DX10的API来构造整个渲染系统的。DX10的API带来很多新的概念设计。比如Constant Buffer的概念,能统一Shader Constant的管理,当然在DX10/DX11里能有效的提高参数传递的效率。

比如:我做了个TransformBuffer。这个Buffer绑定掉了所有的Matrix上。当Camera变化,或者Matrix变化得时候,我只需要加个标记。下次使用这个Buffer的时候,我检查这个Dirty标记。如果Dirty了。那就下载数据到GPU Constant Buffer中。这样的好处就不会所有的Shader都需要download一遍相同的数据到GPU中了。严重节省了GPU-CPU数据交换的时间。

但是杯具的是,DX9中没这个东西。

不过虽然没有。我至少在行为上可以模拟的像一点。顶多不需要那严重节省下来的时间而已。

DX9的ConstantTable里。可以检查一个Constant是不是Struct。 如果是一个Struct,那么它的数据都是连续的。我们可以用Struct来模拟Constant Buffer。

比如:

struct cTransformBuffer
{
matrix matWorld;
matrix matView;
matrix matProject;
float4 cameraUp;
float4 cameraPos;
float4 cameraDir;
float4 cameraArg;//[Near , Far , Fov , Aspect]
};
cTransformBuffer TransformBuffer;

我就有了一个名字为TransformBuffer的Struct。而且这个Struct的大小,和总的D3DXHANDLE在ConstantTable里是都可以拿的到得。

在我们需要数据的时候,用pConstantTable->SetValue()函数,把整块数据扔给ShaderConstantTable就Ok了。

虽然这样没有节省任何CPU-GPU时间。不过代码变的真是干净彻底啊。

PS: 同理把渲染状态进行管理。按照DX11/DX10的分类。然后成组的设置。管理渲染状态也变得更加方便了。

代码如下,自带渲染状态重复判断。不会多设置一个不需要设置的多余的渲染状态。

void xD3D9ZStencilState::Install(xD3D9ZStencilState* pOldStencil)
{
IDirect3DDevice9* pDevice = m_pD3D9RenderApi->getDevice();
if(pOldStencil)
{
GUID_VALUE(m_Stencil.m_Enable ) pDevice->SetRenderState(D3DRS_STENCILENABLE , m_Stencil.m_Enable );
GUID_VALUE(m_Stencil.m_Ref ) pDevice->SetRenderState(D3DRS_STENCILREF , m_Stencil.m_Ref );
GUID_VALUE(m_Stencil.m_Mask ) pDevice->SetRenderState(D3DRS_STENCILMASK , m_Stencil.m_Mask );
GUID_VALUE(m_Stencil.m_WriteMask) pDevice->SetRenderState(D3DRS_STENCILWRITEMASK , m_Stencil.m_WriteMask);

GUID_VALUE(m_Stencil.m_OpCW.m_Fail ) pDevice->SetRenderState(D3DRS_STENCILFAIL , m_Stencil.m_OpCW.m_Fail );
GUID_VALUE(m_Stencil.m_OpCW.m_zFail) pDevice->SetRenderState(D3DRS_STENCILZFAIL , m_Stencil.m_OpCW.m_zFail);
GUID_VALUE(m_Stencil.m_OpCW.m_Pass ) pDevice->SetRenderState(D3DRS_STENCILPASS , m_Stencil.m_OpCW.m_Pass );
GUID_VALUE(m_Stencil.m_OpCW.m_Func ) pDevice->SetRenderState(D3DRS_STENCILFUNC , m_Stencil.m_OpCW.m_Func );

GUID_VALUE(m_Stencil.m_OpCCW.m_Fail ) pDevice->SetRenderState(D3DRS_CCW_STENCILFAIL , m_Stencil.m_OpCCW.m_Fail );
GUID_VALUE(m_Stencil.m_OpCCW.m_zFail) pDevice->SetRenderState(D3DRS_CCW_STENCILZFAIL , m_Stencil.m_OpCCW.m_zFail);
GUID_VALUE(m_Stencil.m_OpCCW.m_Pass ) pDevice->SetRenderState(D3DRS_CCW_STENCILPASS , m_Stencil.m_OpCCW.m_Pass );
GUID_VALUE(m_Stencil.m_OpCCW.m_Func ) pDevice->SetRenderState(D3DRS_CCW_STENCILFUNC , m_Stencil.m_OpCCW.m_Func );
}
else
{
pDevice->SetRenderState(D3DRS_STENCILENABLE , m_Stencil.m_Enable );
pDevice->SetRenderState(D3DRS_STENCILREF , m_Stencil.m_Ref );
pDevice->SetRenderState(D3DRS_STENCILMASK , m_Stencil.m_Mask );
pDevice->SetRenderState(D3DRS_STENCILWRITEMASK , m_Stencil.m_WriteMask);

pDevice->SetRenderState(D3DRS_STENCILFAIL , m_Stencil.m_OpCW.m_Fail );
pDevice->SetRenderState(D3DRS_STENCILZFAIL , m_Stencil.m_OpCW.m_zFail);
pDevice->SetRenderState(D3DRS_STENCILPASS , m_Stencil.m_OpCW.m_Pass );
pDevice->SetRenderState(D3DRS_STENCILFUNC , m_Stencil.m_OpCW.m_Func );

pDevice->SetRenderState(D3DRS_CCW_STENCILFAIL , m_Stencil.m_OpCCW.m_Fail );
pDevice->SetRenderState(D3DRS_CCW_STENCILZFAIL , m_Stencil.m_OpCCW.m_zFail);
pDevice->SetRenderState(D3DRS_CCW_STENCILPASS , m_Stencil.m_OpCCW.m_Pass );
pDevice->SetRenderState(D3DRS_CCW_STENCILFUNC , m_Stencil.m_OpCCW.m_Func );
}
}

相关文章:

  • python怎么除去列表l中所有是x的元素_Python学习教程(Python学习路线):Python3之递归函数简单示例...
  • Windows phone 7 Series发布!
  • json_extract提取复杂json_4个小窍门,让你在Python中高效使用JSON
  • 关于Windows phone 7 series开发方面的传言
  • centos找不到apt-get命令_Centos 使用 pyinstaller 打包踩坑分享
  • python cv2 imshow_Python-OpenCV 2. 图像基本操作
  • wild magic3 渲染状态更新和scene绘制
  • 跨域获取后台数据undefined_拨号跨域问题
  • 软件文档归类汇总
  • java aes加密_行走江湖,安全第一 | 尚硅谷Java安全密码学教程发布!
  • 今天是最后的悠闲。
  • kernel编译 openwrt_OpenWRT实践3:Click Modular Router
  • 关于Mercurial(Hg)
  • python异常处理机制_错误处理
  • 十进制浮点数的表示方法
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • 2017 年终总结 —— 在路上
  • cookie和session
  • Golang-长连接-状态推送
  • GraphQL学习过程应该是这样的
  • HTTP 简介
  • js
  • JS函数式编程 数组部分风格 ES6版
  • Laravel深入学习6 - 应用体系结构:解耦事件处理器
  • Redis的resp协议
  • SpringBoot几种定时任务的实现方式
  • 彻底搞懂浏览器Event-loop
  • 从零开始在ubuntu上搭建node开发环境
  • 分享几个不错的工具
  • 构造函数(constructor)与原型链(prototype)关系
  • 基于 Babel 的 npm 包最小化设置
  • 深入浅出Node.js
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 探索 JS 中的模块化
  • 应用生命周期终极 DevOps 工具包
  • 阿里云ACE认证之理解CDN技术
  • 数据可视化之下发图实践
  • (06)金属布线——为半导体注入生命的连接
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (LeetCode 49)Anagrams
  • (二)hibernate配置管理
  • (三)终结任务
  • (译) 函数式 JS #1:简介
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)http-server应用
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • ::前边啥也没有
  • ??myeclipse+tomcat
  • [ vulhub漏洞复现篇 ] Grafana任意文件读取漏洞CVE-2021-43798
  • [51nod1610]路径计数
  • [Ariticle] 厚黑之道 一 小狐狸听故事
  • [C#]科学计数法(scientific notation)显示为正常数字