C++ SDL导致CEF3生成额外的窗口
我正试图让CEF3(Chromium Embedded Framework:)与SDL(Simple DirectMedia Layer:)一起工作 我对这两个库的预期用途是使用SDL打开窗口,从中接收事件并呈现OpenGL图形(与其他库(如GLEW)结合使用)。我想使用CEF3在屏幕外为用户界面渲染图形元素,然后通过OpenGL纹理在屏幕上显示它们。所有这些工作,我可以打开SDL窗口,处理事件,我可以绘制OpenGL纹理,并从CEF3的屏幕外渲染中获得与OpenGL兼容的数据 问题是,如果我在测试环境中同时运行SDL和CEF3,CEF3会产生多个额外的窗口 这是我用于CEF3的代码C++ SDL导致CEF3生成额外的窗口,c++,windows,sdl,sdl-2,chromium-embedded,C++,Windows,Sdl,Sdl 2,Chromium Embedded,我正试图让CEF3(Chromium Embedded Framework:)与SDL(Simple DirectMedia Layer:)一起工作 我对这两个库的预期用途是使用SDL打开窗口,从中接收事件并呈现OpenGL图形(与其他库(如GLEW)结合使用)。我想使用CEF3在屏幕外为用户界面渲染图形元素,然后通过OpenGL纹理在屏幕上显示它们。所有这些工作,我可以打开SDL窗口,处理事件,我可以绘制OpenGL纹理,并从CEF3的屏幕外渲染中获得与OpenGL兼容的数据 问题是,如果我在
void Example::webTest()
{
//Args
CefMainArgs cefArgs;
//Settings
CefSettings cefSettings;
cefSettings.pack_loading_disabled = true;
cefSettings.windowless_rendering_enabled = true;
//Initialize
CefInitialize(cefArgs, cefSettings, nullptr, nullptr);
//Render Handler
renderHandler = new InterfaceRenderHandler();
//Window Info
CefWindowInfo cefWindowInfo;
//cefWindowInfo.SetAsWindowless(0, true);
cefWindowInfo.windowless_rendering_enabled = true;
cefWindowInfo.transparent_painting_enabled = true;
//Interface Browser
CefRefPtr<InterfaceBrowserClient> cefClient;
cefClient = new InterfaceBrowserClient(renderHandler);
//Browser
CefBrowserSettings cefBrowserSettings;
cefBrowserSettings.windowless_frame_rate = 60;
CefBrowserHost::CreateBrowser(cefWindowInfo, cefClient.get(), "http://www.stackoverflow.com", cefBrowserSettings, nullptr);
//Threaded Loops
thread renderThread(renderLoop);
thread sdlThread(sdlLoop);
//Main Loop
CefRunMessageLoop();
//Unthread
renderThread.join();
sdlThread.join();
//Shutdown
CefShutdown();
}
void示例::webTest()
{
//Args
头孢菌素头孢菌素;
//背景
CEF设置CEF设置;
cefSettings.pack\u loading\u disabled=真;
cefSettings.windowless_rendering_enabled=true;
//初始化
CefInitialize(cefArgs、cefSettings、nullptr、nullptr);
//渲染处理程序
renderHandler=新的InterfaceRenderHandler();
//窗口信息
ceffindowinfo ceffindowinfo;
//ceffindowinfo.SetAsWindowless(0,true);
cefWindowInfo.windowless_rendering_enabled=true;
ceffindowinfo.transparent\u painting\u enabled=true;
//界面浏览器
CefRefPtr cefClient;
cefClient=新的InterfaceBrowserClient(renderHandler);
//浏览者
CefBrowserSettings CefBrowserSettings;
cefBrowserSettings.windowless_frame_rate=60;
CefBrowserHost::CreateBrowser(cefWindowInfo,cefClient.get(),”http://www.stackoverflow.com“,cefBrowserSettings,nullptr);
//螺纹环
线程渲染读取(renderLoop);
螺纹sdlThread(sdlLoop);
//主回路
CefRunMessageLoop();
//无线程
renderThread.join();
sdlThread.join();
//关闭
CefShutdown();
}
关于此代码的一些注释:
- renderLoop函数用于收集完成的纹理,但目前没有任何功能
- 函数sdlLoop只是轮询SDL窗口中的事件,然后丢弃它们
- CefRunMessageLoop锁定程序。(我想它里面的某个地方有一个环)
- 需要运行CefRunMessageLoop才能进行页面呈现,如果不在主线程中运行,它的行为似乎不正确
- InterfaceBrowserClient是我基于CefClient实现的一个类,它在创建renderHandler时只返回renderHandler,而不执行其他任何操作
- InterfaceRenderHandler是我基于CefRenderHandler实现的一个类。它向CEF3提供预期渲染区域的尺寸,并从CEF3接收完成的图像数据
- 我把这些类的代码放在这里,以防有人需要看到它们
newinterfacebrowserclient(renderHandler)上当CefRunMessageLoop()时出现另一个代码>已到达。这些窗口的尺寸与SDL窗口相同,并且具有相同的标题和内容(纯白色)。然后甚至坐在屏幕上完全相同的位置,这样只有最上面的一个是可见的。然而,虽然原始窗口是有响应的,但Windows认为这些窗口没有响应,就好像它们没有运行事件循环一样。我已经尝试将渲染大小更改为不同于窗口大小(这是在InterfaceRenderHandler中完成的),并且我确信他们复制的是SDL窗口的大小,而不是渲染区域的大小
如果不初始化SDL窗口,则根本不会显示任何窗口(当然,命令提示除外),渲染将正常进行(这可以从控制台在加载页面时打印警告中识别)
对窗口系统有更多了解的人是否理解为什么会出现这种情况,更重要的是,我如何摆脱这些额外的窗口?我没有在任何其他OSES上测试过,因为我对Linux C++编译了解不多,但是如果这个问题仍然存在,我会尝试它。
谢谢。多个窗口可能是CEF
生成其子进程、GPU
、渲染
等
对于子进程,只需调用CefExecuteProcess
并返回其退出代码即可。这必须在其他代码执行之前发生。您可以在cefsimple
应用程序中看到一个工作示例
我没有看到调用CefExecuteProcess()。您需要检查其退出代码并返回,因为CEF运行多个进程。参见cefclient和cefcomple示例:我插入了CefExecuteProcess(cefArgs,nullptr,nullptr)代码>在调用CefInitialize之前,没有对行为进行任何更改,渲染仍然很好地完成(就像以前一样,我设法提取了一个图像文件,渲染确实按照预期工作),窗口仍然出现。我很困惑,如果我返回,我肯定无法运行其余的代码?我试着运行CefExecuteProcess(cefArgs,nullptr,nullptr)代码>(不返回)在初始化之前,没有任何更改<代码>如果为浏览器进程调用(由无“type”命令行值标识),它将立即返回值-1
。对于您的主应用程序,代码将被忽略,因为它的检查是针对>=0
,对于您的子进程应用程序,它们将正确执行。请参阅,我认为您可能需要仔细阅读这些页面,我已经查看了这些页面,并在CefExecuteProcess中添加了return(返回不会发生)。我仍然有多个窗口,我尝试基于您发布的示例中的SimpleApp实现我自己的CefApp,其代码如下:。你还有其他建议吗?好的,我已经修好了,结果我需要在
// CEF applications have multiple sub-processes (render, plugin, GPU, etc)
// that share the same executable. This function checks the command-line and,
// if this is a sub-process, executes the appropriate logic.
int exit_code = CefExecuteProcess(main_args, app.get(), sandbox_info);
if (exit_code >= 0) {
// The sub-process has completed so return here.
return exit_code;
}