5

glReadPixels を置き換えるために Android ネイティブ プロセスで EGL_KHR_image_base を使用しようとしています。

これは私がこれまでに持っているものですが、空のバッファーを生成します (ゼロのみ)

uint8_t *ptr;
GLuint mTexture;
status_t error;

GraphicBufferAlloc* mGraphicBufferAlloc  = new GraphicBufferAlloc();    
sp<GraphicBuffer> window = mGraphicBufferAlloc->createGraphicBuffer(width, height, PIXEL_FORMAT_RGBA_8888, GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE,&error);
EGLClientBuffer buffer = (EGLClientBuffer)window->getNativeBuffer();
EGLint eglImageAttributes[] = {EGL_WIDTH, width, EGL_HEIGHT, height, EGL_MATCH_FORMAT_KHR,  EGL_FORMAT_RGBA_8888_KHR, EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
EGLImageKHR image = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,buffer, eglImageAttributes);

glGenTextures(1, &mTexture);    
glBindTexture(GL_TEXTURE_2D, mTexture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
window->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, (void**)&ptr); 
memcpy(texture, ptr, width * height * 4);
window->unlock();

私は何を間違っていますか?

4

2 に答える 2

7

空のバッファを作成し、その内容を読み込んでいます。コードのウォークスルー:

GraphicBufferAlloc* mGraphicBufferAlloc = new GraphicBufferAlloc();
sp<GraphicBuffer> window = mGraphicBufferAlloc->createGraphicBuffer(width, height, PIXEL_FORMAT_RGBA_8888, GraphicBuffer::USAGE_SW_READ_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE,&error);

これによりGraphicBuffer、指定されたサイズとピクセル形式で新しい (「gralloc バッファー」と呼ばれることもあります) が作成されます。使用フラグを使用すると、テクスチャとして使用したり、ソフトウェアから読み取ったりすることができます。これは、必要なものです。

EGLClientBuffer buffer = (EGLClientBuffer)window->getNativeBuffer();
EGLint eglImageAttributes[] = {EGL_WIDTH, width, EGL_HEIGHT, height, EGL_MATCH_FORMAT_KHR,  EGL_FORMAT_RGBA_8888_KHR, EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
EGLImageKHR image = eglCreateImageKHR(eglGetCurrentDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,buffer, eglImageAttributes);

これは、ANativeWindowオブジェクト (ボンネットの下にあるバッファーのキュー) を取得し、それにEGLImage「ハンドル」をアタッチします。

glGenTextures(1, &mTexture);    
glBindTexture(GL_TEXTURE_2D, mTexture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);

これにより、新しいテクスチャ オブジェクトが作成され、 がアタッチEGLImageされます。をテクスチャANativeWindowオブジェクトとして使用できるようになりました。

window->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, (void**)&ptr); 
memcpy(texture, ptr, width * height * 4);
window->unlock();

これにより、バッファーが読み取り用にロックされ、そこからデータがコピーされ、ロックが解除されます。何も描いていないので、読むものは何もありません。

これを有効にするには、テクスチャに何かをレンダリングする必要があります。これを行うには、FBO を作成してそれにテクスチャをカラー バッファとしてアタッチするか、 を使用glCopyTexImage2D()してフレームバッファからテクスチャにピクセルをコピーします。

への呼び出しの前に以下を追加することで、あなたの例を機能させることができましたgrallocBuffer->lock():

glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, width, height, 0);
glFinish();

これglFinish()は、ピクセルを確認する前に、GL がピクセルのコピーを完了していることを確認するために必要です。

編集:私のオフィスメイトは、GL_TEXTURE_2D必要があることを提案しましたGL_TEXTURE_EXTERNAL_OES。まだ試していません。

編集:この質問も参照してください。

于 2014-01-18T01:52:18.610 に答える