我正在尝试将iPhone应用程序移植到Android上,而我却试图让我的Framebuffer代码正常工作。我发现,无论何时我在Android上使用512x512或1024x1024 FBO,缓冲区都会被破坏,从而导致大量工件被绘制。 256x256 FBO工作正常。
我已经建立了一个可以重现问题的小项目。您可以通过this link下载整个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纹理上运行它,一切都很好,我看到了:
如果我使用512x512纹理(或1024x1024)运行它,我会看到:
OpenGL没有返回任何错误,并且此代码在iPhone上正常运行。我尝试过Android 2.1,2.2和2.3,但它们都表现得一样。我在运行2.3.6的Nexus One上进行测试。
在没有FBO的情况下自行渲染512x512纹理可以正常工作,因此问题与FBO有关。我已经坚持了一段时间 - 我非常感谢任何帮助!
答案 0 :(得分:2)
glClear
的开头添加对onSurfaceCreated
的调用,我可以在我的HTC Desire上获得正确的渲染。更奇怪的是,如果仅清除颜色或深度缓冲区似乎并不重要,它甚至在将0作为位掩码时起作用。我猜这只是隐藏了仍然未知的真正原因。