我想使用Irrlicht渲染到SFML创建的窗口中
sf::WindowHandle sf::Window::getSystemHandle() const当然返回sf::WindowHandle,它是一个typedef。在Windows上是HWND__*,在Linux上是unsigned long(可能是X11 Windows ID),在任何其他平台上是void*。在Irrlicht文档中,他们说我应该在Windows上通过HWND,但是其他系统则没有其他要求。

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在Linux上长时间返回无符号,如果我理解正确的话,它是X11的ID。
我的函数GetWindowHandle使用sf::WindowHandle并返回void *
对于Linux,它可以:return reinterpret_cast< void* >(handle);这似乎是正确的方法,我尝试过的任何其他方法都会产生X11错误BadWindowId

创 build 备后,程序执行停止,并且未到达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进行渲染。

最佳答案

容易:SFML已经为其配置了窗口并在其上创建了OpenGL上下文。然后,您将该窗口传递给Irrlicht,该窗口会再次尝试为其配置窗口,但由于已被配置,因此失败。从技术上讲,创建其他OpenGL上下文是完全可能的,但是将GLX窗口创建为另一个GLX窗口的子代(GLX窗口是常规X11窗口的特化)会导致问题。

在您的情况下,解决方案是修补SFML而不进行“花哨的” OpenGL窗口配置和上下文创建,这也意味着它返回普通的X11窗口,而没有通常在其中为OpenGL创建的GLX窗口(长话短说,完成,主要与直接渲染问题有关)。

话虽如此,将Irrlicht嵌入到宿主程序提供的窗口中是为了支持 map 编辑器或类似的预览应用程序。

关于c++ - 从SFML提供的X11句柄创建Irrlicht设备。运行时X11/OpenGL错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41910825/

10-14 07:51