Reputation: 3389
I am trying to implement a motion blur effect in my android game.
After a lot of research I found that the best way to do that is to save the previous frame as a texture using the Frame Buffer Object and render it on top of the current frame. So seeing some nice tutorials on how to do something like that I ended up with this code which basically **render my scene on the texture and then draws the texture to the default framebuffer.
It only draw's a white texture** with a 1286 (Invalid framebuffer operation) error in gl.glGetError()
SOLVED:The problem seems to be the non power of two texture dimmensions as Jean said
int[] fb, depthRb, renderTex;
int texW = 480 * 2;
int texH = 800 * 2;
IntBuffer texBuffer;
int[] buf = new int[texW * texH];
GL11ExtensionPack gl11ep ;
void setup(GL10 gl)
{
gl11ep=(GL11ExtensionPack)gl;
fb = new int[1];
depthRb = new int[1];
renderTex = new int[1];
gl11ep.glGenFramebuffersOES(1, fb, 0);
gl11ep.glGenRenderbuffersOES(1, depthRb, 0); // the depth buffer
gl.glGenTextures(1, renderTex, 0);// generate texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);
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);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
texBuffer = ByteBuffer.allocateDirect(buf.length*4).order(ByteOrder.nativeOrder()).asIntBuffer();
gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGB, texW, texH, 0, GL10.GL_RGB, GL10.GL_UNSIGNED_SHORT_5_6_5, texBuffer);
gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRb[0]);
gl11ep.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, GL11ExtensionPack.GL_DEPTH_COMPONENT16, texW, texH);
}
boolean RenderStart(GL10 gl)
{
// Bind the framebuffer
gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, fb[0]);
// specify texture as color attachment
gl11ep.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D, renderTex[0], 0);
// attach render buffer as depth buffer
gl11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES, GL11ExtensionPack.GL_RENDERBUFFER_OES, depthRb[0]);
int error = gl.glGetError();
if (error != GL10.GL_NO_ERROR) {
Tools.con("Background Load GLError: " + error) ;//here the 1286 error
}
int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES)//here always geting true
{
return false;
}
return true;
}
void RenderEnd(GL10 gl)
{
gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
gl.glClearColor(0f, 0f, 0f, 1.0f);
gl.glClear( gl.GL_DEPTH_BUFFER_BIT | gl.GL_COLOR_BUFFER_BIT);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, renderTex[0]);
gl.glColor4f(1,1,1,1);
((GL11Ext) gl).glDrawTexfOES(0, 0, 0,800, 480);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
public void onDrawFrame(GL10 gl)
{
this.RenderStart(gl);
render(gl);//render scene
this.RenderEnd(gl);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
...
setup(gl);
}
Upvotes: 3
Views: 8057
Reputation: 36
Probably you should make your texture have a power of 2 as height and width (i.e. 512x512, or even less since it's only for a blur effect). Almost every device with hardware acceleration needs that. Quick way to test this is to run it into the emulator (being software only it should work if it supports every other feature you need in your code)
Upvotes: 2