From 6a4fafae4ccb99b9d71b64fdb5eebcf54fbc1c91 Mon Sep 17 00:00:00 2001 From: Natsirt867 Date: Sun, 14 Dec 2025 08:13:43 -0600 Subject: [PATCH] fix opengl context checks --- src/noggit/MapView.cpp | 43 ++++++--- src/noggit/MapView.h | 1 + src/noggit/TextureManager.cpp | 23 ++++- src/noggit/Tool.hpp | 2 + src/noggit/rendering/LiquidRender.cpp | 39 +++++++- src/noggit/rendering/LiquidTextureManager.cpp | 14 ++- src/noggit/rendering/ModelRender.cpp | 17 +++- src/noggit/rendering/TileRender.cpp | 18 ++++ src/noggit/rendering/WMOGroupRender.cpp | 18 +++- src/noggit/tools/AreaTriggerTool.cpp | 11 +++ src/noggit/tools/AreaTriggerTool.hpp | 2 + src/noggit/tools/TexturingTool.cpp | 10 ++ src/noggit/tools/TexturingTool.hpp | 2 + src/noggit/ui/GroundEffectsTool.cpp | 6 ++ src/noggit/ui/GroundEffectsTool.hpp | 1 + src/noggit/ui/texturing_tool.cpp | 8 ++ src/noggit/ui/texturing_tool.hpp | 3 +- .../tools/PreviewRenderer/PreviewRenderer.cpp | 6 +- .../ui/windows/noggitWindow/NoggitWindow.cpp | 34 ++++++- src/noggit/world_model_instances_storage.cpp | 18 +++- src/opengl/context.cpp | 28 ++++++ src/opengl/context.hpp | 9 ++ src/opengl/scoped.hpp | 6 +- src/opengl/scoped.ipp | 95 ++++++++++++++++--- src/opengl/shader.cpp | 15 ++- 25 files changed, 383 insertions(+), 46 deletions(-) diff --git a/src/noggit/MapView.cpp b/src/noggit/MapView.cpp index aca8e12e..64a29a98 100644 --- a/src/noggit/MapView.cpp +++ b/src/noggit/MapView.cpp @@ -2822,6 +2822,8 @@ void MapView::paintGL() OpenGL::context::scoped_setter const _(::gl, context()); makeCurrent(); + gl.processCleanup(); + gl.clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); { @@ -2944,27 +2946,34 @@ void MapView::resizeGL (int width, int height) MapView::~MapView() { - makeCurrent(); + //makeCurrent(); _destroying = true; _main_window->removeToolBar(_main_window->_app_toolbar); - OpenGL::context::scoped_setter const _ (::gl, context()); - delete _texBrush; - delete _viewport_overlay_ui; + //OpenGL::context::scoped_setter const _ (::gl, context()); + + //::gl.processCleanup(); + + //delete _texBrush; + //delete _viewport_overlay_ui; // when the uid fix fail the UI isn't created if (!_uid_fix_failed) { - // delete TexturePicker; // explicitly delete this here to avoid opengl context related crash - // delete objectEditor; - // since the ground effect tool preview renderer got added, this causes crashing on exit to menu. - // Now it crashes in application exit. - // delete texturingTool; - + // delete TexturePicker; // explicitly delete this here to avoid opengl context related crash + // delete objectEditor; + // since the ground effect tool preview renderer got added, this causes crashing on exit to menu. + // Now it crashes in application exit. + // delete texturingTool; + if (_tools[static_cast(editing_mode::area_trigger)]) + { + _tools[static_cast(editing_mode::area_trigger)]->unload(); + } _tools[static_cast(editing_mode::paint)].reset(); _tools[static_cast(editing_mode::object)].reset(); + _tools[static_cast(editing_mode::area_trigger)].reset(); } if (_force_uid_check) @@ -2978,14 +2987,22 @@ MapView::~MapView() Noggit::Ui::selected_texture::texture.reset(); + _buffers.unload(); + + makeCurrent(); + + OpenGL::context::scoped_setter const _(::gl, context()); + + ::gl.processCleanup(); + + delete _texBrush; + delete _viewport_overlay_ui; + ModelManager::report(); TextureManager::report(); WMOManager::report(); NOGGIT_ACTION_MGR->disconnect(); - - _buffers.unload(); - } void MapView::tick (float dt) diff --git a/src/noggit/MapView.h b/src/noggit/MapView.h index 38f392ed..bd6bdb52 100755 --- a/src/noggit/MapView.h +++ b/src/noggit/MapView.h @@ -322,6 +322,7 @@ private: QOpenGLContext* _last_opengl_context; +private: virtual void tabletEvent(QTabletEvent* event) override; virtual void initializeGL() override; virtual void paintGL() override; diff --git a/src/noggit/TextureManager.cpp b/src/noggit/TextureManager.cpp index 6f0ababd..3826561b 100755 --- a/src/noggit/TextureManager.cpp +++ b/src/noggit/TextureManager.cpp @@ -42,8 +42,29 @@ void TextureManager::unload_all(Noggit::NoggitRenderContext context) for (auto& pair : arrays_for_context) { - gl.deleteTextures(static_cast(pair.second.arrays.size()), pair.second.arrays.data()); + std::vector ids_to_delete = std::move(pair.second.arrays); + GLsizei count = static_cast(ids_to_delete.size()); + + if (count == 0) + { + continue; + } + + if (QOpenGLContext::currentContext()) + { + gl.deleteTextures(count, ids_to_delete.data()); + } + else + { + gl.scheduleCleanup([count, ids_to_delete = std::move(ids_to_delete)]() mutable + { + gl.deleteTextures(count, ids_to_delete.data()); + } + ); + } } + + arrays_for_context.clear(); } TexArrayParams& TextureManager::get_tex_array(int width, int height, int mip_level, diff --git a/src/noggit/Tool.hpp b/src/noggit/Tool.hpp index def9f4fe..a928a66e 100644 --- a/src/noggit/Tool.hpp +++ b/src/noggit/Tool.hpp @@ -198,6 +198,8 @@ namespace Noggit // Save tool-specific settings to disk virtual void saveSettings(); + virtual void unload() {}; + protected: void addHotkey(StringHash name, Hotkey hotkey); diff --git a/src/noggit/rendering/LiquidRender.cpp b/src/noggit/rendering/LiquidRender.cpp index c38975e7..b4e990f9 100755 --- a/src/noggit/rendering/LiquidRender.cpp +++ b/src/noggit/rendering/LiquidRender.cpp @@ -191,9 +191,24 @@ void LiquidRender::updateLayerData(LiquidTextureManager* tex_manager) { auto& layer_params = _render_layers.back(); - gl.deleteBuffers(1, &layer_params.chunk_data_buf); - gl.deleteTextures(1, &layer_params.vertex_data_tex); + GLuint buffer_id = layer_params.chunk_data_buf; + GLuint texture_id = layer_params.vertex_data_tex; + if (QOpenGLContext::currentContext()) + { + gl.deleteBuffers(1, &buffer_id); + gl.deleteTextures(1, &texture_id); + } + else + { + gl.scheduleCleanup([buffer_id, texture_id]() mutable + { + gl.deleteBuffers(1, &buffer_id); + gl.deleteTextures(1, &texture_id); + } + ); + } + _render_layers.pop_back(); } } @@ -226,8 +241,24 @@ void LiquidRender::unload() for (auto& render_layer : _render_layers) { - gl.deleteBuffers(1, &render_layer.chunk_data_buf); - gl.deleteTextures(1, &render_layer.vertex_data_tex); + GLuint buffer_id = render_layer.chunk_data_buf; + GLuint texture_id = render_layer.vertex_data_tex; + + if (QOpenGLContext::currentContext()) + { + gl.deleteBuffers(1, &buffer_id); + gl.deleteTextures(1, &texture_id); + } + else + { + gl.scheduleCleanup([buffer_id, texture_id]() mutable + { + gl.deleteBuffers(1, &buffer_id); + gl.deleteTextures(1, &texture_id); + } + ); + } + } _render_layers.clear(); diff --git a/src/noggit/rendering/LiquidTextureManager.cpp b/src/noggit/rendering/LiquidTextureManager.cpp index 3c97fb3a..948492cb 100755 --- a/src/noggit/rendering/LiquidTextureManager.cpp +++ b/src/noggit/rendering/LiquidTextureManager.cpp @@ -137,7 +137,19 @@ void LiquidTextureManager::unload() for (auto& pair : _texture_frames_map) { GLuint array = std::get<0>(pair.second); - gl.deleteTextures(1, &array); + + if (QOpenGLContext::currentContext()) + { + gl.deleteTextures(1, &array); + } + else + { + gl.scheduleCleanup([array]() mutable + { + gl.deleteTextures(1, &array); + } + ); + } } _texture_frames_map.clear(); diff --git a/src/noggit/rendering/ModelRender.cpp b/src/noggit/rendering/ModelRender.cpp index 09445179..23aa832a 100755 --- a/src/noggit/rendering/ModelRender.cpp +++ b/src/noggit/rendering/ModelRender.cpp @@ -74,7 +74,22 @@ void ModelRender::unload() _vertex_arrays.unload(); if (_bone_matrices_buf_tex) - gl.deleteTextures(1, &_bone_matrices_buf_tex); + { + GLuint texture_id = _bone_matrices_buf_tex; + + if (QOpenGLContext::currentContext()) + { + gl.deleteTextures(1, &texture_id); + } + else + { + gl.scheduleCleanup([texture_id]() mutable + { + gl.deleteTextures(1, &texture_id); + } + ); + } + } for (auto& particle : _model->_particles) { diff --git a/src/noggit/rendering/TileRender.cpp b/src/noggit/rendering/TileRender.cpp index 24af58bf..06442830 100755 --- a/src/noggit/rendering/TileRender.cpp +++ b/src/noggit/rendering/TileRender.cpp @@ -50,6 +50,24 @@ void TileRender::unload() _buffers.unload(); _uploaded = false; gl.deleteQueries(1, &_tile_occlusion_query); + + if (_tile_occlusion_query) + { + GLuint query_id = _tile_occlusion_query; + + if (QOpenGLContext::currentContext()) + { + gl.deleteQueries(1, &query_id); + } + else + { + gl.scheduleCleanup([query_id]() mutable + { + gl.deleteQueries(1, &query_id); + } + ); + } + } } diff --git a/src/noggit/rendering/WMOGroupRender.cpp b/src/noggit/rendering/WMOGroupRender.cpp index dc260295..1c3aff10 100755 --- a/src/noggit/rendering/WMOGroupRender.cpp +++ b/src/noggit/rendering/WMOGroupRender.cpp @@ -251,7 +251,23 @@ void WMOGroupRender::unload() _vertex_array.unload(); _buffers.unload(); - gl.deleteTextures(1, &_render_batch_tex); + if (_render_batch_tex) + { + GLuint texture_id = _render_batch_tex; + + if (QOpenGLContext::currentContext()) + { + gl.deleteTextures(1, &texture_id); + } + else + { + gl.scheduleCleanup([texture_id]() mutable + { + gl.deleteTextures(1, &texture_id); + } + ); + } + } _uploaded = false; _vao_is_setup = false; diff --git a/src/noggit/tools/AreaTriggerTool.cpp b/src/noggit/tools/AreaTriggerTool.cpp index 9bb53d1c..fc5d944d 100644 --- a/src/noggit/tools/AreaTriggerTool.cpp +++ b/src/noggit/tools/AreaTriggerTool.cpp @@ -56,6 +56,17 @@ namespace Noggit { } + void AreaTriggerTool::unload() + { + _boxRenderer.unload(); + _sphereRenderer.unload(); + + if (_editor) { + delete _editor; + _editor = nullptr; + } + } + char const* AreaTriggerTool::name() const { return "Area Trigger"; diff --git a/src/noggit/tools/AreaTriggerTool.hpp b/src/noggit/tools/AreaTriggerTool.hpp index 314ec84d..9c69deb5 100644 --- a/src/noggit/tools/AreaTriggerTool.hpp +++ b/src/noggit/tools/AreaTriggerTool.hpp @@ -52,6 +52,8 @@ namespace Noggit void saveSettings() override; + void unload() override; + private: Ui::Tools::AreaTriggerEditor* _editor = nullptr; Noggit::Rendering::Primitives::WireBox _boxRenderer; diff --git a/src/noggit/tools/TexturingTool.cpp b/src/noggit/tools/TexturingTool.cpp index 9e29b478..35f7c231 100644 --- a/src/noggit/tools/TexturingTool.cpp +++ b/src/noggit/tools/TexturingTool.cpp @@ -170,6 +170,16 @@ namespace Noggit setupTexturePicker(mv); } + void TexturingTool::unload() + { + if (_texturingTool) + { + _texturingTool->unload(); + } + + Tool::unload(); + } + void TexturingTool::setupTextureBrowser(MapView* mv) { // Dock diff --git a/src/noggit/tools/TexturingTool.hpp b/src/noggit/tools/TexturingTool.hpp index f2d44d62..b9bff5f0 100644 --- a/src/noggit/tools/TexturingTool.hpp +++ b/src/noggit/tools/TexturingTool.hpp @@ -23,6 +23,8 @@ namespace Noggit TexturingTool(MapView* mapView); ~TexturingTool(); + void unload() override; + [[nodiscard]] char const* name() const override; diff --git a/src/noggit/ui/GroundEffectsTool.cpp b/src/noggit/ui/GroundEffectsTool.cpp index 5758df9a..52c23de3 100644 --- a/src/noggit/ui/GroundEffectsTool.cpp +++ b/src/noggit/ui/GroundEffectsTool.cpp @@ -742,6 +742,12 @@ namespace Noggit void GroundEffectsTool::delete_renderer() { delete _preview_renderer; + _preview_renderer = nullptr; + } + + void GroundEffectsTool::unload() + { + delete_renderer(); } void GroundEffectsTool::showEvent(QShowEvent* event) diff --git a/src/noggit/ui/GroundEffectsTool.hpp b/src/noggit/ui/GroundEffectsTool.hpp index 2f1d67b8..3b7b003b 100644 --- a/src/noggit/ui/GroundEffectsTool.hpp +++ b/src/noggit/ui/GroundEffectsTool.hpp @@ -82,6 +82,7 @@ namespace Noggit void updateTerrainUniformParams(); // Delete renderer. ~GroundEffectsTool(); + void unload(); float radius() const; ground_effect_brush_mode brush_mode() const; bool render_mode() const; diff --git a/src/noggit/ui/texturing_tool.cpp b/src/noggit/ui/texturing_tool.cpp index 3e6ac573..b3c6446b 100644 --- a/src/noggit/ui/texturing_tool.cpp +++ b/src/noggit/ui/texturing_tool.cpp @@ -1025,5 +1025,13 @@ namespace Noggit style()->drawComplexControl(QStyle::CC_Slider, &opt, &p, this); */ } + + void texturing_tool::unload() + { + if (_ground_effect_tool) + { + _ground_effect_tool->unload(); + } + } } } diff --git a/src/noggit/ui/texturing_tool.hpp b/src/noggit/ui/texturing_tool.hpp index cc6f40e7..4c416ef8 100644 --- a/src/noggit/ui/texturing_tool.hpp +++ b/src/noggit/ui/texturing_tool.hpp @@ -77,7 +77,8 @@ namespace Noggit ); ~texturing_tool(); // { _ground_effect_tool->deleteLater(); }; // { delete _ground_effect_tool; }; - + + void unload(); float brush_radius() const; float hardness() const; bool show_unpaintable_chunks() const; diff --git a/src/noggit/ui/tools/PreviewRenderer/PreviewRenderer.cpp b/src/noggit/ui/tools/PreviewRenderer/PreviewRenderer.cpp index 72e26a51..b8de0653 100755 --- a/src/noggit/ui/tools/PreviewRenderer/PreviewRenderer.cpp +++ b/src/noggit/ui/tools/PreviewRenderer/PreviewRenderer.cpp @@ -701,9 +701,9 @@ void PreviewRenderer::unloadOpenglData() return; } - assert(context() != nullptr); - makeCurrent(); - OpenGL::context::scoped_setter const _ (::gl, context()); + //assert(context() != nullptr); + //makeCurrent(); + //OpenGL::context::scoped_setter const _ (::gl, context()); ModelManager::unload_all(_context); WMOManager::unload_all(_context); diff --git a/src/noggit/ui/windows/noggitWindow/NoggitWindow.cpp b/src/noggit/ui/windows/noggitWindow/NoggitWindow.cpp index d882c964..012e016e 100755 --- a/src/noggit/ui/windows/noggitWindow/NoggitWindow.cpp +++ b/src/noggit/ui/windows/noggitWindow/NoggitWindow.cpp @@ -600,6 +600,8 @@ namespace Noggit::Ui::Windows case QMessageBox::AcceptRole: _stack_widget->setCurrentIndex(0); _stack_widget->removeLast(); + + Noggit::Ui::Tools::ViewportManager::ViewportManager::unloadAll(); delete _map_view; _map_view = nullptr; _minimap->world(nullptr); @@ -807,8 +809,16 @@ namespace Noggit::Ui::Windows progress_box->repaint(); qApp->processEvents(); + try { + //if (!clientData->openArchiveForWriting(*archive)) + //{ + // QMessageBox::warning(this, "Error", "Failed to switch archive to writable mode."); + // progress_box->close(); + // return; + //} + auto start = std::chrono::high_resolution_clock::now(); std::array result = clientData->saveLocalFilesToArchive(archive.value(), mpq_compress_files_chk->isChecked(), mpq_compact_chk->isChecked()); @@ -820,9 +830,11 @@ namespace Noggit::Ui::Windows std::ostringstream oss; // duration in seconds with 1 digit oss << std::fixed << std::setprecision(1) << duration.count(); + // clientData->closeArchiveToReadOnly(*archive); + // if no file was processed, archive was most likely opened and not accessible // TODO : we can throw an error message in saveLocalFilesToArchive if (!archive->openForWritting()) instead - if (!processed_files) + if (processed_files <= 0) { QMessageBox::warning(this, "Error", "Project Folder is not a valid directory or client MPQ is not accessible.\ \nMake sure it isn't opened by Wow or MPQ editor"); @@ -833,6 +845,26 @@ namespace Noggit::Ui::Windows } + /* + catch (const BlizzardArchive::Exceptions::Archive::ArchiveOpenError& e) + { + + QMessageBox::critical(this, "Archive Access Error", + QString("Failed to open/close the archive for writing.\nDetails: %1").arg(e.what())); + } + catch (const BlizzardArchive::Exceptions::Archive::FileWriteFailedError& e) + { + + QMessageBox::critical(this, "File Write Error", + QString("A file operation failed during saving.\nDetails: %1").arg(e.what())); + } + + catch (const std::exception& e) + { + + QMessageBox::critical(this, "Standard Exception", + QString("An unexpected standard error occurred: %1").arg(e.what())); + }*/ catch (...) { QMessageBox::critical(nullptr, "Error", "unhandled exception"); diff --git a/src/noggit/world_model_instances_storage.cpp b/src/noggit/world_model_instances_storage.cpp index dfb88287..0aa191cd 100755 --- a/src/noggit/world_model_instances_storage.cpp +++ b/src/noggit/world_model_instances_storage.cpp @@ -401,7 +401,23 @@ namespace Noggit if (!_transform_storage_uploaded) return; - gl.deleteTextures(1, &_m2_instances_transform_buf_tex); + if (_m2_instances_transform_buf_tex) + { + GLuint texture_id = _m2_instances_transform_buf_tex; + + if (QOpenGLContext::currentContext()) + { + gl.deleteTextures(1, &texture_id); + } + else + { + gl.scheduleCleanup([texture_id]() mutable + { + gl.deleteTextures(1, &texture_id); + } + ); + } + } _buffers.unload(); _transform_storage_uploaded = false; diff --git a/src/opengl/context.cpp b/src/opengl/context.cpp index f6e3a5b7..afdb25dc 100755 --- a/src/opengl/context.cpp +++ b/src/opengl/context.cpp @@ -53,4 +53,32 @@ namespace OpenGL { return _current_context; } + + void context::scheduleCleanup(std::function task) + { + QMutexLocker lock(&_cleanup_mutex); + _cleanup_queue.append(task); + } + + void context::processCleanup() + { + if (QOpenGLContext::currentContext() != _current_context) + { + // must be called after the context is made current + assert(QOpenGLContext::currentContext() == _current_context); + + return; + } + + QList> tasks_to_process; + { + QMutexLocker lock(&_cleanup_mutex); + _cleanup_queue.swap(tasks_to_process); + } + + for (const auto& task : tasks_to_process) + { + task(); + } + } } diff --git a/src/opengl/context.hpp b/src/opengl/context.hpp index 53868936..960f7697 100755 --- a/src/opengl/context.hpp +++ b/src/opengl/context.hpp @@ -3,6 +3,9 @@ #pragma once #include #include +#include +#include +#include // NOGGIT_FORCEINLINE ---------------------------------------------// // Macro to use in place of 'inline' to force a function to be inline @@ -55,6 +58,12 @@ namespace OpenGL QOpenGLContext* _current_context = nullptr; QOpenGLFunctions_4_1_Core* _4_1_core_func = nullptr; + QMutex _cleanup_mutex; + QList> _cleanup_queue; + + void scheduleCleanup(std::function task); + void processCleanup(); + NOGGIT_FORCEINLINE bool has_extension(std::string const& name); NOGGIT_FORCEINLINE void enable (GLenum); diff --git a/src/opengl/scoped.hpp b/src/opengl/scoped.hpp index 0417758f..e17a44ca 100755 --- a/src/opengl/scoped.hpp +++ b/src/opengl/scoped.hpp @@ -101,7 +101,7 @@ namespace OpenGL private: bool _buffer_generated = false; - GLuint _buffers[count]; + GLuint _buffers[count] = { 0 }; }; template @@ -139,7 +139,7 @@ namespace OpenGL private: bool _buffer_generated = false; - GLuint _vertex_arrays[count]; + GLuint _vertex_arrays[count] = { 0 }; }; template @@ -160,7 +160,7 @@ namespace OpenGL private: bool _texture_generated = false; - GLuint _textures[count]; + GLuint _textures[count] = { 0 }; }; template diff --git a/src/opengl/scoped.ipp b/src/opengl/scoped.ipp index 5b301b27..0444214b 100755 --- a/src/opengl/scoped.ipp +++ b/src/opengl/scoped.ipp @@ -139,17 +139,38 @@ namespace OpenGL template void deferred_upload_buffers::unload() { - gl.deleteBuffers(count, _buffers); - _buffer_generated = false; + for (int i = 0; i < count; ++i) + { + GLuint& buffer_id = _buffers[i]; + + if (buffer_id == 0) + { + continue; + } + + if (QOpenGLContext::currentContext() && ::gl.getCurrentContext() != nullptr) + { + gl.deleteBuffers(1, &buffer_id); + } + else + { + gl.scheduleCleanup([buffer_id]() mutable + { + gl.deleteBuffers(1, &buffer_id); + } + ); + } + + buffer_id = 0; + } + + _buffer_generated = false; } template deferred_upload_buffers::~deferred_upload_buffers() { - if (_buffer_generated) - { - gl.deleteBuffers (count, _buffers); - } + unload(); } template @@ -186,8 +207,31 @@ namespace OpenGL template void deferred_upload_vertex_arrays::unload() { - gl.deleteVertexArray(count, _vertex_arrays); - _buffer_generated = false; + for (int i = 0; i < count; ++i) + { + GLuint& vertex_array_id = _vertex_arrays[i]; + + if (vertex_array_id == 0) + { + continue; + } + + if (QOpenGLContext::currentContext() && ::gl.getCurrentContext() != nullptr) + { + gl.deleteVertexArray(1, &vertex_array_id); + } + else + { + gl.scheduleCleanup([vertex_array_id]() mutable + { + gl.deleteVertexArray(1, &vertex_array_id); + } + ); + } + + vertex_array_id = 0; + } + _buffer_generated = false; } template @@ -195,7 +239,7 @@ namespace OpenGL { if (_buffer_generated) { - gl.deleteVertexArray (count, _vertex_arrays); + unload(); } } @@ -222,17 +266,38 @@ namespace OpenGL template void deferred_upload_textures::unload() { - gl.deleteTextures(count, _textures); - _texture_generated = false; + for (int i = 0; i < count; ++i) + { + GLuint& texture_id = _textures[i]; + + if (texture_id == 0) + { + continue; + } + + if (QOpenGLContext::currentContext() && ::gl.getCurrentContext() != nullptr) + { + gl.deleteTextures(1, &texture_id); + } + else + { + gl.scheduleCleanup([texture_id]() mutable + { + gl.deleteTextures(1, &texture_id); + } + ); + } + + texture_id = 0; + } + + _texture_generated = false; } template deferred_upload_textures::~deferred_upload_textures() { - if (_texture_generated) - { - gl.deleteTextures(count, _textures); - } + unload(); } template diff --git a/src/opengl/shader.cpp b/src/opengl/shader.cpp index 61be7419..59059ecb 100755 --- a/src/opengl/shader.cpp +++ b/src/opengl/shader.cpp @@ -121,7 +121,20 @@ namespace OpenGL { if (_handle) { - gl.deleteProgram (*_handle); + if (QOpenGLContext::currentContext() && ::gl.getCurrentContext() != nullptr) + { + gl.deleteProgram(*_handle); + } + /*else + { + GLuint id = *_handle; + + gl.scheduleCleanup([id]() + { + gl.deleteProgram(id); + } + ); + }*/ } }