2009-10-30 14 views
7

Próbuję wyrenderować teksturę, a następnie narysować tę teksturę na ekranie przy użyciu OpenGL ES na iPhonie. Używam this question jako punktu wyjścia i robię rysunek w podklasie demona Apple EAGLView.OpenGL ES render do tekstury, a następnie narysuj teksturę

Zmienne instancji:

GLuint textureFrameBuffer; 
Texture2D * texture; 

aby zainicjować bufor ramki i tekstury, robię to:

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); 

Teraz, jeśli po prostu narysować moją scenę na ekranie, jak zwykle, działa dobrze:

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

Ale jeśli odda „textureFrameBuffer”, a następnie „texture” rysować na ekranie, otrzymany im wiek jest do góry nogami i "na wylot". Oznacza to, że wygląda tak, jakby obiekty 3D były skierowane do wewnątrz, a nie na zewnątrz - przednia powierzchnia każdego obiektu jest przezroczysta i widzę wnętrze tylnej ściany. Oto kod:

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]; 

mogę odwrócić obraz w normalnym położeniu dość łatwo poprzez reorganizację (glTexCoordPointer) koordynuje odpowiednio (w metodzie Texture2D za drawInRect), ale to nie rozwiązuje „inside-out” problemu.

Próbowałem zastąpić teksturę Texture2D ręcznie utworzoną teksturą OpenGL, a wynik był taki sam. Rysowanie Texture2D załadowanego z obrazu PNG działa dobrze.

Jeśli chodzi o rysowanie obiektów, każdy wierzchołek ma określoną normalną jednostkę i włączono GL_NORMALIZE.

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

Wszystko rysuje się dobrze, gdy jest renderowane na ekranie; GL_DEPTH_TEST jest włączony i działa świetnie.

Wszelkie sugestie, jak to naprawić? Dzięki!

+0

Jeśli chodzi o problem "inside-out": jeśli twoje prymitywy skierowane do przodu są poddane ubojowi, masz problem z porządkowaniem wierzchołków, który jest używany do określenia aspektu normalnego. To nie jest problem z teksturowaniem, chyba że coś nie rozumiem. Czy masz włączoną obsługę GL_CULL_FACE? – prideout

+0

GL_CULL_FACE nie został włączony. Włączenie go zdecydowanie poprawia ogólny wygląd. Obiekt normalny wydaje się teraz właściwą drogą, ale wiele przednich twarzy, które powinny być ukryte, jest teraz widocznych, niezależnie od tego, czy są (a raczej powinny być) zasłonięte przez inną twarz. Czy to oznacza problem z uzwojeniem moich trójkątów? Używam skryptu do eksportu wierzchołków z Blendera; Upewnię się, że uzwojenie jest jednolite po wyeksportowaniu. Pamiętaj, że wszystko wygląda idealnie, gdy rysuję bezpośrednio na ekranie (a GL_CULL_FACE jest włączone lub wyłączone nie ma znaczenia). –

Odpowiedz

3

Ciekawą częścią jest to, że podczas rysowania bezpośrednio do bufora wstecznego widzisz inny wynik. Ponieważ jesteś na platformie iPhone'a, zawsze jesteś rysowany na FBO, nawet gdy rysujesz na backbufferze.

Upewnij się, że do zewnętrznego FBO masz dołączony bufor głębi. W kodzie inicjującym możesz dodać następujący fragment zaraz po glBindFramebufferOES (...).

// 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

Możesz być na czymś, ale to nie działa jeszcze ... Po wykonaniu tej czynności i dołączeniu tekstury (jak wcześniej), glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES) zwraca GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES. Czy frameBuffer również potrzebuje dołączonego bufora renderowania kolorów? (Próbowałem to szybko, bez powodzenia, ale zachowam to.) Dzięki za twoją pomoc, naprawdę to doceniam. –

+0

Och, chciałem dodać to renderowanie do bufora wstecznego, a następnie skopiować do mojego obrazu za pomocą glCopyTexSubImage2D, a następnie wyświetlając obraz działa (wszystko rysuje tak, jak powinno), jest to po prostu boleśnie powolne. Powrót do zastanowienia się, co jest nie tak z moim buforem ... –

+0

Interesujące. Tak, musisz również dołączyć kolorowy bufor renderowania. Nawiasem mówiąc, nie jest to powiązane, ale możesz chcieć, aby twój obiekt tekstury miał potęgę dwóch rozmiarów, aby działał ze starszymi urządzeniami iPhone. Powodzenia! – prideout

Powiązane problemy