This repository has been archived by the owner on Apr 20, 2022. It is now read-only.
/
RenderToTexture.cs
115 lines (97 loc) · 3.69 KB
/
RenderToTexture.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using OpenTK;
using OpenTK.Graphics.OpenGL;
namespace IIS.SLSharp.Bindings.OpenTK.Textures
{
/// <summary>
/// This class is used, when render output should be captured offscreen into a (set of) Texture(s).
///
/// A fragment shader outputs to the i'th texture by writing to gl_FragData[i] or using an out
/// variable bound to the index
/// After rendering to the RenderToTexture is completed, the independant textures can be accessed
/// through the [index] operator.
/// </summary>
public sealed class RenderToTexture : IDisposable
{
private readonly FramebufferObject _fbo;
private readonly RenderbufferObject _rbo;
private readonly Bindings.OpenTK.Textures.Texture2D[] _textures;
private readonly DrawBuffersEnum[] _bufs;
/// <summary>
/// Retrieves the texture that was rendered to
/// </summary>
/// <param name="index">The output channel index to retrieve</param>
/// <returns></returns>
public Bindings.OpenTK.Textures.Texture2D this[int index]
{
get { return _textures[index]; }
}
/// <summary>
/// Creates new (set of) renderable Texture(s)
/// </summary>
/// <param name="width">The width in pixels of the Texture(s)</param>
/// <param name="height">The height in pixels of the Texture(s)</param>
/// <param name="depth">True if depthbuffer is required when rendering to the Texture(s)</param>
/// <param name="components">The number of color components the Texture(s) have</param>
/// <param name="format">The data format the Texture(s) shall use, default is 16bit Half</param>
/// <param name="buffers">The number of Textures to use.</param>
public RenderToTexture(int width, int height, bool depth, int components = 3, Type format = null, int buffers = 1)
{
_fbo = new FramebufferObject();
_textures = new Bindings.OpenTK.Textures.Texture2D[buffers];
_bufs = new DrawBuffersEnum[buffers];
for (var i = 0; i < buffers; i++)
_bufs[i] = DrawBuffersEnum.ColorAttachment0 + i;
_fbo.Activate();
GL.DrawBuffers(_textures.Length, _bufs);
Utilities.CheckGL();
_fbo.Finish();
GL.DrawBuffer(DrawBufferMode.Front);
Utilities.CheckGL();
for (var i = 0; i < buffers; i++)
{
_textures[i] = new Bindings.OpenTK.Textures.Texture2D(width, height, components, format ?? typeof(Half));
_fbo.SetTexture(_textures[i], i);
}
if (depth)
{
_rbo = new RenderbufferObject();
_fbo.Activate();
_rbo.SetSize(width, height);
_fbo.Finish();
}
_fbo.Check();
Utilities.CheckGL();
}
/// <summary>
/// Starts to capture to the textures
/// </summary>
public void Activate()
{
GL.PushAttrib(AttribMask.ViewportBit);
GL.Viewport(0, 0, _textures[0].Width, _textures[0].Height);
_fbo.Activate();
}
/// <summary>
/// Finishs capturing
/// </summary>
public void Finish()
{
_fbo.Finish();
GL.PopAttrib();
}
public void Dispose()
{
_fbo.Dispose();
if (_rbo != null)
_rbo.Dispose();
foreach (var tex in _textures)
tex.Dispose();
GC.SuppressFinalize(this);
}
~RenderToTexture()
{
Dispose();
}
}
}