OpenGL ES Render to Texture - PullRequest
       50

OpenGL ES Render to Texture

32 голосов
/ 21 июня 2009

У меня были проблемы с поиском простого кода для рендеринга сцены в текстуру в OpenGL ES (особенно для iPhone, если это имеет значение). Мне интересно знать следующее:

  1. Как вы визуализируете сцену в текстуру в OpenGL ES?
  2. Какие параметры вы должны использовать для создания текстуры, которая может быть целью рендеринга в OpenGL ES?
  3. Есть ли какие-либо последствия применения этой визуализированной текстуры к другим примитивам?

Ответы [ 2 ]

43 голосов
/ 21 июня 2009

Вот как я это делаю.

Я определяю переменную текстуры (я использую класс Apple Texture2D, но вы можете использовать идентификатор текстуры OpenGL, если хотите) и буфер кадра:

Texture2d * texture;
GLuint textureFrameBuffer;

Затем в какой-то момент я создаю текстуру, кадровый буфер и присоединяю рендер-буфер. Это нужно сделать только один раз:

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

Каждый раз, когда я хочу рендерить текстуру, я делаю:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);

...
// GL commands
...

glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

По поводу вашего вопроса 3, вот и все, вы можете использовать текстуру, как если бы это была любая другая текстура.

9 голосов
/ 29 января 2013

Для рендеринга сцены в текстуру вы должны использовать рамочный буфер, связанный с текстурой. Вот метод, который я создал, чтобы упростить его:

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

Вы можете легко создать буфер кадра и текстуру:

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

Позже вы можете использовать _framebuffer для рендеринга сцены в _texture в вашем методе рисования:

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

Теперь вы можете делать то, что вы хотите с текстурой. Если вы хотите выполнить некоторую постобработку (размытие, цветение, тень и т. Д.), Вы можете!

...