After I found so many great entries were already posted to this month' challenge-installment, I somehow felt like showing what I've got so far. It's not yet where I want it to be and I'll post some updates later on. It'll probably give some ideas and maybe it's interessting to see the progress, too.
After reading this...
You may change your colour pallette throughout the demo as long as you don't display more than 4 at once
...I figured it would be easy to alternate two (or more) different palettes from frame to frame, thus making two different colours at the same pixel-position appear as a new, different colour.
At a decent refresh rate of 100hz I thought this would work pretty well, yielding 4^2 colours. However, practice showed it's not that easy: LCDs don't handle much more than 60hz and don't blur pixels as nicely as CRTs did.
Flipping a pixel's colour between very different colours just results in heavy flickering, so I reduced the theory to a linear 8 colour-gradient with one frame showing the even colours of the gradient, the the next frame showing the odd colours, thus flipping a pixel's colour between two adjacent colours of the 8-colour palette to reduce the flickering.
See picture 1: gradient reduced to colours 1 3 5 7 (upper), reduced to colours 0 2 4 6 (middle), resulting gradient of alternating both (lower).
This still showed lots of flickering on larger single-coloured areas - so I figured I just wouldn't use single-coloured areas and go for wireframes!
So what I do here is drawing a wireframe-grid using anti-aliased lines with some wave-animation (the classic interference thing). Rendering happens in 8bit greyscale internally (see picture 2) and get's dithered (to reduce colour-banding) to 4 of 8 colours every frame using a 4x4 bayer-matrix. bayer has a less "noisy" layout than floyd-steinberg which works somewhat better with such big pixels. The matrix is then 2x2-transposed every frame to hide the dither-layout.
Now 8 colours aren't particularly much, so I chose the darkest colour not to be black and reduced contrast. Originally I planned a palette that gave a green-monitor's feeling, but that turned out to be a bad choice as the human eye is most sensitive on green. So I went for something amber-like instead.
Since the lighting produces some dark areas (larger single-coloured areas, see above) I chose the same darkest colour in both 4-colour-palettes to reduce the flickering here (didn't hurt much).
For the screenshot (picture 3) I blended two adjacent frames 50:50 to simulate the effect.
You can stop the executable at any time (eg by clicking the window-bar) and count the colours: there are four
Here is some pseudo-code for the bayer-dither:
void dither(unsigned int *dst, unsigned char *src, unsigned int *pal, int xres, int yres)
{
// standard bayer dithering matrix:
char bayer[16]=
{ 1, 9, 3,11,
13, 5,15, 7,
4,12, 2,10,
16, 8,14, 6 };
for (int y=0;y<yres;y++)
{
// select the corresponding line of the dither-matrix
char *matrix= bayer + ((y & 3)<<2);
for (int x=0;x<xres;x++)
{
unsigned char value= *src++ >> 2; // no need for the lowest two bits (0..255 -> 0..63)
unsigned char col= value >> 4; // upper two bits define colour (0..3)
unsigned char sub= value & 0xf; // lower four bits are "sub-precision" for matrix-compare
if (sub >= matrix[x & 3]) // use either "col" or "col+1"
col++;
// to avoid an overflow-check here you can simply set pal[4]=pal[3] initially.
*dst++= pal[col]; // store actual colour
}
}
}
the c++ source is available
here and the freebasic source
here.
And here is a youtube link:
[youtube]0WU5yczRQ_o[/youtube]