Out of bed detection - Volumes' layer texture rendering moved to cpp

This commit is contained in:
Enrico Turri 2018-03-09 14:33:44 +01:00
parent bdd2d725c8
commit 7a2df9f54f
4 changed files with 145 additions and 57 deletions

View File

@ -1309,6 +1309,7 @@ sub Render {
$self->draw_volumes; $self->draw_volumes;
} elsif ($self->UseVBOs) { } elsif ($self->UseVBOs) {
if ($self->enable_picking) { if ($self->enable_picking) {
$self->mark_volumes_for_layer_height;
$self->volumes->set_print_box($self->bed_bounding_box->x_min, $self->bed_bounding_box->y_min, 0.0, $self->bed_bounding_box->x_max, $self->bed_bounding_box->y_max, $self->{config}->get('max_print_height')); $self->volumes->set_print_box($self->bed_bounding_box->x_min, $self->bed_bounding_box->y_min, 0.0, $self->bed_bounding_box->x_max, $self->bed_bounding_box->y_max, $self->{config}->get('max_print_height'));
} }
$self->{plain_shader}->enable if $self->{plain_shader}; $self->{plain_shader}->enable if $self->{plain_shader};
@ -1358,36 +1359,10 @@ sub draw_volumes {
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
my $z_cursor_relative = $self->_variable_layer_thickness_bar_mouse_cursor_z_relative;
foreach my $volume_idx (0..$#{$self->volumes}) { foreach my $volume_idx (0..$#{$self->volumes}) {
my $volume = $self->volumes->[$volume_idx]; my $volume = $self->volumes->[$volume_idx];
my $shader_active = 0; if ($fakecolor) {
my $object_id = int($volume->select_group_id / 1000000);
if ($self->layer_editing_enabled && ! $fakecolor && $volume->selected && $self->{layer_height_edit_shader} &&
$volume->has_layer_height_texture && $object_id < $self->{print}->object_count) {
# Update the height texture if the ModelObject::layer_height_texture is invalid.
$volume->generate_layer_height_texture($self->{print}->get_object($object_id), 0);
$self->{layer_height_edit_shader}->enable;
$self->{layer_height_edit_shader}->set_uniform('z_to_texture_row', $volume->layer_height_texture_z_to_row_id);
$self->{layer_height_edit_shader}->set_uniform('z_texture_row_to_normalized', 1. / $volume->layer_height_texture_height);
$self->{layer_height_edit_shader}->set_uniform('z_cursor', $volume->bounding_box->z_max * $z_cursor_relative);
$self->{layer_height_edit_shader}->set_uniform('z_cursor_band_width', $self->{layer_height_edit_band_width});
glBindTexture(GL_TEXTURE_2D, $self->{layer_preview_z_texture_id});
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LEVEL, 0);
# glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
glTexImage2D_c(GL_TEXTURE_2D, 0, GL_RGBA8, $volume->layer_height_texture_width, $volume->layer_height_texture_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D_c(GL_TEXTURE_2D, 1, GL_RGBA8, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2,
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
# glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
# glPixelStorei(GL_UNPACK_ROW_LENGTH, $self->{layer_preview_z_texture_width});
glTexSubImage2D_c(GL_TEXTURE_2D, 0, 0, 0, $volume->layer_height_texture_width, $volume->layer_height_texture_height,
GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level0);
glTexSubImage2D_c(GL_TEXTURE_2D, 1, 0, 0, $volume->layer_height_texture_width / 2, $volume->layer_height_texture_height / 2,
GL_RGBA, GL_UNSIGNED_BYTE, $volume->layer_height_texture_data_ptr_level1);
$shader_active = 1;
} elsif ($fakecolor) {
# Object picking mode. Render the object with a color encoding the object index. # Object picking mode. Render the object with a color encoding the object index.
my $r = ($volume_idx & 0x000000FF) >> 0; my $r = ($volume_idx & 0x000000FF) >> 0;
my $g = ($volume_idx & 0x0000FF00) >> 8; my $g = ($volume_idx & 0x0000FF00) >> 8;
@ -1402,11 +1377,6 @@ sub draw_volumes {
} }
$volume->render; $volume->render;
if ($shader_active) {
glBindTexture(GL_TEXTURE_2D, 0);
$self->{layer_height_edit_shader}->disable;
}
} }
glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_NORMAL_ARRAY);
glDisable(GL_BLEND); glDisable(GL_BLEND);
@ -1421,6 +1391,22 @@ sub draw_volumes {
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);
} }
sub mark_volumes_for_layer_height {
my ($self) = @_;
foreach my $volume_idx (0..$#{$self->volumes}) {
my $volume = $self->volumes->[$volume_idx];
my $object_id = int($volume->select_group_id / 1000000);
if ($self->layer_editing_enabled && $volume->selected && $self->{layer_height_edit_shader} &&
$volume->has_layer_height_texture && $object_id < $self->{print}->object_count) {
$volume->set_layer_height_texture_data($self->{layer_preview_z_texture_id}, $self->{layer_height_edit_shader}->shader_program_id,
$self->{print}->get_object($object_id), $self->_variable_layer_thickness_bar_mouse_cursor_z_relative, $self->{layer_height_edit_band_width});
} else {
$volume->reset_layer_height_texture_data();
}
}
}
sub _load_image_set_texture { sub _load_image_set_texture {
my ($self, $file_name) = @_; my ($self, $file_name) = @_;
# Load a PNG with an alpha channel. # Load a PNG with an alpha channel.

View File

@ -281,6 +281,51 @@ void GLVolume::render() const
glPopMatrix(); glPopMatrix();
} }
void GLVolume::render_using_layer_height() const
{
if (!is_active)
return;
GLint current_program_id;
glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id);
if ((layer_height_texture_data.shader_id > 0) && (layer_height_texture_data.shader_id != current_program_id))
glUseProgram(layer_height_texture_data.shader_id);
GLint z_to_texture_row_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_to_texture_row") : -1;
GLint z_texture_row_to_normalized_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_texture_row_to_normalized") : -1;
GLint z_cursor_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_cursor") : -1;
GLint z_cursor_band_width_id = (layer_height_texture_data.shader_id > 0) ? glGetUniformLocation(layer_height_texture_data.shader_id, "z_cursor_band_width") : -1;
if (z_to_texture_row_id >= 0)
glUniform1f(z_to_texture_row_id, (GLfloat)layer_height_texture_z_to_row_id());
if (z_texture_row_to_normalized_id >= 0)
glUniform1f(z_texture_row_to_normalized_id, (GLfloat)(1.0f / layer_height_texture_height()));
if (z_cursor_id >= 0)
glUniform1f(z_cursor_id, (GLfloat)(bounding_box.max.z * layer_height_texture_data.z_cursor_relative));
if (z_cursor_band_width_id >= 0)
glUniform1f(z_cursor_band_width_id, (GLfloat)layer_height_texture_data.edit_band_width);
unsigned int w = layer_height_texture_width();
unsigned int h = layer_height_texture_height();
glBindTexture(GL_TEXTURE_2D, layer_height_texture_data.texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, w / 2, h / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level0());
glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, w / 2, h / 2, GL_RGBA, GL_UNSIGNED_BYTE, layer_height_texture_data_ptr_level1());
render();
glBindTexture(GL_TEXTURE_2D, 0);
if ((current_program_id > 0) && (layer_height_texture_data.shader_id != current_program_id))
glUseProgram(current_program_id);
}
void GLVolume::generate_layer_height_texture(PrintObject *print_object, bool force) void GLVolume::generate_layer_height_texture(PrintObject *print_object, bool force)
{ {
GLTexture *tex = this->layer_height_texture.get(); GLTexture *tex = this->layer_height_texture.get();
@ -398,15 +443,15 @@ int GLVolumeCollection::load_wipe_tower_preview(
void GLVolumeCollection::render_VBOs() const void GLVolumeCollection::render_VBOs() const
{ {
glEnable(GL_BLEND); ::glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glCullFace(GL_BACK); ::glCullFace(GL_BACK);
glEnableClientState(GL_VERTEX_ARRAY); ::glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY); ::glEnableClientState(GL_NORMAL_ARRAY);
GLint current_program_id; GLint current_program_id;
glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id); ::glGetIntegerv(GL_CURRENT_PROGRAM, &current_program_id);
GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1; GLint color_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "uniform_color") : -1;
GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1; GLint print_box_min_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.min") : -1;
GLint print_box_max_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.max") : -1; GLint print_box_max_id = (current_program_id > 0) ? glGetUniformLocation(current_program_id, "print_box.max") : -1;
@ -419,6 +464,17 @@ void GLVolumeCollection::render_VBOs() const
if (!volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id) if (!volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id)
continue; continue;
if (volume->layer_height_texture_data.can_use())
{
::glDisableClientState(GL_VERTEX_ARRAY);
::glDisableClientState(GL_NORMAL_ARRAY);
volume->generate_layer_height_texture(volume->layer_height_texture_data.print_object, false);
volume->render_using_layer_height();
::glEnableClientState(GL_VERTEX_ARRAY);
::glEnableClientState(GL_NORMAL_ARRAY);
continue;
}
volume->set_render_color(); volume->set_render_color();
GLsizei n_triangles = GLsizei(std::min(volume->indexed_vertex_array.triangle_indices_size, volume->tverts_range.second - volume->tverts_range.first)); GLsizei n_triangles = GLsizei(std::min(volume->indexed_vertex_array.triangle_indices_size, volume->tverts_range.second - volume->tverts_range.first));
@ -458,9 +514,9 @@ void GLVolumeCollection::render_VBOs() const
} }
if (color_id >= 0) if (color_id >= 0)
glUniform4fv(color_id, 1, (const GLfloat*)volume->render_color); ::glUniform4fv(color_id, 1, (const GLfloat*)volume->render_color);
else else
glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]); ::glColor4f(volume->render_color[0], volume->render_color[1], volume->render_color[2], volume->render_color[3]);
if (print_box_min_id != -1) if (print_box_min_id != -1)
::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min); ::glUniform3fv(print_box_min_id, 1, (const GLfloat*)print_box_min);
@ -474,36 +530,36 @@ void GLVolumeCollection::render_VBOs() const
::glUniform4fv(print_box_origin_id, 1, (const GLfloat*)origin); ::glUniform4fv(print_box_origin_id, 1, (const GLfloat*)origin);
} }
glBindBuffer(GL_ARRAY_BUFFER, volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id); ::glBindBuffer(GL_ARRAY_BUFFER, volume->indexed_vertex_array.vertices_and_normals_interleaved_VBO_id);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float))); ::glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), (const void*)(3 * sizeof(float)));
glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr); ::glNormalPointer(GL_FLOAT, 6 * sizeof(float), nullptr);
bool has_offset = (volume->origin.x != 0) || (volume->origin.y != 0) || (volume->origin.z != 0); bool has_offset = (volume->origin.x != 0) || (volume->origin.y != 0) || (volume->origin.z != 0);
if (has_offset) { if (has_offset) {
glPushMatrix(); ::glPushMatrix();
glTranslated(volume->origin.x, volume->origin.y, volume->origin.z); ::glTranslated(volume->origin.x, volume->origin.y, volume->origin.z);
} }
if (n_triangles > 0) { if (n_triangles > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.triangle_indices_VBO_id); ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.triangle_indices_VBO_id);
glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(volume->tverts_range.first * 4)); ::glDrawElements(GL_TRIANGLES, n_triangles, GL_UNSIGNED_INT, (const void*)(volume->tverts_range.first * 4));
} }
if (n_quads > 0) { if (n_quads > 0) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.quad_indices_VBO_id); ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, volume->indexed_vertex_array.quad_indices_VBO_id);
glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(volume->qverts_range.first * 4)); ::glDrawElements(GL_QUADS, n_quads, GL_UNSIGNED_INT, (const void*)(volume->qverts_range.first * 4));
} }
if (has_offset) if (has_offset)
glPopMatrix(); ::glPopMatrix();
} }
glBindBuffer(GL_ARRAY_BUFFER, 0); ::glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); ::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableClientState(GL_VERTEX_ARRAY); ::glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY); ::glDisableClientState(GL_NORMAL_ARRAY);
glDisable(GL_BLEND); ::glDisable(GL_BLEND);
} }
void GLVolumeCollection::render_legacy() const void GLVolumeCollection::render_legacy() const

