For a simple and quite nice motion blur, I’d go with a following class, for instance (requires GL_TEXTURE_RECTANGLE_EXT):
public class MotionBlurPostFilter
{
private int textureHandle;
private int width;
private int height;
private float alpha;
private float zoom;
private int frameCount;
public MotionBlurPostFilter(int width, int height, float alpha, float zoom, GL gl)
{
this.width = width;
this.height = height;
this.alpha = alpha;
this.zoom = zoom;
setupTexture(gl);
}
public void apply(GL gl)
{
gl.glEnable(GL.GL_TEXTURE_RECTANGLE_EXT);
gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_EXT, textureHandle);
if (frameCount++ > 0)
{
gl.glDisable(GL.GL_LIGHTING);
gl.glDisable(GL.GL_DEPTH_TEST);
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
gl.glColor4f(0, 0, 0, alpha);
viewOrtho(gl);
gl.glBegin(GL.GL_QUADS);
{
gl.glTexCoord2f(width, 0);
gl.glVertex2f(-zoom, -zoom);
gl.glTexCoord2f(width, height);
gl.glVertex2f(-zoom, 1.0f + zoom);
gl.glTexCoord2f(0, height);
gl.glVertex2f(1.0f + zoom, 1.0f + zoom);
gl.glTexCoord2f(0, 0);
gl.glVertex2f(1.0f + zoom, -zoom);
}
gl.glEnd();
viewPerspective(gl);
gl.glEnable(GL.GL_DEPTH_TEST);
}
gl.glCopyTexSubImage2D(GL.GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, 0, 0, width, height);
gl.glDisable(GL.GL_TEXTURE_RECTANGLE_EXT);
}
private void setupTexture(GL gl)
{
int[] textureHandles = new int[1];
gl.glGenTextures(1, textureHandles);
textureHandle = textureHandles[0];
int textureData[] = new int[width * height * 3];
gl.glEnable(GL.GL_TEXTURE_RECTANGLE_EXT);
gl.glBindTexture(GL.GL_TEXTURE_RECTANGLE_EXT, textureHandle);
gl.glTexImage2D(GL.GL_TEXTURE_RECTANGLE_EXT, 0, 3, width, height, 0, GL.GL_RGB, GL.GL_UNSIGNED_INT, textureData);
gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_EXT, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_RECTANGLE_EXT, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glDisable(GL.GL_TEXTURE_RECTANGLE_EXT);
}
void viewOrtho(GL gl)
{
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glOrtho(1, 0, 0, 1, -1, 1000000);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPushMatrix();
gl.glLoadIdentity();
}
void viewPerspective(GL gl)
{
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPopMatrix();
}
}
Usage example:
// Creation
mb = new MotionBlurPostFilter(screen.getWidth(), screen.getHeight(), 0.7f, 0, gl);
// While in rendering loop:
while(!exited)
{
// Render scene
scene.render();
// Apply motion blur
mb.apply(gl);
}
…And yeah, I know it’s not optimized or anything. This was originally written for JOGL, thus the GL instance :). Hope you got something out of this fuzzy (written in less than a minute ;)) description.
Cheers