using System; using System.Drawing; using System.Windows.Forms; using OpenTK; using OpenTK.Graphics.OpenGL; namespace BizHawk.Bizware.BizwareGL.Drivers.OpenTK { /// /// Handles RetroArch's GLSL shader pass format /// This isnt implemented in BizwareGL abstract layer because it relies too much on GLSL peculiarities /// public class RetroShader : IDisposable { public RetroShader(IGL owner, string source, bool debug = false) { Owner = owner as IGL_TK; VertexLayout = owner.CreateVertexLayout(); VertexLayout.DefineVertexAttribute("VertexCoord", 0, 4, VertexAttribPointerType.Float, AttributeUsage.Unspecified, false, 40, 0); //VertexCoord VertexLayout.DefineVertexAttribute("ColorShit", 1, 4, VertexAttribPointerType.Float, AttributeUsage.Unspecified, false, 40, 16); //COLOR VertexLayout.DefineVertexAttribute("TexCoord", 2, 2, VertexAttribPointerType.Float, AttributeUsage.Unspecified, false, 40, 32); //TexCoord (is this vec2 or vec4? the glsl converted from cg had vec4 but the cg had vec2...) VertexLayout.Close(); string vsSource = "#define VERTEX\r\n" + source; string psSource = "#define FRAGMENT\r\n" + source; var vs = Owner.CreateVertexShader(vsSource, debug); var ps = Owner.CreateFragmentShader(psSource, debug); Pipeline = Owner.CreatePipeline(VertexLayout, vs, ps, debug); } public void Dispose() { VertexLayout.Dispose(); VertexLayout = null; } public void Bind() { //lame... Owner.BindPipeline(Pipeline); } public unsafe void Run(Texture2d tex, Size InputSize, Size OutputSize, bool flip) { //ack! make sure to set the pipeline before setting Bind(); Pipeline["InputSize"].Set(new Vector2(InputSize.Width,InputSize.Height)); Pipeline["TextureSize"].Set(new Vector2(InputSize.Width, InputSize.Height)); Pipeline["OutputSize"].Set(new Vector2(OutputSize.Width, OutputSize.Height)); Pipeline["FrameCount"].Set(0); //todo Pipeline["FrameDirection"].Set(1); //todo var Projection = Owner.CreateGuiProjectionMatrix(OutputSize); var Modelview = Owner.CreateGuiViewMatrix(OutputSize); Pipeline["MVPMatrix"].Set(Modelview * Projection, false); Owner.SetTextureWrapMode(tex, true); Pipeline["Texture"].Set(tex); Owner.SetViewport(OutputSize); int w = OutputSize.Width; int h = OutputSize.Height; float v0,v1; if (flip) { v0 = 1; v1 = 0; } else { v0 = 0; v1 = 1; } float* pData = stackalloc float[10*4]; int i=0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 1; //topleft vert pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //junk pData[i++] = 0; pData[i++] = v0; //texcoord pData[i++] = w; pData[i++] = 0; pData[i++] = 0; pData[i++] = 1; //topright vert pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //junk pData[i++] = 1; pData[i++] = v0; //texcoord pData[i++] = 0; pData[i++] = h; pData[i++] = 0; pData[i++] = 1; //bottomleft vert pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //junk pData[i++] = 0; pData[i++] = v1; //texcoord pData[i++] = w; pData[i++] = h; pData[i++] = 0; pData[i++] = 1; //bottomright vert pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; pData[i++] = 0; //junk pData[i++] = 1; pData[i++] = v1; //texcoord Owner.SetBlendState(Owner.BlendNoneCopy); Owner.BindArrayData(pData); Owner.DrawArrays(PrimitiveType.TriangleStrip, 0, 4); } public IGL_TK Owner { get; private set; } VertexLayout VertexLayout; public Pipeline Pipeline; } }