6#include <brenta/renderer/opengl/framebuffer.hpp>
7#include <brenta/renderer/opengl/gl.hpp>
8#include <brenta/logger.hpp>
9#include <brenta/window.hpp>
13using namespace brenta;
15int FrameBuffer::tot_memory = 0;
17FrameBuffer::FrameBuffer(
int width,
int height, GLenum color_format)
20 GLint old_fbo, old_tex, old_rbo;
21 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo);
22 glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_tex);
23 glGetIntegerv(GL_RENDERBUFFER_BINDING, &old_rbo);
26 this->height = height;
27 this->color_format = color_format;
29 glGenFramebuffers(1, &this->
id);
32 ERROR(
"framebuffer: error generating framebuffer");
33 throw std::runtime_error(
"framebuffer: error generating framebuffer");
35 glBindFramebuffer(GL_FRAMEBUFFER, this->
id);
38 glGenTextures(1, &this->texture_id);
39 if (this->texture_id == 0)
41 ERROR(
"framebuffer: error generating texture");
44 glBindTexture(GL_TEXTURE_2D, this->texture_id);
47 glTexImage2D(GL_TEXTURE_2D, 0, this->color_format, width, height, 0, GL_RGB,
48 this->channel_type, NULL);
49 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
50 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
51 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
54 glGenRenderbuffers(1, &this->render_buffer_id);
55 glBindRenderbuffer(GL_RENDERBUFFER, this->render_buffer_id);
56 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
57 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
58 GL_RENDERBUFFER, this->render_buffer_id);
61 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
63 ERROR(
"framebuffer: not complete");
68 glBindFramebuffer(GL_FRAMEBUFFER, old_fbo);
69 glBindTexture(GL_TEXTURE_2D, old_tex);
70 glBindRenderbuffer(GL_RENDERBUFFER, old_rbo);
73 int channels = Gl::get_num_channels(this->color_format);
74 int bytes_per_channel = Gl::get_bytes_per_channel(this->channel_type);
75 this->memory = channels * bytes_per_channel * width * height;
76 FrameBuffer::tot_memory += this->memory;
78 EVENT(Logger::Event::Lifetime,
"framebuffer: initialized");
82FrameBuffer::~FrameBuffer()
88void FrameBuffer::bind()
const
90 glBindFramebuffer(GL_FRAMEBUFFER, this->
id);
95void FrameBuffer::unbind()
const
97 glBindFramebuffer(GL_FRAMEBUFFER, 0);
102void FrameBuffer::destroy()
104 if (this->
id == 0)
return;
106 glDeleteFramebuffers(1, &this->
id);
107 glDeleteTextures(1, &this->texture_id);
110 FrameBuffer::tot_memory -= this->memory;
114 EVENT(Logger::Event::Lifetime,
"framebuffer: destroyed");
118void FrameBuffer::rescale(
int width,
int height)
120 if (this->width == width && this->height == height)
122 FrameBuffer::tot_memory -= this->memory;
124 glBindFramebuffer(GL_FRAMEBUFFER, this->
id);
127 this->height = height;
128 glBindTexture(GL_TEXTURE_2D, this->texture_id);
131 glTexImage2D(GL_TEXTURE_2D, 0, this->color_format, width, height, 0,
132 this->color_format, this->channel_type, NULL);
133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
135 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
136 this->texture_id, 0);
137 glBindTexture(GL_TEXTURE_2D, 0);
140 glBindRenderbuffer(GL_RENDERBUFFER, this->render_buffer_id);
141 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
142 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
143 GL_RENDERBUFFER, this->render_buffer_id);
144 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
146 ERROR(
"framebuffer: not complete");
151 int channels = Gl::get_num_channels(this->color_format);
152 int bytes_per_channel = Gl::get_bytes_per_channel(channel_type);
153 this->memory = channels * bytes_per_channel * width * height;
154 FrameBuffer::tot_memory += this->memory;
159void FrameBuffer::set_color_format(GLenum color_format)
161 this->color_format = color_format;