2013-06-20 3 views
0

Я реализовал метод выбора цвета, и он также работает; иногда. Проблема в том, что когда я вызываю свой метод в методе onSurfaceChanged, он считывает правильные пиксели. Но когда я вызываю свой метод в GLSurfaceView, он возвращает только нули. В моем методе я создаю framebuffer object и присоединяю к нему два renderbuffer objects. Мой рендерер установлен на RENDERMODE_WHEN_DIRTY, а glGetError() возвращает 0. Где именно проблема? Я не уверен, что это мой метод, или я просто не могу сделать это в onTouchevent. Вот исходный код моего метода захватывающего в моем рендер:Выбор цвета на Android в OpenGL ES 2.0

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; 
} 

И так как это может быть Релевентом, вот мой метод:

@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); 
} 

Я прочитал, что метод onDrawFrame работает в отдельном нить, но я не думаю, что это проблема, так как я нахожусь в RENDERMODE_WHEN_DIRTY ...

ответ

0

Почему вы не проверяете эту библиотеку. Я думаю, что это неплохо, вы можете использовать его вместо создания нового набора цветов.

https://github.com/LarsWerkman/HoloColorPicker

+0

Ну, я все еще пытаюсь изучить OpenGL. Поэтому я сначала хочу знать, как что-то работает и создать базовую модель. Когда я смотрю на эту библиотеку, есть еще очень много вещей, о которых я никогда не слышал. Так что это было бы чем-то вроде переполнения для меня ^^ –

+0

Хороший материал, я думаю, вы хорошо себя чувствуете, пытаясь создать его для себя. В любом случае вы всегда можете проверить этот код библиотеки, если вам что-то нужно. ;) – jpardogo

0

Даже если вы используете RENDERMODE_WHEN_DIRTY ваш визуализатор работает в другом потоке, он просто не делает до тех пор пока вы звоните requestRender(). Вы можете попытаться использовать метод queueEvent(), чтобы вместо этого запустить код в потоке визуализации и посмотреть, поможет ли это. Вы также можете изменить свой метод pick() так, чтобы он внутренне использовал Runnable и queueEvent-метод (или Handler). Разумеется, вам также потребуется использовать какой-то обратный вызов, чтобы иметь возможность «вернуть» результат.

 Смежные вопросы

  • Нет связанных вопросов^_^