OpenGL ES 2.0 で Render to Texture 環境をセットアップするのに苦労しています。
必要なのは、画面に表示されるメインの FrameBuffer と、テクスチャに接続されたセカンダリ FrameBuffer です。このテクスチャは、メインの FrameBuffer で使用されます。
まず、次のコードでメインの FrameBuffer を初期化します。
-(void)initializeBuffers{
//Build the main FrameBuffer
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
//Build the color Buffer
glGenRenderbuffers(1, &colorBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
//setup the color buffer with the EAGLLayer (it automatically defines width and height of the buffer)
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:EAGLLayer];
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &bufferWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &bufferHeight);
//Attach the colorbuffer to the framebuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
//Check the Framebuffer status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
NSAssert(status == GL_FRAMEBUFFER_COMPLETE, ERROR_FRAMEBUFFER_FAIL);
}
次に、セカンダリ バッファーを初期化する関数を呼び出します。
-(void)setupRenderToTexture{
glGenTextures(1, &gridTextureID);
glBindTexture(GL_TEXTURE_2D, gridTextureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bufferWidth, bufferHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &textureColorBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, textureColorBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, bufferWidth, bufferHeight);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenFramebuffers(1, &textureFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, textureFrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gridTextureID, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, textureColorBuffer);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER) ;
if(status != GL_FRAMEBUFFER_COMPLETE) {
NSLog(@"failed to make complete framebuffer object %x", status);
}else{
NSLog(@"Buffer ok");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
この時点で、描画するときは、次の関数render
を呼び出す関数を呼び出しますrenderToTexture
。
- (void)render:(CADisplayLink*)displaylink{
[self renderToTexture];
glBindBuffer(GL_FRAMEBUFFER, frameBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
glClearColor(0.0, 1.0, 0.0, 1.0);
glViewport(0, 0, bufferWidth, bufferHeight);
glClear(GL_COLOR_BUFFER_BIT);
for(GLNode *node in sceneNodes){
[node draw]; //Draw some triangles...
}
[context presentRenderbuffer:GL_RENDERBUFFER];
}
ここでrenderToTexture
関数: -(void)renderToTexture{
glBindFramebuffer(GL_FRAMEBUFFER, textureFrameBuffer);
glClearColor(1.0, 0.0, 0.0, 1.0);
glViewport(0, 0, bufferWidth, bufferHeight);
glClear(GL_COLOR_BUFFER_BIT);
//Render something to texture
}
メイン バッファに関連するコードのみを使用すると (つまり、関数initializeBuffers
とrender
)、メイン FrameBuffer の内容が画面に正しく表示されます。setupRenderToTexture
render to texture (および)に関連する関数を使用しようとするとrenderToTexture
、メインの Framebuffer が画面に描画されなくなります。
この構成に何か問題があるのでしょうか。この動作を修正するにはどうすればよいでしょうか。