Irrlicht + SFML. Error creating device from X11 window ID

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Xeverous
Posts: 11
Joined: Tue Jan 24, 2017 7:25 pm

Irrlicht + SFML. Error creating device from X11 window ID

Post by Xeverous »

So what I want is to render using Irrlicht into a window created by SFML
example of it: http://www.sfml-dev.org/documentation/2.4.1/

I want to use SFML due to it's very modern C++ code (enum classes, const/rvalue references, almost no pointers, ...) etc
and due to it's flexibility with SFGUI (http://sfgui.sfml-dev.de/) and Thor (http://www.bromeon.ch/libraries/thor/).

They allow to write very pretty code like this:

Code: Select all

thor::Action a(sf::Keyboard::X, thor::Action::PressOnce); // Key X is pressed once
thor::Action b(sf::Mouse::Left, thor::Action::Hold);      // Left mouse button is currently held down
thor::Action c(sf::Event::Closed);                        // SFML Window is closed
thor::Action both = a and b; // X pressed while left key is held down, "and" is a keyword that works the same way as "&&"
 
thor::ActionMap<std::string> map; // stores actions, obtainable by templated value
 
map["run"] = a;
map["shoot"] = b;
map["quit"] = c;
 
thor::ActionMap<std::string>::CallbackSystem system;
thor::Connection con1 = system.connect("run", std::bind(&sf::Sprite::move, &playerSprite, 10.f, 0.f));
// ... other connections with std::bind()
con3.disconnect();
 
map.update(renderWindow); // polling all events from the window
map.invokeCallbacks(system, &renderWindow); // calls all bound functions - editing maps yield awesome dynamic binding capability





The real problem:
Both libraries can use/return handle to/from created window. Irrlicht allows it in

Code: Select all

IrrlichtDevice* irr::createDeviceEx(const SIrrlichtCreationParameters&  parameters)
One of the values in the struct is a void* (http://irrlicht.sourceforge.net/docu/st ... cef87b6eae).
Documentation says that I should pass HWND here if doing it on Windows.

SFML side:

Code: Select all

sf::WindowHandle sf::Window::getSystemHandle() const
sf::WindowHandle is a typedef, which is:
  • HWND__* for Windows
  • unsigned long for Unix/X11 (also Linux)
  • void* for MacOS, iOS and Android
SFML also provides these 3 functions:

Code: Select all

void sf::RenderTarget::pushGLStates()
void sf::RenderTarget::popGLStates()
void sf::RenderTarget::resetGLStates()
So I can save states that Irrlicht/SFML uses and not break them up together.

Question
Passing handle from SFML window into Irrlicht device constructor seems pretty straightforward. But what to do in case of Linux?
In this case, I don't get a pointer but long integer - what should I do with it? Give Irrlicht address of it? reinterpret_cast<> it?

UPDATE
I have succesfully compiled the whole program on Linux.
Core code:

Code: Select all

    sf::VideoMode desktop = sf::VideoMode::getDesktopMode();
    sf::ContextSettings settings;
    settings.antialiasingLevel = 8;
    settings.depthBits = 16;
    settings.stencilBits = 0;
 
    //my own Logger class
    logger.AddLog("Requesting following settings:\n");
    logger.AddLog(settings);
 
    window = std::make_shared<sf::RenderWindow>(
        sf::VideoMode(WINDOW_SIZE_X, WINDOW_SIZE_Y, desktop.bitsPerPixel),
        sf::String("Irrlicht + SFML test"),
        sf::Style::Default,
        settings);
 
    logger.AddLog("Created SFML Window with following settings:\n");
    logger.AddLog(window->getSettings());
 
    irr::SIrrlichtCreationParameters params;
    params.AntiAlias = 8;
    params.Bits = 16;
    params.DeviceType = irr::EIDT_BEST; //Device creation fails with anything other
    params.DriverType = irr::video::EDT_OPENGL;
    params.Doublebuffer = true;
    params.EventReceiver = nullptr;
    params.Fullscreen = false;
    params.HandleSRGB = false;
    params.IgnoreInput = true;
    params.Stencilbuffer = false;
    params.UsePerformanceTimer = false;
    params.Vsync = false;
    params.WithAlphaChannel = false;
    params.ZBufferBits = 24;
    params.LoggingLevel = irr::ELL_DEBUG;
    params.WindowId = GetWindowHandle(window->getSystemHandle()); // Described below
 
    device.reset(irr::createDeviceEx(params)); // device is std::unique_ptr
    if(device == nullptr)
        std::cout << "Can't create device!\n";
Program execution stops after device creation and does not reach if(device == nullptr) block. My program is terminated and returns 1.
Errors I get in console: (all output before "Irrlicht Engine" is done by my logger object)

Code: Select all

[2017.01.28 13:15:51]
Starting Application
Requesting following settings:
OpenGL context        : 1.1
flags                 : 0
antialiasing level    : 8
bits of depth   buffer: 16
bits of stencil buffer: 0
Created SFML Window with following settings:
OpenGL context        : 4.5
flags                 : 0
antialiasing level    : 8
bits of depth   buffer: 24
bits of stencil buffer: 0
Irrlicht Engine version 1.8.4
Linux 4.4.0-59-generic #80-Ubuntu SMP Fri Jan 6 17:47:47 UTC 2017 x86_64
X Error of failed request:  BadAlloc (insufficient resources for operation)
  Major opcode of failed request:  154 (GLX)
  Minor opcode of failed request:  31 (X_GLXCreateWindow)
  Serial number of failed request:  26
  Current serial number in output stream:  27
 
Description of my function
I know that SFML's getSystemHandle returns unsigned long on Linux builds, which is (if I understood correctly) X11 widnow ID.
My function GetWindowHandle takes sf::WindowHandle and returns void*
For Linux it does: return reinterpret_cast< void* >(handle); This seems to be correct way, any other I tried yields X11 error BadWindowId

What could go wrong? Why do I get "BadAlloc (insufficient resources for operation)"?


UPDATE 2
Seems it's just impossible.
http://stackoverflow.com/questions/4191 ... engl-error
Both libraries create their own OpenGL context, while there can only be one.
The Win32 example (http://irrlicht.sourceforge.net/docu/example014.html) told me alot that there is no simple way
to integrate it wilh OS window API. There is no simple solution, without involving writing sphagetti #define code for each system.
I will probably have to give up and just use only Irrlicht for rendering, and use SFML only for audio.
Last edited by Xeverous on Sun Jan 29, 2017 8:45 pm, edited 4 times in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: How to use external window handle created by SFML?

Post by Vectrotek »

You could search these forums about how people had Irrlicht interact with Simple Direct Media Layer (SDL)..
I suspect it would be similar.. (I know nothing of SFML, but it look interesting)

There could also be clues in pieces dealing with "Win 32" and Irrlicht (see examples etc)

Good luck..
Xeverous
Posts: 11
Joined: Tue Jan 24, 2017 7:25 pm

Re: How to use external window handle created by SFML?

Post by Xeverous »

Win32 is Windows specific. There seems to be no problem passing HWND to Irrlicht. The whole Windows API operates on void pointers.

Thanks for the idea. SFML uses SDL internally, so I should search forum for SDL, but look into unix specific examples.
Xeverous
Posts: 11
Joined: Tue Jan 24, 2017 7:25 pm

Re: Irrlicht + SFML. Error creating device from X11 window I

Post by Xeverous »

Updated topic. Added error message and new question
Post Reply