mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-26 14:56:39 +00:00 
			
		
		
		
	Retain final draw callback as a member variable in ScreenshotManager, and do not call setFinalDrawCallback after init.
This commit is contained in:
		
							parent
							
								
									3d61d7ec9a
								
							
						
					
					
						commit
						5b9a2b73b0
					
				
					 2 changed files with 34 additions and 17 deletions
				
			
		|  | @ -36,8 +36,8 @@ namespace MWRender | ||||||
|     class NotifyDrawCompletedCallback : public osg::Camera::DrawCallback |     class NotifyDrawCompletedCallback : public osg::Camera::DrawCallback | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         NotifyDrawCompletedCallback(unsigned int frame) |         NotifyDrawCompletedCallback() | ||||||
|             : mDone(false), mFrame(frame) |             : mDone(false), mFrame(0) | ||||||
|         { |         { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -59,6 +59,12 @@ namespace MWRender | ||||||
|             mCondition.wait(lock); |             mCondition.wait(lock); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         void reset(unsigned int frame) | ||||||
|  |         { | ||||||
|  |             mDone = false; | ||||||
|  |             mFrame = frame; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         mutable std::condition_variable mCondition; |         mutable std::condition_variable mCondition; | ||||||
|         mutable std::mutex mMutex; |         mutable std::mutex mMutex; | ||||||
|         mutable bool mDone; |         mutable bool mDone; | ||||||
|  | @ -94,8 +100,18 @@ namespace MWRender | ||||||
|         : mViewer(viewer) |         : mViewer(viewer) | ||||||
|         , mRootNode(rootNode) |         , mRootNode(rootNode) | ||||||
|         , mSceneRoot(sceneRoot) |         , mSceneRoot(sceneRoot) | ||||||
|  |         , mDrawCompleteCallback(new NotifyDrawCompletedCallback) | ||||||
|         , mResourceSystem(resourceSystem) |         , mResourceSystem(resourceSystem) | ||||||
|         , mWater(water) |         , mWater(water) | ||||||
|  |     { | ||||||
|  |         // Note: This assumes no other final draw callbacks are set anywhere and that this callback will remain set until the application exits.
 | ||||||
|  |         // This works around *DrawCallback manipulation being unsafe in OSG >= 3.5.10 for release 0.47
 | ||||||
|  |         // If you need to set other final draw callbacks, read the comments of issue 6013 for a suggestion
 | ||||||
|  |         // Ref https://gitlab.com/OpenMW/openmw/-/issues/6013
 | ||||||
|  |         mViewer->getCamera()->setFinalDrawCallback(mDrawCompleteCallback); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ScreenshotManager::~ScreenshotManager() | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -107,16 +123,10 @@ namespace MWRender | ||||||
|         tempDrw->setCullingActive(false); |         tempDrw->setCullingActive(false); | ||||||
|         tempDrw->getOrCreateStateSet()->setRenderBinDetails(100, "RenderBin", osg::StateSet::USE_RENDERBIN_DETAILS); // so its after all scene bins but before POST_RENDER gui camera
 |         tempDrw->getOrCreateStateSet()->setRenderBinDetails(100, "RenderBin", osg::StateSet::USE_RENDERBIN_DETAILS); // so its after all scene bins but before POST_RENDER gui camera
 | ||||||
|         camera->addChild(tempDrw); |         camera->addChild(tempDrw); | ||||||
|         osg::ref_ptr<NotifyDrawCompletedCallback> callback (new NotifyDrawCompletedCallback(mViewer->getFrameStamp()->getFrameNumber())); |         traversalsAndWait(mViewer->getFrameStamp()->getFrameNumber()); | ||||||
|         camera->setFinalDrawCallback(callback); |  | ||||||
|         mViewer->eventTraversal(); |  | ||||||
|         mViewer->updateTraversal(); |  | ||||||
|         mViewer->renderingTraversals(); |  | ||||||
|         callback->waitTillDone(); |  | ||||||
|         // now that we've "used up" the current frame, get a fresh frame number for the next frame() following after the screenshot is completed
 |         // now that we've "used up" the current frame, get a fresh frame number for the next frame() following after the screenshot is completed
 | ||||||
|         mViewer->advance(mViewer->getFrameStamp()->getSimulationTime()); |         mViewer->advance(mViewer->getFrameStamp()->getSimulationTime()); | ||||||
|         camera->removeChild(tempDrw); |         camera->removeChild(tempDrw); | ||||||
|         camera->setFinalDrawCallback(nullptr); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     bool ScreenshotManager::screenshot360(osg::Image* image) |     bool ScreenshotManager::screenshot360(osg::Image* image) | ||||||
|  | @ -257,6 +267,15 @@ namespace MWRender | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     void ScreenshotManager::traversalsAndWait(unsigned int frame) | ||||||
|  |     { | ||||||
|  |         mDrawCompleteCallback->reset(frame); | ||||||
|  |         mViewer->eventTraversal(); | ||||||
|  |         mViewer->updateTraversal(); | ||||||
|  |         mViewer->renderingTraversals(); | ||||||
|  |         mDrawCompleteCallback->waitTillDone(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     void ScreenshotManager::renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h) |     void ScreenshotManager::renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h) | ||||||
|     { |     { | ||||||
|         camera->setNodeMask(Mask_RenderToTexture); |         camera->setNodeMask(Mask_RenderToTexture); | ||||||
|  | @ -280,16 +299,10 @@ namespace MWRender | ||||||
| 
 | 
 | ||||||
|         mRootNode->addChild(camera); |         mRootNode->addChild(camera); | ||||||
| 
 | 
 | ||||||
|         // The draw needs to complete before we can copy back our image.
 |  | ||||||
|         osg::ref_ptr<NotifyDrawCompletedCallback> callback (new NotifyDrawCompletedCallback(0)); |  | ||||||
|         camera->setFinalDrawCallback(callback); |  | ||||||
| 
 |  | ||||||
|         MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOn(false); |         MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOn(false); | ||||||
| 
 | 
 | ||||||
|         mViewer->eventTraversal(); |         // The draw needs to complete before we can copy back our image.
 | ||||||
|         mViewer->updateTraversal(); |         traversalsAndWait(0); | ||||||
|         mViewer->renderingTraversals(); |  | ||||||
|         callback->waitTillDone(); |  | ||||||
| 
 | 
 | ||||||
|         MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOff(); |         MWBase::Environment::get().getWindowManager()->getLoadingScreen()->loadingOff(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -16,11 +16,13 @@ namespace Resource | ||||||
| namespace MWRender | namespace MWRender | ||||||
| { | { | ||||||
|     class Water; |     class Water; | ||||||
|  |     class NotifyDrawCompletedCallback; | ||||||
| 
 | 
 | ||||||
|     class ScreenshotManager |     class ScreenshotManager | ||||||
|     { |     { | ||||||
|     public: |     public: | ||||||
|         ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, osg::ref_ptr<osg::Group> sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water); |         ScreenshotManager(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> rootNode, osg::ref_ptr<osg::Group> sceneRoot, Resource::ResourceSystem* resourceSystem, Water* water); | ||||||
|  |         ~ScreenshotManager(); | ||||||
| 
 | 
 | ||||||
|         void screenshot(osg::Image* image, int w, int h); |         void screenshot(osg::Image* image, int w, int h); | ||||||
|         bool screenshot360(osg::Image* image); |         bool screenshot360(osg::Image* image); | ||||||
|  | @ -29,9 +31,11 @@ namespace MWRender | ||||||
|         osg::ref_ptr<osgViewer::Viewer> mViewer; |         osg::ref_ptr<osgViewer::Viewer> mViewer; | ||||||
|         osg::ref_ptr<osg::Group> mRootNode; |         osg::ref_ptr<osg::Group> mRootNode; | ||||||
|         osg::ref_ptr<osg::Group> mSceneRoot; |         osg::ref_ptr<osg::Group> mSceneRoot; | ||||||
|  |         osg::ref_ptr<NotifyDrawCompletedCallback> mDrawCompleteCallback; | ||||||
|         Resource::ResourceSystem* mResourceSystem; |         Resource::ResourceSystem* mResourceSystem; | ||||||
|         Water* mWater; |         Water* mWater; | ||||||
| 
 | 
 | ||||||
|  |         void traversalsAndWait(unsigned int frame); | ||||||
|         void renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h); |         void renderCameraToImage(osg::Camera *camera, osg::Image *image, int w, int h); | ||||||
|         void makeCubemapScreenshot(osg::Image* image, int w, int h, osg::Matrixd cameraTransform=osg::Matrixd()); |         void makeCubemapScreenshot(osg::Image* image, int w, int h, osg::Matrixd cameraTransform=osg::Matrixd()); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue