调整交换链大小导致位图不可用(SharpDX、directX)
Resizing swapchain causes Bitmap not to be usable (SharpDX, directX)
我想在 windows 表单应用程序的屏幕上调整交换链的大小。当我这样做时,我需要处理我的旧 deviceContext、缓冲区、目标等...
看下面的代码:
Public Overrides Sub Resize(Width As Integer, Height As Integer)
m_backBuffer.Dispose()
m_d2dContext.Dispose()
m_2dTarget.Dispose()
m_swapChain.ResizeBuffers(2, Width, Height, Format.R8G8B8A8_UNorm, SwapChainFlags.None)
m_backBuffer = m_swapChain.GetBackBuffer(Of Surface)(0)
Dim properties As BitmapProperties = New BitmapProperties(New SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.R8G8B8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied), 96, 96)
Dim dxgiDevice As SharpDX.DXGI.Device = m_device.QueryInterface(Of SharpDX.DXGI.Device)()
Dim d2dDevice As SharpDX.Direct2D1.Device = New SharpDX.Direct2D1.Device(dxgiDevice)
m_d2dContext = New SharpDX.Direct2D1.DeviceContext(d2dDevice, SharpDX.Direct2D1.DeviceContextOptions.None)
m_2dTarget = New SharpDX.Direct2D1.Bitmap(m_d2dContext, m_backBuffer, properties)
m_d2dContext.Target = m_2dTarget
CType(m_Context, GpuDrawingContext).setRenderTarget(m_d2dContext)
End Sub
我这样做的问题是,我之前创建的要在屏幕上显示的位图需要一个 DeviceContext 作为其创建的参数。但是,现在我在调整大小时实例化了一个新的 DeviceContext,当我想在 deviceContext 上绘制位图时,我得到了错误 WrongFactory,因为它们不是用我们想要绘制它们的地方的相同 DeviceContext 创建的。
调整大小功能的任何解决方案?
您的代码似乎根本就错了。在处理调整大小时,除了 ResizeBuffers
之外,您实际上不需要调用任何东西。而且您绝对不需要处理 m_d2dContext
,因为通常您会在应用程序的整个生命周期中保留同一个。其余代码实际上属于帧渲染,通常在每次迭代中执行以下操作:
- 获取backbuffer(注意不要缓存因为每个Present交换链之后都会return不同的backbuffer表面)
- 为后台缓冲区表面创建 d2d 位图对象
- 处理后台缓冲区
- 将此 d2d 位图对象设置为 d2d 设备上下文的渲染目标
- 处理 d2d 位图(它仍然存在,因为它正在被 dc 使用)
- 开始抽奖
- 画...
- 平局结束
- 重置 d2d 设备上下文呈现目标
- 呈现新鲜帧
我想在 windows 表单应用程序的屏幕上调整交换链的大小。当我这样做时,我需要处理我的旧 deviceContext、缓冲区、目标等...
看下面的代码:
Public Overrides Sub Resize(Width As Integer, Height As Integer)
m_backBuffer.Dispose()
m_d2dContext.Dispose()
m_2dTarget.Dispose()
m_swapChain.ResizeBuffers(2, Width, Height, Format.R8G8B8A8_UNorm, SwapChainFlags.None)
m_backBuffer = m_swapChain.GetBackBuffer(Of Surface)(0)
Dim properties As BitmapProperties = New BitmapProperties(New SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.R8G8B8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied), 96, 96)
Dim dxgiDevice As SharpDX.DXGI.Device = m_device.QueryInterface(Of SharpDX.DXGI.Device)()
Dim d2dDevice As SharpDX.Direct2D1.Device = New SharpDX.Direct2D1.Device(dxgiDevice)
m_d2dContext = New SharpDX.Direct2D1.DeviceContext(d2dDevice, SharpDX.Direct2D1.DeviceContextOptions.None)
m_2dTarget = New SharpDX.Direct2D1.Bitmap(m_d2dContext, m_backBuffer, properties)
m_d2dContext.Target = m_2dTarget
CType(m_Context, GpuDrawingContext).setRenderTarget(m_d2dContext)
End Sub
我这样做的问题是,我之前创建的要在屏幕上显示的位图需要一个 DeviceContext 作为其创建的参数。但是,现在我在调整大小时实例化了一个新的 DeviceContext,当我想在 deviceContext 上绘制位图时,我得到了错误 WrongFactory,因为它们不是用我们想要绘制它们的地方的相同 DeviceContext 创建的。
调整大小功能的任何解决方案?
您的代码似乎根本就错了。在处理调整大小时,除了 ResizeBuffers
之外,您实际上不需要调用任何东西。而且您绝对不需要处理 m_d2dContext
,因为通常您会在应用程序的整个生命周期中保留同一个。其余代码实际上属于帧渲染,通常在每次迭代中执行以下操作:
- 获取backbuffer(注意不要缓存因为每个Present交换链之后都会return不同的backbuffer表面)
- 为后台缓冲区表面创建 d2d 位图对象
- 处理后台缓冲区
- 将此 d2d 位图对象设置为 d2d 设备上下文的渲染目标
- 处理 d2d 位图(它仍然存在,因为它正在被 dc 使用)
- 开始抽奖
- 画...
- 平局结束
- 重置 d2d 设备上下文呈现目标
- 呈现新鲜帧