我正在尝试创建一个帧缓冲区对象,然后将其传送到主显示器。这样做的目的是缓存一个屏幕截图,我可以在需要时随时将其显示到显示器上,而无需重新渲染对象。我正在使用带有 android NDK 的 Open GLES 3.0。
我以正常方式创建了一个帧缓冲区。
GLuint framebuffer = NULL;
glGenFramebuffers( 1, &framebuffer );
glBindFramebuffer( GL_FRAMEBUFFER, framebuffer );
GLuint colorRenderBuffer = NULL;
glGenRenderbuffers( 1, &colorRenderbuffer );
glBindRenderbuffer( GL_RENDERBUFFER, colorRenderbuffer );
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGBA8, engine->width, engine->height );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer );
GLuint depthRenderbuffer = NULL;
glGenRenderbuffers( 1, &depthRenderbuffer );
glBindRenderbuffer( GL_RENDERBUFFER, depthRenderbuffer );
glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, engine->width, engine->height );
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer );
GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
if (status != GL_FRAMEBUFFER_COMPLETE) {
LOGI( "failed to make complete framebuffer object %d", status );
}
else {
LOGI( "Frame buffer is complete." );
}
这工作没有错误。然后我可以成功地编辑帧缓冲区。
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, framebuffer );
glBindFramebuffer( GL_READ_FRAMEBUFFER, framebuffer );
// Just fill the screen with a color.
glClearColor( red, green, blue, 255 );
glClear( GL_COLOR_BUFFER_BIT );
read_pixels( ); //wrapper for glReadPixels. Shows that all pixels in the frame buffer object have the desired color.
但是,尝试将其传输到主绘图缓冲区失败。
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
glBindFramebuffer( GL_READ_FRAMEBUFFER, framebuffer );
glReadBuffer( GL_COLOR_ATTACHMENT0 );
glBlitFramebuffer( 0, 0, engine->width, engine->height, 0, 0, engine->width, engine->height, GL_COLOR_BUFFER_BIT, GL_LINEAR );
LOGI("GL error after blit: %d", glGetError()); //no error reported
glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
read_pixels( engine ); //gives zero'd buffer (wrong result)
eglSwapBuffers( engine->display, engine->surface ); //shows a black screen, unless I use glClearColor directly on the primary display buffer.