2009-06-21 16 views
32

Mam problem ze znalezieniem prostego kodu do renderowania sceny do tekstury w OpenGL ES (specjalnie dla iPhone'a, jeśli to ma znaczenie). Interesuje mnie znajomość:OpenGL ES Renderowanie do tekstury

  1. Jak renderować scenę do tekstury w OpenGL ES?
  2. Jakie parametry należy użyć do utworzenia tekstury, która może być celem renderowania w OpenGL ES?
  3. Czy są jakieś implikacje związane z zastosowaniem tej renderowanej tekstury do innych elementów pierwotnych?

Odpowiedz

43

Tak to robię.

I zdefiniować zmienną tekstury (używam Texture2D klasę Apple, ale można użyć identyfikatora OpenGL tekstury jeśli chcesz) i bufor ramki:

Texture2d * texture; 
GLuint textureFrameBuffer; 

Wtedy w pewnym momencie, tworzę fakturę , bufor ramki i dołącz bufor renderowania. To wystarczy zrobić to raz:

texture = [[Texture2D alloc] initWithData:0 
          pixelFormat:kTexture2DPixelFormat_RGB888 
          pixelsWide:32 
          pixelsHigh:32 
          contentSize:CGSizeMake(width, height)]; 

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

// unbind frame buffer 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 

każdym razem chcę oddać tekstury, robię:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer); 

... 
// GL commands 
... 

glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 

O swoim pytaniu 3, to jest to, można użyć tekstury jako jeśli jest to jakakolwiek inna tekstura.

+0

Marco, czy wiesz, jak duży jest udział w utrzymywaniu bufora ramki i bufora renderowania dla każdej tekstury, na którą chcesz renderować? Mam kilka dużych tekstur, do których moja aplikacja musi się przydać, a ja łączę różne różne z jednym "dodatkowym" buforem ramki przy użyciu glFramebufferTexture2DOES. Czy utrzymanie osobnego bufora ramki dla każdego byłoby lepsze? –

+0

Czy możesz edytować kod, aby wywołanie initWithData: ... pasowało bez przewijania? – nornagon

+0

OK, edytowane, teraz wygląda lepiej. –

9

Aby renderować scenę do tekstury, należy użyć framebuffera powiązanego z teksturą. Oto sposób, że stworzony w celu uproszczenia go:

void glGenTextureFromFramebuffer(GLuint *t, GLuint *f, GLsizei w, GLsizei h) 
{ 
    glGenFramebuffers(1, f); 
    glGenTextures(1, t); 

    glBindFramebuffer(GL_FRAMEBUFFER, *f); 

    glBindTexture(GL_TEXTURE_2D, *t); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *t, 0); 

    GLuint depthbuffer; 
    glGenRenderbuffers(1, &depthbuffer);  
    glBindRenderbuffer(GL_RENDERBUFFER, depthbuffer); 
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer); 

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 
    if(status != GL_FRAMEBUFFER_COMPLETE) 
     NSLog(@"Framebuffer status: %x", (int)status); 
} 

Można tworzyć bufor ramki i tekstury w prosty sposób:

GLuint _texture, _framebuffer; 
GLsizei w,h; 
float scale = [UIScreen mainScreen].scale; 
w = self.view.bounds.size.width * scale; 
h = self.view.bounds.size.height * scale; 
glGenTextureFromFramebuffer(&_texture, &_framebuffer, w, h); 

można później użyć _framebuffer do renderowania sceny do _texture w losowaniu metoda:

glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); 
//draw here the content you want in the texture 
//_texture is now a texture with the drawn content 

//bind the base framebuffer 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
//or if you use GLKit 
[view bindDrawable]; 
//draw normaly 

Teraz możesz zrobić, co chcesz z fakturą. Jeśli chcesz wykonać trochę przetwarzania (rozmycie, rozkwit, cień itp.), Możesz!

+0

Witaj, skąd otrzymałeś '_renderToTextureBuffer'? –

+0

_renderToTextureBuffer to _framebuffer i popraw to, sry – Anthony

+0

Fajnie, właśnie o tym myślałem. Czy masz to w czynnym przykładzie? Spróbuję dodać to do mojego kodu (ponownie), ale nie jestem pewien, jak narysować teksturę "// narysuj tutaj zawartość, którą chcesz w fakturze" Czy mogę to zrobić przy pomocy VBO i 'glDrawArrays()' ? –

Powiązane problemy