2013-07-17 43 views
0

我想通過在IOS中使用assimp lib將模型導入到渲染器。 我的模型文件的大小是2mb;assimp在使用IOS中的線程時無法導入3d模型

我可以通過不使用線程成功導入模型。

但是,當我在一個線程內運行我的代碼,assimp無法導入。

Assimp::Importer* importer = new Assimp::Importer(); 
scene = importer->ReadFile(modelPath.data,aiProcessPreset_TargetRealtime_MaxQuality); 

所以基本上這個場景變成零如果我使用線程。

我使用線程錯誤嗎?

我錯過了什麼?

你可以看到更多的代碼從這個鏈接:http://pastebin.com/aLjx7dvZ

維護問題的簡單起見,我沒有張貼完整的代碼。

+1

我想你可能會錯過一個EAGLContext。每個線程應該有自己的,並應該調用它作爲當前上下文。要在上下文之間共享資源,您還需要一個共享組。.. –

+0

@MaticOblak http://pastebin.com/aLjx7dvZ你能解釋更多嗎?我使用線程作爲我發佈到pastebin的代碼。 –

回答

1

首先,您需要在每個要使用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]; 

這應該解決你的主要問題,但看看你的代碼可能還有更多。您需要確保在完成之前不使用在後臺線程上創建的資源。您正在使用一些全局對象(而不是指針),您可以在其上分配新創建的資源,但稍後使用同一方法初始化數據。如果同一個指針正在被另一個線程使用,它可能會發生,你將在不幸的時間內交換它,結果(在你的情況下)在主線程中試圖繪製一個未初始化的對象。現在,即使將全局分配移至方法末尾,如果這些資源正在使用中,情況也會變得不穩定。爲了正確地做到這一點,我建議你將後臺線程上的對象獨立地加載到任何全局變量上,然後在主線程上使用對象執行選擇器,以通知它加載完成並在主線程本身上進行交換。