E/libEGL:在没有当前上下文的情况下调用 OpenGL ES API(每个线程记录一次)- Android/SDL
E/libEGL: call to OpenGL ES API with no current context (logged once per thread) - Android/SDL
我知道之前已经回答了这个问题的不同版本,并且我已经阅读了很多。然而 none 似乎可以帮助我解决问题。
我正在使用 SDL 创建一个上下文来保存 OpenGL ES。如果我从包含当前上下文的线程调用 OpenGL ES,我就可以正常渲染。但是,如果我从另一个线程进行 OpenGL ES 调用,我将无法进行任何渲染,并且会在标题中收到错误消息。
E/libEGL: call to OpenGL ES API with no current context (logged once per thread)
我正在使用 SDL 源包中提供的 android 项目模板。这使用名为 SDLActivity 的 class 与 android 和本机 c/c++ 代码进行通信。
问题是如何创建多个 SDL 上下文,以便我仍然可以从另一个线程调用 OpenGL ES?
编辑:这里是我在代码中创建 SDL 上下文的地方:
int SDL_main(int argc, char **argv)
{
window = nullptr;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
return false;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_DisplayMode currentDisplayMode;
int success = SDL_GetCurrentDisplayMode(0, ¤tDisplayMode);
assert(success == 0);
WIDTH = currentDisplayMode.w;
HEIGHT = currentDisplayMode.h;
window = SDL_CreateWindow(Name.c_str(),
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
assert(window != nullptr);
SDL_SetHint("SDL_HINT_ORIENTATIONS", "LandscapeRight LandscapeLeft");
context = SDL_GL_CreateContext(window);
assert(context != nullptr);
glGetError();
//OpenGL configuration
glViewport(0, 0, WIDTH, HEIGHT);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//initialise
obj.functionA();
obj.functionB();
SDL_SetEventFilter(FilteringEvents, NULL);
SDL_Event event;
shouldQuit = false;
while (!shouldQuit)
{
SDL_PollEvent(event);
//Render
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
obj.Render();
SDL_GL_SwapWindow(window);
}
SDL_Quit();
return 0;
}
为了简单起见,我只包含了通过 SDL 创建 Opengl ES 的上下文,以及一些简单的 obj 函数调用,例如对渲染的调用。
如您所见,渲染调用是在 SDL 创建的 OpenGL 上下文的线程中进行的。那么我如何使用 SDL 创建共享上下文,因为当我在该线程之外进行 OpenGL ES 调用时,我得到了错误。请注意,当我 运行 在我的电脑上使用相同的代码时,我没有遇到这个问题,所以我确定这是 Android.
特有的问题
Traditionally, OpenGL ES applications only render to one surface from one thread.
A rendering thread is one CPU thread associated with one graphics context. By default, each graphics context will not be able to access the resources (textures, shaders and vertex buffers) of another context. For this reason, shared contexts are used so one or more background loading threads can access the resources of a primary thread.
我认为你的问题是 EGL 渲染上下文没有绑定到当前渲染线程。
查看 eglCreateContext to know how to make shared context and eglMakeCurrent 将 EGL 渲染上下文绑定到当前渲染线程。
将 SDL 与 OpenGL ES 结合使用
这可以通过调用 SDL_GetWMInfo() 来获取所需的句柄来完成,例如:
SDL_SysWMinfo sysWmInfo;
SDL_VERSION(&sysWmInfo.version);
SDL_GetWMInfo(&sysWmInfo);
eglDisplay = eglGetDisplay((EGLNativeDisplayType)sysWmInfo.info.x11.display);
...
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)sysWmInfo.info.x11.window, NULL);
或者,
您尝试使用 SDL_GL_MakeCurrent 了吗?
我知道之前已经回答了这个问题的不同版本,并且我已经阅读了很多。然而 none 似乎可以帮助我解决问题。
我正在使用 SDL 创建一个上下文来保存 OpenGL ES。如果我从包含当前上下文的线程调用 OpenGL ES,我就可以正常渲染。但是,如果我从另一个线程进行 OpenGL ES 调用,我将无法进行任何渲染,并且会在标题中收到错误消息。
E/libEGL: call to OpenGL ES API with no current context (logged once per thread)
我正在使用 SDL 源包中提供的 android 项目模板。这使用名为 SDLActivity 的 class 与 android 和本机 c/c++ 代码进行通信。
问题是如何创建多个 SDL 上下文,以便我仍然可以从另一个线程调用 OpenGL ES?
编辑:这里是我在代码中创建 SDL 上下文的地方:
int SDL_main(int argc, char **argv)
{
window = nullptr;
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
return false;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
SDL_DisplayMode currentDisplayMode;
int success = SDL_GetCurrentDisplayMode(0, ¤tDisplayMode);
assert(success == 0);
WIDTH = currentDisplayMode.w;
HEIGHT = currentDisplayMode.h;
window = SDL_CreateWindow(Name.c_str(),
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
WIDTH, HEIGHT, SDL_WINDOW_OPENGL);
assert(window != nullptr);
SDL_SetHint("SDL_HINT_ORIENTATIONS", "LandscapeRight LandscapeLeft");
context = SDL_GL_CreateContext(window);
assert(context != nullptr);
glGetError();
//OpenGL configuration
glViewport(0, 0, WIDTH, HEIGHT);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//initialise
obj.functionA();
obj.functionB();
SDL_SetEventFilter(FilteringEvents, NULL);
SDL_Event event;
shouldQuit = false;
while (!shouldQuit)
{
SDL_PollEvent(event);
//Render
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
obj.Render();
SDL_GL_SwapWindow(window);
}
SDL_Quit();
return 0;
}
为了简单起见,我只包含了通过 SDL 创建 Opengl ES 的上下文,以及一些简单的 obj 函数调用,例如对渲染的调用。
如您所见,渲染调用是在 SDL 创建的 OpenGL 上下文的线程中进行的。那么我如何使用 SDL 创建共享上下文,因为当我在该线程之外进行 OpenGL ES 调用时,我得到了错误。请注意,当我 运行 在我的电脑上使用相同的代码时,我没有遇到这个问题,所以我确定这是 Android.
特有的问题Traditionally, OpenGL ES applications only render to one surface from one thread.
A rendering thread is one CPU thread associated with one graphics context. By default, each graphics context will not be able to access the resources (textures, shaders and vertex buffers) of another context. For this reason, shared contexts are used so one or more background loading threads can access the resources of a primary thread.
我认为你的问题是 EGL 渲染上下文没有绑定到当前渲染线程。
查看 eglCreateContext to know how to make shared context and eglMakeCurrent 将 EGL 渲染上下文绑定到当前渲染线程。
将 SDL 与 OpenGL ES 结合使用
这可以通过调用 SDL_GetWMInfo() 来获取所需的句柄来完成,例如:
SDL_SysWMinfo sysWmInfo;
SDL_VERSION(&sysWmInfo.version);
SDL_GetWMInfo(&sysWmInfo);
eglDisplay = eglGetDisplay((EGLNativeDisplayType)sysWmInfo.info.x11.display);
...
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)sysWmInfo.info.x11.window, NULL);
或者,
您尝试使用 SDL_GL_MakeCurrent 了吗?