Index: trunk/src/lib/graphics/effects/cloud_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/cloud_effect.cc	(revision 8228)
+++ trunk/src/lib/graphics/effects/cloud_effect.cc	(revision 8255)
@@ -11,4 +11,6 @@
 ### File Specific:
 	main-programmer: hdavid, amaechler
+
+	INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader
 */
 
@@ -17,12 +19,22 @@
 #include "util/loading/load_param.h"
 #include "util/loading/factory.h"
+#include "util/loading/resource_manager.h"
 
 #include "glincl.h"
-//#include "graphics_engine.h"
+#include "material.h"
 #include <math.h>
+#include "state.h"
+#include "p_node.h"
+#include "shader.h"
+#include "shell_command.h"
 
 #include "parser/tinyxml/tinyxml.h"
 
+#include "sglmodel.h"
+
 using namespace std;
+
+SHELL_COMMAND(activate, CloudEffect, activateCloud);
+SHELL_COMMAND(deactivate, CloudEffect, deactivateCloud);
 
 CREATE_FACTORY(CloudEffect, CL_CLOUD_EFFECT);
@@ -37,5 +49,6 @@
 		this->loadParams(root);
 
-	this->activate();
+	if(cloudActivate)
+		this->activate();
 }
 
@@ -43,5 +56,47 @@
 {
 	this->deactivate();
-}
+
+	delete this->cloudMaterial;
+
+	cloudModel.Delete();
+	Shader::unload(this->cloudShader);
+
+}
+
+
+bool CloudEffect::init()
+{
+	PRINTF(1)("Initializing CloudEffect\n");
+
+	// Default values
+	this->cloudActivate = false;
+	this->cloudTint[4] = ( 0.9f, 0.7f, 0.7f, 1.0f );
+	this->cloudScroll = 1.0f;
+	this->time = 0.0f;
+	//g_cloud_texture = 0;
+
+	this->cloudTexture = "pictures/sky/cloud1.jpg";
+
+	cloudModel.Load("sky.sgl");
+	cloudModel.Unitize();
+
+	// Get the bounding box of the sky dome
+	float bbox[3] = {0};
+	cloudModel.GetDimensions(bbox[0], bbox[1], bbox[2]);
+	
+	// Load Shaders
+	this->cloudShader = new Shader( ResourceManager::getInstance()->getDataDir() + "/shaders/sky.vert", ResourceManager::getInstance()->getDataDir() +"/shaders/sky.frag");
+
+	// Tell the shader the bounding box of the sky dome
+	this->cloudShader->bindShader("bbox", bbox, 4);
+
+	// Initialze Cloud Material
+	this->cloudMaterial = new Material("Sky");
+	this->cloudMaterial->setIllum(3);
+	this->cloudMaterial->setAmbient(1.0, 1.0, 1.0);
+	this->cloudMaterial->setDiffuseMap(this->cloudTexture);
+
+}
+
 
 void CloudEffect::loadParams(const TiXmlElement* root)
@@ -49,39 +104,21 @@
 	WeatherEffect::loadParams(root);
 
-	LoadParam(root, "animSpeed", this, CloudEffect, setCloudAnimation);
-
-}
-
-
-bool CloudEffect::init()
-{
-	// default values
-	this->cloudAnimTimeStep = 0;
-
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-
-	// Generate noise map a
-	CloudEffect::genNoiseMap(cloudMap32_a);
-	
-	if (this->cloudAnimTimeStep > 0) {
-		// Generate noise map b
-		CloudEffect::genNoiseMap(cloudMap32_b);
+	// LoadParam(root, "speed", this, CloudEffect, setCloudAnimation);
+	// LoadParam(root, "texture", this, CloudEffect, setCloudTexture);
+
+	LOAD_PARAM_START_CYCLE(root, element);
+	{
+		LoadParam_CYCLE(element, "option", this, CloudEffect, setCloudOption);
 	}
-}
+	LOAD_PARAM_END_CYCLE(element);
+}
+
 
 bool CloudEffect::activate()
 {
-	PRINTF(0)( "Activating CloudEffect\n");
-	if (this->cloudAnimTimeStep == 0) {
-		for (int i = 0; i < 32*32; i++)
-			cloudMap32_c[i] = cloudMap32_a[i];
-
-		CloudEffect::overlapOctaves();
-		CloudEffect::expFilter();
-		CloudEffect::genCloudTexture();
-	}
+	PRINTF(0)( "Activating CloudEffect with Material %s\n", this->cloudTexture.c_str());
+
+	this->cloudActivate = true;
+	
 }
 
@@ -89,180 +126,98 @@
 {
 	PRINTF(0)("Deactivating CloudEffect\n");
-}
-
-void CloudEffect::genCloudTexture() {
-	for(int i=0; i<256; i++)
-		for(int j=0; j<256; j++) 
-		{
-			float color = cloudMap256[i*256+j]; 
-			cloudTexture[i][j][0] = (char) color;
-			cloudTexture[i][j][1] = (char) color;
-			cloudTexture[i][j][2] = (char) color;
-		}
-
-	glGenTextures(2, &texID[0]);
-	glBindTexture(GL_TEXTURE_2D, texID[0]);
-	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, cloudTexture);
-}
-
-void CloudEffect::calcAnimMap(float timer) {
-
-	for (int x=0; x<32*32; x++)
-		cloudMap32_c[x] = (cloudMap32_a[x] * ((this->cloudAnimTimeStep - timer) / this->cloudAnimTimeStep)) + (cloudMap32_b[x] * (timer / this->cloudAnimTimeStep));
-
+
+	this->cloudActivate = false;
 }
 
 void CloudEffect::draw() const
 {
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
+	if (!this->cloudActivate)
+		return;
+		
+	// 	glMatrixMode(GL_MODELVIEW);
+	// 	glPushMatrix();
+	//
+	// 	// Move sphere along with the camera
+	// 	Vector r = State::getCameraNode()->getAbsCoor();
+	// 	glTranslatef(r.x, r.y, r.z);
+	//
+	// 	// Sky movement
+	// 	glRotatef(mover, 0, 0, 1);
+	//
+	// 	cloudMaterial->select();
+	// 	gluSphere(this->sphereObj, this->sphereRadius, 20, 20);
+	// 	glPopMatrix();
+
+	// ******
+
+	glMatrixMode(GL_MODELVIEW);
 	glPushMatrix();
-	glEnable(GL_TEXTURE_2D);
-
-	glBindTexture(GL_TEXTURE_2D, texID[0]);
-
-	// FIXME : Bind this to the sky - how do I do this?
-	glBegin(GL_QUADS);
-		glTexCoord2f(0.0f, 0.0f); glVertex3f(20, 20,  60);	// Bottom Left Of The Texture and Quad
-		glTexCoord2f(1.0f, 0.0f); glVertex3f(60, 20,  60);	// Bottom Right Of The Texture and Quad
-		glTexCoord2f(1.0f, 1.0f); glVertex3f(60, 60,  60);	// Top Right Of The Texture and Quad
-		glTexCoord2f(0.0f, 1.0f); glVertex3f(20, 60,  60);	// Top Left Of The Texture and Quad
-	glEnd(); 
+
+	// glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	// glShadeModel(GL_SMOOTH);
+	// glEnable(GL_DEPTH_TEST);
+	// glEnable(GL_CULL_FACE);
+	// glCullFace(GL_BACK);
+	// glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+	
+	// glLineWidth(3.0f);
+
+	static float time = 0.0f;
+	// static vector3f eye = {0.0f, 0.0f, 0.0f}, look = {0.0f, 0.0f, 1.0f}, up = {0.0f, 1.0f, 0.0f};
+
+	// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+	// glLoadIdentity();
+	// gluLookAt(eye[x], eye[y], eye[z], look[x], look[y], look[z], up[x], up[y], up[z]);
+
+	// Turn off the depth buffer when rendering the background
+	// glDisable(GL_DEPTH_TEST);
+
+	this->cloudShader->activateShader();
+
+	/* Select the shader program and update parameters. */
+	/* The "time" parameter controls the cloud scrolling. */
+	this->cloudShader->bindShader("time", &time, 1);
+	/* The "horizon" parameter controls the sky tinting. */
+	this->cloudShader->bindShader("horizon", cloudTint, 4);
+
+	glActiveTexture(GL_TEXTURE0 + 0);
+	glActiveTexture(GL_TEXTURE0 + 1);
+
+	// Load the cloud texture
+	//glBindTexture(GL_TEXTURE_2D, g_cloud_texture);
+	this->cloudMaterial->select();
+
+	// Render the sky dome
+	cloudModel.Render();
+
+	// Unselect the shader
+	Shader::deactivateShader();
+
+	/* Turn on the depth buffer when rendering the foreground. */
+	// glEnable(GL_DEPTH_TEST);
+
+	/* Render the forground, for example, a teapot or bunny. */
+	//    glEnable(GL_LIGHTING);
+	//    glColor3f(0.0f, 1.0f, 0.0f);
+	//    glBegin(GL_QUADS);
+	//    glNormal3f( 0.0f,  1.0f,  0.0f);
+	//    glVertex3f( 20.0f, -1.0f,  20.0f);
+	//    glVertex3f( 20.0f, -1.0f, -20.0f);
+	//    glVertex3f(-20.0f, -1.0f, -20.0f);
+	//    glVertex3f(-20.0f, -1.0f,  20.0f);
+	//    glEnd();
+	//    glDisable(GL_LIGHTING);
 
 	glPopMatrix();
+	
 }
 
 void CloudEffect::tick (float dt)
 {
-	if (this->cloudAnimTimeStep > 0) {
-		if (timer >= this->cloudAnimTimeStep) {
-			timer -= this->cloudAnimTimeStep;
-			for (int i = 0; i < 32*32; i++)
-				cloudMap32_a[i] = cloudMap32_b[i];
-			CloudEffect::genNoiseMap(cloudMap32_b);
-		}
-
-		//map32anim = (map32a * (10 - timer)) + (map32b * timer);
-		CloudEffect::calcAnimMap(timer);
-
-		CloudEffect::overlapOctaves();
-		CloudEffect::expFilter();
-		CloudEffect::genCloudTexture();
-
-		timer += dt;
-	}
-}
-
-/* 
-	Random noise generator
-*/
-float CloudEffect::noise(int x, int y, int random)
-{
-		int n = x + y * 57 + random * 131;
-		n = (n<<13) ^ n;
-		return (1.0f - ( (n * (n * n * 15731 + 789221) +
-						1376312589)&0x7fffffff)* 0.000000000931322574615478515625f);
-}
-
-/*
-	Set noise for the 32*32 noise map:
-*/
-void CloudEffect::genNoiseMap(float  *map)
-{
-	float temp[34][34];
-
-	int random = rand() % 5000;
-
-	for (int y = 1; y < 33; y++)
-		for (int x = 1; x < 33; x++)
-			temp[x][y] = 128.0f + CloudEffect::noise(x,  y,  random) * 128.0f;
-
-	// Seamless cloud
-	for (int x=1; x<33; x++)
-	{
-		temp[0][x] = temp[32][x];
-		temp[33][x] = temp[1][x];
-		temp[x][0] = temp[x][32];
-		temp[x][33] = temp[x][1];
-	}
-	temp[0][0] = temp[32][32];
-	temp[33][33] = temp[1][1];
-	temp[0][33] = temp[32][1];
-	temp[33][0] = temp[1][32];
-
-	// We mirror the side and corner elements so our final cloud will be seamless without any ugly borders showing.
-	for (int y=1; y<33; y++)
-		for (int x=1; x<33; x++)
-		{
-			float center = temp[x][y]/4.0f;
-			float sides = (temp[x+1][y] + temp[x-1][y] + temp[x][y+1] + temp[x][y-1])/8.0f;
-			float corners = (temp[x+1][y+1] + temp[x+1][y-1] + temp[x-1][y+1] + temp[x-1][y-1])/16.0f;
-
-			map[((x-1)*32) + (y-1)] = center + sides + corners;
-		}
-}
-
-/*
-	Interpolation - average the value of each pixel value with that of its neighbors' values.
-*/
-float CloudEffect::interpolate(float x, float y, float  *map)
-{
-	int Xint = (int)x;
-	int Yint = (int)y;
-
-	float Xfrac = x - Xint;
-	float Yfrac = y - Yint;
-
-	int X0 = Xint % 32;
-	int Y0 = Yint % 32;
-	int X1 = (Xint + 1) % 32;
-	int Y1 = (Yint + 1) % 32;
-
-	float bot = map[X0*32 + Y0] + Xfrac * (map[X1*32 + Y0] - map[X0*32 + Y0]);
-	float top = map[X0*32 + Y1] + Xfrac * (map[X1*32 +  Y1] - map[X0*32 + Y1]);
-
-	return (bot + Yfrac * (top - bot));
-}
-
-
-/*
-	Octaves are overlapped together to give cloud more turbulence. We will use four octaves for our cloud.
-*/
-void CloudEffect::overlapOctaves()
-{
-	for (int x=0; x<256*256; x++)
-	{
-		cloudMap256[x] = 0;
-	}
-
-	for (int octave=0; octave<4; octave++)
-		for (int x=0; x<256; x++)
-			for (int y=0; y<256; y++)
-			{
-				float scale = 1 / pow(2.0f, (float) 3-octave);
-				float noise = CloudEffect::interpolate(x*scale, y*scale , cloudMap32_c);
-
-				//The octaves are added together with the proper weight factors.
-				//You could replace pow(2, i) with 1<<i for faster computation
-				cloudMap256[(y*256) + x] += noise / pow(2.0f, (float) octave);
-			}
-}
-
-
-/*
-	Filter the noise with exponential function
-*/
-void CloudEffect::expFilter()
-{
-	float cover = 20.0f;
-	float sharpness = 0.95f;
-
-	for (int x=0; x<256*256; x++)
-	{
-		float c = cloudMap256[x] - (255.0f-cover);
-		if (c<0)     c = 0;
-		cloudMap256[x] = 255.0f - ((float)(pow(sharpness, c))*255.0f);
-	}
-}
-
-
+	if (!this->cloudActivate)
+		return;
+
+	// Update the timer for scrolling the clouds
+	time = time + ((1.0f / 2000.0f) * cloudScroll);
+}
+
Index: trunk/src/lib/graphics/effects/cloud_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/cloud_effect.h	(revision 8228)
+++ trunk/src/lib/graphics/effects/cloud_effect.h	(revision 8255)
@@ -6,11 +6,17 @@
 #define _CLOUD_EFFECT
 
