diff --git a/src/BambuStudio_app_msvc.cpp b/src/BambuStudio_app_msvc.cpp index 84f391e67..4014ac410 100644 --- a/src/BambuStudio_app_msvc.cpp +++ b/src/BambuStudio_app_msvc.cpp @@ -14,8 +14,8 @@ extern "C" { // Let the NVIDIA and AMD know we want to use their graphics card // on a dual graphics card system. - __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001; - __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; + __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000000; + __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0; } #endif /* SLIC3R_GUI */ @@ -34,174 +34,6 @@ extern "C" #include -#ifdef SLIC3R_GUI -class OpenGLVersionCheck -{ -public: - std::string version; - std::string glsl_version; - std::string vendor; - std::string renderer; - - HINSTANCE hOpenGL = nullptr; - bool success = false; - - bool load_opengl_dll() - { - MSG msg = {0}; - WNDCLASS wc = {0}; - wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc; - wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr); - wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND); - wc.lpszClassName = L"BambuStudio_opengl_version_check"; - wc.style = CS_OWNDC; - if (RegisterClass(&wc)) { - HWND hwnd = CreateWindowW(wc.lpszClassName, L"BambuStudio_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this); - if (hwnd) { - message_pump_exit = false; - while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit) - DispatchMessage(&msg); - } - } - return this->success; - } - - void unload_opengl_dll() - { - if (this->hOpenGL) { - BOOL released = FreeLibrary(this->hOpenGL); - if (released) - printf("System OpenGL library released\n"); - else - printf("System OpenGL library NOT released\n"); - this->hOpenGL = nullptr; - } - } - - bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const - { - // printf("is_version_greater_or_equal_to, version: %s\n", version.c_str()); - std::vector tokens; - boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on); - if (tokens.empty()) - return false; - - std::vector numbers; - boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on); - - unsigned int gl_major = 0; - unsigned int gl_minor = 0; - if (numbers.size() > 0) - gl_major = ::atoi(numbers[0].c_str()); - if (numbers.size() > 1) - gl_minor = ::atoi(numbers[1].c_str()); - // printf("Major: %d, minor: %d\n", gl_major, gl_minor); - if (gl_major < major) - return false; - else if (gl_major > major) - return true; - else - return gl_minor >= minor; - } - -protected: - static bool message_pump_exit; - - void check(HWND hWnd) - { - hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0); - if (hOpenGL == nullptr) { - printf("Failed loading the system opengl32.dll\n"); - return; - } - - typedef HGLRC (WINAPI *Func_wglCreateContext)(HDC); - typedef BOOL (WINAPI *Func_wglMakeCurrent )(HDC, HGLRC); - typedef BOOL (WINAPI *Func_wglDeleteContext)(HGLRC); - typedef GLubyte* (WINAPI *Func_glGetString )(GLenum); - - Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext"); - Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent"); - Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext"); - Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString"); - - if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) { - printf("Failed loading the system opengl32.dll: The library is invalid.\n"); - return; - } - - PIXELFORMATDESCRIPTOR pfd = - { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, - PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. - 32, // Color depth of the framebuffer. - 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, - 24, // Number of bits for the depthbuffer - 8, // Number of bits for the stencilbuffer - 0, // Number of Aux buffers in the framebuffer. - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; - - HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd); - // Gdi32.dll - int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd); - // Gdi32.dll - SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd); - // Opengl32.dll - HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext); - wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext); - // Opengl32.dll - const char *data = (const char*)glGetString(GL_VERSION); - if (data != nullptr) - this->version = data; - // printf("check -version: %s\n", version.c_str()); - data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION - if (data != nullptr) - this->glsl_version = data; - data = (const char*)glGetString(GL_VENDOR); - if (data != nullptr) - this->vendor = data; - data = (const char*)glGetString(GL_RENDERER); - if (data != nullptr) - this->renderer = data; - // Opengl32.dll - wglDeleteContext(glcontext); - ::ReleaseDC(hWnd, ourWindowHandleToDeviceContext); - this->success = true; - } - - static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) - { - switch(message) - { - case WM_CREATE: - { - CREATESTRUCT *pCreate = reinterpret_cast(lParam); - OpenGLVersionCheck *ogl_data = reinterpret_cast(pCreate->lpCreateParams); - ogl_data->check(hWnd); - DestroyWindow(hWnd); - return 0; - } - case WM_NCDESTROY: - message_pump_exit = true; - return 0; - default: - return DefWindowProc(hWnd, message, wParam, lParam); - } - } -}; - -bool OpenGLVersionCheck::message_pump_exit = false; -#endif /* SLIC3R_GUI */ - extern "C" { typedef int (__stdcall *Slic3rMainFunc)(int argc, wchar_t **argv); Slic3rMainFunc bambustu_main = nullptr; @@ -245,15 +77,6 @@ int wmain(int argc, wchar_t **argv) } argv_extended.emplace_back(nullptr); -#ifdef SLIC3R_GUI - OpenGLVersionCheck opengl_version_check; - bool load_mesa = - // Forced from the command line. - force_mesa || - // Try to load the default OpenGL driver and test its context version. - ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0); -#endif /* SLIC3R_GUI */ - wchar_t path_to_exe[MAX_PATH + 1] = { 0 }; ::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH); wchar_t drive[_MAX_DRIVE]; @@ -263,24 +86,6 @@ int wmain(int argc, wchar_t **argv) _wsplitpath(path_to_exe, drive, dir, fname, ext); _wmakepath(path_to_exe, drive, dir, nullptr, nullptr); -#ifdef SLIC3R_GUI -// https://wiki.qt.io/Cross_compiling_Mesa_for_Windows -// http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/ - if (load_mesa) { - opengl_version_check.unload_opengl_dll(); - wchar_t path_to_mesa[MAX_PATH + 1] = { 0 }; - wcscpy(path_to_mesa, path_to_exe); - wcscat(path_to_mesa, L"mesa\\opengl32.dll"); - printf("Loading MESA OpenGL library: %S\n", path_to_mesa); - HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0); - if (hInstance_OpenGL == nullptr) { - printf("MESA OpenGL library was not loaded\n"); - } else - printf("MESA OpenGL library was loaded sucessfully\n"); - } -#endif /* SLIC3R_GUI */ - - wchar_t path_to_slic3r[MAX_PATH + 1] = { 0 }; wcscpy(path_to_slic3r, path_to_exe); wcscat(path_to_slic3r, L"BambuStudio.dll"); diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index 7bb2cfe87..cf023d9da 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -196,6 +196,9 @@ void AppConfig::set_defaults() if (get("enable_multi_machine").empty()) set_bool("enable_multi_machine", false); + if (get("prefer_to_use_dgpu").empty()) + set_bool("prefer_to_use_dgpu", true); + if (get("show_3d_navigator").empty()) set_bool("show_3d_navigator", true); diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 702a819b5..90301a7ff 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -12,6 +12,8 @@ //BBS: add convex hull logic for toolpath check #include "libslic3r/Geometry/ConvexHull.hpp" +#include "slic3r/GUI/OpenGLManager.hpp" + #include "GUI_App.hpp" #include "MainFrame.hpp" #include "Plater.hpp" diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 90bd83253..bce6e97f9 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2050,7 +2050,12 @@ void GLCanvas3D::render(bool only_init) glsafe(::glLightfv(GL_LIGHT0, GL_POSITION, position_top)); const std::array& viewport = camera.get_viewport(); - auto& ogl_manager = wxGetApp().get_opengl_manager(); + const auto& p_ogl_manager = wxGetApp().get_opengl_manager(); + if (!p_ogl_manager) { + return; + } + + auto& ogl_manager = *p_ogl_manager; ogl_manager.set_viewport_size(viewport[2], viewport[3]); ogl_manager.bind_vao(); @@ -2267,11 +2272,14 @@ void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data, bool for_picking, bool ban_light) { - auto& ogl_manager = wxGetApp().get_opengl_manager(); - ogl_manager.bind_vao(); + const auto& ogl_manager = wxGetApp().get_opengl_manager(); + if (!ogl_manager) { + return; + } + 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(); + ogl_manager->unbind_vao(); } void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_data, @@ -2347,8 +2355,12 @@ void GLCanvas3D::render_thumbnail(ThumbnailData & thumbnail_d void GLCanvas3D::render_calibration_thumbnail(ThumbnailData& thumbnail_data, unsigned int w, unsigned int h, const ThumbnailsParams& thumbnail_params) { //load current plate gcode + const auto& p_ogl_manager = wxGetApp().get_opengl_manager(); + if (!p_ogl_manager) { + return; + } m_gcode_viewer.render_calibration_thumbnail(thumbnail_data, w, h, thumbnail_params, - wxGetApp().plater()->get_partplate_list(), wxGetApp().get_opengl_manager()); + wxGetApp().plater()->get_partplate_list(), *p_ogl_manager); } //BBS @@ -9916,8 +9928,12 @@ void GLCanvas3D::_render_silhouette_effect() {; RenderPipelineStageModifier render_pipeline_stage_modifier(*this, ERenderPipelineStage::Silhouette); - auto& ogl_manager = wxGetApp().get_opengl_manager(); + const auto& p_ogl_manager = wxGetApp().get_opengl_manager(); + if (!p_ogl_manager) { + return; + } + auto& ogl_manager = *p_ogl_manager; { // BBS: render silhouette OpenGLManager::FrameBufferModifier frame_buffer_modifier(ogl_manager, "silhouette"); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 500533e61..4bba176c0 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -5,6 +5,7 @@ #include "GUI_Factories.hpp" #include "slic3r/GUI/UserManager.hpp" #include "slic3r/GUI/TaskManager.hpp" +#include "slic3r/GUI/OpenGLManager.hpp" #include "format.hpp" // Localization headers: include libslic3r version first so everything in this file @@ -2254,17 +2255,25 @@ std::string GUI_App::get_gl_info(bool for_github) wxGLContext* GUI_App::init_glcontext(wxGLCanvas& canvas) { - return m_opengl_mgr.init_glcontext(canvas); + const auto& p_ogl_manager = get_opengl_manager(); + if (!p_ogl_manager) { + return nullptr; + } + return p_ogl_manager->init_glcontext(canvas); } bool GUI_App::init_opengl() { + const auto& p_ogl_mananager = get_opengl_manager(); + if (!p_ogl_mananager) { + return false; + } #ifdef __linux__ - bool status = m_opengl_mgr.init_gl(); + bool status = p_ogl_mananager->init_gl(); m_opengl_initialized = true; return status; #else - return m_opengl_mgr.init_gl(); + return p_ogl_mananager->init_gl(); #endif } @@ -5597,6 +5606,16 @@ static const wxLanguageInfo* linux_get_existing_locale_language(const wxLanguage } #endif +bool GUI_App::is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const +{ + return OpenGLManager::get_gl_info().is_version_greater_or_equal_to(major, minor); +} + +bool GUI_App::is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const +{ + return OpenGLManager::get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); +} + int GUI_App::GetSingleChoiceIndex(const wxString& message, const wxString& caption, const wxArrayString& choices, @@ -7037,6 +7056,45 @@ void GUI_App::gcode_thumbnails_debug() } #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG +const std::shared_ptr& GUI_App::get_opengl_manager() const +{ + if (m_p_opengl_mgr) { + return m_p_opengl_mgr; + } + bool prefer_to_use_dgpu = false; +#ifdef __WIN32__ + prefer_to_use_dgpu = app_config->get_bool("prefer_to_use_dgpu"); +#endif // __WIN32__ + + const bool rt = OpenGLManager::init(prefer_to_use_dgpu); + if (rt) + { + m_p_opengl_mgr = std::make_shared(); + return m_p_opengl_mgr; + } + static std::shared_ptr s_empty{nullptr}; + return s_empty; +} + +GLShaderProgram* GUI_App::get_shader(const std::string &shader_name) const +{ + const auto& p_ogl_manager = get_opengl_manager(); + if (p_ogl_manager) { + return p_ogl_manager->get_shader(shader_name); + } + + return nullptr; +} + +GLShaderProgram* GUI_App::get_current_shader() const +{ + const auto& p_ogl_manager = get_opengl_manager(); + if (p_ogl_manager) { + return p_ogl_manager->get_current_shader(); + } + return nullptr; +} + void GUI_App::window_pos_save(wxTopLevelWindow* window, const std::string &name) { if (name.empty()) { return; } diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index b67792ca3..79adabd32 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -5,7 +5,6 @@ #include #include "ImGuiWrapper.hpp" #include "ConfigWizard.hpp" -#include "OpenGLManager.hpp" #include "libslic3r/Preset.hpp" #include "libslic3r/PresetBundle.hpp" #include "libslic3r/Color.hpp" @@ -49,6 +48,8 @@ class wxMenuBar; class wxTopLevelWindow; class wxDataViewCtrl; class wxBookCtrlBase; +class wxGLContext; +class wxGLCanvas; // BBS class Notebook; struct wxLanguageInfo; @@ -83,7 +84,7 @@ class HMSQuery; class ModelMallDialog; class PingCodeBindDialog; class NetworkErrorDialog; - +class OpenGLManager; enum FileType { @@ -269,7 +270,7 @@ private: // Best translation language, provided by Windows or OSX, owned by wxWidgets. const wxLanguageInfo *m_language_info_best = nullptr; - OpenGLManager m_opengl_mgr; + mutable std::shared_ptr m_p_opengl_mgr{ nullptr }; std::unique_ptr m_removable_drive_manager; std::unique_ptr m_imgui; @@ -636,12 +637,12 @@ public: void gcode_thumbnails_debug(); #endif // ENABLE_THUMBNAIL_GENERATOR_DEBUG - OpenGLManager& get_opengl_manager() { return m_opengl_mgr; } - GLShaderProgram* get_shader(const std::string& shader_name) { return m_opengl_mgr.get_shader(shader_name); } - GLShaderProgram* get_current_shader() { return m_opengl_mgr.get_current_shader(); } + const std::shared_ptr& get_opengl_manager() const; + GLShaderProgram* get_shader(const std::string &shader_name) const; + GLShaderProgram* get_current_shader() const; - bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_version_greater_or_equal_to(major, minor); } - bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); } + bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const; + bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const; int GetSingleChoiceIndex(const wxString& message, const wxString& caption, const wxArrayString& choices, int initialSelection); #ifdef __WXMSW__ diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 4d6a9a6ca..32e0aeacb 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -2711,7 +2711,10 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) const GLboolean was_scissor_test_enabled = glIsEnabled(GL_SCISSOR_TEST); GLboolean was_texture2d_enabled = GL_FALSE; const auto& ogl_manager = wxGetApp().get_opengl_manager(); - const auto& gl_info = ogl_manager.get_gl_info(); + if (!ogl_manager) { + return; + } + const auto& gl_info = ogl_manager->get_gl_info(); const auto formated_gl_version = gl_info.get_formated_gl_version(); if (formated_gl_version < 30) { was_texture2d_enabled = glIsEnabled(GL_TEXTURE_2D); diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 5af621eea..2b0fa7f09 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -23,6 +23,178 @@ #include "../Utils/MacDarkMode.hpp" #endif // __APPLE__ +#ifdef __WIN32__ + +#ifdef SLIC3R_GUI +class OpenGLVersionCheck +{ +public: + std::string version; + std::string glsl_version; + std::string vendor; + std::string renderer; + + HINSTANCE hOpenGL = nullptr; + bool success = false; + + bool load_opengl_dll() + { + MSG msg = {0}; + WNDCLASS wc = {0}; + wc.lpfnWndProc = OpenGLVersionCheck::supports_opengl2_wndproc; + wc.hInstance = (HINSTANCE)GetModuleHandle(nullptr); + wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND); + wc.lpszClassName = L"BambuStudio_opengl_version_check"; + wc.style = CS_OWNDC; + if (RegisterClass(&wc)) { + HWND hwnd = CreateWindowW(wc.lpszClassName, L"BambuStudio_opengl_version_check", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480, 0, 0, wc.hInstance, (LPVOID)this); + if (hwnd) { + message_pump_exit = false; + while (GetMessage(&msg, NULL, 0, 0 ) > 0 && ! message_pump_exit) + DispatchMessage(&msg); + } + } + return this->success; + } + + void unload_opengl_dll() + { + if (this->hOpenGL) { + BOOL released = FreeLibrary(this->hOpenGL); + if (released) + printf("System OpenGL library released\n"); + else + printf("System OpenGL library NOT released\n"); + this->hOpenGL = nullptr; + } + } + + bool is_version_greater_or_equal_to(unsigned int major, unsigned int minor) const + { + // printf("is_version_greater_or_equal_to, version: %s\n", version.c_str()); + std::vector tokens; + boost::split(tokens, version, boost::is_any_of(" "), boost::token_compress_on); + if (tokens.empty()) + return false; + + std::vector numbers; + boost::split(numbers, tokens[0], boost::is_any_of("."), boost::token_compress_on); + + unsigned int gl_major = 0; + unsigned int gl_minor = 0; + if (numbers.size() > 0) + gl_major = ::atoi(numbers[0].c_str()); + if (numbers.size() > 1) + gl_minor = ::atoi(numbers[1].c_str()); + // printf("Major: %d, minor: %d\n", gl_major, gl_minor); + if (gl_major < major) + return false; + else if (gl_major > major) + return true; + else + return gl_minor >= minor; + } + +protected: + static bool message_pump_exit; + + void check(HWND hWnd) + { + hOpenGL = LoadLibraryExW(L"opengl32.dll", nullptr, 0); + if (hOpenGL == nullptr) { + printf("Failed loading the system opengl32.dll\n"); + return; + } + + typedef HGLRC (WINAPI *Func_wglCreateContext)(HDC); + typedef BOOL (WINAPI *Func_wglMakeCurrent )(HDC, HGLRC); + typedef BOOL (WINAPI *Func_wglDeleteContext)(HGLRC); + typedef GLubyte* (WINAPI *Func_glGetString )(GLenum); + + Func_wglCreateContext wglCreateContext = (Func_wglCreateContext)GetProcAddress(hOpenGL, "wglCreateContext"); + Func_wglMakeCurrent wglMakeCurrent = (Func_wglMakeCurrent) GetProcAddress(hOpenGL, "wglMakeCurrent"); + Func_wglDeleteContext wglDeleteContext = (Func_wglDeleteContext)GetProcAddress(hOpenGL, "wglDeleteContext"); + Func_glGetString glGetString = (Func_glGetString) GetProcAddress(hOpenGL, "glGetString"); + + if (wglCreateContext == nullptr || wglMakeCurrent == nullptr || wglDeleteContext == nullptr || glGetString == nullptr) { + printf("Failed loading the system opengl32.dll: The library is invalid.\n"); + return; + } + + PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, + PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. + 32, // Color depth of the framebuffer. + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 24, // Number of bits for the depthbuffer + 8, // Number of bits for the stencilbuffer + 0, // Number of Aux buffers in the framebuffer. + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; + + HDC ourWindowHandleToDeviceContext = ::GetDC(hWnd); + // Gdi32.dll + int letWindowsChooseThisPixelFormat = ::ChoosePixelFormat(ourWindowHandleToDeviceContext, &pfd); + // Gdi32.dll + SetPixelFormat(ourWindowHandleToDeviceContext, letWindowsChooseThisPixelFormat, &pfd); + // Opengl32.dll + HGLRC glcontext = wglCreateContext(ourWindowHandleToDeviceContext); + wglMakeCurrent(ourWindowHandleToDeviceContext, glcontext); + // Opengl32.dll + const char *data = (const char*)glGetString(GL_VERSION); + if (data != nullptr) + this->version = data; + // printf("check -version: %s\n", version.c_str()); + data = (const char*)glGetString(0x8B8C); // GL_SHADING_LANGUAGE_VERSION + if (data != nullptr) + this->glsl_version = data; + data = (const char*)glGetString(GL_VENDOR); + if (data != nullptr) + this->vendor = data; + data = (const char*)glGetString(GL_RENDERER); + if (data != nullptr) + this->renderer = data; + // Opengl32.dll + wglDeleteContext(glcontext); + ::ReleaseDC(hWnd, ourWindowHandleToDeviceContext); + this->success = true; + } + + static LRESULT CALLBACK supports_opengl2_wndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) + { + switch(message) + { + case WM_CREATE: + { + CREATESTRUCT *pCreate = reinterpret_cast(lParam); + OpenGLVersionCheck *ogl_data = reinterpret_cast(pCreate->lpCreateParams); + ogl_data->check(hWnd); + DestroyWindow(hWnd); + return 0; + } + case WM_NCDESTROY: + message_pump_exit = true; + return 0; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + } +}; + +bool OpenGLVersionCheck::message_pump_exit = false; +#endif /* SLIC3R_GUI */ + +#endif // __WIN32__ + #define BBS_GL_EXTENSION_FUNC(_func) (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? _func ## EXT : _func) #define BBS_GL_EXTENSION_FRAMEBUFFER OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? GL_FRAMEBUFFER_EXT : GL_FRAMEBUFFER #define BBS_GL_EXTENSION_COLOR_ATTACHMENT(color_attachment) (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Ext ? color_attachment ## _EXT : color_attachment) @@ -231,12 +403,16 @@ bool OpenGLManager::s_compressed_textures_supported = false; bool OpenGLManager::m_use_manually_generated_mipmaps = true; OpenGLManager::EMultisampleState OpenGLManager::s_multisample = OpenGLManager::EMultisampleState::Unknown; OpenGLManager::EFramebufferType OpenGLManager::s_framebuffers_type = OpenGLManager::EFramebufferType::Unknown; - +bool OpenGLManager::s_b_initialized = false; #ifdef __APPLE__ // 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; #endif // __APPLE__ +OpenGLManager::OpenGLManager() +{ +} + OpenGLManager::~OpenGLManager() { release_vao(); @@ -255,6 +431,61 @@ OpenGLManager::~OpenGLManager() #endif //__APPLE__ } +bool OpenGLManager::init(bool prefer_to_use_dgpu) +{ + if (s_b_initialized) { + return true; + } +#ifdef __WIN32__ + if (prefer_to_use_dgpu) { + HMODULE hModExe = nullptr; + hModExe = GetModuleHandle(NULL); + if (hModExe) { + // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: GetModuleHandle " << hModExe; + auto NvOptimusEnablement = (DWORD *) GetProcAddress(hModExe, "NvOptimusEnablement"); + auto AmdPowerXpressRequestHighPerformance = (int *) GetProcAddress(hModExe, "AmdPowerXpressRequestHighPerformance"); + if (NvOptimusEnablement) { + *NvOptimusEnablement = 0x00000001; + } + if (AmdPowerXpressRequestHighPerformance) { + // BOOST_LOG_TRIVIAL(info) << "wxMediaCtrl2: AmdPowerXpressRequestHighPerformance " << *AmdPowerXpressRequestHighPerformance; + *AmdPowerXpressRequestHighPerformance = 1; + } + } + } + +#ifdef SLIC3R_GUI + bool force_mesa = false; + + wchar_t path_to_exe[MAX_PATH + 1] = {0}; + ::GetModuleFileNameW(nullptr, path_to_exe, MAX_PATH); + OpenGLVersionCheck opengl_version_check; + bool load_mesa = + force_mesa || + // Try to load the default OpenGL driver and test its context version. + !opengl_version_check.load_opengl_dll() || !opengl_version_check.is_version_greater_or_equal_to(2, 0); + // https://wiki.qt.io/Cross_compiling_Mesa_for_Windows + // http://download.qt.io/development_releases/prebuilt/llvmpipe/windows/ + if (load_mesa) { + opengl_version_check.unload_opengl_dll(); + wchar_t path_to_mesa[MAX_PATH + 1] = {0}; + wcscpy(path_to_mesa, path_to_exe); + wcscat(path_to_mesa, L"mesa\\opengl32.dll"); + BOOST_LOG_TRIVIAL(info) << "Loading MESA OpenGL library: " << path_to_mesa; + HINSTANCE hInstance_OpenGL = LoadLibraryExW(path_to_mesa, nullptr, 0); + if (hInstance_OpenGL == nullptr) { + BOOST_LOG_TRIVIAL(error) << "MESA OpenGL library was not loaded"; + } else + BOOST_LOG_TRIVIAL(info) << "MESA OpenGL library was loaded sucessfully"; + } +#endif /* SLIC3R_GUI */ + +#endif // __WIN32__ + + s_b_initialized = true; + return s_b_initialized; +} + bool OpenGLManager::init_gl(bool popup_error) { if (!m_gl_initialized) { diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 011804577..e5c0d3a70 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -141,13 +141,14 @@ private: // Part of hack to remove crash when closing the application on OSX 10.9.5 when building against newer wxWidgets static OSInfo s_os_info; #endif //__APPLE__ + static bool s_b_initialized; static bool s_compressed_textures_supported; static EMultisampleState s_multisample; static EFramebufferType s_framebuffers_type; static bool m_use_manually_generated_mipmaps; public: - OpenGLManager() = default; + OpenGLManager(); ~OpenGLManager(); bool init_gl(bool popup_error = true); @@ -165,6 +166,7 @@ public: void unbind_vao(); void release_vao(); + static bool init(bool prefer_to_use_dgpu = false); 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); } diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 113d65777..e4167baf0 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -22,6 +22,7 @@ #include "libslic3r/Tesselate.hpp" #include "libslic3r/GCode/ThumbnailData.hpp" #include "libslic3r/Utils.hpp" +#include "slic3r/GUI/OpenGLManager.hpp" #include "I18N.hpp" #include "GUI_App.hpp" diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index 165077e29..47b7c2741 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -846,27 +846,12 @@ wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxWindow *pa } } - if (param == "enable_opengl_multi_instance") { - if (wxGetApp().plater()->is_project_dirty()) { - auto result = MessageDialog(static_cast(this), _L("The current project has unsaved changes, save it before continuing?"), - wxString(SLIC3R_APP_FULL_NAME) + " - " + _L("Save"), wxYES_NO | wxYES_DEFAULT | wxCENTRE) - .ShowModal(); - if (result == wxID_YES) { wxGetApp().plater()->save_project(); } - } - MessageDialog msg_wingow(nullptr, - _L("Change opengl multi instance rendering requires application restart.") + "\n" + - _L("Do you want to continue?"), - _L("Enable opengl multi instance rendering"), wxYES | wxYES_DEFAULT | wxCANCEL | wxCENTRE); - if (msg_wingow.ShowModal() == wxID_YES) { - Close(); - GetParent()->RemoveChild(this); - wxGetApp().recreate_GUI(_L("Enable opengl multi instance rendering")); - } else { - checkbox->SetValue(!checkbox->GetValue()); - app_config->set_bool(param, checkbox->GetValue()); - app_config->save(); - } +#ifdef __WIN32__ + if (param == "prefer_to_use_dgpu") { + app_config->set_bool(param, checkbox->GetValue()); + app_config->save(); } +#endif // __WIN32__ e.Skip(); }); @@ -1181,8 +1166,12 @@ wxWindow* PreferencesDialog::create_general_page() auto enable_lod_settings = create_item_checkbox(_L("Improve rendering performance by lod"), page, _L("Improved rendering performance under the scene of multiple plates and many models."), 50, "enable_lod"); - auto enable_opengl_multi_instance_rendering = create_item_checkbox(_L("Enable multi instance rendering by opengl"), page, - _L("If enabled, it can improve certain rendering performance. But for some graphics cards, it may not be applicable, please turn it off."), 50, "enable_opengl_multi_instance"); + +#ifdef __WIN32__ + auto prefer_to_use_dgpu = create_item_checkbox(_L("Prefer to use high performance GPU (Effective after manual restart Bambu Studio)"), page, + _L("If enabled, it can improve certain rendering performance. But for some multi-gpu platforms, it may cause flickering, please turn it off."), 50, "prefer_to_use_dgpu"); +#endif // __WIN32__ + float range_min = 1.0, range_max = 2.5; auto item_grabber_size_settings = create_item_range_input(_L("Grabber scale"), page, _L("Set grabber size for move,rotate,scale tool.") + _L("Value range") + ":[" + std::to_string(range_min) + "," + @@ -1279,7 +1268,11 @@ wxWindow* PreferencesDialog::create_general_page() sizer_page->Add(item_mouse_zoom_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_show_shells_in_preview_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_import_single_svg_and_split, 0, wxTOP, FromDIP(3)); - sizer_page->Add(enable_opengl_multi_instance_rendering, 0, wxTOP, FromDIP(3)); + +#ifdef __WIN32__ + sizer_page->Add(prefer_to_use_dgpu, 0, wxTOP, FromDIP(3)); +#endif // __WIN32__ + sizer_page->Add(enable_lod_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(item_grabber_size_settings, 0, wxTOP, FromDIP(3)); sizer_page->Add(title_presets, 0, wxTOP | wxEXPAND, FromDIP(20)); diff --git a/src/slic3r/Utils/CalibUtils.cpp b/src/slic3r/Utils/CalibUtils.cpp index 77b19c6cd..4c011934f 100644 --- a/src/slic3r/Utils/CalibUtils.cpp +++ b/src/slic3r/Utils/CalibUtils.cpp @@ -4,6 +4,7 @@ #include "../GUI/DeviceManager.hpp" #include "../GUI/Jobs/ProgressIndicator.hpp" #include "../GUI/PartPlate.hpp" +#include "../GUI/OpenGLManager.hpp" #include "libslic3r/Model.hpp" #include "../GUI/MsgDialog.hpp"