/* NIGHTFALL OpenGL Interface */
/* Copyright (C) 2001 Rainer Wichmann & Markus Kuster */
/* */
/* This program is free software; you can redistribute it */
/* and/or modify */
/* it under the terms of the GNU General Public License as */
/* published by */
/* the Free Software Foundation; either version 2 of the License, or */
/* (at your option) any later version. */
/*
*/
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program; if not, write to the Free Software */
/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ANSI C forbids an empty source file, so put this outside */
/* do nothing here if we don't have OpenGL */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Light.h"
#ifdef _WITH_OPENGL
/* CIE Color Matching Functions xb,yb,zb
* conversion table in 5 nm steps from 380 nm to 780 nm */
static double cie_cmf[81][3] = {
{0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201},
{0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102},
{0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456},
{0.2148,0.0073,1.0391}, {0.2839,0.0116,1.3856}, {0.3285,0.0168,1.6230},
{0.3483,0.0230,1.7471}, {0.3481,0.0298,1.7826}, {0.3362,0.0380,1.7721},
{0.3187,0.0480,1.7441}, {0.2908,0.0600,1.6692}, {0.2511,0.0739,1.5281},
{0.1954,0.0910,1.2876}, {0.1421,0.1126,1.0419}, {0.0956,0.1390,0.8130},
{0.0580,0.1693,0.6162}, {0.0320,0.2080,0.4652}, {0.0147,0.2586,0.3533},
{0.0049,0.3230,0.2720}, {0.0024,0.4073,0.2123}, {0.0093,0.5030,0.1582},
{0.0291,0.6082,0.1117}, {0.0633,0.7100,0.0782}, {0.1096,0.7932,0.0573},
{0.1655,0.8620,0.0422}, {0.2257,0.9149,0.0298}, {0.2904,0.9540,0.0203},
{0.3597,0.9803,0.0134}, {0.4334,0.9950,0.0087}, {0.5121,1.0000,0.0057},
{0.5945,0.9950,0.0039}, {0.6784,0.9786,0.0027}, {0.7621,0.9520,0.0021},
{0.8425,0.9154,0.0018}, {0.9163,0.8700,0.0017}, {0.9786,0.8163,0.0014},
{1.0263,0.7570,0.0011}, {1.0567,0.6949,0.0010}, {1.0622,0.6310,0.0008},
{1.0456,0.5668,0.0006}, {1.0026,0.5030,0.0003}, {0.9384,0.4412,0.0002},
{0.8544,0.3810,0.0002}, {0.7514,0.3210,0.0001}, {0.6424,0.2650,0.0000},
{0.5419,0.2170,0.0000}, {0.4479,0.1750,0.0000}, {0.3608,0.1382,0.0000},
{0.2835,0.1070,0.0000}, {0.2187,0.0816,0.0000}, {0.1649,0.0610,0.0000},
{0.1212,0.0446,0.0000}, {0.0874,0.0320,0.0000}, {0.0636,0.0232,0.0000},
{0.0468,0.0170,0.0000}, {0.0329,0.0119,0.0000}, {0.0227,0.0082,0.0000},
{0.0158,0.0057,0.0000}, {0.0114,0.0041,0.0000}, {0.0081,0.0029,0.0000},
{0.0058,0.0021,0.0000}, {0.0041,0.0015,0.0000}, {0.0029,0.0010,0.0000},
{0.0020,0.0007,0.0000}, {0.0014,0.0005,0.0000}, {0.0010,0.0004,0.0000},
{0.0007,0.0002,0.0000}, {0.0005,0.0002,0.0000}, {0.0003,0.0001,0.0000},
{0.0002,0.0001,0.0000}, {0.0002,0.0001,0.0000}, {0.0001,0.0000,0.0000},
{0.0001,0.0000,0.0000}, {0.0001,0.0000,0.0000}, {0.0000,0.0000,0.0000}
};
/****************************************************************************
@package nightfall
@author Markus Kuster (kuster@astro.uni-tuebingen.de)
@version 0.6
@short Calculate relative color cromaticities x,y,z
based on CIE color matching functions for a given Black
Body temperature
@param (double) temperature Black Body temperature
(double) *x CIE x value
(double) *y CIE y value
(double) *z CIE z value
@return (void)
@heading Open GL Animation
****************************************************************************/
void GLBBtoxyz(double temperature, double *x, double *y,double *z)
{
register int i;
double lambda, X=0, Y=0, Z=0, norm;
double Flambda;
for (i=0, lambda=380.0; lambda<=780.0; i++,lambda+=5) {
/* get black body flux for a given temperature and wave length */
Flambda = GLbbflux(lambda, temperature);
/* intergrate cie_cmf contributions over all lambda */
X += Flambda*cie_cmf[i][0];
Y += Flambda*cie_cmf[i][1];
Z += Flambda*cie_cmf[i][2];
/* normalize XYZ values, to get relative cromaticities */
/* we do not need absolute values here */
norm = X+Y+Z;
*x = X/norm;
*y = Y/norm;
*z = Z/norm;
}
}
/****************************************************************************
@package nightfall
@author Markus Kuster (kuster@astro.uni-tuebingen.de)
@version 0.6
@short Transform CIE x,y,z to RGB
@param (double) x CIE x value
(double) y CIE y value
(double) z CIE z value
(double) *R RGB R value
(double) *G RGB G value
(double) *B RGB B value
@return (void)
@heading Open GL Animation
****************************************************************************/
void GLxyztoRGB(struct GLColorSystem *csyst, double x, double y,double z,
double *R, double *G, double *B)
{
double denom;
double zr, zg, zb;
zr = 1.0 - (csyst->xr + csyst->yr);
zg = 1.0 - (csyst->xg + csyst->yg);
zb = 1.0 - (csyst->xb + csyst->yb);
denom = (csyst->xr*csyst->yg - csyst->xg*csyst->yr) * zb
+ (csyst->xb*csyst->yr - csyst->xr*csyst->yb) * zg
+ (csyst->xg*csyst->yb - csyst->xb*csyst->yg) * zr;
/* Get R, G, B values depending on color system we use */
*R = ( (x * csyst->yg - csyst->xg * y ) * zb +
(csyst->xg * csyst->yb - csyst->xb * csyst->yg) * z +
(csyst->xb * y - x * csyst->yb) * zg ) / denom;
*G = ( (y * csyst->xr - csyst->yr * x ) * zb +
(csyst->xb * csyst->yr - csyst->xr * csyst->yb) * z +
(csyst->yb * x - y * csyst->xb) * zr ) / denom;
*B = ( (csyst->xr * csyst->yg - csyst->xg * csyst->yr) * z +
(x * csyst->yr - csyst->xr * y ) * zg +
(csyst->xg * y - x * csyst->yg) * zr ) / denom;
if (*R < 0.0) *R = 0.0;
if (*R > 1.0) *R = 1.0;
if (*G < 0.0) *G = 0.0;
if (*G > 1.0) *G = 1.0;
if (*B < 0.0) *B = 0.0;
if (*B > 1.0) *B = 1.0;
}
/****************************************************************************
@package nightfall
@author Markus Kuster (kuster@astro.uni-tuebingen.de)
@version 1.0
@short Calculate flux from a black body spectal distribution
@param (double) lambda wavelength in meters
(double) temp temperature in K
@return (void)
@heading Open GL Animation
****************************************************************************/
double GLbbflux(double lambda, double temp)
{
double flux;
lambda = lambda * 1e-9; /* convert from nm to meters */
flux = (3.74183e-16 * pow(lambda, -5.0)) / ( exp(1.4388e-2 / (lambda * temp)) - 1.0 );
return(flux);
}
#endif /* OpenGL end */
syntax highlighted by Code2HTML, v. 0.9.1