Я реализовал метод выбора цвета, и он также работает; иногда. Проблема в том, что когда я вызываю свой метод в методе 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
...
Ну, я все еще пытаюсь изучить OpenGL. Поэтому я сначала хочу знать, как что-то работает и создать базовую модель. Когда я смотрю на эту библиотеку, есть еще очень много вещей, о которых я никогда не слышал. Так что это было бы чем-то вроде переполнения для меня ^^ –
Хороший материал, я думаю, вы хорошо себя чувствуете, пытаясь создать его для себя. В любом случае вы всегда можете проверить этот код библиотеки, если вам что-то нужно. ;) – jpardogo