OGRECave/ogre-imgui

Crash when adding light with button

Closed this issue · 5 comments

My app is crashing when creating a light from an ImGui button. I have tested the light creation code in my createScene method and it works. I have also had this same crash when using Ogre add on Caelum.

ImGuiManager.cpp line 251.
Pass * pass = mRenderable.mMaterial->getBestTechnique()->getPass(0);

Get pass method asserts. OgreTechnique.cpp line 321.
assert(index < mPasses.size() && "Index out of bounds");

Callstack

 	OgreMain_d.dll!std::vector<Ogre::Pass *,std::allocator<Ogre::Pass *> >::size() Line 1704	C++
 	OgreMain_d.dll!Ogre::Technique::getPass(unsigned short index) Line 321	C++
>	Project2.exe!Ogre::ImguiManager::renderQueueEnded(unsigned char queueGroupId, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & invocation, bool & repeatThisInvocation) Line 251	C++
 	OgreMain_d.dll!Ogre::SceneManager::fireRenderQueueEnded(unsigned char id, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & invocation) Line 2800	C++
 	OgreMain_d.dll!Ogre::SceneManager::renderVisibleObjectsDefaultSequence() Line 1799	C++
 	OgreMain_d.dll!Ogre::SceneManager::_renderVisibleObjects() Line 1715	C++
 	OgreMain_d.dll!Ogre::SceneManager::_renderScene(Ogre::Camera * camera, Ogre::Viewport * vp, bool includeOverlays) Line 1479	C++
 	OgreMain_d.dll!Ogre::Camera::_renderScene(Ogre::Viewport * vp, bool includeOverlays) Line 418	C++
 	OgreMain_d.dll!Ogre::Viewport::update() Line 222	C++
 	OgreMain_d.dll!Ogre::RenderTarget::_updateViewport(Ogre::Viewport * viewport, bool updateStatistics) Line 204	C++
 	OgreMain_d.dll!Ogre::RenderTarget::_updateAutoUpdatedViewports(bool updateStatistics) Line 181	C++
 	OgreMain_d.dll!Ogre::RenderTarget::updateImpl() Line 158	C++
 	OgreMain_d.dll!Ogre::RenderTarget::update(bool swap) Line 571	C++
 	OgreMain_d.dll!Ogre::RenderSystem::_updateAllRenderTargets(bool swapBuffers) Line 194	C++
 	OgreMain_d.dll!Ogre::Root::_updateAllRenderTargets() Line 1312	C++
 	OgreMain_d.dll!Ogre::Root::renderOneFrame() Line 876	C++
 	Project2.exe!WinMain(HINSTANCE__ * hInst, HINSTANCE__ * __formal, char * strCmdLine, int __formal) Line 21	C++
 	[External Code]	
 	[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]	Unknown

After a bit of further testing it seems adding any light after my main loop has began triggers this. For example if your players avatar has a flashlight and turns it on (creating a light) ImGuiManager crashes at this point.

paroj commented

frameStarted may be called before your createScene. Verify that the call ordering is correct and that all your pointers are NULL initialized. De-referencing uninitialized memory may destroy the stack and lead to crashes in unrelated code.

I made sure all my pointers are set to NULL first thing in my setup() function. I forgot to mention the exception in my first post:

Exception thrown: read access violation.
std::_Vector_alloc<std::_Vec_base_types<Ogre::Pass *,std::allocator<Ogre::Pass *> > >::_Mylast(...) returned 0x8.

Line 704 of vector.h

// return length of sequence
		return (static_cast<size_type>(this->_Mylast() - this->_Myfirst()));

Pointer "this" shows NULL value. 'this' is mPasses in Ogre::Technique::getPass. In my original post I said getPass asserts. This is untrue as vector throws an exception trying to access the NULL pointer.

note:

I have a GUI toggle bool in my program. When set to false GUI isn't rendered and creating a light with the keyboard works. The same key press throws the exception above when GUI is rendered. When I toggle GUI to render after adding the light the program still crashes.

As it stands I can't create a light during runtime with ImGui.

While debugging mRenderable.material I noticed mSupportedTechniques was 0 after creating a light run time. While running ImGui without creating the light the same pointer shows mSupportedTechnique { size=1 } which I assume is normal operation.

I found a work around. I added the following before getPass is called.

			if (mRenderable.mMaterial->getSupportedTechniques().empty())
			{
				mRenderable.mMaterial->load();
			}

getPass is deprecated for getPasses. Reading the documentation for this I read that if the list is empty try calling Material::load. Thanks for the great documentation in Ogre!

I will submit a pull request.