Irrlicht + SFML. Error creating device from X11 window ID
Posted: Tue Jan 24, 2017 8:32 pm
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:
The real problem:
Both libraries can use/return handle to/from created window. Irrlicht allows it in
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:
sf::WindowHandle is a typedef, which is:
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:
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)
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.
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)
Documentation says that I should pass HWND here if doing it on Windows.
SFML side:
Code: Select all
sf::WindowHandle sf::Window::getSystemHandle() const
- HWND__* for Windows
- unsigned long for Unix/X11 (also Linux)
- void* for MacOS, iOS and Android
Code: Select all
void sf::RenderTarget::pushGLStates()
void sf::RenderTarget::popGLStates()
void sf::RenderTarget::resetGLStates()
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";
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
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.