Index: /branches/atmospheric_engine/src/lib/graphics/effects/cloud_effect.cc
===================================================================
--- /branches/atmospheric_engine/src/lib/graphics/effects/cloud_effect.cc	(revision 8174)
+++ /branches/atmospheric_engine/src/lib/graphics/effects/cloud_effect.cc	(revision 8175)
@@ -11,8 +11,7 @@
 ### File Specific:
 	main-programmer: hdavid, amaechler
-	Taken from SkySphere
+
+	INSPIRED BY http://www.codesampler.com/usersrc/usersrc_6.htm#oglu_sky_dome_shader
 */
-
-// TODO: Vektortextur erzeugen und Regionen auswaehlen, Sky...
 
 #include "cloud_effect.h"
@@ -20,13 +19,16 @@
 #include "util/loading/load_param.h"
 #include "util/loading/factory.h"
+#include "util/loading/resource_manager.h"
 
 #include "glincl.h"
 #include "material.h"
 #include <math.h>
-#include "material.h"
 #include "state.h"
 #include "p_node.h"
+#include "shader.h"
 
 #include "parser/tinyxml/tinyxml.h"
+
+#include "sglmodel.h"
 
 using namespace std;
@@ -50,6 +52,9 @@
 	this->deactivate();
 
-	//delete this->skyMaterial;
-	//gluDeleteQuadric(this->sphereObj);
+	delete this->cloudMaterial;
+
+	g_sky_model.Delete();
+	Shader::unload(this->skyShader);
+
 }
 
@@ -59,17 +64,48 @@
 	PRINTF(1)("Initializing CloudEffect\n");
 
-	this->sphereObj = gluNewQuadric();
-	//this->setParentMode(PNODE_MOVEMENT);
-
-	gluQuadricTexture(this->sphereObj, GL_TRUE);
-	gluQuadricOrientation(this->sphereObj, GLU_INSIDE);
-
-	this->setRadius(1900.0);
-
-	mover = 0.0f;
-
-	// Initializing default values
-	this->cloudSpeed = 1.0f;
+	// 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);
+	
+	float diffuse[]  = {1.0f, 1.0f, 1.0f, 1.0f};
+	float position[] = {0.0f, 2.0f, 0.0f, 1.0f};
+	float specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
+	
+	glEnable(GL_LIGHTING);
+	glEnable( GL_LIGHT0);
+	glLightfv(GL_LIGHT0, GL_DIFFUSE,  diffuse);
+	glLightfv(GL_LIGHT0, GL_POSITION, position);
+	glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
+	
+	float shininess = 5.0f;
+	glEnable(GL_COLOR_MATERIAL);
+	glMaterialf( GL_FRONT, GL_SHININESS, shininess);
+	glMaterialfv(GL_FRONT, GL_SPECULAR,  specular);
+
 	this->cloudTexture = "pictures/sky/cloud1.jpg";
+
+	g_sky_model.Load("sky.sgl");
+	g_sky_model.Unitize();
+
+	/* Get the bounding box of the sky dome. */
+	float bbox[3] = {0};
+	g_sky_model.GetDimensions(bbox[0], bbox[1], bbox[2]);
+	
+	// this->skyShader = (Shader*)ResourceManager::getInstance()->load("shaders/sky.vert", SHADER, RP_GAME, "shaders/skyfrag");
+	this->skyShader = 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->skyShader->bindShader("bbox", bbox, 4);
+
+	//g_cloud_texture = 0;
+
+	g_tint[4] = ( 0.9f, 0.7f, 0.7f, 1.0f );
+	g_scroll = 1.0f;
+	time = 0.0f;
 }
 
@@ -101,22 +137,69 @@
 void CloudEffect::draw() const
 {
-	/* TODO:
-		-Load a texture, for now from an existing image, a cloud texture
-		-Blend / Overlay this with a blue sky like in the tutorial
-		-Animate it (for now move it along the sky)
-	*/
+
+// 	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();
 
-	// 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);
+	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->skyShader->activateShader();
+
+	/* Select the shader program and update parameters. */
+	/* The "time" parameter controls the cloud scrolling. */
+	this->skyShader->bindShader("time", &time, 1);
+	/* The "horizon" parameter controls the sky tinting. */
+	this->skyShader->bindShader("horizon", g_tint, 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. */
+	g_sky_model.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();
 }
@@ -124,16 +207,8 @@
 void CloudEffect::tick (float dt)
 {
-	mover = mover + this->cloudSpeed * dt;
-}
-
-
-/**
-*  sets the Radius of the Sphere.
-* @param radius The Radius of The Sphere
-*/
-void CloudEffect::setRadius(float radius)
-{
-	this->sphereRadius = radius;
-}
-
-
+	// mover = mover + this->cloudSpeed * dt;
+
+	/* Update the timer for scrolling the clouds. */
+	time = time + ((1.0f / 2000.0f) * g_scroll);
+}
+
Index: /branches/atmospheric_engine/src/lib/graphics/effects/cloud_effect.h
===================================================================
--- /branches/atmospheric_engine/src/lib/graphics/effects/cloud_effect.h	(revision 8174)
+++ /branches/atmospheric_engine/src/lib/graphics/effects/cloud_effect.h	(revision 8175)
@@ -14,4 +14,7 @@
 #include "glincl.h"
 
+#include "sglmodel.h"
+
+class Shader;
 class Material;
 class Vector;
@@ -33,6 +36,6 @@
 		virtual void tick(float dt);
 
-		void setRadius(float radius);
-		void setTexture(char* fileName);
+		// void setRadius(float radius);
+		// void setTexture(char* fileName);
 
 
@@ -40,5 +43,5 @@
 		void initialize(char* fileName);
 
-		GLUquadricObj*			sphereObj;		// A Placeholder for the Sphere.
+		// GLUquadricObj*		sphereObj;		// A Placeholder for the Sphere.
 		Material*			cloudMaterial;		// A Material for the Sphere.
 		float				sphereRadius;		// Radius of the Sphere.
@@ -51,4 +54,13 @@
 		inline void setCloudAnimation(float speed) { this->cloudSpeed = speed; }
 
+		Sglmodel_sgl g_sky_model;
+		Shader* skyShader;
+
+		float g_tint[4];
+		float g_scroll;
+
+		float time;
+
+
 };
 
Index: /branches/atmospheric_engine/src/lib/graphics/effects/sglmodel.h
===================================================================
--- /branches/atmospheric_engine/src/lib/graphics/effects/sglmodel.h	(revision 8175)
+++ /branches/atmospheric_engine/src/lib/graphics/effects/sglmodel.h	(revision 8175)
@@ -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
