/* Copyright Jeff Lassahn.  See graph3d.tex for details. */#include <stdio.h>#include <stdlib.h>#include <math.h>#include "render.h"#include "liftio.h"typedef struct tagclouds {	float start;	float stop;	PIX_RGB32 fog;	PIX_RGB32 skytop;	PIX_RGB32 skybottom;	//FIXME lighting control} CLOUDS;#define FOG_STRENGTH 0.5#define MIN_VIS 1000.0#define MAX_CLEAR 10000.0#define MAX_VIS 15000.0#define HAZE_DEPTH 5.0void SetFog(PG_ENVIRONMENT *env,CLOUDS *cl,float z,PIX_RGB32 sky[513]){PIX_RGB32 fogcol;PIX_RGB32 top;PIX_RGB32 bottom;int i;float f,depth;	fogcol.red=(env->lights[0].red+env->lights[1].red*env->lights[1].pos.z)*						cl->fog.red;	fogcol.green=(env->lights[0].green+env->lights[1].green*env->lights[1].pos.z)*						cl->fog.green;	fogcol.blue=(env->lights[0].blue+env->lights[1].blue*env->lights[1].pos.z)*						cl->fog.blue;	top.red=env->lights[0].red*cl->skytop.red;	top.green=env->lights[0].green*cl->skytop.green;	top.blue=env->lights[0].blue*cl->skytop.blue;		bottom.red=(env->lights[0].red+env->lights[1].red*2)*						cl->skybottom.red;	bottom.green=(env->lights[0].green+env->lights[1].green*2)*						cl->skybottom.green;	bottom.blue=(env->lights[0].blue+env->lights[1].blue*2)*						cl->skybottom.blue;	if (z<cl->stop) {		depth=(cl->start-cl->stop)*FOG_STRENGTH;	}	else {		depth=(cl->start-z)*FOG_STRENGTH;	}	if (depth<HAZE_DEPTH)		depth=HAZE_DEPTH;	if (env->fog) {		env->fog->col=fogcol;		env->fog->start_dist=HAZE_DEPTH*MAX_CLEAR/depth;		env->fog->stop_dist=MIN_VIS+HAZE_DEPTH*(MAX_VIS-MIN_VIS)/depth;	}	for (i=1;i<257;i++) {		sky[i+256].red=(bottom.red*(256-i)+top.red*(i-1))>>8;		sky[i+256].green=(bottom.green*(256-i)+top.green*(i-1))>>8;		sky[i+256].blue=(bottom.blue*(256-i)+top.blue*(i-1))>>8;		f=depth/i;		if (f>1.0)			f=1.0;		sky[i+256].red=f*fogcol.red+(1.0-f)*sky[i+256].red;		sky[i+256].green=f*fogcol.green+(1.0-f)*sky[i+256].green;		sky[i+256].blue=f*fogcol.blue+(1.0-f)*sky[i+256].blue;	}	for (i=0;i<257;i++) {		sky[i]=fogcol;	}}#define PI 3.1415926#define SECS_PER_DAY (60*60*24)void SetLights(int seconds,PG_LIGHT lights[2]){float ct,st;	ct=-cos(seconds*2.0*PI/SECS_PER_DAY);	st=sin(seconds*2.0*PI/SECS_PER_DAY);	/* ambient light.  brightest at noon */	lights[0].red=0.2+0.3*ct+0.3*ct*ct;	lights[0].green=0.2+0.3*ct+0.3*ct*ct;	lights[0].blue=0.2+0.3*ct+0.3*ct*ct;	/* directed light.  changes direction, intensity, and color as the		day progresses. */	lights[1].pos.x=st;	lights[1].pos.y=0;	/* the new value of st is st^6, which is close to 1 near sunrise and sunset, close to		0 otherwise. */	st=st*st;	st=st*st*st;	if (ct>0.0) { /* if the sun is above the horizon */		lights[1].pos.z=ct;		lights[1].red=0.2+0.4*st;		lights[1].green=0.2+0.1*st;		lights[1].blue=0.2;	}	else {		lights[1].pos.z=-ct;		lights[1].red=0.6*st;		lights[1].green=0.3*st;		lights[1].blue=0.2*st;	}}