BizHawk/Bizware/BizHawk.Bizware.BizwareGL/RetainedGraphicsControl.cs

104 lines
2.4 KiB
C#
Raw Normal View History

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BizHawk.Bizware.BizwareGL;
using OpenTK.Graphics.OpenGL;
namespace BizHawk.Bizware.BizwareGL
{
/// <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 thats annoying.
/// </summary>
public bool Retain
{
get { return _retain; }
set
{
if (_retain && !value)
{
rt.Dispose();
rt = null;
}
_retain = value;
}
}
bool _retain = true;
IGL GL;
RenderTarget rt;
GuiRenderer GuiRenderer;
public override void Begin()
{
base.Begin();
if (_retain)
{
//TODO - frugalize me
if (rt != null)
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();
}
void Draw()
{
if (rt == null) return;
GuiRenderer.Begin(Width, Height, true);
GuiRenderer.SetBlendState(GL.BlendNone);
GuiRenderer.Draw(rt.Texture2d);
GuiRenderer.End();
base.SwapBuffers();
}
public override void SwapBuffers()
{
//if we're not retaining, then we havent 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();
}
}
}