2011-09-06 19 views
9

iPad için OpenGL ES uygulamasının performansını iyileştirmek için, dokuya nadiren güncellenmiş ancak bir sonuç veren öğe çizmeyi planlıyorum. bu yüzden elemanın yeniden çizilmemesi gerekmeden sadece dokuyu kullanabilirim. Bununla birlikte, doku hem simülatörde hem de cihazda doğru şekilde eşleştirilirken, sadece simülatörde dokuya gerçekte bir şey verilmiştir.iOS OpenGL ES'de dokuya renderleme - simülatörde çalışır, ancak cihazda değil

Aşağıdakiler projeye eklediğim koddur. simülatörü hem bir "çerçeve belleği tam geri dönüş değeri verir

int width = 768; 
int height = 270; 

// Prepare texture for off-screen rendering. 
glGenTextures(1, &wTexture); 
glBindTexture(GL_TEXTURE_2D, wTexture); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE); 
glClearColor(.9f, .3f, .6f, 1.0f); // DEBUG 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, 
    GL_UNSIGNED_BYTE, 0); 
glBindTexture(GL_TEXTURE_2D, 0); 

// Depth attachment buffer, always needed. 
glGenRenderbuffersOES(1, &wDepth); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wDepth); 
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, 
    width, height); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0); 

// Create FBO for render-to-texture. 
glGenFramebuffersOES(1, &wBuffer); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, wBuffer); 
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, 
    GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, wTexture, 0); 
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, 
    GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, wDepth); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 

(tabii ki, bağlanmamış önce) yeni FBO A glFramebufferStatusOES: sahne kurma iken, tamponlar ve gerekli doku oluşturmak ve cihaz. Dokunun gerçekte oluşturulduğunu doğrulamak için doku için açık pembe rengi ayarladığımı ve sorunun aslında dokunun hiçbir zaman çizilmediğini unutmayın. doku yeniden çizilmesi gereken zaman

, ben elemanı render önce bunu:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, wBuffer); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glViewport(0, 0, width, height); 
glMatrixMode(GL_MODELVIEW); 
glPushMatrix(); 
// ... 

ve fiili render sonra aşağıdaki:

// ... 
glPopMatrix(); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 

Son olarak, her zaman ekran yeniden çizilir Öyle gibi, ekranda uygun pozisyonda bir Kodesine doku haritası:

float Vertices[] = { 
    -65.0f, -100.0f, .0f, 
    -65.0f, 100.0f, .0f, 
    -10.0f, -100.0f, .0f, 
    -10.0f, 100.0f, .0f}; 
float Texture[] = {.0f, .0f, 1.0f, .0f, .0f, 1.0f, 1.0f, 1.0f}; 

glEnable(GL_TEXTURE_2D); 
glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glBindTexture(GL_TEXTURE_2D, wTexture); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

glVertexPointer(3, GL_FLOAT, 0, Vertices); 
glTexCoordPointer(2, GL_FLOAT, 0, Texture); 
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
glDisable(GL_TEXTURE_2D); 

glBindTexture(GL_TEXTURE_2D, 0); 

iPhone ve iPad simülatörlerinde (4.2, 4.3), kod beklendiği gibi çalışır. İlgili pozisyonda görüntülenen dinamik olarak oluşturulmuş dokuları, hata ayıklama ifademden dolayı şeffaf bir arka plan yerine pembe ile görüyorum. Ancak, iPad 4.2 cihazımda, render-to-texture adımı sırasında neyin çizileceği değil, sadece pembe dikdörtgen oluşturuldu. Böylece, doku ekrana doğru bir şekilde işlenir, ancak bir sebepten ötürü, cihaz üzerinde doku-doku kodu, dokuya bir şey vermeyi başaramaz.

Sanırım aygıtta bulunmayan bazı işlevler kullanıyorum veya bir yerlerde bir hata varsayımı yapıyorum, ama ne olduğunu anlayamıyorum. Ayrıca OpenGL ES Analyzer üzerinden çalıştırmayı denedim, ancak bazı temel performans optimizasyon ipuçlarından başka bir şey vermiyor. Sorunu nerede aramam gerekiyor?

cevap

9

Projemde MSAA kullanıyordum ve bu özelliği devre dışı bıraktığımda sorunun kaybolduğunu öğrendim. Bu, aynı sorunun tartışıldığı (ancak çözülmediği) this other question'u keşfetmemi sağladı.

Sorun, ana örnekleyiciniz için çoklu örnekleme etkinse, tüm özel FBO'larınızın çok örneklemeyi de kullanması gerektiği anlaşılıyor. Normal bir sigara multisampled GL_TEXTURE_2D render olamaz ve bir multisampled GL_TEXTURE_2D_MULTISAMPLE sorunu çözmek için OpenGL ES 2.

kullanılamaz, benim işlemek-to-doku kodu Değiştirilmiş aynı şekilde modifiye çoklu örneklemeyi etkinleştirmek için ana görüntüleme kodum.Ben yeni MSAA tampon bağlayan doku render önce

glGenFramebuffersOES(1, &wmBuffer); 
glGenRenderbuffersOES(1, &wmColor); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, wmBuffer); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wmColor); 
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_RGBA8_OES, width, height); 
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, wmColor); 
glGenRenderbuffersOES(1, &wmDepth); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wmDepth); 
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_DEPTH_COMPONENT16_OES, width, height); 
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, wmDepth); 

: sorudan kodda oluşturulan üç tampon nesnelere ek olarak, ben çok örnek render için üç tane daha yaratmak

glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, wmBuffer); 
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, wBuffer); 
glResolveMultisampleFramebufferAPPLE(); 
GLenum attachments[] = {GL_DEPTH_ATTACHMENT_OES, GL_COLOR_ATTACHMENT0_OES, GL_STENCIL_ATTACHMENT_OES}; 
glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 3, attachments); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 
01:
glBindFramebufferOES(GL_FRAMEBUFFER_OES, wmBuffer); 

Son olarak, render sonra, doku FBO içine MSAA FBO benim ana render framebuffer'ın için aynı şeyleri çözmekDokular artık doğru bir şekilde işleniyor (ve performans harika!)

İlgili konular