首先,您需要在要使用 openGL 的每个线程中使用 EAGLContext。多上下文将确保在处理多个线程时状态更改、绑定等没有冲突。例如,如果您的主线程将尝试绘制一个对象,它可能会绑定一些缓冲区,可能还有一些纹理等等,后台线程将尝试加载一个对象,该对象再次必须绑定一些缓冲区、纹理......因为你无法控制在什么时间执行什么操作(由于多线程),您需要多个上下文,因此不会发生此类冲突。这意味着每次创建新线程时都需要创建一个新上下文:
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:sharegroup]; //ignore sharegroup for now
并将其设置为当前线程本身
[EAGLContext setCurrentContext:context];
通过这样做,就 openGL 而言,这两个线程之间将没有任何关系。这解决了冲突的问题,但提出了一个新问题,即除了创建它的线程之外,您不能使用在后台线程上创建的资源。因此,为了在后台加载对象并在主线程上使用它们,有一个叫做共享组的东西。在创建新上下文时,您应该只创建 1 个实例并将其用作所有后台线程的参数(如已经提到的代码片段)。
EAGLSharegroup *sharegroup = [[EAGLSharegroup alloc] init];
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:sharegroup];
这应该可以解决您的主要问题,但是查看您的代码可能还有更多问题。您需要确保在完成之前不使用在后台线程上创建的资源。您正在使用一些全局对象(而不是指针),您在其上分配新创建的资源,但稍后在同一方法中初始化数据。如果另一个线程正在使用相同的指针,则可能会发生这种情况,您将在不幸的时间内交换它,从而导致(在您的情况下)主线程尝试绘制未初始化的对象。现在,即使您将该全局分配移到方法的末尾,如果这些资源正在使用中,事情也会变得不稳定。为了正确地做到这一点,我建议您将后台线程上的对象完全独立地加载到任何全局变量中,并在主线程上使用对象执行选择器,