Question

J'ai eu du mal à trouver du code simple pour restituer une scène en texture dans OpenGL ES (spécifiquement pour l'iPhone, si cela compte). Je voudrais savoir ce qui suit:

  1. Comment rendre une scène en texture dans OpenGL ES?
  2. Quels paramètres devez-vous utiliser pour créer une texture pouvant être une cible de rendu dans OpenGL ES?
  3. L'application de cette texture rendue à d'autres primitives a-t-elle des implications?
Était-ce utile?

La solution

Voici comment je le fais.

Je définis une variable de texture (j'utilise la classe Texture2D d'Apple, mais vous pouvez utiliser un identifiant de texture OpenGL si vous le souhaitez), ainsi qu'un tampon d'image:

Texture2d * texture;
GLuint textureFrameBuffer;

Ensuite, à un moment donné, je crée la texture, le tampon d'images et attache le tampon de rendu. Il suffit de le faire une fois:

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

Chaque fois que je veux rendre la texture, je fais:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);

...
// GL commands
...

glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

À propos de votre question 3, c'est tout, vous pouvez utiliser la texture comme s'il s'agissait d'une autre texture.

Autres conseils

Pour rendre la scène en texture, vous devez utiliser un framebuffer associé à une texture. Voici une méthode que j'ai créée pour le simplifier:

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

Vous pouvez créer facilement le tampon d'images et la texture:

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

Vous pouvez utiliser ultérieurement _framebuffer pour rendre la scène sous forme de texture dans votre méthode de dessin:

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

Vous pouvez maintenant faire ce que vous voulez avec la texture. Si vous voulez faire du post-traitement (flou, efflorescence, ombre, etc.), vous pouvez!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top