| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- 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);
- }
- }
- }
|