From 95bc69b4487fe6787606cbe459151ba339e8bd36 Mon Sep 17 00:00:00 2001 From: zeromus Date: Mon, 22 Feb 2016 00:23:20 -0600 Subject: [PATCH] some prepwork for opengl texture ID importing (skip rendertarget resolve on OGL display method) but there are still problems and it can't be enabled yet --- BizHawk.Client.Common/SavestateManager.cs | 30 ++++++++++++------- .../DisplayManager/DisplayManager.cs | 20 +++++++++++-- .../DisplayManager/Filters/Gui.cs | 11 ++++++- BizHawk.Client.EmuHawk/MainForm.cs | 7 ++--- BizHawk.Client.EmuHawk/Program.cs | 2 +- .../Consoles/Sega/Saturn/Yabause.cs | 11 +++++-- .../IGL_TK.cs | 4 ++- .../BizHawk.Bizware.BizwareGL/IGuiRenderer.cs | 5 +++- yabause/src/libyabause/libyabause.vcxproj | 1 + yabause/src/libyabause/yui.cpp | 26 +++++++++------- yabause/src/ygl.c | 23 +++++++++++++- 11 files changed, 106 insertions(+), 34 deletions(-) diff --git a/BizHawk.Client.Common/SavestateManager.cs b/BizHawk.Client.Common/SavestateManager.cs index 6d126d966a..b82211153b 100644 --- a/BizHawk.Client.Common/SavestateManager.cs +++ b/BizHawk.Client.Common/SavestateManager.cs @@ -38,18 +38,28 @@ namespace BizHawk.Client.Common { var vp = Global.Emulator.VideoProvider(); var buff = vp.GetVideoBuffer(); - - int out_w = vp.BufferWidth; - int out_h = vp.BufferHeight; - - // if buffer is too big, scale down screenshot - if (!Global.Config.NoLowResLargeScreenshotWithStates && buff.Length >= Global.Config.BigScreenshotSize) + if (buff.Length == 1) { - out_w /= 2; - out_h /= 2; + //is a hacky opengl texture ID. can't handle this now! + //need to discuss options + //1. cores must be able to provide a pixels videoprovider in addition to a texture ID, on command (not very hard overall but interface changing and work per core) + //2. SavestateManager must be setup with a mechanism for resolving texture IDs (even less work, but sloppy) + //There are additional problems with AVWriting. They depend on VideoProvider providing pixels. + } + else + { + int out_w = vp.BufferWidth; + int out_h = vp.BufferHeight; + + // if buffer is too big, scale down screenshot + if (!Global.Config.NoLowResLargeScreenshotWithStates && buff.Length >= Global.Config.BigScreenshotSize) + { + out_w /= 2; + out_h /= 2; + } + using (new SimpleTime("Save Framebuffer")) + bs.PutLump(BinaryStateLump.Framebuffer, (s) => QuickBmpFile.Save(Global.Emulator.VideoProvider(), s, out_w, out_h)); } - using (new SimpleTime("Save Framebuffer")) - bs.PutLump(BinaryStateLump.Framebuffer, (s) => QuickBmpFile.Save(Global.Emulator.VideoProvider(), s, out_w, out_h)); } if (Global.MovieSession.Movie.IsActive) diff --git a/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs b/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs index b4976a4f34..0c4dc81235 100644 --- a/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs +++ b/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs @@ -348,7 +348,7 @@ namespace BizHawk.Client.EmuHawk /// Then it will stuff it into the bound PresentationPanel. /// --- /// If the int[] is size=1, then it contains an openGL texture ID (and the size should be as specified from videoProvider) - /// Don't worry about the case where the frontend isnt using opengl; it isnt supported yet, and it will be my responsibility to deal with anyway + /// Don't worry about the case where the frontend isnt using opengl; DisplayManager deals with it /// public void UpdateSource(IVideoProvider videoProvider) { @@ -364,6 +364,20 @@ namespace BizHawk.Client.EmuHawk UpdateSourceInternal(job); } + public BitmapBuffer RenderVideoProvider(IVideoProvider videoProvider) + { + var job = new JobInfo + { + videoProvider = videoProvider, + simulate = false, + chain_outsize = new Size(videoProvider.BufferWidth, videoProvider.BufferHeight), + offscreen = true, + includeOSD = false + }; + UpdateSourceInternal(job); + return job.offscreenBB; + } + public BitmapBuffer RenderOffscreen(IVideoProvider videoProvider, bool includeOSD) { var job = new JobInfo @@ -653,6 +667,7 @@ namespace BizHawk.Client.EmuHawk fPresent.TextureSize = new Size(bufferWidth, bufferHeight); fPresent.BackgroundColor = videoProvider.BackgroundColor; fPresent.GuiRenderer = Renderer; + fPresent.Flip = isGlTextureId; fPresent.Config_FixAspectRatio = Global.Config.DispFixAspectRatio; fPresent.Config_FixScaleInteger = Global.Config.DispFixScaleInteger; fPresent.Padding = ClientExtraPadding; @@ -681,7 +696,7 @@ namespace BizHawk.Client.EmuHawk //begin rendering on this context //should this have been done earlier? //do i need to check this on an intel video card to see if running excessively is a problem? (it used to be in the FinalTarget command below, shouldnt be a problem) - //GraphicsControl.Begin(); + //GraphicsControl.Begin(); //CRITICAL POINT for yabause+GL GlobalWin.GL.BeginScene(); @@ -736,6 +751,7 @@ namespace BizHawk.Client.EmuHawk if (job.offscreen) { job.offscreenBB = rtCurr.Texture2d.Resolve(); + job.offscreenBB.DiscardAlpha(); } else { diff --git a/BizHawk.Client.EmuHawk/DisplayManager/Filters/Gui.cs b/BizHawk.Client.EmuHawk/DisplayManager/Filters/Gui.cs index b5e527c8e5..1176122869 100644 --- a/BizHawk.Client.EmuHawk/DisplayManager/Filters/Gui.cs +++ b/BizHawk.Client.EmuHawk/DisplayManager/Filters/Gui.cs @@ -178,6 +178,7 @@ namespace BizHawk.Client.EmuHawk.Filters public Size TextureSize, VirtualTextureSize; public int BackgroundColor; public IGuiRenderer GuiRenderer; + public bool Flip; public IGL GL; bool nop; LetterboxingLogic LL; @@ -238,6 +239,8 @@ namespace BizHawk.Client.EmuHawk.Filters need = true; if (FilterOption != eFilterOption.None) need = true; + if (Flip) + need = true; if (!need) { @@ -318,7 +321,13 @@ namespace BizHawk.Client.EmuHawk.Filters } - GuiRenderer.Draw(InputTexture,LL.vx,LL.vy,LL.vw,LL.vh); + GuiRenderer.Modelview.Translate(LL.vx, LL.vy); + if (Flip) + { + GuiRenderer.Modelview.Scale(1, -1); + GuiRenderer.Modelview.Translate(0, -LL.vh); + } + GuiRenderer.Draw(InputTexture,0,0,LL.vw,LL.vh); GuiRenderer.End(); } diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 1d1fd69989..09c5d14679 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -916,7 +916,6 @@ namespace BizHawk.Client.EmuHawk { using (var bb = GlobalWin.DisplayManager.RenderOffscreen(Global.Emulator.VideoProvider(), Global.Config.Screenshot_CaptureOSD)) { - bb.DiscardAlpha(); using (var img = bb.ToSysdrawingBitmap()) Clipboard.SetImage(img); } @@ -1895,11 +1894,9 @@ namespace BizHawk.Client.EmuHawk } } - private static unsafe BitmapBuffer MakeScreenshotImage() + private static BitmapBuffer MakeScreenshotImage() { - var bb = new BitmapBuffer(Global.Emulator.VideoProvider().BufferWidth, Global.Emulator.VideoProvider().BufferHeight, Global.Emulator.VideoProvider().GetVideoBuffer()); - bb.DiscardAlpha(); - return bb; + return GlobalWin.DisplayManager.RenderVideoProvider(Global.Emulator.VideoProvider()); } private void SaveSlotSelectedMessage() diff --git a/BizHawk.Client.EmuHawk/Program.cs b/BizHawk.Client.EmuHawk/Program.cs index 80121e0043..fc77a8dd97 100644 --- a/BizHawk.Client.EmuHawk/Program.cs +++ b/BizHawk.Client.EmuHawk/Program.cs @@ -127,7 +127,7 @@ namespace BizHawk.Client.EmuHawk GlobalWin.IGL_GL = new Bizware.BizwareGL.Drivers.OpenTK.IGL_TK(2,0,false); //setup the GL context manager, needed for coping with multiple opengl cores vs opengl display method - GLManager.CreateInstance(); + GLManager.CreateInstance(GlobalWin.IGL_GL); GlobalWin.GLManager = GLManager.Instance; GlobalWin.CR_GL = GlobalWin.GLManager.GetContextForIGL(GlobalWin.GL); diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs index 7e74dc3453..ed5f7636a1 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs @@ -86,7 +86,7 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn public IEmulatorServiceProvider ServiceProvider { get; private set; } - static object glContext; + object glContext; void ActivateGL() { @@ -329,7 +329,14 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn #region IVideoProvider int[] VideoBuffer = new int[704 * 512]; - public int[] GetVideoBuffer() { return VideoBuffer; } + int[] TextureIdBuffer = new int[1]; //todo + public int[] GetVideoBuffer() { + //doesn't work yet + //if (SyncSettings.UseGL) + // return new[] { VideoBuffer[0] }; + //else + return VideoBuffer; + } public int VirtualWidth { get { return BufferWidth; } } public int VirtualHeight { get { return BufferHeight; } } public int BufferWidth { get; private set; } diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs index e86353152f..364bb05f51 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs @@ -23,6 +23,7 @@ using BizHawk.Bizware.BizwareGL; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; +using otkg = OpenTK.Graphics; namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK { @@ -496,7 +497,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK public Texture2d WrapGLTexture2d(IntPtr glTexId, int width, int height) { - return new Texture2d(this as IGL, glTexId, width, height); + return new Texture2d(this as IGL, glTexId.ToInt32(), width, height); } public void LoadTextureData(Texture2d tex, BitmapBuffer bmp) @@ -590,6 +591,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK var bb = new BitmapBuffer(tex.IntWidth, tex.IntHeight); var bmpdata = bb.LockBits(); GL.GetTexImage(TextureTarget.Texture2D, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bmpdata.Scan0); + var err = GL.GetError(); bb.UnlockBits(bmpdata); return bb; } diff --git a/Bizware/BizHawk.Bizware.BizwareGL/IGuiRenderer.cs b/Bizware/BizHawk.Bizware.BizwareGL/IGuiRenderer.cs index 88610aca05..165ebdccfd 100644 --- a/Bizware/BizHawk.Bizware.BizwareGL/IGuiRenderer.cs +++ b/Bizware/BizHawk.Bizware.BizwareGL/IGuiRenderer.cs @@ -35,8 +35,11 @@ namespace BizHawk.Bizware.BizwareGL /// draws the specified Art resource with the specified offset, with the specified size. This could be tricky if youve applied other rotate or scale transforms first. /// void Draw(Art art, float x, float y, float width, float height); - void Draw(Texture2d art, float x, float y, float width, float height); + /// + /// draws the specified Texture with the specified offset, with the specified size. This could be tricky if youve applied other rotate or scale transforms first. + /// + void Draw(Texture2d art, float x, float y, float width, float height); /// /// draws the specified texture2d resource. diff --git a/yabause/src/libyabause/libyabause.vcxproj b/yabause/src/libyabause/libyabause.vcxproj index f1804474c2..5891c41d48 100644 --- a/yabause/src/libyabause/libyabause.vcxproj +++ b/yabause/src/libyabause/libyabause.vcxproj @@ -52,6 +52,7 @@ WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBYABAUSE_EXPORTS;HAVE_C99_VARIADIC_MACROS;VERSION="LIB";C68K_NO_JUMP_TABLE;HAVE_LIBGL;%(PreprocessorDefinitions) 4244;4996;4018;4146 true + false Windows diff --git a/yabause/src/libyabause/yui.cpp b/yabause/src/libyabause/yui.cpp index ee235f8c58..8b7feed322 100644 --- a/yabause/src/libyabause/yui.cpp +++ b/yabause/src/libyabause/yui.cpp @@ -280,6 +280,7 @@ PerPad_struct *ctrl2; extern "C" int vdp2height; extern "C" int vdp2width; +extern "C" GLuint FboTexture; /* Tells the yui to exchange front and back video buffers. This may end up being moved to the Video Core. */ @@ -305,19 +306,24 @@ void YuiSwapBuffers(void) } else { - glReadPixels(0, 0, glwidth, glheight, GL_BGRA, GL_UNSIGNED_BYTE, glbuff); + #ifdef CAN_RETURN_TEXTURE_IDS + //simply write the FboTexture into the videobuffer for later magic detection in frontend + memcpy(vidbuff,&FboTexture,4); + #else + glReadPixels(0, 0, glwidth, glheight, GL_BGRA, GL_UNSIGNED_BYTE, glbuff); - u32 *src = (u32*)glbuff; - u32 *dst = (u32*)vidbuff; + u32 *src = (u32*)glbuff; + u32 *dst = (u32*)vidbuff; - dst += glwidth * (glheight - 1); + dst += glwidth * (glheight - 1); - for (int j = 0; j < glheight; j++) - { - memcpy(dst, src, glwidth * 4); - src += glwidth; - dst -= glwidth; - } + for (int j = 0; j < glheight; j++) + { + memcpy(dst, src, glwidth * 4); + src += glwidth; + dst -= glwidth; + } + #endif } } } diff --git a/yabause/src/ygl.c b/yabause/src/ygl.c index 311c130d0e..bb4e20e3b7 100644 --- a/yabause/src/ygl.c +++ b/yabause/src/ygl.c @@ -57,6 +57,7 @@ extern int vdp1cog; extern int vdp1cob; GLuint DefaultFrameBuffer; +GLuint FboTexture, MainFbo; #ifdef HAVE_GLXGETPROCADDRESS void STDCALL * (*yglGetProcAddress)(const char *szProcName) = (void STDCALL *(*)(const char *))glXGetProcAddress; @@ -562,7 +563,27 @@ int YglGLInit(int width, int height) { glBindFramebuffer(GL_FRAMEBUFFER, DefaultFrameBuffer); glBindTexture(GL_TEXTURE_2D,_Ygl->texture); - + + + //bizhawk code: create a texture for reading from the main FBO + //if the alternate 'main' FBO isn't created yet, now's the time + if(MainFbo == 0) + { + glGenFramebuffers(1,&MainFbo); + glBindFramebuffer(GL_FRAMEBUFFER, MainFbo); + DefaultFrameBuffer = MainFbo; + } + + //delete existing texture if we already have it + if( FboTexture != 0 ) glDeleteTextures(1,&FboTexture); + glGenTextures(1, &FboTexture); + glBindTexture(GL_TEXTURE_2D, FboTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GlWidth, GlHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,NULL); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FboTexture, 0); + glBindTexture(GL_TEXTURE_2D, 0); + return 0; }