From df00795fcbee8aa2121617798a9f3e485d50ca92 Mon Sep 17 00:00:00 2001 From: "jun.zhang" Date: Thu, 26 Dec 2024 16:47:15 +0800 Subject: [PATCH] NEW: add vao to fix black screen issue jira: no-jira Change-Id: Ibe1dc4c8a2bad1909cf188a2da5fbba953adb981 (cherry picked from commit 4b239e7788c89c2a5ddd23f20878f6cde5a2ded1) --- src/BambuStudio.cpp | 7 +++- src/slic3r/GUI/GLCanvas3D.cpp | 7 +++- src/slic3r/GUI/ImGuiWrapper.cpp | 25 ++++++++--- src/slic3r/GUI/OpenGLManager.cpp | 72 +++++++++++++++++++++++++++++++- src/slic3r/GUI/OpenGLManager.hpp | 15 +++++++ 5 files changed, 118 insertions(+), 8 deletions(-) diff --git a/src/BambuStudio.cpp b/src/BambuStudio.cpp index 5d6ccc0b3..2d5a9eac7 100644 --- a/src/BambuStudio.cpp +++ b/src/BambuStudio.cpp @@ -5860,8 +5860,9 @@ int CLI::run(int argc, char **argv) } sliced_plate_info.triangle_count = plate_triangle_counts[index]; - auto cli_generate_thumbnails = [&partplate_list, &model, &glvolume_collection, &colors_out, &shader](const ThumbnailsParams& params) -> ThumbnailsList{ + auto cli_generate_thumbnails = [&partplate_list, &model, &glvolume_collection, &colors_out, &shader, &opengl_mgr](const ThumbnailsParams& params) -> ThumbnailsList{ ThumbnailsList thumbnails; + opengl_mgr.bind_vao(); for (const Vec2d& size : params.sizes) { thumbnails.push_back(ThumbnailData()); Point isize(size); // round to ints @@ -5891,6 +5892,7 @@ int CLI::run(int argc, char **argv) if (!thumbnails.back().is_valid()) thumbnails.pop_back(); } + opengl_mgr.unbind_vao(); return thumbnails; }; @@ -6400,6 +6402,7 @@ int CLI::run(int argc, char **argv) else {*/ if (opengl_valid) { Model &model = m_models[0]; + opengl_mgr.bind_vao(); for (int i = 0; i < partplate_list.get_plate_count(); i++) { Slic3r::GUI::PartPlate *part_plate = partplate_list.get_plate(i); PlateData *plate_data = plate_data_list[i]; @@ -6631,6 +6634,8 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << boost::format("plate %1%: add thumbnail data for top and pick into group")%(i+1); } } + + opengl_mgr.unbind_vao(); } } //BBS: release glfw diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index c7f9fcf7c..72042abca 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1970,6 +1970,8 @@ void GLCanvas3D::render(bool only_init) auto& ogl_manager = wxGetApp().get_opengl_manager(); ogl_manager.set_viewport_size(viewport[2], viewport[3]); + ogl_manager.bind_vao(); + wxGetApp().imgui()->new_frame(); if (m_picking_enabled) { @@ -2167,7 +2169,7 @@ void GLCanvas3D::render(bool only_init) } wxGetApp().imgui()->render(); - + ogl_manager.unbind_vao(); ogl_manager.clear_dirty(); m_canvas->SwapBuffers(); m_render_stats.increment_fps_counter(); @@ -2182,8 +2184,11 @@ void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data, bool for_picking, bool ban_light) { + auto& ogl_manager = wxGetApp().get_opengl_manager(); + ogl_manager.bind_vao(); ModelObjectPtrs &model_objects = GUI::wxGetApp().model().objects; render_thumbnail(thumbnail_data, w, h, thumbnail_params, model_objects, m_volumes, camera_type, camera_view_angle_type, for_picking, ban_light); + ogl_manager.unbind_vao(); } void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data, diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 51f511e20..4cc2512e6 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -2735,9 +2735,21 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; - 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)))); + 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)); + + glsafe(::glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)IM_OFFSETOF(ImDrawVert, pos)))); + glsafe(::glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)IM_OFFSETOF(ImDrawVert, uv)))); + glsafe(::glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)IM_OFFSETOF(ImDrawVert, col)))); for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -2756,12 +2768,15 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) 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)))); } } idx_buffer += pcmd->ElemCount; } + + glsafe(::glDeleteBuffers(1, &ibo_id)); + glsafe(::glDeleteBuffers(1, &vbo_id)); } // Restore modified state diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index a981b3033..a2bd98431 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -1,4 +1,4 @@ -#include "libslic3r/libslic3r.h" +#include "libslic3r/libslic3r.h" #include "OpenGLManager.hpp" #include "GUI.hpp" @@ -239,6 +239,7 @@ OpenGLManager::OSInfo OpenGLManager::s_os_info; OpenGLManager::~OpenGLManager() { + release_vao(); m_shaders_manager.shutdown(); m_name_to_frame_buffer.clear(); @@ -289,6 +290,17 @@ bool OpenGLManager::init_gl(bool popup_error) s_framebuffers_type = EFramebufferType::Unknown; BOOST_LOG_TRIVIAL(warning) << "Found Framebuffer Type unknown!"<< std::endl; } + if (gl_formated_version >= 30) { + m_vao_type = EVAOType::Core; + } +#if defined(__APPLE__) + else if (GLEW_APPLE_vertex_array_object) { + m_vao_type = EVAOType::Apple; + } +#endif + else if (GLEW_ARB_vertex_array_object) { + m_vao_type = EVAOType::Arb; + } bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); if (!valid_version) { @@ -420,6 +432,64 @@ const std::shared_ptr& OpenGLManager::get_frame_buffer(const std::s return sEmpty; } +void OpenGLManager::bind_vao() +{ + if (m_vao_type != EVAOType::Unknown) { + if (EVAOType::Core == m_vao_type || EVAOType::Arb == m_vao_type) { + if (0 == m_vao) { + glsafe(::glGenVertexArrays(1, &m_vao)); + } + glsafe(::glBindVertexArray(m_vao)); + } + else { +#if defined(__APPLE__) + if (0 == m_vao) { + glsafe(::glGenVertexArraysAPPLE(1, &m_vao)); + } + glsafe(::glBindVertexArrayAPPLE(m_vao)); +#endif + } + } +} + +void OpenGLManager::unbind_vao() +{ + if (0 == m_vao) { + return; + } + + if (m_vao_type != EVAOType::Unknown) { + if (EVAOType::Core == m_vao_type || EVAOType::Arb == m_vao_type) { + glsafe(::glBindVertexArray(0)); + } + else { +#if defined(__APPLE__) + glsafe(::glBindVertexArrayAPPLE(0)); +#endif + } + } +} + +void OpenGLManager::release_vao() +{ + if (0 != m_vao) { + return; + } + if (m_vao_type != EVAOType::Unknown) { + if (EVAOType::Core == m_vao_type || EVAOType::Arb == m_vao_type) { + glsafe(::glBindVertexArray(0)); + glsafe(::glDeleteVertexArrays(1, &m_vao)); + } + else { +#if defined(__APPLE__) + glsafe(::glBindVertexArrayAPPLE(0)); + glsafe(::glDeleteVertexArraysAPPLE(1, &m_vao)); +#endif + } + m_vao = 0; + } +} + std::string OpenGLManager::framebuffer_type_to_string(EFramebufferType type) { switch (type) diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 54f4656fa..011804577 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -44,6 +44,15 @@ public: Arb, Ext }; + enum class EVAOType : uint8_t + { + Unknown, + Core, + Arb, +#ifdef __APPLE__ + Apple +#endif + }; class GLInfo { @@ -125,6 +134,8 @@ private: uint32_t m_viewport_height{ 0 }; bool m_b_viewport_dirty{ true }; std::unordered_map> m_name_to_frame_buffer; + EVAOType m_vao_type{ EVAOType::Unknown }; + uint32_t m_vao{ 0 }; static GLInfo s_gl_info; #ifdef __APPLE__ // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets @@ -150,6 +161,10 @@ public: void get_viewport_size(uint32_t& width, uint32_t& height) const; const std::shared_ptr& get_frame_buffer(const std::string& name) const; + void bind_vao(); + void unbind_vao(); + void release_vao(); + static bool are_compressed_textures_supported() { return s_compressed_textures_supported; } static bool can_multisample() { return s_multisample == EMultisampleState::Enabled; } static bool are_framebuffers_supported() { return (s_framebuffers_type != EFramebufferType::Unknown); }