OGLFrameBuffer.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using OpenTK;
  2. using OpenTK.Graphics.OpenGL;
  3. using System;
  4. namespace Ryujinx.Graphics.Gal.OpenGL
  5. {
  6. class OGLFrameBuffer
  7. {
  8. private struct FrameBuffer
  9. {
  10. public int FbHandle;
  11. public int RbHandle;
  12. public int TexHandle;
  13. }
  14. private struct ShaderProgram
  15. {
  16. public int Handle;
  17. public int VpHandle;
  18. public int FpHandle;
  19. }
  20. private FrameBuffer[] Fbs;
  21. private ShaderProgram Shader;
  22. private bool IsInitialized;
  23. private int VaoHandle;
  24. private int VboHandle;
  25. public OGLFrameBuffer()
  26. {
  27. Fbs = new FrameBuffer[16];
  28. Shader = new ShaderProgram();
  29. }
  30. public void Set(int Index, int Width, int Height)
  31. {
  32. if (Fbs[Index].FbHandle != 0)
  33. {
  34. return;
  35. }
  36. Fbs[Index].FbHandle = GL.GenFramebuffer();
  37. Fbs[Index].RbHandle = GL.GenRenderbuffer();
  38. Fbs[Index].TexHandle = GL.GenTexture();
  39. GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fbs[Index].FbHandle);
  40. GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, Fbs[Index].RbHandle);
  41. GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Depth24Stencil8, 1280, 720);
  42. GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, Fbs[Index].RbHandle);
  43. GL.BindTexture(TextureTarget.Texture2D, Fbs[Index].TexHandle);
  44. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
  45. GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
  46. GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, 1280, 720, 0, PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
  47. GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, Fbs[Index].TexHandle, 0);
  48. GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
  49. }
  50. public void Bind(int Index)
  51. {
  52. if (Fbs[Index].FbHandle == 0)
  53. {
  54. return;
  55. }
  56. GL.BindFramebuffer(FramebufferTarget.Framebuffer, Fbs[Index].FbHandle);
  57. }
  58. public void Draw(int Index)
  59. {
  60. if (Fbs[Index].FbHandle == 0)
  61. {
  62. return;
  63. }
  64. EnsureInitialized();
  65. GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
  66. GL.BindTexture(TextureTarget.Texture2D, Fbs[Index].TexHandle);
  67. GL.ActiveTexture(TextureUnit.Texture0);
  68. GL.BindVertexArray(VaoHandle);
  69. GL.UseProgram(Shader.Handle);
  70. GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);
  71. }
  72. private void EnsureInitialized()
  73. {
  74. if (!IsInitialized)
  75. {
  76. IsInitialized = true;
  77. SetupShader();
  78. SetupVertex();
  79. }
  80. }
  81. private void SetupShader()
  82. {
  83. Shader.VpHandle = GL.CreateShader(ShaderType.VertexShader);
  84. Shader.FpHandle = GL.CreateShader(ShaderType.FragmentShader);
  85. string VpSource = EmbeddedResource.GetString("GlFbVtxShader");
  86. string FpSource = EmbeddedResource.GetString("GlFbFragShader");
  87. GL.ShaderSource(Shader.VpHandle, VpSource);
  88. GL.ShaderSource(Shader.FpHandle, FpSource);
  89. GL.CompileShader(Shader.VpHandle);
  90. GL.CompileShader(Shader.FpHandle);
  91. Shader.Handle = GL.CreateProgram();
  92. GL.AttachShader(Shader.Handle, Shader.VpHandle);
  93. GL.AttachShader(Shader.Handle, Shader.FpHandle);
  94. GL.LinkProgram(Shader.Handle);
  95. GL.UseProgram(Shader.Handle);
  96. Matrix2 Transform = Matrix2.CreateScale(1, -1);
  97. int TexUniformLocation = GL.GetUniformLocation(Shader.Handle, "tex");
  98. GL.Uniform1(TexUniformLocation, 0);
  99. int WindowSizeUniformLocation = GL.GetUniformLocation(Shader.Handle, "window_size");
  100. GL.Uniform2(WindowSizeUniformLocation, new Vector2(1280.0f, 720.0f));
  101. int TransformUniformLocation = GL.GetUniformLocation(Shader.Handle, "transform");
  102. GL.UniformMatrix2(TransformUniformLocation, false, ref Transform);
  103. }
  104. private void SetupVertex()
  105. {
  106. VaoHandle = GL.GenVertexArray();
  107. VboHandle = GL.GenBuffer();
  108. float[] Buffer = new float[]
  109. {
  110. -1, 1, 0, 0,
  111. 1, 1, 1, 0,
  112. -1, -1, 0, 1,
  113. 1, -1, 1, 1
  114. };
  115. IntPtr Length = new IntPtr(Buffer.Length * 4);
  116. GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
  117. GL.BufferData(BufferTarget.ArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw);
  118. GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
  119. GL.BindVertexArray(VaoHandle);
  120. GL.EnableVertexAttribArray(0);
  121. GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
  122. GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 16, 0);
  123. GL.EnableVertexAttribArray(1);
  124. GL.BindBuffer(BufferTarget.ArrayBuffer, VboHandle);
  125. GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 16, 8);
  126. }
  127. }
  128. }