mirror of
https://git.mirrors.martin98.com/https://github.com/bambulab/BambuStudio.git
synced 2025-09-28 15:43:16 +08:00
FIX:cancel glmultidraw or improved glmultidraw stability
jira: STUDIO-12202 Change-Id: I4ad99686b42125c998dfb1dfcf2c533a49375af0
This commit is contained in:
parent
c28e4be2ca
commit
3a8c7527c1
@ -195,6 +195,8 @@ void AppConfig::set_defaults()
|
|||||||
set_bool("user_bed_type", true);
|
set_bool("user_bed_type", true);
|
||||||
if (get("grabber_size_factor").empty())
|
if (get("grabber_size_factor").empty())
|
||||||
set("grabber_size_factor", "1.0");
|
set("grabber_size_factor", "1.0");
|
||||||
|
if (get("cancel_glmultidraw").empty())
|
||||||
|
set_bool("cancel_glmultidraw", false);
|
||||||
//#ifdef SUPPORT_SHOW_HINTS
|
//#ifdef SUPPORT_SHOW_HINTS
|
||||||
if (get("show_hints").empty())
|
if (get("show_hints").empty())
|
||||||
set_bool("show_hints", false);
|
set_bool("show_hints", false);
|
||||||
|
@ -1375,7 +1375,7 @@ static void debug_calibration_output_thumbnail(const ThumbnailData& thumbnail_da
|
|||||||
image.SaveFile("D:/calibrate.png", wxBITMAP_TYPE_PNG);
|
image.SaveFile("D:/calibrate.png", wxBITMAP_TYPE_PNG);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
const int MAX_DRAWS_PER_BATCH = 1024;
|
||||||
void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager)
|
void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnail_data, const ThumbnailsParams& thumbnail_params, PartPlateList& partplate_list, OpenGLManager& opengl_manager)
|
||||||
{
|
{
|
||||||
int plate_idx = thumbnail_params.plate_id;
|
int plate_idx = thumbnail_params.plate_id;
|
||||||
@ -1395,24 +1395,6 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||||||
camera.zoom_to_box(plate_box, 1.0f);
|
camera.zoom_to_box(plate_box, 1.0f);
|
||||||
camera.apply_projection(plate_box);
|
camera.apply_projection(plate_box);
|
||||||
|
|
||||||
auto render_as_triangles = [
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
this
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
](TBuffer &buffer, std::vector<RenderPath>::iterator it_path, std::vector<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;
|
|
||||||
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
|
|
||||||
assert(!path.sizes.empty());
|
|
||||||
assert(!path.offsets.empty());
|
|
||||||
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()));
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
++m_statistics.gl_multi_triangles_calls_count;
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto render_as_instanced_model = [
|
auto render_as_instanced_model = [
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
this
|
this
|
||||||
@ -1564,7 +1546,7 @@ void GCodeViewer::_render_calibration_thumbnail_internal(ThumbnailData& thumbnai
|
|||||||
switch (buffer.render_primitive_type)
|
switch (buffer.render_primitive_type)
|
||||||
{
|
{
|
||||||
case TBuffer::ERenderPrimitiveType::Triangle: {
|
case TBuffer::ERenderPrimitiveType::Triangle: {
|
||||||
render_as_triangles(buffer, it_path, buffer.render_paths.end(), *shader, uniform_color);
|
render_sub_paths(it_path, buffer.render_paths.end(), *shader, uniform_color, (unsigned int) EDrawPrimitiveType::Triangles);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { break; }
|
default: { break; }
|
||||||
@ -3891,6 +3873,46 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool
|
|||||||
statistics->refresh_paths_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start_time).count();
|
statistics->refresh_paths_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start_time).count();
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
}
|
}
|
||||||
|
template<typename Iterator>
|
||||||
|
void GCodeViewer::render_sub_paths(Iterator it_path, Iterator it_end, GLShaderProgram &shader, int uniform_color, unsigned int draw_type)
|
||||||
|
{
|
||||||
|
//std::vector<RenderPath>::iterator it_path, std::vector<RenderPath>::iterator it_end
|
||||||
|
if ((EDrawPrimitiveType) draw_type == EDrawPrimitiveType::Points) {
|
||||||
|
glsafe(::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||||
|
glsafe(::glEnable(GL_POINT_SPRITE));
|
||||||
|
}
|
||||||
|
bool cancel_glmultidraw = wxGetApp().get_opengl_manager()->get_cancle_glmultidraw();
|
||||||
|
for (auto it = it_path; it != it_end && it_path->ibuffer_id == it->ibuffer_id; ++it) {
|
||||||
|
const RenderPath &path = *it;
|
||||||
|
assert(!path.sizes.empty());
|
||||||
|
assert(!path.offsets.empty());
|
||||||
|
glsafe(::glUniform4fv(uniform_color, 1, static_cast<const GLfloat *>(path.color.data())));
|
||||||
|
if (cancel_glmultidraw) {
|
||||||
|
for (size_t i = 0; i < path.sizes.size(); ++i) {
|
||||||
|
GLsizei count = path.sizes[i];
|
||||||
|
glsafe(::glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (const void *) path.offsets[i]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int total_draws = path.sizes.size();
|
||||||
|
int number = path.sizes.size() / MAX_DRAWS_PER_BATCH + 1;
|
||||||
|
for (size_t batch = 0; batch < number; batch++) {
|
||||||
|
int start = batch * MAX_DRAWS_PER_BATCH;
|
||||||
|
int count = std::min(MAX_DRAWS_PER_BATCH, total_draws - start);
|
||||||
|
if (count == 0) { continue; }
|
||||||
|
glsafe(::glMultiDrawElements(OpenGLManager::get_draw_primitive_type((EDrawPrimitiveType)draw_type), (const GLsizei *) path.sizes.data() + start, GL_UNSIGNED_SHORT,
|
||||||
|
(const void *const *) (path.offsets.data() + start),
|
||||||
|
(GLsizei) count));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
|
++m_statistics.gl_multi_triangles_calls_count;
|
||||||
|
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
|
}
|
||||||
|
if ((EDrawPrimitiveType) draw_type == EDrawPrimitiveType::Points) {
|
||||||
|
glsafe(::glDisable(GL_POINT_SPRITE));
|
||||||
|
glsafe(::glDisable(GL_VERTEX_PROGRAM_POINT_SIZE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GCodeViewer::render_toolpaths()
|
void GCodeViewer::render_toolpaths()
|
||||||
{
|
{
|
||||||
@ -3919,68 +3941,10 @@ void GCodeViewer::render_toolpaths()
|
|||||||
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<RenderPath>::reverse_iterator it_path, std::vector<RenderPath>::reverse_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());
|
|
||||||
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()));
|
|
||||||
#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));
|
|
||||||
};
|
|
||||||
|
|
||||||
auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
|
auto shader_init_as_lines = [light_intensity](GLShaderProgram &shader) {
|
||||||
shader.set_uniform("light_intensity", light_intensity);
|
shader.set_uniform("light_intensity", light_intensity);
|
||||||
};
|
};
|
||||||
auto render_as_lines = [
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
this
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
](std::vector<RenderPath>::reverse_iterator it_path, std::vector<RenderPath>::reverse_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;
|
|
||||||
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
|
|
||||||
assert(! path.sizes.empty());
|
|
||||||
assert(! path.offsets.empty());
|
|
||||||
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()));
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
++m_statistics.gl_multi_lines_calls_count;
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto render_as_triangles = [
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
this
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
](std::vector<RenderPath>::reverse_iterator it_path, std::vector<RenderPath>::reverse_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;
|
|
||||||
// Some OpenGL drivers crash on empty glMultiDrawElements, see GH #7415.
|
|
||||||
assert(! path.sizes.empty());
|
|
||||||
assert(! path.offsets.empty());
|
|
||||||
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()));
|
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
++m_statistics.gl_multi_triangles_calls_count;
|
|
||||||
#endif // ENABLE_GCODE_VIEWER_STATISTICS
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto render_as_instanced_model = [
|
auto render_as_instanced_model = [
|
||||||
#if ENABLE_GCODE_VIEWER_STATISTICS
|
#if ENABLE_GCODE_VIEWER_STATISTICS
|
||||||
@ -4151,16 +4115,16 @@ void GCodeViewer::render_toolpaths()
|
|||||||
switch (buffer.render_primitive_type)
|
switch (buffer.render_primitive_type)
|
||||||
{
|
{
|
||||||
case TBuffer::ERenderPrimitiveType::Point: {
|
case TBuffer::ERenderPrimitiveType::Point: {
|
||||||
render_as_points(it_path, buffer.render_paths.rend(), *shader, uniform_color);
|
render_sub_paths(it_path, buffer.render_paths.rend(), *shader, uniform_color, (unsigned int) EDrawPrimitiveType::Points);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TBuffer::ERenderPrimitiveType::Line: {
|
case TBuffer::ERenderPrimitiveType::Line: {
|
||||||
p_ogl_manager->set_line_width(static_cast<float>(line_width(zoom)));
|
p_ogl_manager->set_line_width(static_cast<float>(line_width(zoom)));
|
||||||
render_as_lines(it_path, buffer.render_paths.rend(), *shader, uniform_color);
|
render_sub_paths(it_path, buffer.render_paths.rend(), *shader, uniform_color, (unsigned int) EDrawPrimitiveType::Lines);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TBuffer::ERenderPrimitiveType::Triangle: {
|
case TBuffer::ERenderPrimitiveType::Triangle: {
|
||||||
render_as_triangles(it_path, buffer.render_paths.rend(), *shader, uniform_color);
|
render_sub_paths(it_path, buffer.render_paths.rend(), *shader, uniform_color, (unsigned int) EDrawPrimitiveType::Triangles);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { break; }
|
default: { break; }
|
||||||
|
@ -920,6 +920,8 @@ private:
|
|||||||
//BBS: always load shell at preview
|
//BBS: always load shell at preview
|
||||||
//void load_shells(const Print& print, bool initialized);
|
//void load_shells(const Print& print, bool initialized);
|
||||||
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
|
void refresh_render_paths(bool keep_sequential_current_first, bool keep_sequential_current_last) const;
|
||||||
|
template<typename Iterator>
|
||||||
|
void render_sub_paths(Iterator it_path, Iterator it_end, GLShaderProgram &shader, int uniform_color, unsigned int draw_type);
|
||||||
void render_toolpaths();
|
void render_toolpaths();
|
||||||
void render_shells();
|
void render_shells();
|
||||||
|
|
||||||
|
@ -2925,6 +2925,9 @@ bool GUI_App::on_init_inner()
|
|||||||
|
|
||||||
const bool gizmo_keep_screen_size = app_config->get_bool("gizmo_keep_screen_size");
|
const bool gizmo_keep_screen_size = app_config->get_bool("gizmo_keep_screen_size");
|
||||||
p_ogl_manager->set_gizmo_keep_screen_size_enabled(gizmo_keep_screen_size);
|
p_ogl_manager->set_gizmo_keep_screen_size_enabled(gizmo_keep_screen_size);
|
||||||
|
|
||||||
|
const bool cancel_glmultidraw = app_config->get_bool("cancel_glmultidraw");
|
||||||
|
p_ogl_manager->set_cancle_glmultidraw(cancel_glmultidraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
BBLSplashScreen * scrn = nullptr;
|
BBLSplashScreen * scrn = nullptr;
|
||||||
|
@ -316,6 +316,7 @@ OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::E
|
|||||||
OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown;
|
OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown;
|
||||||
bool OpenGLManager::s_b_initialized = false;
|
bool OpenGLManager::s_b_initialized = false;
|
||||||
ColorRGBA OpenGLManager::s_cut_plane_color = {1.0f, 0.37f, 0.0f, 1.0f};
|
ColorRGBA OpenGLManager::s_cut_plane_color = {1.0f, 0.37f, 0.0f, 1.0f};
|
||||||
|
bool OpenGLManager::s_cancle_glmultidraw = false;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
|
// Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets
|
||||||
OpenGLManager::OSInfo OpenGLManager::s_os_info;
|
OpenGLManager::OSInfo OpenGLManager::s_os_info;
|
||||||
@ -851,6 +852,34 @@ const ColorRGBA &OpenGLManager::get_cut_plane_color(){
|
|||||||
return s_cut_plane_color;
|
return s_cut_plane_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int OpenGLManager::get_draw_primitive_type(EDrawPrimitiveType type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case EDrawPrimitiveType::Points: {
|
||||||
|
return GL_POINTS;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
case EDrawPrimitiveType::Triangles: {
|
||||||
|
return GL_TRIANGLES;
|
||||||
|
}
|
||||||
|
case EDrawPrimitiveType::TriangleStrip: {
|
||||||
|
return GL_TRIANGLE_STRIP;
|
||||||
|
}
|
||||||
|
case EDrawPrimitiveType::TriangleFan: {
|
||||||
|
return GL_TRIANGLE_FAN;
|
||||||
|
}
|
||||||
|
case EDrawPrimitiveType::Lines: {
|
||||||
|
return GL_LINES;
|
||||||
|
}
|
||||||
|
case EDrawPrimitiveType::LineStrip: {
|
||||||
|
return GL_LINE_STRIP;
|
||||||
|
}
|
||||||
|
case EDrawPrimitiveType::LineLoop: {
|
||||||
|
return GL_LINE_LOOP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLManager::detect_multisample(int* attribList)
|
void OpenGLManager::detect_multisample(int* attribList)
|
||||||
{
|
{
|
||||||
int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER;
|
int wxVersion = wxMAJOR_VERSION * 10000 + wxMINOR_VERSION * 100 + wxRELEASE_NUMBER;
|
||||||
|
@ -45,6 +45,16 @@ enum class EPixelDataType : uint16_t
|
|||||||
Float
|
Float
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EDrawPrimitiveType : uint8_t{
|
||||||
|
Points,
|
||||||
|
Triangles,
|
||||||
|
TriangleStrip,
|
||||||
|
TriangleFan,
|
||||||
|
Lines,
|
||||||
|
LineStrip,
|
||||||
|
LineLoop
|
||||||
|
};
|
||||||
|
|
||||||
struct FrameBufferParams
|
struct FrameBufferParams
|
||||||
{
|
{
|
||||||
uint32_t m_width{ 0 };
|
uint32_t m_width{ 0 };
|
||||||
@ -232,6 +242,7 @@ private:
|
|||||||
static EFramebufferType s_framebuffers_type;
|
static EFramebufferType s_framebuffers_type;
|
||||||
static bool m_use_manually_generated_mipmaps;
|
static bool m_use_manually_generated_mipmaps;
|
||||||
static ColorRGBA s_cut_plane_color;
|
static ColorRGBA s_cut_plane_color;
|
||||||
|
static bool s_cancle_glmultidraw;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OpenGLManager();
|
OpenGLManager();
|
||||||
@ -279,6 +290,9 @@ public:
|
|||||||
static bool use_manually_generated_mipmaps() { return m_use_manually_generated_mipmaps; }
|
static bool use_manually_generated_mipmaps() { return m_use_manually_generated_mipmaps; }
|
||||||
static void set_cut_plane_color(ColorRGBA);
|
static void set_cut_plane_color(ColorRGBA);
|
||||||
static const ColorRGBA &get_cut_plane_color();
|
static const ColorRGBA &get_cut_plane_color();
|
||||||
|
static bool get_cancle_glmultidraw() { return s_cancle_glmultidraw; }
|
||||||
|
static void set_cancle_glmultidraw(bool flag) { s_cancle_glmultidraw = flag; }
|
||||||
|
static unsigned int get_draw_primitive_type(EDrawPrimitiveType type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void detect_multisample(int* attribList);
|
static void detect_multisample(int* attribList);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user