DirectX渲染时Clear无效的原因(造成叠影)
最近在开发D3D程序的过程中,发现一件很奇怪的事情,就是在Render的时候,纹理总是留有“残影”(即上次Render后的帧):
如上图,是一副纹理绕中心点旋转的向日葵,但是可以看到每次Render的时候,都会留下上次Render的帧,即Clear似乎没有起作用。
原来是Clear没调用成功,代码如下:
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 100), 1.0f, 0);
后来经过跟踪代码,发现这其实与Clear函数中的D3DCLEAR_ZBUFFER标志位或者说是创建设备时使用的设备描述参数(深度模板)有关。
在DX SDK中关于Clear的函数返回值有如下描述:
IDirect3DDevice9::Clear will fail if you:
Try to clear either the depth buffer or the stencil buffer of a render target that does not have an attached depth buffer.
Try to clear the stencil buffer when the depth buffer does not contain stencil data.
然后,回到IDevice3D9::CreateDevice的参数D3DPRESENT_PARAMETERS看到我的程序中根本没有设置EnableAutoDepthStencil和AutoDepthStencilFormat这两个参数(即使用默认值EnableAutoDepthStencil=FALSE),所以才导致“残影”的产生。
从程序逻辑的角度看,就是说我们在创建设备的时候没有使用深度模板缓存,但是我们在Clear的时候却去清除ZBUFFER,导致Clear函数调用失败。如果此时将Clear的参数D3DCLEAR_ZBUFFER去掉,那么就不会有“残影”产生,因为此时就不会去清除深度模板缓存,因此Clear就会返回D3D_OK。
此外,在创建设备的时候,指定EnableAutoDepthStencil=TRUE(必须同时指定AutoDepthStencilFormat参数才能创建设备成功),那么原来的Clear函数就会成功,而且也不会再产生“残影”了。
bool Direct3D_Init(HWND window, int width, int height, bool fullscreen)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (!d3d) return false;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = !fullscreen;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.hDeviceWindow = window; d3dpp.EnableAutoDepthStencil = 1;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
if (!d3ddev) return false; d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
D3DXCreateSprite(d3ddev, &spriteobj); return true;
}
正确的渲染:
总结:
如果创建D3D设备的时候没有指定深度模板缓存,那么Clear的时候就不要去清除这个模板缓存,否则就会造成所谓的“残影”现象(因为Clear本身就失败了啊)。
DirectX渲染时Clear无效的原因(造成叠影)的更多相关文章
- 配置python+mod_wsgi+apache 时 在浏览器中访问服务器时报错:Invalid HTTP_HOST header: 'XXXXX'. You may need to add u'XXXXX' to ALLOWED_HOSTS,在setting.py中添加‘*”无效的原因
配置python+mod_wsgi+apache 时 在浏览器中访问服务器时报错:Invalid HTTP_HOST header: 'XXXXX'. You may need to add u'XX ...
- 使用 ADOX 将 Table 添加到 Catalog 时报“类型无效”的原因和解决方法
http://blog.csdn.net/kfhzy/article/details/6020283 http://blog.csdn.net/kfhzy/article/details/602054 ...
- 关于mouse_event和sendinput无效的原因
关于mouse_event和sendinput无效的原因 SetCursorPos 有用, 于mouse_event和sendinput 无用, 导致问题不清晰, 原来是我换了杀毒软件, 360 ...
- angular.js ng-repeat渲染时出现闪烁问题解决
当我们前端运用到angular.js框架时,想必大家都会遇到一些坑.其中,我也来分享一个常见的angular.js渲染时出现的坑. 当我们进行页面渲染时,绑定表达式最开始会用{{data.name}} ...
- $(document).ready()和onload() html渲染时的区别
不谈调用次数,加载先后问题,只看渲染时区别 1.都在数据绑定完加载. 2.ready可以有多个,且都执行,onload虽可以写多个,但是只执行最后一个. 3. $.ready = function ( ...
- 服务端渲染时无法获得环境变量的值,一直是undefined
1.服务端渲染时无法获得环境变量的值,一直是undefined 2.ngnix做代理以后无法无法获取node设置的cookie
- Mybatis order by语句使用<Choose><When>动态拼装无效的原因及解决方法
在使用 <choose> <when test=""> </when> <otherwise> </otherwise> ...
- 当Vue中img的src是动态渲染时不显示问题
最近遇见动态渲染img时,想起了当初刚开始写vue时,曾经遇见的一个小小坑. Vue中:img的src属性是动态渲染时不显示问题1.需求:展示用户头像,数据从后台获取,如果没有拿到则显示默认图片. 如 ...
- Java byte类型转换成int类型时需要 & 0XFF的原因
Java byte类型转换成int类型时需要 & 0XFF的原因 假设有byte b = -1; 那么b的二进制是:1111 1111. 如果将b直接转换为int类型,那么二进制是 1111 ...
随机推荐
- Dotnet洋葱架构实践
一个很清晰的架构实践,同时刨刨MySQL的坑. 一.洋葱架构简介 洋葱架构出来的其实有一点年头了.大约在2017年下半年,就有相关的说法了.不过,大量的文章在于理论性的讨论,而我们今天会用一个项目 ...
- A Color Game
题目大意: 给定一个只包含七种字母的字符串,如果满足一段连续相同的字符长度大于等于K那么即可消除,问最后能不能变为空字符. 题解:很明显是用区间dp来解决,我们设dp[l][r][k]代表的是在[l ...
- MyBatis、Spring、SpringMVC 源码下载地址
MyBatis.Spring.SpringMVC 源码下载地址 github mybatis https://github.com/fengyu415/MyBatis-Learn.git spring ...
- matplotlib常规使用方法
1,指定图片大小和像素 Python绘图问题:Matplotlib中指定图片大小和像素 2,绘图命令的基本架构及其属性设置 绘图与可视化 3,python基础语法(二)--- plt的一些函数使用 p ...
- 图解双链表(Java实现)
原创公众号:bigsai 文章已收录在 全网都在关注的数据结构与算法学习仓库 前言 前面有很详细的讲过线性表(顺序表和链表),当时讲的链表以但链表为主,但实际上在实际应用中双链表的应用多一些就比如Li ...
- Detach blobs with a contact point
https://answers.opencv.org/question/87583/detach-blobs-with-a-contact-point/ 一.问题描述 带有接触点的斑点时遇到问题,需要 ...
- C++并发与多线程学习笔记--async、future、packaged_task、promise
async future packaged_task promise async std:async 是个函数,用来启动一个异步任务,启动起来一个异步任务之后,返回一个std::futre对象,启动一 ...
- Dynamics CRM产生公共签名,避免每次插件换环境重新输入签名密钥账号密码
在Dynamcs CRM项目维护交接过程中,我们经常会使用其他合作者的插件代码.但是每次拿到别人代码编译的时候插件密钥都要重新输入密钥的账号密码.而且如果密钥都是的话比较麻烦.所以这里就针对这个问题做 ...
- 如何调试 Java 开源项目源码,记一种源码导入开发工具并调试的通用方法
楔子 说起读开源项目源码,很多朋友觉得高大上.大佬牛逼,云云~ 挡在很多人面前的不是源码怎么读,而是不知道如何导入源码到开发工具以及如何调试源码. 本文将以 spring-cloud-gateway ...
- Linux pgrep命令
1 pgrep pgrep是一个根据名称查找进程ID的命令,返回的是进程ID,若存在当个进程,则分为不同的行返回ID(默认实现). 2 示例 查找java进程: pgrep java 上图还显示了ps ...