cgv
Loading...
Searching...
No Matches
a_buffer.cxx
1#include "a_buffer.h"
2
3namespace cgv {
4 namespace render {
5
6 void a_buffer::ensure_buffers(context& ctx)
7 {
8 unsigned num_pixels = ctx.get_width() * ctx.get_height();
9 // Generate buffers for the a-buffer transparency implementation
10 node_counter_buffer.create_or_resize(ctx, sizeof(GLuint));
11 head_pointer_buffer.create_or_resize(ctx, num_pixels * sizeof(GLuint));
12 node_buffer.create_or_resize(ctx, nodes_per_pixel * 3 * num_pixels * sizeof(GLuint));
13 }
14 void a_buffer::update_shader_program_options(shader_compile_options& options, bool include_binding_points)
15 {
16 options.define_macro_if_not_default("MAX_FRAGMENTS", fragments_per_pixel, 32u);
17 options.define_macro_if_not_default("PRE_MULTIPLY_OPACITY", pre_multiply_opacity, true);
18 options.define_macro_if_not_default("Z_FIGHT_REMOVAL", z_fight_removal, 0);
19 if(include_binding_points) {
20 options.define_macro_if_not_default("NODE_COUNTER_BINDING_POINT", node_counter_binding_point, 0);
21 options.define_macro_if_not_default("HEAD_POINTERS_BINDING_POINT", head_pointers_binding_point, 0);
22 options.define_macro_if_not_default("NODES_BINDING_POINT", nodes_binding_point, 1);
23 }
24 }
25 void a_buffer::update_shader_program_options(shader_compile_options& options)
26 {
27 update_shader_program_options(options, true);
28 }
29 a_buffer::a_buffer(unsigned _fragments_per_pixel, unsigned _nodes_per_pixel, int _depth_tex_unit,
30 int _node_counter_binding_point, int _head_pointers_binding_point, int _nodes_binding_point)
31 : depth_tex("[D]")
32 {
33 depth_tex.set_min_filter(TF_NEAREST);
34 depth_tex.set_mag_filter(TF_NEAREST);
35 fragments_per_pixel = _fragments_per_pixel;
36 nodes_per_pixel = _nodes_per_pixel;
37
38 depth_tex_unit = _depth_tex_unit;
39 node_counter_binding_point = _node_counter_binding_point;
40 head_pointers_binding_point = _head_pointers_binding_point;
41 nodes_binding_point = _nodes_binding_point;
42
43 init_frame_called = false;
44 }
46 {
47 if (!clear_ssbo_prog.build_files(ctx, "a_buffer_clear", true))
48 return false;
49 update_shader_program_options(prog_options, false);
50 if (!a_buffer_prog.build_program(ctx, "a_buffer.glpr", prog_options, true))
51 return false;
52 last_prog_options = prog_options;
53 return true;
54 }
56 {
57 clear_ssbo_prog.destruct(ctx);
58 a_buffer_prog.destruct(ctx);
61 head_pointer_buffer.destruct(ctx);
62 node_buffer.destruct(ctx);
63 }
65 {
66 // Ensure depth texture and node buffers of correct size
69
70 if (!depth_tex.is_created())
71 depth_tex.create(ctx, TT_2D, ctx.get_width(), ctx.get_height());
72
73 ensure_buffers(ctx);
74
75 // Clear the atomic counter
76 const GLuint zero = 0;
77 node_counter_buffer.replace(ctx, 0, &zero, 1);
78
79 // Clear the head pointer buffer using a compute shader
80 head_pointer_buffer.bind(ctx, 0);
81 unsigned buffer_size = ctx.get_width() * ctx.get_height();
82 clear_ssbo_prog.enable(ctx);
83 clear_ssbo_prog.set_uniform(ctx, "size", buffer_size);
84 clear_ssbo_prog.set_uniform(ctx, "clear_value", -1);
85 glDispatchCompute(GLuint(ceil(buffer_size / 4)), 1, 1);
86 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
87 clear_ssbo_prog.disable(ctx);
88 head_pointer_buffer.unbind(ctx, 0);
89
90 // Check if the shader program needs to be rebuilt
91 update_shader_program_options(prog_options, false);
92 if (prog_options != last_prog_options) {
93 if (a_buffer_prog.is_created())
94 a_buffer_prog.destruct(ctx);
95 if (a_buffer_prog.build_program(ctx, "a_buffer.glpr", prog_options, true)) {
96 last_prog_options = prog_options;
97 std::cout << "a_buffer: rebuilt shader program" << std::endl;
98 }
99 }
100 init_frame_called = true;
101 }
102 bool a_buffer::enable(context& ctx, shader_program& prog, int tex_unit)
103 {
104 // in first call after init_frame, copy depth buffer to depth texture
105 if (init_frame_called) {
106 depth_tex.replace_from_buffer(ctx, 0, 0, 0, 0, ctx.get_width(), ctx.get_height());
107 init_frame_called = false;
108 }
109 // set program uniforms
110 if (!prog.set_uniform(ctx, "viewport_dims", ivec2(ctx.get_width(), ctx.get_height()))) {
111 std::cerr << "ERROR in a_buffer::enable(): uniform ivec2 viewport_dims not found in program." << std::endl;
112 return false;
113 }
114 if (!prog.set_uniform(ctx, "nodes_per_pixel", (int)nodes_per_pixel)) {
115 std::cerr << "ERROR in a_buffer::enable(): uniform int nodes_per_pixel not found in program." << std::endl;
116 return false;
117 }
118 // enable depth texture
119 if (tex_unit == -1)
120 tex_unit = depth_tex_unit;
121 depth_tex.enable(ctx, tex_unit);
122 if (!prog.set_uniform(ctx, "depth_tex", tex_unit)) {
123 std::cerr << "ERROR in a_buffer::enable(): uniform sampler2D depth_tex not found in program." << std::endl;
124 return false;
125 }
126 // Bind buffers for first a-buffer pass
128 head_pointer_buffer.bind(ctx, head_pointers_binding_point);
129 node_buffer.bind(ctx, nodes_binding_point);
130
131 return true;
132 }
133 // return current number of nodes in node buffer
134 void a_buffer::disable(context& ctx, size_t* node_count)
135 {
136 // Unbind texture and buffers
137 depth_tex.disable(ctx);
138
140 head_pointer_buffer.unbind(ctx, head_pointers_binding_point);
141 node_buffer.unbind(ctx, nodes_binding_point);
142
143 // Read back node count if requested
144 if(node_count) {
145 GLuint temp = 0;
146 node_counter_buffer.copy(ctx, 0, &temp, 1);
147 *node_count = temp;
148 }
149 }
151 {
152 ctx.push_blend_state();
153 ctx.enable_blending();
155
156 head_pointer_buffer.bind(ctx, 0);
157 node_buffer.bind(ctx, 1);
158
159 a_buffer_prog.enable(ctx);
160 a_buffer_prog.set_uniform(ctx, "viewport_dims", ivec2(ctx.get_width(), ctx.get_height()));
161 a_buffer_prog.set_uniform(ctx, "nodes_per_pixel", nodes_per_pixel);
162 if (z_fight_removal > 0) {
163 a_buffer_prog.set_uniform(ctx, "z_fight_delta", pow(10.0f, z_fight_removal_exp));
164 if (z_fight_removal > 1)
165 a_buffer_prog.set_uniform(ctx, "z_fight_window_width", z_fight_window_width);
166 }
167 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
168 a_buffer_prog.disable(ctx);
169
170 head_pointer_buffer.unbind(ctx, 0);
171 node_buffer.unbind(ctx, 1);
172
173 ctx.pop_blend_state();
174 }
175 }
176}
size_t get_width() const
return the resolution in the first dimension, or 1 if not defined
size_t get_height() const
return the resolution in the second dimension, or 1 if not defined
float z_fight_removal_exp
set thickness of fragments to 10^z_fight_removal_exp where this is measured in scaling of depth buffe...
Definition a_buffer.h:46
unsigned nodes_per_pixel
to be reserved number of fragment nodes per pixel (changes are applied when in init_frame() function)
Definition a_buffer.h:55
int z_fight_removal
whether to use volumetric blending of thickened fragments
Definition a_buffer.h:44
unsigned fragments_per_pixel
to be handled fragments per pixel (changes are applied when in init_frame() function)
Definition a_buffer.h:53
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
Definition a_buffer.cxx:29
bool pre_multiply_opacity
whether to assume that fragment color is already multiplied with opacity
Definition a_buffer.h:42
void destruct(context &ctx)
destruct all render objects
Definition a_buffer.cxx:55
bool init(context &ctx)
construct internally used programs
Definition a_buffer.cxx:45
unsigned z_fight_window_width
size of disambiguation windows
Definition a_buffer.h:48
texture depth_tex
Depth texture used to emulate depth buffer.
Definition a_buffer.h:22
bool enable(context &ctx, shader_program &prog, int tex_unit=-1)
Enable writing fragments to a_buffer with provided program.
Definition a_buffer.cxx:102
void disable(context &ctx, size_t *out_node_count=nullptr)
finish writing fragments to a_buffer and return current number of nodes in node buffer
Definition a_buffer.cxx:134
cgv::render::vertex_buffer node_counter_buffer
Buffers used to store per pixel frament lists.
Definition a_buffer.h:24
int node_counter_binding_point
Buffer binding point indices.
Definition a_buffer.h:30
void init_frame(context &ctx)
ensure that a_buffer size corresponds to context size
Definition a_buffer.cxx:64
int depth_tex_unit
Default texture unit used for depth texture.
Definition a_buffer.h:28
void finish_frame(context &ctx)
per fragment sort nodes and blend over current framebuffer
Definition a_buffer.cxx:150
base class for all drawables, which is independent of the used rendering API.
Definition context.h:670
void set_blend_func_back_to_front()
set the default blend function for back to front blending (source = BF_SRC_ALPHA, destination = BF_ON...
Definition context.cxx:1896
void push_blend_state()
push a copy of the current blend state onto the stack saved attributes: blend enablement,...
Definition context.cxx:1860
void pop_blend_state()
pop the top of the current culling state from the stack
Definition context.cxx:1864
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 void enable_blending()
enable blending
Definition context.cxx:1900
virtual bool is_created() const
return whether component has been created
Definition context.cxx:2226
Stores preprocessor options used for conditionally compiling shader programs.
Definition shader_code.h:73
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_program(const context &ctx, const std::string &file_name, bool show_error=false)
successively calls create, attach_program and link.
bool build_files(const context &ctx, const std::string &base_name, bool show_error=false)
successively calls create, attach_files and link.
void set_mag_filter(TextureFilter _mag_filter)
set the magnification filter
Definition texture.cxx:144
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.
Definition texture.cxx:214
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.
Definition texture.cxx:650
bool disable(const context &ctx)
disable texture and restore state from before last enable call
Definition texture.cxx:752
bool enable(const context &ctx, int tex_unit=-1)
enable this texture in the given texture unit, -1 corresponds to the current unit.
Definition texture.cxx:741
bool destruct(const context &ctx)
destruct the texture and free texture memory and handle
Definition texture.cxx:726
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...
Definition texture.cxx:126
bool create_or_resize(const context &ctx, size_t size_in_bytes)
Convenience wrapper to either create() or resize() the buffer.
bool copy(const context &ctx, size_t src_offset_in_bytes, size_t size_in_bytes, vertex_buffer &dst, size_t dst_offset_in_bytes) const
Copy bytes between different vertex_buffer instances.
void unbind(const context &ctx, VertexBufferType type=VBT_UNDEF) const
Unbind buffer from the appropriate target.
void destruct(const context &ctx)
destruct the render buffer
void bind(const context &ctx, VertexBufferType type=VBT_UNDEF) const
Bind buffer to appropriate target.
bool replace(const context &ctx, size_t buffer_offset_in_bytes, const T *array_ptr, size_t nr_elements)
replace part (starting at byte offset buffer_offset_in_bytes) or whole vertex buffer content from nr_...
this header is dependency free
Definition print.h:11
cgv::math::fvec< int32_t, 2 > ivec2
declare type of 2d 32 bit integer vectors
Definition fvec.h:713