-#include "vector.h"
-#include "vector2D.h"
-
 #include "weather_effect.h"
 
 #include "sound_buffer.h"
 #include "sound_source.h"
+
+#include "world_entity.h"
+#include "glincl.h"
+
+#include "sglmodel.h"
+
+class Shader;
+class Material;
+class Vector;
 
 class CloudEffect : public WeatherEffect
@@ -27,34 +33,31 @@
 		virtual bool deactivate();
 
+		inline void activateCloud() { this->activate(); }
+		inline void deactivateCloud() { this->deactivate(); }
+		
 		virtual void draw() const;
 		virtual void tick(float dt);
 
-		inline void setCloudAnimation(float timestep) { this->cloudAnimTimeStep = timestep; }
+		inline void setCloudOption(const std::string& option) {
+			if (option == "activate") this->cloudActivate = true;
+		}
+
 
 	private:
-		// Basic noise maps 32x32
-		float 														cloudMap32_a[32 * 32];
-		float 														cloudMap32_b[32 * 32];
-		float 														cloudMap32_c[32 * 32];
+		void initialize(char* fileName);
 
-		// The cloud map 256x256
-		float 														cloudMap256[256 * 256];
+		bool				cloudActivate;
 
-		// Temporary array to hold texture RGB values 
-		char 															cloudTexture[256][256][3];
+		Material*			cloudMaterial;		// A Material for the Sphere.
 
-		GLuint 														texID[2];
-		float 														timer;
+		std::string			cloudTexture;
 
-		bool															cloudAnimTimeStep;
+		Sglmodel_sgl			cloudModel;
+		Shader*				cloudShader;
 
-		float 														noise(int x, int y, int random);
-		float 														interpolate(float x, float y, float  *map);
-		void  														overlapOctaves();
-		void  														expFilter();
+		GLfloat				cloudTint[4];
+		GLfloat				cloudScroll;
 
-		void  														genNoiseMap(float  *map);
-		void  														genCloudTexture();
-		void  														calcAnimMap(float timer);
+		float				time;
 
 };
Index: trunk/src/lib/graphics/effects/fog_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/fog_effect.cc	(revision 8228)
+++ trunk/src/lib/graphics/effects/fog_effect.cc	(revision 8255)
@@ -20,9 +20,9 @@
 #include "glincl.h"
 
-/*#include "shell_command.h"
-SHELL_COMMAND(activateFog, FogEffect, FogEffect::activate)
-	->setAlias("aFog");
-SHELL_COMMAND(deactivateFog, FogEffect, FogEffect::deactivate)
-	->setAlias("dFog");*/
+#include "shell_command.h"
+
+SHELL_COMMAND(activate, FogEffect, activateFog);
+SHELL_COMMAND(deactivate, FogEffect, deactivateFog);
+SHELL_COMMAND(startfogging, FogEffect, startFogging);
 
 using namespace std;
@@ -39,5 +39,6 @@
 		this->loadParams(root);
 
-	this->activate();
+	if (this->fogActivate)
+		this->activate();
 }
 
@@ -57,4 +58,10 @@
 	LoadParam(root, "range", this, FogEffect, setFogRange);
 	LoadParam(root, "color", this, FogEffect, setFogColor);
+
+	LOAD_PARAM_START_CYCLE(root, element);
+	{
+		LoadParam_CYCLE(element, "option", this, FogEffect, setFogOption);
+	}
+	LOAD_PARAM_END_CYCLE(element);
 }
 
@@ -62,11 +69,15 @@
 {
 	//default values
+	this->fogActivate = false;
+	this->fogFadeDuration = 0;
+	this->localTimer = 0;
+	
 	this->fogMode = GL_EXP2;
 	this->fogDensity = 0.001;
 	this->fogStart = 0;
 	this->fogEnd = 5000;
-  this->colorVector = Vector(0.7, 0.7, 0.7);
+	this->colorVector = Vector(0.7, 0.7, 0.7);
+
 }
-
 
 
@@ -75,16 +86,16 @@
 	PRINTF(0)( "Enabling FogEffect, mode: %i, density: %f, start: %f, end: %f, color %f, %f, %f\n", this->fogMode, this->fogDensity, this->fogStart, this->fogEnd, this->colorVector.x, this->colorVector.y, this->colorVector.z);
 
+	this->fogActivate = true;
+	
+	GLfloat fogColor[4] = { colorVector.x, colorVector.y, colorVector.z, 1.0};
+	glFogi(GL_FOG_MODE, this->fogMode);
+	glFogfv(GL_FOG_COLOR, fogColor);
+	glFogf(GL_FOG_DENSITY, this->fogDensity);
+	glHint(GL_FOG_HINT, GL_DONT_CARE);
+	glFogf(GL_FOG_START, this->fogStart);
+	glFogf(GL_FOG_END, this->fogEnd);
+	
 	glEnable(GL_FOG);
-	{
-		GLfloat fogColor[4] = { colorVector.x, colorVector.y, colorVector.z, 1.0};
-
-		glFogi(GL_FOG_MODE, this->fogMode);
-		glFogfv(GL_FOG_COLOR, fogColor);
-		glFogf(GL_FOG_DENSITY, this->fogDensity);
-		glHint(GL_FOG_HINT, GL_DONT_CARE);
-		glFogf(GL_FOG_START, this->fogStart);
-		glFogf(GL_FOG_END, this->fogEnd);
-	}
-	glClearColor(0.5, 0.5, 0.5, 1.0);
+	// glClearColor(0.5, 0.5, 0.5, 1.0);
 }
 
@@ -93,5 +104,40 @@
 {
 	PRINTF(0)("Deactivating FogEffect\n");
+
+	this->fogActivate = false;
+	
 	glDisable(GL_FOG);
+}
+
+void FogEffect::draw() const {
+
+	if (this->fogFadeDuration != 0 && this->localTimer < this->fogFadeDuration)
+		glFogf(GL_FOG_DENSITY, this->fogFadeDensity);
+	//else
+	//	glFogf(GL_FOG_DENSITY, this->fogDensity);
+
+}
+void FogEffect::tick(float dt)
+{
+	if (!this->fogActivate)
+		return;
+		
+
+	if (this->fogFadeDuration != 0 && this->localTimer < this->fogFadeDuration) {
+		this->localTimer += dt;
+		float progress = this->localTimer / this->fogFadeDuration;
+		this->fogFadeDensity = progress * this->fogDensity;
+	}
+}
+
+void FogEffect::startFogging() {
+
+	if (this->fogActivate)
+		this->deactivate();
+
+	this->fogFadeDuration = 10;
+	this->localTimer = 0;
+	this->activate();
+
 }
 
Index: trunk/src/lib/graphics/effects/fog_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/fog_effect.h	(revision 8228)
+++ trunk/src/lib/graphics/effects/fog_effect.h	(revision 8255)
@@ -23,18 +23,32 @@
 		virtual bool deactivate();
 
+		void activateFog() { this->activate(); }
+		void deactivateFog() { this->deactivate(); }
+
+		virtual void draw() const;
+		virtual void tick(float dt);
+
 		inline void setFogMode(const std::string& mode) { this->fogMode = this->stringToFogMode(mode); }
 		inline void setFogDensity(float density) { this->fogDensity = density; }
 		inline void setFogRange(float start, float end) { this->fogStart = start; this->fogEnd = end; }
 		inline void setFogColor(float r, float g, float b) { this->colorVector = Vector(r, g, b); }
+		inline void setFogOption(const std::string& option) { if (option == "activate") this->fogActivate = true; }
+
+		void startFogging();
 
 	private:
 		GLint stringToFogMode(const std::string& mode);
 
-	private:
-		GLint                   fogMode;
-		GLfloat                 fogDensity;
-		GLfloat                 fogStart;
-		GLfloat                 fogEnd;
-		Vector                  colorVector;
+		bool				fogActivate;
+		GLfloat				fogFadeDuration;
+		float				localTimer;
+		
+		GLint				fogMode;
+		GLfloat				fogDensity;
+		GLfloat				fogFadeDensity;
+
+		GLfloat				fogStart;
+		GLfloat				fogEnd;
+		Vector				colorVector;
 };
 
Index: trunk/src/lib/graphics/effects/lightening_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/lightening_effect.cc	(revision 8228)
+++ trunk/src/lib/graphics/effects/lightening_effect.cc	(revision 8255)
@@ -18,9 +18,15 @@
 #include "util/loading/load_param.h"
 #include "util/loading/factory.h"
-#include "render2D/image_plane.h"
+#include "effects/billboard.h"
 
 #include "glincl.h"
 #include "parser/tinyxml/tinyxml.h"
 
+#include "shell_command.h"
+#include "light.h"
+
+SHELL_COMMAND(activate, LighteningEffect, activateLightening);
+SHELL_COMMAND(deactivate, LighteningEffect, deactivateLightening);
+
 using namespace std;
 
@@ -30,12 +36,4 @@
 {
 	this->setClassID(CL_LIGHTENING_EFFECT, "LighteningEffect");
-  
-  
-  lightening = new ImagePlane(NULL);
-  lightening->setTexture("maps/lightning_bolt.png");
-  lightening->setSize(50, 50);
-  lightening->setAbsCoor2D(10,10);
-  lightening->setVisibility(true);
-  
   
 	this->init();
@@ -44,5 +42,6 @@
 		this->loadParams(root);
 
-	this->activate();
+  if(this->lighteningActivate)
+	 this->activate();
 }
 
@@ -50,5 +49,4 @@
 {
 	this->deactivate();
-  delete lightening;
 }
 
@@ -56,4 +54,12 @@
 {
 	WeatherEffect::loadParams(root);
+  
+  LoadParam(root, "coord", this, LighteningEffect, coord);
+  LoadParam(root, "option", this, LighteningEffect, setLighteningOption);
+  LoadParam(root, "frequency", this, LighteningEffect, setFlashFrequency);
+  LoadParam(root, "const-time", this, LighteningEffect, setFlashConstTime);
+  LoadParam(root, "rising-time", this, LighteningEffect, setFlashRisingTime);
+  LoadParam(root, "size", this, LighteningEffect, setFlashSize);
+  LoadParam(root, "seed", this, LighteningEffect, setFlashSeed);
 }
 
@@ -61,5 +67,78 @@
 bool LighteningEffect::init()
 {
-	//Default values
+  lighteningActivate = false;
+  
+  this->time = 0.0;
+  this->flashFrequency = 1.4f;
+  this->flashConstTime = 0.5f;
+  this->flashRisingTime = 0.1f;
+
+  this->width = 400.0f;
+  this->height = 100.0f;
+  this->seedWidth = 50;
+  this->seedHeight = 50;
+  this->bNewCoordinate = false;
+
+  this->seedX = 500.f;
+  this->seedZ = 1000.0f;
+  this->seedTime = 4.0f;
+
+  this->billboard[0] = new Billboard(NULL);
+  this->billboard[0]->setTexture("maps/lightning_bolt1.png");
+  this->billboard[0]->setSize(this->width, this->height);
+  this->billboard[0]->setAbsCoor(3000,850,0);
+  this->billboard[0]->setVisibiliy(false);
+
+  this->billboard[1] = new Billboard(NULL);
+  this->billboard[1]->setTexture("maps/lightning_bolt2.png");
+  this->billboard[1]->setSize(this->width, this->height);
+  this->billboard[1]->setAbsCoor(3000,850,0);
+  this->billboard[1]->setVisibiliy(false);
+
+  this->billboard[2] = new Billboard(NULL);
+  this->billboard[2]->setTexture("maps/lightning_bolt3.png");
+  this->billboard[2]->setSize(this->width, this->height);
+  this->billboard[2]->setAbsCoor(3000,850,0);
+  this->billboard[2]->setVisibiliy(false);
+
+  this->billboard[3] = new Billboard(NULL);
+  this->billboard[3]->setTexture("maps/lightning_bolt4.png");
+  this->billboard[3]->setSize(this->width, this->height);
+  this->billboard[3]->setAbsCoor(0.0f, 50.0f, 0.0f);
+  this->billboard[3]->setVisibiliy(false);
+/*
+  this->soundSource = NULL;
+  this->thunderBuffer = NULL;
+
+  this->soundSource.setSourceNode(this);
+
+  //load sound
+  if (this->thunderBuffer != NULL)
+    ResourceManager::getInstance()->unload(this->thunderBuffer);
+  this->thunderBuffer = (OrxSound::SoundBuffer*)ResourceManager::getInstance()->load("sound/thunder.wav", WAV);*/
+}
+
+void LighteningEffect::coord(float x, float y, float z)
+{
+  this->billboard[0]->setAbsCoor(x, y, z);
+  this->billboard[1]->setAbsCoor(x, y, z);
+  this->billboard[2]->setAbsCoor(x, y, z);
+  this->billboard[3]->setAbsCoor(x, y, z);
+  this->mainPosX = x;
+  this->mainPosY = y;
+  this->mainPosZ = z;
+}
+
+
+void LighteningEffect::setFlashSize(float width, float height, float seedWidth, float seedHeight)
+{
+  this->width = width;
+  this->height = height;
+  this->seedWidth = seedWidth;
+  this->seedHeight = seedHeight;
+  this->billboard[0]->setSize(this->width, this->height);
+  this->billboard[1]->setSize(this->width, this->height);
+  this->billboard[2]->setSize(this->width, this->height);
+  this->billboard[3]->setSize(this->width, this->height);
 }
 
