// License: Apache 2.0. See LICENSE file in root directory. // Copyright(c) 2023 Intel Corporation. All Rights Reserved. #pragma once #include <librealsense2/rs.hpp> #include <librealsense2-gl/rs_processing_gl.hpp> #include <string> #include <map> #include <thread> #include "opengl3.h" #include <GLFW/glfw3.h> namespace rs2 { class viewer_model; class processing_block_model; class subdevice_model; class post_processing_filters { public: post_processing_filters(viewer_model& viewer) : processing_block([&](rs2::frame f, const rs2::frame_source& source) { process(std::move(f), source); }), viewer(viewer), depth_stream_active(false), resulting_queue_max_size(20), resulting_queue(static_cast<unsigned int>(resulting_queue_max_size)), render_thread(), render_thread_active(false), pc(new gl::pointcloud()), uploader(new gl::uploader()), disp_to_depth(false) { std::string s; pc_gen = std::make_shared<processing_block_model>(nullptr, "Pointcloud Engine", pc, [=](rs2::frame f) { return pc->calculate(f); }, s); processing_block.start(resulting_queue); } ~post_processing_filters() { stop(); } void update_texture(frame f) { pc->map_to(f); } /* Start the rendering thread in case its disabled */ void start(); /* Stop the rendering thread in case its enabled */ void stop(); bool is_rendering() const { return render_thread_active.load(); } rs2::frameset get_points() { frame f; if (resulting_queue.poll_for_frame(&f)) { rs2::frameset frameset(f); model = frameset; } return model; } void reset(void) { rs2::frame f{}; model = f; while (resulting_queue.poll_for_frame(&f)); } std::atomic<bool> depth_stream_active; const size_t resulting_queue_max_size; std::map<int, rs2::frame_queue> frames_queue; rs2::frame_queue resulting_queue; std::shared_ptr<pointcloud> get_pc() const { return pc; } std::shared_ptr<processing_block_model> get_pc_model() const { return pc_gen; } private: viewer_model& viewer; void process(rs2::frame f, const rs2::frame_source& source); std::vector<rs2::frame> handle_frame(rs2::frame f, const rs2::frame_source& source); void map_id(rs2::frame new_frame, rs2::frame old_frame); void map_id_frameset_to_frame(rs2::frameset first, rs2::frame second); void map_id_frameset_to_frameset(rs2::frameset first, rs2::frameset second); void map_id_frame_to_frame(rs2::frame first, rs2::frame second); rs2::frame apply_filters(rs2::frame f, const rs2::frame_source& source); std::shared_ptr<subdevice_model> get_frame_origin(const rs2::frame& f); void zero_first_pixel(const rs2::frame& f); rs2::frame last_tex_frame; rs2::processing_block processing_block; std::shared_ptr<pointcloud> pc; rs2::frameset model; std::shared_ptr<processing_block_model> pc_gen; rs2::disparity_transform disp_to_depth; /* Post processing filter rendering */ std::atomic<bool> render_thread_active; // True when render post processing filter rendering thread is active, False otherwise std::shared_ptr<std::thread> render_thread; // Post processing filter rendering Thread running render_loop() void render_loop(); // Post processing filter rendering function std::shared_ptr<gl::uploader> uploader; // GL element that helps pre-emptively copy frames to the GPU }; }