New gcode visualization library - Added methods to release gpu resources on demand.

This commit is contained in:
enricoturri1966 2024-01-09 09:05:55 +01:00 committed by Lukas Matena
parent ecd829de80
commit 4242ef20e9
12 changed files with 170 additions and 58 deletions

View File

@ -24,9 +24,24 @@ public:
Viewer& operator = (const Viewer& other) = delete; Viewer& operator = (const Viewer& other) = delete;
Viewer& operator = (Viewer&& other) = delete; Viewer& operator = (Viewer&& other) = delete;
//
// Initialize the viewer.
// This method must be called after a valid OpenGL context has been already created
// and before to call any other method of the viewer.
//
void init(); void init();
//
// Release the resources used by the viewer.
// This method must be called before releasing the OpenGL context if the viewer
// destructor is called after releasing the OpenGL context.
//
void shutdown();
void reset(); void reset();
void load(GCodeInputData&& gcode_data); void load(GCodeInputData&& gcode_data);
//
// Render the toolpaths according to the current settings,
// using the given camera matrices.
//
void render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix); void render(const Mat4x4& view_matrix, const Mat4x4& projection_matrix);
EViewType get_view_type() const; EViewType get_view_type() const;

View File

@ -14,16 +14,6 @@
namespace libvgcode { namespace libvgcode {
CogMarker::~CogMarker()
{
if (m_ibo_id != 0)
glsafe(glDeleteBuffers(1, &m_ibo_id));
if (m_vbo_id != 0)
glsafe(glDeleteBuffers(1, &m_vbo_id));
if (m_vao_id != 0)
glsafe(glDeleteVertexArrays(1, &m_vao_id));
}
// Geometry: // Geometry:
// sphere with 'resolution' sides, centered at (0.0, 0.0, 0.0) and radius equal to 'radius' // sphere with 'resolution' sides, centered at (0.0, 0.0, 0.0) and radius equal to 'radius'
void CogMarker::init(uint8_t resolution, float radius) void CogMarker::init(uint8_t resolution, float radius)
@ -122,6 +112,22 @@ void CogMarker::init(uint8_t resolution, float radius)
glsafe(glBindVertexArray(curr_vertex_array)); glsafe(glBindVertexArray(curr_vertex_array));
} }
void CogMarker::shutdown()
{
if (m_ibo_id != 0) {
glsafe(glDeleteBuffers(1, &m_ibo_id));
m_ibo_id = 0;
}
if (m_vbo_id != 0) {
glsafe(glDeleteBuffers(1, &m_vbo_id));
m_vbo_id = 0;
}
if (m_vao_id != 0) {
glsafe(glDeleteVertexArrays(1, &m_vao_id));
m_vao_id = 0;
}
}
void CogMarker::render() void CogMarker::render()
{ {
if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0 || m_indices_count == 0) if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0 || m_indices_count == 0)

View File

