aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-04-08 16:17:35 -0300
committergdkchan <gab.dark.100@gmail.com>2018-04-08 16:41:38 -0300
commitb9aa3966c00b4bb3ff0292dc28ed53ad26cf284b (patch)
treecd2ab3d65c61ac6c6ceb312116e5d138868a3e18 /Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs
parent7acd0e01226d64d05b2675f6ae07507039a31835 (diff)
Merge shader branch, adding support for GLSL decompilation, a macro
interpreter, and a rewrite of the GPU code.
Diffstat (limited to 'Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs')
-rw-r--r--Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs182
1 files changed, 182 insertions, 0 deletions
diff --git a/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs
new file mode 100644
index 00000000..f9c42ae0
--- /dev/null
+++ b/Ryujinx.Graphics/Gal/OpenGL/OGLFrameBuffer.cs
@@ -0,0 +1,182 @@
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using System;
+
+namespace Ryujinx.Graphics.Gal.OpenGL
+{
+ class OGLFrameBuffer
+ {
+ private struct FrameBuffer
+ {
+ public int FbHandle;
+ public int RbHandle;
+ public int TexHandle;
+ }
+
+ private struct ShaderProgram
+ {
+ public int Handle;
+ public int VpHandle;
+ public int FpHandle;
+ }
+
+ private FrameBuffer[] Fbs;
+
+ private ShaderProgram Shader;
+
+ private bool IsInitialized;
+
+ private int VaoHandle;
+ private int VboHandle;
+
+ public OGLFrameBuffer()
+ {
+ Fbs = new FrameBuffer[16];
+
+ Shader = new ShaderProgram();
+ }
+
+ public void Set(int Index, int Width, int Height)
+ {
+ if (Fbs[Index].FbHandle != 0)
+ {
+ return;
+ }
+
+ Fbs[Index].FbHandle = GL.GenFramebuffer();
+ Fbs[Index].RbHandle = GL.GenRenderbuffer();
+ Fbs[Index].TexHandle = GL.GenTexture();
+
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fbs[Index].FbHandle);
+
+ GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Fbs[Index].RbHandle);
+
+ GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Depth24Stencil8, 1280, 720);
+
+ GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, Fbs[Index].RbHandle);
+
+ GL.BindTexture(TextureTarget.Texture2D, Fbs[Index].TexHandle);
+
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, 1280, 720, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
+
+ GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, Fbs[Index].TexHandle, 0);
+
+ GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
+ }
+
+ public void Bind(int Index)
+ {
+ if (Fbs[Index].FbHandle == 0)
+ {
+ return;
+ }
+
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fbs[Index].FbHandle);
+ }
+
+ public void Draw(int Index)
+ {
+ if (Fbs[Index].FbHandle == 0)
+ {
+ return;
+ }
+
+ EnsureInitialized();
+
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
+
+ GL.BindTexture(TextureTarget.Texture2D, Fbs[Index].TexHandle);
+
+ GL.ActiveTexture(TextureUnit.Texture0);
+
+ GL.BindVertexArray(VaoHandle);
+
+ GL.UseProgram(Shader.Handle);
+
+ GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
+ }
+
+ private void EnsureInitialized()
+ {
+ if (!IsInitialized)
+ {
+ IsInitialized = true;
+
+ SetupShader();
+ SetupVertex();
+ }
+ }
+
+ private void SetupShader()
+ {
+ Shader.VpHandle = GL.CreateShader(ShaderType.VertexShader);
+ Shader.FpHandle = GL.CreateShader(ShaderType.FragmentShader);
+
+ string VpSource = EmbeddedResource.GetString("GlFbVtxShader");
+ string FpSource = EmbeddedResource.GetString("GlFbFragShader");
+
+ GL.ShaderSource(Shader.VpHandle, VpSource);
+ GL.ShaderSource(Shader.FpHandle, FpSource);
+ GL.CompileShader(Shader.VpHandle);
+ GL.CompileShader(Shader.FpHandle);
+
+ Shader.Handle = GL.CreateProgram();
+
+ GL.AttachShader(Shader.Handle, Shader.VpHandle);
+ GL.AttachShader(Shader.Handle, Shader.FpHandle);
+ GL.LinkProgram(Shader.Handle);
+ GL.UseProgram(Shader.Handle);
+
+ Matrix2 Transform = Matrix2.CreateScale(1, -1);
+
+ int TexUniformLocation = GL.GetUniformLocation(Shader.Handle, "tex");
+
+ GL.Uniform1(TexUniformLocation, 0);
+
+ int WindowSizeUniformLocation = GL.GetUniformLocation(Shader.Handle, "window_size");
+
+ GL.Uniform2(WindowSizeUniformLocation, new Vector2(1280.0f, 720.0f));
+
+ int TransformUniformLocation = GL.GetUniformLocation(Shader.Handle, "transform");
+
+ GL.UniformMatrix2(TransformUniformLocation, false, ref Transform);
+ }
+
+ private void SetupVertex()
+ {
+ VaoHandle = GL.GenVertexArray();
+ VboHandle = GL.GenBuffer();
+
+ float[] Buffer = new float[]
+ {
+ -1, 1, 0, 0,
+ 1, 1, 1, 0,
+ -1, -1, 0, 1,
+ 1, -1, 1, 1
+ };
+
+ IntPtr Length = new IntPtr(Buffer.Length * 4);
+
+ GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
+ GL.BufferData(BufferTarget.ArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
+ GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
+
+ GL.BindVertexArray(VaoHandle);
+
+ GL.EnableVertexAttribArray(0);
+
+ GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
+
+ GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 16, 0);
+
+ GL.EnableVertexAttribArray(1);
+
+ GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
+
+ GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 16, 8);
+ }
+ }
+} \ No newline at end of file