Change RenderTarget to IRenderTarget, implement classes accordingly
Changes GDI+ handling quite a bit, hopefully didn't break anything
This commit is contained in:
parent
25f62c6620
commit
8aac335d9b
|
@ -9,15 +9,19 @@ namespace BizHawk.Bizware.Graphics.Controls
|
||||||
{
|
{
|
||||||
internal sealed class GDIPlusControl : GraphicsControl
|
internal sealed class GDIPlusControl : GraphicsControl
|
||||||
{
|
{
|
||||||
public GDIPlusControl(Func<Func<(SDGraphics Graphics, Rectangle Rectangle)>, GDIPlusRenderTarget> createControlRenderTarget)
|
/// <summary>
|
||||||
|
/// The render target for rendering to this control
|
||||||
|
/// </summary>
|
||||||
|
private readonly GDIPlusControlRenderTarget _renderTarget;
|
||||||
|
|
||||||
|
public GDIPlusControl(Func<Func<(SDGraphics Graphics, Rectangle Rectangle)>, GDIPlusControlRenderTarget> createControlRenderTarget)
|
||||||
{
|
{
|
||||||
RenderTarget = createControlRenderTarget(GetControlRenderContext);
|
_renderTarget = createControlRenderTarget(GetControlRenderContext);
|
||||||
|
|
||||||
SetStyle(ControlStyles.UserPaint, true);
|
SetStyle(ControlStyles.UserPaint, true);
|
||||||
SetStyle(ControlStyles.Opaque, true);
|
SetStyle(ControlStyles.Opaque, true);
|
||||||
SetStyle(ControlStyles.UserMouse, true);
|
SetStyle(ControlStyles.UserMouse, true);
|
||||||
DoubleBuffered = true;
|
DoubleBuffered = true;
|
||||||
BackColor = Color.Black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private (SDGraphics Graphics, Rectangle Rectangle) GetControlRenderContext()
|
private (SDGraphics Graphics, Rectangle Rectangle) GetControlRenderContext()
|
||||||
|
@ -28,11 +32,6 @@ namespace BizHawk.Bizware.Graphics.Controls
|
||||||
return (graphics, ClientRectangle);
|
return (graphics, ClientRectangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The render target for rendering to this control
|
|
||||||
/// </summary>
|
|
||||||
private GDIPlusRenderTarget RenderTarget { get; }
|
|
||||||
|
|
||||||
public override void AllowTearing(bool state)
|
public override void AllowTearing(bool state)
|
||||||
{
|
{
|
||||||
// not controllable
|
// not controllable
|
||||||
|
@ -54,22 +53,22 @@ namespace BizHawk.Bizware.Graphics.Controls
|
||||||
protected override void OnHandleCreated(EventArgs e)
|
protected override void OnHandleCreated(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnHandleCreated(e);
|
base.OnHandleCreated(e);
|
||||||
RenderTarget.CreateGraphics();
|
_renderTarget.CreateGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnHandleDestroyed(EventArgs e)
|
protected override void OnHandleDestroyed(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnHandleDestroyed(e);
|
base.OnHandleDestroyed(e);
|
||||||
RenderTarget.Dispose();
|
_renderTarget.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnResize(EventArgs e)
|
protected override void OnResize(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnResize(e);
|
base.OnResize(e);
|
||||||
RenderTarget.CreateGraphics();
|
_renderTarget.CreateGraphics();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SwapBuffers()
|
public override void SwapBuffers()
|
||||||
=> RenderTarget.BufferedGraphics?.Render(RenderTarget.CurGraphics);
|
=> _renderTarget.BufferedGraphics?.Render(_renderTarget.ControlGraphics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
using Vortice.Direct3D11;
|
||||||
|
using Vortice.DXGI;
|
||||||
|
|
||||||
|
namespace BizHawk.Bizware.Graphics
|
||||||
|
{
|
||||||
|
internal sealed class D3D11RenderTarget : D3D11Texture2D, IRenderTarget
|
||||||
|
{
|
||||||
|
public ID3D11RenderTargetView RTV;
|
||||||
|
|
||||||
|
public D3D11RenderTarget(D3D11Resources resources, int width, int height)
|
||||||
|
: base(resources, BindFlags.ShaderResource | BindFlags.RenderTarget, ResourceUsage.Default, CpuAccessFlags.None, width, height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CreateTexture()
|
||||||
|
{
|
||||||
|
base.CreateTexture();
|
||||||
|
var rtvd = new RenderTargetViewDescription(RenderTargetViewDimension.Texture2D, Format.B8G8R8A8_UNorm);
|
||||||
|
RTV = Device.CreateRenderTargetView(Texture, rtvd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DestroyTexture()
|
||||||
|
{
|
||||||
|
RTV?.Dispose();
|
||||||
|
RTV = null;
|
||||||
|
base.DestroyTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Bind()
|
||||||
|
{
|
||||||
|
Context.OMSetRenderTargets(RTV);
|
||||||
|
_resources.CurRenderTarget = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
=> $"D3D11 RenderTarget: {Width}x{Height}";
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,8 +26,9 @@ namespace BizHawk.Bizware.Graphics
|
||||||
|
|
||||||
public FeatureLevel DeviceFeatureLevel;
|
public FeatureLevel DeviceFeatureLevel;
|
||||||
|
|
||||||
public readonly HashSet<RenderTarget> RenderTargets = new();
|
public D3D11RenderTarget CurRenderTarget;
|
||||||
public readonly HashSet<D3D11Texture2D> ShaderTextures = new();
|
|
||||||
|
public readonly HashSet<D3D11Texture2D> Textures = new();
|
||||||
public readonly HashSet<Shader> VertexShaders = new();
|
public readonly HashSet<Shader> VertexShaders = new();
|
||||||
public readonly HashSet<Shader> PixelShaders = new();
|
public readonly HashSet<Shader> PixelShaders = new();
|
||||||
public readonly HashSet<Pipeline> Pipelines = new();
|
public readonly HashSet<Pipeline> Pipelines = new();
|
||||||
|
@ -94,6 +95,11 @@ namespace BizHawk.Bizware.Graphics
|
||||||
RasterizerState = Device.CreateRasterizerState(rd);
|
RasterizerState = Device.CreateRasterizerState(rd);
|
||||||
|
|
||||||
Context.IASetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
Context.IASetPrimitiveTopology(PrimitiveTopology.TriangleStrip);
|
||||||
|
|
||||||
|
foreach (var tex2d in Textures)
|
||||||
|
{
|
||||||
|
tex2d.CreateTexture();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -102,8 +108,15 @@ namespace BizHawk.Bizware.Graphics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void DestroyResources()
|
||||||
{
|
{
|
||||||
|
foreach (var tex2d in Textures)
|
||||||
|
{
|
||||||
|
tex2d.DestroyTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
CurRenderTarget = null;
|
||||||
|
|
||||||
LinearSamplerState?.Dispose();
|
LinearSamplerState?.Dispose();
|
||||||
LinearSamplerState = null;
|
LinearSamplerState = null;
|
||||||
PointSamplerState?.Dispose();
|
PointSamplerState?.Dispose();
|
||||||
|
@ -128,5 +141,11 @@ namespace BizHawk.Bizware.Graphics
|
||||||
Factory1?.Dispose();
|
Factory1?.Dispose();
|
||||||
Factory1 = null;
|
Factory1 = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
DestroyResources();
|
||||||
|
Textures.Clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,18 +10,18 @@ namespace BizHawk.Bizware.Graphics
|
||||||
{
|
{
|
||||||
internal class D3D11Texture2D : ITexture2D
|
internal class D3D11Texture2D : ITexture2D
|
||||||
{
|
{
|
||||||
private readonly D3D11Resources _resources;
|
protected readonly D3D11Resources _resources;
|
||||||
private readonly BindFlags _bindFlags;
|
private readonly BindFlags _bindFlags;
|
||||||
private readonly ResourceUsage _usage;
|
private readonly ResourceUsage _usage;
|
||||||
private readonly CpuAccessFlags _cpuAccessFlags;
|
private readonly CpuAccessFlags _cpuAccessFlags;
|
||||||
|
|
||||||
private ID3D11Device Device => _resources.Device;
|
protected ID3D11Device Device => _resources.Device;
|
||||||
private ID3D11DeviceContext Context => _resources.Context;
|
protected ID3D11DeviceContext Context => _resources.Context;
|
||||||
private HashSet<D3D11Texture2D> ShaderTextures => _resources.ShaderTextures;
|
private HashSet<D3D11Texture2D> Textures => _resources.Textures;
|
||||||
|
|
||||||
private ID3D11Texture2D StagingTexture;
|
private ID3D11Texture2D StagingTexture;
|
||||||
|
|
||||||
public ID3D11Texture2D Texture;
|
protected ID3D11Texture2D Texture;
|
||||||
public ID3D11ShaderResourceView SRV;
|
public ID3D11ShaderResourceView SRV;
|
||||||
public bool LinearFiltering;
|
public bool LinearFiltering;
|
||||||
|
|
||||||
|
@ -37,17 +37,18 @@ namespace BizHawk.Bizware.Graphics
|
||||||
_cpuAccessFlags = cpuAccessFlags;
|
_cpuAccessFlags = cpuAccessFlags;
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
|
// ReSharper disable once VirtualMemberCallInConstructor
|
||||||
CreateTexture();
|
CreateTexture();
|
||||||
ShaderTextures.Add(this);
|
Textures.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
DestroyTexture();
|
DestroyTexture();
|
||||||
ShaderTextures.Remove(this);
|
Textures.Remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateTexture()
|
public virtual void CreateTexture()
|
||||||
{
|
{
|
||||||
Texture = Device.CreateTexture2D(
|
Texture = Device.CreateTexture2D(
|
||||||
Format.B8G8R8A8_UNorm,
|
Format.B8G8R8A8_UNorm,
|
||||||
|
@ -62,7 +63,7 @@ namespace BizHawk.Bizware.Graphics
|
||||||
SRV = Device.CreateShaderResourceView(Texture, srvd);
|
SRV = Device.CreateShaderResourceView(Texture, srvd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DestroyTexture()
|
public virtual void DestroyTexture()
|
||||||
{
|
{
|
||||||
SRV?.Dispose();
|
SRV?.Dispose();
|
||||||
SRV = null;
|
SRV = null;
|
||||||
|
|
|
@ -38,10 +38,10 @@ namespace BizHawk.Bizware.Graphics
|
||||||
private ID3D11RasterizerState RasterizerState => _resources.RasterizerState;
|
private ID3D11RasterizerState RasterizerState => _resources.RasterizerState;
|
||||||
|
|
||||||
private FeatureLevel DeviceFeatureLevel => _resources.DeviceFeatureLevel;
|
private FeatureLevel DeviceFeatureLevel => _resources.DeviceFeatureLevel;
|
||||||
|
private D3D11RenderTarget CurRenderTarget => _resources.CurRenderTarget;
|
||||||
|
|
||||||
// rendering state
|
// rendering state
|
||||||
private Pipeline _curPipeline;
|
private Pipeline _curPipeline;
|
||||||
private RenderTarget _curRenderTarget;
|
|
||||||
private D3D11SwapChain.SwapChainResources _controlSwapChain;
|
private D3D11SwapChain.SwapChainResources _controlSwapChain;
|
||||||
|
|
||||||
public IGL_D3D11()
|
public IGL_D3D11()
|
||||||
|
@ -151,32 +151,9 @@ namespace BizHawk.Bizware.Graphics
|
||||||
sw.PS = null;
|
sw.PS = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var rw in _resources.RenderTargets.Select(rt => (RenderTargetWrapper)rt.Opaque))
|
_resources.DestroyResources();
|
||||||
{
|
|
||||||
rw.RTV.Dispose();
|
|
||||||
rw.RTV = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var tex2d in _resources.ShaderTextures)
|
|
||||||
{
|
|
||||||
tex2d.DestroyTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
_resources.Dispose();
|
|
||||||
_resources.CreateResources();
|
_resources.CreateResources();
|
||||||
|
|
||||||
foreach (var tex2d in _resources.ShaderTextures)
|
|
||||||
{
|
|
||||||
tex2d.CreateTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var rt in _resources.RenderTargets)
|
|
||||||
{
|
|
||||||
var rw = (RenderTargetWrapper)rt.Opaque;
|
|
||||||
var rtvd = new RenderTargetViewDescription(RenderTargetViewDimension.Texture2D, Format.B8G8R8A8_UNorm);
|
|
||||||
rw.RTV = Device.CreateRenderTargetView(((D3D11Texture2D)rt.Texture2D).Texture, rtvd);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var sw in _resources.VertexShaders.Select(vertexShader => (ShaderWrapper)vertexShader.Opaque))
|
foreach (var sw in _resources.VertexShaders.Select(vertexShader => (ShaderWrapper)vertexShader.Opaque))
|
||||||
{
|
{
|
||||||
sw.VS = Device.CreateVertexShader(sw.Bytecode.Span);
|
sw.VS = Device.CreateVertexShader(sw.Bytecode.Span);
|
||||||
|
@ -264,17 +241,7 @@ namespace BizHawk.Bizware.Graphics
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearColor(Color color)
|
public void ClearColor(Color color)
|
||||||
{
|
=> Context.ClearRenderTargetView(CurRenderTarget?.RTV ?? _controlSwapChain.RTV, new(color.R, color.B, color.G, color.A));
|
||||||
if (_curRenderTarget == null)
|
|
||||||
{
|
|
||||||
Context.ClearRenderTargetView(_controlSwapChain.RTV, new(color.R, color.B, color.G, color.A));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var rw = (RenderTargetWrapper)_curRenderTarget.Opaque;
|
|
||||||
Context.ClearRenderTargetView(rw.RTV, new(color.R, color.B, color.G, color.A));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ShaderWrapper // Disposable fields cleaned up by Internal_FreeShader
|
private class ShaderWrapper // Disposable fields cleaned up by Internal_FreeShader
|
||||||
{
|
{
|
||||||
|
@ -607,11 +574,6 @@ namespace BizHawk.Bizware.Graphics
|
||||||
public ShaderWrapper VertexShader, FragmentShader;
|
public ShaderWrapper VertexShader, FragmentShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RenderTargetWrapper
|
|
||||||
{
|
|
||||||
public ID3D11RenderTargetView RTV;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class VertexLayoutWrapper
|
private class VertexLayoutWrapper
|
||||||
{
|
{
|
||||||
public ID3D11InputLayout VertexInputLayout;
|
public ID3D11InputLayout VertexInputLayout;
|
||||||
|
@ -875,36 +837,13 @@ namespace BizHawk.Bizware.Graphics
|
||||||
Context.RSSetScissorRect(x, y, width, height);
|
Context.RSSetScissorRect(x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FreeRenderTarget(RenderTarget rt)
|
public IRenderTarget CreateRenderTarget(int width, int height)
|
||||||
|
=> new D3D11RenderTarget(_resources, width, height);
|
||||||
|
|
||||||
|
public void BindDefaultRenderTarget()
|
||||||
{
|
{
|
||||||
var rw = (RenderTargetWrapper)rt.Opaque;
|
_resources.CurRenderTarget = null;
|
||||||
rw.RTV.Dispose();
|
Context.OMSetRenderTargets(_controlSwapChain.RTV);
|
||||||
_resources.RenderTargets.Remove(rt);
|
|
||||||
rt.Texture2D.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RenderTarget CreateRenderTarget(int width, int height)
|
|
||||||
{
|
|
||||||
var tex = new D3D11Texture2D(_resources, BindFlags.ShaderResource | BindFlags.RenderTarget, ResourceUsage.Default, CpuAccessFlags.None, width, height);
|
|
||||||
var rtvd = new RenderTargetViewDescription(RenderTargetViewDimension.Texture2D, Format.B8G8R8A8_UNorm);
|
|
||||||
var rw = new RenderTargetWrapper { RTV = Device.CreateRenderTargetView(tex.Texture, rtvd) };
|
|
||||||
var rt = new RenderTarget(this, rw, tex);
|
|
||||||
_resources.RenderTargets.Add(rt);
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BindRenderTarget(RenderTarget rt)
|
|
||||||
{
|
|
||||||
_curRenderTarget = rt;
|
|
||||||
|
|
||||||
if (rt == null)
|
|
||||||
{
|
|
||||||
Context.OMSetRenderTargets(_controlSwapChain.RTV);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var rw = (RenderTargetWrapper)rt.Opaque;
|
|
||||||
Context.OMSetRenderTargets(rw.RTV);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(IntPtr data, int count)
|
public void Draw(IntPtr data, int count)
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
|
||||||
|
using SDGraphics = System.Drawing.Graphics;
|
||||||
|
|
||||||
|
namespace BizHawk.Bizware.Graphics
|
||||||
|
{
|
||||||
|
public sealed class GDIPlusControlRenderTarget : IDisposable
|
||||||
|
{
|
||||||
|
private readonly Func<(SDGraphics, Rectangle)> _getControlRenderContext;
|
||||||
|
private BufferedGraphicsContext _bufferedGraphicsContext = new();
|
||||||
|
|
||||||
|
public SDGraphics ControlGraphics;
|
||||||
|
public BufferedGraphics BufferedGraphics;
|
||||||
|
|
||||||
|
internal GDIPlusControlRenderTarget(Func<(SDGraphics Graphics, Rectangle Rectangle)> getControlRenderContext)
|
||||||
|
=> _getControlRenderContext = getControlRenderContext;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
ControlGraphics?.Dispose();
|
||||||
|
ControlGraphics = null;
|
||||||
|
BufferedGraphics?.Dispose();
|
||||||
|
BufferedGraphics = null;
|
||||||
|
_bufferedGraphicsContext?.Dispose();
|
||||||
|
_bufferedGraphicsContext = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateGraphics()
|
||||||
|
{
|
||||||
|
ControlGraphics?.Dispose();
|
||||||
|
BufferedGraphics?.Dispose();
|
||||||
|
(ControlGraphics, var r) = _getControlRenderContext();
|
||||||
|
BufferedGraphics = _bufferedGraphicsContext.Allocate(ControlGraphics, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,63 +1,30 @@
|
||||||
using System;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
using SDGraphics = System.Drawing.Graphics;
|
using SDGraphics = System.Drawing.Graphics;
|
||||||
|
|
||||||
namespace BizHawk.Bizware.Graphics
|
namespace BizHawk.Bizware.Graphics
|
||||||
{
|
{
|
||||||
public class GDIPlusRenderTarget : IDisposable
|
internal sealed class GDIPlusRenderTarget : GDIPlusTexture2D, IRenderTarget
|
||||||
{
|
{
|
||||||
internal GDIPlusRenderTarget(Func<BufferedGraphicsContext> getBufferedGraphicsContext,
|
private readonly IGL_GDIPlus _gdiPlus;
|
||||||
Func<(SDGraphics Graphics, Rectangle Rectangle)> getControlRenderContext = null)
|
public SDGraphics TextureGraphics;
|
||||||
|
|
||||||
|
internal GDIPlusRenderTarget(IGL_GDIPlus gdiPlus, int width, int height)
|
||||||
|
: base(width, height)
|
||||||
{
|
{
|
||||||
_getBufferedGraphicsContext = getBufferedGraphicsContext;
|
_gdiPlus = gdiPlus;
|
||||||
_getControlRenderContext = getControlRenderContext;
|
TextureGraphics = SDGraphics.FromImage(SDBitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
if (_getControlRenderContext != null)
|
TextureGraphics?.Dispose();
|
||||||
{
|
TextureGraphics = null;
|
||||||
CurGraphics?.Dispose();
|
base.Dispose();
|
||||||
CurGraphics = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedGraphics?.Dispose();
|
|
||||||
BufferedGraphics = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly Func<BufferedGraphicsContext> _getBufferedGraphicsContext;
|
public void Bind()
|
||||||
|
=> _gdiPlus.CurRenderTarget = this;
|
||||||
|
|
||||||
/// <summary>
|
public override string ToString()
|
||||||
/// get Graphics and Rectangle from a control, if any
|
=> $"GDI+ RenderTarget: {Width}x{Height}";
|
||||||
/// </summary>
|
|
||||||
private readonly Func<(SDGraphics, Rectangle)> _getControlRenderContext;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// the offscreen render target, if that's what this is representing
|
|
||||||
/// </summary>
|
|
||||||
public RenderTarget Target;
|
|
||||||
|
|
||||||
public SDGraphics CurGraphics;
|
|
||||||
public BufferedGraphics BufferedGraphics;
|
|
||||||
|
|
||||||
public void CreateGraphics()
|
|
||||||
{
|
|
||||||
Rectangle r;
|
|
||||||
if (_getControlRenderContext != null)
|
|
||||||
{
|
|
||||||
(CurGraphics, r) = _getControlRenderContext();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var gtex = (GDIPlusTexture2D)Target.Texture2D;
|
|
||||||
CurGraphics?.Dispose();
|
|
||||||
CurGraphics = SDGraphics.FromImage(gtex.SDBitmap);
|
|
||||||
r = gtex.GetRectangle();
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferedGraphics?.Dispose();
|
|
||||||
BufferedGraphics = _getBufferedGraphicsContext().Allocate(CurGraphics, r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Drawing.Imaging;
|
||||||
|
|
||||||
namespace BizHawk.Bizware.Graphics
|
namespace BizHawk.Bizware.Graphics
|
||||||
{
|
{
|
||||||
public class GDIPlusTexture2D : ITexture2D
|
internal class GDIPlusTexture2D : ITexture2D
|
||||||
{
|
{
|
||||||
public Bitmap SDBitmap;
|
public Bitmap SDBitmap;
|
||||||
public bool LinearFiltering;
|
public bool LinearFiltering;
|
||||||
|
@ -19,7 +19,7 @@ namespace BizHawk.Bizware.Graphics
|
||||||
SDBitmap = new(width, height, PixelFormat.Format32bppArgb);
|
SDBitmap = new(width, height, PixelFormat.Format32bppArgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public virtual void Dispose()
|
||||||
{
|
{
|
||||||
SDBitmap?.Dispose();
|
SDBitmap?.Dispose();
|
||||||
SDBitmap = null;
|
SDBitmap = null;
|
||||||
|
|
|
@ -5,15 +5,22 @@ using System.Numerics;
|
||||||
|
|
||||||
using SDGraphics = System.Drawing.Graphics;
|
using SDGraphics = System.Drawing.Graphics;
|
||||||
|
|
||||||
//TODO - maybe a layer to cache Graphics parameters (notably, filtering) ?
|
|
||||||
namespace BizHawk.Bizware.Graphics
|
namespace BizHawk.Bizware.Graphics
|
||||||
{
|
{
|
||||||
public class IGL_GDIPlus : IGL
|
public class IGL_GDIPlus : IGL
|
||||||
{
|
{
|
||||||
|
private GDIPlusControlRenderTarget _controlRenderTarget;
|
||||||
|
|
||||||
|
internal GDIPlusRenderTarget CurRenderTarget;
|
||||||
|
|
||||||
public EDispMethod DispMethodEnum => EDispMethod.GdiPlus;
|
public EDispMethod DispMethodEnum => EDispMethod.GdiPlus;
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
=> BufferedGraphicsContext.Dispose();
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
internal SDGraphics GetCurrentGraphics()
|
||||||
|
=> CurRenderTarget?.TextureGraphics ?? _controlRenderTarget.BufferedGraphics.Graphics;
|
||||||
|
|
||||||
public void ClearColor(Color color)
|
public void ClearColor(Color color)
|
||||||
=> GetCurrentGraphics().Clear(color);
|
=> GetCurrentGraphics().Clear(color);
|
||||||
|
@ -118,62 +125,21 @@ namespace BizHawk.Bizware.Graphics
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FreeRenderTarget(RenderTarget rt)
|
public IRenderTarget CreateRenderTarget(int width, int height)
|
||||||
{
|
=> new GDIPlusRenderTarget(this, width, height);
|
||||||
var grt = (GDIPlusRenderTarget)rt.Opaque;
|
|
||||||
grt.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
public RenderTarget CreateRenderTarget(int width, int height)
|
public void BindDefaultRenderTarget()
|
||||||
{
|
=> CurRenderTarget = null;
|
||||||
var tex2d = new GDIPlusTexture2D(width, height);
|
|
||||||
var grt = new GDIPlusRenderTarget(() => BufferedGraphicsContext);
|
|
||||||
var rt = new RenderTarget(this, grt, tex2d);
|
|
||||||
grt.Target = rt;
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BindRenderTarget(RenderTarget rt)
|
public GDIPlusControlRenderTarget CreateControlRenderTarget(Func<(SDGraphics Graphics, Rectangle Rectangle)> getControlRenderContext)
|
||||||
{
|
|
||||||
if (_currOffscreenGraphics != null)
|
|
||||||
{
|
|
||||||
_currOffscreenGraphics.Dispose();
|
|
||||||
_currOffscreenGraphics = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rt == null)
|
|
||||||
{
|
|
||||||
// null means to use the default RT for the current control
|
|
||||||
CurrentRenderTarget = _controlRenderTarget;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var gtex = (GDIPlusTexture2D)rt.Texture2D;
|
|
||||||
CurrentRenderTarget = (GDIPlusRenderTarget)rt.Opaque;
|
|
||||||
_currOffscreenGraphics = SDGraphics.FromImage(gtex.SDBitmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private GDIPlusRenderTarget _controlRenderTarget;
|
|
||||||
|
|
||||||
public GDIPlusRenderTarget CreateControlRenderTarget(Func<(SDGraphics Graphics, Rectangle Rectangle)> getControlRenderContext)
|
|
||||||
{
|
{
|
||||||
if (_controlRenderTarget != null)
|
if (_controlRenderTarget != null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"{nameof(IGL_GDIPlus)} can only have one control render target");
|
throw new InvalidOperationException($"{nameof(IGL_GDIPlus)} can only have one control render target");
|
||||||
}
|
}
|
||||||
|
|
||||||
_controlRenderTarget = new(() => BufferedGraphicsContext, getControlRenderContext);
|
_controlRenderTarget = new(getControlRenderContext);
|
||||||
return _controlRenderTarget;
|
return _controlRenderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SDGraphics _currOffscreenGraphics;
|
|
||||||
|
|
||||||
public SDGraphics GetCurrentGraphics()
|
|
||||||
=> _currOffscreenGraphics ?? CurrentRenderTarget.BufferedGraphics.Graphics;
|
|
||||||
|
|
||||||
public GDIPlusRenderTarget CurrentRenderTarget;
|
|
||||||
|
|
||||||
public readonly BufferedGraphicsContext BufferedGraphicsContext = new();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,17 +19,17 @@ namespace BizHawk.Bizware.Graphics
|
||||||
EDispMethod DispMethodEnum { get; }
|
EDispMethod DispMethodEnum { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears the color buffer with the specified color
|
/// Clears the currently bound render target with the specified color
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void ClearColor(Color color);
|
void ClearColor(Color color);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// compile a fragment shader. This is the simplified method. A more complex method may be added later which will accept multiple sources and preprocessor definitions independently
|
/// Compile a fragment shader. This is the simplified method. A more complex method may be added later which will accept multiple sources and preprocessor definitions independently
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Shader CreateFragmentShader(string source, string entry, bool required);
|
Shader CreateFragmentShader(string source, string entry, bool required);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// compile a vertex shader. This is the simplified method. A more complex method may be added later which will accept multiple sources and preprocessor definitions independently
|
/// Compile a vertex shader. This is the simplified method. A more complex method may be added later which will accept multiple sources and preprocessor definitions independently
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Shader CreateVertexShader(string source, string entry, bool required);
|
Shader CreateVertexShader(string source, string entry, bool required);
|
||||||
|
|
||||||
|
@ -59,40 +59,40 @@ namespace BizHawk.Bizware.Graphics
|
||||||
void SetPipelineUniformMatrix(PipelineUniform uniform, ref Matrix4x4 mat, bool transpose);
|
void SetPipelineUniformMatrix(PipelineUniform uniform, ref Matrix4x4 mat, bool transpose);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// sets a uniform value
|
/// Sets a uniform value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetPipelineUniform(PipelineUniform uniform, Vector4 value);
|
void SetPipelineUniform(PipelineUniform uniform, Vector4 value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// sets a uniform value
|
/// Sets a uniform value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetPipelineUniform(PipelineUniform uniform, Vector2 value);
|
void SetPipelineUniform(PipelineUniform uniform, Vector2 value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// sets a uniform value
|
/// Sets a uniform value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetPipelineUniform(PipelineUniform uniform, float value);
|
void SetPipelineUniform(PipelineUniform uniform, float value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// sets uniform values
|
/// Sets uniform values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetPipelineUniform(PipelineUniform uniform, Vector4[] values);
|
void SetPipelineUniform(PipelineUniform uniform, Vector4[] values);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// sets a uniform value
|
/// Sets a uniform value
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetPipelineUniform(PipelineUniform uniform, bool value);
|
void SetPipelineUniform(PipelineUniform uniform, bool value);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Draws based on the currently set pipeline
|
/// Draws based on the currently set pipeline
|
||||||
/// data contains vertexes based on the pipeline's VertexLayout
|
/// Data contains vertexes based on the pipeline's VertexLayout
|
||||||
/// count is the vertex count
|
/// Count is the vertex count
|
||||||
/// Vertexes must form triangle strips
|
/// Vertexes must form triangle strips
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Draw(IntPtr data, int count);
|
void Draw(IntPtr data, int count);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// creates a vertex layout resource
|
/// Creates a vertex layout resource
|
||||||
/// </summary>
|
/// </summary>
|
||||||
VertexLayout CreateVertexLayout();
|
VertexLayout CreateVertexLayout();
|
||||||
|
|
||||||
|
@ -119,35 +119,32 @@ namespace BizHawk.Bizware.Graphics
|
||||||
ITexture2D WrapGLTexture2D(int glTexId, int width, int height);
|
ITexture2D WrapGLTexture2D(int glTexId, int width, int height);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// sets the viewport (and scissor) according to the provided specifications
|
/// Sets the viewport (and scissor) according to the provided specifications
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void SetViewport(int x, int y, int width, int height);
|
void SetViewport(int x, int y, int width, int height);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// generates a proper 2d othographic projection for the given destination size, suitable for use in a GUI
|
/// Generates a proper 2D othographic projection for the given destination size, suitable for use in a GUI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Matrix4x4 CreateGuiProjectionMatrix(int width, int height);
|
Matrix4x4 CreateGuiProjectionMatrix(int width, int height);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// generates a proper view transform for a standard 2d ortho projection, including half-pixel jitter if necessary and
|
/// Generates a proper view transform for a standard 2D othographic projection, including half-pixel jitter if necessary
|
||||||
/// re-establishing of a normal 2d graphics top-left origin. suitable for use in a GUI
|
/// and re-establishing of a normal 2D graphics top-left origin. Suitable for use in a GUI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Matrix4x4 CreateGuiViewMatrix(int width, int height, bool autoflip = true);
|
Matrix4x4 CreateGuiViewMatrix(int width, int height, bool autoflip = true);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a render target. Only includes a color buffer. Pixel format control TBD
|
/// Creates a render target. Only includes a color buffer, and will always be in byte order BGRA (i.e. little endian ARGB)
|
||||||
|
/// This may unbind a previously bound render target
|
||||||
/// </summary>
|
/// </summary>
|
||||||
RenderTarget CreateRenderTarget(int width, int height);
|
IRenderTarget CreateRenderTarget(int width, int height);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binds a RenderTarget for current rendering
|
/// Binds the IGL's default render target (i.e. to the IGL's control)
|
||||||
|
/// This implicitly unbinds any previously bound IRenderTarget
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void BindRenderTarget(RenderTarget rt);
|
void BindDefaultRenderTarget();
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Frees the provided render target. Same as disposing the resource.
|
|
||||||
/// </summary>
|
|
||||||
void FreeRenderTarget(RenderTarget rt);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Frees the provided pipeline. Same as disposing the resource.
|
/// Frees the provided pipeline. Same as disposing the resource.
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
namespace BizHawk.Bizware.Graphics
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A render target, essentially just a 2D texture which can be written as if it was a window
|
||||||
|
/// As this is effectively a texture, it inherits ITexture2D
|
||||||
|
/// However, note that semantically the CPU shouldn't be writing to a render target, so LoadFrom might not work!
|
||||||
|
/// </summary>
|
||||||
|
public interface IRenderTarget : ITexture2D
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Binds this render target
|
||||||
|
/// </summary>
|
||||||
|
void Bind();
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,7 +34,7 @@ namespace BizHawk.Bizware.Graphics
|
||||||
|
|
||||||
// rendering state
|
// rendering state
|
||||||
private Pipeline _currPipeline;
|
private Pipeline _currPipeline;
|
||||||
private RenderTarget _currRenderTarget;
|
internal bool DefaultRenderTargetBound;
|
||||||
|
|
||||||
// this IGL either requires at least OpenGL 3.0
|
// this IGL either requires at least OpenGL 3.0
|
||||||
public static bool Available => OpenGLVersion.SupportsVersion(3, 0);
|
public static bool Available => OpenGLVersion.SupportsVersion(3, 0);
|
||||||
|
@ -451,50 +451,14 @@ namespace BizHawk.Bizware.Graphics
|
||||||
public ITexture2D WrapGLTexture2D(int glTexId, int width, int height)
|
public ITexture2D WrapGLTexture2D(int glTexId, int width, int height)
|
||||||
=> new OpenGLTexture2D(GL, (uint)glTexId, width, height);
|
=> new OpenGLTexture2D(GL, (uint)glTexId, width, height);
|
||||||
|
|
||||||
public void FreeRenderTarget(RenderTarget rt)
|
|
||||||
{
|
|
||||||
rt.Texture2D.Dispose();
|
|
||||||
GL.DeleteFramebuffer((uint)rt.Opaque);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <exception cref="InvalidOperationException">framebuffer creation unsuccessful</exception>
|
/// <exception cref="InvalidOperationException">framebuffer creation unsuccessful</exception>
|
||||||
public RenderTarget CreateRenderTarget(int width, int height)
|
public IRenderTarget CreateRenderTarget(int width, int height)
|
||||||
|
=> new OpenGLRenderTarget(this, GL, width, height);
|
||||||
|
|
||||||
|
public void BindDefaultRenderTarget()
|
||||||
{
|
{
|
||||||
// create a texture for it
|
|
||||||
var tex2d = new OpenGLTexture2D(GL, width, height);
|
|
||||||
|
|
||||||
// create the FBO
|
|
||||||
var fbId = GL.GenFramebuffer();
|
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbId);
|
|
||||||
|
|
||||||
// bind the tex to the FBO
|
|
||||||
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, tex2d.TexID, 0);
|
|
||||||
|
|
||||||
// do something, I guess say which color buffers are used by the framebuffer
|
|
||||||
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
|
|
||||||
|
|
||||||
if ((FramebufferStatus)GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.Complete)
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"Error creating framebuffer (at {nameof(GL.CheckFramebufferStatus)})");
|
|
||||||
}
|
|
||||||
|
|
||||||
// since we're done configuring unbind this framebuffer, to return to the default
|
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
||||||
|
DefaultRenderTargetBound = true;
|
||||||
return new(this, fbId, tex2d);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BindRenderTarget(RenderTarget rt)
|
|
||||||
{
|
|
||||||
_currRenderTarget = rt;
|
|
||||||
if (rt == null)
|
|
||||||
{
|
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, (uint)rt.Opaque);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Matrix4x4 CreateGuiProjectionMatrix(int width, int height)
|
public Matrix4x4 CreateGuiProjectionMatrix(int width, int height)
|
||||||
|
@ -511,7 +475,7 @@ namespace BizHawk.Bizware.Graphics
|
||||||
ret.M22 = -1.0f;
|
ret.M22 = -1.0f;
|
||||||
ret.M41 = width * -0.5f;
|
ret.M41 = width * -0.5f;
|
||||||
ret.M42 = height * 0.5f;
|
ret.M42 = height * 0.5f;
|
||||||
if (autoflip && _currRenderTarget is not null) // flip as long as we're not a final render target
|
if (autoflip && !DefaultRenderTargetBound) // flip as long as we're not a final render target
|
||||||
{
|
{
|
||||||
ret.M22 = 1.0f;
|
ret.M22 = 1.0f;
|
||||||
ret.M42 *= -1;
|
ret.M42 *= -1;
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Silk.NET.OpenGL.Legacy;
|
||||||
|
|
||||||
|
namespace BizHawk.Bizware.Graphics
|
||||||
|
{
|
||||||
|
internal sealed class OpenGLRenderTarget : OpenGLTexture2D, IRenderTarget
|
||||||
|
{
|
||||||
|
private readonly IGL_OpenGL _openGL;
|
||||||
|
private readonly GL GL;
|
||||||
|
|
||||||
|
public readonly uint FBO;
|
||||||
|
|
||||||
|
public OpenGLRenderTarget(IGL_OpenGL openGL, GL gl, int width, int height)
|
||||||
|
: base(gl, width, height)
|
||||||
|
{
|
||||||
|
_openGL = openGL;
|
||||||
|
GL = gl;
|
||||||
|
|
||||||
|
// create the FBO
|
||||||
|
FBO = GL.GenFramebuffer();
|
||||||
|
Bind();
|
||||||
|
|
||||||
|
// bind the tex to the FBO
|
||||||
|
GL.FramebufferTexture2D(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D, TexID, 0);
|
||||||
|
|
||||||
|
// do something, I guess say which color buffers are used by the framebuffer
|
||||||
|
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
|
||||||
|
|
||||||
|
if ((FramebufferStatus)GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferStatus.Complete)
|
||||||
|
{
|
||||||
|
Dispose();
|
||||||
|
throw new InvalidOperationException($"Error creating framebuffer (at {nameof(GL.CheckFramebufferStatus)})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
GL.DeleteFramebuffer(FBO);
|
||||||
|
base.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Bind()
|
||||||
|
{
|
||||||
|
GL.BindFramebuffer(FramebufferTarget.Framebuffer, FBO);
|
||||||
|
_openGL.DefaultRenderTargetBound = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
=> $"OpenGL RenderTarget: {Width}x{Height}";
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,7 +44,7 @@ namespace BizHawk.Bizware.Graphics
|
||||||
IsUpsideDown = true;
|
IsUpsideDown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public virtual void Dispose()
|
||||||
=> GL.DeleteTexture(TexID);
|
=> GL.DeleteTexture(TexID);
|
||||||
|
|
||||||
public unsafe BitmapBuffer Resolve()
|
public unsafe BitmapBuffer Resolve()
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace BizHawk.Bizware.Graphics
|
|
||||||
{
|
|
||||||
public class RenderTarget : IDisposable
|
|
||||||
{
|
|
||||||
public RenderTarget(IGL owner, object opaque, ITexture2D tex)
|
|
||||||
{
|
|
||||||
Owner = owner;
|
|
||||||
Opaque = opaque;
|
|
||||||
Texture2D = tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return $"GL RT: {Texture2D.Width}x{Texture2D.Height}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public object Opaque { get; }
|
|
||||||
public IGL Owner { get; }
|
|
||||||
public ITexture2D Texture2D { get; }
|
|
||||||
|
|
||||||
public void Unbind()
|
|
||||||
{
|
|
||||||
Owner.BindRenderTarget(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Bind()
|
|
||||||
{
|
|
||||||
Owner.BindRenderTarget(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
Owner.FreeRenderTarget(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -32,14 +32,14 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
protected class DisplayManagerRenderTargetProvider : IRenderTargetProvider
|
protected class DisplayManagerRenderTargetProvider : IRenderTargetProvider
|
||||||
{
|
{
|
||||||
private readonly Func<Size, RenderTarget> _callback;
|
private readonly Func<Size, IRenderTarget> _callback;
|
||||||
|
|
||||||
RenderTarget IRenderTargetProvider.Get(Size size)
|
public IRenderTarget Get(Size size)
|
||||||
{
|
{
|
||||||
return _callback(size);
|
return _callback(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DisplayManagerRenderTargetProvider(Func<Size, RenderTarget> callback)
|
public DisplayManagerRenderTargetProvider(Func<Size, IRenderTarget> callback)
|
||||||
{
|
{
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
}
|
}
|
||||||
|
@ -864,7 +864,7 @@ namespace BizHawk.Client.Common
|
||||||
public void Blank()
|
public void Blank()
|
||||||
{
|
{
|
||||||
ActivateGraphicsControlContext();
|
ActivateGraphicsControlContext();
|
||||||
_gl.BindRenderTarget(null);
|
_gl.BindDefaultRenderTarget();
|
||||||
_gl.ClearColor(Color.Black);
|
_gl.ClearColor(Color.Black);
|
||||||
SwapBuffersOfGraphicsControl();
|
SwapBuffersOfGraphicsControl();
|
||||||
}
|
}
|
||||||
|
@ -880,11 +880,11 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
RunFilterChainSteps(ref rtCounter, out var rtCurr, out _);
|
RunFilterChainSteps(ref rtCounter, out var rtCurr, out _);
|
||||||
|
|
||||||
job.OffscreenBb = rtCurr.Texture2D.Resolve();
|
job.OffscreenBb = rtCurr.Resolve();
|
||||||
job.OffscreenBb.DiscardAlpha();
|
job.OffscreenBb.DiscardAlpha();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RunFilterChainSteps(ref int rtCounter, out RenderTarget rtCurr, out bool inFinalTarget)
|
protected void RunFilterChainSteps(ref int rtCounter, out IRenderTarget rtCurr, out bool inFinalTarget)
|
||||||
{
|
{
|
||||||
ITexture2D texCurr = null;
|
ITexture2D texCurr = null;
|
||||||
rtCurr = null;
|
rtCurr = null;
|
||||||
|
@ -907,7 +907,7 @@ namespace BizHawk.Client.Common
|
||||||
break;
|
break;
|
||||||
case FilterProgram.ProgramStepType.FinalTarget:
|
case FilterProgram.ProgramStepType.FinalTarget:
|
||||||
_currentFilterProgram.CurrRenderTarget = rtCurr = null;
|
_currentFilterProgram.CurrRenderTarget = rtCurr = null;
|
||||||
_gl.BindRenderTarget(rtCurr);
|
_gl.BindDefaultRenderTarget();
|
||||||
inFinalTarget = true;
|
inFinalTarget = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace BizHawk.Client.Common.FilterManager
|
||||||
|
|
||||||
public interface IRenderTargetProvider
|
public interface IRenderTargetProvider
|
||||||
{
|
{
|
||||||
RenderTarget Get(Size size);
|
IRenderTarget Get(Size size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FilterProgram
|
public class FilterProgram
|
||||||
|
@ -69,9 +69,9 @@ namespace BizHawk.Client.Common.FilterManager
|
||||||
public IGL GL;
|
public IGL GL;
|
||||||
public IRenderTargetProvider RenderTargetProvider;
|
public IRenderTargetProvider RenderTargetProvider;
|
||||||
|
|
||||||
public RenderTarget CurrRenderTarget;
|
public IRenderTarget CurrRenderTarget;
|
||||||
|
|
||||||
public RenderTarget GetTempTarget(int width, int height)
|
public IRenderTarget GetTempTarget(int width, int height)
|
||||||
{
|
{
|
||||||
return RenderTargetProvider.Get(new(width, height));
|
return RenderTargetProvider.Get(new(width, height));
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace BizHawk.Client.Common.Filters
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - why a different param order than DeclareOutput?
|
// TODO - why a different param order than DeclareOutput?
|
||||||
protected RenderTarget GetTempTarget(int width, int height)
|
protected IRenderTarget GetTempTarget(int width, int height)
|
||||||
{
|
{
|
||||||
return FilterProgram.GetTempTarget(width, height);
|
return FilterProgram.GetTempTarget(width, height);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace BizHawk.Client.Common.Filters
|
||||||
|
|
||||||
public override void Run()
|
public override void Run()
|
||||||
{
|
{
|
||||||
YieldOutput(FilterProgram.CurrRenderTarget.Texture2D);
|
YieldOutput(FilterProgram.CurrRenderTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -30,26 +30,26 @@ namespace BizHawk.Client.Common
|
||||||
|
|
||||||
private void ResetList()
|
private void ResetList()
|
||||||
{
|
{
|
||||||
_currentRenderTargets = new List<RenderTarget> { null, null };
|
_currentRenderTargets = new List<IRenderTarget> { null, null };
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IGL _gl;
|
private readonly IGL _gl;
|
||||||
private List<RenderTarget> _currentRenderTargets;
|
private List<IRenderTarget> _currentRenderTargets;
|
||||||
|
|
||||||
public RenderTarget Get(Size dimensions)
|
public IRenderTarget Get(Size dimensions)
|
||||||
{
|
{
|
||||||
return Get(dimensions.Width, dimensions.Height);
|
return Get(dimensions.Width, dimensions.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RenderTarget Get(int width, int height)
|
public IRenderTarget Get(int width, int height)
|
||||||
{
|
{
|
||||||
//get the current entry
|
//get the current entry
|
||||||
var currentRenderTarget = _currentRenderTargets[0];
|
var currentRenderTarget = _currentRenderTargets[0];
|
||||||
|
|
||||||
//check if its rotten and needs recreating
|
//check if its rotten and needs recreating
|
||||||
if (currentRenderTarget == null
|
if (currentRenderTarget == null
|
||||||
|| currentRenderTarget.Texture2D.Width != width
|
|| currentRenderTarget.Width != width
|
||||||
|| currentRenderTarget.Texture2D.Height != height)
|
|| currentRenderTarget.Height != height)
|
||||||
{
|
{
|
||||||
// needs recreating. be sure to kill the old one...
|
// needs recreating. be sure to kill the old one...
|
||||||
currentRenderTarget?.Dispose();
|
currentRenderTarget?.Dispose();
|
||||||
|
|
|
@ -99,7 +99,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
if (job.Offscreen)
|
if (job.Offscreen)
|
||||||
{
|
{
|
||||||
job.OffscreenBb = rtCurr.Texture2D.Resolve();
|
job.OffscreenBb = rtCurr.Resolve();
|
||||||
job.OffscreenBb.DiscardAlpha();
|
job.OffscreenBb.DiscardAlpha();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private readonly IGL _gl;
|
private readonly IGL _gl;
|
||||||
private readonly GraphicsControl _graphicsControl;
|
private readonly GraphicsControl _graphicsControl;
|
||||||
private RenderTarget _rt;
|
private IRenderTarget _rt;
|
||||||
private readonly GuiRenderer _guiRenderer;
|
private readonly GuiRenderer _guiRenderer;
|
||||||
|
|
||||||
protected override void OnPaint(PaintEventArgs e)
|
protected override void OnPaint(PaintEventArgs e)
|
||||||
|
@ -75,7 +75,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
if (_retain)
|
if (_retain)
|
||||||
{
|
{
|
||||||
_rt.Unbind();
|
_gl.BindDefaultRenderTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
_graphicsControl.End();
|
_graphicsControl.End();
|
||||||
|
@ -91,7 +91,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're retaining, then we cant draw until we unbind! its semantically a bit odd, but we expect users to call SwapBuffers() before end, so we cant unbind in End() even thoug hit makes a bit more sense.
|
// if we're retaining, then we cant draw until we unbind! its semantically a bit odd, but we expect users to call SwapBuffers() before end, so we cant unbind in End() even thoug hit makes a bit more sense.
|
||||||
_rt.Unbind();
|
_gl.BindDefaultRenderTarget();
|
||||||
Draw();
|
Draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,9 +104,9 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
_guiRenderer.Begin(Width, Height);
|
_guiRenderer.Begin(Width, Height);
|
||||||
_guiRenderer.DisableBlending();
|
_guiRenderer.DisableBlending();
|
||||||
_guiRenderer.Draw(_rt.Texture2D);
|
_guiRenderer.Draw(_rt);
|
||||||
_guiRenderer.End();
|
_guiRenderer.End();
|
||||||
_graphicsControl.SwapBuffers();
|
_graphicsControl.SwapBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue