diff options
author | bubnikv <bubnikv@gmail.com> | 2018-02-15 16:37:53 +0300 |
---|---|---|
committer | bubnikv <bubnikv@gmail.com> | 2018-02-15 16:37:53 +0300 |
commit | f9cdda7bfd14c6eb972b6c89079d983f4c742964 (patch) | |
tree | 67a3c9827a82c4164543cc8c93b39f2ad161b104 /xs | |
parent | b5bdb4626864277eaa7e68e0b98ea03ee73694b9 (diff) |
Delayed loading of the opengl texture for the G-code preview legend,
as the opengl context may not be ready on some platforms (Linux)
at the time the window gets its focus for the first time.
Changed the G-code preview invalidation to trigger when the print
gets invalidated. At that time the 3D path preview switches to the old
preview, if there is anything valid left.
Diffstat (limited to 'xs')
-rw-r--r-- | xs/src/libslic3r/GCode.cpp | 2 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/3DScene.cpp | 110 | ||||
-rw-r--r-- | xs/src/slic3r/GUI/3DScene.hpp | 20 | ||||
-rw-r--r-- | xs/xsp/GUI_3DScene.xsp | 7 |
4 files changed, 65 insertions, 74 deletions
diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 39f1a4102..538f9fefa 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -776,7 +776,7 @@ void GCode::_do_export(Print &print, FILE *file, GCodePreviewData *preview_data) _writeln(file, this->placeholder_parser_process("end_filament_gcode", print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id())); } else { for (const std::string &end_gcode : print.config.end_filament_gcode.values) - _writeln(file, this->placeholder_parser_process("end_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()))); + _writeln(file, this->placeholder_parser_process("end_filament_gcode", end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front()))); } _writeln(file, this->placeholder_parser_process("end_gcode", print.config.end_gcode, m_writer.extruder()->id())); _write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100% diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 616d43496..3deadd105 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1117,21 +1117,12 @@ const unsigned char _3DScene::LegendTexture::Squares_Border_Color[3] = { 64, 64, const unsigned char _3DScene::LegendTexture::Background_Color[3] = { 9, 91, 134 }; const unsigned char _3DScene::LegendTexture::Opacity = 255; -_3DScene::LegendTexture::LegendTexture() - : m_tex_id(0) - , m_tex_width(0) - , m_tex_height(0) +// Generate a texture data, but don't load it into the GPU yet, as the GPU context may not yet be valid. +bool _3DScene::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors) { -} - -_3DScene::LegendTexture::~LegendTexture() -{ - _destroy_texture(); -} - -bool _3DScene::LegendTexture::generate_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors) -{ - _destroy_texture(); + // Mark the texture as released, but don't release the texture from the GPU yet. + m_tex_width = m_tex_height = 0; + m_data.clear(); // collects items to render const std::string& title = preview_data.get_legend_title(); @@ -1241,64 +1232,45 @@ bool _3DScene::LegendTexture::generate_texture(const GCodePreviewData& preview_d memDC.SelectObject(wxNullBitmap); - return _create_texture(preview_data, bitmap); -} - -unsigned int _3DScene::LegendTexture::get_texture_id() const -{ - return m_tex_id; -} - -unsigned int _3DScene::LegendTexture::get_texture_width() const -{ - return m_tex_width; -} - -unsigned int _3DScene::LegendTexture::get_texture_height() const -{ - return m_tex_height; -} - -void _3DScene::LegendTexture::reset_texture() -{ - _destroy_texture(); -} - -bool _3DScene::LegendTexture::_create_texture(const GCodePreviewData& preview_data, const wxBitmap& bitmap) -{ - if ((m_tex_width == 0) || (m_tex_height == 0)) - return false; - - wxImage image = bitmap.ConvertToImage(); - image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); - - // prepare buffer - std::vector<unsigned char> buffer(4 * m_tex_width * m_tex_height, 0); - for (unsigned int h = 0; h < m_tex_height; ++h) + // Convert the bitmap into a linear data ready to be loaded into the GPU. { - unsigned int hh = h * m_tex_width; - for (unsigned int w = 0; w < m_tex_width; ++w) + wxImage image = bitmap.ConvertToImage(); + image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); + + // prepare buffer + m_data.assign(4 * m_tex_width * m_tex_height, 0); + for (unsigned int h = 0; h < m_tex_height; ++h) { - unsigned char* px_ptr = buffer.data() + 4 * (hh + w); - *px_ptr++ = image.GetRed(w, h); - *px_ptr++ = image.GetGreen(w, h); - *px_ptr++ = image.GetBlue(w, h); - *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; + unsigned int hh = h * m_tex_width; + unsigned char* px_ptr = m_data.data() + 4 * hh; + for (unsigned int w = 0; w < m_tex_width; ++w) + { + *px_ptr++ = image.GetRed(w, h); + *px_ptr++ = image.GetGreen(w, h); + *px_ptr++ = image.GetBlue(w, h); + *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; + } } } - - // sends buffer to gpu - ::glGenTextures(1, &m_tex_id); - ::glBindTexture(GL_TEXTURE_2D, m_tex_id); - ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_tex_width, (GLsizei)m_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)buffer.data()); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - ::glBindTexture(GL_TEXTURE_2D, 0); - return true; } +unsigned int _3DScene::LegendTexture::finalize() +{ + if (! m_data.empty()) { + // sends buffer to gpu + ::glGenTextures(1, &m_tex_id); + ::glBindTexture(GL_TEXTURE_2D, m_tex_id); + ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)m_tex_width, (GLsizei)m_tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid*)m_data.data()); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + ::glBindTexture(GL_TEXTURE_2D, 0); + m_data.clear(); + } + return (m_tex_width > 0 && m_tex_height > 0) ? m_tex_id : 0; +} + void _3DScene::LegendTexture::_destroy_texture() { if (m_tex_id > 0) @@ -1308,6 +1280,7 @@ void _3DScene::LegendTexture::_destroy_texture() m_tex_height = 0; m_tex_width = 0; } + m_data.clear(); } void _3DScene::_glew_init() @@ -2267,7 +2240,12 @@ void _3DScene::_update_gcode_volumes_visibility(const GCodePreviewData& preview_ void _3DScene::_generate_legend_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors) { - s_legend_texture.generate_texture(preview_data, tool_colors); + s_legend_texture.generate(preview_data, tool_colors); +} + +unsigned int _3DScene::finalize_legend_texture() +{ + return s_legend_texture.finalize(); } void _3DScene::_load_shells(const Print& print, GLVolumeCollection& volumes, bool use_VBOs) diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index bf3515ac5..9cbcb6ebc 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -421,20 +421,25 @@ class _3DScene unsigned int m_tex_height; public: - LegendTexture(); - ~LegendTexture(); + LegendTexture() : m_tex_id(0), m_tex_width(0), m_tex_height(0) {} + ~LegendTexture() { _destroy_texture(); } - bool generate_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors); + // Generate a texture data, but don't load it into the GPU yet, as the glcontext may not be valid yet. + bool generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors); + // If not loaded, load the texture data into the GPU. Return a texture ID or 0 if the texture has zero size. + unsigned int finalize(); - unsigned int get_texture_id() const; - unsigned int get_texture_width() const; - unsigned int get_texture_height() const; + unsigned int get_texture_id() const { return m_tex_id; } + unsigned int get_texture_width() const { return m_tex_width; } + unsigned int get_texture_height() const { return m_tex_height; } - void reset_texture(); + void reset_texture() { _destroy_texture(); } private: bool _create_texture(const GCodePreviewData& preview_data, const wxBitmap& bitmap); void _destroy_texture(); + // generate() fills in m_data with the pixels, while finalize() moves the data to the GPU before rendering. + std::vector<unsigned char> m_data; }; static LegendTexture s_legend_texture; @@ -449,6 +454,7 @@ public: static unsigned int get_legend_texture_height(); static void reset_legend_texture(); + static unsigned int finalize_legend_texture(); static void _load_print_toolpaths( const Print *print, diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index c06c659b1..961c837d9 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -142,6 +142,13 @@ _glew_init() _3DScene::_glew_init(); unsigned int +finalize_legend_texture() + CODE: + RETVAL = _3DScene::finalize_legend_texture(); + OUTPUT: + RETVAL + +unsigned int get_legend_texture_id() CODE: RETVAL = _3DScene::get_legend_texture_id(); |