@@ -68,5 +147,6 @@
 {
 	PRINTF(0)( "Activating LighteningEffect\n" );
-
+  this->time = 0;
+  lighteningActivate = true;
 }
 
@@ -75,8 +155,84 @@
 {
 	PRINTF(0)("Deactivating LighteningEffect\n");
+  this->billboard[0]->setVisibiliy(false);
+  this->billboard[1]->setVisibiliy(false);
+  this->billboard[2]->setVisibiliy(false);
+  this->billboard[3]->setVisibiliy(false);
+  lighteningActivate = false;
 }
 
 void LighteningEffect::tick (float dt)
 {
-
-}
+  if(!lighteningActivate)
+    return;
+  
+  this->time += dt;
+
+  /*if( flashLight != NULL)
+  {
+    if((int)(100*time)%2)
+      this->flashLight->setDiffuseColor(0,0,0);
+    else
+      this->flashLight->setDiffuseColor(100,100,100);
+    
+    //PRINTF(0)("100*time: %f %i\n", 100*time, (int)(100*time));
+}*/
+  
+  if( this->time > this->flashFrequency)
+  {
+    this->billboard[0]->setVisibiliy(true);
+    this->time = 0.0f;
+    
+    this->flashLight = new Light();
+    this->flashLight->setAbsCoor(this->billboard[0]->getAbsCoor().x, this->billboard[0]->getAbsCoor().y, this->billboard[0]->getAbsCoor().z);
+    this->flashLight->setDiffuseColor(100,100,100);
+    
+    //this->soundSource.play(this->thunderBuffer);
+  }
+  else if( this->billboard[3]->isVisible() && this->time > this->flashConstTime)
+  {
+    this->billboard[3]->setVisibiliy(false);
+    this->time = 0.0f;
+    this->bNewCoordinate = true;
+    
+    if(flashLight != NULL)
+    {
+      delete this->flashLight;
+      flashLight = NULL;
+    }
+  }
+
+  if( this->billboard[2]->isVisible() && this->time > this->flashRisingTime)
+  {
+    this->billboard[2]->setVisibiliy(false);
+    this->billboard[3]->setVisibiliy(true);
+    this->flashLight->setDiffuseColor(100,100,100);
+  }
+  else if( this->billboard[1]->isVisible() && this->time > this->flashRisingTime*2/3 )
+  {
+    this->billboard[1]->setVisibiliy(false);
+    this->billboard[2]->setVisibiliy(true);
+    this->flashLight->setDiffuseColor(0,0,0);
+  }
+  else if( this->billboard[0]->isVisible() && this->time > this->flashRisingTime*1/3 )
+  {
+    this->billboard[0]->setVisibiliy(false);
+    this->billboard[1]->setVisibiliy(true);
+    this->flashLight->setDiffuseColor(100,100,100);
+  }
+
+  if( this->bNewCoordinate)
+  {
+    float posX = this->mainPosX - this->seedX * (float)rand()/(float)RAND_MAX;
+    float posZ = this->mainPosZ + this->seedZ * (float)rand()/(float)RAND_MAX;
+    this->billboard[0]->setAbsCoor(posX, this->mainPosY, posZ);
+    this->billboard[1]->setAbsCoor(posX, this->mainPosY, posZ);
+    this->billboard[2]->setAbsCoor(posX, this->mainPosY, posZ);
+    this->billboard[3]->setAbsCoor(posX, this->mainPosY, posZ);
+    this->bNewCoordinate = false;
+  }
+}
+
+void LighteningEffect::draw() const
+{
+}
Index: trunk/src/lib/graphics/effects/lightening_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/lightening_effect.h	(revision 8228)
+++ trunk/src/lib/graphics/effects/lightening_effect.h	(revision 8255)
@@ -15,5 +15,6 @@
 
 
-class ImagePlane;
+class Billboard;
+class Light;
 
 class LighteningEffect : public WeatherEffect
@@ -30,8 +31,52 @@
 		virtual bool deactivate();
 
-		virtual void tick(float dt);
+    virtual void draw() const;
+    virtual void tick(float dt);
+    
+    void coord(float x, float y, float z);
+    void setFlashSize(float width, float height, float seedWidth, float seedHeight);
+    
+    inline void setLighteningOption(const std::string& option) { if (option == "activate") this->lighteningActivate = true;}
+    inline void setFlashFrequency(float flashFrequency) { this->flashFrequency = flashFrequency; }
+    inline void setFlashConstTime(float flashConstTime) { this->flashConstTime = flashConstTime; }
+    inline void setFlashRisingTime(float flashRisingTime) { if(flashRisingTime > this->flashConstTime)
+                                                                                        this->flashRisingTime = this->flashConstTime/2;
+                                                                                      else
+                                                                                        this->flashRisingTime = flashRisingTime; }
+    inline void setFlashSeed(float seedX, float seedZ, float seedTime) { this->seedX = seedX;
+                                                                                                         this->seedZ = seedZ;
+                                                                                                         this->seedTime = seedTime; }
 
+    void activateLightening() { this->activate(); }
+    void deactivateLightening() { this->deactivate(); }
+    
 	private:
-    ImagePlane* lightening;
+    Billboard* billboard[4];
+    bool lighteningActivate;
+
+    float flashFrequency;
+    float flashConstTime;
+    float flashRisingTime;
+
+    float time;
+
+    bool  bNewCoordinate;
+    float width;
+    float height;
+    float seedWidth;
+    float seedHeight;
+
+    float seedX;
+    float seedZ;
+    float seedTime;
+    
+    float mainPosX;
+    float mainPosY;
+    float mainPosZ;
+
+    Light* flashLight;
+    
+    //OrxSound::SoundSource    soundSource;
+    //OrxSound::SoundBuffer*   thunderBuffer;
 
 };
Index: trunk/src/lib/graphics/effects/rain_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/rain_effect.cc	(revision 8228)
+++ trunk/src/lib/graphics/effects/rain_effect.cc	(revision 8255)
@@ -1,14 +1,14 @@
 /*
-   orxonox - the future of 3D-vertical-scrollers
-
-   Copyright (C) 2004 orx
-
-   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, or (at your option)
-   any later version.
+orxonox - the future of 3D-vertical-scrollers
+
+Copyright (C) 2004 orx
+
+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, or (at your option)
+any later version.
 
 ### File Specific:
-   main-programmer: hdavid, amaechler
+main-programmer: hdavid, amaechler
 */
 
@@ -25,4 +25,5 @@
 #include "plane_emitter.h"
 #include "shell_command.h"
+#include "light.h"
 
 #include "parser/tinyxml/tinyxml.h"
@@ -31,7 +32,11 @@
 SHELL_COMMAND(deactivate, RainEffect, deactivateRain);
 
+SHELL_COMMAND(startRaining, RainEffect, startRaining);
+
 using namespace std;
 
 CREATE_FACTORY(RainEffect, CL_RAIN_EFFECT);
+
+// TODO: Dim Light with Rain, Finish preCaching, check out if multiple rain emitters work,  Think about what happens with building poss. to hang movewithcam off, benchmark, possible to activate lightening, turn off visibility when in a building, variable emitter size depending on playable, also rain velocity
 
 RainEffect::RainEffect(const TiXmlElement* root)
@@ -50,5 +55,5 @@
 
 	//load wind sound
-	if (this->rainWindForce > 0) {
+	if (this->rainWindForce != 0) {
 		if (this->windBuffer != NULL)
 			ResourceManager::getInstance()->unload(this->windBuffer);
@@ -56,5 +61,6 @@
 	}
 
-	this->activate();
+	if(rainActivate)
+		this->activate();
 }
 
@@ -80,5 +86,12 @@
 	LoadParam(root, "life", this, RainEffect, setRainLife);
 	LoadParam(root, "wind", this, RainEffect, setRainWind);
-	LoadParam(root, "option", this, RainEffect, setRainOption);
+	LoadParam(root, "startraining", this, RainEffect, setRainStart);
+
+	LOAD_PARAM_START_CYCLE(root, element);
+	{
+		LoadParam_CYCLE(element, "option", this, RainEffect, setRainOption);
+	}
+	LOAD_PARAM_END_CYCLE(element);
+
 }
 
@@ -87,4 +100,6 @@
 {
 	//Default values
+	this->rainActivate = false;
+	this->rainMove = false;
 	this->rainCoord = Vector(500, 500, 500);
 	this->rainSize = Vector2D(1000, 1000);
@@ -94,6 +109,12 @@
 	this->rainMaxParticles = this->rainRate * this->rainLife;
 	this->rainWindForce  = 0;
+	this->rainStartDuration = 0;
+	this->localTimer = 0;
+	this->soundRainVolume = 0.8f;
 
 	this->emitter = new PlaneEmitter(this->rainSize);
+
+	lightMan = LightManager::getInstance();
+	this->rainAmbient = lightMan->getAmbientColor();
 }
 
@@ -104,4 +125,6 @@
 {
 	PRINTF(0)( "Activating RainEffect, coord: %f, %f, %f, size: %f, %f, rate: %f, velocity: %f, moveRain: %s\n", this->rainCoord.x, this->rainCoord.y, this->rainCoord.z, this->rainSize.x, this-> rainSize.y, this->rainRate, this->rainVelocity, this->rainMove ? "true" : "false" );
+
+	this->rainActivate = true;
 
 	if (unlikely(RainEffect::rainParticles == NULL))
@@ -114,7 +137,7 @@
 		RainEffect::rainParticles->setRadius(0.2, 0.02);
 		RainEffect::rainParticles->setRadius(1, 0.01);
-		RainEffect::rainParticles->setColor(0, 0.3, 0.3, 0.5, 0.2); // grey blue 1
-		RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2); // grey blue 2
-		RainEffect::rainParticles->setColor(1, 0.7, 0.7, 0.7, 0.2); // light grey
+		RainEffect::rainParticles->setColor(0, 0.3, 0.3, 0.5, 0.2);	// grey blue 1
+		RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2);	// grey blue 2
+		RainEffect::rainParticles->setColor(1, 0.7, 0.7, 0.7, 0.2);	// light grey
 	}
 
@@ -128,7 +151,8 @@
 	this->emitter->setSpread(this->rainWindForce / 50, 0.2);
 	
-	this->soundSource.loop(this->rainBuffer);
-	if (this->rainWindForce > 0)
-		this->soundSource.loop(this->windBuffer);
+	this->soundSource.loop(this->rainBuffer, this->soundRainVolume);
+	if (this->rainWindForce != 0) this->soundSource.loop(this->windBuffer, 0.1f * this->rainWindForce);
+
+	lightMan->setAmbientColor(.1,.1,.1);
 }
 
@@ -137,25 +161,56 @@
 {
 	PRINTF(0)("Deactivating RainEffect\n");
+	
+	this->rainActivate = false;
 	this->emitter->setSystem(NULL);
 
+	// Stop Sound
 	this->soundSource.stop();
-}
-
-void RainEffect::activateRain()
-{
-	this->activate();
-}
-
-void RainEffect::deactivateRain()
-{
-	this->deactivate();
-}
-
+
+	// Restore Light Ambient
+	lightMan->setAmbientColor(this->rainAmbient, this->rainAmbient, this->rainAmbient);
+}
 
 void RainEffect::tick (float dt)
 {
+	if (!this->rainActivate)
+		return;
+		
 	if (this->rainMove) {
 		this->rainCoord = State::getCameraNode()->getAbsCoor();
 		this->emitter->setRelCoor(this->rainCoord.x , this->rainCoord.y+800, this->rainCoord.z);
 	}
-}
+
+	if (this->rainStartDuration != 0 && this->localTimer < this->rainStartDuration) {
+		this->localTimer += dt;
+		float progress = this->localTimer / this->rainStartDuration;
+
+		// Dim Light
+		lightMan->setAmbientColor(1.1 - progress, 1.1 - progress, 1.1 - progress);
+
+		// use alpha in color to fade in
+		RainEffect::rainParticles->setColor(0,   0.3, 0.3, 0.5, 0.2 * progress); // grey blue 1
+		RainEffect::rainParticles->setColor(0.5, 0.4, 0.4, 0.5, 0.2 * progress); // grey blue 2
+		RainEffect::rainParticles->setColor(1,   0.7, 0.7, 0.7, 0.2 * progress); // light grey
+
+		// increase radius for more "heavy" rain
+		RainEffect::rainParticles->setRadius(0, 0.03 * progress);
+		RainEffect::rainParticles->setRadius(0.2, 0.02 * progress);
+		RainEffect::rainParticles->setRadius(1, 0.01 * progress);
+
+		// increase sound volume
+		// this->soundSource.fadein(this->rainBuffer, 10);
+	}
+	
+}
+
+void RainEffect::startRaining() {
+
+	if (this->rainActivate)
+		this->deactivate();
+
+	this->rainStartDuration = 10;
+	this->localTimer = 0;
+	this->activate();
+
+}
Index: trunk/src/lib/graphics/effects/rain_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/rain_effect.h	(revision 8228)
+++ trunk/src/lib/graphics/effects/rain_effect.h	(revision 8255)
@@ -14,4 +14,5 @@
 class SparkParticles;
 class PlainEmitter;
