Failed to initialize FBO on Android SDK emulator

So, this is how the FBO is initialized:

/**
 * Initializes Renderbuffer.
 */
static GLuint init_renderbuffer(GLuint width, GLuint height, GLenum format) {
    GLuint renderbuffer;

    glGenRenderbuffers(1, &renderbuffer);
    checkGlError("init_renderbuffer: glGenRenderbuffers");

    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    checkGlError("init_renderbuffer: glBindRenderbuffer");

    glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
    checkGlError("init_renderbuffer: glRenderbufferStorage");

    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    checkGlError("init_renderbuffer: glBindRenderbuffer");

    return renderbuffer;
}

/**
 * Initializes FBO.
 */
static void engine_init_fbo(struct engine* engine, GLuint width, GLuint height) {
    // create renderable texture
    glGenTextures(1, &engine->renderableTexture);
    checkGlError("engine_init_fbo: glGenTextures");

    glBindTexture(GL_TEXTURE_2D, engine->renderableTexture);
    checkGlError("engine_init_fbo: glBindTexture");

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
    checkGlError("engine_init_fbo: glTexImage2D");

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    checkGlError("engine_init_fbo: glTexParameteri");

    // create render buffers
    engine->depthRenderBuffer   = init_renderbuffer(width, height, GL_DEPTH_COMPONENT16);
    engine->stencilRenderBuffer = init_renderbuffer(width, height, GL_STENCIL_INDEX8);

    LOGI("****************************** FBO: T: %d, D: %d, S: %d", engine->renderableTexture,
         engine->depthRenderBuffer, engine->stencilRenderBuffer);

    // create framebuffer object
    glGenFramebuffers(1, &engine->framebufferObject);
    checkGlError("engine_init_fbo: glGenFramebuffers");

    glBindFramebuffer(GL_FRAMEBUFFER, engine->framebufferObject);
    checkGlError("engine_init_fbo: glBindFramebuffer");

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, engine->renderableTexture, 0);
    checkGlError("engine_init_fbo: glFramebufferTexture2D");

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, engine->depthRenderBuffer);
    checkGlError("engine_init_fbo: glFramebufferRenderbuffer");

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, engine->stencilRenderBuffer);
    checkGlError("engine_init_fbo: glFramebufferRenderbuffer");

    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    checkGlError("engine_init_fbo: glCheckFramebufferStatus");

    if(status != GL_FRAMEBUFFER_COMPLETE) {
        switch(status) {
            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
                LOGI("****************************** engine_init_fbo: FBO error: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
                break;

            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
                LOGI("****************************** engine_init_fbo: FBO error: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
                break;

            case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
                LOGI("****************************** engine_init_fbo: FBO error: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
                break;

            case GL_FRAMEBUFFER_UNSUPPORTED:
                LOGI("****************************** engine_init_fbo: FBO error: FRAMEBUFFER_UNSUPPORTED");
                break;

            default:
                LOGI("****************************** engine_init_fbo: Unknown FBO error");
        }
    }
    else {
        LOGI("****************************** engine_init_fbo: FBO has been successfully initialized");
    }

    glBindTexture(GL_TEXTURE_2D, 0);
    checkGlError("engine_init_fbo: glBindTexture");

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    checkGlError("engine_init_fbo: glBindFramebuffer");
}

      

As you can see, everything here is done in accordance with the OpenGL ES standard: a 2D texture with internal RGB565 format is used as a color; 2 renderbuffers are used as surface depth and stencils; dimensions 32x32.

It works fine on a real device (Alcatel OT 918D, prints "FBO initialized successfully" in adb logcat), but FRAMEBUFFER_UNSUPPORTED is not executed with the virtual device.

My virtual device processor is an atom, GPU emulation is enabled, OpenGL ES 2.0 works great with other applications (that don't use FBOs).

The entire project (based on the NDK sample native activity) that can be compiled with ndk-build is here: https://docs.google.com/file/d/0Byy41LxMuTKUZVJxSUtBZDVDXzA/edit?usp=sharing

My question is: Is this a bug in the android-sdk emulator? As everything seems to meet the minimum requirements for an OpenGL ES 2.0 implementation.

Thank!

EDIT: Found a solution. It looks like AVD doesn't support this attachment configuration. I had to remove the stencil attachment to get it to work.

EDIT2: This appears to be a context creation issue. I don't need stencil bits, so AVD created context without stencil support, and Alcatel phone with stencil.

Anyway, this is not a mistake, but my mistake.

+3


source to share





All Articles