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.
This commit is contained in:
parent
b5bdb46268
commit
f9cdda7bfd
@ -1602,7 +1602,8 @@ sub draw_legend {
|
|||||||
|
|
||||||
if ($self->_legend_enabled)
|
if ($self->_legend_enabled)
|
||||||
{
|
{
|
||||||
my $tex_id = Slic3r::GUI::_3DScene::get_legend_texture_id;
|
# If the legend texture has not been loaded into the GPU, do it now.
|
||||||
|
my $tex_id = Slic3r::GUI::_3DScene::finalize_legend_texture;
|
||||||
if ($tex_id > 0)
|
if ($tex_id > 0)
|
||||||
{
|
{
|
||||||
my $tex_w = Slic3r::GUI::_3DScene::get_legend_texture_width;
|
my $tex_w = Slic3r::GUI::_3DScene::get_legend_texture_width;
|
||||||
|
@ -786,7 +786,6 @@ sub remove {
|
|||||||
splice @{$self->{objects}}, $obj_idx, 1;
|
splice @{$self->{objects}}, $obj_idx, 1;
|
||||||
$self->{model}->delete_object($obj_idx);
|
$self->{model}->delete_object($obj_idx);
|
||||||
$self->{print}->delete_object($obj_idx);
|
$self->{print}->delete_object($obj_idx);
|
||||||
$self->{gcode_preview_data}->reset;
|
|
||||||
$self->{list}->DeleteItem($obj_idx);
|
$self->{list}->DeleteItem($obj_idx);
|
||||||
$self->object_list_changed;
|
$self->object_list_changed;
|
||||||
|
|
||||||
@ -807,7 +806,6 @@ sub reset {
|
|||||||
@{$self->{objects}} = ();
|
@{$self->{objects}} = ();
|
||||||
$self->{model}->clear_objects;
|
$self->{model}->clear_objects;
|
||||||
$self->{print}->clear_objects;
|
$self->{print}->clear_objects;
|
||||||
$self->{gcode_preview_data}->reset;
|
|
||||||
$self->{list}->DeleteAllItems;
|
$self->{list}->DeleteAllItems;
|
||||||
$self->object_list_changed;
|
$self->object_list_changed;
|
||||||
|
|
||||||
@ -1161,6 +1159,7 @@ sub async_apply_config {
|
|||||||
# Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared.
|
# Reset preview canvases. If the print has been invalidated, the preview canvases will be cleared.
|
||||||
# Otherwise they will be just refreshed.
|
# Otherwise they will be just refreshed.
|
||||||
if ($invalidated) {
|
if ($invalidated) {
|
||||||
|
$self->{gcode_preview_data}->reset;
|
||||||
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
|
$self->{toolpaths2D}->reload_print if $self->{toolpaths2D};
|
||||||
$self->{preview3D}->reload_print if $self->{preview3D};
|
$self->{preview3D}->reload_print if $self->{preview3D};
|
||||||
}
|
}
|
||||||
@ -1267,8 +1266,6 @@ sub reslice {
|
|||||||
$self->stop_background_process;
|
$self->stop_background_process;
|
||||||
# Rather perform one additional unnecessary update of the print object instead of skipping a pending async update.
|
# Rather perform one additional unnecessary update of the print object instead of skipping a pending async update.
|
||||||
$self->async_apply_config;
|
$self->async_apply_config;
|
||||||
# Reset gcode data
|
|
||||||
$self->{gcode_preview_data}->reset;
|
|
||||||
$self->statusbar->SetCancelCallback(sub {
|
$self->statusbar->SetCancelCallback(sub {
|
||||||
$self->stop_background_process;
|
$self->stop_background_process;
|
||||||
$self->statusbar->SetStatusText("Slicing cancelled");
|
$self->statusbar->SetStatusText("Slicing cancelled");
|
||||||
|
@ -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()));
|
_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 {
|
} else {
|
||||||
for (const std::string &end_gcode : print.config.end_filament_gcode.values)
|
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()));
|
_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%
|
_write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
|
||||||
|
@ -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::Background_Color[3] = { 9, 91, 134 };
|
||||||
const unsigned char _3DScene::LegendTexture::Opacity = 255;
|
const unsigned char _3DScene::LegendTexture::Opacity = 255;
|
||||||
|
|
||||||
_3DScene::LegendTexture::LegendTexture()
|
// Generate a texture data, but don't load it into the GPU yet, as the GPU context may not yet be valid.
|
||||||
: m_tex_id(0)
|
bool _3DScene::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
|
||||||
, m_tex_width(0)
|
|
||||||
, m_tex_height(0)
|
|
||||||
{
|
{
|
||||||
}
|
// Mark the texture as released, but don't release the texture from the GPU yet.
|
||||||
|
m_tex_width = m_tex_height = 0;
|
||||||
_3DScene::LegendTexture::~LegendTexture()
|
m_data.clear();
|
||||||
{
|
|
||||||
_destroy_texture();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _3DScene::LegendTexture::generate_texture(const GCodePreviewData& preview_data, const std::vector<float>& tool_colors)
|
|
||||||
{
|
|
||||||
_destroy_texture();
|
|
||||||
|
|
||||||
// collects items to render
|
// collects items to render
|
||||||
const std::string& title = preview_data.get_legend_title();
|
const std::string& title = preview_data.get_legend_title();
|
||||||
@ -1241,62 +1232,43 @@ bool _3DScene::LegendTexture::generate_texture(const GCodePreviewData& preview_d
|
|||||||
|
|
||||||
memDC.SelectObject(wxNullBitmap);
|
memDC.SelectObject(wxNullBitmap);
|
||||||
|
|
||||||
return _create_texture(preview_data, bitmap);
|
// Convert the bitmap into a linear data ready to be loaded into the GPU.
|
||||||
}
|
{
|
||||||
|
|
||||||
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();
|
wxImage image = bitmap.ConvertToImage();
|
||||||
image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]);
|
image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]);
|
||||||
|
|
||||||
// prepare buffer
|
// prepare buffer
|
||||||
std::vector<unsigned char> buffer(4 * m_tex_width * m_tex_height, 0);
|
m_data.assign(4 * m_tex_width * m_tex_height, 0);
|
||||||
for (unsigned int h = 0; h < m_tex_height; ++h)
|
for (unsigned int h = 0; h < m_tex_height; ++h)
|
||||||
{
|
{
|
||||||
unsigned int hh = h * m_tex_width;
|
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)
|
for (unsigned int w = 0; w < m_tex_width; ++w)
|
||||||
{
|
{
|
||||||
unsigned char* px_ptr = buffer.data() + 4 * (hh + w);
|
|
||||||
*px_ptr++ = image.GetRed(w, h);
|
*px_ptr++ = image.GetRed(w, h);
|
||||||
*px_ptr++ = image.GetGreen(w, h);
|
*px_ptr++ = image.GetGreen(w, h);
|
||||||
*px_ptr++ = image.GetBlue(w, h);
|
*px_ptr++ = image.GetBlue(w, h);
|
||||||
*px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity;
|
*px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int _3DScene::LegendTexture::finalize()
|
||||||
|
{
|
||||||
|
if (! m_data.empty()) {
|
||||||
// sends buffer to gpu
|
// sends buffer to gpu
|
||||||
::glGenTextures(1, &m_tex_id);
|
::glGenTextures(1, &m_tex_id);
|
||||||
::glBindTexture(GL_TEXTURE_2D, 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());
|
::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_MAG_FILTER, GL_LINEAR);
|
||||||
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||||
::glBindTexture(GL_TEXTURE_2D, 0);
|
::glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
m_data.clear();
|
||||||
return true;
|
}
|
||||||
|
return (m_tex_width > 0 && m_tex_height > 0) ? m_tex_id : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _3DScene::LegendTexture::_destroy_texture()
|
void _3DScene::LegendTexture::_destroy_texture()
|
||||||
@ -1308,6 +1280,7 @@ void _3DScene::LegendTexture::_destroy_texture()
|
|||||||
m_tex_height = 0;
|
m_tex_height = 0;
|
||||||
m_tex_width = 0;
|
m_tex_width = 0;
|
||||||
}
|
}
|
||||||
|
m_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _3DScene::_glew_init()
|
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)
|
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)
|
void _3DScene::_load_shells(const Print& print, GLVolumeCollection& volumes, bool use_VBOs)
|
||||||
|
@ -421,20 +421,25 @@ class _3DScene
|
|||||||
unsigned int m_tex_height;
|
unsigned int m_tex_height;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LegendTexture();
|
LegendTexture() : m_tex_id(0), m_tex_width(0), m_tex_height(0) {}
|
||||||
~LegendTexture();
|
~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_id() const { return m_tex_id; }
|
||||||
unsigned int get_texture_width() const;
|
unsigned int get_texture_width() const { return m_tex_width; }
|
||||||
unsigned int get_texture_height() const;
|
unsigned int get_texture_height() const { return m_tex_height; }
|
||||||
|
|
||||||
void reset_texture();
|
void reset_texture() { _destroy_texture(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _create_texture(const GCodePreviewData& preview_data, const wxBitmap& bitmap);
|
bool _create_texture(const GCodePreviewData& preview_data, const wxBitmap& bitmap);
|
||||||
void _destroy_texture();
|
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;
|
static LegendTexture s_legend_texture;
|
||||||
@ -449,6 +454,7 @@ public:
|
|||||||
static unsigned int get_legend_texture_height();
|
static unsigned int get_legend_texture_height();
|
||||||
|
|
||||||
static void reset_legend_texture();
|
static void reset_legend_texture();
|
||||||
|
static unsigned int finalize_legend_texture();
|
||||||
|
|
||||||
static void _load_print_toolpaths(
|
static void _load_print_toolpaths(
|
||||||
const Print *print,
|
const Print *print,
|
||||||
|
@ -141,6 +141,13 @@ _glew_init()
|
|||||||
CODE:
|
CODE:
|
||||||
_3DScene::_glew_init();
|
_3DScene::_glew_init();
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
finalize_legend_texture()
|
||||||
|
CODE:
|
||||||
|
RETVAL = _3DScene::finalize_legend_texture();
|
||||||
|
OUTPUT:
|
||||||
|
RETVAL
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
get_legend_texture_id()
|
get_legend_texture_id()
|
||||||
CODE:
|
CODE:
|
||||||
|
Loading…
Reference in New Issue
Block a user