+class LightManager;
 
 #include "weather_effect.h"
@@ -34,8 +35,9 @@
 		virtual bool deactivate();
 
-		void activateRain();
-		void deactivateRain();
+		virtual void tick(float dt);
 
-		virtual void tick(float dt);
+		inline void activateRain() { this->activate(); }
+		inline void deactivateRain() { this->deactivate(); }
+		void startRaining();
 
 		inline void setRainCoord(float x, float y, float z) { this->rainCoord = Vector(x, y, z); }
@@ -45,25 +47,39 @@
 		inline void setRainLife(float life) { this->rainLife = life; }
 		inline void setRainWind(int force) { this->rainWindForce = force; }
-		inline void setRainOption(const std::string& option) { if (option == "moverain") this->rainMove = true; }
+		inline void setRainStart(float duration) { this->rainStartDuration = duration; }
+
+		inline void setRainOption(const std::string& option) {
+			if (option == "moverain") this->rainMove = true;
+			if (option == "activate") this->rainActivate = true;
+		}
 
 
 	private:
-		static SparkParticles*						rainParticles;
-		ParticleEmitter*									emitter;
+		static SparkParticles*			rainParticles;
+		ParticleEmitter*			emitter;
 
-		Vector														rainCoord;
-		Vector2D													rainSize;
-		GLfloat														rainRate;
-		GLfloat														rainVelocity;
-		GLfloat														rainLife;
-		GLfloat														rainMaxParticles;
-		int																rainWindForce;
-		bool															rainMove;
+		float					localTimer;
+
+		Vector					rainCoord;
+		Vector2D				rainSize;
+		GLfloat					rainRate;
+		GLfloat					rainVelocity;
+		GLfloat					rainLife;
+		GLfloat					rainMaxParticles;
+		int					rainWindForce;
+		GLfloat					rainStartDuration;
+		bool					rainMove;
+		bool					rainActivate;
 
 		OrxSound::SoundSource			soundSource;
 		OrxSound::SoundBuffer*			rainBuffer;
 		OrxSound::SoundBuffer*			windBuffer;
+
+		float					soundRainVolume;
+
+		LightManager*				lightMan;
+		GLfloat					rainAmbient;
+
 };
 
-
 #endif  /* _RAIN_EFFECT */
