1 module polyplex.core.render.gl.renderbuf;
2 import core = polyplex.core.render;
3 import polyplex.core.render.gl.gloo;
4 
5 enum Attachment {
6     Color=GL_COLOR_ATTACHMENT0,
7     Depth=GL_DEPTH_ATTACHMENT
8 }
9 
10 public class GlFramebufferImpl : core.FramebufferImpl {
11 private:
12     Framebuffer     fbo;
13     Renderbuffer    rbo;
14     Texture[]       renderTextures;
15     GLenum[] drawBufs;
16 
17     void bufferTexture() {
18         fbo.Bind();
19 
20         // Prepare textures.
21         foreach(to; renderTextures) {
22             if (to is null) continue;
23             to.Bind(TextureType.Tex2D);
24             to.Image2D(TextureType.Tex2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
25             to.SetParameter(TextureType.Tex2D, TextureParameter.MagFilter, GL.Nearest);
26             to.SetParameter(TextureType.Tex2D, TextureParameter.MinFilter, GL.Nearest);
27         }
28 
29         rbo.Bind(); 
30         rbo.Storage(GL_DEPTH_COMPONENT, width, height);
31         fbo.Renderbuffer(FramebufferType.Multi, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo.Id);
32 
33         // Attach textures.
34         foreach(i, to; renderTextures) {
35             to.Bind(TextureType.Tex2D);
36             fbo.Texture(GL_FRAMEBUFFER, drawBufs[i], to.Id, 0);
37         }
38         GL.DrawBuffers(cast(int)drawBufs.length, drawBufs.ptr);
39     }
40 
41     void updateTextureBuffer() {
42 
43     }
44 
45 public:
46     override @property int Width() {
47         return width;
48     }
49 
50     override @property int Height() {
51         return height;
52     }
53 
54     this(int width, int height, int colorAttachments = 1) {
55         super(width, height, colorAttachments);
56         fbo = new Framebuffer();
57         rbo = new Renderbuffer();
58 
59         int colors = 0;
60         foreach(i; 0..colorAttachments) {
61             drawBufs ~= GL_COLOR_ATTACHMENT0+colors;
62             renderTextures ~= new Texture();
63             colors++;
64         }
65 
66         // Setup framebuffer
67         bufferTexture();
68         fbo.Unbind();
69     }
70     ~this() {
71         destroy(fbo);
72         destroy(renderTextures);
73         destroy(rbo);
74     }
75 
76     Texture[] OutTextures() {
77         return renderTextures;
78     }
79 
80     override void Resize(int width, int height, int colorAttachments = 1) {
81         destroy(rbo);
82         destroy(fbo);
83         destroy(renderTextures);
84         destroy(drawBufs);
85 
86         this.width = width;
87         this.height = height;
88 
89         fbo = new Framebuffer();
90         rbo = new Renderbuffer();
91 
92         // TODO: Optimize this.
93         renderTextures = new Texture[colorAttachments];
94         if (colorAttachments != drawBufs.length) {
95             drawBufs = [];
96             int colors;
97             foreach(i; 0..colorAttachments) {
98                 drawBufs ~= GL_COLOR_ATTACHMENT0+colors;
99                 renderTextures[i] = new Texture();
100                 colors++;
101             }
102         }
103 
104         // Setup framebuffer
105         bufferTexture();
106         fbo.Unbind();
107     }
108 
109     override void Begin() {
110         //destroy(rbo);
111         //destroy(to);
112         //to  = new Texture();
113         //rbo = new Renderbuffer();
114         fbo.Bind(FramebufferType.Multi);
115         bufferTexture();
116         GL.Viewport(0, 0, width, height);
117     }
118 
119     static void End() {
120         GL.BindFramebuffer(GL_FRAMEBUFFER, 0);
121     }
122 }