Я пытаюсь перенести приложение iPhone на Android, и я застрял, пытаясь заставить мой Framebuffer-код работать. Я обнаружил, что всякий раз, когда я использую FBO 512x512 или 1024x1024 на Android, буфер повреждается, что приводит к рисованию множества артефактов. 256x256 FBO работают нормально.
Я создал небольшой проект, который воспроизводит проблему. Вы можете скачать весь проект repro по этой ссылке , но я также вставил здесь важную часть:
class GLRenderer implements GLSurfaceView.Renderer {
int TextureID;
int FrameBufferID;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//Create texture
int[] buf = new int[1];
gl.glGenTextures(1, buf, 0);
TextureID = buf[0];
gl.glBindTexture(GL11.GL_TEXTURE_2D, TextureID);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
//Render our jpeg into the texture as the background
GLUtils.texImage2D(GL11.GL_TEXTURE_2D, 0, FBOTestActivity.BackgroundBitmap, 0);
GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl;
//Create a framebuffer
gl11ep.glGenFramebuffersOES(1, buf, 0);
FrameBufferID = buf[0];
gl11ep.glBindFramebufferOES(GLES11Ext.GL_FRAMEBUFFER_OES, FrameBufferID);
gl11ep.glFramebufferTexture2DOES(GLES11Ext.GL_FRAMEBUFFER_OES, GLES11Ext.GL_COLOR_ATTACHMENT0_OES, GL11.GL_TEXTURE_2D, TextureID, 0);
//Render a rectangle into the framebuffer
gl.glMatrixMode(GL11.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0, FBOTestActivity.Size, 0, FBOTestActivity.Size, -1, 1);
gl.glMatrixMode(GL11.GL_MODELVIEW);
gl.glViewport(0,0, FBOTestActivity.Size, FBOTestActivity.Size);
gl.glVertexPointer(2, GL11.GL_FLOAT, 0, MakeBuffer(new float[] { 64, 64, 192, 64, 64, 192, 192,192 }));
gl.glEnableClientState(GL11.GL_VERTEX_ARRAY);
gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
//Unbind
gl11ep.glBindFramebufferOES(GLES11Ext.GL_FRAMEBUFFER_OES, 0);
}
public void onSurfaceChanged(GL10 gl, int w, int h) {
gl.glViewport(0, 0, w, h);
}
private FloatBuffer MakeBuffer(float[] arr)
{
ByteBuffer vbb = ByteBuffer.allocateDirect(2 * 4 * 8);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer fb = vbb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
public void onDrawFrame(GL10 gl) {
gl.glMatrixMode(GL11.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(0f, 1.0f, 1f, 0f, -1.0f, 1.0f);
gl.glMatrixMode(GL11.GL_MODELVIEW);
gl.glClearColor(255, 0,0, 255);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//Just render the texture. It should show our background with a white rectangle in front.
gl.glEnableClientState(GL11.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
gl.glEnable(GL11.GL_TEXTURE_2D);
gl.glBindTexture(GL11.GL_TEXTURE_2D, TextureID);
gl.glVertexPointer(2, GL11.GL_FLOAT, 0, MakeBuffer(new float[] { 0, 0, 0, 1, 1, 0, 1, 1 }));
gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, MakeBuffer(new float[] {0, 0, 0, 1, 1, 0, 1, 1}));
gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, 4);
}
}
Если я запускаю это на текстуре 256x256, все хорошо, и я вижу это:
![](https://s3.amazonaws.com/warlightdev/FBOIssue/RightS.png)
Если я запускаю это с текстурой 512x512 (или 1024x1024), я вижу это:
![](https://s3.amazonaws.com/warlightdev/FBOIssue/WrongS.png)
OpenGL не возвращает никаких ошибок, и этот код корректно работает на iPhone. Я пробовал Android 2.1, 2.2 и 2.3, но все они ведут себя одинаково. Я тестирую Nexus One под управлением 2.3.6.
Рендеринг текстуры 512x512 без FBO работает нормально, поэтому проблема связана с FBO. Я застрял на этом некоторое время - я был бы очень признателен за любую помощь!