From f8b840ea41646a083f2037da1e213cf4f8db3721 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sat, 25 Jul 2015 17:25:10 -0500 Subject: [PATCH] fix gdi+ lua rendering and prescale option --- .../DisplayManager/DisplayManager.cs | 2 - .../GdiPlusGuiRenderer.cs | 68 +++++++++++++++---- .../IGL_GdiPlus.cs | 31 +++++++-- .../BizHawk.Bizware.BizwareGL/BitmapBuffer.cs | 13 ++++ .../BizHawk.Bizware.BizwareGL/Extensions.cs | 4 ++ 5 files changed, 99 insertions(+), 19 deletions(-) diff --git a/BizHawk.Client.MultiHawk/DisplayManager/DisplayManager.cs b/BizHawk.Client.MultiHawk/DisplayManager/DisplayManager.cs index 71a3e1de83..490670b31a 100644 --- a/BizHawk.Client.MultiHawk/DisplayManager/DisplayManager.cs +++ b/BizHawk.Client.MultiHawk/DisplayManager/DisplayManager.cs @@ -146,8 +146,6 @@ namespace BizHawk.Client.MultiHawk if (Global.Config.DispFinalFilter == 1) finalFilter = BizHawk.Client.EmuHawk.Filters.FinalPresentation.eFilterOption.Bilinear; if (Global.Config.DispFinalFilter == 2) finalFilter = BizHawk.Client.EmuHawk.Filters.FinalPresentation.eFilterOption.Bicubic; - finalFilter = BizHawk.Client.EmuHawk.Filters.FinalPresentation.eFilterOption.None; - fPresent.FilterOption = finalFilter; //add final presentation diff --git a/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/GdiPlusGuiRenderer.cs b/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/GdiPlusGuiRenderer.cs index ad1e8b6299..c0317f65a8 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/GdiPlusGuiRenderer.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/GdiPlusGuiRenderer.cs @@ -170,10 +170,34 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus float y0 = v0 * tex.Height; float x1 = u1 * tex.Width; float y1 = v1 * tex.Height; + + //==========HACKY COPYPASTE============= + + //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' 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); + + //------------------ + //( reminder: this is just an experiment: we need to turn this into a transform on the GraphicsDevice ) + //------------------ + Matrix4 mat = Projection.Top * Modelview.Top * fixmat; + var tl = new Vector3(x, y, 0); + var tr = new Vector3(x + w, y, 0); + var bl = new Vector3(x, y + h, 0); + tl = Vector3.Transform(tl, mat); + tr = Vector3.Transform(tr, mat); + bl = Vector3.Transform(bl, mat); + + //======================================= + sd.PointF[] destPoints = new sd.PointF[] { - new sd.PointF(x,y), - new sd.PointF(x+w,y), - new sd.PointF(x,y+h), + tl.ToSDPointf(), + tr.ToSDPointf(), + bl.ToSDPointf(), }; g.DrawImage(tw.SDBitmap, destPoints, new sd.RectangleF(x0, y0, x1 - x0, y1 - y0), sd.GraphicsUnit.Pixel, CurrentImageAttributes); @@ -234,19 +258,37 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus var g = Gdi.GetCurrentGraphics(); PrepDraw(g, tw); + //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' 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); + + //------------------ + //( reminder: this is just an experiment: we need to turn this into a transform on the GraphicsDevice ) + //------------------ + Matrix4 mat = Projection.Top * Modelview.Top * fixmat; + var tl = new Vector3(x, y, 0); + var tr = new Vector3(x + w, y, 0); + var bl = new Vector3(x, y + h, 0); + tl = Vector3.Transform(tl, mat); + tr = Vector3.Transform(tr, mat); + bl = Vector3.Transform(bl, mat); + //a little bit of a fastpath.. I think it's safe + //SO WHY DIDNT IT WORK? + //anyway, it would interfere with the transforming //if (w == tex.Width && h == tex.Height && x == (int)x && y == (int)y) // g.DrawImageUnscaled(tw.SDBitmap, (int)x, (int)y); - //else - { - sd.PointF[] destPoints = new sd.PointF[] { - new sd.PointF(x,y), - new sd.PointF(x+w,y), - new sd.PointF(x,y+h), - }; - //g.DrawImage(tw.SDBitmap, x, y, w, h); //original - g.DrawImage(tw.SDBitmap, destPoints, new sd.RectangleF(0, 0, tex.Width, tex.Height), sd.GraphicsUnit.Pixel, CurrentImageAttributes); - } + sd.PointF[] destPoints = new sd.PointF[] { + tl.ToSDPointf(), + tr.ToSDPointf(), + bl.ToSDPointf(), + }; + + g.DrawImage(tw.SDBitmap, destPoints, new sd.RectangleF(0, 0, tex.Width, tex.Height), sd.GraphicsUnit.Pixel, CurrentImageAttributes); } unsafe void DrawInternal(Art art, float x, float y, float w, float h, bool fx, bool fy) diff --git a/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/IGL_GdiPlus.cs b/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/IGL_GdiPlus.cs index 441d88b918..be9b5c0969 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/IGL_GdiPlus.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.GdiPlus/IGL_GdiPlus.cs @@ -84,6 +84,11 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus public void Clear(OpenTK.Graphics.OpenGL.ClearBufferMask mask) { + var g = GetCurrentGraphics(); + if((mask & ClearBufferMask.ColorBufferBit) != 0) + { + g.Clear(_currentClearColor); + } } public string API { get { return "GDIPLUS"; } } @@ -94,9 +99,10 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus return null; } + private sd.Color _currentClearColor = Color.Transparent; public void SetClearColor(sd.Color color) { - + _currentClearColor = color; } public unsafe void BindArrayData(void* pData) @@ -349,9 +355,10 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus public BufferedGraphics MyBufferedGraphics; + public Graphics refGraphics; //?? hacky? + public void CreateGraphics() { - Graphics refGraphics; Rectangle r; if (Control != null) { @@ -392,13 +399,17 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus { int id = rt.Id.ToInt32(); var rtw = ResourceIDs.Lookup[id] as RenderTargetWrapper; - rtw.Target.Dispose(); ResourceIDs.Free(rt.Id); } public unsafe RenderTarget CreateRenderTarget(int w, int h) { - Texture2d tex = null; + TextureWrapper tw = new TextureWrapper(); + tw.SDBitmap = new Bitmap(w,h, sdi.PixelFormat.Format32bppArgb); + IntPtr texid = GenTexture(); + ResourceIDs.Lookup[texid.ToInt32()] = tw; + var tex = new Texture2d(this, texid, null, w, h); + var rt = new RenderTarget(this, ResourceIDs.Alloc(ResourceIdManager.EResourceType.RenderTarget), tex); int id = rt.Id.ToInt32(); RenderTargetWrapper rtw = new RenderTargetWrapper(this); @@ -409,6 +420,16 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus public void BindRenderTarget(RenderTarget rt) { + if (CurrentRenderTargetWrapper != null) + { + if (CurrentRenderTargetWrapper == CurrentControl.RenderTargetWrapper) + { + //dont do anything til swapbuffers + } + else + CurrentRenderTargetWrapper.MyBufferedGraphics.Render(); + } + if (rt == null) { //null means to use the default RT for the current control @@ -417,6 +438,8 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.GdiPlus else { CurrentRenderTargetWrapper = RenderTargetWrapperForRt(rt); + if (CurrentRenderTargetWrapper.MyBufferedGraphics == null) + CurrentRenderTargetWrapper.CreateGraphics(); } } diff --git a/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs b/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs index c35ee585e5..77a70bc378 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/BitmapBuffer.cs @@ -477,6 +477,8 @@ namespace BizHawk.Bizware.BizwareGL /// public unsafe Bitmap ToSysdrawingBitmap() { + if (WrappedBitmap != null) + return (Bitmap)WrappedBitmap.Clone(); var pf = PixelFormat.Format32bppArgb; if (!HasAlpha) pf = PixelFormat.Format24bppRgb; @@ -491,6 +493,17 @@ namespace BizHawk.Bizware.BizwareGL /// public unsafe void ToSysdrawingBitmap(Bitmap bmp) { + if (WrappedBitmap != null) + { + using (var g = Graphics.FromImage(bmp)) + { + g.CompositingMode = sd.Drawing2D.CompositingMode.SourceCopy; + g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; + g.DrawImageUnscaled(WrappedBitmap, 0, 0); + return; + } + } + //note: we lock it as 32bpp even if the bitmap is 24bpp so we can write to it more conveniently. var bmpdata = bmp.LockBits(new sd.Rectangle(0, 0, Width, Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); diff --git a/Bizware/BizHawk.Bizware.BizwareGL/Extensions.cs b/Bizware/BizHawk.Bizware.BizwareGL/Extensions.cs index fbb064c45a..bf743e5f3c 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/Extensions.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/Extensions.cs @@ -13,5 +13,9 @@ namespace BizHawk.Bizware.BizwareGL { return new Vector2(size.Width, size.Height); } + public static PointF ToSDPointf(this Vector3 v) + { + return new PointF(v.X, v.Y); + } } } \ No newline at end of file