问题
I'm trying to implement color picking using GLES20.glReadPixels function in android OpenGL ES. The problem is that this function is always returning 0,0,0,0 as color and not the correct color values. Any idea why? My code looks like this:
public boolean onTouchEvent(MotionEvent event)
{
if (event != null)
{
float x = event.getX();
float y = event.getY();
if (event.getAction() == MotionEvent.ACTION_UP)
{
int newX = (int)x;
int newY = (int)y;
ByteBuffer pixel = ByteBuffer.allocate(4);
pixel.order(ByteOrder.nativeOrder());
pixel.position(0);
GLES20.glReadPixels(newX, (int)mRenderer.viewport[3] - newY, 1, 1,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, pixel);
}
return true;
}
else
{
return super.onTouchEvent(event);
}
So as I said before... the result of the pixel array is always 0,0,0,0. Dont know why :/ What am I doing wrong? I was using the lighthouse tutorial as a reference: http://www.lighthouse3d.com/opengl/picking/index.php3?color2 And I really can't see the mistake at this point :/ Oh I forgot to tell that my scene contains a 3D cube which is fully BLUE so the result should be something like 0,0,1,0 when I click on it but it isn't :(
EDIT: The code from the Renderer where the Cube is drawn (it rotates arround its y-axis)
public void onDrawFrame(GL10 unused) {
float[] scratch = new float[16];
GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glEnable(GLES20.GL_DEPTH_TEST);
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3.0f, 0f, -0.3f, 0.0f, 0.0f, 1.0f, 0.0f);
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
float[] mModelMatrix = new float[16];
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, 0, 0, -0.5f);
Matrix.setIdentityM(mRotationMatrix, 0);
Matrix.rotateM(mRotationMatrix, 0, mDeltaX, 0, 1.0f, 0);
Matrix.rotateM(mRotationMatrix, 0, -mDeltaY, 1.0f, 0, 0);
mDeltaX = 0.2f;
mDeltaY = 0.2f;
float[] mTempMatrix = new float[16];
Matrix.multiplyMM(mTempMatrix, 0, mRotationMatrix, 0, mAccumulatedRotation, 0);
System.arraycopy(mTempMatrix, 0, mAccumulatedRotation, 0, 16);
float[] temp = new float[16];
Matrix.multiplyMM(temp, 0, mModelMatrix, 0 , mAccumulatedRotation, 0);
Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, temp, 0);
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, 0, 0, 0.5f);
float[] temp2 = new float[16];
Matrix.multiplyMM(temp2, 0, scratch, 0, mModelMatrix, 0);
mCube.drawCube(temp2);
}
回答1:
Like all other OpenGL calls, glReadPixels()
only works if there is a current OpenGL context.
In Android, OpenGL rendering is mostly done using a GLSurfaceView
, which takes care of spawning a secondary thread for rendering, creating an OpenGL context, and making that context current in the secondary rendering thread while invoking the methods in your GLSurfaceView.Renderer
implementation.
onTouchEvent()
is invoked in the UI thread, so you won't have a current OpenGL context here. To use glReadPixels()
, you can forward the request to your rendering thread using the GLSurfaceView.queueEvent()
method, and then process it asynchronously the next time your Renderer.onDraw()
method is invoked.
来源:https://stackoverflow.com/questions/24083972/opengl-es-2-0-android-color-picking