display manager: sort out all the y-flipping madness and fix some bugs in gdi+ with screenshot and prescaling
This commit is contained in:
parent
d9b765ac89
commit
f0c34517e1
|
@ -576,7 +576,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
using (var bb = GlobalWin.DisplayManager.RenderOffscreen(Global.Emulator.VideoProvider(), Global.Config.Screenshot_CaptureOSD))
|
||||
{
|
||||
bb.Normalize(true);
|
||||
bb.DiscardAlpha();
|
||||
using (var img = bb.ToSysdrawingBitmap())
|
||||
Clipboard.SetImage(img);
|
||||
}
|
||||
|
|
|
@ -2285,7 +2285,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
public BitmapBuffer CaptureOSD()
|
||||
{
|
||||
var bb = GlobalWin.DisplayManager.RenderOffscreen(Global.Emulator.VideoProvider(), true);
|
||||
bb.Normalize(true);
|
||||
bb.DiscardAlpha();
|
||||
return bb;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
|
|||
public void Begin(sd.Size size) { Begin(size.Width, size.Height); }
|
||||
|
||||
|
||||
public void Begin(int width, int height, bool yflipped = false)
|
||||
public void Begin(int width, int height)
|
||||
{
|
||||
Begin();
|
||||
|
||||
|
@ -234,15 +234,9 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
|
|||
|
||||
private void SetupMatrix(sd.Graphics g)
|
||||
{
|
||||
//first we need to make a transform that will change us from the default GDI+ transformation (a top left identity transformation) to an opengl-styled one
|
||||
//(this is necessary because a 'GuiProjectionMatrix' etc. call doesnt have any sense of the size of the destination viewport it's meant for)
|
||||
var vcb = g.VisibleClipBounds;
|
||||
float vw = vcb.Width;
|
||||
float vh = vcb.Height;
|
||||
Matrix4 fixmat = Matrix4.CreateTranslation(vw / 2, -vh / 2, 0);
|
||||
fixmat *= Matrix4.CreateScale(vw / 2, -vh / 2, 1);
|
||||
|
||||
Matrix4 mat = Projection.Top * Modelview.Top * fixmat;
|
||||
//projection is always identity, so who cares i guess
|
||||
//Matrix4 mat = Projection.Top * Modelview.Top;
|
||||
Matrix4 mat = Modelview.Top;
|
||||
g.Transform = new sd.Drawing2D.Matrix(mat.M11, mat.M12, mat.M21, mat.M22, mat.M41, mat.M42);
|
||||
}
|
||||
|
||||
|
|
|
@ -202,10 +202,12 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
|
|||
public unsafe BitmapBuffer ResolveTexture2d(Texture2d tex)
|
||||
{
|
||||
var tw = tex.Opaque as TextureWrapper;
|
||||
return new BitmapBuffer(tw.SDBitmap, new BitmapLoadOptions()
|
||||
var blow = new BitmapLoadOptions()
|
||||
{
|
||||
AllowWrap = false //must be an independent resource
|
||||
});
|
||||
};
|
||||
var bb = new BitmapBuffer(tw.SDBitmap,blow);
|
||||
return bb;
|
||||
}
|
||||
|
||||
public Texture2d LoadTexture(string path)
|
||||
|
@ -228,39 +230,24 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
|
|||
|
||||
public Matrix4 CreateGuiProjectionMatrix(sd.Size dims)
|
||||
{
|
||||
Matrix4 ret = Matrix4.Identity;
|
||||
|
||||
//must handle 0s here otherwise we generate infinity and that causes problems later with gdi+
|
||||
//gdi+ is additionally sensitive to otherwise reasonable (say, 0,0,0,0 matrices) so use a 1 here i guess
|
||||
|
||||
if (dims.Width == 0)
|
||||
ret.M11 = 1;
|
||||
else ret.M11 = 2.0f / (float)dims.Width;
|
||||
|
||||
if (dims.Height == 0)
|
||||
ret.M22 = 1;
|
||||
else ret.M22 = 2.0f / (float)dims.Height;
|
||||
|
||||
|
||||
return ret;
|
||||
//see CreateGuiViewMatrix for more
|
||||
return Matrix4.Identity;
|
||||
}
|
||||
|
||||
public Matrix4 CreateGuiViewMatrix(sd.Size dims, bool autoflip)
|
||||
{
|
||||
Matrix4 ret = Matrix4.Identity;
|
||||
ret.M22 = -1.0f;
|
||||
ret.M41 = -(float)dims.Width * 0.5f;
|
||||
ret.M42 = (float)dims.Height * 0.5f;
|
||||
if (autoflip)
|
||||
{
|
||||
if (_CurrRenderTarget == null) { }
|
||||
else
|
||||
{
|
||||
//flip as long as we're not a final render target
|
||||
ret.M22 = 1.0f;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
//on account of gdi+ working internally with a default view exactly like we want, we don't need to setup a new one here
|
||||
//furthermore, we _cant_, without inverting the GuiView and GuiProjection before drawing, to completely undo it
|
||||
//this might be feasible, but its kind of slow and annoying and worse, seemingly numerically unstable
|
||||
//if (autoflip && _CurrRenderTarget != null)
|
||||
//{
|
||||
// Matrix4 ret = Matrix4.Identity;
|
||||
// ret.M22 = -1;
|
||||
// ret.M42 = dims.Height;
|
||||
// return ret;
|
||||
//}
|
||||
//else
|
||||
return Matrix4.Identity;
|
||||
}
|
||||
|
||||
public void SetViewport(int x, int y, int width, int height)
|
||||
|
@ -393,6 +380,12 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
|
|||
|
||||
public void BindRenderTarget(RenderTarget rt)
|
||||
{
|
||||
if (_CurrentOffscreenGraphics != null)
|
||||
{
|
||||
_CurrentOffscreenGraphics.Dispose();
|
||||
_CurrentOffscreenGraphics = null;
|
||||
}
|
||||
|
||||
_CurrRenderTarget = rt;
|
||||
if (CurrentRenderTargetWrapper != null)
|
||||
{
|
||||
|
@ -401,7 +394,9 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
|
|||
//dont do anything til swapbuffers
|
||||
}
|
||||
else
|
||||
CurrentRenderTargetWrapper.MyBufferedGraphics.Render();
|
||||
{
|
||||
//CurrentRenderTargetWrapper.MyBufferedGraphics.Render();
|
||||
}
|
||||
}
|
||||
|
||||
if (rt == null)
|
||||
|
@ -411,14 +406,20 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus
|
|||
}
|
||||
else
|
||||
{
|
||||
var tw = rt.Texture2d.Opaque as TextureWrapper;
|
||||
CurrentRenderTargetWrapper = rt.Opaque as RenderTargetWrapper;
|
||||
if (CurrentRenderTargetWrapper.MyBufferedGraphics == null)
|
||||
CurrentRenderTargetWrapper.CreateGraphics();
|
||||
_CurrentOffscreenGraphics = Graphics.FromImage(tw.SDBitmap);
|
||||
//if (CurrentRenderTargetWrapper.MyBufferedGraphics == null)
|
||||
// CurrentRenderTargetWrapper.CreateGraphics();
|
||||
}
|
||||
}
|
||||
|
||||
Graphics _CurrentOffscreenGraphics;
|
||||
|
||||
public Graphics GetCurrentGraphics()
|
||||
{
|
||||
if (_CurrentOffscreenGraphics != null)
|
||||
return _CurrentOffscreenGraphics;
|
||||
var rtw = CurrentRenderTargetWrapper;
|
||||
return rtw.MyBufferedGraphics.Graphics;
|
||||
}
|
||||
|
|
|
@ -672,9 +672,6 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.SlimDX
|
|||
var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight, pixels);
|
||||
target.UnlockRectangle(0);
|
||||
target.Dispose(); //buffer churn warning
|
||||
|
||||
//TEMPORARY until flipping is sorted out
|
||||
bb.YFlip();
|
||||
return bb;
|
||||
}
|
||||
|
||||
|
|
|
@ -105,6 +105,9 @@ namespace BizHawk.Bizware.BizwareGL
|
|||
Pixels = newPixels;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes sure the alpha channel is clean and optionally y-flips
|
||||
/// </summary>
|
||||
public unsafe void Normalize(bool yflip)
|
||||
{
|
||||
var bmpdata = LockBits();
|
||||
|
@ -114,6 +117,7 @@ namespace BizHawk.Bizware.BizwareGL
|
|||
fixed (int* d = newPixels)
|
||||
{
|
||||
if (yflip)
|
||||
{
|
||||
for (int y = 0, si = 0, di = (Height - 1) * Width; y < Height; y++)
|
||||
{
|
||||
for (int x = 0; x < Width; x++, si++, di++)
|
||||
|
@ -122,9 +126,16 @@ namespace BizHawk.Bizware.BizwareGL
|
|||
}
|
||||
di -= Width * 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO
|
||||
for (int y = 0, i=0; y < Height; y++)
|
||||
{
|
||||
for (int x = 0; x < Width; x++, i++)
|
||||
{
|
||||
d[i] = s[i] | unchecked((int)0xFF000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,19 +137,13 @@ namespace BizHawk.Bizware.BizwareGL
|
|||
|
||||
public void Begin(sd.Size size) { Begin(size.Width, size.Height); }
|
||||
|
||||
public void Begin(int width, int height, bool yflipped = false)
|
||||
public void Begin(int width, int height)
|
||||
{
|
||||
Begin();
|
||||
|
||||
Projection = Owner.CreateGuiProjectionMatrix(width, height);
|
||||
Modelview = Owner.CreateGuiViewMatrix(width, height);
|
||||
|
||||
//if (yflipped)
|
||||
//{
|
||||
// //not sure this is the best way to do it. could be done in the view matrix creation
|
||||
// Modelview.Scale(1, -1);
|
||||
// Modelview.Translate(0, -height);
|
||||
//}
|
||||
Owner.SetViewport(width, height);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,7 @@ namespace BizHawk.Bizware.BizwareGL
|
|||
/// <summary>
|
||||
/// begin rendering, initializing viewport and projections to the given dimensions
|
||||
/// </summary>
|
||||
/// <param name="yflipped">Whether the matrices should be Y-flipped, for use with render targets</param>
|
||||
void Begin(int width, int height, bool yflipped = false);
|
||||
void Begin(int width, int height);
|
||||
|
||||
/// <summary>
|
||||
/// draws the specified Art resource
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace BizHawk.Bizware.BizwareGL
|
|||
void Draw()
|
||||
{
|
||||
if (rt == null) return;
|
||||
GuiRenderer.Begin(Width, Height, true);
|
||||
GuiRenderer.Begin(Width, Height);
|
||||
GuiRenderer.SetBlendState(GL.BlendNoneCopy);
|
||||
GuiRenderer.Draw(rt.Texture2d);
|
||||
GuiRenderer.End();
|
||||
|
|
Loading…
Reference in New Issue