OpenGLES2.0中Android上的颜色拾取

OpenGLES2.0中Android上的颜色拾取,android,colors,opengl-es-2.0,picking,Android,Colors,Opengl Es 2.0,Picking,我已经实现了一个颜色选择方法,它也可以工作;有时候。问题是,当我在onSurfaceChanged方法中调用我的方法时,它确实读回了正确的像素。但是当我在GLSurfaceView的onTouchevent中调用我的方法时,它只回读零。在我的方法中,我创建了一个framebuffer对象,并将两个renderbuffer对象附加到它。当脏时,我的渲染器被设置为RENDERMODE\u,并且glGetError()返回0。问题到底出在哪里?我不确定这是否是我的方法,或者我只是不能在onTouche

我已经实现了一个颜色选择方法,它也可以工作;有时候。问题是,当我在
onSurfaceChanged
方法中调用我的方法时,它确实读回了正确的像素。但是当我在GLSurfaceView的
onTouchevent
中调用我的方法时,它只回读零。在我的方法中,我创建了一个
framebuffer对象
,并将两个
renderbuffer对象
附加到它。当脏时,我的渲染器被设置为
RENDERMODE\u,并且
glGetError()
返回0。问题到底出在哪里?我不确定这是否是我的方法,或者我只是不能在
onTouchevent
中这样做。以下是我在渲染器中拾取方法的源代码:

public int pick(int x, int y) {
    int result = -2;

    int[]  view = new int[4];
    GLES20.glGetIntegerv(GLES20.GL_VIEWPORT, view, 0);

    y = view[3] - y;

    int[] fbo = new int[1];
    GLES20.glGenFramebuffers(1, fbo, 0);
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);

    int[] rbo = new int[2];
    GLES20.glGenRenderbuffers(2, rbo, 0);

    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, rbo[0]);
    GLES20.glRenderbufferStorage(
            GLES20.GL_RENDERBUFFER, 
            GLES20.GL_RGBA4, view[2], view[3]);

    GLES20.glFramebufferRenderbuffer(
            GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, 
            GLES20.GL_RENDERBUFFER, rbo[0]);

    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, rbo[1]);
    GLES20.glRenderbufferStorage(
            GLES20.GL_RENDERBUFFER, 
            GLES20.GL_DEPTH_COMPONENT16, 
            view[2], view[3]);

    GLES20.glFramebufferRenderbuffer(
            GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, 
            GLES20.GL_RENDERBUFFER, rbo[1]);

    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
    if (status == GLES20.GL_FRAMEBUFFER_COMPLETE) {
        result = -1;
        GLES20.glClear(
                GLES20.GL_COLOR_BUFFER_BIT | 
                GLES20.GL_DEPTH_BUFFER_BIT);

        for (int i = 0; i < mObjects.size(); i++)
            mObjects.get(i).render(mProgram, mMatrixMVP, true);

        ByteBuffer pixels = ByteBuffer.allocate(view[2] * view[3] * 4);
        pixels.order(ByteOrder.nativeOrder());

        GLES20.glReadPixels( // I read every pixel just for debugging
                0, 0, view[2], view[3], GLES20.GL_RGBA, 
                GLES20.GL_UNSIGNED_BYTE, pixels);

        int e = GLES20.glGetError(); // always returns 0
        byte[] tmp = pixels.array(); // only zeros when called in onTouch

        for (int i = 0; i < mObjects.size(); i++)
            if ((Math.abs(r - mObjects.get(i).CODE_R) < 8) &&
                (Math.abs(g - mObjects.get(i).CODE_G) < 8) &&
                (Math.abs(b - mObjects.get(i).CODE_B) < 8)) {

                result = i;
                break;
            }
    } 

    GLES20.glDeleteRenderbuffers(2, rbo, 0);
    GLES20.glDeleteFramebuffers(1, fbo, 0);
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);

    return result;
}

我已经读到onDrawFrame方法在一个单独的线程中运行,但我不认为这是问题所在,因为我在
RENDERMODE\u DIRTY

为什么不检查这个库呢。我认为它很好,你可以用它来代替创建一个新的颜色选择器


即使在渲染器在不同线程上运行时使用了
RENDERMODE,\u DIRTY
渲染器,在调用
requestRender()
之前,它也不会渲染。您可以尝试使用-方法在渲染线程上运行代码,看看这是否有帮助。
您还可以更改
pick()
-方法,使其在内部使用
Runnable
queueEvent
-方法(或a)。当然,您还需要使用某种回调才能“返回”结果。

好吧,我仍在努力学习OpenGL。因此,我首先想知道一些东西是如何工作的,并自己创建一个基本模型。当我看到这个图书馆时,仍然有很多我从未听说过的东西。所以这对我来说有点过分了^^好东西,我认为你为自己创造它做得很好。无论如何,您可以随时检查此库代码,以备需要。;)
@Override
public void onDrawFrame(GL10 gl) {
    GLES20.glClear(
            GLES20.GL_COLOR_BUFFER_BIT | 
            GLES20.GL_DEPTH_BUFFER_BIT);

    for (int i = 0; i < mObjects.size(); i++)
        mObjects.get(i).render(mProgram, mMatrixMVP, false);
}