Switch Workspace on render thread at runtime assert Topic is solved

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Lax
Gnoll
Posts: 683
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 65

Switch Workspace on render thread at runtime assert

Post by Lax »

Hi,

I create a workspace on render thread at runtime for another camera. In that case something goes wrong with workspace shadow compositornode "ShadowNode Camera ID 50 Map 0" and its frustum.

min = {x=-nan(ind) y=0.00000000 z=0.00000000 }
max = {x=-nan(ind) y=0.00000000 z=0.00000000 }

So I get an assert:

Code: Select all

inline void setExtents( const Vector3 &min, const Vector3 &max )
{
    assert( ( min.x <= max.x && min.y <= max.y && min.z <= max.z ) &&
            "The minimum corner of the box must be less than or equal to maximum corner" );

mExtent = EXTENT_FINITE;
mMinimum = min;
mMaximum = max;
}

It comes from a compositor shadow node, when updating frustum. I will appear, if i activate another Ogre::Camera and re-create the workspace on the fly.

I call from lua script camera:setActivated(true), so that the GamePlayCamera takes control and internally creates a workspace for the camera. I use this command:

Code: Select all

void setActivated(CameraComponent* instance, bool activated)
{
	NOWA::AppStateManager::getSingletonPtr()->bStall = true;
	NOWA::ProcessPtr delayProcess(new NOWA::DelayProcess(0.25f));
	auto ptrFunction = [instance, activated]()
	{
		ENQUEUE_RENDER_COMMAND_MULTI_WAIT_NO_THIS("Camera::setActivated from Lua", _2(instance, activated),
		{
			instance->setActivated(activated);
			NOWA::AppStateManager::getSingletonPtr()->bStall = false;
		});
	};
	NOWA::ProcessPtr closureProcess(new NOWA::ClosureProcess(ptrFunction));
	delayProcess->attachChild(closureProcess);
	NOWA::ProcessManager::getInstance()->attachProcess(delayProcess);
}

This is the stacktrace:

Code: Select all

OgreMain_d.dll!Ogre::AxisAlignedBox::setExtents(const Ogre::Vector3 & min={...}, const Ogre::Vector3 & max={...}) Zeile 233	C++
	OgreMain_d.dll!Ogre::Frustum::updateFrustumImpl() Zeile 601	C++
 	OgreMain_d.dll!Ogre::Frustum::updateFrustum() Zeile 613	C++
 	OgreMain_d.dll!Ogre::Frustum::getProjectionMatrixWithRSDepth() Zeile 207	C++
	
OgreMain_d.dll!Ogre::RenderQueue::renderPassPrepare(bool casterPass=true, bool dualParaboloid=false) Zeile 324	C++
OgreMain_d.dll!Ogre::SceneManager::_cullPhase01(Ogre::Camera * cullCamera=0x000002c8dbb7cef0, Ogre::Camera * renderCamera=0x000002c8dbb7cef0, const Ogre::Camera * lodCamera=0x000002c8dbb7f7d0, unsigned char firstRq='\0', unsigned char lastRq='ÿ', bool reuseCullData=false) Zeile 1321	C++
OgreMain_d.dll!Ogre::Camera::_cullScenePhase01(Ogre::Camera * renderCamera=0x000002c8dbb7cef0, const Ogre::Camera * lodCamera=0x000002c8dbb7f7d0, Ogre::Viewport * vp=0x000002c8a75c6340, unsigned char firstRq='\0', unsigned char lastRq='ÿ', bool reuseCullData=false) Zeile 379	C++
OgreMain_d.dll!Ogre::Viewport::_updateCullPhase01(Ogre::Camera * renderCamera=0x000002c8dbb7cef0, Ogre::Camera * cullCamera=0x000002c8dbb7cef0, const Ogre::Camera * lodCamera=0x000002c8dbb7f7d0, unsigned char firstRq='\0', unsigned char lastRq='ÿ', bool reuseCullData=false) Zeile 201	C++
OgreMain_d.dll!Ogre::CompositorPassScene::execute(const Ogre::Camera * lodCamera=0x000002c8dbb7f7d0) Zeile 308	C++
OgreMain_d.dll!Ogre::CompositorNode::_update(const Ogre::Camera * lodCamera=0x000002c8dbb7f7d0, Ogre::SceneManager * sceneManager=0x000002c8dbcfa070) Zeile 836	C++
OgreMain_d.dll!Ogre::CompositorShadowNode::_update(Ogre::Camera * camera=0x000002c8dbb7f7d0, const Ogre::Camera * lodCamera=0x000002c8dbb7f7d0, Ogre::SceneManager * sceneManager=0x000002c8dbcfa070) Zeile 648	C++
OgreMain_d.dll!Ogre::CompositorPassScene::execute(const Ogre::Camera * lodCamera=0x0000000000000000) Zeile 259	C++
OgreMain_d.dll!Ogre::CompositorNode::_update(const Ogre::Camera * lodCamera=0x0000000000000000, Ogre::SceneManager * sceneManager=0x000002c8dbcfa070) Zeile 836	C++
OgreMain_d.dll!Ogre::CompositorWorkspace::_update(const bool bInsideAutoreleasePool=true) Zeile 898	C++
OgreMain_d.dll!Ogre::CompositorManager2::_updateImplementation() Zeile 791	C++
OgreMain_d.dll!Ogre::RenderSystem::updateCompositorManager(Ogre::CompositorManager2 * compositorManager=0x000002c8aff048a0) Zeile 1316	C++
OgreMain_d.dll!Ogre::CompositorManager2::_update() Zeile 713	C++
OgreMain_d.dll!Ogre::Root::_updateAllRenderTargets() Zeile 1573	C++
OgreMain_d.dll!Ogre::Root::renderOneFrame() Zeile 1104	C++
NOWA_Engine_d.dll!NOWA::GraphicsModule::renderThreadFunction() Zeile 166	C++
 

