Merge branch 'master' into et_world_coordinates
This commit is contained in:
commit
fe71e7c597
23 changed files with 638 additions and 227 deletions
|
@ -529,7 +529,7 @@ void Bed3D::render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, co
|
|||
render_model(view_matrix, projection_matrix);
|
||||
|
||||
if (show_texture)
|
||||
render_texture(bottom, canvas);
|
||||
render_texture(bottom, canvas, view_matrix, projection_matrix);
|
||||
}
|
||||
#else
|
||||
void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture)
|
||||
|
@ -542,11 +542,19 @@ void Bed3D::render_system(GLCanvas3D& canvas, bool bottom, bool show_texture)
|
|||
}
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix)
|
||||
#else
|
||||
void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
{
|
||||
if (m_texture_filename.empty()) {
|
||||
m_texture.reset();
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
render_default(bottom, false, view_matrix, projection_matrix);
|
||||
#else
|
||||
render_default(bottom, false);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -559,7 +567,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
|
|||
if (m_temp_texture.get_id() == 0 || m_temp_texture.get_source() != m_texture_filename) {
|
||||
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
|
||||
if (!m_temp_texture.load_from_svg_file(m_texture_filename, false, false, false, max_tex_size / 8)) {
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
render_default(bottom, false, view_matrix, projection_matrix);
|
||||
#else
|
||||
render_default(bottom, false);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
return;
|
||||
}
|
||||
canvas.request_extra_frame();
|
||||
|
@ -567,7 +579,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
|
|||
|
||||
// starts generating the main texture, compression will run asynchronously
|
||||
if (!m_texture.load_from_svg_file(m_texture_filename, true, true, true, max_tex_size)) {
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
render_default(bottom, false, view_matrix, projection_matrix);
|
||||
#else
|
||||
render_default(bottom, false);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -575,7 +591,11 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
|
|||
// generate a temporary lower resolution texture to show while no main texture levels have been compressed
|
||||
if (m_temp_texture.get_id() == 0 || m_temp_texture.get_source() != m_texture_filename) {
|
||||
if (!m_temp_texture.load_from_file(m_texture_filename, false, GLTexture::None, false)) {
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
render_default(bottom, false, view_matrix, projection_matrix);
|
||||
#else
|
||||
render_default(bottom, false);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
return;
|
||||
}
|
||||
canvas.request_extra_frame();
|
||||
|
@ -583,12 +603,20 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
|
|||
|
||||
// starts generating the main texture, compression will run asynchronously
|
||||
if (!m_texture.load_from_file(m_texture_filename, true, GLTexture::MultiThreaded, true)) {
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
render_default(bottom, false, view_matrix, projection_matrix);
|
||||
#else
|
||||
render_default(bottom, false);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
render_default(bottom, false, view_matrix, projection_matrix);
|
||||
#else
|
||||
render_default(bottom, false);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -614,9 +642,8 @@ void Bed3D::render_texture(bool bottom, GLCanvas3D& canvas)
|
|||
if (shader != nullptr) {
|
||||
shader->start_using();
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("view_model_matrix", view_matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
shader->set_uniform("transparent_background", bottom);
|
||||
shader->set_uniform("svg_source", boost::algorithm::iends_with(m_texture.get_source(), ".svg"));
|
||||
|
@ -768,7 +795,11 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bo
|
|||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
{
|
||||
if (m_texture_filename.empty() && m_model_filename.empty()) {
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
render_default(bottom, picking, view_matrix, projection_matrix);
|
||||
#else
|
||||
render_default(bottom, picking);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -780,10 +811,18 @@ void Bed3D::render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bo
|
|||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
if (show_texture)
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
render_texture(bottom, canvas, view_matrix, projection_matrix);
|
||||
#else
|
||||
render_texture(bottom, canvas);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
}
|
||||
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
void Bed3D::render_default(bool bottom, bool picking, const Transform3d& view_matrix, const Transform3d& projection_matrix)
|
||||
#else
|
||||
void Bed3D::render_default(bool bottom, bool picking)
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
{
|
||||
m_texture.reset();
|
||||
|
||||
|
@ -800,9 +839,8 @@ void Bed3D::render_default(bool bottom, bool picking)
|
|||
shader->start_using();
|
||||
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("view_model_matrix", view_matrix);
|
||||
shader->set_uniform("projection_matrix", projection_matrix);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||
|
|
|
@ -178,18 +178,18 @@ private:
|
|||
void render_axes();
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
void render_system(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture);
|
||||
#else
|
||||
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
void render_texture(bool bottom, GLCanvas3D& canvas);
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
void render_texture(bool bottom, GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix);
|
||||
void render_model(const Transform3d& view_matrix, const Transform3d& projection_matrix);
|
||||
void render_custom(GLCanvas3D& canvas, const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_texture, bool picking);
|
||||
void render_default(bool bottom, bool picking, const Transform3d& view_matrix, const Transform3d& projection_matrix);
|
||||
#else
|
||||
void render_system(GLCanvas3D& canvas, bool bottom, bool show_texture);
|
||||
void render_texture(bool bottom, GLCanvas3D& canvas);
|
||||
void render_model();
|
||||
void render_custom(GLCanvas3D& canvas, bool bottom, bool show_texture, bool picking);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
void render_default(bool bottom, bool picking);
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
#if !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
void release_VBOs();
|
||||
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
|
|
@ -459,6 +459,7 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u
|
|||
static const ImVec4 COMMAND_COLOR = { 0.8f, 0.8f, 0.0f, 1.0f };
|
||||
static const ImVec4 PARAMETERS_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f };
|
||||
static const ImVec4 ELLIPSIS_COLOR = { 0.0f, 0.7f, 0.0f, 1.0f };
|
||||
|
||||
if (!m_visible || m_filename.empty() || m_lines_ends.empty() || curr_line_id == 0)
|
||||
return;
|
||||
|
@ -503,6 +504,35 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u
|
|||
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
|
||||
auto add_item_to_line = [&imgui](const std::string& txt, const ImVec4& color, float spacing, size_t& current_length) {
|
||||
static const size_t LENGTH_THRESHOLD = 60;
|
||||
|
||||
if (txt.empty())
|
||||
return false;
|
||||
|
||||
std::string out_text = txt;
|
||||
bool reduced = false;
|
||||
if (current_length + out_text.length() > LENGTH_THRESHOLD) {
|
||||
out_text = out_text.substr(0, LENGTH_THRESHOLD - current_length);
|
||||
reduced = true;
|
||||
}
|
||||
|
||||
current_length += out_text.length();
|
||||
|
||||
ImGui::SameLine(0.0f, spacing);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||
imgui.text(out_text);
|
||||
ImGui::PopStyleColor();
|
||||
if (reduced) {
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ELLIPSIS_COLOR);
|
||||
imgui.text("...");
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
return reduced;
|
||||
};
|
||||
|
||||
imgui.set_next_window_pos(0.0f, top, ImGuiCond_Always, 0.0f, 0.0f);
|
||||
imgui.set_next_window_size(0.0f, wnd_height, ImGuiCond_Always);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
|
@ -527,41 +557,22 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, u
|
|||
ImGui::GetColorU32(SELECTION_RECT_COLOR));
|
||||
}
|
||||
|
||||
// render line number
|
||||
const std::string id_str = std::to_string(id);
|
||||
// spacer to right align text
|
||||
ImGui::Dummy({ id_width - ImGui::CalcTextSize(id_str.c_str()).x, text_height });
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, LINE_NUMBER_COLOR);
|
||||
imgui.text(id_str);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (!line.command.empty() || !line.comment.empty())
|
||||
ImGui::SameLine();
|
||||
|
||||
// render command
|
||||
if (!line.command.empty()) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, COMMAND_COLOR);
|
||||
imgui.text(line.command);
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
// render parameters
|
||||
if (!line.parameters.empty()) {
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, PARAMETERS_COLOR);
|
||||
imgui.text(line.parameters);
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
|
||||
// render comment
|
||||
if (!line.comment.empty()) {
|
||||
if (!line.command.empty())
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, COMMENT_COLOR);
|
||||
imgui.text(line.comment);
|
||||
ImGui::PopStyleColor();
|
||||
}
|
||||
size_t line_length = 0;
|
||||
// render line number
|
||||
bool stop_adding = add_item_to_line(id_str, LINE_NUMBER_COLOR, 0.0f, line_length);
|
||||
if (!stop_adding && !line.command.empty())
|
||||
// render command
|
||||
stop_adding = add_item_to_line(line.command, COMMAND_COLOR, -1.0f, line_length);
|
||||
if (!stop_adding && !line.parameters.empty())
|
||||
// render parameters
|
||||
stop_adding = add_item_to_line(line.parameters, PARAMETERS_COLOR, 0.0f, line_length);
|
||||
if (!stop_adding && !line.comment.empty())
|
||||
// render comment
|
||||
stop_adding = add_item_to_line(line.comment, COMMENT_COLOR, line.command.empty() ? -1.0f : 0.0f, line_length);
|
||||
}
|
||||
|
||||
imgui.end();
|
||||
|
@ -1310,18 +1321,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
|||
log_memory_used(label, vertices_size + indices_size);
|
||||
};
|
||||
|
||||
// format data into the buffers to be rendered as points
|
||||
auto add_vertices_as_point = [](const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
|
||||
vertices.push_back(curr.position.x());
|
||||
vertices.push_back(curr.position.y());
|
||||
vertices.push_back(curr.position.z());
|
||||
};
|
||||
auto add_indices_as_point = [](const GCodeProcessorResult::MoveVertex& curr, TBuffer& buffer,
|
||||
unsigned int ibuffer_id, IndexBuffer& indices, size_t move_id) {
|
||||
buffer.add_path(curr, ibuffer_id, indices.size(), move_id);
|
||||
indices.push_back(static_cast<IBufferType>(indices.size()));
|
||||
};
|
||||
|
||||
// format data into the buffers to be rendered as lines
|
||||
auto add_vertices_as_line = [](const GCodeProcessorResult::MoveVertex& prev, const GCodeProcessorResult::MoveVertex& curr, VertexBuffer& vertices) {
|
||||
#if !ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
@ -1816,7 +1815,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
|||
|
||||
switch (t_buffer.render_primitive_type)
|
||||
{
|
||||
case TBuffer::ERenderPrimitiveType::Point: { add_vertices_as_point(curr, v_buffer); break; }
|
||||
case TBuffer::ERenderPrimitiveType::Line: { add_vertices_as_line(prev, curr, v_buffer); break; }
|
||||
#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC
|
||||
case TBuffer::ERenderPrimitiveType::Triangle: { add_vertices_as_solid(prev, curr, t_buffer, static_cast<unsigned int>(v_multibuffer.size()) - 1, v_buffer, move_id, account_for_volumetric_rate); break; }
|
||||
|
@ -2152,8 +2150,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
|||
if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - indiced_size_to_add) {
|
||||
i_multibuffer.push_back(IndexBuffer());
|
||||
vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]);
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point &&
|
||||
t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
Path& last_path = t_buffer.paths.back();
|
||||
last_path.add_sub_path(prev, static_cast<unsigned int>(i_multibuffer.size()) - 1, 0, move_id - 1);
|
||||
}
|
||||
|
@ -2169,8 +2166,7 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
|||
curr_vertex_buffer.second = 0;
|
||||
vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]);
|
||||
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::Point &&
|
||||
t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
Path& last_path = t_buffer.paths.back();
|
||||
last_path.add_sub_path(prev, static_cast<unsigned int>(i_multibuffer.size()) - 1, 0, move_id - 1);
|
||||
}
|
||||
|
@ -2180,11 +2176,6 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result)
|
|||
|
||||
switch (t_buffer.render_primitive_type)
|
||||
{
|
||||
case TBuffer::ERenderPrimitiveType::Point: {
|
||||
add_indices_as_point(curr, t_buffer, static_cast<unsigned int>(i_multibuffer.size()) - 1, i_buffer, move_id);
|
||||
curr_vertex_buffer.second += t_buffer.max_vertices_per_segment();
|
||||
break;
|
||||
}
|
||||
case TBuffer::ERenderPrimitiveType::Line: {
|
||||
#if ENABLE_VOLUMETRIC_RATE_TOOLPATHS_RECALC
|
||||
add_indices_as_line(prev, curr, t_buffer, static_cast<unsigned int>(i_multibuffer.size()) - 1, i_buffer, move_id, account_for_volumetric_rate);
|
||||
|
@ -2732,10 +2723,6 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||
unsigned int size_in_indices = 0;
|
||||
switch (buffer.render_primitive_type)
|
||||
{
|
||||
case TBuffer::ERenderPrimitiveType::Point: {
|
||||
size_in_indices = buffer.indices_per_segment();
|
||||
break;
|
||||
}
|
||||
case TBuffer::ERenderPrimitiveType::Line:
|
||||
case TBuffer::ERenderPrimitiveType::Triangle: {
|
||||
unsigned int segments_count = std::min(m_sequential_view.current.last, sub_path.last.s_id) - std::max(m_sequential_view.current.first, sub_path.first.s_id);
|
||||
|
@ -2968,56 +2955,11 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||
|
||||
void GCodeViewer::render_toolpaths()
|
||||
{
|
||||
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
||||
const float point_size = 20.0f;
|
||||
#else
|
||||
const float point_size = 0.8f;
|
||||
#endif // ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
||||
#if !ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
const std::array<float, 4> light_intensity = { 0.25f, 0.70f, 0.75f, 0.75f };
|
||||
#endif // !ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const double zoom = camera.get_zoom();
|
||||
const std::array<int, 4>& viewport = camera.get_viewport();
|
||||
const float near_plane_height = camera.get_type() == Camera::EType::Perspective ? static_cast<float>(viewport[3]) / (2.0f * static_cast<float>(2.0 * std::tan(0.5 * Geometry::deg2rad(camera.get_fov())))) :
|
||||
static_cast<float>(viewport[3]) * 0.0005;
|
||||
|
||||
auto shader_init_as_points = [zoom, point_size, near_plane_height](GLShaderProgram& shader) {
|
||||
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
||||
shader.set_uniform("use_fixed_screen_size", 1);
|
||||
#else
|
||||
shader.set_uniform("use_fixed_screen_size", 0);
|
||||
#endif // ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
||||
shader.set_uniform("zoom", zoom);
|
||||
shader.set_uniform("percent_outline_radius", 0.0f);
|
||||
shader.set_uniform("percent_center_radius", 0.33f);
|
||||
shader.set_uniform("point_size", point_size);
|
||||
shader.set_uniform("near_plane_height", near_plane_height);
|
||||
};
|
||||
|
||||
auto render_as_points = [
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
this
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
](std::vector<RenderPath>::iterator it_path, std::vector<RenderPath>::iterator it_end, GLShaderProgram& shader, int uniform_color) {
|
||||
glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||
glsafe(::glEnable(GL_POINT_SPRITE));
|
||||
|
||||
for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) {
|
||||
const RenderPath& path = *it;
|
||||
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
|
||||
assert(! path.sizes.empty());
|
||||
assert(! path.offsets.empty());
|
||||
shader.set_uniform(uniform_color, path.color);
|
||||
glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
++m_statistics.gl_multi_points_calls_count;
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
}
|
||||
|
||||
glsafe(::glDisable(GL_POINT_SPRITE));
|
||||
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||
};
|
||||
|
||||
#if !ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
|
||||
|
@ -3194,15 +3136,10 @@ void GCodeViewer::render_toolpaths()
|
|||
shader->start_using();
|
||||
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
int position_id = -1;
|
||||
int normal_id = -1;
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
position_id = shader->get_attrib_location("v_position");
|
||||
normal_id = shader->get_attrib_location("v_normal");
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::InstancedModel) {
|
||||
|
@ -3213,6 +3150,8 @@ void GCodeViewer::render_toolpaths()
|
|||
else if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::BatchedModel) {
|
||||
shader->set_uniform("emission_factor", 0.25f);
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
const int position_id = shader->get_attrib_location("v_position");
|
||||
const int normal_id = shader->get_attrib_location("v_normal");
|
||||
render_as_batched_model(buffer, *shader, position_id, normal_id);
|
||||
#else
|
||||
render_as_batched_model(buffer, *shader);
|
||||
|
@ -3221,8 +3160,8 @@ void GCodeViewer::render_toolpaths()
|
|||
}
|
||||
else {
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
if (buffer.render_primitive_type == TBuffer::ERenderPrimitiveType::Point)
|
||||
shader_init_as_points(*shader);
|
||||
const int position_id = shader->get_attrib_location("v_position");
|
||||
const int normal_id = shader->get_attrib_location("v_normal");
|
||||
#else
|
||||
switch (buffer.render_primitive_type) {
|
||||
case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break;
|
||||
|
@ -3269,10 +3208,6 @@ void GCodeViewer::render_toolpaths()
|
|||
// Render all elements with it_path->ibuffer_id == ibuffer_id, possible with varying colors.
|
||||
switch (buffer.render_primitive_type)
|
||||
{
|
||||
case TBuffer::ERenderPrimitiveType::Point: {
|
||||
render_as_points(it_path, buffer.render_paths.end(), *shader, uniform_color);
|
||||
break;
|
||||
}
|
||||
case TBuffer::ERenderPrimitiveType::Line: {
|
||||
glsafe(::glLineWidth(static_cast<GLfloat>(line_width(zoom))));
|
||||
render_as_lines(it_path, buffer.render_paths.end(), *shader, uniform_color);
|
||||
|
@ -3306,9 +3241,9 @@ void GCodeViewer::render_toolpaths()
|
|||
}
|
||||
|
||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||
auto render_sequential_range_cap = [this]
|
||||
auto render_sequential_range_cap = [this, &camera]
|
||||
#else
|
||||
auto render_sequential_range_cap = []
|
||||
auto render_sequential_range_cap = [&camera]
|
||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||
(const SequentialRangeCap& cap) {
|
||||
const TBuffer* buffer = cap.buffer;
|
||||
|
@ -3319,16 +3254,13 @@ void GCodeViewer::render_toolpaths()
|
|||
shader->start_using();
|
||||
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
int position_id = -1;
|
||||
int normal_id = -1;
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d& view_matrix = camera.get_view_matrix();
|
||||
shader->set_uniform("view_model_matrix", view_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
|
||||
position_id = shader->get_attrib_location("v_position");
|
||||
normal_id = shader->get_attrib_location("v_normal");
|
||||
const int position_id = shader->get_attrib_location("v_position");
|
||||
const int normal_id = shader->get_attrib_location("v_normal");
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo));
|
||||
|
@ -4682,7 +4614,6 @@ void GCodeViewer::render_statistics()
|
|||
}
|
||||
|
||||
if (ImGui::CollapsingHeader("OpenGL calls")) {
|
||||
add_counter(std::string("Multi GL_POINTS:"), m_statistics.gl_multi_points_calls_count);
|
||||
add_counter(std::string("Multi GL_LINES:"), m_statistics.gl_multi_lines_calls_count);
|
||||
add_counter(std::string("Multi GL_TRIANGLES:"), m_statistics.gl_multi_triangles_calls_count);
|
||||
add_counter(std::string("GL_TRIANGLES:"), m_statistics.gl_triangles_calls_count);
|
||||
|
|
|
@ -284,7 +284,6 @@ class GCodeViewer
|
|||
{
|
||||
enum class ERenderPrimitiveType : unsigned char
|
||||
{
|
||||
Point,
|
||||
Line,
|
||||
Triangle,
|
||||
InstancedModel,
|
||||
|
@ -325,7 +324,6 @@ class GCodeViewer
|
|||
unsigned int max_vertices_per_segment() const {
|
||||
switch (render_primitive_type)
|
||||
{
|
||||
case ERenderPrimitiveType::Point: { return 1; }
|
||||
case ERenderPrimitiveType::Line: { return 2; }
|
||||
case ERenderPrimitiveType::Triangle: { return 8; }
|
||||
default: { return 0; }
|
||||
|
@ -337,7 +335,6 @@ class GCodeViewer
|
|||
unsigned int indices_per_segment() const {
|
||||
switch (render_primitive_type)
|
||||
{
|
||||
case ERenderPrimitiveType::Point: { return 1; }
|
||||
case ERenderPrimitiveType::Line: { return 2; }
|
||||
case ERenderPrimitiveType::Triangle: { return 30; } // 3 indices x 10 triangles
|
||||
default: { return 0; }
|
||||
|
@ -347,7 +344,6 @@ class GCodeViewer
|
|||
unsigned int max_indices_per_segment() const {
|
||||
switch (render_primitive_type)
|
||||
{
|
||||
case ERenderPrimitiveType::Point: { return 1; }
|
||||
case ERenderPrimitiveType::Line: { return 2; }
|
||||
case ERenderPrimitiveType::Triangle: { return 36; } // 3 indices x 12 triangles
|
||||
default: { return 0; }
|
||||
|
@ -358,7 +354,6 @@ class GCodeViewer
|
|||
bool has_data() const {
|
||||
switch (render_primitive_type)
|
||||
{
|
||||
case ERenderPrimitiveType::Point:
|
||||
case ERenderPrimitiveType::Line:
|
||||
case ERenderPrimitiveType::Triangle: {
|
||||
return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0;
|
||||
|
@ -585,7 +580,6 @@ class GCodeViewer
|
|||
int64_t refresh_time{ 0 };
|
||||
int64_t refresh_paths_time{ 0 };
|
||||
// opengl calls
|
||||
int64_t gl_multi_points_calls_count{ 0 };
|
||||
int64_t gl_multi_lines_calls_count{ 0 };
|
||||
int64_t gl_multi_triangles_calls_count{ 0 };
|
||||
int64_t gl_triangles_calls_count{ 0 };
|
||||
|
@ -628,7 +622,6 @@ class GCodeViewer
|
|||
}
|
||||
|
||||
void reset_opengl() {
|
||||
gl_multi_points_calls_count = 0;
|
||||
gl_multi_lines_calls_count = 0;
|
||||
gl_multi_triangles_calls_count = 0;
|
||||
gl_triangles_calls_count = 0;
|
||||
|
|
|
@ -1667,6 +1667,10 @@ void GLCanvas3D::render()
|
|||
wxGetApp().plater()->init_environment_texture();
|
||||
#endif // ENABLE_ENVIRONMENT_MAP
|
||||
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
GLModel::reset_statistics_counters();
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
|
||||
const Size& cnv_size = get_canvas_size();
|
||||
// Probably due to different order of events on Linux/GTK2, when one switched from 3D scene
|
||||
// to preview, this was called before canvas had its final size. It reported zero width
|
||||
|
@ -1692,13 +1696,17 @@ void GLCanvas3D::render()
|
|||
wxGetApp().imgui()->new_frame();
|
||||
|
||||
if (m_picking_enabled) {
|
||||
if (m_rectangle_selection.is_dragging())
|
||||
// picking pass using rectangle selection
|
||||
_rectangular_selection_picking_pass();
|
||||
else if (!m_volumes.empty())
|
||||
// regular picking pass
|
||||
_picking_pass();
|
||||
}
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (m_rectangle_selection.is_dragging() && !m_rectangle_selection.is_empty())
|
||||
#else
|
||||
if (m_rectangle_selection.is_dragging())
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
// picking pass using rectangle selection
|
||||
_rectangular_selection_picking_pass();
|
||||
else if (!m_volumes.empty())
|
||||
// regular picking pass
|
||||
_picking_pass();
|
||||
}
|
||||
|
||||
#if ENABLE_RENDER_PICKING_PASS
|
||||
if (!m_picking_enabled || !m_show_picking_texture) {
|
||||
|
@ -1776,6 +1784,9 @@ void GLCanvas3D::render()
|
|||
#if ENABLE_CAMERA_STATISTICS
|
||||
camera.debug_render();
|
||||
#endif // ENABLE_CAMERA_STATISTICS
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
GLModel::render_statistics();
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
|
||||
std::string tooltip;
|
||||
|
||||
|
@ -2917,8 +2928,7 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
if (imgui->update_key_data(evt)) {
|
||||
render();
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
if (!m_gizmos.on_key(evt)) {
|
||||
if (evt.GetEventType() == wxEVT_KEY_UP) {
|
||||
if (evt.ShiftDown() && evt.ControlDown() && keyCode == WXK_SPACE) {
|
||||
|
@ -2941,8 +2951,13 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
_update_selection_from_hover();
|
||||
m_rectangle_selection.stop_dragging();
|
||||
m_mouse.ignore_left_up = true;
|
||||
#if !ENABLE_NEW_RECTANGLE_SELECTION
|
||||
m_dirty = true;
|
||||
#endif // !ENABLE_NEW_RECTANGLE_SELECTION
|
||||
}
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
m_dirty = true;
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
// set_cursor(Standard);
|
||||
}
|
||||
else if (keyCode == WXK_ALT) {
|
||||
|
@ -2954,8 +2969,17 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
}
|
||||
// set_cursor(Standard);
|
||||
}
|
||||
else if (keyCode == WXK_CONTROL)
|
||||
else if (keyCode == WXK_CONTROL) {
|
||||
#if ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
if (m_mouse.dragging) {
|
||||
// if the user releases CTRL while rotating the 3D scene
|
||||
// prevent from moving the selected volume
|
||||
m_mouse.drag.move_volume_idx = -1;
|
||||
m_mouse.set_start_position_3D_as_invalid();
|
||||
}
|
||||
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
m_dirty = true;
|
||||
}
|
||||
else if (m_gizmos.is_enabled() && !m_selection.is_empty()) {
|
||||
translationProcessor.process(evt);
|
||||
|
||||
|
@ -2986,15 +3010,16 @@ void GLCanvas3D::on_key(wxKeyEvent& evt)
|
|||
if (keyCode == WXK_SHIFT) {
|
||||
translationProcessor.process(evt);
|
||||
|
||||
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports))
|
||||
{
|
||||
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports)) {
|
||||
m_mouse.ignore_left_up = false;
|
||||
// set_cursor(Cross);
|
||||
}
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
m_dirty = true;
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
}
|
||||
else if (keyCode == WXK_ALT) {
|
||||
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports))
|
||||
{
|
||||
if (m_picking_enabled && (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports)) {
|
||||
m_mouse.ignore_left_up = false;
|
||||
// set_cursor(Cross);
|
||||
}
|
||||
|
@ -3413,6 +3438,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
m_layers_editing.state = LayersEditing::Editing;
|
||||
_perform_layer_editing_action(&evt);
|
||||
}
|
||||
#if !ENABLE_NEW_RECTANGLE_SELECTION
|
||||
else if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) {
|
||||
if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports
|
||||
&& m_gizmos.get_current_type() != GLGizmosManager::FdmSupports
|
||||
|
@ -3422,23 +3448,52 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
#endif // !ENABLE_NEW_RECTANGLE_SELECTION
|
||||
else {
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (evt.LeftDown() && (evt.ShiftDown() || evt.AltDown()) && m_picking_enabled) {
|
||||
if (m_gizmos.get_current_type() != GLGizmosManager::SlaSupports &&
|
||||
m_gizmos.get_current_type() != GLGizmosManager::FdmSupports &&
|
||||
m_gizmos.get_current_type() != GLGizmosManager::Seam &&
|
||||
m_gizmos.get_current_type() != GLGizmosManager::MmuSegmentation) {
|
||||
m_rectangle_selection.start_dragging(m_mouse.position, evt.ShiftDown() ? GLSelectionRectangle::EState::Select : GLSelectionRectangle::EState::Deselect);
|
||||
m_dirty = true;
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
|
||||
// Select volume in this 3D canvas.
|
||||
// Don't deselect a volume if layer editing is enabled or any gizmo is active. We want the object to stay selected
|
||||
// during the scene manipulation.
|
||||
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (m_picking_enabled && (!any_gizmo_active || !evt.ShiftDown()) && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled()) &&
|
||||
!m_rectangle_selection.is_dragging()) {
|
||||
#else
|
||||
if (m_picking_enabled && (!any_gizmo_active || !evt.CmdDown()) && (!m_hover_volume_idxs.empty() || !is_layers_editing_enabled())) {
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (evt.LeftDown() && !m_hover_volume_idxs.empty()) {
|
||||
int volume_idx = get_first_hover_volume_idx();
|
||||
bool already_selected = m_selection.contains_volume(volume_idx);
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
bool shift_down = evt.ShiftDown();
|
||||
#else
|
||||
bool ctrl_down = evt.CmdDown();
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
|
||||
Selection::IndicesList curr_idxs = m_selection.get_volume_idxs();
|
||||
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (already_selected && shift_down)
|
||||
m_selection.remove(volume_idx);
|
||||
else {
|
||||
m_selection.add(volume_idx, !shift_down, true);
|
||||
#else
|
||||
if (already_selected && ctrl_down)
|
||||
m_selection.remove(volume_idx);
|
||||
else {
|
||||
m_selection.add(volume_idx, !ctrl_down, true);
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
m_mouse.drag.move_requires_threshold = !already_selected;
|
||||
if (already_selected)
|
||||
m_mouse.set_move_start_threshold_position_2D_as_invalid();
|
||||
|
@ -3460,18 +3515,25 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (!m_hover_volume_idxs.empty() && !m_rectangle_selection.is_dragging()) {
|
||||
#else
|
||||
if (!m_hover_volume_idxs.empty()) {
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (evt.LeftDown() && m_moving_enabled && m_mouse.drag.move_volume_idx == -1) {
|
||||
// Only accept the initial position, if it is inside the volume bounding box.
|
||||
int volume_idx = get_first_hover_volume_idx();
|
||||
const int volume_idx = get_first_hover_volume_idx();
|
||||
BoundingBoxf3 volume_bbox = m_volumes.volumes[volume_idx]->transformed_bounding_box();
|
||||
volume_bbox.offset(1.0);
|
||||
if ((!any_gizmo_active || !evt.CmdDown()) && volume_bbox.contains(m_mouse.scene_position)) {
|
||||
m_volumes.volumes[volume_idx]->hover = GLVolume::HS_None;
|
||||
// The dragging operation is initiated.
|
||||
m_mouse.drag.move_volume_idx = volume_idx;
|
||||
#if ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
m_selection.setup_cache();
|
||||
m_mouse.drag.start_position_3D = m_mouse.scene_position;
|
||||
if (!evt.CmdDown())
|
||||
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
m_mouse.drag.start_position_3D = m_mouse.scene_position;
|
||||
m_sequential_print_clearance_first_displacement = true;
|
||||
m_moving = true;
|
||||
}
|
||||
|
@ -3479,31 +3541,36 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
}
|
||||
#if ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
else if (evt.Dragging() && evt.LeftIsDown() && !evt.CmdDown() && m_layers_editing.state == LayersEditing::Unknown &&
|
||||
m_mouse.drag.move_volume_idx != -1 && m_mouse.is_start_position_3D_defined()) {
|
||||
#else
|
||||
else if (evt.Dragging() && evt.LeftIsDown() && m_layers_editing.state == LayersEditing::Unknown && m_mouse.drag.move_volume_idx != -1) {
|
||||
if (!m_mouse.drag.move_requires_threshold) {
|
||||
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
if (!m_mouse.drag.move_requires_threshold) {
|
||||
m_mouse.dragging = true;
|
||||
Vec3d cur_pos = m_mouse.drag.start_position_3D;
|
||||
// we do not want to translate objects if the user just clicked on an object while pressing shift to remove it from the selection and then drag
|
||||
if (m_selection.contains_volume(get_first_hover_volume_idx())) {
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
if (std::abs(camera.get_dir_forward()(2)) < EPSILON) {
|
||||
if (std::abs(camera.get_dir_forward().z()) < EPSILON) {
|
||||
// side view -> move selected volumes orthogonally to camera view direction
|
||||
Linef3 ray = mouse_ray(pos);
|
||||
Vec3d dir = ray.unit_vector();
|
||||
const Linef3 ray = mouse_ray(pos);
|
||||
const Vec3d dir = ray.unit_vector();
|
||||
// finds the intersection of the mouse ray with the plane parallel to the camera viewport and passing throught the starting position
|
||||
// use ray-plane intersection see i.e. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection algebric form
|
||||
// in our case plane normal and ray direction are the same (orthogonal view)
|
||||
// when moving to perspective camera the negative z unit axis of the camera needs to be transformed in world space and used as plane normal
|
||||
Vec3d inters = ray.a + (m_mouse.drag.start_position_3D - ray.a).dot(dir) / dir.squaredNorm() * dir;
|
||||
const Vec3d inters = ray.a + (m_mouse.drag.start_position_3D - ray.a).dot(dir) / dir.squaredNorm() * dir;
|
||||
// vector from the starting position to the found intersection
|
||||
Vec3d inters_vec = inters - m_mouse.drag.start_position_3D;
|
||||
const Vec3d inters_vec = inters - m_mouse.drag.start_position_3D;
|
||||
|
||||
Vec3d camera_right = camera.get_dir_right();
|
||||
Vec3d camera_up = camera.get_dir_up();
|
||||
const Vec3d camera_right = camera.get_dir_right();
|
||||
const Vec3d camera_up = camera.get_dir_up();
|
||||
|
||||
// finds projection of the vector along the camera axes
|
||||
double projection_x = inters_vec.dot(camera_right);
|
||||
double projection_z = inters_vec.dot(camera_up);
|
||||
const double projection_x = inters_vec.dot(camera_right);
|
||||
const double projection_z = inters_vec.dot(camera_up);
|
||||
|
||||
// apply offset
|
||||
cur_pos = m_mouse.drag.start_position_3D + projection_x * camera_right + projection_z * camera_up;
|
||||
|
@ -3513,7 +3580,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
// Get new position at the same Z of the initial click point.
|
||||
float z0 = 0.0f;
|
||||
float z1 = 1.0f;
|
||||
cur_pos = Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D(2));
|
||||
cur_pos = Linef3(_mouse_to_3d(pos, &z0), _mouse_to_3d(pos, &z1)).intersect_plane(m_mouse.drag.start_position_3D.z());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3525,7 +3592,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
else if (evt.Dragging() && evt.LeftIsDown() && m_picking_enabled && m_rectangle_selection.is_dragging()) {
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
// keeps the mouse position updated while dragging the selection rectangle
|
||||
m_mouse.position = pos.cast<double>();
|
||||
m_rectangle_selection.dragging(m_mouse.position);
|
||||
#else
|
||||
m_rectangle_selection.dragging(pos.cast<double>());
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
m_dirty = true;
|
||||
}
|
||||
else if (evt.Dragging()) {
|
||||
|
@ -3538,13 +3611,19 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
}
|
||||
}
|
||||
// do not process the dragging if the left mouse was set down in another canvas
|
||||
else if (evt.LeftIsDown()) {
|
||||
#if ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
else if (evt.LeftIsDown() || evt.MiddleIsDown()) {
|
||||
// if dragging over blank area with left button, rotate
|
||||
if ((any_gizmo_active || evt.CmdDown() || evt.MiddleIsDown() || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) {
|
||||
#else
|
||||
// if dragging over blank area with left button, rotate
|
||||
else if (evt.LeftIsDown()) {
|
||||
if ((any_gizmo_active || m_hover_volume_idxs.empty()) && m_mouse.is_start_position_3D_defined()) {
|
||||
const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.);
|
||||
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
const Vec3d rot = (Vec3d(pos.x(), pos.y(), 0.0) - m_mouse.drag.start_position_3D) * (PI * TRACKBALLSIZE / 180.0);
|
||||
if (wxGetApp().app_config->get("use_free_camera") == "1")
|
||||
// Virtual track ball (similar to the 3DConnexion mouse).
|
||||
wxGetApp().plater()->get_camera().rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.));
|
||||
wxGetApp().plater()->get_camera().rotate_local_around_target(Vec3d(rot.y(), rot.x(), 0.0));
|
||||
else {
|
||||
// Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation.
|
||||
// It is cheaper to call this function right away instead of testing wxGetApp().plater()->get_mouse3d_controller().connected(),
|
||||
|
@ -3557,15 +3636,20 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
|
||||
m_dirty = true;
|
||||
}
|
||||
m_mouse.drag.start_position_3D = Vec3d((double)pos(0), (double)pos(1), 0.0);
|
||||
m_mouse.drag.start_position_3D = Vec3d((double)pos.x(), (double)pos.y(), 0.0);
|
||||
}
|
||||
#if ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
else if (evt.RightIsDown()) {
|
||||
// If dragging with right button, pan.
|
||||
#else
|
||||
else if (evt.MiddleIsDown() || evt.RightIsDown()) {
|
||||
// If dragging over blank area with right button, pan.
|
||||
#endif // ENABLE_NEW_CAMERA_MOVEMENTS
|
||||
if (m_mouse.is_start_position_2D_defined()) {
|
||||
// get point in model space at Z = 0
|
||||
float z = 0.0f;
|
||||
const Vec3d& cur_pos = _mouse_to_3d(pos, &z);
|
||||
Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
|
||||
const Vec3d orig = _mouse_to_3d(m_mouse.drag.start_position_2D, &z);
|
||||
Camera& camera = wxGetApp().plater()->get_camera();
|
||||
if (wxGetApp().app_config->get("use_free_camera") != "1")
|
||||
// Forces camera right vector to be parallel to XY plane in case it has been misaligned using the 3D mouse free rotation.
|
||||
|
@ -3638,7 +3722,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
|||
if (!m_mouse.dragging) {
|
||||
// do not post the event if the user is panning the scene
|
||||
// or if right click was done over the wipe tower
|
||||
bool post_right_click_event = m_hover_volume_idxs.empty() || !m_volumes.volumes[get_first_hover_volume_idx()]->is_wipe_tower;
|
||||
const bool post_right_click_event = m_hover_volume_idxs.empty() || !m_volumes.volumes[get_first_hover_volume_idx()]->is_wipe_tower;
|
||||
if (post_right_click_event)
|
||||
post_event(RBtnEvent(EVT_GLCANVAS_RIGHT_CLICK, { logical_pos, m_hover_volume_idxs.empty() }));
|
||||
}
|
||||
|
@ -6331,7 +6415,9 @@ void GLCanvas3D::_update_volumes_hover_state()
|
|||
return;
|
||||
}
|
||||
|
||||
#if !ENABLE_NEW_RECTANGLE_SELECTION
|
||||
bool selection_modifiers_only = m_selection.is_empty() || m_selection.is_any_modifier();
|
||||
#endif // !ENABLE_NEW_RECTANGLE_SELECTION
|
||||
|
||||
bool hover_modifiers_only = true;
|
||||
for (int i : m_hover_volume_idxs) {
|
||||
|
@ -6360,9 +6446,14 @@ void GLCanvas3D::_update_volumes_hover_state()
|
|||
if (volume.hover != GLVolume::HS_None)
|
||||
continue;
|
||||
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
bool deselect = volume.selected && ((shift_pressed && m_rectangle_selection.is_empty()) || (alt_pressed && !m_rectangle_selection.is_empty()));
|
||||
bool select = !volume.selected && (m_rectangle_selection.is_empty() || (shift_pressed && !m_rectangle_selection.is_empty()));
|
||||
#else
|
||||
bool deselect = volume.selected && ((ctrl_pressed && !shift_pressed) || alt_pressed);
|
||||
// (volume->is_modifier && !selection_modifiers_only && !is_ctrl_pressed) -> allows hovering on selected modifiers belonging to selection of type Instance
|
||||
bool select = (!volume.selected || (volume.is_modifier && !selection_modifiers_only && !ctrl_pressed)) && !alt_pressed;
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
|
||||
if (select || deselect) {
|
||||
bool as_volume =
|
||||
|
@ -7280,7 +7371,7 @@ void GLCanvas3D::_update_selection_from_hover()
|
|||
bool ctrl_pressed = wxGetKeyState(WXK_CONTROL);
|
||||
|
||||
if (m_hover_volume_idxs.empty()) {
|
||||
if (!ctrl_pressed && (m_rectangle_selection.get_state() == GLSelectionRectangle::Select))
|
||||
if (!ctrl_pressed && m_rectangle_selection.get_state() == GLSelectionRectangle::EState::Select)
|
||||
m_selection.remove_all();
|
||||
|
||||
return;
|
||||
|
@ -7297,7 +7388,10 @@ void GLCanvas3D::_update_selection_from_hover()
|
|||
}
|
||||
|
||||
bool selection_changed = false;
|
||||
if (state == GLSelectionRectangle::Select) {
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (!m_rectangle_selection.is_empty()) {
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
if (state == GLSelectionRectangle::EState::Select) {
|
||||
bool contains_all = true;
|
||||
for (int i : m_hover_volume_idxs) {
|
||||
if (!m_selection.contains_volume((unsigned int)i)) {
|
||||
|
@ -7308,7 +7402,7 @@ void GLCanvas3D::_update_selection_from_hover()
|
|||
|
||||
// the selection is going to be modified (Add)
|
||||
if (!contains_all) {
|
||||
wxGetApp().plater()->take_snapshot(_(L("Selection-Add from rectangle")), UndoRedo::SnapshotType::Selection);
|
||||
wxGetApp().plater()->take_snapshot(_L("Selection-Add from rectangle"), UndoRedo::SnapshotType::Selection);
|
||||
selection_changed = true;
|
||||
}
|
||||
}
|
||||
|
@ -7323,21 +7417,24 @@ void GLCanvas3D::_update_selection_from_hover()
|
|||
|
||||
// the selection is going to be modified (Remove)
|
||||
if (contains_any) {
|
||||
wxGetApp().plater()->take_snapshot(_(L("Selection-Remove from rectangle")), UndoRedo::SnapshotType::Selection);
|
||||
wxGetApp().plater()->take_snapshot(_L("Selection-Remove from rectangle"), UndoRedo::SnapshotType::Selection);
|
||||
selection_changed = true;
|
||||
}
|
||||
}
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
}
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
|
||||
if (!selection_changed)
|
||||
return;
|
||||
|
||||
Plater::SuppressSnapshots suppress(wxGetApp().plater());
|
||||
|
||||
if ((state == GLSelectionRectangle::Select) && !ctrl_pressed)
|
||||
if (state == GLSelectionRectangle::EState::Select && !ctrl_pressed)
|
||||
m_selection.clear();
|
||||
|
||||
for (int i : m_hover_volume_idxs) {
|
||||
if (state == GLSelectionRectangle::Select) {
|
||||
if (state == GLSelectionRectangle::EState::Select) {
|
||||
if (hover_modifiers_only) {
|
||||
const GLVolume& v = *m_volumes.volumes[i];
|
||||
m_selection.add_volume(v.object_idx(), v.volume_idx(), v.instance_idx(), false);
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
#include "3DScene.hpp"
|
||||
#include "GUI_App.hpp"
|
||||
#include "GLShader.hpp"
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
#include "Plater.hpp"
|
||||
#include "GLCanvas3D.hpp"
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
|
@ -13,6 +17,10 @@
|
|||
#include "libslic3r/Geometry/ConvexHull.hpp"
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
#include <imgui/imgui_internal.h>
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
|
@ -380,6 +388,10 @@ size_t GLModel::Geometry::indices_count() const
|
|||
}
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
GLModel::Statistics GLModel::s_statistics;
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
void GLModel::init_from(Geometry&& data)
|
||||
#else
|
||||
|
@ -702,10 +714,16 @@ void GLModel::reset()
|
|||
if (m_render_data.ibo_id > 0) {
|
||||
glsafe(::glDeleteBuffers(1, &m_render_data.ibo_id));
|
||||
m_render_data.ibo_id = 0;
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
s_statistics.gpu_memory.indices.current -= indices_size_bytes();
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
}
|
||||
if (m_render_data.vbo_id > 0) {
|
||||
glsafe(::glDeleteBuffers(1, &m_render_data.vbo_id));
|
||||
m_render_data.vbo_id = 0;
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
s_statistics.gpu_memory.vertices.current -= vertices_size_bytes();
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
}
|
||||
|
||||
m_render_data.vertices_count = 0;
|
||||
|
@ -899,6 +917,10 @@ void GLModel::render(const std::pair<size_t, size_t>& range)
|
|||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
++s_statistics.render_calls;
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
}
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
|
@ -1054,6 +1076,10 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance
|
|||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
++s_statistics.render_instanced_calls;
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
}
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
@ -1076,6 +1102,10 @@ bool GLModel::send_to_gpu()
|
|||
glsafe(::glBufferData(GL_ARRAY_BUFFER, data.vertices_size_bytes(), data.vertices.data(), GL_STATIC_DRAW));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
m_render_data.vertices_count = vertices_count();
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
s_statistics.gpu_memory.vertices.current += data.vertices_size_bytes();
|
||||
s_statistics.gpu_memory.vertices.max = std::max(s_statistics.gpu_memory.vertices.current, s_statistics.gpu_memory.vertices.max);
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
data.vertices = std::vector<float>();
|
||||
|
||||
// indices
|
||||
|
@ -1107,10 +1137,75 @@ bool GLModel::send_to_gpu()
|
|||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
}
|
||||
m_render_data.indices_count = indices_count;
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
s_statistics.gpu_memory.indices.current += data.indices_size_bytes();
|
||||
s_statistics.gpu_memory.indices.max = std::max(s_statistics.gpu_memory.indices.current, s_statistics.gpu_memory.indices.max);
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
data.indices = std::vector<unsigned int>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
void GLModel::render_statistics()
|
||||
{
|
||||
static const float offset = 175.0f;
|
||||
ImGuiWrapper& imgui = *wxGetApp().imgui();
|
||||
|
||||
auto add_memory = [&imgui](const std::string& label, int64_t memory) {
|
||||
auto format_string = [memory](const std::string& units, float value) {
|
||||
return std::to_string(memory) + " bytes (" +
|
||||
Slic3r::float_to_string_decimal_point(float(memory) * value, 3)
|
||||
+ " " + units + ")";
|
||||
};
|
||||
|
||||
static const float kb = 1024.0f;
|
||||
static const float inv_kb = 1.0f / kb;
|
||||
static const float mb = 1024.0f * kb;
|
||||
static const float inv_mb = 1.0f / mb;
|
||||
static const float gb = 1024.0f * mb;
|
||||
static const float inv_gb = 1.0f / gb;
|
||||
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
|
||||
ImGui::SameLine(offset);
|
||||
if (static_cast<float>(memory) < mb)
|
||||
imgui.text(format_string("KB", inv_kb));
|
||||
else if (static_cast<float>(memory) < gb)
|
||||
imgui.text(format_string("MB", inv_mb));
|
||||
else
|
||||
imgui.text(format_string("GB", inv_gb));
|
||||
};
|
||||
|
||||
auto add_counter = [&imgui](const std::string& label, int64_t counter) {
|
||||
imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, label);
|
||||
ImGui::SameLine(offset);
|
||||
imgui.text(std::to_string(counter));
|
||||
};
|
||||
|
||||
imgui.set_next_window_pos(0.5f * wxGetApp().plater()->get_current_canvas3D()->get_canvas_size().get_width(), 0.0f, ImGuiCond_Once, 0.5f, 0.0f);
|
||||
ImGui::SetNextWindowSizeConstraints({ 300.0f, 100.0f }, { 600.0f, 900.0f });
|
||||
imgui.begin(std::string("GLModel Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize);
|
||||
ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
|
||||
|
||||
add_counter(std::string("Render calls:"), s_statistics.render_calls);
|
||||
add_counter(std::string("Render instanced calls:"), s_statistics.render_instanced_calls);
|
||||
|
||||
if (ImGui::CollapsingHeader("GPU memory")) {
|
||||
ImGui::Indent(10.0f);
|
||||
if (ImGui::CollapsingHeader("Vertices")) {
|
||||
add_memory(std::string("Current:"), s_statistics.gpu_memory.vertices.current);
|
||||
add_memory(std::string("Max:"), s_statistics.gpu_memory.vertices.max);
|
||||
}
|
||||
if (ImGui::CollapsingHeader("Indices")) {
|
||||
add_memory(std::string("Current:"), s_statistics.gpu_memory.indices.current);
|
||||
add_memory(std::string("Max:"), s_statistics.gpu_memory.indices.max);
|
||||
}
|
||||
ImGui::Unindent(10.0f);
|
||||
}
|
||||
|
||||
imgui.end();
|
||||
}
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
|
||||
#else
|
||||
void GLModel::send_to_gpu(RenderData& data, const std::vector<float>& vertices, const std::vector<unsigned int>& indices)
|
||||
{
|
||||
|
|
|
@ -177,6 +177,29 @@ namespace GUI {
|
|||
|
||||
private:
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
struct Statistics
|
||||
{
|
||||
struct Buffers
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
size_t current{ 0 };
|
||||
size_t max{ 0 };
|
||||
};
|
||||
Data indices;
|
||||
Data vertices;
|
||||
};
|
||||
|
||||
Buffers gpu_memory;
|
||||
|
||||
int64_t render_calls{ 0 };
|
||||
int64_t render_instanced_calls{ 0 };
|
||||
};
|
||||
|
||||
static Statistics s_statistics;
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
|
||||
RenderData m_render_data;
|
||||
|
||||
// By default the vertex and index buffers data are sent to gpu at the first call to render() method.
|
||||
|
@ -272,6 +295,14 @@ namespace GUI {
|
|||
ret += indices_size_bytes();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if ENABLE_GLMODEL_STATISTICS
|
||||
static void render_statistics();
|
||||
static void reset_statistics_counters() {
|
||||
s_statistics.render_calls = 0;
|
||||
s_statistics.render_instanced_calls = 0;
|
||||
}
|
||||
#endif // ENABLE_GLMODEL_STATISTICS
|
||||
#endif // ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,12 +13,12 @@ namespace GUI {
|
|||
|
||||
void GLSelectionRectangle::start_dragging(const Vec2d& mouse_position, EState state)
|
||||
{
|
||||
if (is_dragging() || (state == Off))
|
||||
if (is_dragging() || state == EState::Off)
|
||||
return;
|
||||
|
||||
m_state = state;
|
||||
m_start_corner = mouse_position;
|
||||
m_end_corner = mouse_position;
|
||||
m_end_corner = mouse_position;
|
||||
}
|
||||
|
||||
void GLSelectionRectangle::dragging(const Vec2d& mouse_position)
|
||||
|
@ -36,7 +36,7 @@ namespace GUI {
|
|||
if (!is_dragging())
|
||||
return out;
|
||||
|
||||
m_state = Off;
|
||||
m_state = EState::Off;
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Matrix4d modelview = camera.get_view_matrix().matrix();
|
||||
|
@ -66,7 +66,7 @@ namespace GUI {
|
|||
void GLSelectionRectangle::stop_dragging()
|
||||
{
|
||||
if (is_dragging())
|
||||
m_state = Off;
|
||||
m_state = EState::Off;
|
||||
}
|
||||
|
||||
void GLSelectionRectangle::render(const GLCanvas3D& canvas)
|
||||
|
@ -108,8 +108,8 @@ namespace GUI {
|
|||
glsafe(::glLineWidth(1.5f));
|
||||
#if !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
float color[3];
|
||||
color[0] = (m_state == Select) ? 0.3f : 1.0f;
|
||||
color[1] = (m_state == Select) ? 1.0f : 0.3f;
|
||||
color[0] = (m_state == EState::Select) ? 0.3f : 1.0f;
|
||||
color[1] = (m_state == EState::Select) ? 1.0f : 0.3f;
|
||||
color[2] = 0.3f;
|
||||
glsafe(::glColor3fv(color));
|
||||
#endif // !ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
@ -169,7 +169,7 @@ namespace GUI {
|
|||
shader->set_uniform("projection_matrix", Transform3d::Identity());
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
m_rectangle.set_color(ColorRGBA((m_state == Select) ? 0.3f : 1.0f, (m_state == Select) ? 1.0f : 0.3f, 0.3f, 1.0f));
|
||||
m_rectangle.set_color(ColorRGBA((m_state == EState::Select) ? 0.3f : 1.0f, (m_state == EState::Select) ? 1.0f : 0.3f, 0.3f, 1.0f));
|
||||
m_rectangle.render();
|
||||
shader->stop_using();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ class GLCanvas3D;
|
|||
|
||||
class GLSelectionRectangle {
|
||||
public:
|
||||
enum EState {
|
||||
enum class EState {
|
||||
Off,
|
||||
Select,
|
||||
Deselect
|
||||
|
@ -35,7 +35,11 @@ public:
|
|||
|
||||
void render(const GLCanvas3D& canvas);
|
||||
|
||||
bool is_dragging() const { return m_state != Off; }
|
||||
bool is_dragging() const { return m_state != EState::Off; }
|
||||
#if ENABLE_NEW_RECTANGLE_SELECTION
|
||||
bool is_empty() const { return m_state == EState::Off || m_start_corner.isApprox(m_end_corner); }
|
||||
#endif // ENABLE_NEW_RECTANGLE_SELECTION
|
||||
|
||||
EState get_state() const { return m_state; }
|
||||
|
||||
float get_width() const { return std::abs(m_start_corner.x() - m_end_corner.x()); }
|
||||
|
@ -46,7 +50,7 @@ public:
|
|||
float get_bottom() const { return std::min(m_start_corner.y(), m_end_corner.y()); }
|
||||
|
||||
private:
|
||||
EState m_state{ Off };
|
||||
EState m_state{ EState::Off };
|
||||
Vec2d m_start_corner{ Vec2d::Zero() };
|
||||
Vec2d m_end_corner{ Vec2d::Zero() };
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
|
|
|
@ -122,8 +122,7 @@ bool GLShaderProgram::init_from_texts(const std::string& name, const ShaderSourc
|
|||
|
||||
for (size_t i = 0; i < static_cast<size_t>(EShaderType::Count); ++i) {
|
||||
const std::string& source = sources[i];
|
||||
if (!source.empty())
|
||||
{
|
||||
if (!source.empty()) {
|
||||
EShaderType type = static_cast<EShaderType>(i);
|
||||
auto [result, id] = create_shader(type);
|
||||
if (result)
|
||||
|
@ -303,6 +302,19 @@ void GLShaderProgram::set_uniform(int id, const Matrix3d& value) const
|
|||
}
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
void GLShaderProgram::set_uniform(int id, const Matrix4f& value) const
|
||||
{
|
||||
if (id >= 0)
|
||||
glsafe(::glUniformMatrix4fv(id, 1, GL_FALSE, static_cast<const GLfloat*>(value.data())));
|
||||
}
|
||||
|
||||
void GLShaderProgram::set_uniform(int id, const Matrix4d& value) const
|
||||
{
|
||||
set_uniform(id, (Matrix4f)value.cast<float>());
|
||||
}
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
|
||||
void GLShaderProgram::set_uniform(int id, const Vec3f& value) const
|
||||
{
|
||||
if (id >= 0)
|
||||
|
|
|
@ -64,6 +64,10 @@ public:
|
|||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
void set_uniform(const char* name, const Matrix3d& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
void set_uniform(const char* name, const Matrix4f& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const Matrix4d& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
void set_uniform(const char* name, const Vec3f& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const Vec3d& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
void set_uniform(const char* name, const ColorRGB& value) const { set_uniform(get_uniform_location(name), value); }
|
||||
|
@ -86,6 +90,10 @@ public:
|
|||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
void set_uniform(int id, const Matrix3d& value) const;
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
void set_uniform(int id, const Matrix4f& value) const;
|
||||
void set_uniform(int id, const Matrix4d& value) const;
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
void set_uniform(int id, const Vec3f& value) const;
|
||||
void set_uniform(int id, const Vec3d& value) const;
|
||||
void set_uniform(int id, const ColorRGB& value) const;
|
||||
|
|
|
@ -35,6 +35,8 @@ std::pair<bool, std::string> GLShadersManager::init()
|
|||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
// imgui shader
|
||||
valid &= append_shader("imgui", { "imgui.vs", "imgui.fs" });
|
||||
// basic shader, used to render all what was previously rendered using the immediate mode
|
||||
valid &= append_shader("flat_attr", { "flat_attr.vs", "flat.fs" });
|
||||
// basic shader for textures, used to render textures
|
||||
|
|
|
@ -293,7 +293,7 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
|
|||
if (action == SLAGizmoEventType::LeftDown && (shift_down || alt_down || control_down)) {
|
||||
if (m_hover_id == -1) {
|
||||
if (shift_down || alt_down) {
|
||||
m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::Select : GLSelectionRectangle::Deselect);
|
||||
m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::EState::Select : GLSelectionRectangle::EState::Deselect);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -359,7 +359,7 @@ bool GLGizmoHollow::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_pos
|
|||
trafo, wxGetApp().plater()->get_camera(), points_inside,
|
||||
m_c->object_clipper()->get_clipping_plane()))
|
||||
{
|
||||
if (rectangle_status == GLSelectionRectangle::Deselect)
|
||||
if (rectangle_status == GLSelectionRectangle::EState::Deselect)
|
||||
unselect_point(points_idxs[idx]);
|
||||
else
|
||||
select_point(points_idxs[idx]);
|
||||
|
|
|
@ -600,11 +600,17 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
|
|||
return;
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
assert(shader->get_name() == "mm_gouraud_attr");
|
||||
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * matrix;
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
shader->set_uniform("normal_matrix", (Matrix3d)view_model_matrix.matrix().block(0, 0, 3, 3).inverse().transpose());
|
||||
#else
|
||||
assert(shader->get_name() == "mm_gouraud");
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx)
|
||||
for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx) {
|
||||
if (m_gizmo_scene.has_VBOs(color_idx)) {
|
||||
if (color_idx > m_colors.size()) // Seed fill VBO
|
||||
shader->set_uniform("uniform_color", TriangleSelectorGUI::get_seed_fill_color(color_idx == (m_colors.size() + 1) ? m_default_volume_color : m_colors[color_idx - (m_colors.size() + 1) - 1]));
|
||||
|
@ -613,6 +619,7 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui)
|
|||
|
||||
m_gizmo_scene.render(color_idx);
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_LEGACY_OPENGL_REMOVAL
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
@ -724,19 +731,41 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const
|
|||
assert(this->vertices_VBO_id != 0);
|
||||
assert(this->triangle_indices_VBO_ids[triangle_indices_idx] != 0);
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
GLShaderProgram* shader = wxGetApp().get_current_shader();
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id));
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
const GLint position_id = shader->get_attrib_location("v_position");
|
||||
if (position_id != -1) {
|
||||
glsafe(::glVertexAttribPointer(position_id, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (GLvoid*)0));
|
||||
glsafe(::glEnableVertexAttribArray(position_id));
|
||||
}
|
||||
|
||||
// Render using the Vertex Buffer Objects.
|
||||
if (this->triangle_indices_VBO_ids[triangle_indices_idx] != 0 &&
|
||||
this->triangle_indices_sizes[triangle_indices_idx] > 0) {
|
||||
#else
|
||||
glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), (const void*)(0 * sizeof(float))));
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
|
||||
// Render using the Vertex Buffer Objects.
|
||||
if (this->triangle_indices_sizes[triangle_indices_idx] > 0) {
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->triangle_indices_VBO_ids[triangle_indices_idx]));
|
||||
glsafe(::glDrawElements(GL_TRIANGLES, GLsizei(this->triangle_indices_sizes[triangle_indices_idx]), GL_UNSIGNED_INT, nullptr));
|
||||
glsafe(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
#else
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
|
|
@ -195,8 +195,7 @@ void GLGizmoRotate::on_render()
|
|||
|
||||
#if ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||
Transform3d view_model_matrix = camera.get_view_matrix() * m_grabbers.front().matrix;
|
||||
|
||||
const Transform3d view_model_matrix = camera.get_view_matrix() * m_grabbers.front().matrix;
|
||||
shader->set_uniform("view_model_matrix", view_model_matrix);
|
||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||
#endif // ENABLE_GL_SHADERS_ATTRIBUTES
|
||||
|
|
|
@ -419,7 +419,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
if (action == SLAGizmoEventType::LeftDown && (shift_down || alt_down || control_down)) {
|
||||
if (m_hover_id == -1) {
|
||||
if (shift_down || alt_down) {
|
||||
m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::Select : GLSelectionRectangle::Deselect);
|
||||
m_selection_rectangle.start_dragging(mouse_position, shift_down ? GLSelectionRectangle::EState::Select : GLSelectionRectangle::EState::Deselect);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -490,7 +490,7 @@ bool GLGizmoSlaSupports::gizmo_event(SLAGizmoEventType action, const Vec2d& mous
|
|||
{
|
||||
if (idx >= orig_pts_num) // this is a cone-base, get index of point it belongs to
|
||||
idx -= orig_pts_num;
|
||||
if (rectangle_status == GLSelectionRectangle::Deselect)
|
||||
if (rectangle_status == GLSelectionRectangle::EState::Deselect)
|
||||
unselect_point(points_idxs[idx]);
|
||||
else
|
||||
select_point(points_idxs[idx]);
|
||||
|
|
|
@ -26,13 +26,18 @@
|
|||
#include "libslic3r/libslic3r.h"
|
||||
#include "libslic3r/Utils.hpp"
|
||||
#include "libslic3r/Color.hpp"
|
||||
|
||||
#include "3DScene.hpp"
|
||||
#include "GUI.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "Search.hpp"
|
||||
#include "BitmapCache.hpp"
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
#include "GUI_App.hpp"
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
|
||||
#include "../Utils/MacDarkMode.hpp"
|
||||
|
||||
#include "nanosvg/nanosvg.h"
|
||||
#include "nanosvg/nanosvgrast.h"
|
||||
|
||||
|
@ -1442,13 +1447,31 @@ void ImGuiWrapper::init_style()
|
|||
|
||||
void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
|
||||
{
|
||||
if (draw_data == nullptr || draw_data->CmdListsCount == 0)
|
||||
return;
|
||||
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
GLShaderProgram* shader = wxGetApp().get_shader("imgui");
|
||||
if (shader == nullptr)
|
||||
return;
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
const int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x);
|
||||
const int fb_width = (int)(draw_data->DisplaySize.x * io.DisplayFramebufferScale.x);
|
||||
const int fb_height = (int)(draw_data->DisplaySize.y * io.DisplayFramebufferScale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
GLShaderProgram* curr_shader = wxGetApp().get_current_shader();
|
||||
if (curr_shader != nullptr)
|
||||
curr_shader->stop_using();
|
||||
|
||||
shader->start_using();
|
||||
#else
|
||||
draw_data->ScaleClipRects(io.DisplayFramebufferScale);
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
|
||||
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
|
||||
// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
|
||||
|
@ -1456,25 +1479,43 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
|
|||
GLint last_polygon_mode[2]; glsafe(::glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode));
|
||||
GLint last_viewport[4]; glsafe(::glGetIntegerv(GL_VIEWPORT, last_viewport));
|
||||
GLint last_scissor_box[4]; glsafe(::glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box));
|
||||
GLint last_texture_env_mode; glsafe(::glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_texture_env_mode));
|
||||
glsafe(::glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT));
|
||||
glsafe(::glEnable(GL_BLEND));
|
||||
glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
glsafe(::glDisable(GL_CULL_FACE));
|
||||
glsafe(::glDisable(GL_DEPTH_TEST));
|
||||
glsafe(::glEnable(GL_SCISSOR_TEST));
|
||||
#if !ENABLE_GL_IMGUI_SHADERS
|
||||
glsafe(::glDisable(GL_LIGHTING));
|
||||
glsafe(::glDisable(GL_COLOR_MATERIAL));
|
||||
glsafe(::glEnable(GL_SCISSOR_TEST));
|
||||
glsafe(::glEnableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
glsafe(::glEnableClientState(GL_COLOR_ARRAY));
|
||||
#endif // !ENABLE_GL_IMGUI_SHADERS
|
||||
glsafe(::glEnable(GL_TEXTURE_2D));
|
||||
glsafe(::glPolygonMode(GL_FRONT_AND_BACK, GL_FILL));
|
||||
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
|
||||
GLint texture_env_mode = GL_MODULATE;
|
||||
glsafe(::glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texture_env_mode));
|
||||
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
|
||||
//glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound
|
||||
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
glsafe(::glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
||||
const float L = draw_data->DisplayPos.x;
|
||||
const float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
const float T = draw_data->DisplayPos.y;
|
||||
const float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
|
||||
Matrix4f ortho_projection;
|
||||
ortho_projection <<
|
||||
2.0f / (R - L), 0.0f, 0.0f, (R + L) / (L - R),
|
||||
0.0f, 2.0f / (T - B), 0.0f, (T + B) / (B - T),
|
||||
0.0f, 0.0f, -1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f;
|
||||
|
||||
shader->set_uniform("Texture", 0);
|
||||
shader->set_uniform("ProjMtx", ortho_projection);
|
||||
#else
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps.
|
||||
glsafe(::glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
||||
|
@ -1485,16 +1526,55 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
|
|||
glsafe(::glMatrixMode(GL_MODELVIEW));
|
||||
glsafe(::glPushMatrix());
|
||||
glsafe(::glLoadIdentity());
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
const ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
const ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
#else
|
||||
const ImVec2 pos = draw_data->DisplayPos;
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
|
||||
// Render command lists
|
||||
ImVec2 pos = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; ++n) {
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||
const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
||||
|
||||
GLuint vbo_id;
|
||||
glsafe(::glGenBuffers(1, &vbo_id));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, vbo_id));
|
||||
glsafe(::glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, vtx_buffer, GL_STATIC_DRAW));
|
||||
|
||||
GLuint ibo_id;
|
||||
glsafe(::glGenBuffers(1, &ibo_id));
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id));
|
||||
glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, idx_buffer, GL_STATIC_DRAW));
|
||||
|
||||
const int position_id = shader->get_attrib_location("Position");
|
||||
if (position_id != -1) {
|
||||
glsafe(::glVertexAttribPointer(position_id, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)));
|
||||
glsafe(::glEnableVertexAttribArray(position_id));
|
||||
}
|
||||
const int uv_id = shader->get_attrib_location("UV");
|
||||
if (uv_id != -1) {
|
||||
glsafe(::glVertexAttribPointer(uv_id, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)));
|
||||
glsafe(::glEnableVertexAttribArray(uv_id));
|
||||
}
|
||||
const int color_id = shader->get_attrib_location("Color");
|
||||
if (color_id != -1) {
|
||||
glsafe(::glVertexAttribPointer(color_id, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)));
|
||||
glsafe(::glEnableVertexAttribArray(color_id));
|
||||
}
|
||||
#else
|
||||
glsafe(::glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos))));
|
||||
glsafe(::glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv))));
|
||||
glsafe(::glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col))));
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; ++cmd_i) {
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
|
@ -1502,34 +1582,71 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
|
|||
// User callback (registered via ImDrawList::AddCallback)
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
else {
|
||||
ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y);
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
const ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
const ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle (Y is inverted in OpenGL)
|
||||
glsafe(::glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)));
|
||||
|
||||
// Bind texture, Draw
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()));
|
||||
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))));
|
||||
#else
|
||||
const ImVec4 clip_rect = ImVec4(pcmd->ClipRect.x - pos.x, pcmd->ClipRect.y - pos.y, pcmd->ClipRect.z - pos.x, pcmd->ClipRect.w - pos.y);
|
||||
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f) {
|
||||
// Apply scissor/clipping rectangle
|
||||
glsafe(::glScissor((int)clip_rect.x, (int)(fb_height - clip_rect.w), (int)(clip_rect.z - clip_rect.x), (int)(clip_rect.w - clip_rect.y)));
|
||||
|
||||
// Bind texture, Draw
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId));
|
||||
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()));
|
||||
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))));
|
||||
}
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
}
|
||||
idx_buffer += pcmd->ElemCount;
|
||||
}
|
||||
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
if (position_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(position_id));
|
||||
if (uv_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(uv_id));
|
||||
if (color_id != -1)
|
||||
glsafe(::glDisableVertexAttribArray(color_id));
|
||||
|
||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0));
|
||||
|
||||
glsafe(::glDeleteBuffers(1, &ibo_id));
|
||||
glsafe(::glDeleteBuffers(1, &vbo_id));
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
}
|
||||
|
||||
// Restore modified state
|
||||
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texture_env_mode));
|
||||
glsafe(::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_texture_env_mode));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture));
|
||||
#if !ENABLE_GL_IMGUI_SHADERS
|
||||
glsafe(::glDisableClientState(GL_COLOR_ARRAY));
|
||||
glsafe(::glDisableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
glsafe(::glDisableClientState(GL_VERTEX_ARRAY));
|
||||
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)last_texture));
|
||||
glsafe(::glMatrixMode(GL_MODELVIEW));
|
||||
glsafe(::glPopMatrix());
|
||||
glsafe(::glMatrixMode(GL_PROJECTION));
|
||||
glsafe(::glPopMatrix());
|
||||
#endif // !ENABLE_GL_IMGUI_SHADERS
|
||||
glsafe(::glPopAttrib());
|
||||
glsafe(::glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]));
|
||||
glsafe(::glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]));
|
||||
glsafe(::glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]));
|
||||
|
||||
#if ENABLE_GL_IMGUI_SHADERS
|
||||
if (curr_shader != nullptr)
|
||||
curr_shader->start_using();
|
||||
#endif // ENABLE_GL_IMGUI_SHADERS
|
||||
}
|
||||
|
||||
bool ImGuiWrapper::display_initialized() const
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue