6 void a_buffer::ensure_buffer(GLuint& buffer, GLenum target, GLsizeiptr size,
const void* data, GLenum usage)
9 glGenBuffers(1, &buffer);
10 glBindBuffer(target, buffer);
11 glBufferData(target, size, data, usage);
12 glBindBuffer(target, 0);
16 void a_buffer::destruct_buffer(GLuint& buffer)
19 glDeleteBuffers(1, &buffer);
23 void a_buffer::destruct_buffers(context& ctx)
26 destruct_buffer(head_pointer_buffer);
27 destruct_buffer(node_buffer);
29 void a_buffer::ensure_buffers(context& ctx)
31 unsigned num_pixels = ctx.get_width() * ctx.get_height();
33 ensure_buffer(
node_buffer_counter, GL_ATOMIC_COUNTER_BUFFER,
sizeof(GLuint), NULL, GL_STATIC_DRAW);
34 ensure_buffer(head_pointer_buffer, GL_SHADER_STORAGE_BUFFER, num_pixels *
sizeof(GLuint), NULL);
36 destruct_buffer(node_buffer);
37 ensure_buffer(node_buffer, GL_SHADER_STORAGE_BUFFER,
nodes_per_pixel * 3 * num_pixels *
sizeof(GLuint), NULL);
40 void a_buffer::update_defines(
shader_define_map& defines,
bool include_binding_points)
43 defines.erase(
"MAX_FRAGMENTS");
47 if (!include_binding_points)
51 defines.erase(
"NODE_COUNTER_BINDING_POINT");
54 if (head_pointers_binding_point == 0)
55 defines.erase(
"HEAD_POINTERS_BINDING_POINT");
58 if (nodes_binding_point == 1)
59 defines.erase(
"NODES_BINDING_POINT");
65 update_defines(defines,
true);
67 a_buffer::a_buffer(
unsigned _fragments_per_pixel,
unsigned _nodes_per_pixel,
int _depth_tex_unit,
68 int _node_counter_binding_point,
int _head_pointers_binding_point,
int _nodes_binding_point)
75 last_nodes_per_pixel = 0;
77 head_pointer_buffer = 0;
82 head_pointers_binding_point = _head_pointers_binding_point;
83 nodes_binding_point = _nodes_binding_point;
85 init_frame_called =
false;
89 if (!clear_ssbo_prog.
build_files(ctx,
"a_buffer_clear",
true))
91 update_defines(defines,
false);
92 if (!a_buffer_prog.
build_program(ctx,
"a_buffer.glpr",
true, defines))
94 last_defines = defines;
102 destruct_buffers(ctx);
109 destruct_buffer(head_pointer_buffer);
110 destruct_buffer(node_buffer);
118 GLuint* ptr = (GLuint*)glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0,
sizeof(GLuint), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
119 memset(ptr, 0,
sizeof(GLuint));
120 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
121 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
124 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, head_pointer_buffer);
126 clear_ssbo_prog.
enable(ctx);
127 clear_ssbo_prog.
set_uniform(ctx,
"size", buffer_size);
128 clear_ssbo_prog.
set_uniform(ctx,
"clear_value", -1);
129 glDispatchCompute(GLuint(ceil(buffer_size / 4)), 1, 1);
130 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
132 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
135 update_defines(defines,
false);
136 if (defines != last_defines) {
139 if (a_buffer_prog.
build_program(ctx,
"a_buffer.glpr",
true, defines)) {
140 last_defines = defines;
141 std::cout <<
"a_buffer: rebuilt shader program" << std::endl;
144 init_frame_called =
true;
149 if (init_frame_called) {
151 init_frame_called =
false;
155 std::cerr <<
"ERROR in a_buffer::enable(): uniform ivec2 viewport_dims not found in program." << std::endl;
159 std::cerr <<
"ERROR in a_buffer::enable(): uniform int nodes_per_pixel not found in program." << std::endl;
166 if (!prog.
set_uniform(ctx,
"depth_tex", tex_unit)) {
167 std::cerr <<
"ERROR in a_buffer::enable(): uniform sampler2D depth_tex not found in program." << std::endl;
172 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, head_pointers_binding_point, head_pointer_buffer);
173 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, nodes_binding_point, node_buffer);
182 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, head_pointers_binding_point, 0);
183 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, nodes_binding_point, 0);
187 GLuint* ptr = (GLuint*)glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0,
sizeof(GLuint), GL_MAP_READ_BIT);
188 GLuint node_cnt = *ptr;
189 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
190 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
196 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
198 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, head_pointer_buffer);
199 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, node_buffer);
201 a_buffer_prog.
enable(ctx);
204 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
207 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
208 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
unsigned node_buffer_counter
Buffers used to store per pixel frament lists.
unsigned nodes_per_pixel
to be reserved number of fragment nodes per pixel (changes are applied when in init_frame() function)
unsigned fragments_per_pixel
to be handled fragments per pixel (changes are applied when in init_frame() function)
a_buffer(unsigned _fragments_per_pixel=32, unsigned _nodes_per_pixel=64, int _depth_tex_unit=0, int _node_counter_binding_point=0, int _head_pointers_binding_point=0, int _nodes_binding_point=1)
construct and configure
void destruct(context &ctx)
destruct all render objects
bool init(context &ctx)
construct internally used programs
texture depth_tex
Depth texture used to emulate depth buffer.
bool enable(context &ctx, shader_program &prog, int tex_unit=-1)
Enable writing fragments to a_buffer with provided program.
int node_counter_binding_point
Buffer binding point indices.
void init_frame(context &ctx)
ensure that a_buffer size corresponds to context size
int depth_tex_unit
Default texture unit used for depth texture.
void finish_frame(context &ctx)
per fragment sort nodes and blend over current framebuffer
size_t disable(context &ctx)
finish writing fragments to a_buffer and return current number of nodes in node buffer
base class for all drawables, which is independent of the used rendering API.
virtual unsigned int get_width() const =0
return the width of the window
virtual unsigned int get_height() const =0
return the height of the window
virtual bool is_created() const
return whether component has been created
a shader program combines several shader code fragments to a complete definition of the shading pipel...
bool enable(context &ctx)
enable the shader program
bool disable(context &ctx)
disable shader program and restore fixed functionality
bool set_uniform(const context &ctx, const std::string &name, const T &value, bool generate_error=false)
Set the value of a uniform by name, where the type can be any of int, unsigned, float,...
void destruct(const context &ctx)
destruct shader program
bool build_files(const context &ctx, const std::string &base_name, bool show_error=false, const shader_define_map &defines=shader_define_map())
successively calls create, attach_files and link.
bool build_program(const context &ctx, const std::string &file_name, bool show_error=false, const shader_define_map &defines=shader_define_map())
successively calls create, attach_program and link.
void set_mag_filter(TextureFilter _mag_filter)
set the magnification filter
bool create(const context &ctx, TextureType _tt=TT_UNDEF, unsigned width=-1, unsigned height=-1, unsigned depth=-1)
create the texture of dimension and resolution specified in the data format base class.
bool replace_from_buffer(const context &ctx, int x, int y, int x_buffer, int y_buffer, int width, int height, int level=-1)
replace a block within a 2d texture from the current read buffer.
bool disable(const context &ctx)
disable texture and restore state from before last enable call
bool enable(const context &ctx, int tex_unit=-1)
enable this texture in the given texture unit, -1 corresponds to the current unit.
bool destruct(const context &ctx)
destruct the texture and free texture memory and handle
void set_min_filter(TextureFilter _min_filter, float _anisotropy=2.0f)
set the minification filters, if minification is set to TF_ANISOTROP, the second floating point param...
std::map< std::string, std::string > shader_define_map
typedef for shader define map data structure
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
cgv::math::fvec< int32_t, 2 > ivec2
declare type of 2d 32 bit integer vectors