// Install a callback to set the OpenGL/WebGPU overrides.
// This is done here to ensure that the callback is called whenever a new factory is registered
// with the vtkObjectFactory.
vtkNew<vtkCallbackCommand> callbackCommand;
callbackCommand->SetCallback(
  [](vtkObject* caller, unsigned long eid, void*, void*)
  {
    if (eid != vtkCommand::ModifiedEvent)
    {
      return;
    }
    if (auto collection = vtkObjectFactoryCollection::SafeDownCast(caller))
    {
      // defaults
      int useOpenGL = 1;
      int useWebGPU = 0;
      // Query the environmental for backend to use.
      if (const char* p = std::getenv("VTK_GRAPHICS_BACKEND"))
      {
        const std::string backend(p);
        if (backend == "OPENGL")
        {
          useWebGPU = 0;
          useOpenGL = 1;
        }
        else if (backend == "WEBGPU")
        {
          useWebGPU = 1;
          useOpenGL = 0;
        }
        else
        {
          std::cerr << "Unknown backend '" << backend << "' specified. Using default OPENGL.\n";
        }
      }

      vtkObjectFactory* factory = nullptr;
      vtkCollectionSimpleIterator osit;
      for (collection->InitTraversal(osit); (factory = collection->GetNextObjectFactory(osit));)
      {
        if (factory->HasOverride("vtkActor"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkActor", "vtkWebGPUActor");
          factory->SetEnableFlag(useOpenGL, "vtkActor", "vtkOpenGLActor");
        }
        if (factory->HasOverride("vtkCamera"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkCamera", "vtkWebGPUCamera");
          factory->SetEnableFlag(useOpenGL, "vtkCamera", "vtkOpenGLCamera");
        }
        if (factory->HasOverride("vtkGlyph3DMapper"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkGlyph3DMapper", "vtkWebGPUGlyph3DMapper");
          factory->SetEnableFlag(useOpenGL, "vtkGlyph3DMapper", "vtkOpenGLGlyph3DMapper");
        }
        if (factory->HasOverride("vtkHardwareSelector"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkHardwareSelector", "vtkWebGPUHardwareSelector");
          factory->SetEnableFlag(useOpenGL, "vtkHardwareSelector", "vtkOpenGLHardwareSelector");
        }
        if (factory->HasOverride("vtkLight"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkLight", "vtkWebGPULight");
          factory->SetEnableFlag(useOpenGL, "vtkLight", "vtkOpenGLLight");
        }
        if (factory->HasOverride("vtkPolyDataMapper"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkPolyDataMapper", "vtkWebGPUPolyDataMapper");
          factory->SetEnableFlag(useOpenGL, "vtkPolyDataMapper", "vtkOpenGLPolyDataMapper");
          factory->SetEnableFlag(
            useOpenGL, "vtkPolyDataMapper", "vtkOpenGLLowMemoryPolyDataMapper");
          factory->SetEnableFlag(useWebGPU, "vtkCompositePolyDataMapperDelegator",
            "vtkWebGPUCompositePolyDataMapperDelegator");
          factory->SetEnableFlag(useOpenGL, "vtkCompositePolyDataMapperDelegator",
            "vtkOpenGLCompositePolyDataMapperDelegator");
        }
        if (factory->HasOverride("vtkPolyDataMapper2D"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkPolyDataMapper2D", "vtkWebGPUPolyDataMapper2D");
          factory->SetEnableFlag(useOpenGL, "vtkPolyDataMapper2D", "vtkOpenGLPolyDataMapper2D");
          factory->SetEnableFlag(useOpenGL, "vtkPolyDataMapper2D", "vtkOpenGLES30PolyDataMapper2D");
        }
        if (factory->HasOverride("vtkShaderProperty"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkShaderProperty", "vtkWebGPUShaderProperty");
          factory->SetEnableFlag(useOpenGL, "vtkShaderProperty", "vtkOpenGLShaderProperty");
        }
        if (factory->HasOverride("vtkProperty"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkProperty", "vtkWebGPUProperty");
          factory->SetEnableFlag(useOpenGL, "vtkProperty", "vtkOpenGLProperty");
        }
        if (factory->HasOverride("vtkRenderer"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkRenderer", "vtkWebGPURenderer");
          factory->SetEnableFlag(useOpenGL, "vtkRenderer", "vtkOpenGLRenderer");
        }
        if (factory->HasOverride("vtkRenderWindow"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkRenderWindow", "vtkWebAssemblyWebGPURenderWindow");
          // disable/enable ALL opengl render window overrides.
          factory->SetEnableFlag(useOpenGL, "vtkRenderWindow", "vtkOpenGLRenderWindow");
          factory->SetEnableFlag(useOpenGL, "vtkRenderWindow", "vtkCocoaRenderWindow");
          factory->SetEnableFlag(useOpenGL, "vtkRenderWindow", "vtkWin32OpenGLRenderWindow");
          factory->SetEnableFlag(useOpenGL, "vtkRenderWindow", "vtkXOpenGLRenderWindow");
          factory->SetEnableFlag(useOpenGL, "vtkRenderWindow", "vtkWebAssemblyOpenGLRenderWindow");
        }
        if (factory->HasOverride("vtkTexture"))
        {
          factory->SetEnableFlag(useWebGPU, "vtkTexture", "vtkWebGPUTexture");
          factory->SetEnableFlag(useOpenGL, "vtkTexture", "vtkOpenGLTexture");
        }
      }
    }
  });
vtkObjectFactory::GetRegisteredFactories()->AddObserver(vtkCommand::ModifiedEvent, callbackCommand);
