Создание устройства Irrlicht из дескриптора X11, предоставленного SFML. Ошибка выполнения X11 / OpenGL

Я хочу выполнить рендеринг с использованием Irrlicht в окне, созданном SFML

sf::WindowHandle sf::Window::getSystemHandle() const, конечно, возвращает sf::WindowHandle, который является typedef. В Windows это HWND__*, в Linux это unsigned long (который, вероятно, является идентификатором Windows X11), на любой другой платформе void*. В документации Irrlicht сказано, что я должен передать HWND здесь, в Windows, но о других системах больше ничего не сказано.

Irrlicht позволяет создавать свой главный объект irr::IrrlichtDevice специализированным методом из внешнего окна. Требуется struct irr::SIrrlichtCreationParameters. Одна из структурных переменных void* WindowId

Итак, что я пытаюсь сделать, это создать окно с использованием SFML (а затем использовать все функции SFML для опроса событий и т. Д.) И сделать рендеринг Irrlicht внутри этого окна.

Основной код:

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;
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";

Описание моей функции SFML getSystemHandle возвращает unsigned long в Linux, что является идентификатором Widnow X11, если я правильно понял. Моя функция GetWindowHandle принимает sf :: WindowHandle и возвращает void * Для Linux это так: return reinterpret_cast< void* >(handle); Кажется, это правильный способ, любой другой способ, который я пробовал, дает ошибку X11 BadWindowId

Выполнение программы останавливается после создания устройства и не достигает if(device == nullptr) блока. Моя программа завершается и возвращает 1.

Ошибки, которые я получаю в консоли: (весь вывод до "Irrlicht Engine" выполняется моим объектом регистратора)

[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

Что может вызвать такую ​​ошибку?

Редактировать Пробовал с sf::Window. Тоже не работает. Я получаю ту же ошибку. Согласно документации SFML, этот класс также создает свой собственный контекст. Мне, вероятно, придется отказаться от объединения этих двух библиотек и использовать SFML только для звука и рендерить только с помощью Irrlicht.


person Xeverous    schedule 28.01.2017    source источник


Ответы (1)


Легко: SFML уже настроил окно и создал для него контекст OpenGL. Затем вы передаете это окно Irrlicht, который пытается (снова) настроить окно для своих целей и терпит неудачу, потому что оно уже было настроено. Технически создание дополнительных контекстов OpenGL вполне возможно, но создание окна GLX как дочернего для другого окна GLX (окна GLX являются специализацией обычных окон X11) приводит к проблемам.

Решением в вашем случае было бы исправление SFML, чтобы не выполнять "причудливую" конфигурацию окна OpenGL и создание контекста, что также означает, что он возвращает простое окно X11 без окна GLX, которое обычно создается внутри него для OpenGL (длинная история, почему это сделано, в основном это связано с проблемами прямого рендеринга).

При этом встраивание Irrlicht в окно, предоставляемое основной программой, предназначено для поддержки таких вещей, как редакторы карт или аналогичные приложения предварительного просмотра.

person datenwolf    schedule 28.01.2017
comment
создание окна GLX как дочернего для другого окна GLX (окна GLX являются специализацией обычных окон X11) приводит к проблемам. Какие проблемы могут возникнуть? - person Xeverous; 28.01.2017
comment
О том, что исправление SFML - насколько это сложно? Есть ли простой обходной путь? Любое простое решение с кодом C ++, которое позволило бы мне использовать обе библиотеки? - person Xeverous; 28.01.2017
comment
Подожди, лол, я только что понял, что есть sf::RenderWindow, но есть и sf::Window. - person Xeverous; 28.01.2017