View File

@ -210,6 +210,32 @@ public:
}; };
class GLVolume { class GLVolume {
struct LayerHeightTextureData
{
// ID of the layer height texture
unsigned int texture_id;
// ID of the shader used to render with the layer height texture
unsigned int shader_id;
// The print object to update when generating the layer height texture
PrintObject* print_object;
float z_cursor_relative;
float edit_band_width;
LayerHeightTextureData() { reset(); }
void reset()
{
texture_id = 0;
shader_id = 0;
print_object = nullptr;
z_cursor_relative = 0.0f;
edit_band_width = 0.0f;
}
bool can_use() { return (texture_id > 0) && (shader_id > 0) && (print_object != nullptr); }
};
public: public:
static const float SELECTED_COLOR[4]; static const float SELECTED_COLOR[4];
static const float HOVER_COLOR[4]; static const float HOVER_COLOR[4];
@ -301,11 +327,14 @@ public:
void set_range(coordf_t low, coordf_t high); void set_range(coordf_t low, coordf_t high);
void render() const; void render() const;
void render_using_layer_height() const;
void finalize_geometry(bool use_VBOs) { this->indexed_vertex_array.finalize_geometry(use_VBOs); } void finalize_geometry(bool use_VBOs) { this->indexed_vertex_array.finalize_geometry(use_VBOs); }
void release_geometry() { this->indexed_vertex_array.release_geometry(); } void release_geometry() { this->indexed_vertex_array.release_geometry(); }
/************************************************ Layer height texture ****************************************************/ /************************************************ Layer height texture ****************************************************/
std::shared_ptr<GLTexture> layer_height_texture; std::shared_ptr<GLTexture> layer_height_texture;
// Data to render this volume using the layer height texture
LayerHeightTextureData layer_height_texture_data;
bool has_layer_height_texture() const bool has_layer_height_texture() const
{ return this->layer_height_texture.get() != nullptr; } { return this->layer_height_texture.get() != nullptr; }
@ -315,11 +344,11 @@ public:
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->height; } { return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->height; }
size_t layer_height_texture_cells() const size_t layer_height_texture_cells() const
{ return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->cells; } { return (this->layer_height_texture.get() == nullptr) ? 0 : this->layer_height_texture->cells; }
void* layer_height_texture_data_ptr_level0() { void* layer_height_texture_data_ptr_level0() const {
return (layer_height_texture.get() == nullptr) ? 0 : return (layer_height_texture.get() == nullptr) ? 0 :
(void*)layer_height_texture->data.data(); (void*)layer_height_texture->data.data();
} }
void* layer_height_texture_data_ptr_level1() { void* layer_height_texture_data_ptr_level1() const {
return (layer_height_texture.get() == nullptr) ? 0 : return (layer_height_texture.get() == nullptr) ? 0 :
(void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4); (void*)(layer_height_texture->data.data() + layer_height_texture->width * layer_height_texture->height * 4);
} }
@ -328,6 +357,17 @@ public:
double(this->layer_height_texture->cells - 1) / (double(this->layer_height_texture->width) * bounding_box.max.z); double(this->layer_height_texture->cells - 1) / (double(this->layer_height_texture->width) * bounding_box.max.z);
} }
void generate_layer_height_texture(PrintObject *print_object, bool force); void generate_layer_height_texture(PrintObject *print_object, bool force);
void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, PrintObject* print_object, float z_cursor_relative, float edit_band_width)
{
layer_height_texture_data.texture_id = texture_id;
layer_height_texture_data.shader_id = shader_id;
layer_height_texture_data.print_object = print_object;
layer_height_texture_data.z_cursor_relative = z_cursor_relative;
layer_height_texture_data.edit_band_width = edit_band_width;
}
void reset_layer_height_texture_data() { layer_height_texture_data.reset(); }
}; };
class GLVolumeCollection class GLVolumeCollection

View File

@ -19,6 +19,9 @@
void enable() const; void enable() const;
void disable() const; void disable() const;
int shader_program_id() const
%code%{ RETVAL = THIS->shader_program_id; %};
std::string last_error() const std::string last_error() const
%code%{ RETVAL = THIS->last_error; %}; %code%{ RETVAL = THIS->last_error; %};
}; };
@ -45,6 +48,9 @@
int zoom_to_volumes() int zoom_to_volumes()
%code%{ RETVAL = THIS->zoom_to_volumes; %}; %code%{ RETVAL = THIS->zoom_to_volumes; %};
void set_layer_height_texture_data(unsigned int texture_id, unsigned int shader_id, PrintObject* print_object, float z_cursor_relative, float edit_band_width);
void reset_layer_height_texture_data();
int object_idx() const; int object_idx() const;
int volume_idx() const; int volume_idx() const;
int instance_idx() const; int instance_idx() const;