mirror of
https://github.com/4sval/FModel.git
synced 2026-03-22 01:34:37 -05:00
129 lines
4.1 KiB
C#
129 lines
4.1 KiB
C#
using System;
|
|
using FModel.Views.Snooper.Shading;
|
|
using FModel.Views.Snooper.Textures;
|
|
using OpenTK.Graphics.OpenGL4;
|
|
|
|
namespace FModel.Views.Snooper.Buffers;
|
|
|
|
public class FramebufferObject : IDisposable
|
|
{
|
|
private int _framebufferHandle;
|
|
private int _postProcessingHandle;
|
|
|
|
private int _width;
|
|
private int _height;
|
|
private readonly MsaaTexture _framebufferTexture;
|
|
private readonly RenderbufferObject _renderbuffer;
|
|
private readonly FramebufferTexture _postProcessingTexture;
|
|
|
|
private BufferObject<uint> _ebo;
|
|
private BufferObject<float> _vbo;
|
|
private VertexArrayObject<float, uint> _vao;
|
|
|
|
private Shader _shader;
|
|
|
|
public readonly uint[] Indices = { 0, 1, 2, 3, 4, 5 };
|
|
public readonly float[] Vertices = {
|
|
// Coords // texCoords
|
|
1.0f, -1.0f, 1.0f, 0.0f,
|
|
-1.0f, -1.0f, 0.0f, 0.0f,
|
|
-1.0f, 1.0f, 0.0f, 1.0f,
|
|
|
|
1.0f, 1.0f, 1.0f, 1.0f,
|
|
1.0f, -1.0f, 1.0f, 0.0f,
|
|
-1.0f, 1.0f, 0.0f, 1.0f
|
|
};
|
|
|
|
public FramebufferObject(OpenTK.Mathematics.Vector2i size)
|
|
{
|
|
_width = size.X;
|
|
_height = size.Y;
|
|
_framebufferTexture = new MsaaTexture((uint) _width, (uint) _height);
|
|
_renderbuffer = new RenderbufferObject(_width, _height);
|
|
_postProcessingTexture = new FramebufferTexture(_width, _height);
|
|
}
|
|
|
|
public void Setup()
|
|
{
|
|
_framebufferHandle = GL.GenFramebuffer();
|
|
Bind();
|
|
|
|
_framebufferTexture.Setup();
|
|
_renderbuffer.Setup();
|
|
|
|
_shader = new Shader("framebuffer");
|
|
_shader.Use();
|
|
_shader.SetUniform("screenTexture", 0);
|
|
|
|
_ebo = new BufferObject<uint>(Indices, BufferTarget.ElementArrayBuffer);
|
|
_vbo = new BufferObject<float>(Vertices, BufferTarget.ArrayBuffer);
|
|
_vao = new VertexArrayObject<float, uint>(_vbo, _ebo);
|
|
|
|
_vao.VertexAttributePointer(0, 2, VertexAttribPointerType.Float, 4, 0); // position
|
|
_vao.VertexAttributePointer(1, 2, VertexAttribPointerType.Float, 4, 2); // uv
|
|
|
|
var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
|
|
if (status != FramebufferErrorCode.FramebufferComplete)
|
|
{
|
|
throw new Exception($"Framebuffer failed to bind with error: {GL.GetProgramInfoLog(_framebufferHandle)}");
|
|
}
|
|
|
|
_postProcessingHandle = GL.GenFramebuffer();
|
|
Bind(_postProcessingHandle);
|
|
|
|
_postProcessingTexture.Setup();
|
|
|
|
status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
|
|
if (status != FramebufferErrorCode.FramebufferComplete)
|
|
{
|
|
throw new Exception($"Post-Processing framebuffer failed to bind with error: {GL.GetProgramInfoLog(_postProcessingHandle)}");
|
|
}
|
|
}
|
|
|
|
public void Bind() => Bind(_framebufferHandle);
|
|
public void Bind(int handle)
|
|
{
|
|
GL.BindFramebuffer(FramebufferTarget.Framebuffer, handle);
|
|
}
|
|
|
|
public void BindMsaa()
|
|
{
|
|
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, _framebufferHandle);
|
|
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, _postProcessingHandle);
|
|
GL.BlitFramebuffer(0, 0, _width, _height, 0, 0, _width, _height, ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest);
|
|
GL.Disable(EnableCap.DepthTest);
|
|
|
|
_shader.Use();
|
|
_vao.Bind();
|
|
|
|
_postProcessingTexture.Bind(TextureUnit.Texture0);
|
|
|
|
GL.DrawArrays(PrimitiveType.Triangles, 0, Indices.Length);
|
|
GL.Enable(EnableCap.DepthTest);
|
|
}
|
|
|
|
public IntPtr GetPointer() => _postProcessingTexture.GetPointer();
|
|
|
|
public void WindowResized(int width, int height)
|
|
{
|
|
_width = width;
|
|
_height = height;
|
|
|
|
_renderbuffer.WindowResized(width, height);
|
|
|
|
_framebufferTexture.WindowResized(width, height);
|
|
_postProcessingTexture.WindowResized(width, height);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_vao?.Dispose();
|
|
_shader?.Dispose();
|
|
_framebufferTexture?.Dispose();
|
|
_postProcessingTexture?.Dispose();
|
|
_renderbuffer?.Dispose();
|
|
GL.DeleteFramebuffer(_framebufferHandle);
|
|
GL.DeleteFramebuffer(_postProcessingHandle);
|
|
}
|
|
}
|