Index: trunk/src/lib/graphics/effects/sglmodel.h
===================================================================
--- trunk/src/lib/graphics/effects/sglmodel.h	(revision 8255)
+++ trunk/src/lib/graphics/effects/sglmodel.h	(revision 8255)
@@ -0,0 +1,812 @@
+/* File: sglmodel.h; Mode: C++; Tab-width: 3; Author: Simon Flannery;             */
+
+/*
+   The Silicon Graphic Library model format is a light weight, simple and
+   flexible format designed for the Open Graphics Library. The format allows
+   static models to be streamed promptly within the Open Graphics Library
+   framework. This is a high performance implementation and currently only
+   supports the GL_V3F, GL_N3F_V3F, GL_T2F_N3F_V3F vertex formats!
+
+   The binary file format is described:
+      - The number of elements.
+      - The format of the elements (for example GL_V3F), which determines the size of
+        each element.
+      - The mode of the elements (for example GL_TRIANGLES).
+      - The array of data.
+
+   This Implementation is Copyright (c) 2005 Simon Flannery.
+ */
+
+#ifndef SGLMODEL_H
+#define SGLMODEL_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+enum {x, y, z, w};
+
+#pragma pack(push)
+#pragma pack(1)
+
+struct texture
+{
+   float u, v;
+};
+
+struct vertex
+{
+// GL_V3F
+   float m[3];
+
+   float& operator[](int i)
+   { 
+      return m[i];
+   }
+
+   float operator[](int i) const
+   { 
+      return m[i];
+   }
+};
+
+struct color_vertex
+{
+// GL_C4UB_V3F
+   unsigned char r, g, b, a;
+   vertex v;
+};
+
+struct normal_vertex
+{
+// GL_N3F_V3F
+   vertex n;
+   vertex v;
+};
+
+struct texture_vertex
+{
+// GL_T2F_N3F_V3F
+   texture t;
+   vertex n;
+   vertex v;
+};
+
+struct object_vertex
+{
+   vertex  position;
+   vertex  normal;
+   texture texcoord;
+};
+
+#pragma pack(pop)
+
+float my_max(float a, float b)
+{
+   return (a > b) ? a : b;
+}
+
+class Sglmodel
+{
+public:
+   virtual bool Load(char* szFileName) = 0;
+   virtual void GetDimensions(float& width, float& height, float& depth) = 0;
+   virtual void GetCenter(float& cx, float& cy, float& cz) = 0;
+   virtual void Unitize() = 0;
+   virtual void Scale(float scale) = 0;
+   virtual void Translate(float tx, float ty, float tz) = 0;
+
+   virtual void Render() const = 0;
+
+   virtual void Delete() = 0;
+};
+
+class Sglmodel_sgl : public Sglmodel
+{
+public:
+   typedef void (Sglmodel_sgl::*p_Sglmodel_sgl_member)();
+   typedef void (Sglmodel_sgl::*p_Sglmodel_sgl_member_1f)(float);
+   typedef void (Sglmodel_sgl::*p_Sglmodel_sgl_member_3f)(float, float, float);
+   typedef void (Sglmodel_sgl::*p_Sglmodel_sgl_member_3f_reference)(float&, float&, float&);
+   
+   virtual bool Load(char* szFileName);
+   virtual void GetDimensions(float& width, float& height, float& depth);
+   virtual void GetCenter(float& cx, float& cy, float& cz);
+   virtual void Unitize();
+   virtual void Scale(float scale);
+   virtual void Translate(float tx, float ty, float tz);
+
+   virtual void Render() const;
+
+           bool Save(char* szFileName) const;
+   virtual void Delete();
+
+   void SetTexture(unsigned int t) {   id = t; return;   }
+   unsigned int GetTexture() const {   return id;   }
+
+private:
+
+   void GL_V3F_Dimensions(float& width, float& height, float& depth);
+   void GL_N3F_V3F_Dimensions(float& width, float& height, float& depth);
+   void GL_T2F_N3F_V3F_Dimensions(float& width, float& height, float& depth);
+   void GL_V3F_Center(float& cx, float& cy, float& cz);
+   void GL_N3F_V3F_Center(float& cx, float& cy, float& cz);
+   void GL_T2F_N3F_V3F_Center(float& cx, float& cy, float& cz);
+   void GL_V3F_Unitize();
+   void GL_N3F_V3F_Unitize();
+   void GL_T2F_N3F_V3F_Unitize();
+   void GL_V3F_Scale(float scale);
+   void GL_N3F_V3F_Scale(float scale);
+   void GL_T2F_N3F_V3F_Scale(float scale);
+   void GL_V3F_Translate(float tx, float ty, float tz);
+   void GL_N3F_V3F_Translate(float tx, float tt, float tz);
+   void GL_T2F_N3F_V3F_Translate(float tx, float ty, float tz);
+
+   void* data;
+   int format, count, mode;
+   unsigned int id;
+
+   p_Sglmodel_sgl_member_3f_reference pDimensions;
+   p_Sglmodel_sgl_member_3f_reference pCenter;
+   p_Sglmodel_sgl_member pUnitize;
+   p_Sglmodel_sgl_member_1f pScale;
+   p_Sglmodel_sgl_member_3f pTranslate;
+};
+
+bool Sglmodel_sgl::Load(char* szFileName)
+{
+   data = NULL; format = count = mode = 0; id = 0;
+   pDimensions = NULL;
+   pCenter     = NULL;
+   pUnitize    = NULL;
+   pScale      = NULL;
+   pTranslate  = NULL;
+
+   FILE* file = fopen(szFileName, "rb");
+
+   if (file != NULL)
+   {
+      if (fread(&count, sizeof(int), 1, file) > 0 && count > 0)
+      {
+         if (fread(&format, sizeof(int), 1, file) > 0 && format > 0)
+         {
+            if (fread(&mode, sizeof(int), 1, file) > 0 && mode > 0)
+            {
+               size_t size = 0;
+
+               switch (format) /* Setup member function pointers. */
+               {
+               case GL_V3F:
+                  size = sizeof(vertex);
+                  pDimensions = &Sglmodel_sgl::GL_V3F_Dimensions;
+                  pCenter     = &Sglmodel_sgl::GL_V3F_Center;
+                  pScale      = &Sglmodel_sgl::GL_V3F_Scale;
+                  pUnitize    = &Sglmodel_sgl::GL_V3F_Unitize;
+                  pTranslate  = &Sglmodel_sgl::GL_V3F_Translate;
+                  break;
+
+               case GL_N3F_V3F:
+                  size = sizeof(normal_vertex);
+                  pDimensions = &Sglmodel_sgl::GL_N3F_V3F_Dimensions;
+                  pCenter     = &Sglmodel_sgl::GL_N3F_V3F_Center;
+                  pScale      = &Sglmodel_sgl::GL_N3F_V3F_Scale;
+                  pUnitize    = &Sglmodel_sgl::GL_N3F_V3F_Unitize;
+                  pTranslate  = &Sglmodel_sgl::GL_N3F_V3F_Translate;
+                  break;
+
+               case GL_T2F_N3F_V3F:
+                  size = sizeof(texture_vertex);
+                  pDimensions = &Sglmodel_sgl::GL_T2F_N3F_V3F_Dimensions;
+                  pCenter     = &Sglmodel_sgl::GL_T2F_N3F_V3F_Center;
+                  pScale      = &Sglmodel_sgl::GL_T2F_N3F_V3F_Scale;
+                  pUnitize    = &Sglmodel_sgl::GL_T2F_N3F_V3F_Unitize;
+                  pTranslate  = &Sglmodel_sgl::GL_T2F_N3F_V3F_Translate;
+                  break;
+               }
+
+               if (size != 0)
+               {
+                  if ((data = malloc(size * count)) != NULL)
+                  {
+                     if (fread(data, size, count, file) != count)
+                     {
+                        Delete();
+                     }
+                  }
+               }
+            }
+         }
+      }
+
+      fclose(file);
+   }
+
+   return data != NULL;
+}
+
+void Sglmodel_sgl::GetDimensions(float& width, float& height, float& depth)
+{
+   if (pDimensions != NULL)
+   {
+      (this->*pDimensions)(width, height, depth);
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GetCenter(float& cx, float& cy, float& cz)
+{
+   if (pCenter != NULL)
+   {
+      (this->*pCenter)(cx, cy, cz);
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::Unitize()
+{
+   if (pUnitize != NULL)
+   {
+      (this->*pUnitize)();
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::Scale(float scale)
+{
+   if (pScale != NULL)
+   {
+      (this->*pScale)(scale);
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::Translate(float tx, float ty, float tz)
+{
+   if (pTranslate != NULL)
+   {
+      (this->*pTranslate)(tx, ty, tz);
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::Render() const
+{
+   if (data != NULL)
+   {
+      glInterleavedArrays(format, 0, data);
+      glDrawArrays(mode, 0, count);
+   }
+
+   return;
+}
+
+bool Sglmodel_sgl::Save(char* szFileName) const
+{
+   if (data != NULL)
+   {
+      FILE* file = fopen(szFileName, "wb");
+
+      if (file != NULL)
+      {
+         fwrite(&count,  sizeof(int), 1, file);
+         fwrite(&format, sizeof(int), 1, file);
+         fwrite(&mode,   sizeof(int), 1, file);
+
+         size_t size = 0;
+
+         switch (format)
+         {
+         case GL_V3F:
+            size = sizeof(vertex);
+            break;
+
+         case GL_N3F_V3F:
+            size = sizeof(normal_vertex);
+            break;
+
+         case GL_T2F_N3F_V3F:
+            size = sizeof(texture_vertex);
+            break;
+         }
+
+         fwrite(data, size, count, file);
+
+         fclose(file);
+      }
+   }
+
+   return true;
+}
+
+void Sglmodel_sgl::Delete()
+{
+   free(data); data = NULL; format = count = mode = 0; id = 0;
+
+   pDimensions = NULL;
+   pCenter     = NULL;
+   pUnitize    = NULL;
+   pScale      = NULL;
+   pTranslate  = NULL;
+
+   return;
+}
+
+void Sglmodel_sgl::GL_V3F_Dimensions(float& width, float& height, float& depth)
+{
+   width = height = depth = 0.0f;
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      vertex* v = (vertex*) data;
+
+      maxx = minx = v[0][x];
+      maxy = miny = v[0][y];
+      maxz = minz = v[0][z];
+      
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i][x]) {   maxx = v[i][x];   }
+         if (minx > v[i][x]) {   minx = v[i][x];   }
+         if (maxy < v[i][y]) {   maxy = v[i][y];   }
+         if (miny > v[i][y]) {   miny = v[i][y];   }
+         if (maxz < v[i][z]) {   maxz = v[i][z];   }
+         if (minz > v[i][z]) {   minz = v[i][z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      width  = fabs(maxx) + fabs(minx);
+      height = fabs(maxy) + fabs(miny);
+      depth  = fabs(maxz) + fabs(minz);
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_N3F_V3F_Dimensions(float& width, float& height, float& depth)
+{
+   width = height = depth = 0.0f;
+
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      normal_vertex* v = (normal_vertex*) data;
+      
+      maxx = minx = v[0].v[x];
+      maxy = miny = v[0].v[y];
+      maxz = minz = v[0].v[z];
+      
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i].v[x]) {   maxx = v[i].v[x];   }
+         if (minx > v[i].v[x]) {   minx = v[i].v[x];   }
+         if (maxy < v[i].v[y]) {   maxy = v[i].v[y];   }
+         if (miny > v[i].v[y]) {   miny = v[i].v[y];   }
+         if (maxz < v[i].v[z]) {   maxz = v[i].v[z];   }
+         if (minz > v[i].v[z]) {   minz = v[i].v[z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      width  = fabs(maxx) + fabs(minx);
+      height = fabs(maxy) + fabs(miny);
+      depth  = fabs(maxz) + fabs(minz);
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_T2F_N3F_V3F_Dimensions(float& width, float& height, float& depth)
+{
+   width = height = depth = 0.0f;
+
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      texture_vertex* v = (texture_vertex*) data;
+
+      maxx = minx = v[0].v[x];
+      maxy = miny = v[0].v[y];
+      maxz = minz = v[0].v[z];
+
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i].v[x]) {   maxx = v[i].v[x];   }
+         if (minx > v[i].v[x]) {   minx = v[i].v[x];   }
+         if (maxy < v[i].v[y]) {   maxy = v[i].v[y];   }
+         if (miny > v[i].v[y]) {   miny = v[i].v[y];   }
+         if (maxz < v[i].v[z]) {   maxz = v[i].v[z];   }
+         if (minz > v[i].v[z]) {   minz = v[i].v[z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      width  = fabs(maxx) + fabs(minx);
+      height = fabs(maxy) + fabs(miny);
+      depth  = fabs(maxz) + fabs(minz);
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_V3F_Center(float& cx, float& cy, float& cz)
+{
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      vertex* v = (vertex*) data;
+
+      maxx = minx = v[0][x];
+      maxy = miny = v[0][y];
+      maxz = minz = v[0][z];
+      
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i][x]) {   maxx = v[i][x];   }
+         if (minx > v[i][x]) {   minx = v[i][x];   }
+         if (maxy < v[i][y]) {   maxy = v[i][y];   }
+         if (miny > v[i][y]) {   miny = v[i][y];   }
+         if (maxz < v[i][z]) {   maxz = v[i][z];   }
+         if (minz > v[i][z]) {   minz = v[i][z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      float width  = fabs(maxx) + fabs(minx);
+      float height = fabs(maxy) + fabs(miny);
+      float depth  = fabs(maxz) + fabs(minz);
+       
+   /* Calculate center of the model. */
+      cx = (maxx + minx) / 2.0f;
+      cy = (maxy + miny) / 2.0f;
+      cz = (maxz + minz) / 2.0f;
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_N3F_V3F_Center(float& cx, float& cy, float& cz)
+{
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      normal_vertex* v = (normal_vertex*) data;
+
+      maxx = minx = v[0].v[x];
+      maxy = miny = v[0].v[y];
+      maxz = minz = v[0].v[z];
+      
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i].v[x]) {   maxx = v[i].v[x];   }
+         if (minx > v[i].v[x]) {   minx = v[i].v[x];   }
+         if (maxy < v[i].v[y]) {   maxy = v[i].v[y];   }
+         if (miny > v[i].v[y]) {   miny = v[i].v[y];   }
+         if (maxz < v[i].v[z]) {   maxz = v[i].v[z];   }
+         if (minz > v[i].v[z]) {   minz = v[i].v[z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      float width  = fabs(maxx) + fabs(minx);
+      float height = fabs(maxy) + fabs(miny);
+      float depth  = fabs(maxz) + fabs(minz);
+       
+   /* Calculate center of the model. */
+      cx = (maxx + minx) / 2.0f;
+      cy = (maxy + miny) / 2.0f;
+      cz = (maxz + minz) / 2.0f;
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_T2F_N3F_V3F_Center(float& cx, float& cy, float& cz)
+{
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      texture_vertex* v = (texture_vertex*) data;
+
+      maxx = minx = v[0].v[x];
+      maxy = miny = v[0].v[y];
+      maxz = minz = v[0].v[z];
+      
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i].v[x]) {   maxx = v[i].v[x];   }
+         if (minx > v[i].v[x]) {   minx = v[i].v[x];   }
+         if (maxy < v[i].v[y]) {   maxy = v[i].v[y];   }
+         if (miny > v[i].v[y]) {   miny = v[i].v[y];   }
+         if (maxz < v[i].v[z]) {   maxz = v[i].v[z];   }
+         if (minz > v[i].v[z]) {   minz = v[i].v[z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      float width  = fabs(maxx) + fabs(minx);
+      float height = fabs(maxy) + fabs(miny);
+      float depth  = fabs(maxz) + fabs(minz);
+       
+   /* Calculate center of the model. */
+      cx = (maxx + minx) / 2.0f;
+      cy = (maxy + miny) / 2.0f;
+      cz = (maxz + minz) / 2.0f;
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_V3F_Unitize()
+{
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      vertex* v = (vertex*) data;
+
+      maxx = minx = v[0][x];
+      maxy = miny = v[0][y];
+      maxz = minz = v[0][z];
+      
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i][x]) {   maxx = v[i][x];   }
+         if (minx > v[i][x]) {   minx = v[i][x];   }
+         if (maxy < v[i][y]) {   maxy = v[i][y];   }
+         if (miny > v[i][y]) {   miny = v[i][y];   }
+         if (maxz < v[i][z]) {   maxz = v[i][z];   }
+         if (minz > v[i][z]) {   minz = v[i][z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      float width  = fabs(maxx) + fabs(minx);
+      float height = fabs(maxy) + fabs(miny);
+      float depth  = fabs(maxz) + fabs(minz);
+       
+   /* Calculate center of the model. */
+      float cx = (maxx + minx) / 2.0f;
+      float cy = (maxy + miny) / 2.0f;
+      float cz = (maxz + minz) / 2.0f;
+
+   /* Calculate unitizing scale factor. */
+      float scale = 2.0f / my_max(my_max(width, height), depth);
+
+   /* Translate around center then scale. */
+      v = (vertex*) data;
+      
+      for (int i = 0; i < count; ++i)
+      {
+         v[i][x] -= cx;
+         v[i][y] -= cy;
+         v[i][z] -= cz;
+         v[i][x] *= scale;
+         v[i][y] *= scale;
+         v[i][z] *= scale;
+      }
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_N3F_V3F_Unitize()
+{
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      normal_vertex* v = (normal_vertex*) data;
+      
+      maxx = minx = v[0].v[x];
+      maxy = miny = v[0].v[y];
+      maxz = minz = v[0].v[z];
+      
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i].v[x]) {   maxx = v[i].v[x];   }
+         if (minx > v[i].v[x]) {   minx = v[i].v[x];   }
+         if (maxy < v[i].v[y]) {   maxy = v[i].v[y];   }
+         if (miny > v[i].v[y]) {   miny = v[i].v[y];   }
+         if (maxz < v[i].v[z]) {   maxz = v[i].v[z];   }
+         if (minz > v[i].v[z]) {   minz = v[i].v[z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      float width  = fabs(maxx) + fabs(minx);
+      float height = fabs(maxy) + fabs(miny);
+      float depth  = fabs(maxz) + fabs(minz);
+       
+   /* Calculate center of the model. */
+      float cx = (maxx + minx) / 2.0f;
+      float cy = (maxy + miny) / 2.0f;
+      float cz = (maxz + minz) / 2.0f;
+
+   /* Calculate unitizing scale factor. */
+      float scale = 2.0f / my_max(my_max(width, height), depth);
+
+   /* Translate around center then scale. */
+      v = (normal_vertex*) data;
+      
+      for (int i = 0; i < count; ++i)
+      {
+         v[i].v[x] -= cx;
+         v[i].v[y] -= cy;
+         v[i].v[z] -= cz;
+         v[i].v[x] *= scale;
+         v[i].v[y] *= scale;
+         v[i].v[z] *= scale;
+      }
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_T2F_N3F_V3F_Unitize()
+{
+   float maxx = 0.0f, minx = 0.0f, maxy = 0.0f, miny = 0.0f, maxz = 0.0f, minz = 0.0f;
+
+   if (data != NULL)
+   {
+   /* Get the maximum and minimum. */
+      texture_vertex* v = (texture_vertex*) data;
+
+      maxx = minx = v[0].v[x];
+      maxy = miny = v[0].v[y];
+      maxz = minz = v[0].v[z];
+
+      for (int i = 0; i < count; ++i)
+      {
+         if (maxx < v[i].v[x]) {   maxx = v[i].v[x];   }
+         if (minx > v[i].v[x]) {   minx = v[i].v[x];   }
+         if (maxy < v[i].v[y]) {   maxy = v[i].v[y];   }
+         if (miny > v[i].v[y]) {   miny = v[i].v[y];   }
+         if (maxz < v[i].v[z]) {   maxz = v[i].v[z];   }
+         if (minz > v[i].v[z]) {   minz = v[i].v[z];   }
+      }
+
+   /* Calculate model width, height, and depth. */
+      float width  = fabs(maxx) + fabs(minx);
+      float height = fabs(maxy) + fabs(miny);
+      float depth  = fabs(maxz) + fabs(minz);
+       
+   /* Calculate center of the model. */
+      float cx = (maxx + minx) / 2.0f;
+      float cy = (maxy + miny) / 2.0f;
+      float cz = (maxz + minz) / 2.0f;
+
+   /* Calculate unitizing scale factor. */
+      float scale = 2.0f / my_max(my_max(width, height), depth);
+
+   /* Translate around center then scale. */
+      v = (texture_vertex*) data;
+      
+      for (int i = 0; i < count; ++i)
+      {
+         v[i].v[x] -= cx;
+         v[i].v[y] -= cy;
+         v[i].v[z] -= cz;
+         v[i].v[x] *= scale;
+         v[i].v[y] *= scale;
+         v[i].v[z] *= scale;
+      }
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_V3F_Scale(float scale)
+{
+   if (data != NULL)
+   {
+      vertex* v = (vertex*) data;
+      
+      for (int i = 0; i < count; ++i)
+      {
+         v[i][x] *= scale;
+         v[i][y] *= scale;
+         v[i][z] *= scale;
+      }
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_N3F_V3F_Scale(float scale)
+{
+   if (data != NULL)
+   {
+      normal_vertex* v = (normal_vertex*) data;
+      
+      for (int i = 0; i < count; ++i)
+      {
+         v[i].v[x] *= scale;
+         v[i].v[y] *= scale;
+         v[i].v[z] *= scale;
+      }
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_T2F_N3F_V3F_Scale(float scale)
+{
+   if (data != NULL)
+   {
+      texture_vertex* v = (texture_vertex*) data;
+      
+      for (int i = 0; i < count; ++i)
+      {
+         v[i].v[x] *= scale;
+         v[i].v[y] *= scale;
+         v[i].v[z] *= scale;
+      }
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_V3F_Translate(float tx, float ty, float tz)
+{
+   if (data != NULL)
+   {
+      vertex* v = (vertex*) data;
+      
+      for (int i = 0; i < count; ++i)
+      {
+         v[i][x] += tx;
+         v[i][y] += ty;
+         v[i][z] += tz;
+      }
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_N3F_V3F_Translate(float tx, float ty, float tz)
+{
+   if (data != NULL)
+   {
+      normal_vertex* v = (normal_vertex*) data;
+
+      for (int i = 0; i < count; ++i)
+      {
+         v[i].v[x] += tx;
+         v[i].v[y] += ty;
+         v[i].v[z] += tz;
+      }
+   }
+
+   return;
+}
+
+void Sglmodel_sgl::GL_T2F_N3F_V3F_Translate(float tx, float ty, float tz)
+{
+   if (data != NULL)
+   {
+      texture_vertex* v = (texture_vertex*) data;
+
+      for (int i = 0; i < count; ++i)
+      {
+         v[i].v[x] += tx;
+         v[i].v[y] += ty;
+         v[i].v[z] += tz;
+      }
+   }
+
+   return;
+}
+
+#endif
Index: trunk/src/lib/graphics/effects/snow_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/snow_effect.cc	(revision 8228)
+++ trunk/src/lib/graphics/effects/snow_effect.cc	(revision 8255)
@@ -53,5 +53,6 @@
 	}
 
-	this->activate();
+	if(snowActivate)
+		this->activate();
 }
 
@@ -75,7 +76,13 @@
 	LoadParam(root, "emissionRate", this, SnowEffect, emissionRate);
 	LoadParam(root, "emissionVelocity", this, SnowEffect, emissionVelocity);
-  LoadParam(root, "wind", this, SnowEffect, wind);
+	LoadParam(root, "wind", this, SnowEffect, wind);
 	LoadParam(root, "size", this, SnowEffect, size);
 	LoadParam(root, "coord", this, SnowEffect, coord);
+  
+	LOAD_PARAM_START_CYCLE(root, element);
+	{
+		LoadParam_CYCLE(element, "option", this, SnowEffect, setSnowOption);
+	}
+	LOAD_PARAM_END_CYCLE(element);
 }
 
@@ -85,4 +92,6 @@
 
 	// Default values
+	this->snowActivate = false;
+	this->snowMove = false;
 	this->particles = 12000;
 	this->texture = "maps/snow_flake_01_32x32.png";
@@ -100,8 +109,6 @@
 	this->alpha = 0.5;
 	this->snowSize = Vector2D(2500, 2500);
-  this->snowCoord = Vector(100,450,400);
+	this->snowCoord = Vector(100,450,400);
 	this->snowWindForce = 1;
-
-	this->activated = false;
 }
 
@@ -109,5 +116,6 @@
 {
 	PRINTF(0)("Activating SnowEffect\n");
-	activated = true;
+
+	this->snowActivate = true;
 
 	SnowEffect::snowParticles = new SpriteParticles(particles);
@@ -131,5 +139,5 @@
 	this->emitter->setSize(snowSize);
 
-  //SnowEffect::snowParticles->precache(8);
+	// SnowEffect::snowParticles->precache(8);
 
 	if (this->snowWindForce > 1)
@@ -141,6 +149,6 @@
 {
 	PRINTF(0)("Deactivating SnowEffect\n");
-	activated = false;
-
+
+	this->snowActivate = false;
 	this->emitter->setSystem(NULL);
 
@@ -150,52 +158,52 @@
 }
 
-void SnowEffect::activateSnow()
-{
+void SnowEffect::draw() const
+{
+	if (!this->snowActivate)
+		return;
+}
+
+void SnowEffect::tick(float dt)
+{
+	if (!this->snowActivate)
+		return;
+
+	/*
+	float distance = (State::getCameraNode()->getAbsCoor() - Vector(snowCoord.x, State::getCameraNode()->getAbsCoor().y, snowCoord.z)).len();
+	
+	if(activated)
+	{
+	if(distance > 0.3*snowSize.x || distance > 0.3*snowSize.y)
+			this->deactivate();
+	else if(distance > 0.25*snowSize.x || distance > 0.25*snowSize.y)
+	this->alpha = 0.15;
+	else if(distance > 0.2*snowSize.x || distance > 0.2*snowSize.y)
+	this->alpha = 0.25;
+	else if(distance > 0.1*snowSize.x || distance > 0.1*snowSize.y)
+	this->alpha = 0.4;
+	
+	SnowEffect::snowParticles->setColor(0,1, 1, 1, alpha);
+	SnowEffect::snowParticles->setColor(.5, .6, .6, .6, alpha/2);
+	SnowEffect::snowParticles->setColor(1, .0, .0, .0, .0);
+	}
+	else
+	{
+	if(distance < 0.3*snowSize.x || distance < 0.3*snowSize.y )
 	this->activate();
-}
-
-void SnowEffect::deactivateSnow()
-{
-	this->deactivate();
-}
-
-void SnowEffect::draw() const
-{
-}
-
-void SnowEffect::tick(float dt)
-{
-  float distance = (State::getCameraNode()->getAbsCoor() - Vector(snowCoord.x, State::getCameraNode()->getAbsCoor().y, snowCoord.z)).len();
-  
-  if(activated)
-  {
-    if(distance > 0.3*snowSize.x || distance > 0.3*snowSize.y)
-		  this->deactivate();
-    else if(distance > 0.25*snowSize.x || distance > 0.25*snowSize.y) 
-      this->alpha = 0.15;
-    else if(distance > 0.2*snowSize.x || distance > 0.2*snowSize.y) 
-      this->alpha = 0.25;
-    else if(distance > 0.1*snowSize.x || distance > 0.1*snowSize.y) 
-      this->alpha = 0.4;
-
-    SnowEffect::snowParticles->setColor(0,1, 1, 1, alpha);
-    SnowEffect::snowParticles->setColor(.5, .6, .6, .6, alpha/2);
-    SnowEffect::snowParticles->setColor(1, .0, .0, .0, .0);
-  }
-  else
-  {
-  if(distance < 0.3*snowSize.x || distance < 0.3*snowSize.y )
-    this->activate();
-  if( distance < 0.25*snowSize.x || distance < 0.25*snowSize.y )
-    this->alpha = 0.25;
-  else if( distance < 0.2*snowSize.x || distance < 0.2*snowSize.y )
-    this->alpha = 0.4;
-  else if( distance < 0.1*snowSize.x || distance < 0.1*snowSize.y )
-    this->alpha = 0.5;
-
-    SnowEffect::snowParticles->setColor(0,1, 1, 1, alpha);
-    SnowEffect::snowParticles->setColor(.5, .6, .6, .6, alpha/2);
-    SnowEffect::snowParticles->setColor(1, .0, .0, .0, .0);
-  }
-}
-
+	if( distance < 0.25*snowSize.x || distance < 0.25*snowSize.y )
+	this->alpha = 0.25;
+	else if( distance < 0.2*snowSize.x || distance < 0.2*snowSize.y )
+	this->alpha = 0.4;
+	else if( distance < 0.1*snowSize.x || distance < 0.1*snowSize.y )
+	this->alpha = 0.5;
+	
+	SnowEffect::snowParticles->setColor(0,1, 1, 1, alpha);
+	SnowEffect::snowParticles->setColor(.5, .6, .6, .6, alpha/2);
+	SnowEffect::snowParticles->setColor(1, .0, .0, .0, .0);
+	}*/
+
+	if (this->snowMove) {
+		this->snowCoord = State::getCameraNode()->getAbsCoor();
+		this->emitter->setRelCoor(this->snowCoord.x , this->snowCoord.y+300, this->snowCoord.z);
+	}
+}
Index: trunk/src/lib/graphics/effects/snow_effect.h
===================================================================
--- trunk/src/lib/graphics/effects/snow_effect.h	(revision 8228)
+++ trunk/src/lib/graphics/effects/snow_effect.h	(revision 8255)
@@ -33,9 +33,10 @@
 		virtual bool deactivate();
 
+		inline void activateSnow() { this->activate(); }
+		inline void deactivateSnow() { this->deactivate(); }
+		
 		virtual void draw() const;
 		virtual void tick(float dt);
 
-		void activateSnow();
-		void deactivateSnow();
 
 		inline void numParticles(int n) { this->particles = n; }
@@ -48,28 +49,35 @@
 		inline void size(float sizeX, float sizeY) { this->snowSize = Vector2D(sizeX, sizeY); }
 		inline void coord(float x, float y, float z) { this->snowCoord = Vector(x, y, z); }
-    inline void wind(int force) { this->snowWindForce = force; }
+		inline void wind(int force) { this->snowWindForce = force; }
+
+		inline void setSnowOption(const std::string& option) {
+			/*if (option == "fade") this->snowFade = true;*/
+			if (option == "movesnow") this->snowMove = true;
+			if (option == "activate") this->snowActivate = true;
+		}
 
 
 	private:
-		int 																particles;
-		std::string 												texture;
-		float 															life, randomLife;
-		float																snowRadius, randomRadius;
-		float																snowMass, randomMass;
-		float 															rate;
-		float 															velocity, randomVelocity;
-		float 															angle, randomAngle;
-		float 															alpha;
-		Vector 															snowCoord;
-		Vector2D 														snowSize;
-		int																	snowWindForce;
+		int 				particles;
+		std::string 			texture;
+		float				life, randomLife;
+		float				snowRadius, randomRadius;
+		float				snowMass, randomMass;
+		float 				rate;
+		float 				velocity, randomVelocity;
+		float 				angle, randomAngle;
+		float 				alpha;
+		Vector 				snowCoord;
+		Vector2D 			snowSize;
+		int				snowWindForce;
 
-		bool																activated;
+		bool 				snowMove;
+		bool 				snowActivate;
 
-		PlaneEmitter*												emitter;
+		PlaneEmitter*			emitter;
 
-		static SpriteParticles* 						snowParticles;
-		OrxSound::SoundSource              soundSource;
-		OrxSound::SoundBuffer*             windBuffer;
+		static SpriteParticles*		snowParticles;
+		OrxSound::SoundSource		soundSource;
+		OrxSound::SoundBuffer*		windBuffer;
 
 };
Index: trunk/src/lib/graphics/effects/weather_effect.cc
===================================================================
--- trunk/src/lib/graphics/effects/weather_effect.cc	(revision 8228)
+++ trunk/src/lib/graphics/effects/weather_effect.cc	(revision 8255)
@@ -15,4 +15,5 @@
 */
 
+// TODO: descriptions to loadparams, movealong unified, start activation
 
 #include "weather_effect.h"
Index: trunk/src/lib/graphics/light.h
===================================================================
--- trunk/src/lib/graphics/light.h	(revision 8228)
+++ trunk/src/lib/graphics/light.h	(revision 8255)
@@ -1,9 +1,9 @@
 /*!
- * @file light.h
-  *  Handles Lights.
+* @file light.h
+*  Handles Lights.
 
-    A Light is one of the more important things in a 3D-environment,
-    without it one sees nothing :)
-    It is here for diffuse-, specular- and Bump-Mappings.
+A Light is one of the more important things in a 3D-environment,
+without it one sees nothing :)
+It is here for diffuse-, specular- and Bump-Mappings.
 */
 
@@ -25,98 +25,100 @@
 class Light : public PNode
 {
- public:
-  Light(const TiXmlElement* root = NULL);
-  virtual ~Light();
-
-  virtual void loadParams(const TiXmlElement* root);
-
-  void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
-  void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
-  void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
-  void setSpotDirection(const Vector& direction);
-  void setSpotDirection(float x, float y, float z) { setSpotDirection(Vector(x,y,z)); };
-  void setSpotCutoff(GLfloat cutoff);
-
-  /** @returns the lightNumber*/
-  int getLightNumber() const {return this->lightNumber;}
-
-  virtual void draw() const;
-
-  void debug() const;
-
-  // attributes
- private:
-  int              lightNumber;               //!< The number of this Light.
-  GLfloat          diffuseColor[4];           //!< The Diffuse Color this Light emmits.
-  GLfloat          specularColor[4];          //!< The specular Color of this Light.
-  float            constantAttenuation;       //!< The Factor of the the Constant Attenuation.
-  float            linearAttenuation;         //!< The Factor of the the Linear Attenuation.
-  float            quadraticAttenuation;      //!< The Factor of the the Quadratic Attenuation.
-  GLfloat          spotDirection[4];          //!< The direction of the Spot Light.
-  GLfloat          spotCutoff;                //!< The cutoff Angle of the Light Source
+	public:
+		Light(const TiXmlElement* root = NULL);
+		virtual ~Light();
+		
+		virtual void loadParams(const TiXmlElement* root);
+		
+		void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+		void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+		void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+		void setSpotDirection(const Vector& direction);
+		void setSpotDirection(float x, float y, float z) { setSpotDirection(Vector(x,y,z)); };
+		void setSpotCutoff(GLfloat cutoff);
+		
+		/** @returns the lightNumber*/
+		int getLightNumber() const {return this->lightNumber;}
+		
+		virtual void draw() const;
+		
+		void debug() const;
+	
+	// attributes
+	private:
+		int              lightNumber;               //!< The number of this Light.
+		GLfloat          diffuseColor[4];           //!< The Diffuse Color this Light emmits.
+		GLfloat          specularColor[4];          //!< The specular Color of this Light.
+		float            constantAttenuation;       //!< The Factor of the the Constant Attenuation.
+		float            linearAttenuation;         //!< The Factor of the the Linear Attenuation.
+		float            quadraticAttenuation;      //!< The Factor of the the Quadratic Attenuation.
+		GLfloat          spotDirection[4];          //!< The direction of the Spot Light.
+		GLfloat          spotCutoff;                //!< The cutoff Angle of the Light Source
 };
-
-
-
+	
+	
+	
 //! A class that handles Lights
 /**
-   A Light is a source that emits light rays (photons)
+A Light is a source that emits light rays (photons)
 
-   <b>Usage:</b>\n
-   First you have to get the Light Manager up and running by using LightManager::getInstance().
-   This automatically initiates the GL_LIGHTING, and sets some default stuff about the light.\n
-   Then you will create a new light using:
-   \li new Light();
+<b>Usage:</b>\n
+First you have to get the Light Manager up and running by using LightManager::getInstance().
+This automatically initiates the GL_LIGHTING, and sets some default stuff about the light.\n
+Then you will create a new light using:
+\li new Light();
 
-   if you want to operate on this Light just apply the following functions onto it.
-       (You can also optain the Light-pointer with LightManager::getInstance()->getLight(lightNumber))
+if you want to operate on this Light just apply the following functions onto it.
+(You can also optain the Light-pointer with LightManager::getInstance()->getLight(lightNumber))
 
-   now you can operate on the light as follows:
-   \li void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
-   \li void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
-   \li void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
-   \li void setSpotDirection(Vector direction);
-   \li void setSpotCutoff(GLfloat cutoff);
-   \li all PNode stuff also works
+now you can operate on the light as follows:
+\li void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+\li void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+\li void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+\li void setSpotDirection(Vector direction);
+\li void setSpotCutoff(GLfloat cutoff);
+\li all PNode stuff also works
 
-   To redraw the light use
-   \li void draw() const; (this is automatically done by the LightManager)
+To redraw the light use
+\li void draw() const; (this is automatically done by the LightManager)
 
-   for some nice output just use:
-   \li void debug() const; (either on LightManager for a resume or on any Light for single information.)
+for some nice output just use:
+\li void debug() const; (either on LightManager for a resume or on any Light for single information.)
 */
 class LightManager : public BaseObject
-{
-  friend class Light;
+	{
+	friend class Light;
 
- public:
-  virtual ~LightManager();
-  /** @returns a Pointer to the only object of this Class */
-  inline static LightManager* getInstance() { if (!singletonRef) singletonRef = new LightManager();  return singletonRef; };
+	public:
+		virtual ~LightManager();
+		/** @returns a Pointer to the only object of this Class */
+		inline static LightManager* getInstance() { if (!singletonRef) singletonRef = new LightManager();  return singletonRef; };
 
-  virtual void loadParams(const TiXmlElement* root);
-  void loadLights(const TiXmlElement* root);
+		virtual void loadParams(const TiXmlElement* root);
+		void loadLights(const TiXmlElement* root);
 
-  void setAmbientColor(GLfloat r, GLfloat g, GLfloat b);
+		void setAmbientColor(GLfloat r, GLfloat g, GLfloat b);
+		// HACK: Assuming r = g = b values
+		inline GLfloat getAmbientColor() {  return this->ambientColor[0]; }
 
-  Light* getLight(int lightNumber) const;
-  inline Light* getLight() const { return this->currentLight; };
+		Light* getLight(int lightNumber) const;
+		inline Light* getLight() const { return this->currentLight; };
 
-  void draw() const;
+		void draw() const;
 
-  void debug() const;
+		void debug() const;
 
- private:
-  LightManager();
+	private:
+		LightManager();
 
-  int  registerLight(Light* light);
-  void unregisterLight(Light* light);
+		int  registerLight(Light* light);
+		void unregisterLight(Light* light);
 
- private:
-  static LightManager*    singletonRef;       //!< This is the LightHandlers Reference.
-  GLfloat                 ambientColor[4];    //!< The ambient Color of the scene.
+	private:
+		static LightManager*    singletonRef;       //!< This is the LightHandlers Reference.
+		GLfloat                 ambientColor[4];    //!< The ambient Color of the scene.
 
-  Light**                 lights;             //!< An array of Lenght NUMBEROFLIGHTS, that holds pointers to all LightValues.
-  Light*                  currentLight;       //!< The current Light, we are working with.
+		Light**                 lights;             //!< An array of Lenght NUMBEROFLIGHTS, that holds pointers to all LightValues.
+		Light*                  currentLight;       //!< The current Light, we are working with.
 
 };
Index: trunk/src/lib/graphics/shader.cc
===================================================================
--- trunk/src/lib/graphics/shader.cc	(revision 8228)
+++ trunk/src/lib/graphics/shader.cc	(revision 8255)
@@ -201,4 +201,22 @@
 }
 
+void Shader::bindShader(const char* name, const float* value, size_t size)
+{
+	if (likely (this->shaderProgram != 0)) {
+		glUseProgramObjectARB(this->shaderProgram);
+
+		unsigned int location = glGetUniformLocationARB(this->shaderProgram, name);
+		/* This is EXPENSIVE and should be avoided. */
+
+		if      (size == 1)  glUniform1fvARB(location, 1, value);
+		else if (size == 2)  glUniform2fvARB(location, 1, value);
+		else if (size == 3)  glUniform3fvARB(location, 1, value);
+		else if (size == 4)  glUniform4fvARB(location, 1, value);
+		else if (size == 9)  glUniformMatrix3fvARB(location, 1, false, value);
+		else if (size == 16) glUniformMatrix4fvARB(location, 1, false, value);
+
+	}
+}
+
 void Shader::deactivateShader()
 {
Index: trunk/src/lib/graphics/shader.h
===================================================================
--- trunk/src/lib/graphics/shader.h	(revision 8228)
+++ trunk/src/lib/graphics/shader.h	(revision 8255)
@@ -96,4 +96,5 @@
   static bool checkShaderAbility();
   void activateShader();
+  void bindShader(const char* name, const float* value, size_t size);
   static void deactivateShader();
 
Index: trunk/src/lib/sound/sound_source.cc
===================================================================
--- trunk/src/lib/sound/sound_source.cc	(revision 8228)
+++ trunk/src/lib/sound/sound_source.cc	(revision 8255)
@@ -1,15 +1,15 @@
 /*
-   orxonox - the future of 3D-vertical-scrollers
-
-   Copyright (C) 2004 orx
-
-   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, or (at your option)
-   any later version.
-
-   ### File Specific:
-   main-programmer: Benjamin Grauer
-   co-programmer: ...
+	orxonox - the future of 3D-vertical-scrollers
+
+	Copyright (C) 2004 orx
+
+	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, or (at your option)
+	any later version.
+
+	### File Specific:
+	main-programmer: Benjamin Grauer
+	co-programmer: ...
 */
 
@@ -24,262 +24,368 @@
 namespace OrxSound
 {
-  /**
-   * @brief creates a SoundSource at position sourceNode with the SoundBuffer buffer
-   */
-  SoundSource::SoundSource(const PNode* sourceNode, const SoundBuffer* buffer)
-  {
-    this->setClassID(CL_SOUND_SOURCE, "SoundSource");
-
-    // adding the Source to the SourcesList of the SoundEngine
-    this->buffer = buffer;
-    this->sourceNode = sourceNode;
-    this->resident = false;
-
-    this->sourceID = 0;
-    this->bPlay = false;
-  }
-
-
-  /**
-   * @brief construct a SoundSource out of the another soundSource
-   * @param source the Source to create this source from.
-   *
-   * Copies the buffer from source to this Source.
-   * Acquires a new SourceID if source is Playing.
-   */
-  SoundSource::SoundSource(const SoundSource& source)
-  {
-    this->setClassID(CL_SOUND_SOURCE, "SoundSource");
-
-    // adding the Source to the SourcesList of the SoundEngine
-    this->buffer = source.buffer;
-    this->sourceNode = source.sourceNode;
-    this->resident = source.resident;
-
-    this->sourceID = 0;
-    if (source.bPlay == true)
-    {
-      this->bPlay = true;
-      SoundEngine::getInstance()->popALSource(this->sourceID);
-    }
-    else
-      this->bPlay = false;
-  }
-
-
-  /**
-   * @brief paste a copy of the source into this Source.
-   * @param source the SoundSource to paste into this one.
-   * @returns a Reference to this Source.
-   *
-   */
-  SoundSource& SoundSource::operator=(const SoundSource& source)
-  {
-    this->buffer = source.buffer;
-    this->sourceNode = sourceNode;
-    this->resident = source.resident;
-
-    if (source.bPlay)
-      this->play();
-    else
-      this->stop();
-  }
-
-
-  /**
-   * @brief compares two Sources with each other.
-   * @param source the Source to compare against this One.
-   * Two Sources are the same, if the PNodes match, and the Sound Played are the same.
-   * The alSource must not match, because no two Sources can have the same alSource.
-   */
-  bool SoundSource::operator==(const SoundSource& source)
-  {
-    return (this->buffer == source.buffer &&
-            this->bPlay == source.bPlay &&
-            this->sourceNode == source.sourceNode);
-  }
-
-
-  /**
-   * @brief deletes a SoundSource
-   */
-  SoundSource::~SoundSource()
-  {
-    this->stop();
-    if (this->sourceID != 0)
-      SoundEngine::getInstance()->pushALSource(this->sourceID);
-  }
-
-
-  /**
-   * @brief Plays back a SoundSource
-   */
-  void SoundSource::play()
-  {
-    if (this->buffer && this->retrieveSource())
-    {
-      if (this->bPlay)
-        alSourceStop(this->sourceID);
-      alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
-    alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE  );
-    alSourcePlay(this->sourceID);
-
-      if (DEBUG_LEVEL >= 3)
-        SoundEngine::checkError("Play Source", __LINE__);
-      this->bPlay = true;
-    }
-  }
-
-
-  /**
-   * @brief Plays back buffer on this Source
-   * @param buffer the buffer to play back on this Source
-   */
-  void SoundSource::play(const SoundBuffer* buffer)
-  {
-    if (!this->retrieveSource())
-    {
-      PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
-      return;
-    }
-
-  alSourceStop(this->sourceID);
-  alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
-  alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE  );
-  alSourcePlay(this->sourceID);
-
-    if (unlikely(this->buffer != NULL))
-      alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
-    this->bPlay = true;
-
-    if (DEBUG_LEVEL >= 3)
-      SoundEngine::checkError("Play Source", __LINE__);
-  }
-
-
-/**
- * @brief Plays and loops buffer on this Source
- * @param buffer the buffer to play back on this Source
- */
-void SoundSource::loop(const SoundBuffer* buffer)
-{
-  if (this->buffer && this->retrieveSource())
-  {
-    if (this->bPlay)
-      alSourceStop(this->sourceID);
-
-    alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
-    alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE  );
-    alSourcePlay(this->sourceID);
-
-    if (DEBUG_LEVEL >= 3)
-      SoundEngine::checkError("Play LoopSource", __LINE__);
-    this->bPlay = true;
-  }
+	/**
+	* @brief creates a SoundSource at position sourceNode with the SoundBuffer buffer
+	*/
+	SoundSource::SoundSource(const PNode* sourceNode, const SoundBuffer* buffer)
+	{
+		this->setClassID(CL_SOUND_SOURCE, "SoundSource");
+
+		// adding the Source to the SourcesList of the SoundEngine
+		this->buffer = buffer;
+		this->sourceNode = sourceNode;
+		this->resident = false;
+
+		this->sourceID = 0;
+		this->bPlay = false;
+	}
+
+
+	/**
+	* @brief construct a SoundSource out of the another soundSource
+	* @param source the Source to create this source from.
+	*
+	* Copies the buffer from source to this Source.
+	* Acquires a new SourceID if source is Playing.
+	*/
+	SoundSource::SoundSource(const SoundSource& source)
+	{
+		this->setClassID(CL_SOUND_SOURCE, "SoundSource");
+
+		// adding the Source to the SourcesList of the SoundEngine
+		this->buffer = source.buffer;
+		this->sourceNode = source.sourceNode;
+		this->resident = source.resident;
+
+		this->sourceID = 0;
+		if (source.bPlay == true)
+		{
+			this->bPlay = true;
+			SoundEngine::getInstance()->popALSource(this->sourceID);
+		}
+		else
+			this->bPlay = false;
+	}
+
+
+	/**
+	* @brief paste a copy of the source into this Source.
+	* @param source the SoundSource to paste into this one.
+	* @returns a Reference to this Source.
+	*
+	*/
+	SoundSource& SoundSource::operator=(const SoundSource& source)
+	{
+		this->buffer = source.buffer;
+		this->sourceNode = sourceNode;
+		this->resident = source.resident;
+
+		if (source.bPlay)
+			this->play();
+		else
+			this->stop();
+	}
+
+
+	/**
+	* @brief compares two Sources with each other.
+	* @param source the Source to compare against this One.
+	* Two Sources are the same, if the PNodes match, and the Sound Played are the same.
+	* The alSource must not match, because no two Sources can have the same alSource.
+	*/
+	bool SoundSource::operator==(const SoundSource& source)
+	{
+		return (this->buffer == source.buffer &&
+						this->bPlay == source.bPlay &&
+						this->sourceNode == source.sourceNode);
+	}
+
+
+	/**
+	* @brief deletes a SoundSource
+	*/
+	SoundSource::~SoundSource()
+	{
+		this->stop();
+		if (this->sourceID != 0)
+			SoundEngine::getInstance()->pushALSource(this->sourceID);
+	}
+
+
+	/**
+	* @brief Plays back a SoundSource
+	*/
+	void SoundSource::play()
+	{
+		if (this->buffer && this->retrieveSource())
+		{
+			if (this->bPlay)
+				alSourceStop(this->sourceID);
+			
+			alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
+			alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
+			alSourcef (this->sourceID, AL_GAIN, 1);
+			alSourcePlay(this->sourceID);
+
+			if (DEBUG_LEVEL >= 3)
+				SoundEngine::checkError("Play Source", __LINE__);
+			this->bPlay = true;
+		}
+	}
+
+
+	/**
+	* @brief Plays back buffer on this Source
+	* @param buffer the buffer to play back on this Source
+	*/
+	void SoundSource::play(const SoundBuffer* buffer)
+	{
+		if (!this->retrieveSource())
+		{
+			PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
+			return;
+		}
+
+		alSourceStop(this->sourceID);
+		alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
+		alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
+		alSourcef (this->sourceID, AL_GAIN, 1);
+
+		alSourcePlay(this->sourceID);
+
+		if (unlikely(this->buffer != NULL))
+			alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
+		this->bPlay = true;
+
+		if (DEBUG_LEVEL >= 3)
+			SoundEngine::checkError("Play Source", __LINE__);
+	}
+
+
+	/**
+	* @brief Plays back buffer on this Source with gain
+	* @param buffer the buffer to play back on this Source
+	*/
+	void SoundSource::play(const SoundBuffer* buffer, float gain)
+	{
+		if (!this->retrieveSource())
+		{
+			PRINTF(3)("No more Free sources (You might consider raising the Source-Count).\n");
+			return;
+		}
+
+		alSourceStop(this->sourceID);
+		alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
+		alSourcei (this->sourceID, AL_LOOPING,  AL_FALSE);
+		alSourcef (this->sourceID, AL_GAIN, gain);
+
+		alSourcePlay(this->sourceID);
+
+		if (unlikely(this->buffer != NULL))
+			alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
+		this->bPlay = true;
+
+		if (DEBUG_LEVEL >= 3)
+			SoundEngine::checkError("Play Source", __LINE__);
+	}
+
+
+	/**
+	* @brief Plays and loops back a SoundSource
+	*/
+	void SoundSource::loop()
+	{
+		if (this->buffer && this->retrieveSource())
+		{
+			if (this->bPlay)
+				alSourceStop(this->sourceID);
+			
+			alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
+			alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE);
+			alSourcef (this->sourceID, AL_GAIN, 1);
+			alSourcePlay(this->sourceID);
+
+			if (DEBUG_LEVEL >= 3)
+				SoundEngine::checkError("Play Source", __LINE__);
+			this->bPlay = true;
+		}
+	}
+
+	/**
+	* @brief Plays and loops buffer on this Source
+	* @param buffer the buffer to play back on this Source
+	*/
+	void SoundSource::loop(const SoundBuffer* buffer)
+	{
+		if (this->buffer && this->retrieveSource())
+		{
+			if (this->bPlay)
+				alSourceStop(this->sourceID);
+	
+			alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
+			alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE);
+			alSourcef (this->sourceID, AL_GAIN, 1);
+	
+			alSourcePlay(this->sourceID);
+	
+			if (DEBUG_LEVEL >= 3)
+				SoundEngine::checkError("Loop Source", __LINE__);
+			this->bPlay = true;
+		}
+	}
+	
+	
+	/**
+	* @brief Plays and loops buffer on this Source with gain control
+	* @param buffer the buffer to play back on this Source
+	*/
+	void SoundSource::loop(const SoundBuffer* buffer, float gain)
+	{
+		if (this->buffer && this->retrieveSource())
+		{
+			if (this->bPlay)
+				alSourceStop(this->sourceID);
+	
+			alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
+			alSourcei (this->sourceID, AL_LOOPING,  AL_TRUE);
+			alSourcef (this->sourceID, AL_GAIN, gain);
+	
+			alSourcePlay(this->sourceID);
+	
+			if (DEBUG_LEVEL >= 3)
+				SoundEngine::checkError("Loop Source", __LINE__);
+			this->bPlay = true;
+		}
+	}
+	
+	
+	/**
+	* @brief Stops playback of a SoundSource
+	*/
+	void SoundSource::stop()
+	{
+		this->bPlay = false;
+		if (this->sourceID != 0)
+		{
+			this->bPlay = false;
+			if (this->sourceID != 0)
+			{
+				alSourceStop(this->sourceID);
+				if (DEBUG_LEVEL >= 3)
+					SoundEngine::checkError("StopSource", __LINE__);
+				alSourcei(this->sourceID, AL_BUFFER, 0);
+				if (!this->resident)
+					SoundEngine::getInstance()->pushALSource(this->sourceID);
+				this->sourceID = 0;
+			}
+		}
+	}
+
+	/**
+	* @brief Pauses Playback of a SoundSource
+	*/
+	void SoundSource::pause()
+	{
+		alSourcePause(this->sourceID);
+		if (DEBUG_LEVEL >= 3)
+			SoundEngine::checkError("Pause Source", __LINE__);
+	}
+
+
+	/**
+	* @brief Rewinds Playback of a SoundSource
+	*/
+	void SoundSource::rewind()
+	{
+		alSourceRewind(this->sourceID);
+
+		if (DEBUG_LEVEL >= 3)
+			SoundEngine::checkError("Rewind Source", __LINE__);
+	}
+
+
+	/**
+	* @brief sets the RolloffFactor of the Sound emitted from the SoundSource
+	* @param rolloffFactor The Factor described
+	*
+	* this tells openAL how fast the Sounds decay outward from the Source
+	*/
+	void SoundSource::setRolloffFactor(ALfloat rolloffFactor)
+	{
+		alSourcef(this->sourceID, AL_ROLLOFF_FACTOR, rolloffFactor);
+
+		if (DEBUG_LEVEL >= 3)
+			SoundEngine::checkError("Set Source Rolloff-factor", __LINE__);
+	}
+
+
+	/**
+	* @brief sets the Positional this Source should be attached to.
+	* @param sourceNode the Source this is attached to.
+	* If sourceNode == NULL then the Source will be centered, and Audio will be played on all channels.
+	*/
+	void SoundSource::setSourceNode(const PNode* sourceNode)
+	{
+		this->sourceNode = sourceNode;
+	}
+
+	/**
+	* @brief retrieve a Source.
+	*/
+	bool SoundSource::retrieveSource()
+	{
+		if (this->sourceID != 0)
+			return true;
+		else
+		{
+			SoundEngine::getInstance()->popALSource(this->sourceID);
+			if (this->sourceID != 0)
+			{
+				if (unlikely(this->sourceNode == NULL))
+					resetSource(this->sourceID);
+				return true;
+			}
+		}
+		return false;
+	}
+
+
+	/**
+	* @brief reset an alSource to its default Values.
+	*/
+	void SoundSource::resetSource(ALuint sourceID)
+	{
+		alSource3f(sourceID, AL_POSITION,        0.0, 0.0, 0.0);
+		alSource3f(sourceID, AL_VELOCITY,        0.0, 0.0, 0.0);
+		alSource3f(sourceID, AL_DIRECTION,       0.0, 0.0, 0.0);
+		alSourcef (sourceID, AL_ROLLOFF_FACTOR,  0.0          );
+		//alSourcei (sourceID, AL_SOURCE_RELATIVE, AL_TRUE      );
+		alSourcef (sourceID, AL_GAIN,            SoundEngine::getInstance()->getEffectsVolume());
+	}
+
+
+	/**
+	* @brief Fades in a Source over a time period
+	* @param duration time perios to fade in
+	*/
+	void SoundSource::fadein(const SoundBuffer* buffer, ALfloat duration)
+	{
+		//if (this->buffer && this->retrieveSource())
+		//{
+
+		for (ALfloat n = 0.0; n < 1.0; n+=.01)
+		{
+			alSourcef(this->sourceID, AL_GAIN, n);
+			// sleep(1);
+		}
+
+		//	alSourcePlay(this->sourceID);
+	
+		//	if (DEBUG_LEVEL >= 3)
+		//		SoundEngine::checkError("Loop Source", __LINE__);
+		//	this->bPlay = true;
+		//}
+
+	}
+
+
 }
-
-
-/**
- * @brief Stops playback of a SoundSource
- */
-void SoundSource::stop()
-{
-  this->bPlay = false;
-  if (this->sourceID != 0)
-  {
-    this->bPlay = false;
-    if (this->sourceID != 0)
-    {
-      alSourceStop(this->sourceID);
-      if (DEBUG_LEVEL >= 3)
-        SoundEngine::checkError("StopSource", __LINE__);
-      alSourcei(this->sourceID, AL_BUFFER, 0);
-      if (!this->resident)
-        SoundEngine::getInstance()->pushALSource(this->sourceID);
-      this->sourceID = 0;
-    }
-  }
-}
-
-  /**
-   * @brief Pauses Playback of a SoundSource
-   */
-  void SoundSource::pause()
-  {
-    alSourcePause(this->sourceID);
-    if (DEBUG_LEVEL >= 3)
-      SoundEngine::checkError("Pause Source", __LINE__);
-  }
-
-
-  /**
-   * @brief Rewinds Playback of a SoundSource
-   */
-  void SoundSource::rewind()
-  {
-    alSourceRewind(this->sourceID);
-
-    if (DEBUG_LEVEL >= 3)
-      SoundEngine::checkError("Rewind Source", __LINE__);
-  }
-
-
-  /**
-   * @brief sets the RolloffFactor of the Sound emitted from the SoundSource
-   * @param rolloffFactor The Factor described
-   *
-   * this tells openAL how fast the Sounds decay outward from the Source
-   */
-  void SoundSource::setRolloffFactor(ALfloat rolloffFactor)
-  {
-    alSourcef(this->sourceID, AL_ROLLOFF_FACTOR, rolloffFactor);
-
-    if (DEBUG_LEVEL >= 3)
-      SoundEngine::checkError("Set Source Rolloff-factor", __LINE__);
-  }
-
-
-  /**
-   * @brief sets the Positional this Source should be attached to.
-   * @param sourceNode the Source this is attached to.
-   * If sourceNode == NULL then the Source will be centered, and Audio will be played on all channels.
-   */
-  void SoundSource::setSourceNode(const PNode* sourceNode)
-  {
-    this->sourceNode = sourceNode;
-  }
-
-  /**
-   * @brief retrieve a Source.
-   */
-  bool SoundSource::retrieveSource()
-  {
-    if (this->sourceID != 0)
-      return true;
-    else
-    {
-      SoundEngine::getInstance()->popALSource(this->sourceID);
-      if (this->sourceID != 0)
-      {
-        if (unlikely(this->sourceNode == NULL))
-          resetSource(this->sourceID);
-        return true;
-      }
-    }
-    return false;
-  }
-
-
-  /**
-   * @brief reset an alSource to its default Values.
-   */
-  void SoundSource::resetSource(ALuint sourceID)
-  {
-    alSource3f(sourceID, AL_POSITION,        0.0, 0.0, 0.0);
-    alSource3f(sourceID, AL_VELOCITY,        0.0, 0.0, 0.0);
-    alSource3f(sourceID, AL_DIRECTION,       0.0, 0.0, 0.0);
-    alSourcef (sourceID, AL_ROLLOFF_FACTOR,  0.0          );
-    //alSourcei (sourceID, AL_SOURCE_RELATIVE, AL_TRUE      );
-    alSourcef (sourceID, AL_GAIN,            SoundEngine::getInstance()->getEffectsVolume());
-  }
-}
Index: trunk/src/lib/sound/sound_source.h
===================================================================
--- trunk/src/lib/sound/sound_source.h	(revision 8228)
+++ trunk/src/lib/sound/sound_source.h	(revision 8255)
@@ -1,5 +1,5 @@
 /*!
- * @file sound_source.h
- * @brief Definition of the SoundSource.
+* @file sound_source.h
+* @brief Definition of the SoundSource.
 */
 
@@ -14,54 +14,58 @@
 namespace OrxSound
 {
-  class SoundBuffer;
-  //! A class that represents a SoundSource
-  class SoundSource : public BaseObject
-  {
-  public:
-    SoundSource(const PNode* sourceNode = NULL, const SoundBuffer* buffer = NULL);
-    SoundSource(const SoundSource& source);
-    SoundSource& operator=(const SoundSource& source);
-    bool operator==(const SoundSource& source);
-
-    virtual ~SoundSource();
-
-    // user interaction
-    void play();
-    void play(const SoundBuffer* buffer);
-    void loop();
-    void loop(const SoundBuffer* buffer);
-    void stop();
-    void pause();
-    void rewind();
-
-    // development functions
-    /** @returns The ID of this Source */
-    inline ALuint getID() const { return this->sourceID; };
-    /** @returns true, if the Source is Playing */
-    inline bool   isPlaying() const { return this->bPlay; };
-    void setSourceNode(const PNode* sourceNode);
-    /** @returns the SoundBuffer of this Source */
-    inline const SoundBuffer* getBuffer() const { return this->buffer; };
-    /** @returns the SourceNode of this Source */
-    inline const PNode* getNode() const { return this->sourceNode; };
-    /** @param resident if the Source is Resident */
-    inline void setResident(bool resident) { this->resident = resident; };
-    /** @returns true if the alSource is Resident */
-    inline bool isResident() const { return this->resident; };
-
-    void setRolloffFactor(ALfloat rolloffFactor);
-
-    static void resetSource(ALuint sourceID);
-
-  private:
-    bool retrieveSource();
-
-  private:
-    bool                   bPlay;                 //!< If the Source is Playing.
-    bool                   resident;              //!< If the alSource should be resident (if true, the alSource will be returned on deletion).
-    ALuint                 sourceID;              //!< The ID of the Source
-    const SoundBuffer*     buffer;                //!< The buffer to play in this source.
-    const PNode*           sourceNode;            //!< The SourceNode representing the position/velocity... of this source.
-  };
+	class SoundBuffer;
+	//! A class that represents a SoundSource
+	class SoundSource : public BaseObject
+	{
+		public:
+			SoundSource(const PNode* sourceNode = NULL, const SoundBuffer* buffer = NULL);
+			SoundSource(const SoundSource& source);
+			SoundSource& operator=(const SoundSource& source);
+			bool operator==(const SoundSource& source);
+			
+			virtual ~SoundSource();
+			
+			// user interaction
+			void play();
+			void play(const SoundBuffer* buffer);
+			void play(const SoundBuffer* buffer, float gain);
+			void loop();
+			void loop(const SoundBuffer* buffer);
+			void loop(const SoundBuffer* buffer, float gain);
+			void stop();
+			void pause();
+			void rewind();
+			void fadein(const SoundBuffer* buffer, ALfloat duration);
+			
+			
+			// development functions
+			/** @returns The ID of this Source */
+			inline ALuint getID() const { return this->sourceID; };
+			/** @returns true, if the Source is Playing */
+			inline bool   isPlaying() const { return this->bPlay; };
+			void setSourceNode(const PNode* sourceNode);
+			/** @returns the SoundBuffer of this Source */
+			inline const SoundBuffer* getBuffer() const { return this->buffer; };
+			/** @returns the SourceNode of this Source */
+			inline const PNode* getNode() const { return this->sourceNode; };
+			/** @param resident if the Source is Resident */
+			inline void setResident(bool resident) { this->resident = resident; };
+			/** @returns true if the alSource is Resident */
+			inline bool isResident() const { return this->resident; };
+			
+			void setRolloffFactor(ALfloat rolloffFactor);
+			
+			static void resetSource(ALuint sourceID);
+		
+		private:
+			bool retrieveSource();
+			
+		private:
+			bool                   bPlay;		//!< If the Source is Playing.
+			bool                   resident;	//!< If the alSource should be resident (if true, the alSource will be returned on deletion).
+			ALuint                 sourceID;	//!< The ID of the Source
+			const SoundBuffer*     buffer;		//!< The buffer to play in this source.
+			const PNode*           sourceNode;	//!< The SourceNode representing the position/velocity... of this source.
+	};
 }
 #endif /* _SOUND_SOURCE_H */
