So I said to myself, what the heck let's try some of that film grain. I am starting by trying to create a generic post process that's non engine based. So it's a direct to graphics draw with no other apis involved. Later I figure i'll do a JPCTFilmGrain version.
Though I could use some help on this.
Heres my FilmGrain code. It can generate a few images of grey scale static. Quality depending on choice. lower the better.
/** FilmGrain
This api is designed to give an old time cinematic feel to images or animated
scenes.
@author Jason T. Jarvis
*/
package sre.gfx;
import java.util.Random;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.*;
import java.awt.image.*;
public class FilmGrain
{
private int _width = 1;
private int _height = 1;
private int _alpha = 50;
private int _quality = 32;
private int _frames = 1;
private int _currentFrame = 0;
private int _duration = 1;
private int _durationCount = 0;
private BufferedImage[] _texture;
public FilmGrain(int width, int height)
{
_width = width;
_height = height;
init();
}
public FilmGrain(int frames, int width, int height)
{
_frames = frames;
_width = width;
_height = height;
init();
}
public void setAlpha(int alpha)
{
if(alpha < 0 || alpha > 255)
alpha = _alpha;
_alpha = alpha;
}
public void setQuality(int quality)
{
if(quality < 1 || quality > 64)
quality = _quality;
_quality = quality;
}
public void setGrainFrames(int frames)
{
if(frames < 1 || frames > 10)
frames = _frames;
_frames = frames;
}
public void setDuration(int duration)
{
if(duration < 1)
duration = _duration;
_duration = duration;
}
public void init()
{
_texture = new BufferedImage[_frames];
for(int i = 0; i < _frames; i++)
{
_texture[i] = new BufferedImage(_width, _height, BufferedImage.TYPE_INT_ARGB);
createGrain(_texture[i]);
}
}
public void apply(Component c)
{
Graphics g = c.getGraphics();
if(_durationCount >= _duration)
{
_currentFrame++;
if(_currentFrame >= _frames)
{
_currentFrame = 0;
}
}
g.drawImage(_texture[_currentFrame], 0, 0, _width, _height, c);
_durationCount++;
}
public void apply(Graphics g, Component c)
{
if(_durationCount >= _duration)
{
_currentFrame++;
if(_currentFrame >= _frames)
{
_currentFrame = 0;
}
}
g.drawImage(_texture[_currentFrame], 0, 0, _width, _height, c);
_durationCount++;
}
private void createGrain(BufferedImage image)
{
int argb = 0x000000;// 0x 00 00 00 00
int r, g, b;
int width = (int)_width / _quality;
int height = (int)_height / _quality;
int size = width * height;
int pixels[] = new int[size];
Random random = new Random();
for(int i = 0, y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
r = random.nextInt(256);
//g = random.nextInt(256);
//b = random.nextInt(256);
argb = ( (_alpha<<24) | (r<<16) | (r<<8) | r );
pixels[i++] = argb;
image.setRGB(x, y, argb);
//System.out.println(argb);
}
}
//image.setRGB(0, 0, _width, _height, pixels, offset, scanline);
}
}
Here is the implementation code
--- initilization
filmgrain = new FilmGrain(800, 600);
filmgrain.setGrainFrames(3);
filmgrain.setDuration(3);
filmgrain.setAlpha(200);
filmgrain.setQuality(32);
filmgrain.init();
--- render loop
dynamicWorld.debugDrawWorld();
filmgrain.apply(buffer.getGraphics(), frame);
buffer.display(frame.getGraphics());
the problem is that I don't see anything. I have increased the alpha by a lot so I know there is some visible blitting happening and it's just not light. but there pretty much nothing. though the fps drops a lot when filmgrain.apply() is used. so the drawing does seem to happen.
am I drawing wrong or something?