3#include <unordered_map>
5#include <cgv/math/constants.h>
6#include "clod_point_renderer.h"
11 constexpr int clod_reduce_group_size = 256;
24 GLuint baseInstance = 0;
30 static int ref_count = 0;
32 r.manage_singelton(ctx,
"clod_point_renderer", ref_count, ref_count_change);
40 min_millimeters = 1.f;
50 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, drawp_pos, active_draw_parameter_buffer);
51 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, render_pos, active_render_buffer);
52 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index_pos, active_index_buffer);
54 reset_draw_parameters(ctx, active_draw_parameter_buffer);
55 reduce_prog.
set_uniform(ctx, uniforms.frustum_extent, frustum_extend);
56 reduce_prog.
set_uniform(ctx, uniforms.target_buffer_size, active_buffer_manager_ptr->
size());
65 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, input_pos, buffer);
66 if (point_id_buffer != -1) {
67 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, input_id_pos, point_id_buffer);
68 reduce_prog.
set_uniform(ctx,
"use_index_as_id",
false);
71 reduce_prog.
set_uniform(ctx, uniforms.batch_offset, (
int)start);
72 reduce_prog.
set_uniform(ctx, uniforms.batch_size, (
int)count);
74 glDispatchCompute(
static_cast<GLuint
>(count / clod_reduce_group_size) + 1, 1, 1);
80 glMemoryBarrier(GL_ALL_BARRIER_BITS);
88 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, drawp_pos, active_draw_parameter_buffer);
89 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, render_pos, active_render_buffer);
90 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index_pos, active_index_buffer);
92 reset_draw_parameters(ctx, active_draw_parameter_buffer);
94 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, input_pos, input_buffer);
97 reduce_prog.
set_uniform(ctx, uniforms.batch_offset, (
int)start);
98 reduce_prog.
set_uniform(ctx, uniforms.batch_size, (
int)count);
99 reduce_prog.
set_uniform(ctx, uniforms.frustum_extent, frustum_extend);
100 reduce_prog.
set_uniform(ctx, uniforms.target_buffer_size, active_buffer_manager_ptr->
size());
104 glDispatchCompute((input_buffer_num_points / clod_reduce_group_size) + 1, 1, 1);
107 glMemoryBarrier(GL_ALL_BARRIER_BITS);
116 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, drawp_pos, active_draw_parameter_buffer);
117 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, render_pos, active_render_buffer);
118 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index_pos, active_index_buffer);
120 reset_draw_parameters(ctx, active_draw_parameter_buffer);
122 reduce_prog.
set_uniform(ctx, uniforms.frustum_extent, frustum_extend);
123 reduce_prog.
set_uniform(ctx, uniforms.target_buffer_size, active_buffer_manager_ptr->
size());
126 for (uint32_t i = 0; i < num_reduction_sources; ++i) {
127 auto chunk_id = reduction_sources[i];
128 reduce_prog.
set_uniform(ctx, uniforms.batch_offset, (
int)chunk_starts[chunk_id]);
129 reduce_prog.
set_uniform(ctx, uniforms.batch_size, (
int)chunk_point_counts[chunk_id]);
130 glDispatchCompute((chunk_point_counts[chunk_id] / clod_reduce_group_size) + 1, 1, 1);
134 glMemoryBarrier(GL_ALL_BARRIER_BITS);
141 draw_prog_ptr->
enable(ctx);
143 glBindVertexArray(active_vertex_array);
144 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, active_draw_parameter_buffer);
145 glDrawArraysIndirect(GL_POINTS, 0);
155 const render_style* clod_point_renderer::get_style_ptr()
const
159 if (default_render_style)
160 return default_render_style;
161 default_render_style = create_render_style();
162 return default_render_style;
165 clod_point_renderer::clod_point_renderer()
167 pivot_point_in_view_space =
vec4(0.0, 0.0, 0.0, 1.0);
170 render_style* clod_point_renderer::create_render_style()
const
172 return new clod_point_render_style();
175 bool clod_point_renderer::init(context& ctx)
179 add_shader(ctx, reduce_prog,
"point_clod_filter_points.glcs", cgv::render::ST_COMPUTE);
180 reduce_prog.
link(ctx);
187 uniforms.protection_zone_points = reduce_prog.
get_uniform_location(ctx,
"protection_zone_points");
198 glGenBuffers(1, &input_buffer);
200 buffer_manager.init(ctx);
201 buffer_manager.resize(1000000);
202 enable_buffer_manager(buffer_manager);
204 draw_prog_ptr = &draw_prog;
211 const clod_point_render_style& prs = get_style<clod_point_render_style>();
225 vec2 screenSize(
static_cast<float>(ctx.get_width()),
static_cast<float>(ctx.get_height()));
227 draw_prog_ptr->
set_uniform(ctx,
"CLOD" , prs.CLOD);
228 draw_prog_ptr->
set_uniform(ctx,
"scale", prs.scale);
229 draw_prog_ptr->
set_uniform(ctx,
"spacing", prs.spacing);
230 draw_prog_ptr->
set_uniform(ctx,
"pointSize", prs.pointSize);
231 draw_prog_ptr->
set_uniform(ctx,
"minMilimeters", prs.min_millimeters);
232 draw_prog_ptr->
set_uniform(ctx,
"screenSize", screenSize);
233 draw_prog_ptr->
set_uniform(ctx,
"pivot", pivot_point_in_view_space);
234 draw_prog_ptr->
set_uniform(ctx,
"draw_circles", prs.draw_circles);
238 mat4 modelview_matrix = ctx.get_modelview_matrix();
239 mat4 projection_matrix = ctx.get_projection_matrix();
240 mat4 reduction_mvp_matrix = projection_matrix * reduction_model_view_matrix;
241 mat4 mvp_matrix = projection_matrix * modelview_matrix;
242 draw_prog_ptr->
set_uniform(ctx,
"modelview", modelview_matrix);
243 draw_prog_ptr->
set_uniform(ctx,
"projection", projection_matrix);
245 draw_prog_ptr->
set_uniform(ctx,
"model_view_projection", mvp_matrix);
247 reduce_prog.
set_uniform(ctx,
"model_view_projection", reduction_mvp_matrix);
248 reduce_prog.
set_uniform(ctx,
"model_view", reduction_model_view_matrix);
251 reduce_prog.
set_uniform(ctx, uniforms.CLOD, prs.CLOD);
252 reduce_prog.
set_uniform(ctx, uniforms.scale, prs.scale);
253 reduce_prog.
set_uniform(ctx, uniforms.spacing, prs.spacing);
254 reduce_prog.
set_uniform(ctx, uniforms.pivot, pivot_point_in_view_space);
255 reduce_prog.
set_uniform(ctx, uniforms.screenSize, screenSize);
257 reduce_prog.
set_uniform(ctx,
"use_clod", prs.use_clod);
260 dmat4 transform = ctx.get_projection_matrix();
261 vec4 p4 = transform.row(3);
263 vec4 hpa = p4 - transform.row(1);
264 vec4 hpb = p4 + transform.row(1);
266 vec3 pa =
vec3(hpa.x(), hpa.y(), hpa.z());
267 vec3 pb =
vec3(hpb.x(), hpb.y(), hpb.z());
269 double y_view_angle = PI - acos(dot(pa, pb) / (pa.length() * pb.length()));
270 float pixel_extent_per_depth = (float)(2.0 * tan(0.5 * y_view_angle) / ctx.get_height());
273 draw_prog_ptr->
set_uniform(ctx,
"use_color_index",
false);
274 draw_prog_ptr->
set_uniform(ctx,
"pixel_extent_per_depth", pixel_extent_per_depth);
282 return enable(ctx, reduce_model_view);
285 bool clod_point_renderer::disable(
context& ctx)
287 draw_prog_ptr = &draw_prog;
290 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
291 glBindVertexArray(0);
293 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
304 void clod_point_renderer::disable_buffer_manager()
306 enable_buffer_manager(buffer_manager);
315 bool clod_point_renderer::render(
context& ctx,
size_t start,
size_t count)
318 draw(ctx, start, count);
325 assert(input_buffer != 0);
326 glBindBuffer(GL_SHADER_STORAGE_BUFFER, input_buffer);
327 glBufferData(GL_SHADER_STORAGE_BUFFER, num_points *
sizeof(
Point), pnts, GL_STATIC_READ);
328 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
329 input_buffer_size = num_points *
sizeof(
Point);
330 input_buffer_num_points =
static_cast<GLuint
>(num_points);
331 buffers_outofdate =
true;
336 std::vector<Point> input_buffer_data(num_points);
337 const uint8_t* pos_end = (uint8_t*)positions + (stride * num_points);
339 auto input_it = input_buffer_data.begin();
341 for (
int i = 0; i < num_points; ++i) {
342 input_it->position() = *positions;
343 input_it->color() = *colors;
344 input_it->level() = *lods;
348 positions = (
vec3*)((uint8_t*)positions + stride);
349 colors = (
rgb8*)((uint8_t*)colors + stride);
359 set_points(ctx, input_buffer_data.data(),input_buffer_data.size());
364 active_buffer_manager_ptr = &manager;
368 active_vertex_array = manager.get_vertex_array();
373 void clod_point_renderer::set_max_drawn_points(
cgv::render::context& ctx,
const unsigned max_points)
375 if (active_buffer_manager_ptr->
size() != max_points) {
376 active_buffer_manager_ptr->resize(max_points);
380 void clod_point_renderer::set_frustum_extend(
const float& fe)
385 void clod_point_renderer::set_pivot_point(
const vec4& pivot)
387 pivot_point_in_view_space = pivot;
390 void clod_point_renderer::set_render_style(
const render_style& rs)
395 void clod_point_renderer::manage_singelton(context& ctx,
const std::string& renderer_name,
int& ref_count,
int ref_count_change)
397 switch (ref_count_change) {
399 if (ref_count == 0) {
401 ctx.error(std::string(
"unable to initialize ") + renderer_name +
" singelton");
409 ctx.error(std::string(
"attempt to decrease reference count of ") + renderer_name +
" singelton below 0");
411 if (--ref_count == 0)
416 ctx.error(std::string(
"invalid change reference count outside {-1,0,1} for ") + renderer_name +
" singelton");
422 draw_prog_ptr = &one_shot_prog;
429 std::cout <<
"add shader " << sf <<
'\n';
443 DrawParameters* device_draw_parameters =
static_cast<DrawParameters*
>(glMapNamedBufferRange(active_draw_parameter_buffer, 0,
sizeof(DrawParameters), GL_MAP_READ_BIT));
444 unsigned ret = device_draw_parameters->count;
445 glUnmapNamedBuffer(active_draw_parameter_buffer);
449 void clod_point_renderer::clear_buffers(
context& ctx)
451 glDeleteBuffers(1, &input_buffer);
452 buffer_manager.clear(ctx);
456 void clod_point_renderer::reset_draw_parameters(context& ctx, GLuint draw_parameter_buffer)
459 DrawParameters dp = DrawParameters();
460 glNamedBufferSubData(draw_parameter_buffer, 0,
sizeof(DrawParameters), &dp);
481 GLuint clod_point_buffer_manager::get_vertex_array()
486 void clod_point_buffer_manager::init(context& ctx)
488 glCreateBuffers(1, &points);
489 glCreateBuffers(1, &indices);
490 glCreateBuffers(1, &draw_parameters);
491 glGenVertexArrays(1, &vertex_array);
494 glBindVertexArray(vertex_array);
496 glBindBuffer(GL_ARRAY_BUFFER, points);
497 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE,
sizeof(clod_point_renderer::Point), (
void*)0);
498 glEnableVertexAttribArray(0);
500 glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE,
sizeof(clod_point_renderer::Point),
501 (
void*)(
sizeof(
vec3)));
502 glEnableVertexAttribArray(1);
504 glBindBuffer(GL_ARRAY_BUFFER, indices);
505 glVertexAttribIPointer(2, 1, GL_UNSIGNED_INT, 0, (
void*)0);
506 glEnableVertexAttribArray(2);
507 glBindBuffer(GL_ARRAY_BUFFER, 0);
508 glBindVertexArray(0);
511 glBindBuffer(GL_SHADER_STORAGE_BUFFER, draw_parameters);
512 glBufferData(GL_SHADER_STORAGE_BUFFER,
sizeof(DrawParameters),
nullptr, GL_STREAM_DRAW);
513 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
516 void clod_point_buffer_manager::clear(context& ctx) {
517 glDeleteBuffers(1, &points);
518 glDeleteBuffers(1, &indices);
519 glDeleteBuffers(1, &draw_parameters);
520 glDeleteVertexArrays(1, &vertex_array);
523 void clod_point_buffer_manager::resize(GLuint num_points) {
524 if (max_num_points == num_points)
527 glBufferData(GL_SHADER_STORAGE_BUFFER, num_points *
sizeof(clod_point_renderer::Point),
nullptr, GL_DYNAMIC_DRAW);
530 glBufferData(GL_SHADER_STORAGE_BUFFER, num_points *
sizeof(GLuint),
nullptr, GL_DYNAMIC_DRAW);
531 glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
533 max_num_points = num_points;
543 return draw_parameters;
553 DrawParameters* device_draw_parameters =
static_cast<DrawParameters*
>(
554 glMapNamedBufferRange(draw_parameters, 0,
sizeof(DrawParameters), GL_MAP_READ_BIT));
555 GLuint ret = device_draw_parameters->count;
556 glUnmapNamedBuffer(draw_parameters);
562 return max_num_points;
569#include <cgv/gui/provider.h>
577 void* value_ptr,
const std::string& value_type,
578 const std::string& gui_type,
const std::string& options,
bool*) {
583 p->
add_member_control(b,
"CLOD factor", rs_ptr->CLOD,
"value_slider",
"min=0.1;max=10;ticks=true");
584 p->
add_member_control(b,
"scale", rs_ptr->scale,
"value_slider",
"min=0.1;max=10;ticks=true");
586 p->
add_member_control(b,
"point size", rs_ptr->pointSize,
"value_slider",
"min=0.1;max=10;ticks=true");
587 p->
add_member_control(b,
"min millimeters", rs_ptr->min_millimeters,
"value_slider",
"min=0.1;max=10;ticks=true");
base class for all classes that can be registered with support for dynamic properties (see also secti...
helper template for registration of gui creators
derive from this class to provide a gui to the current viewer
data::ref_ptr< control< T > > add_member_control(cgv::base::base *base_ptr, const std::string &label, T &value, const std::string &gui_type="", const std::string &options="", const std::string &align="\n")
add control with callback to cgv::base::on_set method on cgv::gui::control::value_change
the self reflection handler is passed to the virtual self_reflect() method of cgv::base::base.
bool reflect_member(const std::string &member_name, T &member_ref, bool hard_cast=false)
call this to reflect a member by member name and reference to the member.
GLuint get_reduced_points()
get the opengl id used to access the internal draw buffer
GLuint get_index_buffer()
get the opengl id used to access the index buffer
GLuint size()
max number of points stored in the managed buffers without resizing
GLuint num_reduced_points()
maps draw_parameters to memory and reads size
GLuint get_draw_parameters()
get the opengl id used to access the internal draw parameters
void set_prog(shader_program &one_shot_prog)
set a custom shader program that is used for one enable disable cycle
void reduce_buffer(context &ctx, const GLuint buffer, const GLuint point_id_buffer, size_t start, size_t count)
reduces a provided opengl buffer
void draw_points(context &ctx)
render reduced points, you need to call reduce_points first to fill the render_buffer
bool enable(context &ctx)
sets most uniforms
void set_points(cgv::render::context &ctx, const Point *pnts, const size_t num_points)
this method can be used if the data format of pnts matches with the internal format given by the Poin...
void reduce_points(context &ctx, size_t start, size_t count)
run point reduction step on the input data, you need to call enable first
void reduce_chunks(context &ctx, const uint32_t *chunk_starts, const uint32_t *chunk_point_counts, const uint32_t *reduction_sources, uint32_t num_reduction_sources)
do a point reduction over preselected segments of the input buffer
unsigned int num_reduced_points()
gives the number of points written to the reduction buffer
void draw(context &ctx, size_t start=0, size_t count=0)
reduces and renders the input by calling reduce_points and draw_points
void reduce_buffer_finish(context &ctx)
synchronizes and disables the shader prog.
void reduce_buffer_init(context &ctx, bool reset_parameters=true)
initializes reduce,
base class for all drawables, which is independent of the used rendering API.
virtual dmat4 get_modelview_matrix() const =0
return homogeneous 4x4 viewing matrix, which transforms from world to eye space
virtual bool is_created() const
return whether component has been created
std::string last_error
a string that contains the last error
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 create(const context &ctx)
create the shader program
bool is_linked() const
return whether program is linked
bool link(const context &ctx, bool show_error=false)
link shaders to an executable program
bool attach_file(const context &ctx, const std::string &file_name, ShaderType st=ST_DETECT, const shader_define_map &defines=shader_define_map())
read shader code from file, compile and attach to program
int get_uniform_location(const context &ctx, const std::string &name) const
query location index of an uniform
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.
ShaderType
different shader types
cgv::math::fvec< float, 4 > vec4
declare type of 4d single precision floating point vectors (used for homogeneous coordinates)
cgv::math::fmat< double, 4, 4 > dmat4
declare type of 4x4 matrices
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors
cgv::math::fvec< float, 3 > vec3
declare type of 3d single precision floating point vectors
cgv::math::fmat< float, 4, 4 > mat4
declare type of 4x4 matrices
bool create(provider *p, const std::string &label, void *value_ptr, const std::string &value_type, const std::string &gui_type, const std::string &options, bool *)
attempt to create a gui and return whether this was successful
interface for gui creators
this reflection traits implementation is used for external self_reflect implementations of instances ...
render style for sphere rendere
clod_point_render_style()
construct with default values
float spacing
:= root spacing, match this to your inputs point spacing in the octrees root level,...
base class for all render styles
traits class with a static function get_name() of type const char* that returns the type name of the ...