我如何:将表面转换为纹理或使用某些多重采样参数创建纹理或使用 alpha 层渲染表面
我正在创建两个渲染目标,两者都必须共享后台缓冲区的深度缓冲区,因此将它们设置为具有相同的多重采样参数非常重要,但是 pDevice->CreateTexture(..) 没有提供任何用于设置多种采样类型。因此,我使用 pDevice->CreateRenderTarget(...) 创建了两个渲染目标表面,给出了与深度缓冲区相同的值,现在深度缓冲区与我的渲染目标结合使用,但是我无法在屏幕上正确渲染它们因为 alpha 混合不适用于 ->StretchRect (或者我被告知,当我尝试时它不起作用)。
所以这个问题的标题基本上是我的问题,我该如何: - 将表面转换为纹理或 - 使用某些多重采样参数创建纹理或 - 使用 alpha 层正确渲染表面
I am creating two render targets, both must share the back buffer's depth buffer, so it is important that I set them to have the same multi sampling parameters, however pDevice->CreateTexture(..) does not give any parameters for setting the multi sampling types. So I created two render target surfaces using pDevice->CreateRenderTarget(...) giving the same values as the depth buffer, now the depth buffer works in conjunction with my render targets, however I am unable to render them over the screen properly because alpha blending does not work with ->StretchRect (or so I have been told, and it did not work when I tried).
So the title of this question is basically my questions, how do i:
- convert a surface to a texture or
- create a texture with certain multisampling parameters or
- render a surface properly with an alpha layer
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是对一个老问题的新回答,但我遇到了这个问题,并认为我会提供一个答案,以防其他人在遇到这个问题时遇到它。这是带有我的包装器和函数的精简版本的解决方案。
我有一个游戏,其中渲染器有多个层,其中一个是几何层。渲染时,它会迭代所有图层,调用它们的 Draw 函数。每个层都有自己的 RenderTarget 包装器实例。当图层绘制时,它会“激活”其渲染目标,将缓冲区清除为 Alpha,绘制场景,然后“停用”其渲染目标。当所有图层都绘制到其渲染目标后,所有这些渲染目标都会组合到后缓冲区上以生成最终图像。
几何图层::绘制
* 激活该层使用的渲染目标
* 设置所需的渲染状态
* 清除缓冲区
* 绘制几何图形
* 停用该层使用的渲染目标
我的 RenderTarget 包装器包含一个 IDirect3DTexture9* (m_pTexture),它与 D3DXCreateTexture 一起使用来生成要绘制的纹理。它还包含由纹理给出的 IDirect3DSurface9* (m_pSurface)。它还包含另一个 IDirect3DSurface9* (m_pMSAASurface)。
在我的 RenderTarget 的初始化中,有一个启用多重采样的选项。如果关闭此选项,则 m_pMSAASurface 将初始化为 nullptr。如果打开此选项,则会使用 IDirect3DDevice9::CreateRenderTarget 函数为您创建 m_pMSAASurface,并将我当前的多重采样设置指定为第四个和第五个参数。
渲染目标::初始化
* 创建纹理
* 从纹理中获取表面(添加到表面的引用计数)
* 如果 MSAA,则创建启用 msaa 的表面
如果此 MSAA 设置关闭,则 RenderTarget::Activate 将 m_pSurface 设置为渲染目标。如果启用此 MSAA 设置,则 RenderTarget::Activate 将 m_pMSAASurface 设置为渲染目标并启用多重采样渲染状态。
渲染目标::激活
* 存储当前渲染目标(添加到该表面的引用计数)
* 如果不是 MSAA,则将表面设置为新的渲染目标
* 如果 MSAA,将 msaa 表面设置为新的渲染目标,启用 msaa 渲染状态
如果此 MSAA 设置关闭,则 RenderTarget::Deactivate 仅恢复原始渲染目标。如果启用此 MSAA 设置,RenderTarget::Deactivate 也会恢复原始渲染目标,但也会将 m_pMSAASurface 复制到 m_pSurface。
渲染目标::停用
* 如果是 MSAA,则禁用 MSAA 渲染状态
* 恢复之前的渲染目标
* 删除先前渲染目标上的引用计数
当渲染器稍后向几何图层请求其 RenderTarget 纹理以便将其与其他图层组合时,该纹理将具有从 m_pMSAASurface 复制的图像。假设您使用的是有助于 Alpha 通道的格式,则该纹理可以与其他纹理混合,就像我对多个图层的渲染目标所做的那样。
So new response to an old question, but I came across this and thought I'd supply an answer in case someone else comes across it while running into this problem. Here is the solution with a stripped down version of my wrappers and functions for it.
I have a game in which the renderer has several layers, one of which is a geometry layer. When rendering, it iterates over all layers, calling their Draw functions. Each layer has its own instance of my RenderTarget wrapper. When the layer Draws, it "activates" its render target, clears the buffer to alpha, draws the scene, then "deactivates" its render target. After all layers have drawn to their render targets, all of those render targets are then combined onto the backbuffer to produce the final image.
GeometryLayer::Draw
* Activates the render target used by this layer
* Sets needed render states
* Clears the buffer
* Draws geometry
* Deactivates the render target used by this layer
My RenderTarget wrapper contains an IDirect3DTexture9* (m_pTexture) which is used with D3DXCreateTexture to generate the texture to be drawn to. It also contains an IDirect3DSurface9* (m_pSurface) which is given by the texture. It also contains another IDirect3DSurface9* (m_pMSAASurface).
In the initialization of my RenderTarget, there is an option to enable multisampling. If this option is turned off, the m_pMSAASurface is initialized to nullptr. If this option is turned on, the m_pMSAASurface is created for you using the IDirect3DDevice9::CreateRenderTarget function, specifying my current multisampling settings as the 4th and 5th arguments.
RenderTarget::Init
* Creates a texture
* Gets a surface off the texture (adds to surface's ref count)
* If MSAA, creates msaa-enabled surface
If this MSAA setting is off, RenderTarget::Activate sets m_pSurface as the render target. If this MSAA setting is on, RenderTarget::Activate sets m_pMSAASurface as the render target and enables the multisampling render state.
RenderTarget::Activate
* Stores the current render target (adds to that surface's ref count)
* If not MSAA, sets surface as the new render target
* If MSAA, sets msaa surface as the new render target, enables msaa render state
If this MSAA setting is off, RenderTarget::Deactivate simply restores the original render target. If this MSAA setting is on, RenderTarget::Deactivate restores the original render target too, but also copies m_pMSAASurface onto m_pSurface.
RenderTarget::Deactivate
* If MSAA, disables MSAA render state
* Restores the previous render target
* Drops ref counts on the previous render target
When the Renderer later asks the geometry layer for its RenderTarget texture in order to combine it with the other layers, that texture has the image copied from m_pMSAASurface on it. Assuming you're using a format that facilitates an alpha channel, this texture can be be blended with others, as I'm doing with the render targets of several layers.
StretchRect 的文档具体解释了如何为此:
The documentation for StretchRect specifically explains how to do this: