Here's a screenshot:

compared to the previous images, also with γ=.2 the improvement is pretty evident.

Who said lights are just white? Introducing an almost coherent red light.
Here we go! Accumulation buffers allowed an easy drawing of multiple light sources and relative shadows.
for (;;) {
glClear (GL_COLOR_BUFFER_BIT | GL_ACCUM_BUFFER_BIT)
const range = 10
for i=1 to range do {
render(i);
glAccum(GL_ACCUM, 1.0f/range)
}
glAccum(GL_RETURN, 1)
swapBuffers
}
As the engine grows up, I refactor some routine. Cleaner code allows me to use some higher level function, like a 3Ds objects loader. And here appears a well-know issue: z-fighting.Even on a surface closest to the light source, you will always discover minor differences in the values associated with the R texture coordinate(...). This can result in "surface acne"(...). You can mitigate this problem by applying a depth offset when rendering in the shadow map:That balance is not so easy to achieve; as Nvidia says in its papers, it's really matter of art.
...
glEnable (GL_POLYGON_OFFSET_FILL);
glPolygonOffset (factor, 0.0f);
...
(...)A balance need to be struck when it comes to polygon offset usage.
from OpenGL superbible 4th edition by Richard Wright (Wesley).


function lookupStuff(flag) {
if (flag) {
do_things();
} else {
clearTimeout(timerid);
timerid = setTimeout("lookupStuff(true)", 1000);
}
}
This simple function returns a pointer to an handful 4x4 array of floats, without memory flaws. Maybe this snippet will be helpful for someone in the future.
float* matrixProduct(float* A, float* B) {
// we have to allocate space for a 4x4 floats matrix
float* pointer= (float *) calloc(sizeof(float), 16);
// in order to compute the resulting matrix, we have to use two nested fors
for (int r=0; r<4; r++) {
for (int c=0; c<4; c++) {
// actual multiplications
for (int i=0; i<4; i++) {
pointer[r*4+c] = pointer[r*4+c] + A[r*4+i]*B[c+i*4];
}
}
}
return pointer;
}
