我一直无法找到直观的代码来渲染场景到OpenGL ES中的纹理(特别是iPhone,如果有的话)。我有兴趣了解以下内容:OpenGL ES渲染到纹理
- 如何在OpenGL ES中渲染场景到纹理?
- 您必须使用哪些参数来创建能够成为OpenGL ES中渲染目标的纹理?
- 将这个渲染纹理应用到其他基元有什么意义吗?
我一直无法找到直观的代码来渲染场景到OpenGL ES中的纹理(特别是iPhone,如果有的话)。我有兴趣了解以下内容:OpenGL ES渲染到纹理
这就是我的做法。
我定义了一个纹理变量(我用苹果的Texture2D
类,但如果你愿意,你可以使用一个OpenGL纹理ID)和帧缓冲器:
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,就是这样,你可以使用质地如果它是任何其他纹理。
要将场景渲染到纹理,您必须使用与纹理关联的帧缓冲区。下面是我创建简化它的方法:
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
现在你可以做你想要的纹理。如果你想做一些后处理(模糊,绽放,阴影等),你可以!
Marco,你知道为每个需要渲染的纹理保留一个framebuffer和renderbuffer需要多少开销吗?我有几个大的纹理我的应用程序需要绘制到,我用curFramebufferTexture2DOES currnetly附加到一个单独的“额外”帧缓冲区。会保持一个单独的帧缓冲每个更好? – 2009-06-21 20:12:56
您可否请编辑您的代码,以便initWithData:...调用适合不滚动? – nornagon 2010-06-12 00:08:19