1

私のC++コードはiOS用に設計されており、最小限の変更でNDKに移植しました。

フレームバッファをバインドして呼び出します

glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

次に、このようにメインフレームバッファをバインドします

glBindFramebuffer(GL_FRAMEBUFFER, 0);

glGetError()戻り値GL_INVALID_FRAMEBUFFER_OPERATION

フレームバッファに描画し、そのテクスチャを使用してメインフレームバッファに描画できます。しかし、私が電話glReadPixelsをすると、ゼロになります

そのコードはiOSで機能し、ほとんどのコードはAndroidで機能します。glReadPixels

glCheckFramebufferStatus(GL_FRAMEBUFFER)GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT0x8CD7を返します

-

フレームバッファまたはテクスチャからピクセルデータを取得し、ファイルに保存できるサンプルコードを検討します。answer

現在、テクスチャがアタッチされたバッファに描画でき、そのテクスチャを使用してメインバッファに描画できます。しかし、フレームバッファ/テクスチャからピクセルを取得してファイルに保存したり、Facebookに投稿したりすることはできません。

4

1 に答える 1

2

NDKの例「GL2JNIActivity」を変更するフレームバッファからglReadPixelsを実行することができました。

gl_code.cppを変更しました。ここで、初期化関数を追加しました。

char *pixel = NULL;
GLuint fbuffer, rbuffers[2];
int width, height;
bool setupMyStuff(int w, int h) {
     // Allocate the memory
     if(pixel != NULL) free(pixel);
     pixel = (char *) calloc(w * h * 4, sizeof(char)); //4 components
     if(pixel == NULL)  {
                  LOGE("memory not allocated!");
                       return false;
                       }

                       // Create and bind the framebuffer
    glGenFramebuffers(1, &fbuffer);
    checkGlError("glGenFramebuffer");

    glBindFramebuffer(GL_FRAMEBUFFER, fbuffer);
    checkGlError("glBindFramebuffer");

    glGenRenderbuffers(2, rbuffers);
    checkGlError("glGenRenderbuffers");

    glBindRenderbuffer(GL_RENDERBUFFER, rbuffers[0]);
    checkGlError("glGenFramebuffer[color]");

    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, w, h);
    checkGlError("glGenFramebuffer[color]");

    glBindRenderbuffer(GL_RENDERBUFFER, rbuffers[1]);
    checkGlError("glGenFramebuffer[depth]");

    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, w, h);
    checkGlError("glGenFramebuffer[depth]");

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbuffers[0]);
    checkGlError("glGenFramebuffer[color]");
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,  GL_RENDERBUFFER, rbuffers[1]);
    checkGlError("glGenFramebuffer[depth]");

    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
                                                    LOGE("Framebuffer not complete");
                                                    return false;
    }

    // Turn this on to confront the results in pixels when the fb is active with the ones obtained from the screen
    if(false) {
                  glBindFramebuffer(GL_FRAMEBUFFER, 0);
        checkGlError("glBindFramebuffer");
    }

    width = w;
    height = h;

    return true;
}

これは、フレームバッファを初期化し、出力用のスペースを割り当てるだけで、最後に呼び出します。

bool setupGraphics(int w, int h);

そして、出力をピクセル配列に保存するためのブロック(明らかに、

    checkGlError("glDrawArrays");

renderFrame()のステートメント:

{ 
// save the output of glReadPixels somewhere... I'm a noob about JNI however, so I leave this part as an exercise for the reader ;-)
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
checkGlError("glReadPixel(0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, pixel)");
int end = width * height * 4 - 1;
// This function returns the same results regardless of where the data comes from (screen or fbo)
LOGI("glReadPixel => (%hhu,%hhu,%hhu,%hhu),(%hhu,%hhu,%hhu,%hhu),(%hhu,%hhu,%hhu,%hhu),..., (%hhu, %hhu, %hhu, %hhu)",
      pixel[0], pixel[1], pixel[2], pixel[3],
      pixel[4], pixel[5], pixel[6], pixel[7],
      pixel[8], pixel[9], pixel[10], pixel[11],
      pixel[end - 3], pixel[end - 2], pixel[end - 1], pixel[end]);
}

logcatの結果は、フレームバッファに描画するか画面に描画するかに関係なく、同じです。

I/libgl2jni( 5246): glReadPixel => (0,4,0,255),(8,4,8,255),(0,4,0,255),..., (0, 4, 0, 255)
I/libgl2jni( 5246): glReadPixel => (8,4,8,255),(8,8,8,255),(0,4,0,255),..., (8, 8, 8, 255)
I/libgl2jni( 5246): glReadPixel => (8,8,8,255),(8,12,8,255),(8,8,8,255),..., (8, 8, 8, 255)
I/libgl2jni( 5246): glReadPixel => (8,12,8,255),(16,12,16,255),(8,12,8,255),..., (8, 12, 8, 255)
I/libgl2jni( 5246): glReadPixel => (16,12,16,255),(16,16,16,255),(8,12,8,255),..., (16, 16, 16, 255)
[...]

Froyo(電話)と4.0.3タブレットでテスト済み。

他のすべての詳細は、元のNDKの例(GL2JNIActivity)にあります。

お役に立てれば

編集:また、必ず確認してください:

オフスクリーンバッファからのAndroidNDKglReadPixels()

ポスターには同じ症状があるように見えました(そして正しいスレッドからglReadPixelsを呼び出す問題を解決しました)。

于 2013-03-29T23:00:17.660 に答える