`
dengbaoleng
  • 浏览: 1133599 次
文章分类
社区版块
存档分类
最新评论

CreateRenderTarget 和 CreateTexture区别

 
阅读更多

前几天做全屏抗锯齿,发现所有RT渲染的结果 zBuffer 错乱. D3D 报的错误,是RenderTarget 的深度和模版格式不匹配。先以为CreateDepthStencilSurface 抗锯齿参数填错了,后来发现用CreateTexture 创建的RenderTarget 支持不了全屏抗锯齿,只能用CreateRenderTarget 创建RenderTarget才能支持全屏抗锯齿。

看一下文档参数

HRESULT CreateTexture(
UINT Width,
UINT Height,
UINT Levels,
DWORD Usage,
D3DFORMAT Format,
D3DPOOL Pool,
IDirect3DTexture9** ppTexture,
HANDLE* pSharedHandle
);

HRESULT CreateRenderTarget(
UINT Width,
UINT Height,
D3DFORMAT Format,
D3DMULTISAMPLE_TYPE MultiSample,
DWORD MultisampleQuality,
BOOL Lockable,
IDirect3DSurface9** ppSurface,
HANDLE* pSharedHandle
);

看参数可以看到,CreateRenderTarget 可以看到MultiSample, MultisampleQuality 支持抗锯齿参数,此外CreateTexture 创建的RT不能locked 而CreateRenderTarget 能locked。

还有CreateRenderTarget 创建的是IDirect3DSurface9*,而CreateTexture 创建的是IDirect3DTexture9*,要转IDirect3DTexture9 需要StretchRect 转换。

关于RenderTarget的注意事项:

1. 设置一个RenderTarget会导致viewport变成跟RenderTarget一样大

2. 反锯齿类型必须跟DepthStencilBuffer一样

3. RenderTarget的类型必须跟DepthStencilBuffer的类型兼容, 可以用IDirect3D9::CheckDepthStencilMatch进行检测

4. DepthStencilBuffer的大小必须>=RenderTarget的大小

5. IDirect3DDevice9::SetRenderTarget的第0个不能为NULL

6. Usage为D3DUSAGE_RENDERTARGET的Texture不能进行反锯齿, 而且Pool必须为D3DPOOL_DEFAULT. 如果想利用RenderTarget做为纹理又想反锯齿, 可以先把场景渲染到一个CreateRenderTarget创建的Surface(或BackBuffer)上, 再用IDirect3DDevice9::StretchRect拷贝到纹理上

7. RTT不能既做为输入就做为输出目标, 某些显卡上可能只会给一个warning, 有些显卡上则会发生报错/黑屏/死机之类不可预计的事情...另外, Depth stencil texture(参见Hareware shadow map)也有同样的问题, 用完之后要SetTexture(n, NULL)清空, 不然A卡会黑屏/花屏/深度错误, 既使你没有使用, 只要它被寄存器引用了, 显卡还是会当做是正在使用的, 这时就不能做为depth stencil buffer

8. RTT如果想保存到文件中, 是不能直接SaveToTexture的. 需要创建一个OffscreenSurface, 拷贝过去, 再保存. 不过N卡好像不支持DXT1格式的OffscreenSurface, 可以创建Texture, 取其level0的surface代替.

9. N卡在开启了锯齿后冒似所有的RTT都要反锯齿, 不然深度测试会失败-_-

10. Intel的显卡在RTT没有设置DepthBuffer时可能所有绘制全部深度测试失败, 需要关闭深度测试再画.

补充:

D3D9下的获得RenderTarget有2种方法

1. 使用D3DXCreateTexture或者Device->CreateTexture 创建纹理

调用Device->GetSurfaceLevel(0, &SurfacePtr );获得Surface指针

将Surface指针使用Device->SetRenderTarget设置上去即可开始绘制

注意:D3DXCreateTexture创建的是2的n次幂的纹理,而Device->CreateTexture 创建的则可以是任意大小的纹理

这种方法创建的Texture与Surface是一一对应的,由D3D底层自动做了Resolve的过程

不能使用MultiSample

2. 使用Device->CreateRenderTarget()创建一个Surface,用Surface直接设置为RenderTarget

可以开启Lockable选项,但是效率会非常低

可以使用MultiSample

由于没有Texture的关联,这种方法绘制速度理论上会快一些

可以使用Device->StretchRect来将Surface直接拷贝到后备缓冲或者另外一个Surface。不过在DX8和某些DX9的驱动上有一定兼容性问题,具体请参考SDK

分享到:
评论

相关推荐

    ImFileDialog:亲爱的ImGui的文件对话框库

    ImFile对话框亲爱的ImGui的简单文件对话框库... 这是有关如何使用ImFileDialog的示例: 您需要设置CreateTexture和DeleteTexture函数ifd::FileDialog::Instance ().CreateTexture = []( uint8_t * data, int w, int h,

    glo-texture:WebGL纹理界面

    用于2D,3D,多维数据集和2DArray数据的通用WebGL纹理接口。 实验性的,随时可能更改的; 不要依赖要进行语义更新的版本。 var createTexture = require ( 'glo-texture/2d' ) var tex = createTexture ( gl , ...

    gl-checker-texture:创建全屏方格背景

    gl-checker-纹理 创建一个 2x2 方格重复 WebGL 纹理。 适用于方格背景、虚线等。 var Checker = require ( 'gl-checker-texture' ) var tex = Checker ( gl ) ... 新纹理设置为gl.REPEAT wrap 和gl.NEA

    OpenGL读取3DS文件示例

    使用OpenGL读取3DS文件的示例代码。 演示说明了3DS文件的结构、三维控件中视线、旋转设置,以及简单的动画...如果读取结果是黑屏,往往是视角和视场设置错误,可以查看三维数据的位置,更改gluLookAt和gluPerspective。

    gli:jvm gli

    这是原始( GLI )的Kotlin端口,它由 ()编写, 是用于图形软件的仅标头C ++图像库。 GLI提供了类和函数来加载图像文件,促进图形API纹理创建,比较纹理,访问纹理纹理,采样纹理,...fun createTexture ( filename

    StereoIssues

    V_RETURN(d3d10->CreateTexture2D(&desc;, NULL, &gStereoParamTexture;)); // Since we need to bind the texture to a shader input, we also need a resource view. D3D10_SHADER_RESOURCE_VIEW_DESC descRV;...

Global site tag (gtag.js) - Google Analytics