2011-09-09 27 views
0

オーバーライドされたレンダラー機能の外でGL10オブジェクトを使用すると、私はこの奇妙な問題を抱えています。glReadPixelsの奇妙な問題

たとえば、カラーコードでジオメトリを選択する目的で、glReadPixelsでカラーバッファを読み込もうとしました。

@Override 
public void onDrawFrame(GL10 gl) { 

... 

    ByteBuffer pixel = ByteBuffer.allocateDirect(4); 
    pixel.order(ByteOrder.nativeOrder()); 
    gl.glReadPixels(0, 0, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixel); 

    while (pixel.hasRemaining()){ 
    Log.v(TAG,""+(int)(pixel.get() & 0xFF)); 
    } 

} 

これは動作し、左下隅のピクセルの範囲0..255のカラー値を与えます。 今、私は私のGL10-オブジェクトを取得し、フィールドとしてクラス全体が使用できるようにしたとき、それはdoesn'tもはや動作するように見える:

@Override 
public void update(Observable observable, Object data) { 
Log.v(TAG, "update Observer glsurfaceviewrenderer"); 
if (data instanceof MotionEvent){ 
    MotionEvent event = (MotionEvent) data; 

    ByteBuffer pixel = ByteBuffer.allocateDirect(4); 
    pixel.order(ByteOrder.nativeOrder()); 
    gl.glReadPixels(0, 0, 1, 1, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, pixel); 


    while (pixel.hasRemaining()){ 
    Log.v(TAG,""+(int)(pixel.get() & 0xFF)); 

    } 

} 
} 

このdoesn't作業を、すべての色が値0のみを持っています違いは、私はフィールドを介してgl - オブジェクトを使用し、関数 - 引数を使用しないことです。 gl-objectへのメモリポインタをLogに印字して、両方が同じアドレスを持つようにしました。

私は今本当に困っています...アイデアを持っている人は誰ですか?

答えて

4

2つの問題:

1)あなたが唯一のOpenGLコンテキストがバインドされているスレッドから呼び出しを行うことができます。 onDrawFrameは、GLSurfaceViewで作成されたスレッドで実行されますが、メインUIスレッドから更新メソッドが呼び出されたと仮定しています。

2)glReadPixelsは、現在レンダリング中のバッファから読み込みます。 onDrawFrameが返った後、GLSurfaceViewはeglSwapBuffersを呼び出します。あなたが描画していたバッファを読み取ることができなくなります。

コードを再編成して、onDrawFrameが呼び出されるタイミングでどのピクセルを読む必要があるかを知る必要があります。唯一の他の選択肢は、毎回フレーム全体をフェッチすることです。

+1

http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/eglSwapBuffers.html サーフェスのEGL_SWAP_BEHAVIOR属性の値がEGL_BUFFER_PRESERVEDの場合、カラーバッファの内容は変更されません値がEGL_BUFFER_DESTROYEDの場合は未定義です。属性EGL_SWAP_BEHAVIORは、EGLバージョンが1.2以上の場合にのみサポートされます。しかし、AndroidはEGL10とEGL11のみをサポートしています。 レンダラーがJNIで実装されている場合は、eglSwapBuffersを自分で呼び出す必要があるため、レンダリングサイクルの動作をさらに制御できます。 Android NDKのネイティブアクティビティサンプルを参照してください。 – AndrewBloom