diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
index 9a5043eeb5..553d0a4fbd 100644
--- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
+++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
@@ -1151,8 +1151,6 @@
WatchEditor.cs
-
-
SettingsSingleFileGenerator
Settings.Designer.cs
diff --git a/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs b/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs
index eafcc8f115..faf1f576db 100644
--- a/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs
+++ b/BizHawk.Client.EmuHawk/DisplayManager/DisplayManager.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
@@ -15,6 +16,9 @@ using BizHawk.Client.Common;
using BizHawk.Bizware.BizwareGL;
+using OpenTK;
+using OpenTK.Graphics;
+
namespace BizHawk.Client.EmuHawk
{
///
@@ -39,26 +43,26 @@ namespace BizHawk.Client.EmuHawk
LuaEmuTextureFrugalizer = new TextureFrugalizer(GL);
Video2xFrugalizer = new RenderTargetFrugalizer(GL);
+ ShaderChainFrugalizers = new RenderTargetFrugalizer[16]; //hacky hardcoded limit.. need some other way to manage these
+ for (int i = 0; i < 16; i++)
+ {
+ ShaderChainFrugalizers[i] = new RenderTargetFrugalizer(GL);
+ }
+
using (var xml = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px.fnt"))
using (var tex = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.Resources.courier16px_0.png"))
TheOneFont = new StringRenderer(GL, xml, tex);
- using (var stream = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.DisplayManager.Filters.hq2x.glsl"))
- {
- var str = new System.IO.StreamReader(stream).ReadToEnd();
- RetroShader_Hq2x = new Bizware.BizwareGL.Drivers.OpenTK.RetroShader(GL, str);
- }
-
- using (var stream = typeof(Program).Assembly.GetManifestResourceStream("BizHawk.Client.EmuHawk.DisplayManager.Filters.BizScanlines.glsl"))
- {
- var str = new System.IO.StreamReader(stream).ReadToEnd();
- RetroShader_BizScanlines = new Bizware.BizwareGL.Drivers.OpenTK.RetroShader(GL, str);
- }
-
+ var fiHq2x = new FileInfo(System.IO.Path.Combine(PathManager.GetExeDirectoryAbsolute(),"Shaders/BizHawk/hq2x.cgp"));
+ if(fiHq2x.Exists)
+ using(var stream = fiHq2x.OpenRead())
+ ShaderChain_hq2x = new RetroShaderChain(GL,new RetroShaderPreset(stream), System.IO.Path.Combine(PathManager.GetExeDirectoryAbsolute(),"Shaders/BizHawk"));
+ var fiScanlines = new FileInfo(System.IO.Path.Combine(PathManager.GetExeDirectoryAbsolute(), "Shaders/BizHawk/BizScanlines.cgp"));
+ if (fiScanlines.Exists)
+ using (var stream = fiScanlines.OpenRead())
+ ShaderChain_scanlines = new RetroShaderChain(GL,new RetroShaderPreset(stream), System.IO.Path.Combine(PathManager.GetExeDirectoryAbsolute(),"Shaders/BizHawk"));
}
- Bizware.BizwareGL.Drivers.OpenTK.RetroShader RetroShader_Hq2x, RetroShader_BizScanlines;
-
public bool Disposed { get; private set; }
public void Dispose()
@@ -67,6 +71,9 @@ namespace BizHawk.Client.EmuHawk
Disposed = true;
VideoTextureFrugalizer.Dispose();
LuaEmuTextureFrugalizer.Dispose();
+ foreach (var f in ShaderChainFrugalizers)
+ if (f != null)
+ f.Dispose();
}
//rendering resources:
@@ -95,6 +102,8 @@ namespace BizHawk.Client.EmuHawk
TextureFrugalizer VideoTextureFrugalizer, LuaEmuTextureFrugalizer;
RenderTargetFrugalizer Video2xFrugalizer;
+ RenderTargetFrugalizer[] ShaderChainFrugalizers;
+ RetroShaderChain ShaderChain_hq2x, ShaderChain_scanlines;
///
/// This will receive an emulated output frame from an IVideoProvider and run it through the complete frame processing pipeline
@@ -117,37 +126,58 @@ namespace BizHawk.Client.EmuHawk
if (luaEmuSurface != null)
luaEmuTexture = LuaEmuTextureFrugalizer.Get(luaEmuSurface);
-
- //TargetScanlineFilterIntensity
- //apply filter chain (currently, over-simplified)
+ //select shader chain
+ 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;
+
+ //run shader chain
Texture2d currentTexture = videoTexture;
- if (Global.Config.TargetDisplayFilter == 1 && RetroShader_Hq2x.Pipeline.Available)
+ if (selectedChain != null)
{
- var rt = Video2xFrugalizer.Get(videoTexture.IntWidth*2,videoTexture.IntHeight*2);
- rt.Bind();
- Size outSize = new Size(videoTexture.IntWidth * 2, videoTexture.IntHeight * 2);
- RetroShader_Hq2x.Run(videoTexture, videoTexture.Size, outSize, true);
- currentTexture = rt.Texture2d;
- }
- if (Global.Config.TargetDisplayFilter == 2 && RetroShader_BizScanlines.Pipeline.Available)
- {
- var rt = Video2xFrugalizer.Get(videoTexture.IntWidth*2,videoTexture.IntHeight*2);
- rt.Bind();
- Size outSize = new Size(videoTexture.IntWidth * 2, videoTexture.IntHeight * 2);
- RetroShader_BizScanlines.Bind();
- RetroShader_BizScanlines.Pipeline["uIntensity"].Set(1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f);
- RetroShader_BizScanlines.Run(videoTexture, videoTexture.Size, outSize, true);
- currentTexture = rt.Texture2d;
+ foreach (var pass in selectedChain.Passes)
+ {
+ //calculate size of input and output (note, we dont have a distinction between logical size and POW2 buffer size yet, like we should)
+
+ Size insize = currentTexture.Size;
+ Size outsize = insize;
+
+ //calculate letterboxing scale factors for the current configuration, so that ScaleType.Viewport can do something intelligent
+ var LLpass = new LetterboxingLogic(GraphicsControl.Width, GraphicsControl.Height, insize.Width, insize.Height);
+
+ if (pass.ScaleTypeX == RetroShaderPreset.ScaleType.Absolute) { throw new NotImplementedException("ScaleType Absolute"); }
+ if (pass.ScaleTypeX == RetroShaderPreset.ScaleType.Viewport) outsize.Width = LLpass.Rectangle.Width;
+ if (pass.ScaleTypeX == RetroShaderPreset.ScaleType.Source) outsize.Width = (int)(insize.Width * pass.Scale.X);
+ if (pass.ScaleTypeY == RetroShaderPreset.ScaleType.Absolute) { throw new NotImplementedException("ScaleType Absolute"); }
+ if (pass.ScaleTypeY == RetroShaderPreset.ScaleType.Viewport) outsize.Height = LLpass.Rectangle.Height;
+ if (pass.ScaleTypeY == RetroShaderPreset.ScaleType.Source) outsize.Height = (int)(insize.Height * pass.Scale.Y);
+
+ if (pass.InputFilterLinear)
+ videoTexture.SetFilterLinear();
+ else
+ videoTexture.SetFilterNearest();
+
+ var rt = ShaderChainFrugalizers[pass.Index].Get(outsize.Width, outsize.Height);
+ rt.Bind();
+
+ var shader = selectedChain.Shaders[pass.Index];
+ shader.Bind();
+ if(selectedChain == ShaderChain_scanlines)
+ shader.Pipeline["uIntensity"].Set(1.0f - Global.Config.TargetScanlineFilterIntensity / 256.0f);
+ shader.Run(currentTexture, insize, outsize, true);
+ currentTexture = rt.Texture2d;
+ }
}
//begin drawing to the PresentationPanel:
GraphicsControl.Begin();
- //1. clear it with the background color that the emulator specified
+ //1. clear it with the background color that the emulator specified (could we please only clear the necessary letterbox area, to save some time?)
GL.SetClearColor(Color.FromArgb(videoProvider.BackgroundColor));
GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit);
-
//2. begin 2d rendering
Renderer.Begin(GraphicsControl.Width, GraphicsControl.Height);
@@ -264,6 +294,7 @@ namespace BizHawk.Client.EmuHawk
finalScale = Math.Min(widthScale, heightScale);
dx = (int)((vw - finalScale * sourceWidth) / 2);
dy = (int)((vh - finalScale * sourceHeight) / 2);
+ Rectangle = new Rectangle((int)dx, (int)dy, (int)(finalScale * sourceWidth), (int)(finalScale * sourceHeight));
}
///
@@ -275,6 +306,11 @@ namespace BizHawk.Client.EmuHawk
/// offset
///
public float dx, dy;
+
+ ///
+ /// The destination rectangle
+ ///
+ public Rectangle Rectangle;
}
}
diff --git a/BizHawk.Client.EmuHawk/DisplayManager/FilterManager.cs b/BizHawk.Client.EmuHawk/DisplayManager/FilterManager.cs
index 48551751ee..bf25266574 100644
--- a/BizHawk.Client.EmuHawk/DisplayManager/FilterManager.cs
+++ b/BizHawk.Client.EmuHawk/DisplayManager/FilterManager.cs
@@ -1,14 +1,200 @@
//https://github.com/Themaister/RetroArch/wiki/GLSL-shaders
//https://github.com/Themaister/Emulator-Shader-Pack/blob/master/Cg/README
+//https://github.com/libretro/common-shaders/
using System;
+using System.Collections.Generic;
+using System.IO;
using System.Drawing;
using BizHawk.Common;
using BizHawk.Client.Common;
using BizHawk.Bizware.BizwareGL;
+using BizHawk.Bizware.BizwareGL.Drivers.OpenTK;
+using OpenTK;
+using OpenTK.Graphics;
+
+namespace BizHawk.Client.EmuHawk
+{
+ ///
+ ///
+ ///
+ class RetroShaderChain : IDisposable
+ {
+ public RetroShaderChain(IGL owner, RetroShaderPreset preset, string baseDirectory, bool debug = false)
+ {
+ Owner = owner;
+ this.Preset = preset;
+ Passes = preset.Passes.ToArray();
+
+ bool ok = true;
+
+ //load up the shaders
+ Shaders = new RetroShader[preset.Passes.Count];
+ for(int i=0;i
+ /// Whether this shader chain is available (it wont be available if some resources failed to load or compile)
+ ///
+ public bool Available { get; private set; }
+
+ public readonly IGL Owner;
+ public readonly RetroShaderPreset Preset;
+ public readonly RetroShader[] Shaders;
+ public readonly RetroShaderPreset.ShaderPass[] Passes;
+ }
+
+ class RetroShaderPreset
+ {
+ ///
+ /// Parses an instance from a stream to a CGP file
+ ///
+ public RetroShaderPreset(Stream stream)
+ {
+ var content = new StreamReader(stream).ReadToEnd();
+ Dictionary dict = new Dictionary();
+
+ //parse the key-value-pair format of the file
+ content = content.Replace("\r", "");
+ foreach (var _line in content.Split('\n'))
+ {
+ var line = _line.Trim();
+ if(line.StartsWith("#")) continue; //lines that are solely comments
+ if (line == "") continue; //empty line
+ int eq = line.IndexOf('=');
+ var key = line.Substring(0,eq).Trim();
+ var value = line.Substring(eq + 1).Trim();
+ int quote = value.IndexOf('\"');
+ if (quote != -1)
+ value = value.Substring(quote + 1, value.IndexOf('\"', quote + 1) - (quote + 1));
+ else
+ {
+ //remove comments from end of value. exclusive from above condition, since comments after quoted strings would be snipped by the quoted string extraction
+ int hash = value.IndexOf('#');
+ if (hash != -1)
+ value = value.Substring(0, hash);
+ value = value.Trim();
+ }
+ dict[key.ToLower()] = value;
+ }
+
+ //process the keys
+ int nShaders = FetchInt(dict, "shaders", 0);
+ for (int i = 0; i < nShaders; i++)
+ {
+ ShaderPass sp = new ShaderPass();
+ sp.Index = i;
+ Passes.Add(sp);
+
+ sp.InputFilterLinear = FetchBool(dict, "filter_linear" + i, false); //Should this value not be defined, the filtering option is implementation defined.
+ sp.OuputFloat = FetchBool(dict, "float_framebuffer" + i, false);
+ sp.FrameCountMod = FetchInt(dict, "frame_count_mod" + i, 1);
+ sp.ShaderPath = FetchString(dict, "shader" + i, "?"); //todo - change extension to .cg for better compatibility? just change .cg to .glsl transparently at last second?
+
+ //If no scale type is assumed, it is assumed that it is set to "source" with scaleN set to 1.0.
+ //It is possible to set scale_type_xN and scale_type_yN to specialize the scaling type in either direction. scale_typeN however overrides both of these.
+ sp.ScaleTypeX = (ScaleType)Enum.Parse(typeof(ScaleType), FetchString(dict, "scale_type_x" + i, "Source"), true);
+ sp.ScaleTypeY = (ScaleType)Enum.Parse(typeof(ScaleType), FetchString(dict, "scale_type_y" + i, "Source"), true);
+ ScaleType st = (ScaleType)Enum.Parse(typeof(ScaleType), FetchString(dict, "scale_type" + i, "NotSet"), true);
+ if (st != ScaleType.NotSet)
+ sp.ScaleTypeX = sp.ScaleTypeY = st;
+
+ //scaleN controls both scaling type in horizontal and vertical directions. If scaleN is defined, scale_xN and scale_yN have no effect.
+ sp.Scale.X = FetchFloat(dict, "scale_x" + i, 1);
+ sp.Scale.Y = FetchFloat(dict, "scale_y" + i, 1);
+ float scale = FetchFloat(dict, "scale" + i, -999);
+ if(scale != -999)
+ sp.Scale.X = sp.Scale.Y = FetchFloat(dict,"scale" + i, 1);
+
+ //TODO - LUTs
+ }
+ }
+
+ public List Passes = new List();
+
+ public enum ScaleType
+ {
+ NotSet, Source, Viewport, Absolute
+ }
+
+ public class ShaderPass
+ {
+ public int Index;
+ public string ShaderPath;
+ public bool InputFilterLinear;
+ public bool OuputFloat;
+ public int FrameCountMod;
+ public ScaleType ScaleTypeX;
+ public ScaleType ScaleTypeY;
+ public Vector2 Scale;
+ }
+
+ string FetchString(Dictionary dict, string key, string @default)
+ {
+ string str;
+ if (dict.TryGetValue(key, out str))
+ return str;
+ else return @default;
+ }
+
+ int FetchInt(Dictionary dict, string key, int @default)
+ {
+ string str;
+ if (dict.TryGetValue(key, out str))
+ return int.Parse(str);
+ else return @default;
+ }
+
+ float FetchFloat(Dictionary dict, string key, float @default)
+ {
+ string str;
+ if (dict.TryGetValue(key, out str))
+ return float.Parse(str);
+ else return @default;
+ }
+
+ bool FetchBool(Dictionary dict, string key, bool @default)
+ {
+ string str;
+ if (dict.TryGetValue(key, out str))
+ return ParseBool(str);
+ else return @default;
+ }
+
+
+ bool ParseBool(string value)
+ {
+ if (value == "1") return true;
+ if (value == "0") return false;
+ value = value.ToLower();
+ if (value == "true") return true;
+ if (value == "false") return false;
+ throw new InvalidOperationException("Unparseable bool in CGP file content");
+ }
+ }
+}
//Here, I started making code to support GUI editing of filter chains.
//I decided to go for broke and implement retroarch's system first, and then the GUI editing should be able to internally produce a metashader
diff --git a/BizHawk.Client.EmuHawk/config/DisplayConfigLite.Designer.cs b/BizHawk.Client.EmuHawk/config/DisplayConfigLite.Designer.cs
index 686809cae7..80a5e2a7d7 100644
--- a/BizHawk.Client.EmuHawk/config/DisplayConfigLite.Designer.cs
+++ b/BizHawk.Client.EmuHawk/config/DisplayConfigLite.Designer.cs
@@ -33,10 +33,11 @@
this.checkBilinearFilter = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
- this.rbHq2x = new System.Windows.Forms.RadioButton();
- this.rbScanlines = new System.Windows.Forms.RadioButton();
- this.rbNone = new System.Windows.Forms.RadioButton();
this.tbScanlineIntensity = new System.Windows.Forms.TrackBar();
+ this.rbNone = new System.Windows.Forms.RadioButton();
+ this.rbScanlines = new System.Windows.Forms.RadioButton();
+ this.rbHq2x = new System.Windows.Forms.RadioButton();
+ this.checkLetterbox = new System.Windows.Forms.CheckBox();
this.groupBox1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.tbScanlineIntensity)).BeginInit();
this.SuspendLayout();
@@ -95,27 +96,16 @@
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Filter";
//
- // rbHq2x
+ // tbScanlineIntensity
//
- this.rbHq2x.AutoSize = true;
- this.rbHq2x.Location = new System.Drawing.Point(6, 42);
- this.rbHq2x.Name = "rbHq2x";
- this.rbHq2x.Size = new System.Drawing.Size(50, 17);
- this.rbHq2x.TabIndex = 0;
- this.rbHq2x.TabStop = true;
- this.rbHq2x.Text = "Hq2x";
- this.rbHq2x.UseVisualStyleBackColor = true;
- //
- // rbScanlines
- //
- this.rbScanlines.AutoSize = true;
- this.rbScanlines.Location = new System.Drawing.Point(6, 65);
- this.rbScanlines.Name = "rbScanlines";
- this.rbScanlines.Size = new System.Drawing.Size(71, 17);
- this.rbScanlines.TabIndex = 1;
- this.rbScanlines.TabStop = true;
- this.rbScanlines.Text = "Scanlines";
- this.rbScanlines.UseVisualStyleBackColor = true;
+ this.tbScanlineIntensity.LargeChange = 32;
+ this.tbScanlineIntensity.Location = new System.Drawing.Point(83, 55);
+ this.tbScanlineIntensity.Maximum = 255;
+ this.tbScanlineIntensity.Name = "tbScanlineIntensity";
+ this.tbScanlineIntensity.Size = new System.Drawing.Size(70, 42);
+ this.tbScanlineIntensity.TabIndex = 3;
+ this.tbScanlineIntensity.TickFrequency = 32;
+ this.tbScanlineIntensity.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
//
// rbNone
//
@@ -128,16 +118,37 @@
this.rbNone.Text = "None";
this.rbNone.UseVisualStyleBackColor = true;
//
- // tbScanlineIntensity
+ // rbScanlines
//
- this.tbScanlineIntensity.LargeChange = 32;
- this.tbScanlineIntensity.Location = new System.Drawing.Point(83, 55);
- this.tbScanlineIntensity.Maximum = 255;
- this.tbScanlineIntensity.Name = "tbScanlineIntensity";
- this.tbScanlineIntensity.Size = new System.Drawing.Size(70, 42);
- this.tbScanlineIntensity.TabIndex = 3;
- this.tbScanlineIntensity.TickFrequency = 32;
- this.tbScanlineIntensity.TickStyle = System.Windows.Forms.TickStyle.TopLeft;
+ this.rbScanlines.AutoSize = true;
+ this.rbScanlines.Location = new System.Drawing.Point(6, 65);
+ this.rbScanlines.Name = "rbScanlines";
+ this.rbScanlines.Size = new System.Drawing.Size(71, 17);
+ this.rbScanlines.TabIndex = 1;
+ this.rbScanlines.TabStop = true;
+ this.rbScanlines.Text = "Scanlines";
+ this.rbScanlines.UseVisualStyleBackColor = true;
+ //
+ // rbHq2x
+ //
+ this.rbHq2x.AutoSize = true;
+ this.rbHq2x.Location = new System.Drawing.Point(6, 42);
+ this.rbHq2x.Name = "rbHq2x";
+ this.rbHq2x.Size = new System.Drawing.Size(50, 17);
+ this.rbHq2x.TabIndex = 0;
+ this.rbHq2x.TabStop = true;
+ this.rbHq2x.Text = "Hq2x";
+ this.rbHq2x.UseVisualStyleBackColor = true;
+ //
+ // checkLetterbox
+ //
+ this.checkLetterbox.AutoSize = true;
+ this.checkLetterbox.Location = new System.Drawing.Point(12, 168);
+ this.checkLetterbox.Name = "checkLetterbox";
+ this.checkLetterbox.Size = new System.Drawing.Size(188, 17);
+ this.checkLetterbox.TabIndex = 8;
+ this.checkLetterbox.Text = "Letterbox (to maintain aspect ratio)";
+ this.checkLetterbox.UseVisualStyleBackColor = true;
//
// DisplayConfigLite
//
@@ -146,6 +157,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(292, 236);
+ this.Controls.Add(this.checkLetterbox);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.label1);
this.Controls.Add(this.checkBilinearFilter);
@@ -173,5 +185,6 @@
private System.Windows.Forms.RadioButton rbScanlines;
private System.Windows.Forms.RadioButton rbHq2x;
private System.Windows.Forms.TrackBar tbScanlineIntensity;
+ private System.Windows.Forms.CheckBox checkLetterbox;
}
}
\ No newline at end of file
diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs
index ba0741eee8..78363a7506 100644
--- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs
+++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/IGL_TK.cs
@@ -513,6 +513,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
GL.DeleteShader(sid);
sid = 0;
}
+
return new Shader(this, new IntPtr(sid), ok);
}
diff --git a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/RetroShader.cs b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/RetroShader.cs
index e2f7381b91..76c789e118 100644
--- a/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/RetroShader.cs
+++ b/Bizware/BizHawk.Bizware.BizwareGL.OpenTK/RetroShader.cs
@@ -13,7 +13,7 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
///
public class RetroShader : IDisposable
{
- public RetroShader(IGL owner, string source)
+ public RetroShader(IGL owner, string source, bool debug = false)
{
Owner = owner as IGL_TK;
@@ -25,9 +25,9 @@ namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK
string vsSource = "#define VERTEX\r\n" + source;
string psSource = "#define FRAGMENT\r\n" + source;
- var vs = Owner.CreateVertexShader(vsSource, false);
- var ps = Owner.CreateFragmentShader(psSource, false);
- Pipeline = Owner.CreatePipeline(VertexLayout, vs, ps, false);
+ var vs = Owner.CreateVertexShader(vsSource, debug);
+ var ps = Owner.CreateFragmentShader(psSource, debug);
+ Pipeline = Owner.CreatePipeline(VertexLayout, vs, ps, debug);
}
public void Dispose()
diff --git a/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj b/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj
index ecc48b8b14..28cb4ec6e8 100644
--- a/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj
+++ b/Bizware/BizHawk.Bizware.BizwareGL/BizHawk.Bizware.BizwareGL.csproj
@@ -58,6 +58,7 @@
+
UserControl
diff --git a/Bizware/BizHawk.Bizware.BizwareGL/Extensions.cs b/Bizware/BizHawk.Bizware.BizwareGL/Extensions.cs
new file mode 100644
index 0000000000..fbb064c45a
--- /dev/null
+++ b/Bizware/BizHawk.Bizware.BizwareGL/Extensions.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Drawing;
+using System.Text;
+
+using OpenTK;
+using OpenTK.Graphics;
+
+namespace BizHawk.Bizware.BizwareGL
+{
+ public static class BizwareGLExtensions
+ {
+ public static Vector2 ToVector2(this Size size)
+ {
+ return new Vector2(size.Width, size.Height);
+ }
+ }
+}
\ No newline at end of file
diff --git a/output/Shaders/BizHawk/BizScanlines.cgp b/output/Shaders/BizHawk/BizScanlines.cgp
new file mode 100644
index 0000000000..fe50cf6252
--- /dev/null
+++ b/output/Shaders/BizHawk/BizScanlines.cgp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = BizScanlines.glsl
+scale0 = 2
diff --git a/BizHawk.Client.EmuHawk/DisplayManager/Filters/BizScanlines.glsl b/output/Shaders/BizHawk/BizScanlines.glsl
similarity index 92%
rename from BizHawk.Client.EmuHawk/DisplayManager/Filters/BizScanlines.glsl
rename to output/Shaders/BizHawk/BizScanlines.glsl
index bd5123caac..f7dfbddcc4 100644
--- a/BizHawk.Client.EmuHawk/DisplayManager/Filters/BizScanlines.glsl
+++ b/output/Shaders/BizHawk/BizScanlines.glsl
@@ -70,7 +70,7 @@ uniform float uIntensity;
void main()
{
vec4 temp = texture2D(Texture,vTexCoord0);
- if(((int)gl_FragCoord.y)%2==1) temp.rgb *= uIntensity;
+ if((int(gl_FragCoord.y))%2==1) temp.rgb *= uIntensity;
FragColor = temp;
}
#endif
diff --git a/output/Shaders/BizHawk/bicubic-fast.glsl b/output/Shaders/BizHawk/bicubic-fast.glsl
new file mode 100644
index 0000000000..d87555728a
--- /dev/null
+++ b/output/Shaders/BizHawk/bicubic-fast.glsl
@@ -0,0 +1,338 @@
+// GLSL shader autogenerated by cg2glsl.py.
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying
+#define COMPAT_ATTRIBUTE attribute
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+COMPAT_VARYING vec2 VARt8;
+COMPAT_VARYING vec4 VARt7;
+COMPAT_VARYING vec4 VARt6;
+COMPAT_VARYING vec4 VARt5;
+COMPAT_VARYING vec4 VARt4;
+COMPAT_VARYING vec4 VARt3;
+COMPAT_VARYING vec4 VARt2;
+COMPAT_VARYING vec4 VARt1;
+COMPAT_VARYING vec2 VARtexCoord;
+COMPAT_VARYING float _frame_rotation;
+
+
+struct input_dummy {
+ vec2 _video_size;
+ vec2 _texture_size;
+ vec2 _output_dummy_size;
+ float _frame_count;
+ float _frame_direction;
+ float _frame_rotation;
+};
+
+struct out_vertex {
+ vec2 VARtexCoord;
+ vec4 VARt1;
+ vec4 VARt2;
+ vec4 VARt3;
+ vec4 VARt4;
+ vec4 VARt5;
+ vec4 VARt6;
+ vec4 VARt7;
+ vec2 VARt8;
+};
+
+vec4 _oPosition1;
+out_vertex _ret_0;
+
+input_dummy _IN1;
+vec4 _r0023;
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+
+
+uniform mat4 MVPMatrix;
+uniform int FrameDirection;
+uniform int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+void main()
+{
+
+ vec2 _ps;
+ out_vertex _TMP17;
+
+ _ps = vec2(1.00000000E+000/TextureSize.x, 1.00000000E+000/TextureSize.y);
+ _r0023 = VertexCoord.x*MVPMatrix[0];
+ _r0023 = _r0023 + VertexCoord.y*MVPMatrix[1];
+ _r0023 = _r0023 + VertexCoord.z*MVPMatrix[2];
+ _r0023 = _r0023 + VertexCoord.w*MVPMatrix[3];
+ _oPosition1 = _r0023;
+ _TMP17.VARt1 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(-_ps.x, -_ps.y, 0.00000000E+000, -_ps.y);
+ _TMP17.VARt2 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(_ps.x, -_ps.y, 2.00000000E+000*_ps.x, -_ps.y);
+ _TMP17.VARt3 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(-_ps.x, 0.00000000E+000, _ps.x, 0.00000000E+000);
+ _TMP17.VARt4 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(2.00000000E+000*_ps.x, 0.00000000E+000, -_ps.x, _ps.y);
+ _TMP17.VARt5 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(0.00000000E+000, _ps.y, _ps.x, _ps.y);
+ _TMP17.VARt6 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(2.00000000E+000*_ps.x, _ps.y, -_ps.x, 2.00000000E+000*_ps.y);
+ _TMP17.VARt7 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(0.00000000E+000, 2.00000000E+000*_ps.y, _ps.x, 2.00000000E+000*_ps.y);
+ _TMP17.VARt8 = TexCoord.xy + vec2(2.00000000E+000*_ps.x, 2.00000000E+000*_ps.y);
+ VARtexCoord = TexCoord.xy;
+ VARt1 = _TMP17.VARt1;
+ VARt2 = _TMP17.VARt2;
+ VARt3 = _TMP17.VARt3;
+ VARt4 = _TMP17.VARt4;
+ VARt5 = _TMP17.VARt5;
+ VARt6 = _TMP17.VARt6;
+ VARt7 = _TMP17.VARt7;
+ VARt8 = _TMP17.VARt8;
+ gl_Position = _r0023;
+ return;
+}
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+COMPAT_VARYING vec2 VARt8;
+COMPAT_VARYING vec4 VARt7;
+COMPAT_VARYING vec4 VARt6;
+COMPAT_VARYING vec4 VARt5;
+COMPAT_VARYING vec4 VARt4;
+COMPAT_VARYING vec4 VARt3;
+COMPAT_VARYING vec4 VARt2;
+COMPAT_VARYING vec4 VARt1;
+COMPAT_VARYING vec2 VARtexCoord;
+COMPAT_VARYING float _frame_rotation;
+
+
+struct input_dummy {
+ vec2 _video_size;
+ vec2 _texture_size;
+ vec2 _output_dummy_size;
+ float _frame_count;
+ float _frame_direction;
+ float _frame_rotation;
+};
+
+struct out_vertex {
+ vec2 VARtexCoord;
+ vec4 VARt1;
+ vec4 VARt2;
+ vec4 VARt3;
+ vec4 VARt4;
+ vec4 VARt5;
+ vec4 VARt6;
+ vec4 VARt7;
+ vec2 VARt8;
+};
+
+vec4 _ret_0;
+vec4 _TMP15;
+vec4 _TMP14;
+vec4 _TMP13;
+vec4 _TMP12;
+vec4 _TMP11;
+vec4 _TMP10;
+vec4 _TMP9;
+vec4 _TMP8;
+vec4 _TMP7;
+vec4 _TMP6;
+vec4 _TMP5;
+vec4 _TMP4;
+vec4 _TMP3;
+vec4 _TMP2;
+vec4 _TMP1;
+vec4 _TMP0;
+out_vertex _VAR1;
+uniform sampler2D Texture;
+input_dummy _IN1;
+vec2 _x0035;
+vec4 _C0069;
+vec4 _C0079[1];
+vec4 _C0081;
+float _C0091;
+vec4 _C0093;
+float _C0103;
+vec4 _C0105;
+float _C0115;
+vec4 _TMP116;
+vec4 _TMP117;
+vec4 _TMP118;
+vec4 _TMP119;
+vec4 _TMP120;
+vec4 _TMP121;
+vec4 _TMP122;
+vec4 _TMP123;
+vec4 _TMP124;
+vec4 _TMP125;
+vec4 _TMP126;
+vec4 _TMP127;
+vec4 _TMP128;
+vec4 _TMP129;
+vec4 _TMP130;
+vec4 _TMP131;
+
+
+uniform int FrameDirection;
+uniform int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+void main()
+{
+
+ vec2 _fp;
+ vec4 _TMP26[1];
+ vec4 _TMP27;
+ vec4 _TMP29[4];
+ vec4 _TMP30[4];
+ vec4 _TMP31[4];
+
+ _x0035 = VARtexCoord*TextureSize;
+ _fp = fract(_x0035);
+ _TMP0 = COMPAT_TEXTURE(Texture, VARt1.xy);
+ _TMP1 = COMPAT_TEXTURE(Texture, VARt1.zw);
+ _TMP2 = COMPAT_TEXTURE(Texture, VARt2.xy);
+ _TMP3 = COMPAT_TEXTURE(Texture, VARt2.zw);
+ _TMP4 = COMPAT_TEXTURE(Texture, VARt3.xy);
+ _TMP5 = COMPAT_TEXTURE(Texture, VARtexCoord);
+ _TMP6 = COMPAT_TEXTURE(Texture, VARt3.zw);
+ _TMP7 = COMPAT_TEXTURE(Texture, VARt4.xy);
+ _TMP8 = COMPAT_TEXTURE(Texture, VARt4.zw);
+ _TMP9 = COMPAT_TEXTURE(Texture, VARt5.xy);
+ _TMP10 = COMPAT_TEXTURE(Texture, VARt5.zw);
+ _TMP11 = COMPAT_TEXTURE(Texture, VARt6.xy);
+ _TMP12 = COMPAT_TEXTURE(Texture, VARt6.zw);
+ _TMP13 = COMPAT_TEXTURE(Texture, VARt7.xy);
+ _TMP14 = COMPAT_TEXTURE(Texture, VARt7.zw);
+ _TMP15 = COMPAT_TEXTURE(Texture, VARt8.xy);
+ _TMP31[0] = vec4(_TMP0.x, _TMP1.x, _TMP2.x, _TMP3.x);
+ _TMP31[1] = vec4(_TMP4.x, _TMP5.x, _TMP6.x, _TMP7.x);
+ _TMP31[2] = vec4(_TMP8.x, _TMP9.x, _TMP10.x, _TMP11.x);
+ _TMP31[3] = vec4(_TMP12.x, _TMP13.x, _TMP14.x, _TMP15.x);
+ _TMP30[0] = vec4(_TMP0.y, _TMP1.y, _TMP2.y, _TMP3.y);
+ _TMP30[1] = vec4(_TMP4.y, _TMP5.y, _TMP6.y, _TMP7.y);
+ _TMP30[2] = vec4(_TMP8.y, _TMP9.y, _TMP10.y, _TMP11.y);
+ _TMP30[3] = vec4(_TMP12.y, _TMP13.y, _TMP14.y, _TMP15.y);
+ _TMP29[0] = vec4(_TMP0.z, _TMP1.z, _TMP2.z, _TMP3.z);
+ _TMP29[1] = vec4(_TMP4.z, _TMP5.z, _TMP6.z, _TMP7.z);
+ _TMP29[2] = vec4(_TMP8.z, _TMP9.z, _TMP10.z, _TMP11.z);
+ _TMP29[3] = vec4(_TMP12.z, _TMP13.z, _TMP14.z, _TMP15.z);
+ _TMP27[0] = _fp.x*_fp.x*_fp.x;
+ _TMP27[1] = _fp.x*_fp.x;
+ _TMP27[2] = _fp.x;
+ _TMP116.x = _TMP27[0];
+ _TMP116.y = _TMP27[1];
+ _TMP116.z = _TMP27[2];
+ _TMP116.w = 1.00000000E+000;
+ _C0069[0] = dot(vec4( -1.66666672E-001, 5.00000000E-001, -3.33333343E-001, 0.00000000E+000), _TMP116);
+ _TMP117.x = _TMP27[0];
+ _TMP117.y = _TMP27[1];
+ _TMP117.z = _TMP27[2];
+ _TMP117.w = 1.00000000E+000;
+ _C0069[1] = dot(vec4( 5.00000000E-001, -1.00000000E+000, -5.00000000E-001, 1.00000000E+000), _TMP117);
+ _TMP118.x = _TMP27[0];
+ _TMP118.y = _TMP27[1];
+ _TMP118.z = _TMP27[2];
+ _TMP118.w = 1.00000000E+000;
+ _C0069[2] = dot(vec4( -5.00000000E-001, 5.00000000E-001, 1.00000000E+000, 0.00000000E+000), _TMP118);
+ _TMP119.x = _TMP27[0];
+ _TMP119.y = _TMP27[1];
+ _TMP119.z = _TMP27[2];
+ _TMP119.w = 1.00000000E+000;
+ _C0069[3] = dot(vec4( 1.66666672E-001, 0.00000000E+000, -1.66666672E-001, 0.00000000E+000), _TMP119);
+ _TMP26[0] = vec4(_fp.y*_fp.y*_fp.y, _fp.y*_fp.y, _fp.y, 1.00000000E+000);
+ _C0079[0] = _TMP26[0].x*vec4( -1.66666672E-001, 5.00000000E-001, -5.00000000E-001, 1.66666672E-001) + _TMP26[0].y*vec4( 5.00000000E-001, -1.00000000E+000, 5.00000000E-001, 0.00000000E+000) + _TMP26[0].z*vec4( -3.33333343E-001, -5.00000000E-001, 1.00000000E+000, -1.66666672E-001) + _TMP26[0].w*vec4( 0.00000000E+000, 1.00000000E+000, 0.00000000E+000, 0.00000000E+000);
+ _TMP120.x = _C0069[0];
+ _TMP120.y = _C0069[1];
+ _TMP120.z = _C0069[2];
+ _TMP120.w = _C0069[3];
+ _C0081[0] = dot(_TMP31[0], _TMP120);
+ _TMP121.x = _C0069[0];
+ _TMP121.y = _C0069[1];
+ _TMP121.z = _C0069[2];
+ _TMP121.w = _C0069[3];
+ _C0081[1] = dot(_TMP31[1], _TMP121);
+ _TMP122.x = _C0069[0];
+ _TMP122.y = _C0069[1];
+ _TMP122.z = _C0069[2];
+ _TMP122.w = _C0069[3];
+ _C0081[2] = dot(_TMP31[2], _TMP122);
+ _TMP123.x = _C0069[0];
+ _TMP123.y = _C0069[1];
+ _TMP123.z = _C0069[2];
+ _TMP123.w = _C0069[3];
+ _C0081[3] = dot(_TMP31[3], _TMP123);
+ _C0091 = _C0079[0].x*_C0081[0] + _C0079[0].y*_C0081[1] + _C0079[0].z*_C0081[2] + _C0079[0].w*_C0081[3];
+ _TMP124.x = _C0069[0];
+ _TMP124.y = _C0069[1];
+ _TMP124.z = _C0069[2];
+ _TMP124.w = _C0069[3];
+ _C0093[0] = dot(_TMP30[0], _TMP124);
+ _TMP125.x = _C0069[0];
+ _TMP125.y = _C0069[1];
+ _TMP125.z = _C0069[2];
+ _TMP125.w = _C0069[3];
+ _C0093[1] = dot(_TMP30[1], _TMP125);
+ _TMP126.x = _C0069[0];
+ _TMP126.y = _C0069[1];
+ _TMP126.z = _C0069[2];
+ _TMP126.w = _C0069[3];
+ _C0093[2] = dot(_TMP30[2], _TMP126);
+ _TMP127.x = _C0069[0];
+ _TMP127.y = _C0069[1];
+ _TMP127.z = _C0069[2];
+ _TMP127.w = _C0069[3];
+ _C0093[3] = dot(_TMP30[3], _TMP127);
+ _C0103 = _C0079[0].x*_C0093[0] + _C0079[0].y*_C0093[1] + _C0079[0].z*_C0093[2] + _C0079[0].w*_C0093[3];
+ _TMP128.x = _C0069[0];
+ _TMP128.y = _C0069[1];
+ _TMP128.z = _C0069[2];
+ _TMP128.w = _C0069[3];
+ _C0105[0] = dot(_TMP29[0], _TMP128);
+ _TMP129.x = _C0069[0];
+ _TMP129.y = _C0069[1];
+ _TMP129.z = _C0069[2];
+ _TMP129.w = _C0069[3];
+ _C0105[1] = dot(_TMP29[1], _TMP129);
+ _TMP130.x = _C0069[0];
+ _TMP130.y = _C0069[1];
+ _TMP130.z = _C0069[2];
+ _TMP130.w = _C0069[3];
+ _C0105[2] = dot(_TMP29[2], _TMP130);
+ _TMP131.x = _C0069[0];
+ _TMP131.y = _C0069[1];
+ _TMP131.z = _C0069[2];
+ _TMP131.w = _C0069[3];
+ _C0105[3] = dot(_TMP29[3], _TMP131);
+ _C0115 = _C0079[0].x*_C0105[0] + _C0079[0].y*_C0105[1] + _C0079[0].z*_C0105[2] + _C0079[0].w*_C0105[3];
+ _ret_0 = vec4(_C0091, _C0103, _C0115, 1.00000000E+000);
+ FragColor = _ret_0;
+ return;
+}
+#endif
diff --git a/BizHawk.Client.EmuHawk/DisplayManager/Filters/hq2x.cg b/output/Shaders/BizHawk/hq2x.cg
similarity index 100%
rename from BizHawk.Client.EmuHawk/DisplayManager/Filters/hq2x.cg
rename to output/Shaders/BizHawk/hq2x.cg
diff --git a/output/Shaders/BizHawk/hq2x.cgp b/output/Shaders/BizHawk/hq2x.cgp
new file mode 100644
index 0000000000..658d55b50d
--- /dev/null
+++ b/output/Shaders/BizHawk/hq2x.cgp
@@ -0,0 +1,4 @@
+shaders = 1
+
+shader0 = hq2x.glsl
+scale0 = 2
diff --git a/BizHawk.Client.EmuHawk/DisplayManager/Filters/hq2x.glsl b/output/Shaders/BizHawk/hq2x.glsl
similarity index 100%
rename from BizHawk.Client.EmuHawk/DisplayManager/Filters/hq2x.glsl
rename to output/Shaders/BizHawk/hq2x.glsl
diff --git a/output/Shaders/BizHawk/test.cgp b/output/Shaders/BizHawk/test.cgp
new file mode 100644
index 0000000000..957b0dfbf8
--- /dev/null
+++ b/output/Shaders/BizHawk/test.cgp
@@ -0,0 +1,18 @@
+shaders = 3
+
+shader0 = hq2x.glsl
+scale0 = 2
+
+shader1 = bicubic-fast.glsl
+scale_type1 = viewport
+
+shader2 = BizScanlines.glsl
+scale_type2 = source
+
+#shaders = "2" #ass
+#shader0 = dummy.cg # ass
+#shader1 = orig.cg
+#scale_type0 = source
+#scale0 = 1.0
+#filter_linear0 = true
+#filter_linear1 = true
\ No newline at end of file
diff --git a/output/Shaders/bicubic/bicubic-fast.cg b/output/Shaders/bicubic/bicubic-fast.cg
new file mode 100644
index 0000000000..3717ff27ff
--- /dev/null
+++ b/output/Shaders/bicubic/bicubic-fast.cg
@@ -0,0 +1,132 @@
+/* COMPATIBILITY
+ - HLSL compilers
+ - Cg compilers
+*/
+
+/*
+ bicubic-fast Shader
+
+ Programmed by Hyllian - 2012
+
+*/
+
+const static float4x4 invX = float4x4(-1.0/6.0, 0.5, -1.0/3.0, 0.0,
+ 0.5, -1.0, -0.5, 1.0,
+ -0.5, 0.5, 1.0, 0.0,
+ 1.0/6.0, 0.0, -1.0/6.0, 0.0);
+
+
+// Can't init statically from variable, even though it's const ...
+//const static float4x4 invY = transpose(invX);
+const static float4x4 invY = float4x4(-1.0/6.0, 0.5, -0.5, 1.0/6.0,
+ 0.5, -1.0, 0.5, 0.0,
+ -1.0/3.0, -0.5, 1.0, -1.0/6.0,
+ 0.0, 1.0, 0.0, 0.0);
+
+struct input
+{
+ float2 video_size;
+ float2 texture_size;
+ float2 output_size;
+ float frame_count;
+ float frame_direction;
+ float frame_rotation;
+};
+
+
+struct out_vertex {
+ float2 texCoord;
+ float4 t1;
+ float4 t2;
+ float4 t3;
+ float4 t4;
+ float4 t5;
+ float4 t6;
+ float4 t7;
+ float2 t8;
+};
+
+/* VERTEX_SHADER */
+out_vertex main_vertex
+(
+ float4 position : POSITION,
+ out float4 oPosition : POSITION,
+ float2 tex : TEXCOORD0,
+
+ uniform float4x4 modelViewProj,
+ uniform input IN
+)
+{
+ float2 ps = float2(1.0/IN.texture_size.x, 1.0/IN.texture_size.y);
+ float dx = ps.x;
+ float dy = ps.y;
+
+ oPosition = mul(modelViewProj, position);
+
+ out_vertex OUT = {
+ tex,
+ float4(tex,tex) + float4( -dx, -dy, 0.0, -dy),
+ float4(tex,tex) + float4( dx, -dy, 2.0*dx, -dy),
+ float4(tex,tex) + float4( -dx, 0.0, dx, 0.0),
+ float4(tex,tex) + float4(2.0*dx, 0.0, -dx, dy),
+ float4(tex,tex) + float4( 0.0, dy, dx, dy),
+ float4(tex,tex) + float4(2.0*dx, dy, -dx, 2.0*dy),
+ float4(tex,tex) + float4( 0.0, 2.0*dy, dx, 2.0*dy),
+ tex + float2(2.0*dx, 2.0*dy)
+ };
+
+
+ return OUT;
+}
+
+
+float4 main_fragment(in out_vertex VAR, uniform sampler2D s_p : TEXUNIT0, uniform input IN) : COLOR
+{
+
+ float2 fp = frac(VAR.texCoord*IN.texture_size);
+
+ float3 c00 = tex2D(s_p, VAR.t1.xy).xyz;
+ float3 c01 = tex2D(s_p, VAR.t1.zw).xyz;
+ float3 c02 = tex2D(s_p, VAR.t2.xy).xyz;
+ float3 c03 = tex2D(s_p, VAR.t2.zw).xyz;
+ float3 c10 = tex2D(s_p, VAR.t3.xy).xyz;
+ float3 c11 = tex2D(s_p, VAR.texCoord).xyz;
+ float3 c12 = tex2D(s_p, VAR.t3.zw).xyz;
+ float3 c13 = tex2D(s_p, VAR.t4.xy).xyz;
+ float3 c20 = tex2D(s_p, VAR.t4.zw).xyz;
+ float3 c21 = tex2D(s_p, VAR.t5.xy).xyz;
+ float3 c22 = tex2D(s_p, VAR.t5.zw).xyz;
+ float3 c23 = tex2D(s_p, VAR.t6.xy).xyz;
+ float3 c30 = tex2D(s_p, VAR.t6.zw).xyz;
+ float3 c31 = tex2D(s_p, VAR.t7.xy).xyz;
+ float3 c32 = tex2D(s_p, VAR.t7.zw).xyz;
+ float3 c33 = tex2D(s_p, VAR.t8.xy).xyz;
+
+
+ float4x4 red_matrix = float4x4(c00.x, c01.x, c02.x, c03.x,
+ c10.x, c11.x, c12.x, c13.x,
+ c20.x, c21.x, c22.x, c23.x,
+ c30.x, c31.x, c32.x, c33.x);
+
+ float4x4 green_matrix = float4x4(c00.y, c01.y, c02.y, c03.y,
+ c10.y, c11.y, c12.y, c13.y,
+ c20.y, c21.y, c22.y, c23.y,
+ c30.y, c31.y, c32.y, c33.y);
+
+ float4x4 blue_matrix = float4x4(c00.z, c01.z, c02.z, c03.z,
+ c10.z, c11.z, c12.z, c13.z,
+ c20.z, c21.z, c22.z, c23.z,
+ c30.z, c31.z, c32.z, c33.z);
+
+
+ float4x1 invX_Px = mul(invX, float4x1(fp.x*fp.x*fp.x, fp.x*fp.x, fp.x, 1.0));
+ float1x4 Py_invY = mul(float1x4(fp.y*fp.y*fp.y, fp.y*fp.y, fp.y, 1.0), invY);
+
+
+ float red = mul(Py_invY, mul( red_matrix, invX_Px));
+ float green = mul(Py_invY, mul(green_matrix, invX_Px));
+ float blue = mul(Py_invY, mul( blue_matrix, invX_Px));
+
+ return float4(red, green, blue, 1.0);
+}
+
diff --git a/output/Shaders/bicubic/bicubic-fast.glsl b/output/Shaders/bicubic/bicubic-fast.glsl
new file mode 100644
index 0000000000..d87555728a
--- /dev/null
+++ b/output/Shaders/bicubic/bicubic-fast.glsl
@@ -0,0 +1,338 @@
+// GLSL shader autogenerated by cg2glsl.py.
+#if defined(VERTEX)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING out
+#define COMPAT_ATTRIBUTE in
+#define COMPAT_TEXTURE texture
+#else
+#define COMPAT_VARYING varying
+#define COMPAT_ATTRIBUTE attribute
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+COMPAT_VARYING vec2 VARt8;
+COMPAT_VARYING vec4 VARt7;
+COMPAT_VARYING vec4 VARt6;
+COMPAT_VARYING vec4 VARt5;
+COMPAT_VARYING vec4 VARt4;
+COMPAT_VARYING vec4 VARt3;
+COMPAT_VARYING vec4 VARt2;
+COMPAT_VARYING vec4 VARt1;
+COMPAT_VARYING vec2 VARtexCoord;
+COMPAT_VARYING float _frame_rotation;
+
+
+struct input_dummy {
+ vec2 _video_size;
+ vec2 _texture_size;
+ vec2 _output_dummy_size;
+ float _frame_count;
+ float _frame_direction;
+ float _frame_rotation;
+};
+
+struct out_vertex {
+ vec2 VARtexCoord;
+ vec4 VARt1;
+ vec4 VARt2;
+ vec4 VARt3;
+ vec4 VARt4;
+ vec4 VARt5;
+ vec4 VARt6;
+ vec4 VARt7;
+ vec2 VARt8;
+};
+
+vec4 _oPosition1;
+out_vertex _ret_0;
+
+input_dummy _IN1;
+vec4 _r0023;
+COMPAT_ATTRIBUTE vec4 VertexCoord;
+COMPAT_ATTRIBUTE vec4 TexCoord;
+
+
+uniform mat4 MVPMatrix;
+uniform int FrameDirection;
+uniform int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+void main()
+{
+
+ vec2 _ps;
+ out_vertex _TMP17;
+
+ _ps = vec2(1.00000000E+000/TextureSize.x, 1.00000000E+000/TextureSize.y);
+ _r0023 = VertexCoord.x*MVPMatrix[0];
+ _r0023 = _r0023 + VertexCoord.y*MVPMatrix[1];
+ _r0023 = _r0023 + VertexCoord.z*MVPMatrix[2];
+ _r0023 = _r0023 + VertexCoord.w*MVPMatrix[3];
+ _oPosition1 = _r0023;
+ _TMP17.VARt1 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(-_ps.x, -_ps.y, 0.00000000E+000, -_ps.y);
+ _TMP17.VARt2 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(_ps.x, -_ps.y, 2.00000000E+000*_ps.x, -_ps.y);
+ _TMP17.VARt3 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(-_ps.x, 0.00000000E+000, _ps.x, 0.00000000E+000);
+ _TMP17.VARt4 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(2.00000000E+000*_ps.x, 0.00000000E+000, -_ps.x, _ps.y);
+ _TMP17.VARt5 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(0.00000000E+000, _ps.y, _ps.x, _ps.y);
+ _TMP17.VARt6 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(2.00000000E+000*_ps.x, _ps.y, -_ps.x, 2.00000000E+000*_ps.y);
+ _TMP17.VARt7 = vec4(TexCoord.x, TexCoord.y, TexCoord.x, TexCoord.y) + vec4(0.00000000E+000, 2.00000000E+000*_ps.y, _ps.x, 2.00000000E+000*_ps.y);
+ _TMP17.VARt8 = TexCoord.xy + vec2(2.00000000E+000*_ps.x, 2.00000000E+000*_ps.y);
+ VARtexCoord = TexCoord.xy;
+ VARt1 = _TMP17.VARt1;
+ VARt2 = _TMP17.VARt2;
+ VARt3 = _TMP17.VARt3;
+ VARt4 = _TMP17.VARt4;
+ VARt5 = _TMP17.VARt5;
+ VARt6 = _TMP17.VARt6;
+ VARt7 = _TMP17.VARt7;
+ VARt8 = _TMP17.VARt8;
+ gl_Position = _r0023;
+ return;
+}
+#elif defined(FRAGMENT)
+
+#if __VERSION__ >= 130
+#define COMPAT_VARYING in
+#define COMPAT_TEXTURE texture
+out vec4 FragColor;
+#else
+#define COMPAT_VARYING varying
+#define FragColor gl_FragColor
+#define COMPAT_TEXTURE texture2D
+#endif
+
+#ifdef GL_ES
+#ifdef GL_FRAGMENT_PRECISION_HIGH
+precision highp float;
+#else
+precision mediump float;
+#endif
+#define COMPAT_PRECISION mediump
+#else
+#define COMPAT_PRECISION
+#endif
+COMPAT_VARYING vec2 VARt8;
+COMPAT_VARYING vec4 VARt7;
+COMPAT_VARYING vec4 VARt6;
+COMPAT_VARYING vec4 VARt5;
+COMPAT_VARYING vec4 VARt4;
+COMPAT_VARYING vec4 VARt3;
+COMPAT_VARYING vec4 VARt2;
+COMPAT_VARYING vec4 VARt1;
+COMPAT_VARYING vec2 VARtexCoord;
+COMPAT_VARYING float _frame_rotation;
+
+
+struct input_dummy {
+ vec2 _video_size;
+ vec2 _texture_size;
+ vec2 _output_dummy_size;
+ float _frame_count;
+ float _frame_direction;
+ float _frame_rotation;
+};
+
+struct out_vertex {
+ vec2 VARtexCoord;
+ vec4 VARt1;
+ vec4 VARt2;
+ vec4 VARt3;
+ vec4 VARt4;
+ vec4 VARt5;
+ vec4 VARt6;
+ vec4 VARt7;
+ vec2 VARt8;
+};
+
+vec4 _ret_0;
+vec4 _TMP15;
+vec4 _TMP14;
+vec4 _TMP13;
+vec4 _TMP12;
+vec4 _TMP11;
+vec4 _TMP10;
+vec4 _TMP9;
+vec4 _TMP8;
+vec4 _TMP7;
+vec4 _TMP6;
+vec4 _TMP5;
+vec4 _TMP4;
+vec4 _TMP3;
+vec4 _TMP2;
+vec4 _TMP1;
+vec4 _TMP0;
+out_vertex _VAR1;
+uniform sampler2D Texture;
+input_dummy _IN1;
+vec2 _x0035;
+vec4 _C0069;
+vec4 _C0079[1];
+vec4 _C0081;
+float _C0091;
+vec4 _C0093;
+float _C0103;
+vec4 _C0105;
+float _C0115;
+vec4 _TMP116;
+vec4 _TMP117;
+vec4 _TMP118;
+vec4 _TMP119;
+vec4 _TMP120;
+vec4 _TMP121;
+vec4 _TMP122;
+vec4 _TMP123;
+vec4 _TMP124;
+vec4 _TMP125;
+vec4 _TMP126;
+vec4 _TMP127;
+vec4 _TMP128;
+vec4 _TMP129;
+vec4 _TMP130;
+vec4 _TMP131;
+
+
+uniform int FrameDirection;
+uniform int FrameCount;
+uniform COMPAT_PRECISION vec2 OutputSize;
+uniform COMPAT_PRECISION vec2 TextureSize;
+uniform COMPAT_PRECISION vec2 InputSize;
+void main()
+{
+
+ vec2 _fp;
+ vec4 _TMP26[1];
+ vec4 _TMP27;
+ vec4 _TMP29[4];
+ vec4 _TMP30[4];
+ vec4 _TMP31[4];
+
+ _x0035 = VARtexCoord*TextureSize;
+ _fp = fract(_x0035);
+ _TMP0 = COMPAT_TEXTURE(Texture, VARt1.xy);
+ _TMP1 = COMPAT_TEXTURE(Texture, VARt1.zw);
+ _TMP2 = COMPAT_TEXTURE(Texture, VARt2.xy);
+ _TMP3 = COMPAT_TEXTURE(Texture, VARt2.zw);
+ _TMP4 = COMPAT_TEXTURE(Texture, VARt3.xy);
+ _TMP5 = COMPAT_TEXTURE(Texture, VARtexCoord);
+ _TMP6 = COMPAT_TEXTURE(Texture, VARt3.zw);
+ _TMP7 = COMPAT_TEXTURE(Texture, VARt4.xy);
+ _TMP8 = COMPAT_TEXTURE(Texture, VARt4.zw);
+ _TMP9 = COMPAT_TEXTURE(Texture, VARt5.xy);
+ _TMP10 = COMPAT_TEXTURE(Texture, VARt5.zw);
+ _TMP11 = COMPAT_TEXTURE(Texture, VARt6.xy);
+ _TMP12 = COMPAT_TEXTURE(Texture, VARt6.zw);
+ _TMP13 = COMPAT_TEXTURE(Texture, VARt7.xy);
+ _TMP14 = COMPAT_TEXTURE(Texture, VARt7.zw);
+ _TMP15 = COMPAT_TEXTURE(Texture, VARt8.xy);
+ _TMP31[0] = vec4(_TMP0.x, _TMP1.x, _TMP2.x, _TMP3.x);
+ _TMP31[1] = vec4(_TMP4.x, _TMP5.x, _TMP6.x, _TMP7.x);
+ _TMP31[2] = vec4(_TMP8.x, _TMP9.x, _TMP10.x, _TMP11.x);
+ _TMP31[3] = vec4(_TMP12.x, _TMP13.x, _TMP14.x, _TMP15.x);
+ _TMP30[0] = vec4(_TMP0.y, _TMP1.y, _TMP2.y, _TMP3.y);
+ _TMP30[1] = vec4(_TMP4.y, _TMP5.y, _TMP6.y, _TMP7.y);
+ _TMP30[2] = vec4(_TMP8.y, _TMP9.y, _TMP10.y, _TMP11.y);
+ _TMP30[3] = vec4(_TMP12.y, _TMP13.y, _TMP14.y, _TMP15.y);
+ _TMP29[0] = vec4(_TMP0.z, _TMP1.z, _TMP2.z, _TMP3.z);
+ _TMP29[1] = vec4(_TMP4.z, _TMP5.z, _TMP6.z, _TMP7.z);
+ _TMP29[2] = vec4(_TMP8.z, _TMP9.z, _TMP10.z, _TMP11.z);
+ _TMP29[3] = vec4(_TMP12.z, _TMP13.z, _TMP14.z, _TMP15.z);
+ _TMP27[0] = _fp.x*_fp.x*_fp.x;
+ _TMP27[1] = _fp.x*_fp.x;
+ _TMP27[2] = _fp.x;
+ _TMP116.x = _TMP27[0];
+ _TMP116.y = _TMP27[1];
+ _TMP116.z = _TMP27[2];
+ _TMP116.w = 1.00000000E+000;
+ _C0069[0] = dot(vec4( -1.66666672E-001, 5.00000000E-001, -3.33333343E-001, 0.00000000E+000), _TMP116);
+ _TMP117.x = _TMP27[0];
+ _TMP117.y = _TMP27[1];
+ _TMP117.z = _TMP27[2];
+ _TMP117.w = 1.00000000E+000;
+ _C0069[1] = dot(vec4( 5.00000000E-001, -1.00000000E+000, -5.00000000E-001, 1.00000000E+000), _TMP117);
+ _TMP118.x = _TMP27[0];
+ _TMP118.y = _TMP27[1];
+ _TMP118.z = _TMP27[2];
+ _TMP118.w = 1.00000000E+000;
+ _C0069[2] = dot(vec4( -5.00000000E-001, 5.00000000E-001, 1.00000000E+000, 0.00000000E+000), _TMP118);
+ _TMP119.x = _TMP27[0];
+ _TMP119.y = _TMP27[1];
+ _TMP119.z = _TMP27[2];
+ _TMP119.w = 1.00000000E+000;
+ _C0069[3] = dot(vec4( 1.66666672E-001, 0.00000000E+000, -1.66666672E-001, 0.00000000E+000), _TMP119);
+ _TMP26[0] = vec4(_fp.y*_fp.y*_fp.y, _fp.y*_fp.y, _fp.y, 1.00000000E+000);
+ _C0079[0] = _TMP26[0].x*vec4( -1.66666672E-001, 5.00000000E-001, -5.00000000E-001, 1.66666672E-001) + _TMP26[0].y*vec4( 5.00000000E-001, -1.00000000E+000, 5.00000000E-001, 0.00000000E+000) + _TMP26[0].z*vec4( -3.33333343E-001, -5.00000000E-001, 1.00000000E+000, -1.66666672E-001) + _TMP26[0].w*vec4( 0.00000000E+000, 1.00000000E+000, 0.00000000E+000, 0.00000000E+000);
+ _TMP120.x = _C0069[0];
+ _TMP120.y = _C0069[1];
+ _TMP120.z = _C0069[2];
+ _TMP120.w = _C0069[3];
+ _C0081[0] = dot(_TMP31[0], _TMP120);
+ _TMP121.x = _C0069[0];
+ _TMP121.y = _C0069[1];
+ _TMP121.z = _C0069[2];
+ _TMP121.w = _C0069[3];
+ _C0081[1] = dot(_TMP31[1], _TMP121);
+ _TMP122.x = _C0069[0];
+ _TMP122.y = _C0069[1];
+ _TMP122.z = _C0069[2];
+ _TMP122.w = _C0069[3];
+ _C0081[2] = dot(_TMP31[2], _TMP122);
+ _TMP123.x = _C0069[0];
+ _TMP123.y = _C0069[1];
+ _TMP123.z = _C0069[2];
+ _TMP123.w = _C0069[3];
+ _C0081[3] = dot(_TMP31[3], _TMP123);
+ _C0091 = _C0079[0].x*_C0081[0] + _C0079[0].y*_C0081[1] + _C0079[0].z*_C0081[2] + _C0079[0].w*_C0081[3];
+ _TMP124.x = _C0069[0];
+ _TMP124.y = _C0069[1];
+ _TMP124.z = _C0069[2];
+ _TMP124.w = _C0069[3];
+ _C0093[0] = dot(_TMP30[0], _TMP124);
+ _TMP125.x = _C0069[0];
+ _TMP125.y = _C0069[1];
+ _TMP125.z = _C0069[2];
+ _TMP125.w = _C0069[3];
+ _C0093[1] = dot(_TMP30[1], _TMP125);
+ _TMP126.x = _C0069[0];
+ _TMP126.y = _C0069[1];
+ _TMP126.z = _C0069[2];
+ _TMP126.w = _C0069[3];
+ _C0093[2] = dot(_TMP30[2], _TMP126);
+ _TMP127.x = _C0069[0];
+ _TMP127.y = _C0069[1];
+ _TMP127.z = _C0069[2];
+ _TMP127.w = _C0069[3];
+ _C0093[3] = dot(_TMP30[3], _TMP127);
+ _C0103 = _C0079[0].x*_C0093[0] + _C0079[0].y*_C0093[1] + _C0079[0].z*_C0093[2] + _C0079[0].w*_C0093[3];
+ _TMP128.x = _C0069[0];
+ _TMP128.y = _C0069[1];
+ _TMP128.z = _C0069[2];
+ _TMP128.w = _C0069[3];
+ _C0105[0] = dot(_TMP29[0], _TMP128);
+ _TMP129.x = _C0069[0];
+ _TMP129.y = _C0069[1];
+ _TMP129.z = _C0069[2];
+ _TMP129.w = _C0069[3];
+ _C0105[1] = dot(_TMP29[1], _TMP129);
+ _TMP130.x = _C0069[0];
+ _TMP130.y = _C0069[1];
+ _TMP130.z = _C0069[2];
+ _TMP130.w = _C0069[3];
+ _C0105[2] = dot(_TMP29[2], _TMP130);
+ _TMP131.x = _C0069[0];
+ _TMP131.y = _C0069[1];
+ _TMP131.z = _C0069[2];
+ _TMP131.w = _C0069[3];
+ _C0105[3] = dot(_TMP29[3], _TMP131);
+ _C0115 = _C0079[0].x*_C0105[0] + _C0079[0].y*_C0105[1] + _C0079[0].z*_C0105[2] + _C0079[0].w*_C0105[3];
+ _ret_0 = vec4(_C0091, _C0103, _C0115, 1.00000000E+000);
+ FragColor = _ret_0;
+ return;
+}
+#endif