Optimization of G-code rendering, may improve speed issues mentioned in #7415
This commit is contained in:
parent
68d5a47121
commit
c37090a64d
@ -2636,12 +2636,7 @@ void GCodeViewer::render_toolpaths()
|
|||||||
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())))) :
|
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;
|
static_cast<float>(viewport[3]) * 0.0005;
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
auto shader_init_as_points = [zoom, point_size, near_plane_height](GLShaderProgram& shader) {
|
||||||
auto render_as_points = [this, zoom, point_size, near_plane_height]
|
|
||||||
#else
|
|
||||||
auto render_as_points = [zoom, point_size, near_plane_height]
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
(const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
|
||||||
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
#if ENABLE_FIXED_SCREEN_SIZE_POINT_MARKERS
|
||||||
shader.set_uniform("use_fixed_screen_size", 1);
|
shader.set_uniform("use_fixed_screen_size", 1);
|
||||||
#else
|
#else
|
||||||
@ -2652,65 +2647,67 @@ void GCodeViewer::render_toolpaths()
|
|||||||
shader.set_uniform("percent_center_radius", 0.33f);
|
shader.set_uniform("percent_center_radius", 0.33f);
|
||||||
shader.set_uniform("point_size", point_size);
|
shader.set_uniform("point_size", point_size);
|
||||||
shader.set_uniform("near_plane_height", near_plane_height);
|
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<const RenderPath*>::iterator it_path, std::vector<const RenderPath*>::iterator it_end, GLShaderProgram& shader, int uniform_color) {
|
||||||
glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||||
glsafe(::glEnable(GL_POINT_SPRITE));
|
glsafe(::glEnable(GL_POINT_SPRITE));
|
||||||
|
|
||||||
for (const RenderPath& path : buffer.render_paths) {
|
for (auto it = it_path; it != it_end && (*it_path)->ibuffer_id == (*it)->ibuffer_id; ++ it) {
|
||||||
if (path.ibuffer_id == ibuffer_id) {
|
const RenderPath& path = **it;
|
||||||
shader.set_uniform("uniform_color", path.color);
|
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
|
||||||
glsafe(::glMultiDrawElements(GL_POINTS, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
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
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
++m_statistics.gl_multi_points_calls_count;
|
++m_statistics.gl_multi_points_calls_count;
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
glsafe(::glDisable(GL_POINT_SPRITE));
|
glsafe(::glDisable(GL_POINT_SPRITE));
|
||||||
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
|
||||||
auto render_as_lines = [this, light_intensity]
|
|
||||||
#else
|
|
||||||
auto render_as_lines = [light_intensity]
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
(const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
|
||||||
shader.set_uniform("light_intensity", light_intensity);
|
shader.set_uniform("light_intensity", light_intensity);
|
||||||
for (const RenderPath& path : buffer.render_paths) {
|
};
|
||||||
if (path.ibuffer_id == ibuffer_id) {
|
auto render_as_lines = [
|
||||||
shader.set_uniform("uniform_color", path.color);
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
|
this
|
||||||
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
|
](std::vector<const RenderPath*>::iterator it_path, std::vector<const RenderPath*>::iterator it_end, GLShaderProgram &shader, int uniform_color) {
|
||||||
|
for (auto it = it_path; it != it_end && (*it_path)->ibuffer_id == (*it)->ibuffer_id; ++it) {
|
||||||
|
const RenderPath& path = **it;
|
||||||
|
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
|
||||||
glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
glsafe(::glMultiDrawElements(GL_LINES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
++m_statistics.gl_multi_lines_calls_count;
|
++m_statistics.gl_multi_lines_calls_count;
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto render_as_triangles = [
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
auto render_as_triangles = [this]
|
this
|
||||||
#else
|
|
||||||
auto render_as_triangles = []
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
(const TBuffer& buffer, unsigned int ibuffer_id, GLShaderProgram& shader) {
|
](std::vector<const RenderPath*>::iterator it_path, std::vector<const RenderPath*>::iterator it_end, GLShaderProgram &shader, int uniform_color) {
|
||||||
for (const RenderPath& path : buffer.render_paths) {
|
for (auto it = it_path; it != it_end && (*it_path)->ibuffer_id == (*it)->ibuffer_id; ++it) {
|
||||||
if (path.ibuffer_id == ibuffer_id) {
|
const RenderPath& path = **it;
|
||||||
shader.set_uniform("uniform_color", path.color);
|
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat*>(path.color.data())));
|
||||||
glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
glsafe(::glMultiDrawElements(GL_TRIANGLES, (const GLsizei*)path.sizes.data(), GL_UNSIGNED_SHORT, (const void* const*)path.offsets.data(), (GLsizei)path.sizes.size()));
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
++m_statistics.gl_multi_triangles_calls_count;
|
++m_statistics.gl_multi_triangles_calls_count;
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto render_as_instanced_model = [
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
auto render_as_instanced_model = [this]
|
this
|
||||||
#else
|
|
||||||
auto render_as_instanced_model = []
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
(TBuffer& buffer, GLShaderProgram & shader) {
|
](TBuffer& buffer, GLShaderProgram & shader) {
|
||||||
for (auto& range : buffer.model.instances.render_ranges.ranges) {
|
for (auto& range : buffer.model.instances.render_ranges.ranges) {
|
||||||
if (range.vbo == 0 && range.count > 0) {
|
if (range.vbo == 0 && range.count > 0) {
|
||||||
glsafe(::glGenBuffers(1, &range.vbo));
|
glsafe(::glGenBuffers(1, &range.vbo));
|
||||||
@ -2815,8 +2812,27 @@ void GCodeViewer::render_toolpaths()
|
|||||||
shader->set_uniform("emission_factor", 0.0f);
|
shader->set_uniform("emission_factor", 0.0f);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (size_t j = 0; j < buffer.indices.size(); ++j) {
|
switch (buffer.render_primitive_type) {
|
||||||
const IBuffer& i_buffer = buffer.indices[j];
|
case TBuffer::ERenderPrimitiveType::Point: shader_init_as_points(*shader); break;
|
||||||
|
case TBuffer::ERenderPrimitiveType::Line: shader_init_as_lines(*shader); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
int uniform_color = shader->get_uniform_location("uniform_color");
|
||||||
|
// Render paths are sorted by ibuffer_id.
|
||||||
|
std::vector<const RenderPath*> paths;
|
||||||
|
paths.reserve(buffer.render_paths.size());
|
||||||
|
for (const RenderPath& path : buffer.render_paths)
|
||||||
|
paths.emplace_back(&path);
|
||||||
|
std::stable_sort(paths.begin(), paths.end(), [](const auto* l, const auto* r){ return l->ibuffer_id < r->ibuffer_id; });
|
||||||
|
//FIXME maybe std::sort would suffice?
|
||||||
|
auto it_path = paths.begin();
|
||||||
|
for (unsigned int ibuffer_id = 0; ibuffer_id < static_cast<unsigned int>(buffer.indices.size()); ++ibuffer_id) {
|
||||||
|
const IBuffer& i_buffer = buffer.indices[ibuffer_id];
|
||||||
|
// Skip all paths with ibuffer_id < ibuffer_id.
|
||||||
|
for (; it_path != paths.end() && (*it_path)->ibuffer_id < ibuffer_id; ++ it_path) ;
|
||||||
|
if (it_path == paths.end() || (*it_path)->ibuffer_id > ibuffer_id)
|
||||||
|
// Not found. This shall not happen.
|
||||||
|
continue;
|
||||||
|
|
||||||
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
|
glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo));
|
||||||
glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
|
glsafe(::glVertexPointer(buffer.vertices.position_size_floats(), GL_FLOAT, buffer.vertices.vertex_size_bytes(), (const void*)buffer.vertices.position_offset_bytes()));
|
||||||
@ -2829,19 +2845,20 @@ void GCodeViewer::render_toolpaths()
|
|||||||
|
|
||||||
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
|
glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, i_buffer.ibo));
|
||||||
|
|
||||||
|
// Render all elements with it_path->ibuffer_id == ibuffer_id, possible with varying colors.
|
||||||
switch (buffer.render_primitive_type)
|
switch (buffer.render_primitive_type)
|
||||||
{
|
{
|
||||||
case TBuffer::ERenderPrimitiveType::Point: {
|
case TBuffer::ERenderPrimitiveType::Point: {
|
||||||
render_as_points(buffer, static_cast<unsigned int>(j), *shader);
|
render_as_points(it_path, paths.end(), *shader, uniform_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TBuffer::ERenderPrimitiveType::Line: {
|
case TBuffer::ERenderPrimitiveType::Line: {
|
||||||
glsafe(::glLineWidth(static_cast<GLfloat>(line_width(zoom))));
|
glsafe(::glLineWidth(static_cast<GLfloat>(line_width(zoom))));
|
||||||
render_as_lines(buffer, static_cast<unsigned int>(j), *shader);
|
render_as_lines(it_path, paths.end(), *shader, uniform_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TBuffer::ERenderPrimitiveType::Triangle: {
|
case TBuffer::ERenderPrimitiveType::Triangle: {
|
||||||
render_as_triangles(buffer, static_cast<unsigned int>(j), *shader);
|
render_as_triangles(it_path, paths.end(), *shader, uniform_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { break; }
|
default: { break; }
|
||||||
|
Loading…
Reference in New Issue
Block a user