Sign in to follow this  

SDL and Ogre3D not shutting down cleanly

This topic is 1197 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I currently open an SDL window (without creating an OpenGL context) and have Ogre3D render to SDL's window. This works until shutdown, that's when the following error occurs:
 

*-*-* OGRE Shutdown
Unregistering ResourceManager for type Compositor
Unregistering ResourceManager for type Skeleton
Unregistering ResourceManager for type Mesh
Unregistering ResourceManager for type HighLevelGpuProgram
Uninstalling plugin: GL RenderSystem
Unregistering ResourceManager for type GpuProgram
******************************
*** Stopping GLX Subsystem ***
******************************
Unregistering ResourceManager for type Texture
X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  4 (X_DestroyWindow)
  Resource id in failed request:  0x6c00002
  Serial number of failed request:  21
  Current serial number in output stream:  23
 
Here is the code for initialising Ogre3D:
 

RenderSystem::RenderSystem() :
    m_Root(new Ogre::Root("","","Ogre.log")),
    m_SceneMgr(nullptr),
    m_RenderWindow(nullptr),
    m_RootSceneNode(nullptr),
    m_WindowHandle(0),
    m_Window(nullptr)
{
    // The idea here is to open an SDL window *without* creating a GL context
    // and let Ogre create its own GL context, since it seems to be a little
    // sensitive when given an external one.
    // Ogre can be instructed to render to an external window, namely the one
    // SDL created.
 
    // TODO get window width and height from somewhere (config file?)
    unsigned int windowWidth = 800;
    unsigned int windowHeight = 600;
 
    // Create SDL Window without OpenGL context
    m_Window = SDL_CreateWindow( "Window",
                                 SDL_WINDOWPOS_CENTERED,
                                 SDL_WINDOWPOS_CENTERED,
                                 windowWidth,
                                 windowHeight,
                                 SDL_WINDOWPOS_CENTERED|SDL_WINDOW_RESIZABLE // TODO Add window resize support
                                 );
 
    // Prepare Ogre render window parameters
    Ogre::NameValuePairList lParams;
    lParams["FSAA"] = "0";
    lParams["vsync"] = "true";
    lParams["macAPI"] = "carbon";
 
    // Get SDL window handle and insert into parameter list so ogre knows which
    // external window to use.
    SDL_SysWMinfo info;
    SDL_VERSION(&info.version);
    SDL_GetWindowWMInfo( m_Window, &info );
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
    size_t winHandle = reinterpret_cast<size_t>(info.info.win.window);
    lParams["externalWindowHandle"] = Ogre::StringConverter::toString(winHandle);
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
    size_t winHandle = reinterpret_cast<size_t>(info.info.x11.window);
    lParams["parentWindowHandle"] = Ogre::StringConverter::toString(winHandle);
#else
#   error Defined OGRE_PLATFORM not supported
#endif
 
 
    // Load the GL Rendersystem and set up
    Ogre::String renderer = "./RenderSystem_GL";
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 && defined(_DEBUG)
    renderer.append("_d");
#endif
    m_Root->loadPlugin( renderer );
    Ogre::RenderSystem* renderSystem = m_Root->getAvailableRenderers()[0];
    m_Root->setRenderSystem(renderSystem);
 
    // Initialise ogre to use the SDL window
    m_Root->initialise( false, "", "" );
    m_RenderWindow = m_Root->createRenderWindow( "Window", windowWidth, windowHeight, false, &lParams );
}
 
Here is the code for shutting down:
 

RenderSystem::~RenderSystem()
{
 
    // Shut down ogre
    m_Root->destroySceneManager( m_SceneMgr );
    delete m_Root;
 
    SDL_DestroyWindow(m_Window);
}
 
I'm running on Ubuntu, Linux and am using g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2.

Share this post


Link to post
Share on other sites
Why are you using both SDL and Ogre3d? Ogre3d already has its own window system. In Windows, every widget and window can store one pointer to userdata. It's possible that both libraries are attempting to set its own user data on the win32 window, which would explain the "invalid window parameter" error.

Share this post


Link to post
Share on other sites

That is exactly what is happening! Same thing happened to me.

 

Here's my startup code:

bool init()
{
    mRoot.reset(new Ogre::Root(plugins_cfg));
    if ( !mRoot->showConfigDialog() ) {
    	// User cancelled.
    	return false;
    }

    Ogre::RenderWindow* mWindow = mRoot->initialise(true);
    if ( mWindow == nullptr ) {
	std::cerr << "Window could not be initialized." << std::endl;
	return false;
    }
		
    size_t window_handle = 0;
    mWindow->getCustomAttribute("WINDOW", &window_handle);
    if ( !SDL_CreateWindowFrom( (void*)window_handle ) ) {
	std::cerr << SDL_GetError() << std::endl;
	return false;
    }

The getCustomAttribute method of the root literally says that this is a hacky way of doing this, but I think it's pretty solid. To quit now, all you need to do is call SDL_Quit().

 

When you destroy the root, the root deletes all of its components, including the RenderWindow.

Edited by status_quo69

Share this post


Link to post
Share on other sites

This topic is 1197 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this