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 = (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();
//
// 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 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);
EViewType get_view_type() const;

View File

@ -14,16 +14,6 @@
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:
// 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)
@ -122,6 +112,22 @@ void CogMarker::init(uint8_t resolution, float radius)
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()
{
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:
CogMarker() = default;
~CogMarker();
~CogMarker() { shutdown(); }
CogMarker(const CogMarker& other) = delete;
CogMarker(CogMarker&& other) = delete;
CogMarker& operator = (const CogMarker& other) = delete;
CogMarker& operator = (CogMarker&& other) = delete;
//
// Initialize geometry on gpu
// Initialize gpu buffers.
//
void init(uint8_t resolution, float radius);
//
// Release gpu buffers.
//
void shutdown();
void render();
//
@ -50,6 +54,9 @@ private:
Vec3 m_total_position{ 0.0f, 0.0f, 0.0f };
uint16_t m_indices_count{ 0 };
//
// gpu buffers ids.
//
unsigned int m_vao_id{ 0 };
unsigned int m_vbo_id{ 0 };
unsigned int m_ibo_id{ 0 };

View File

@ -12,18 +12,6 @@
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:
// diamond with 'resolution' sides, centered at (0.0, 0.0, 0.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));
}
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)
{
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:
OptionTemplate() = default;
~OptionTemplate();
~OptionTemplate() { shutdown(); }
OptionTemplate(const OptionTemplate& other) = delete;
OptionTemplate(OptionTemplate&& other) = delete;
OptionTemplate& operator = (const OptionTemplate& other) = delete;
OptionTemplate& operator = (OptionTemplate&& other) = delete;
//
// Initialize gpu buffers.
//
void init(uint8_t resolution);
//
// Release gpu buffers.
//
void shutdown();
void render(size_t count);
private:
uint8_t m_resolution{ 0 };
uint8_t m_vertices_count{ 0 };
//
// gpu buffers ids.
//
unsigned int m_top_vao_id{ 0 };
unsigned int m_top_vbo_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
};
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()
{
if (m_vao_id != 0)
@ -58,6 +49,18 @@ void SegmentTemplate::init()
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)
{
if (m_vao_id == 0 || m_vbo_id == 0 || count == 0)

View File

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

View File

@ -12,16 +12,6 @@
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:
// 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
@ -142,6 +132,22 @@ void ToolMarker::init(uint16_t resolution, float tip_radius, float tip_height, f
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()
{
if (m_vao_id == 0 || m_vbo_id == 0 || m_ibo_id == 0)

View File

@ -16,13 +16,20 @@ class ToolMarker
{
public:
ToolMarker() = default;
~ToolMarker();
~ToolMarker() { shutdown(); }
ToolMarker(const ToolMarker& other) = delete;
ToolMarker(ToolMarker&& other) = delete;
ToolMarker& operator = (const 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);
//
// Release gpu buffers.
//
void shutdown();
void render();
bool is_enabled() const { return m_enabled; }
@ -48,6 +55,9 @@ private:
float m_alpha{ 0.5f };
uint16_t m_indices_count{ 0 };
//
// gpu buffers ids.
//
unsigned int m_vao_id{ 0 };
unsigned int m_vbo_id{ 0 };
unsigned int m_ibo_id{ 0 };

View File

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

View File

@ -316,15 +316,6 @@ const std::map<EOptionType, Color> ViewerImpl::DEFAULT_OPTIONS_COLORS{ {
{ 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()
{
if (m_initialized)
@ -414,6 +405,26 @@ void ViewerImpl::init()
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()
{
m_layers.reset();
@ -593,6 +604,9 @@ void ViewerImpl::load(GCodeInputData&& gcode_data)
void ViewerImpl::update_enabled_entities()
{
if (m_vertices.empty())
return;
std::vector<uint32_t> enabled_segments;
std::vector<uint32_t> enabled_options;
Interval range = m_view_range.get_visible();
@ -687,6 +701,20 @@ static float encode_color(const Color& color) {
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();
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:
ViewerImpl() = default;
~ViewerImpl();
~ViewerImpl() { shutdown(); }
ViewerImpl(const ViewerImpl& other) = delete;
ViewerImpl(ViewerImpl&& other) = delete;
ViewerImpl& operator = (const ViewerImpl& other) = delete;
ViewerImpl& operator = (ViewerImpl&& other) = delete;
//
// Initialize shaders, uniform indices and segment geometry
// Initialize shaders, uniform indices and segment geometry.
//
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();