103 lines
2.4 KiB
C#
103 lines
2.4 KiB
C#
using System.Windows.Forms;
|
|
using BizHawk.Bizware.BizwareGL;
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
|
{
|
|
/// <summary>
|
|
/// Adapts a GraphicsControl to gain the power of remembering what was drawn to it, and keeping it presented in response to Paint events
|
|
/// </summary>
|
|
public class RetainedGraphicsControl : GraphicsControl
|
|
{
|
|
public RetainedGraphicsControl(IGL gl)
|
|
: base(gl)
|
|
{
|
|
_gl = gl;
|
|
_guiRenderer = new GuiRenderer(gl);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Control whether rendering goes into the retaining buffer (it's slower) or straight to the viewport.
|
|
/// This could be useful as a performance hack, or if someone was very clever, they could wait for a control to get deactivated, enable retaining, and render it one more time.
|
|
/// Of course, even better still is to be able to repaint viewports continually, but sometimes that's annoying.
|
|
/// </summary>
|
|
public bool Retain
|
|
{
|
|
get => _retain;
|
|
set
|
|
{
|
|
if (_retain && !value)
|
|
{
|
|
_rt.Dispose();
|
|
_rt = null;
|
|
}
|
|
_retain = value;
|
|
}
|
|
}
|
|
|
|
private bool _retain = true;
|
|
|
|
private readonly IGL _gl;
|
|
private RenderTarget _rt;
|
|
private readonly GuiRenderer _guiRenderer;
|
|
|
|
public override void Begin()
|
|
{
|
|
base.Begin();
|
|
|
|
if (_retain)
|
|
{
|
|
// TODO - frugalize me
|
|
_rt?.Dispose();
|
|
_rt = _gl.CreateRenderTarget(Width, Height);
|
|
_rt.Bind();
|
|
}
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
base.OnPaint(e);
|
|
// todo - check whether we're begun?
|
|
base.Begin();
|
|
Draw();
|
|
base.End();
|
|
}
|
|
|
|
private void Draw()
|
|
{
|
|
if (_rt == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_guiRenderer.Begin(Width, Height);
|
|
_guiRenderer.SetBlendState(_gl.BlendNoneCopy);
|
|
_guiRenderer.Draw(_rt.Texture2d);
|
|
_guiRenderer.End();
|
|
base.SwapBuffers();
|
|
}
|
|
|
|
public override void SwapBuffers()
|
|
{
|
|
// if we're not retaining, then we haven't been collecting into a framebuffer. just swap it
|
|
if (!_retain)
|
|
{
|
|
base.SwapBuffers();
|
|
return;
|
|
}
|
|
|
|
// 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();
|
|
Draw();
|
|
}
|
|
|
|
public override void End()
|
|
{
|
|
if (_retain)
|
|
{
|
|
_rt.Unbind();
|
|
}
|
|
|
|
base.End();
|
|
}
|
|
}
|
|
} |