2011-10-24 13 views
10

OpenGL ES kullanarak Android için küçük bir oyun motoru yazmayı deniyorum. Oyun nesnelerini güncelleyen bir Oyun Konusu oluşturdum ve GLThread ile sahneyi çiziyorum. Dokularmı GLSurfaceView'ın onSurfaceCreated yönteminde yüklemeniz gerektiğini okudum. Bunu takip ediyorum ama bazı hata ayıklama amaçları için, GLThread yerine Oyun İpliğimden doku yüklemeye çalışıyordum. Hatam olmadı ve doku ekranda görünmüyordu. Tüm günümü problemi çözmeye çalışarak geçirdim ve sonunda aşağıdaki hereOpenGL ES işlevleri neden başka bir iş parçacığından çağrılabilir?

"Sadece OpenGL'yi ana iş parçacığında kullandığınızdan emin olun." Çok önemli. Oyun Motorunuzda (başka bir iş parçacığında olabilir) gl-thread ile senkronize olmayan bir doku yükleme fonksiyonunu arayamazsınız. Yeni bir doku yüklemek için gl-thread'inizi işaretlemek için bir bayrak ayarlayın (örneğin, yeni bir doku yüklü olup olmadığını kontrol eden bir OnDrawFrame (GL gl) işlevini yerleştirebilirsiniz.

Kodumu değiştireceğim Bu yüzden dokular GL Thread'den yüklenecek. Ben sadece neden olduğunu anlayamadım Neden OpenGL fonksiyonları başka bir threadden çalışmıyor?

Konu oluşturmayı biliyorum ama ne olduğunu bilmiyorum Senkronizasyon, yukarıdaki ekstrakttan bahsetmektedir, "Oyun Motorunuzda (ki bu da başka bir iş parçacığında olabilir) gl-thread ile senkronize olmayan bir doku yükleme fonksiyonunu arayamaz." Tahminimce Oyun İpliği senkronize olmayabilir GL Thread ile. GL Thread'e senkronize edilen başka bir iplik oluşturmak mümkün mü? Böylece GL fonksiyonları bundan çağrılabilir mi? Bu kavramları anlamak için nelere dikkat etmeliyim?

+5

Android'de çalışan bir adam değilim, ancak iOS'ta benzer uyarılar için iki neden var: biri şu anki GL bağlamının konuya özel olması, dolayısıyla içerik parasını iş parçacıklarına aktarmanız ve ikinci olmanız gerekir (daha fazlası daha önemlisi, eşzamanlama olmaksızın birden çok iplikten GL durumu ile çatışmanın, sadece GL bağlamı halini bozarak sona ermesidir. HTH. –

+0

Bence bu sadece uyum sağlamayı önlemek –

cevap

8

quixoto'nun yorumu en yakın, bence. OpenGL bağlamlarının hemen hemen her platformda belirli bir konu olduğu geleneksel neden, OpenGL'nin büyük ölçüde devletlere bağımlı olması ve bir dizi değişikliği atomik yapmak için semantikleri olmamasıdır. Bu nedenle, örneğin, bir iş parçacığı üzerinde çizme işlemi olabilir:

glVertexPointer(... supply vertex positions ...) 
glTexCoordPointer(... provide texture positions ...) 
/* and supply a few other pointers, maybe bind a texture */ 

glDrawArrays(... draw some geometry ...) 

Yani son çağrı sadece önceki çağrıların bağlamında öngörülebilir sonuçlar sağlar. Bu kod bitinin glVertexPointer'dan sonra duraklatılmasına izin verirseniz, başka bir iplik atlayarak geometrisini çizmek için aynı sıralamayı yapıyor ve sonra bu kod ilerliyorsa, büyük olasılıkla yanlış geometriyle çiziyorsunuz, muhtemelen Değiştirilen dizilerden bazıları orijinallerden daha küçükse, bağlı bellek erişir.

Android, bir OpenGL paylaşım grubunun genel konseptini destekleyen EGL'yi (dolaylı olarak örtük olsa da, yeni bir bağlamın olmasını istediğiniz bir bağlamı, üçüncü bağımsız değişken ile eglCreateContext aracılığıyla sağladığınız bir bağlam sağlarsınız) sağlar. İki bağlam bir paylaşım grubundaysa, her birinin bağımsız bir durumu vardır ve yalnızca bir iş parçacığından aramak güvenlidir, ancak her biri için doku veya köşe nesnesi gibi nesneler kullanılabilir. Bu nedenle, paylaşım gruplarını kullanarak, sonuçları tek bir iş parçacığı üzerinde birleştirebilmek için aynı anda birden çok iş parçacığı üzerinde OpenGL eylemleri gerçekleştirebilirsiniz.

İçeriği tek bir iş parçacığına bağlamak bu nedenle çok fazla sorun değil. OpenGL'nin kendi için planlaması da bir marş olmayacaktı çünkü OpenGL bağlamlarının bir işletim sistemine özel olarak yaratılmasının, yönetilmesinin ve bertaraf edilmesinin nedeninin bir kısmı, bazı işletim sistemlerinin bu şeyleri diğerlerine radikal olarak farklı şekillerde ele alması gerektiğidir. veya kendi benzersiz çözümlerini ortaya çıkararak daha iyi çözümler sunabilir.