android - Draw to framebuffer object, then blit to primary display (GLES 3.0) -
i attempting create framebuffer object, , blit primary display. purpose of to cache screen shot can blit display whenever want without re-rendering object. using open gles 3.0 android ndk.
i created frame buffer in normal way.
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 make complete framebuffer object %d", status ); } else { logi( "frame buffer complete." ); }
this works without error. able edit frame buffer, successfully.
glbindframebuffer( gl_draw_framebuffer, framebuffer ); glbindframebuffer( gl_read_framebuffer, framebuffer ); // fill screen color. glclearcolor( red, green, blue, 255 ); glclear( gl_color_buffer_bit ); read_pixels( ); //wrapper glreadpixels. shows pixels in frame buffer object have desired color.
however, attempting blit main draw buffer fails.
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 black screen, unless use glclearcolor directly on primary display buffer.
i able around problem using texture (instead of render buffer) frame buffer object, drawing frame buffer, , drawing frame buffer texture default buffer. isn't answer, work around, i'd still appreciate if has answer original question.
for reference, include key code below:
gluint loadframebuffertexture( escontext *context, int width, int height ) { glgenframebuffers( 1, &(context->framebuffer) ); glbindframebuffer( gl_framebuffer, context->framebuffer ); // create texture gluint texture; glgentextures( 1, &texture ); glbindtexture( gl_texture_2d, texture ); gltexparameteri( gl_texture_2d, gl_texture_min_filter, gl_linear ); glteximage2d( gl_texture_2d, 0, gl_rgba, width, height, 0, gl_rgba, gl_unsigned_byte, null ); glframebuffertexture2d( gl_framebuffer, gl_color_attachment0, gl_texture_2d, texture, 0 ); gluint depthrenderbuffer; glgenrenderbuffers( 1, &depthrenderbuffer ); glbindrenderbuffer( gl_renderbuffer, depthrenderbuffer ); glrenderbufferstorage( gl_renderbuffer, gl_depth_component16, width, height ); glframebufferrenderbuffer( gl_framebuffer, gl_depth_attachment, gl_renderbuffer, depthrenderbuffer ); glenum status = glcheckframebufferstatus( gl_framebuffer ); if (status != gl_framebuffer_complete) { logi("failed make complete framebuffer object "); } else { logi("frame buffer complete."); } glbindframebuffer( gl_framebuffer, 0 ); return texture; } void draw_frame(int red, int green, int blue) { glbindframebuffer( gl_framebuffer, escontext->framebuffer ); glclearcolor( red, green, blue, 255 ); glclear( gl_color_buffer_bit ); glbindframebuffer(gl_framebuffer, 0 ); drawframe( escontext ); eglswapbuffers( engine->display, engine->surface ); } void drawframe( escontext *escontext ) { userdata *userdata = (userdata *)escontext->userdata; glfloat vvertices[] = {-1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f }; glushort indices[] = { 0, 1, 2, 0, 2, 3 }; glviewport( 0, 0, escontext->width, escontext->height ); gluseprogram( userdata->programobject ); glvertexattribpointer( 0, 3, gl_float, gl_false, 5 * sizeof( glfloat ), vvertices ); glvertexattribpointer( 1, 2, gl_float, gl_false, 5 * sizeof( glfloat ), &vvertices[3] ); glenablevertexattribarray( 0 ); glenablevertexattribarray( 1 ); glactivetexture( gl_texture0 ); glbindtexture( gl_texture_2d, userdata->frametexid ); gluniform1i( userdata->basemaploc, 0 ); gldrawelements( gl_triangles, 6, gl_unsigned_short, indices ); }
Comments
Post a Comment