@ -15,16 +15,20 @@ class CogMarker
{ {
public: public:
CogMarker() = default; CogMarker() = default;
~CogMarker(); ~CogMarker() { shutdown(); }
CogMarker(const CogMarker& other) = delete; CogMarker(const CogMarker& other) = delete;
CogMarker(CogMarker&& other) = delete; CogMarker(CogMarker&& other) = delete;
CogMarker& operator = (const CogMarker& other) = delete; CogMarker& operator = (const CogMarker& other) = delete;
CogMarker& operator = (CogMarker&& other) = delete; CogMarker& operator = (CogMarker&& other) = delete;
// //
// Initialize geometry on gpu // Initialize gpu buffers.
// //
void init(uint8_t resolution, float radius); void init(uint8_t resolution, float radius);
//
// Release gpu buffers.
//
void shutdown();
void render(); void render();
// //
@ -50,6 +54,9 @@ private:
Vec3 m_total_position{ 0.0f, 0.0f, 0.0f }; Vec3 m_total_position{ 0.0f, 0.0f, 0.0f };
uint16_t m_indices_count{ 0 }; uint16_t m_indices_count{ 0 };
//
// gpu buffers ids.
//
unsigned int m_vao_id{ 0 }; unsigned int m_vao_id{ 0 };
unsigned int m_vbo_id{ 0 }; unsigned int m_vbo_id{ 0 };
unsigned int m_ibo_id{ 0 }; unsigned int m_ibo_id{ 0 };

View File

@ -12,18 +12,6 @@
namespace libvgcode { namespace libvgcode {
OptionTemplate::~OptionTemplate()
{
if (m_bottom_vbo_id != 0)
glsafe(glDeleteBuffers(1, &m_bottom_vbo_id));
if (m_bottom_vao_id != 0)
glsafe(glDeleteVertexArrays(1, &m_bottom_vao_id));
if (m_top_vbo_id != 0)
glsafe(glDeleteBuffers(1, &m_top_vbo_id));
if (m_top_vao_id != 0)
glsafe(glDeleteVertexArrays(1, &m_top_vao_id));
}
// Geometry: // Geometry:
// diamond with 'resolution' sides, centered at (0.0, 0.0, 0.0) // diamond with 'resolution' sides, centered at (0.0, 0.0, 0.0)
// height and width of the diamond are equal to 1.0 // height and width of the diamond are equal to 1.0
@ -95,6 +83,26 @@ void OptionTemplate::init(uint8_t resolution)
glsafe(glBindVertexArray(curr_vertex_array)); glsafe(glBindVertexArray(curr_vertex_array));
} }
void OptionTemplate::shutdown()
{
if (m_bottom_vbo_id != 0) {
glsafe(glDeleteBuffers(1, &m_bottom_vbo_id));
m_bottom_vbo_id = 0;
}
if (m_bottom_vao_id != 0) {
glsafe(glDeleteVertexArrays(1, &m_bottom_vao_id));
m_bottom_vao_id = 0;
}
if (m_top_vbo_id != 0) {
glsafe(glDeleteBuffers(1, &m_top_vbo_id));
m_top_vbo_id = 0;
}
if (m_top_vao_id != 0) {
glsafe(glDeleteVertexArrays(1, &m_top_vao_id));
m_top_vao_id = 0;
}
}
void OptionTemplate::render(size_t count) void OptionTemplate::render(size_t count)
{ {
if (m_top_vao_id == 0 || m_top_vbo_id == 0 || m_bottom_vao_id == 0 || m_bottom_vbo_id == 0 || count == 0) if (m_top_vao_id == 0 || m_top_vbo_id == 0 || m_bottom_vao_id == 0 || m_bottom_vbo_id == 0 || count == 0)

View File

@ -14,18 +14,28 @@ class OptionTemplate
{ {
public: public:
OptionTemplate() = default; OptionTemplate() = default;
~OptionTemplate(); ~OptionTemplate() { shutdown(); }
OptionTemplate(const OptionTemplate& other) = delete; OptionTemplate(const OptionTemplate& other) = delete;
OptionTemplate(OptionTemplate&& other) = delete; OptionTemplate(OptionTemplate&& other) = delete;
OptionTemplate& operator = (const OptionTemplate& other) = delete; OptionTemplate& operator = (const OptionTemplate& other) = delete;
OptionTemplate& operator = (OptionTemplate&& other) = delete; OptionTemplate& operator = (OptionTemplate&& other) = delete;
//
// Initialize gpu buffers.
//
void init(uint8_t resolution); void init(uint8_t resolution);
//
// Release gpu buffers.
//
void shutdown();
void render(size_t count); void render(size_t count);
private: private:
uint8_t m_resolution{ 0 }; uint8_t m_resolution{ 0 };
uint8_t m_vertices_count{ 0 }; uint8_t m_vertices_count{ 0 };
//
// gpu buffers ids.
//
unsigned int m_top_vao_id{ 0 }; unsigned int m_top_vao_id{ 0 };
unsigned int m_top_vbo_id{ 0 }; unsigned int m_top_vbo_id{ 0 };
unsigned int m_bottom_vao_id{ 0 }; unsigned int m_bottom_vao_id{ 0 };

View File

@ -26,15 +26,6 @@ static constexpr const std::array<uint8_t, 24> VERTEX_DATA = {
5, 7, 6, // back spike 5, 7, 6, // back spike
}; };
SegmentTemplate::~SegmentTemplate()
{
if (m_vbo_id != 0)
glsafe(glDeleteBuffers(1, &m_vbo_id));
if (m_vao_id != 0)
glsafe(glDeleteVertexArrays(1, &m_vao_id));
}
void SegmentTemplate::init() void SegmentTemplate::init()
{ {
if (m_vao_id != 0) if (m_vao_id != 0)
@ -58,6 +49,18 @@ void SegmentTemplate::init()
glsafe(glBindVertexArray(curr_vertex_array)); glsafe(glBindVertexArray(curr_vertex_array));
} }
void SegmentTemplate::shutdown()
{
if (m_vbo_id != 0) {
glsafe(glDeleteBuffers(1, &m_vbo_id));
m_vbo_id = 0;
}
if (m_vao_id != 0) {
glsafe(glDeleteVertexArrays(1, &m_vao_id));
m_vao_id = 0;
}
}
void SegmentTemplate::render(size_t count) void SegmentTemplate::render(size_t count)
{ {
if (m_vao_id == 0 || m_vbo_id == 0 || count == 0) if (m_vao_id == 0 || m_vbo_id == 0 || count == 0)

View File

@ -13,16 +13,26 @@ class SegmentTemplate
{ {
public: public:
SegmentTemplate() = default; SegmentTemplate() = default;
~SegmentTemplate(); ~SegmentTemplate() { shutdown(); }
SegmentTemplate(const SegmentTemplate& other) = delete; SegmentTemplate(const SegmentTemplate& other) = delete;
SegmentTemplate(SegmentTemplate&& other) = delete; SegmentTemplate(SegmentTemplate&& other) = delete;
SegmentTemplate& operator = (const SegmentTemplate& other) = delete; SegmentTemplate& operator = (const SegmentTemplate& other) = delete;
SegmentTemplate& operator = (SegmentTemplate&& other) = delete; SegmentTemplate& operator = (SegmentTemplate&& other) = delete;
//
// Initialize gpu buffers.
//
void init(); void init();
//
// Release gpu buffers.
//
void shutdown();
void render(size_t count); void render(size_t count);
private: private:
//
// gpu buffers ids.
//
unsigned int m_vao_id{ 0 }; unsigned int m_vao_id{ 0 };
unsigned int m_vbo_id{ 0 }; unsigned int m_vbo_id{ 0 };
}; };

View File

@ -12,16 +12,6 @@
namespace libvgcode { namespace libvgcode {
ToolMarker::~ToolMarker()
{
if (m_ibo_id != 0)
glsafe(glDeleteBuffers(1, &m_ibo_id));
if (m_vbo_id != 0)
glsafe(glDeleteBuffers(1, &m_vbo_id));
if (m_vao_id != 0)
glsafe(glDeleteVertexArrays(1, &m_vao_id));
}
// Geometry: // Geometry:
// Arrow with cylindrical stem and conical tip, with the given dimensions and resolution // Arrow with cylindrical stem and conical tip, with the given dimensions and resolution
// The origin of the arrow is at the tip of the conical section // The origin of the arrow is at the tip of the conical section
@ -142,6 +132,22 @@ void ToolMarker::init(uint16_t resolution, float tip_radius, float tip_height, f
glsafe(glBindVertexArray(curr_vertex_array)); glsafe(glBindVertexArray(curr_vertex_array));
} }
void ToolMarker::shutdown()
{
if (m_ibo_id != 0) {
glsafe(glDeleteBuffers(1, &m_ibo_id));
m_ibo_id = 0;
}
if (m_vbo_id != 0) {
glsafe(glDeleteBuffers(1, &m_vbo_id));
m_vbo_id = 0;
}
if (m_vao_id != 0) {
glsafe(glDeleteVertexArrays(1, &m_vao_id));
m_vao_id = 0;
}
}
void ToolMarker::render() void ToolMarker::render()
{ {
if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0) if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0)

View File

@ -16,13 +16,20 @@ class ToolMarker
{ {
public: public:
ToolMarker() = default; ToolMarker() = default;
~ToolMarker(); ~ToolMarker() { shutdown(); }
ToolMarker(const ToolMarker& other) = delete; ToolMarker(const ToolMarker& other) = delete;
ToolMarker(ToolMarker&& other) = delete; ToolMarker(ToolMarker&& other) = delete;
ToolMarker& operator = (const ToolMarker& other) = delete; ToolMarker& operator = (const ToolMarker& other) = delete;
ToolMarker& operator = (ToolMarker&& other) = delete; ToolMarker& operator = (ToolMarker&& other) = delete;
//
// Initialize gpu buffers.
//
void init(uint16_t resolution, float tip_radius, float tip_height, float stem_radius, float stem_height); void init(uint16_t resolution, float tip_radius, float tip_height, float stem_radius, float stem_height);
//
// Release gpu buffers.
//
void shutdown();
void render(); void render();
bool is_enabled() const { return m_enabled; } bool is_enabled() const { return m_enabled; }
@ -48,6 +55,9 @@ private:
float m_alpha{ 0.5f }; float m_alpha{ 0.5f };
uint16_t m_indices_count{ 0 }; uint16_t m_indices_count{ 0 };
//
// gpu buffers ids.
//
unsigned int m_vao_id{ 0 }; unsigned int m_vao_id{ 0 };
unsigned int m_vbo_id{ 0 }; unsigned int m_vbo_id{ 0 };
unsigned int m_ibo_id{ 0 }; unsigned int m_ibo_id{ 0 };

View File

@ -22,6 +22,11 @@ void Viewer::init()
m_impl->init(); m_impl->init();
} }
void Viewer::shutdown()
{
m_impl->shutdown();
}
void Viewer::reset() void Viewer::reset()
{ {
m_impl->reset(); m_impl->reset();

View File

@ -316,15 +316,6 @@ const std::map<EOptionType, Color> ViewerImpl::DEFAULT_OPTIONS_COLORS{ {
{ EOptionType::CustomGCodes, { 226, 210, 67 } } { EOptionType::CustomGCodes, { 226, 210, 67 } }
} }; } };
ViewerImpl::~ViewerImpl()
{
reset();
if (m_options_shader_id != 0)
glsafe(glDeleteProgram(m_options_shader_id));
if (m_segments_shader_id != 0)
glsafe(glDeleteProgram(m_segments_shader_id));
}
void ViewerImpl::init() void ViewerImpl::init()
{ {
if (m_initialized) if (m_initialized)
@ -414,6 +405,26 @@ void ViewerImpl::init()
m_initialized = true; m_initialized = true;
} }
void ViewerImpl::shutdown()
{
reset();
#if ENABLE_COG_AND_TOOL_MARKERS
m_tool_marker.shutdown();
m_cog_marker.shutdown();
#endif // ENABLE_COG_AND_TOOL_MARKERS
m_option_template.shutdown();
m_segment_template.shutdown();
if (m_options_shader_id != 0) {
glsafe(glDeleteProgram(m_options_shader_id));
m_options_shader_id = 0;
}
if (m_segments_shader_id != 0) {
glsafe(glDeleteProgram(m_segments_shader_id));
m_segments_shader_id = 0;
}
m_initialized = false;
}
void ViewerImpl::reset() void ViewerImpl::reset()
{ {
m_layers.reset(); m_layers.reset();
@ -593,6 +604,9 @@ void ViewerImpl::load(GCodeInputData&& gcode_data)
void ViewerImpl::update_enabled_entities() void ViewerImpl::update_enabled_entities()
{ {
if (m_vertices.empty())
return;
std::vector<uint32_t> enabled_segments; std::vector<uint32_t> enabled_segments;
std::vector<uint32_t> enabled_options; std::vector<uint32_t> enabled_options;
Interval range = m_view_range.get_visible(); Interval range = m_view_range.get_visible();
@ -687,6 +701,20 @@ static float encode_color(const Color& color) {
void ViewerImpl::update_colors() void ViewerImpl::update_colors()
{ {
if (m_colors_buf_id == 0)
return;
if (!m_used_extruders_ids.empty()) {
// ensure that the number of defined tool colors matches the max id of the used extruders
const size_t max_used_extruder_id = 1 + static_cast<size_t>(m_used_extruders_ids.back());
const size_t tool_colors_size = m_tool_colors.size();
if (m_tool_colors.size() < max_used_extruder_id) {
for (size_t i = 0; i < max_used_extruder_id - tool_colors_size; ++i) {
m_tool_colors.emplace_back(DUMMY_COLOR);
}
}
}
update_color_ranges(); update_color_ranges();
const size_t top_layer_id = m_settings.top_layer_only_view_range ? m_layers.get_view_range()[1] : 0; const size_t top_layer_id = m_settings.top_layer_only_view_range ? m_layers.get_view_range()[1] : 0;

View File

@ -27,19 +27,23 @@ class ViewerImpl
{ {
public: public:
ViewerImpl() = default; ViewerImpl() = default;
~ViewerImpl(); ~ViewerImpl() { shutdown(); }
ViewerImpl(const ViewerImpl& other) = delete; ViewerImpl(const ViewerImpl& other) = delete;
ViewerImpl(ViewerImpl&& other) = delete; ViewerImpl(ViewerImpl&& other) = delete;
ViewerImpl& operator = (const ViewerImpl& other) = delete; ViewerImpl& operator = (const ViewerImpl& other) = delete;
ViewerImpl& operator = (ViewerImpl&& other) = delete; ViewerImpl& operator = (ViewerImpl&& other) = delete;
// //
// Initialize shaders, uniform indices and segment geometry // Initialize shaders, uniform indices and segment geometry.
// //
void init(); void init();
//
// Release the resources used by the viewer.
//
void shutdown();
// //
// Reset all caches and free gpu memory // Reset all caches and free gpu memory.
// //
void reset(); void reset();