3

したがって、これは FBO の初期化方法です。

/**
 * 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");
}

ご覧のとおり、ここではすべて OpenGL ES 標準に従って行われます。RGB565 内部形式の 2D テクスチャが色として使用されます。2 つのレンダー バッファーが深度およびステンシル サーフェスとして使用されます。寸法は32x32です。

実際のデバイスでは正常に動作しますが (Alcatel OT 918D、adb logcat に「FBO が正常に初期化されました」と表示されます)、仮想デバイスでは FRAMEBUFFER_UNSUPPORTED で失敗します。

私の仮想デバイスの CPU はアトムで、GPU エミュレーションが有効で、OpenGL ES 2.0 は正常に動作します - 別のアプリケーション (FBO を使用しない) で確認しました。

プロジェクト全体 (NDK のネイティブ アクティビティ サンプルに基づく) は、ndk-build でコンパイルできます: https://docs.google.com/file/d/0Byy41LxMuTKUZVJxSUtBZDVDXzA/edit?usp=sharing

私の質問は: これは android-sdk エミュレーターのバグですか? すべてが OpenGL ES 2.0 実装の最小要件を満たしているように見えるためです。

ありがとうございました!

編集:解決策が見つかりました。AVD は、添付オブジェクトのこの構成をサポートしていないようです。それを機能させるには、ステンシルの添付ファイルを削除する必要がありました。

EDIT2: コンテキスト作成の問題のようです。私はステンシル ビットを必要としなかったので、おそらく AVD はステンシルをサポートせずにコンテキストを作成し、アルカテルの電話はステンシルを使用して作成されました。

とにかく、これはバグではなく、私のミスです。

4

0 に答える 0