首先,您需要在每個要使用openGL的線程中使用EAGLContext。多個上下文將確保在處理多個線程時狀態更改,綁定等沒有衝突。例如,如果你的主線程將試圖繪製一個對象,它可能會綁定一些緩衝區,可能還有一些紋理等等,後臺線程將嘗試加載一個對象,該對象將再次綁定一些緩衝區,紋理......因爲你沒有對什麼操作在什麼時候執行的控制(由於多線程),您需要多個上下文,因此不會發生這種衝突。這意味着你需要創建一個新的上下文每次創建一個新的線程時間:
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:sharegroup]; //ignore sharegroup for now
並將其設置爲當前線程本身
[EAGLContext setCurrentContext:context];
通過這樣做在那裏將是沒有關係至於OpenGL的2個線程。這解決了衝突問題,但提出了一個新問題,您不能使用在其他任何位置創建的後臺線程上創建的資源,而只能創建在其上創建的線程。所以爲了在後臺加載對象並在主線程中使用它們,有一個叫做共享組的東西。在創建新的上下文時,您應該只創建1個實例並將其用作所有後臺線程的參數(如前面提到的代碼片段所示)。
EAGLSharegroup *sharegroup = [[EAGLSharegroup alloc] init];
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:sharegroup];
這應該解決你的主要問題,但看看你的代碼可能還有更多。您需要確保在完成之前不使用在後臺線程上創建的資源。您正在使用一些全局對象(而不是指針),您可以在其上分配新創建的資源,但稍後使用同一方法初始化數據。如果同一個指針正在被另一個線程使用,它可能會發生,你將在不幸的時間內交換它,結果(在你的情況下)在主線程中試圖繪製一個未初始化的對象。現在,即使將全局分配移至方法末尾,如果這些資源正在使用中,情況也會變得不穩定。爲了正確地做到這一點,我建議你將後臺線程上的對象獨立地加載到任何全局變量上,然後在主線程上使用對象執行選擇器,以通知它加載完成並在主線程本身上進行交換。
我想你可能會錯過一個EAGLContext。每個線程應該有自己的,並應該調用它作爲當前上下文。要在上下文之間共享資源,您還需要一個共享組。.. –
@MaticOblak http://pastebin.com/aLjx7dvZ你能解釋更多嗎?我使用線程作爲我發佈到pastebin的代碼。 –