private FilterProgram UpdateSourceInternal(JobInfo job) { //no drawing actually happens. it's important not to begin drawing on a control if (!job.Simulate && !job.Offscreen) { GLManager.Activate(CR_GraphicsControl); if (job.ChainOutsize.Width == 0 || job.ChainOutsize.Height == 0) { // this has to be a NOP, because lots of stuff will malfunction on a 0-sized viewport if (_currentFilterProgram != null) { UpdateSourceDrawingWork(job); //but we still need to do this, because of vsync } return(null); } } IVideoProvider videoProvider = job.VideoProvider; bool simulate = job.Simulate; Size chainOutsize = job.ChainOutsize; //simulate = true; int vw = videoProvider.BufferWidth; int vh = videoProvider.BufferHeight; if (Global.Config.DispFixAspectRatio) { if (Global.Config.DispManagerAR == EDispManagerAR.System) { vw = videoProvider.VirtualWidth; vh = videoProvider.VirtualHeight; } if (Global.Config.DispManagerAR == EDispManagerAR.Custom) { vw = Global.Config.DispCustomUserARWidth; vh = Global.Config.DispCustomUserARHeight; } if (Global.Config.DispManagerAR == EDispManagerAR.CustomRatio) { FixRatio(Global.Config.DispCustomUserArx, Global.Config.DispCustomUserAry, videoProvider.BufferWidth, videoProvider.BufferHeight, out vw, out vh); } } var padding = CalculateCompleteContentPadding(true, false); vw += padding.Horizontal; vh += padding.Vertical; int[] videoBuffer = videoProvider.GetVideoBuffer(); int bufferWidth = videoProvider.BufferWidth; int bufferHeight = videoProvider.BufferHeight; bool isGlTextureId = videoBuffer.Length == 1; BitmapBuffer bb = null; Texture2d videoTexture = null; if (!simulate) { if (isGlTextureId) { //FYI: this is a million years from happening on n64, since it's all geriatric non-FBO code //is it workable for saturn? videoTexture = GL.WrapGLTexture2d(new IntPtr(videoBuffer[0]), bufferWidth, bufferHeight); } else { //wrap the VideoProvider data in a BitmapBuffer (no point to refactoring that many IVideoProviders) bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer); bb.DiscardAlpha(); //now, acquire the data sent from the videoProvider into a texture videoTexture = VideoTextureFrugalizer.Get(bb); // lets not use this. lets define BizwareGL to make clamp by default (TBD: check opengl) //GL.SetTextureWrapMode(videoTexture, true); } } // record the size of what we received, since lua and stuff is gonna want to draw onto it currEmuWidth = bufferWidth; currEmuHeight = bufferHeight; //build the default filter chain and set it up with services filters will need Size chainInsize = new Size(bufferWidth, bufferHeight); var filterProgram = BuildDefaultChain(chainInsize, chainOutsize, job.IncludeOSD); filterProgram.GuiRenderer = Renderer; filterProgram.GL = GL; //setup the source image filter Filters.SourceImage fInput = filterProgram["input"] as Filters.SourceImage; fInput.Texture = videoTexture; //setup the final presentation filter Filters.FinalPresentation fPresent = filterProgram["presentation"] as Filters.FinalPresentation; fPresent.VirtualTextureSize = new Size(vw, vh); 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; fPresent.AutoPrescale = Global.Config.DispAutoPrescale; fPresent.GL = GL; filterProgram.Compile("default", chainInsize, chainOutsize, !job.Offscreen); if (simulate) { } else { _currentFilterProgram = filterProgram; UpdateSourceDrawingWork(job); } // cleanup: bb?.Dispose(); return(filterProgram); }
FilterProgram BuildDefaultChain(Size chainInSize, Size chainOutSize, bool includeOSD) { // select user special FX shader chain var selectedChainProperties = new Dictionary <string, object>(); Filters.RetroShaderChain selectedChain = null; if (Global.Config.TargetDisplayFilter == 1 && ShaderChain_hq2x != null && ShaderChain_hq2x.Available) { selectedChain = ShaderChain_hq2x; } if (Global.Config.TargetDisplayFilter == 2 && ShaderChain_scanlines != null && ShaderChain_scanlines.Available) { selectedChain = ShaderChain_scanlines; selectedChainProperties["uIntensity"] = 1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f; } if (Global.Config.TargetDisplayFilter == 3 && ShaderChain_user != null && ShaderChain_user.Available) { selectedChain = ShaderChain_user; } var fPresent = new Filters.FinalPresentation(chainOutSize); var fInput = new Filters.SourceImage(chainInSize); var fOSD = new Filters.OSD(); fOSD.RenderCallback = () => { if (!includeOSD) { return; } var size = fOSD.FindInput().SurfaceFormat.Size; Renderer.Begin(size.Width, size.Height); var myBlitter = new MyBlitter(this) { ClipBounds = new Rectangle(0, 0, size.Width, size.Height) }; Renderer.SetBlendState(GL.BlendNormal); GlobalWin.OSD.Begin(myBlitter); GlobalWin.OSD.DrawScreenInfo(myBlitter); GlobalWin.OSD.DrawMessages(myBlitter); Renderer.End(); }; var chain = new FilterProgram(); //add the first filter, encompassing output from the emulator core chain.AddFilter(fInput, "input"); // if a non-zero padding is required, add a filter to allow for that // note, we have two sources of padding right now.. one can come from the VideoProvider and one from the user. // we're combining these now and just using black, for sake of being lean, despite the discussion below: // keep in mind, the VideoProvider design in principle might call for another color. // we haven't really been using this very hard, but users will probably want black there (they could fill it to another color if needed tho) var padding = CalculateCompleteContentPadding(true, true); if (padding.Vertical != 0 || padding.Horizontal != 0) { // TODO - add another filter just for this, its cumbersome to use final presentation... I think. but maybe there's enough similarities to justify it. Size size = chainInSize; size.Width += padding.Horizontal; size.Height += padding.Vertical; Filters.FinalPresentation fPadding = new Filters.FinalPresentation(size); chain.AddFilter(fPadding, "padding"); fPadding.GuiRenderer = Renderer; fPadding.GL = GL; fPadding.Config_PadOnly = true; fPadding.Padding = padding; } //add lua layer 'emu' AppendLuaLayer(chain, "emu"); if (Global.Config.DispPrescale != 1) { var fPrescale = new Filters.PrescaleFilter() { Scale = Global.Config.DispPrescale }; chain.AddFilter(fPrescale, "user_prescale"); } // add user-selected retro shader if (selectedChain != null) { AppendRetroShaderChain(chain, "retroShader", selectedChain, selectedChainProperties); } // AutoPrescale makes no sense for a None final filter if (Global.Config.DispAutoPrescale && Global.Config.DispFinalFilter != (int)Filters.FinalPresentation.eFilterOption.None) { var apf = new Filters.AutoPrescaleFilter(); chain.AddFilter(apf, "auto_prescale"); } //choose final filter var finalFilter = Filters.FinalPresentation.eFilterOption.None; if (Global.Config.DispFinalFilter == 1) { finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear; } if (Global.Config.DispFinalFilter == 2) { finalFilter = Filters.FinalPresentation.eFilterOption.Bicubic; } //if bicubic is selected and unavailable, don't use it. use bilinear instead I guess if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic) { if (ShaderChain_bicubic == null || !ShaderChain_bicubic.Available) { finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear; } } fPresent.FilterOption = finalFilter; // now if bicubic is chosen, insert it if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic) { AppendRetroShaderChain(chain, "bicubic", ShaderChain_bicubic, null); } // add final presentation chain.AddFilter(fPresent, "presentation"); //add lua layer 'native' AppendLuaLayer(chain, "native"); // and OSD goes on top of that // TODO - things break if this isn't present (the final presentation filter gets messed up when used with prescaling) // so, always include it (we'll handle this flag in the callback to do no rendering) //if (includeOSD) chain.AddFilter(fOSD, "osd"); return(chain); }
FilterProgram UpdateSourceInternal(JobInfo job) { GlobalWin.GLManager.Activate(CR_GraphicsControl); IVideoProvider videoProvider = job.videoProvider; bool simulate = job.simulate; Size chain_outsize = job.chain_outsize; int vw = videoProvider.BufferWidth; int vh = videoProvider.BufferHeight; if (Global.Config.DispObeyAR && Global.Config.DispFixAspectRatio) { vw = videoProvider.VirtualWidth; vh = videoProvider.VirtualHeight; } int[] videoBuffer = videoProvider.GetVideoBuffer(); TESTEROO: int bufferWidth = videoProvider.BufferWidth; int bufferHeight = videoProvider.BufferHeight; bool isGlTextureId = videoBuffer.Length == 1; BitmapBuffer bb = null; Texture2d videoTexture = null; if (!simulate) { if (isGlTextureId) { videoTexture = GL.WrapGLTexture2d(new IntPtr(videoBuffer[0]), bufferWidth, bufferHeight); } else { //wrap the videoprovider data in a BitmapBuffer (no point to refactoring that many IVideoProviders) bb = new BitmapBuffer(bufferWidth, bufferHeight, videoBuffer); //now, acquire the data sent from the videoProvider into a texture videoTexture = VideoTextureFrugalizer.Get(bb); GL.SetTextureWrapMode(videoTexture, true); } //TEST (to be removed once we have an actual example of bring in a texture ID from opengl emu core): if (!isGlTextureId) { videoBuffer = new int[1] { videoTexture.Id.ToInt32() }; goto TESTEROO; } } //record the size of what we received, since lua and stuff is gonna want to draw onto it currEmuWidth = bufferWidth; currEmuHeight = bufferHeight; //build the default filter chain and set it up with services filters will need Size chain_insize = new Size(bufferWidth, bufferHeight); var filterProgram = BuildDefaultChain(chain_insize, chain_outsize, job.includeOSD); filterProgram.GuiRenderer = Renderer; filterProgram.GL = GL; //setup the source image filter Filters.SourceImage fInput = filterProgram["input"] as Filters.SourceImage; fInput.Texture = videoTexture; //setup the final presentation filter Filters.FinalPresentation fPresent = filterProgram["presentation"] as Filters.FinalPresentation; fPresent.VirtualTextureSize = new Size(vw, vh); fPresent.TextureSize = new Size(bufferWidth, bufferHeight); fPresent.BackgroundColor = videoProvider.BackgroundColor; fPresent.GuiRenderer = Renderer; fPresent.GL = GL; filterProgram.Compile("default", chain_insize, chain_outsize, !job.offscreen); if (simulate) { } else { CurrentFilterProgram = filterProgram; UpdateSourceDrawingWork(job); } //cleanup: if (bb != null) { bb.Dispose(); } return(filterProgram); }
FilterProgram BuildDefaultChain(Size chain_insize, Size chain_outsize, bool includeOSD) { //select user special FX shader chain Dictionary <string, object> selectedChainProperties = new Dictionary <string, object>(); Filters.RetroShaderChain selectedChain = null; if (Global.Config.TargetDisplayFilter == 1 && ShaderChain_hq2x != null && ShaderChain_hq2x.Available) { selectedChain = ShaderChain_hq2x; } if (Global.Config.TargetDisplayFilter == 2 && ShaderChain_scanlines != null && ShaderChain_scanlines.Available) { //shader.Pipeline["uIntensity"].Set(1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f); selectedChain = ShaderChain_scanlines; selectedChainProperties["uIntensity"] = 1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f; } if (Global.Config.TargetDisplayFilter == 3 && ShaderChain_user != null && ShaderChain_user.Available) { selectedChain = ShaderChain_user; } Filters.FinalPresentation fPresent = new Filters.FinalPresentation(chain_outsize); Filters.SourceImage fInput = new Filters.SourceImage(chain_insize); Filters.OSD fOSD = new Filters.OSD(); fOSD.RenderCallback = () => { if (!includeOSD) { return; } var size = fOSD.FindInput().SurfaceFormat.Size; Renderer.Begin(size.Width, size.Height); MyBlitter myBlitter = new MyBlitter(this); myBlitter.ClipBounds = new Rectangle(0, 0, size.Width, size.Height); Renderer.SetBlendState(GL.BlendNormal); GlobalWin.OSD.Begin(myBlitter); GlobalWin.OSD.DrawScreenInfo(myBlitter); GlobalWin.OSD.DrawMessages(myBlitter); Renderer.End(); }; var chain = new FilterProgram(); //add the first filter, encompassing output from the emulator core chain.AddFilter(fInput, "input"); //add lua layer 'emu' AppendLuaLayer(chain, "emu"); //add user-selected retro shader if (selectedChain != null) { AppendRetroShaderChain(chain, "retroShader", selectedChain, selectedChainProperties); } //choose final filter Filters.FinalPresentation.eFilterOption finalFilter = Filters.FinalPresentation.eFilterOption.None; if (Global.Config.DispFinalFilter == 1) { finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear; } if (Global.Config.DispFinalFilter == 2) { finalFilter = Filters.FinalPresentation.eFilterOption.Bicubic; } //if bicubic is selected and unavailable, dont use it if (!ShaderChain_bicubic.Available && fPresent.FilterOption == Filters.FinalPresentation.eFilterOption.Bicubic) { finalFilter = Filters.FinalPresentation.eFilterOption.None; } fPresent.FilterOption = finalFilter; //now if bicubic is chosen, insert it if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic) { AppendRetroShaderChain(chain, "bicubic", ShaderChain_bicubic, null); } //add final presentation chain.AddFilter(fPresent, "presentation"); //add lua layer 'native' AppendLuaLayer(chain, "native"); //and OSD goes on top of that //TODO - things break if this isnt present (the final presentation filter gets messed up) //so, always include it (we'll handle this flag in the callback to do no rendering) //if (includeOSD) chain.AddFilter(fOSD, "osd"); return(chain); }
FilterProgram BuildDefaultChain(Size chain_insize, Size chain_outsize, bool includeOSD) { //select user special FX shader chain Dictionary<string, object> selectedChainProperties = new Dictionary<string, object>(); Filters.RetroShaderChain selectedChain = null; if (Global.Config.TargetDisplayFilter == 1 && ShaderChain_hq2x != null && ShaderChain_hq2x.Available) selectedChain = ShaderChain_hq2x; if (Global.Config.TargetDisplayFilter == 2 && ShaderChain_scanlines != null && ShaderChain_scanlines.Available) { selectedChain = ShaderChain_scanlines; selectedChainProperties["uIntensity"] = 1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f; } if (Global.Config.TargetDisplayFilter == 3 && ShaderChain_user != null && ShaderChain_user.Available) selectedChain = ShaderChain_user; Filters.FinalPresentation fPresent = new Filters.FinalPresentation(chain_outsize); Filters.SourceImage fInput = new Filters.SourceImage(chain_insize); Filters.OSD fOSD = new Filters.OSD(); fOSD.RenderCallback = () => { if (!includeOSD) return; var size = fOSD.FindInput().SurfaceFormat.Size; Renderer.Begin(size.Width, size.Height); MyBlitter myBlitter = new MyBlitter(this); myBlitter.ClipBounds = new Rectangle(0, 0, size.Width, size.Height); Renderer.SetBlendState(GL.BlendNormal); GlobalWin.OSD.Begin(myBlitter); GlobalWin.OSD.DrawScreenInfo(myBlitter); GlobalWin.OSD.DrawMessages(myBlitter); Renderer.End(); }; var chain = new FilterProgram(); //add the first filter, encompassing output from the emulator core chain.AddFilter(fInput, "input"); //if a non-zero padding is required, add a filter to allow for that //note, we have two sources of padding right now.. one can come from the videoprovider and one from the user. //we're combining these now and just using black, for sake of being lean, despite the discussion below: //keep in mind, the videoprovider design in principle might call for another color. //we havent really been using this very hard, but users will probably want black there (they could fill it to another color if needed tho) var padding = CalculateCompleteContentPadding(true,true); if (padding.Vertical != 0 || padding.Horizontal != 0) { //TODO - add another filter just for this, its cumbersome to use final presentation... I think. but maybe theres enough similarities to justify it. Size size = chain_insize; size.Width += padding.Horizontal; size.Height += padding.Vertical; Filters.FinalPresentation fPadding = new Filters.FinalPresentation(size); chain.AddFilter(fPadding, "padding"); fPadding.GuiRenderer = Renderer; fPadding.GL = GL; fPadding.Config_PadOnly = true; fPadding.Padding = padding; } //add lua layer 'emu' AppendLuaLayer(chain, "emu"); if (Global.Config.DispPrescale != 1) { Filters.PrescaleFilter fPrescale = new Filters.PrescaleFilter() { Scale = Global.Config.DispPrescale }; chain.AddFilter(fPrescale, "prescale"); } //add user-selected retro shader if (selectedChain != null) AppendRetroShaderChain(chain, "retroShader", selectedChain, selectedChainProperties); //choose final filter Filters.FinalPresentation.eFilterOption finalFilter = Filters.FinalPresentation.eFilterOption.None; if (Global.Config.DispFinalFilter == 1) finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear; if (Global.Config.DispFinalFilter == 2) finalFilter = Filters.FinalPresentation.eFilterOption.Bicubic; //if bicubic is selected and unavailable, dont use it. use bilinear instead I guess if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic) { if (ShaderChain_bicubic == null || !ShaderChain_bicubic.Available) finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear; } fPresent.FilterOption = finalFilter; //now if bicubic is chosen, insert it if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic) AppendRetroShaderChain(chain, "bicubic", ShaderChain_bicubic, null); //add final presentation chain.AddFilter(fPresent, "presentation"); //add lua layer 'native' AppendLuaLayer(chain, "native"); //and OSD goes on top of that //TODO - things break if this isnt present (the final presentation filter gets messed up when used with prescaling) //so, always include it (we'll handle this flag in the callback to do no rendering) //if (includeOSD) chain.AddFilter(fOSD, "osd"); return chain; }
FilterProgram BuildDefaultChain(Size chain_insize, Size chain_outsize, bool includeOSD) { //select user special FX shader chain Dictionary<string, object> selectedChainProperties = new Dictionary<string, object>(); Filters.RetroShaderChain selectedChain = null; if (Global.Config.TargetDisplayFilter == 1 && ShaderChain_hq2x != null && ShaderChain_hq2x.Available) selectedChain = ShaderChain_hq2x; if (Global.Config.TargetDisplayFilter == 2 && ShaderChain_scanlines != null && ShaderChain_scanlines.Available) { //shader.Pipeline["uIntensity"].Set(1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f); selectedChain = ShaderChain_scanlines; selectedChainProperties["uIntensity"] = 1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f; } if (Global.Config.TargetDisplayFilter == 3 && ShaderChain_user != null && ShaderChain_user.Available) selectedChain = ShaderChain_user; Filters.FinalPresentation fPresent = new Filters.FinalPresentation(chain_outsize); Filters.SourceImage fInput = new Filters.SourceImage(chain_insize); Filters.OSD fOSD = new Filters.OSD(); fOSD.RenderCallback = () => { if (!includeOSD) return; var size = fOSD.FindInput().SurfaceFormat.Size; Renderer.Begin(size.Width, size.Height); MyBlitter myBlitter = new MyBlitter(this); myBlitter.ClipBounds = new Rectangle(0, 0, size.Width, size.Height); Renderer.SetBlendState(GL.BlendNormal); GlobalWin.OSD.Begin(myBlitter); GlobalWin.OSD.DrawScreenInfo(myBlitter); GlobalWin.OSD.DrawMessages(myBlitter); Renderer.End(); }; var chain = new FilterProgram(); //add the first filter, encompassing output from the emulator core chain.AddFilter(fInput, "input"); //add lua layer 'emu' AppendLuaLayer(chain, "emu"); //add user-selected retro shader if (selectedChain != null) AppendRetroShaderChain(chain, "retroShader", selectedChain, selectedChainProperties); //choose final filter Filters.FinalPresentation.eFilterOption finalFilter = Filters.FinalPresentation.eFilterOption.None; if (Global.Config.DispFinalFilter == 1) finalFilter = Filters.FinalPresentation.eFilterOption.Bilinear; if (Global.Config.DispFinalFilter == 2) finalFilter = Filters.FinalPresentation.eFilterOption.Bicubic; //if bicubic is selected and unavailable, dont use it if (!ShaderChain_bicubic.Available && fPresent.FilterOption == Filters.FinalPresentation.eFilterOption.Bicubic) { finalFilter = Filters.FinalPresentation.eFilterOption.None; } fPresent.FilterOption = finalFilter; //now if bicubic is chosen, insert it if (finalFilter == Filters.FinalPresentation.eFilterOption.Bicubic) AppendRetroShaderChain(chain, "bicubic", ShaderChain_bicubic, null); //add final presentation chain.AddFilter(fPresent, "presentation"); //add lua layer 'native' AppendLuaLayer(chain, "native"); //and OSD goes on top of that //TODO - things break if this isnt present (the final presentation filter gets messed up) //so, always include it (we'll handle this flag in the callback to do no rendering) //if (includeOSD) chain.AddFilter(fOSD, "osd"); return chain; }