Browse Source

Add explicit OpenGL cleanup before QML engine destruction

Co-authored-by: djeada <[email protected]>
copilot-swe-agent[bot] 1 month ago
parent
commit
d28d7418e7
3 changed files with 50 additions and 4 deletions
  1. 33 0
      app/core/game_engine.cpp
  2. 2 0
      app/core/game_engine.h
  3. 15 4
      main.cpp

+ 33 - 0
app/core/game_engine.cpp

@@ -295,6 +295,39 @@ GameEngine::~GameEngine() {
   qInfo() << "AudioSystem shut down";
 }
 
+void GameEngine::cleanupOpenGLResources() {
+  qInfo() << "Cleaning up OpenGL resources...";
+  
+  // Shutdown renderer and all OpenGL-dependent resources
+  // Must be called while OpenGL context is still valid
+  if (m_renderer) {
+    m_renderer->shutdown();
+    qInfo() << "Renderer shut down";
+  }
+  
+  // Clear render passes that reference renderer resources
+  m_passes.clear();
+  
+  // Reset all renderer-dependent unique_ptrs
+  m_ground.reset();
+  m_terrain.reset();
+  m_biome.reset();
+  m_river.reset();
+  m_riverbank.reset();
+  m_bridge.reset();
+  m_fog.reset();
+  m_stone.reset();
+  m_plant.reset();
+  m_pine.reset();
+  m_firecamp.reset();
+  
+  // Reset renderer and resources
+  m_renderer.reset();
+  m_resources.reset();
+  
+  qInfo() << "OpenGL resources cleaned up";
+}
+
 void GameEngine::onMapClicked(qreal sx, qreal sy) {
   if (m_window == nullptr) {
     return;

+ 2 - 0
app/core/game_engine.h

@@ -80,6 +80,8 @@ public:
   explicit GameEngine(QObject *parent = nullptr);
   ~GameEngine() override;
 
+  void cleanupOpenGLResources();
+
   Q_PROPERTY(QObject *selectedUnitsModel READ selectedUnitsModel NOTIFY
                  selectedUnitsChanged)
   Q_PROPERTY(bool paused READ paused WRITE setPaused)

+ 15 - 4
main.cpp

@@ -369,13 +369,24 @@ auto main(int argc, char *argv[]) -> int {
   int const result = QGuiApplication::exec();
 
   // Explicitly destroy in correct order to prevent segfault
-  // QML engine must be destroyed first, then game objects
+  // Must cleanup OpenGL resources before destroying QML engine/window
   qInfo() << "Shutting down...";
-  engine.reset();  // Destroy QML engine first
+  
+  // Clean up OpenGL resources while context is still valid
+  if (game_engine) {
+    game_engine->cleanupOpenGLResources();
+  }
+  
+  // Now safe to destroy QML engine (and OpenGL context)
+  engine.reset();
   qInfo() << "QML engine destroyed";
-  game_engine.reset();  // Then destroy game engine
+  
+  // Then destroy game engine (non-OpenGL cleanup in destructor)
+  game_engine.reset();
   qInfo() << "GameEngine destroyed";
-  language_manager.reset();  // Finally destroy language manager
+  
+  // Finally destroy language manager
+  language_manager.reset();
   qInfo() << "LanguageManager destroyed";
 
 #ifdef Q_OS_WIN