android - E/libEGL : call to OpenGL ES API with no current context (logged once per thread) - Android/SDL

标签 android c++ multithreading opengl-es sdl

我知道之前已经回答了这个问题的不同版本,并且我已经阅读了很多。然而,似乎没有人能帮助我解决我的问题。

我正在使用 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 的类来与 android 和 native 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, &currentDisplayMode);
       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 调用时,我得到了错误。请注意,当我在我的 PC 上运行相同的代码时,我没有遇到这个问题,所以我确定这是 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 渲染上下文未绑定(bind)到当前渲染线程。

看看eglCreateContext知道如何创建共享上下文和eglMakeCurrent将 EGL 渲染上下文绑定(bind)到当前渲染线程。


将 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

关于android - E/libEGL : call to OpenGL ES API with no current context (logged once per thread) - Android/SDL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44610576/

相关文章:

Android 在连接到 Socket 时出错

Android NDK 构建以支持所有可用设备

c++ - 单个变量的线程安全

java - ExecutorService 池中的数组中所有元素的总和不起作用

android - 如何知道我的应用程序需要什么 UUID?

具有多行的 Horizo​​ntalScrollView 中的 Android LinearLayout

c++ - Sum 帮助程序无法上课

c++ - 使用命名管道的客户端服务器聊天

C++ 使用 .getline() 从文件中读取第一行

c# - 使用静态方法寻找关于线程安全的建议到 'process' 类实例