How can I fix that?
Can I set somehow maybe nearclip and farclip distance for shadow camera manually? Or call another Ogre function, which does update shadow cameras correctly?

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Lax
Gnoll
Posts: 683
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 65

Re: Switch Workspace on render thread at runtime assert

Post by Lax »

Hi put in another words:

I orientated on the Ogre-Next Multithreading Sample. But there is no workspace switch with different camera at runtime. But that is what I do.
If my simulation starts. I change from MainCamera to a GamePlay Camera. I destroy the workspace for the MainCamera and create a workspace for the GamePlay Camera at render thread. So I enqueue a command closure, which is executed on the render thread to do that.

But then its getting weird and I get an assert and crash because of:

Code: Select all

min = {x=-nan(ind) y=0.00000000 z=0.00000000 }
max = {x=-nan(ind) y=0.00000000 z=0.00000000 }

inline void setExtents( const Vector3 &min, const Vector3 &max )
{
    assert( ( min.x <= max.x && min.y <= max.y && min.z <= max.z ) &&
            "The minimum corner of the box must be less than or equal to maximum corner" );

mExtent = EXTENT_FINITE;
mMinimum = min;
mMaximum = max;
}

From a ShadowNode "ShadowNode Camera ID 50 Map 0", because somehow somewhere bounding box values are invalid.
What is going on?

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Lax
Gnoll
Posts: 683
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 65

Re: Switch Workspace on render thread at runtime assert

Post by Lax »

Nevermind,

I think I got it. It was because I to often switched the workspace and I missed to call reconnectAllNodes.

Its really hard to deal with Ogre stuff on rendering thread and having a main thread for logic...

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62

Lax
Gnoll
Posts: 683
Joined: Mon Aug 06, 2007 12:53 pm
Location: Saarland, Germany
x 65

Re: Switch Workspace on render thread at runtime assert

Post by Lax »

Ok, there are several errors using ShadowNodes, if workspace is switched during runtime in a render thread.
I get for example a runtime error here in Ogre:

Code: Select all

void CompositorNode::_update( const Camera *lodCamera, SceneManager *sceneManager )
{
    // If we're in a caster pass, we need to skip shadow map passes that have no light associated
    const CompositorShadowNode *shadowNode = 0;
    if( sceneManager->_getCurrentRenderStage() == SceneManager::IRS_RENDER_TO_TEXTURE )
        shadowNode = sceneManager->getCurrentShadowNode();
    uint8 executionMask = mWorkspace->getExecutionMask();

// Execute our passes
CompositorPassVec::const_iterator itor = mPasses.begin();
CompositorPassVec::const_iterator endt = mPasses.end();

while( itor != endt )
{
    CompositorPass *pass = *itor;
    const CompositorPassDef *passDef = pass->getDefinition();

    const CompositorTargetDef *targetDef = passDef->getParentTargetDef();

    if( executionMask & passDef->mExecutionMask &&
        ( !shadowNode || ( !shadowNode->isShadowMapIdxInValidRange( passDef->mShadowMapIdx ) ||
                           ( shadowNode->_shouldUpdateShadowMapIdx( passDef->mShadowMapIdx ) &&
                             ( shadowNode->getShadowMapLightTypeMask( passDef->mShadowMapIdx ) &
                               targetDef->getShadowMapSupportedLightTypes() ) ) ) ) )
    {
        // Make explicitly exposed textures available to materials during this pass.
        const size_t oldNumTextures = sceneManager->getNumCompositorTextures();
        IdStringVec::const_iterator itExposed = passDef->mExposedTextures.begin();
        IdStringVec::const_iterator enExposed = passDef->mExposedTextures.end();

        while( itExposed != enExposed )
        {
            TextureGpu *exposedChannel = this->getDefinedTexture( *itExposed );
            sceneManager->_addCompositorTexture( *itExposed, exposedChannel );
            ++itExposed;
        }

        // Execute pass
        pass->execute( lodCamera );

        // Remove our textures
        sceneManager->_removeCompositorTextures( oldNumTextures );
    }
    ++itor;
}
}

Expression: can't increment invalidated vector iterator

I have no idea, what is going on, but the ShadowNodes do cause really trouble. Maybe a bug in Ogre-Next?
Maybe the Sample Multithreaded should be extended for Switching a workspace for a different camera at runtime?

Best Regards
Lax

http://www.lukas-kalinowski.com/Homepage/?page_id=1631
Please support Second Earth Technic Base built of Lego bricks for Lego ideas: https://ideas.lego.com/projects/81b9bd1 ... b97b79be62