[BACK]Return to env.c CVS log [TXT][DIR] Up to [Development] / performer / src / sample / C / common

File: [Development] / performer / src / sample / C / common / env.c (download)

Revision 1.1, Tue Nov 21 21:39:43 2000 UTC (16 years, 11 months ago) by flynnt
Branch: MAIN
CVS Tags: HEAD

Initial check-in based on OpenGL Performer 2.4 tree.
-flynnt

/*
 * Copyright 1993, 1995, Silicon Graphics, Inc.
 * ALL RIGHTS RESERVED
 *
 * This source code ("Source Code") was originally derived from a
 * code base owned by Silicon Graphics, Inc. ("SGI")
 * 
 * LICENSE: SGI grants the user ("Licensee") permission to reproduce,
 * distribute, and create derivative works from this Source Code,
 * provided that: (1) the user reproduces this entire notice within
 * both source and binary format redistributions and any accompanying
 * materials such as documentation in printed or electronic format;
 * (2) the Source Code is not to be used, or ported or modified for
 * use, except in conjunction with OpenGL Performer; and (3) the
 * names of Silicon Graphics, Inc.  and SGI may not be used in any
 * advertising or publicity relating to the Source Code without the
 * prior written permission of SGI.  No further license or permission
 * may be inferred or deemed or construed to exist with regard to the
 * Source Code or the code base of which it forms a part. All rights
 * not expressly granted are reserved.
 * 
 * This Source Code is provided to Licensee AS IS, without any
 * warranty of any kind, either express, implied, or statutory,
 * including, but not limited to, any warranty that the Source Code
 * will conform to specifications, any implied warranties of
 * merchantability, fitness for a particular purpose, and freedom
 * from infringement, and any warranty that the documentation will
 * conform to the program, or any warranty that the Source Code will
 * be error free.
 * 
 * IN NO EVENT WILL SGI BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT
 * LIMITED TO DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES,
 * ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THE
 * SOURCE CODE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT OR
 * OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM,
 * OR AROSE OUT OF USE OR RESULTS FROM USE OF, OR LACK OF ABILITY TO
 * USE, THE SOURCE CODE.
 * 
 * Contact information:  Silicon Graphics, Inc., 
 * 1600 Amphitheatre Pkwy, Mountain View, CA  94043, 
 * or:  http://www.sgi.com
 */


/* 
 * env.c	environment functions, ie. weather, time of day, etc
 *
 * $Revision: 1.1 $
 * $Date: 2000/11/21 21:39:43 $
 *
 */

#include <math.h>
#include <Performer/pf.h>
#include <Performer/pfutil.h>

#include "custom.h"

static pfFog	 *eskyFog;
static pfVec3	fogColor;

#define	TOTAL_HORIZ_ANGLE	7.0f

	/*-----------------------------------------------------*/

void
initEnvironment(void)
{
    pfEarthSky 	*es;

    /* Initialize sun */
    ViewState->sun = pfNewLSource();
    ViewState->sunDCS = pfNewDCS();

    /* Point in direction of view for easier LIGHTING_EYE computation */
    pfLSourcePos(ViewState->sun, 0.0f, -1.0f, 0.0f, 0.0f);

    pfAddChild(ViewState->scene, ViewState->sunDCS);
    pfAddChild(ViewState->sunDCS, ViewState->sun);

    es = pfNewESky();
    pfESkyMode(es, PFES_BUFFER_CLEAR, ViewState->earthSkyMode); 
    pfESkyAttr(es, PFES_GRND_HT, -0.5f * ViewState->sceneSize);
    pfESkyColor(es, PFES_CLEAR, 
		    ViewState->earthSkyColor[0],
		    ViewState->earthSkyColor[1],
		    ViewState->earthSkyColor[2],
		    ViewState->earthSkyColor[3]);
    pfESkyAttr(es, PFES_HORIZ_ANGLE, TOTAL_HORIZ_ANGLE);

    /* setup the fog for general visibility */
    eskyFog = pfNewFog(pfGetSharedArena());
    pfSetVec3(fogColor, .6f, .6f, .6f);

    if(ViewState->fog != PFFOG_OFF)
    {
	pfFogType(eskyFog, ViewState->fog);
	pfFogColor(eskyFog, 
		   fogColor[0] * ViewState->timeOfDay, 
		   fogColor[1] * ViewState->timeOfDay, 
		   fogColor[2] * ViewState->timeOfDay); 
	pfFogRange(eskyFog, ViewState->nearFogRange, ViewState->farFogRange);
    }
    ViewState->eSky = es;
}

