cgv
Loading...
Searching...
No Matches
managed_frame_buffer.cxx
1#include "managed_frame_buffer.h"
2
3namespace cgv {
4namespace render {
5
6managed_frame_buffer::managed_frame_buffer() {
7
8 index_counter = 0;
9 size = ivec2(0);
10}
11
12managed_frame_buffer::~managed_frame_buffer() {
13
14 attachments.clear();
15}
16
17void managed_frame_buffer::destruct(const context& ctx) {
18
19 fb.destruct(ctx);
20
21 index_counter = 0;
22 for(auto it = attachments.begin(); it != attachments.end(); ++it) {
23 attachment& a = (*it).second;
24 a.tex.destruct(ctx);
25 }
26}
27
28ivec2 managed_frame_buffer::get_size() {
29
30 return ivec2(fb.get_width(), fb.get_height());
31}
32
34
35 // TODO: need gl_context for that but cannot include it in this lib
36 //GLint max_render_buffer_size;
37 //glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_render_buffer_size);
38
39 int max_render_buffer_size = 12288;
40
41 // TODO: in static builds (exe) the max render buffer size does not return useful values when this method is called in a drawable constructor
42 if(max_render_buffer_size > 0) {
43 if(size.x() > max_render_buffer_size || size.y() > max_render_buffer_size) {
44 this->size = ivec2(-1);
45 return false;
46 }
47 }
48 this->size = size;
49 return true;
50}
51
52void managed_frame_buffer::add_attachment(const std::string& name, const std::string& format, TextureFilter tf, TextureWrap tw, bool attach) {
53
54 attachment a;
55 a.attach = attach;
56 a.format = format;
57 a.tf = tf;
58 a.tw = tw;
59
60 if(a.is_depth_attachment()) {
61 a.index = 0;
62 } else {
63 a.index = index_counter;
64 ++index_counter;
65 }
66
67 attachments.insert(std::make_pair(name, a));
68}
69
70bool managed_frame_buffer::enable_attachment(context& ctx, const std::string& name, int tex_unit) {
71
72 auto elem = attachments.find(name);
73 if(elem != attachments.end()) {
74 attachment& a = (*elem).second;
75 return a.tex.enable(ctx, tex_unit);
76 }
77
78 return false;
79}
80
81bool managed_frame_buffer::disable_attachment(context& ctx, const std::string& name) {
82
83 auto elem = attachments.find(name);
84 if(elem != attachments.end()) {
85 attachment& a = (*elem).second;
86 return a.tex.disable(ctx);
87 }
88
89 return false;
90}
91
92texture* managed_frame_buffer::attachment_texture_ptr(const std::string& name) {
93
94 auto elem = attachments.find(name);
95 if(elem != attachments.end()) {
96 attachment& a = (*elem).second;
97 return &a.tex;
98 }
99
100 return nullptr;
101}
102
103bool managed_frame_buffer::ensure(context& ctx) {
104
105 ivec2 actual_size = get_actual_size(ctx);
106
107 if(!fb.is_created() || fb.get_width() != actual_size.x() || fb.get_height() != actual_size.y()) {
108 destruct(ctx);
109 if(!create_and_validate(ctx, actual_size)) {
110 std::cerr << "Error: fbo not complete" << std::endl;
111 abort();
112 }
113 return true;
114 }
115
116 return false;
117}
118
119bool managed_frame_buffer::enable(context& ctx) {
120
121 bool success = fb.enable(ctx);
122 fb.push_viewport(ctx);
123 return success;
124}
125
126bool managed_frame_buffer::disable(context& ctx) {
127
128 fb.pop_viewport(ctx);
129 return fb.disable(ctx);
130}
131
132bool managed_frame_buffer::create_and_validate(context& ctx, const ivec2& size) {
133
134 fb.create(ctx, size.x(), size.y());
135
136 for(auto it = attachments.begin(); it != attachments.end(); ++it) {
137 attachment& a = (*it).second;
138
139 unsigned filter_specifier = (unsigned)a.tf;
140
141 // even filter specifiers are nearest and odd are linear
142 TextureFilter mag_filter = (filter_specifier & 1) ? TF_LINEAR : TF_NEAREST;
143 // specifiers larger than 1 are using mipmaps
144 bool use_mipmaps = filter_specifier > 1;
145
146 a.tex = texture(a.format, mag_filter, a.tf, a.tw, a.tw);
147 a.tex.create(ctx, TT_2D, size.x(), size.y());
148
149 if(use_mipmaps)
150 a.tex.generate_mipmaps(ctx);
151
152 if(a.is_depth_attachment()) {
153 fb.attach(ctx, a.tex);
154 } else {
155 if(a.attach) {
156 fb.attach(ctx, a.tex, 0, a.index);
157 }
158 }
159 }
160
161 return fb.is_complete(ctx);
162}
163
164ivec2 managed_frame_buffer::get_actual_size(context& ctx) {
165
166 ivec2 actual_size(size);
167 if(size.x() <= 0)
168 actual_size.x() = ctx.get_width();
169 if(size.y() <= 0)
170 actual_size.y() = ctx.get_height();
171 return actual_size;
172}
173
174}
175}
bool create(const context &ctx, int _width=-1, int _height=-1)
create framebuffer if extension is supported, otherwise return false.
void push_viewport(context &ctx, const dvec2 &depth_range=dvec2(0, 1))
push a new window transformation to cover the fbo onto the window transformation stack
bool is_complete(const context &ctx) const
check for completeness, if not complete, get the reason in last_error
int get_width() const
return the width
void pop_viewport(context &ctx)
recover the window transformation array active before the last call to push_viewport
void destruct(const context &ctx)
destruct the framebuffer objext
bool attach(const context &ctx, const render_buffer &rb, int i=0)
attach render buffer to depth buffer if it is a depth buffer, to stencil if it is a stencil buffer or...
bool enable(context &ctx, int i0=-1, int i1=-1, int i2=-1, int i3=-1, int i4=-1, int i5=-1, int i6=-1, int i7=-1, int i8=-1, int i9=-1, int i10=-1, int i11=-1, int i12=-1, int i13=-1, int i14=-1, int i15=-1)
enable the framebuffer either with all color attachments if no arguments are given or if arguments ar...
bool disable(context &ctx)
disable the framebuffer object
int get_height() const
return the height
bool set_size(const ivec2 &size)
Sets the size of the framebuffer renderbuffers.
virtual bool is_created() const
return whether component has been created
Definition context.cxx:2046
TextureFilter
different texture filter
Definition context.h:189
TextureWrap
different texture wrap modes
Definition context.h:173
the cgv namespace
Definition print.h:11
cgv::math::fvec< int32_t, 2 > ivec2
declare type of 2d 32 bit integer vectors
Definition fvec.h:694