2009-10-30 19 views
7

Bir dokuya işlem yapmaya çalışıyorum, daha sonra bu dokuyu iPhone'daki OpenGL ES kullanarak ekrana çiziyorum. Başlangıç ​​noktası olarak this question kullanıyorum ve çizimi Apple'ın demo EAGLView alt sınıfında yapıyorum.OpenGL ES dokuya işlenir, ardından doku çizilir

örnek değişkenleri:

GLuint textureFrameBuffer; 
Texture2D * texture; 

çerçeve tampon ve doku başlatmak için, ben bu işi yapıyorum:

GLint oldFBO; 
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO); 

// initWithData results in a white image on the device (works fine in the simulator) 
texture = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"blank320.png"]]; 

// create framebuffer 
glGenFramebuffersOES(1, &textureFrameBuffer); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer); 

// attach renderbuffer 
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture.name, 0); 

if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) 
    NSLog(@"incomplete"); 

glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO); 

Şimdi, her zamanki gibi ekrana benim sahneyi çekmek bile, bunu çalışıyor: Ben ekrana 'doku' çizmek ardından, 'textureFrameBuffer' render eğer

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
// draw some triangles, complete with vertex normals 
[contentDelegate draw]; 
[self swapBuffers]; 

Fakat, ortaya çıkan im yaş baş aşağı ve "içeride" dir. Yani, 3 boyutlu nesnelerin normalleri dışa doğru değil, içe doğru işaret ediyor gibi görünür - her nesnenin en ön yüzü saydamdır ve arka yüzün iç kısmını görebilirim.

GLint oldFBO; 
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO); 

glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

// draw some polygons 
[contentDelegate draw]; 

glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO); 

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
glEnable(GL_TEXTURE_2D); 
glColor4f(1, 1, 1, 1); 
[texture drawInRect:CGRectMake(0, 0, 320, 480)];  
glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
glDisable(GL_TEXTURE_2D); 

[self swapBuffers]; 

I (Texture2D en drawInRect yönteminde) koordinatlarını buna göre (glTexCoordPointer) yeniden sıralama ile kolayca yeterli görüntü RIGHTSIDE-yukarı çevirmek, ancak bu "içten dışa" sorunu çözmez: İşte kod.

Texture2D dokusunu manuel olarak oluşturulmuş OpenGL dokusuyla değiştirmeyi denedim ve sonuç aynıydı. PNG görüntüsünden yüklenen bir Texture2D çizimi iyi çalışıyor.

Nesneleri çizmek için, her köşe noktasının belirtilen bir birimi normaldir ve GL_NORMALIZE etkinleştirilmiş demektir.

glVertexPointer(3, GL_FLOAT, 0, myVerts); 
glNormalPointer(GL_FLOAT, 0, myNormals); 
glDrawArrays(GL_TRIANGLES, 0, numVerts); 

Her şey ekrana işlendiğinde iyi çizilir; GL_DEPTH_TEST etkin ve harika çalışıyor.

Bunu nasıl düzeltebileceğiniz konusunda herhangi bir öneriniz var mı? Teşekkürler!

+0

"İçten dışa" sorunu için: ön yüzünüzdeki ilkel öğeler iptal edilirse, normal ayarı belirlemek için kullanılan köşe siparişi ile ilgili bir sorununuz vardır. Bir şeyi yanlış anlamadığım sürece, tekstüre ile ilgili bir sorun değil. GL_CULL_FACE etkin misiniz? – prideout

+0

GL_CULL_FACE etkin değil. Etkinleştirilmesi, kesinlikle genel görünümü geliştirir. Nesne normları şu anda doğru bir çıkış yolu gibi gözüküyor, ancak başka bir yüz tarafından gizlenmiş olsun ya da olmasın, gizlenmiş olması gereken çok sayıda ön yüz yüze şimdi görülebilir. Üçgenlerimin sarılmasıyla ilgili bir sorun mu gösteriyor? Blender'dan köşe ihraç etmek için bir komut dosyası kullanıyorum; Dışa aktarıldığında sargının muntazam olduğundan emin olacağım. Doğrudan ekrana çizdiğimde her şeyin mükemmel göründüğüne dikkat edin (ve GL_CULL_FACE açık ya da kapalı hiçbir fark yaratmaz). –

cevap

3

Bunun ilginç kısmı, doğrudan arka plana çizim yaparken farklı bir sonuç gördüğünüzdür. IPhone platformunda olduğunuzdan, backbuffer'a çizdiğinizde bile bir FBO'ya her zaman çizim yapıyorsunuz.

Ekran önünüzdeki FBO'ya bağlı bir derinlik tamponunuzun olduğundan emin olun. Başlatma kodunuzda, aşağıdaki snippet'i glBindFramebufferOES (...)'dan hemen sonra eklemek isteyebilirsiniz.

// attach depth buffer 
GLuint depthRenderbuffer; 
glGenRenderbuffersOES(1, &depthRenderbuffer); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); 
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height); 
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); 
+0

Bir şeye bağlı olabilirsiniz, ancak henüz çalışmıyor ... Bunu yaptıktan ve doku ekledikten sonra (önceki gibi) glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES), GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES değerini döndürür. FrameBuffer'ın buna eklenmiş bir renk oluşturucuya ihtiyacı var mı? (Bunu çabucak denedim, henüz şans denemedim, ama devam edeceğim.) Bu arada yardımın için teşekkürler, gerçekten takdir ediyorum. –

+0

Oh, bu görüntüleyiciyi backbuffer'a eklemek istedim, sonra glCopyTexSubImage2D kullanarak görüntüye kopyaladıktan sonra görüntü çalışmalarını görüntülemeyi (her şey gereken şekilde çizer), sadece acı verici bir şekilde yavaşlatmaktı. Arabamın nesi yanlış olduğunu anlamaya geri dönüyorum ... –

+0

İlginç. Evet, aynı zamanda bir renk renderbuffer eklemeniz gerekir. Bu arada, bu ilişkili değil, ancak doku nesnesinin ikiden fazla bir boyuta sahip olduğundan emin olmak isteyebilirsiniz, böylece eski iPhone'larla çalışır. İyi şanslar! – prideout