void
updateEnvironment(void)
{
    pfEarthSky 		*es = ViewState->eSky;
    static int 	 	earthSkyMode = -1;
    static int 	 	fog = -1;
    static float 	nearFogRange = 0.0f, farFogRange = 0.0f;
    
    if ((earthSkyMode == ViewState->earthSkyMode) && 
	(fog == ViewState->fog) && 
	(nearFogRange == ViewState->nearFogRange) &&
	(farFogRange == ViewState->farFogRange))
	return;
 
    pfESkyMode(es, PFES_BUFFER_CLEAR, ViewState->earthSkyMode); 

    if (ViewState->fog != PFFOG_OFF)
    {
	pfFogType(eskyFog, ViewState->fog);
	pfFogRange(eskyFog, ViewState->nearFogRange, ViewState->farFogRange);
	pfESkyFog(es, PFES_GENERAL, eskyFog);
	pfFogColor(eskyFog, 
		   fogColor[0] * ViewState->timeOfDay, 
		   fogColor[1] * ViewState->timeOfDay, 
		   fogColor[2] * ViewState->timeOfDay); 
	pfESkyColor(es, PFES_CLEAR, 
		    fogColor[0] * ViewState->timeOfDay, 
		    fogColor[1] * ViewState->timeOfDay, 
		    fogColor[2] * ViewState->timeOfDay,
		    ViewState->earthSkyColor[3]);
    }
    else
    {
	pfESkyFog(es, PFES_GENERAL, NULL);
	pfESkyColor(es, PFES_CLEAR, 
		    ViewState->earthSkyColor[0],
		    ViewState->earthSkyColor[1],
		    ViewState->earthSkyColor[2],
		    ViewState->earthSkyColor[3]);
    }

    /* update static values */
    earthSkyMode = ViewState->earthSkyMode;
    fog = ViewState->fog;
    nearFogRange = ViewState->nearFogRange;
    farFogRange = ViewState->farFogRange;
}


void
updateTimeOfDay(float newTod)
{
    float 		r, g, b;
    float 		s;
    pfVec3 		t;
    pfEarthSky		*es;
    static int		lighting = -1;
    static float  	tod = -1.0f;
    static pfVec3	noon = {-.05f, -.1f, 1.0f};
    static pfVec3	night = {-.15f, 1.0f, .2f};
    static pfVec3	prevViewDir;

    /* only do if necessary */
    if (ViewState->lighting == lighting && newTod == tod && 
	(ViewState->lighting == LIGHTING_SUN || 
	 PFEQUAL_VEC3(ViewState->viewMat[1], prevViewDir)))
        return;

    tod = newTod;
    lighting = ViewState->lighting;
    pfCopyVec3(prevViewDir, ViewState->viewMat[1]); 

    es = ViewState->eSky;

    /* make horizon band angle directly proportional to time of day */
    pfESkyAttr(es, PFES_HORIZ_ANGLE, 1.0f + (TOTAL_HORIZ_ANGLE - 1.0f)*tod);

    /* scale it for the following ramp calcs */
    s = tod * 4.0f;	
    
    /* top of sky */
    r = (0.4f * s) - 1.6f;   r = PF_MAX2(0.0f, r);  r = PF_MIN2(0.7f, r);
    g = (0.4f * s) - 1.6f;   g = PF_MAX2(0.0f, g);  g = PF_MIN2(0.7f, g); 
    b = (0.8f * s) - 1.6f;   b = PF_MAX2(0.0f, b);  b = PF_MIN2(1.0f, b);
    pfESkyColor(es, PFES_SKY_TOP, r,g,b, 1.0f);
    
    /* bottom of sky */
    r = (0.6f * s) - 1.6f;   r = PF_MAX2(0.0f, r);  r = PF_MIN2(0.7f, r);
    g = (0.6f * s) - 1.6f;   g = PF_MAX2(0.0f, g);  g = PF_MIN2(0.7f, g); 
    b = (1.0f * s) - 1.6f;   b = PF_MAX2(0.0f, b);  b = PF_MIN2(1.0f, b);
    pfESkyColor(es, PFES_SKY_BOT, r,g,b, 1.0f);
	
    /* horizon */
    r = (1.45f * s) - 0.4f;   r = PF_MAX2(0.0f, r);  r = PF_MIN2(0.7f, r);
    g = (0.65f * s) - 1.4f;   g = PF_MAX2(0.0f, g);  g = PF_MIN2(0.7f, g); 
    b = (0.65f * s) - 1.6f;   b = PF_MAX2(0.0f, b);  b = PF_MIN2(1.0f, b);
    pfESkyColor(es, PFES_HORIZ, r,g,b, 1.0f);
    
    /* ground */
    r = (0.0181f * (s - 0.8f));   r = PF_MAX2(0.0f, r);  r = PF_MIN2(0.058f, r);
    g = (0.0840f * (s - 0.8f));   g = PF_MAX2(0.0f, g);  g = PF_MIN2(0.270f, g); 
    b = (0.0181f * (s - 0.8f));   b = PF_MAX2(0.0f, b);  b = PF_MIN2(0.058f, b); 
    pfESkyColor(es, PFES_GRND_NEAR, r ,g, b, 1.0f);
    pfESkyColor(es, PFES_GRND_FAR,  r ,g, b, 1.0f);

    /* Scale fog color based on time of day */
    if (ViewState->fog != PFFOG_OFF)
    {
	pfFogColor(eskyFog, 
		   fogColor[0] * ViewState->timeOfDay, 
		   fogColor[1] * ViewState->timeOfDay, 
		   fogColor[2] * ViewState->timeOfDay); 
	pfESkyColor(es, PFES_CLEAR, 
		    fogColor[0] * ViewState->timeOfDay, 
		    fogColor[1] * ViewState->timeOfDay, 
		    fogColor[2] * ViewState->timeOfDay,
		    ViewState->earthSkyColor[3]);
    }
    
    /* Here we set the light position. */
    pfCombineVec3(t, tod, noon, 1.0f - tod, night);
    pfNormalizeVec3(t);
    if (ViewState->lighting == LIGHTING_SUN)
    {
	pfMatrix	mat;
	static pfVec3	nyaxis = {0.0f, -1.0f, 0.0f};

	pfMakeVecRotVecMat(mat, nyaxis, t);
    	pfDCSMat(ViewState->sunDCS, mat);
	pfLSourceColor(ViewState->sun, PFLT_AMBIENT,
		       0.8f*tod, 0.8f*tod, 0.8f*tod); 
    }
    else /* LIGHTING_EYE */	
    {
	pfLSourceColor(ViewState->sun, PFLT_AMBIENT, 0.0f, 0.0f, 0.0f);
    	pfDCSMat(ViewState->sunDCS, ViewState->viewMat);
    }

    pfLSourceColor(ViewState->sun, PFLT_DIFFUSE,  
		   0.8f*tod, 0.8f*tod, 0.8f*tod); 
    pfLSourceColor(ViewState->sun, PFLT_SPECULAR, 
		   0.8f*tod, 0.8f*tod, 0.8f*tod); 
}