Main Page | Namespace List | Class List | File List | Class Members | File Members

water.cpp File Reference

#include <GL/gl.h>
#include <assert.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <complex>
#include "config.h"
#include "water.h"

Go to the source code of this file.

Typedefs

typedef float normal [3]

Functions

float gethf (int x, int y)
 Get value of the height field at certain coordinate.

const normalgetnormal (int x, int y)
void computeNormal (int x, int y, float &nx, float &ny, float &nz)
 Compute normal to the height field at certain position.

double gauss_rand ()
 Gaussian random number (bad algorithm using the "Gesetz der grossen Zahlen").

complex< float > fourier (float x, float y)
void initWater (int W, int H)
 Initialize the water surface.

float computeHeight (int x, int y, float t)
 Compute the vertex height at a given position and time.

void computeWater (float fTime)
 Compute water vertices and normals at a certain time instant.

float fresnelTerm (float a)
void streamVertex (int x, int y, float xp, float yp, float zoff)
void drawWaterQuad (int x, int y, float xp, float yp)
void drawWaterQuads (const vector< _S_WaterQuad > &water)

Variables

float * g_hf = NULL
normalg_hf_normals = NULL
float * g_hf_fc_re = NULL
float * g_hf_fc_im = NULL
int g_W = 0
int g_H = 0
float g_xe
float g_ye
float g_ze


Typedef Documentation

typedef float normal[3]
 

Definition at line 17 of file water.cpp.

Referenced by computeWater(), drawFaces(), getnormal(), initWater(), and streamVertex().


Function Documentation

float computeHeight int  x,
int  y,
float  t
 

Compute the vertex height at a given position and time.

Definition at line 125 of file water.cpp.

References g_fWaterScale, g_H, g_hf_fc_im, g_hf_fc_re, and g_W.

Referenced by computeWater().

00126 {
00127   float tOff = t*0.1f;
00128   float re = 0.0f;
00129 
00130   const int N = 8;
00131   for (int xc=1; xc<N; xc++) {
00132     for (int yc=1; yc<N; yc++) {
00133       float xp = x/float(g_W);
00134       float yp = y/float(g_H);
00135       float p = 2*M_PI* (xc*(xp+tOff) + yc*(yp+tOff));
00136       int i = xc + yc*g_W;
00137       re += g_hf_fc_re[i]*cos(p) - g_hf_fc_im[i]*sin(p);
00138     }
00139   }
00140   return g_fWaterScale * re / N*N;
00141 }

void computeNormal int  x,
int  y,
float &  nx,
float &  ny,
float &  nz
[inline, static]
 

Compute normal to the height field at certain position.

Definition at line 45 of file water.cpp.

References g_cellsize, g_H, g_W, and gethf().

Referenced by computeWater(), and initHeightField().

00046 {
00047   assert( x>=0 && x<g_W );
00048   assert( y>=0 && y<g_H );
00049 
00050   // Compute normal using forward/backward differences
00051   nx = 0.5f * (gethf( x+1,y ) - gethf( x-1,y )) / g_cellsize;
00052   ny = -1;
00053   nz = 0.5f * (gethf( x,y+1 ) - gethf( x,y-1 )) / g_cellsize;
00054   // Normalize
00055   float len = (float)sqrt( nx*nx + ny*ny + nz*nz );
00056   assert( len != 0 );
00057   nx /= len; ny /= len; nz /= len;
00058 }

void computeWater float  fTime  ) 
 

Compute water vertices and normals at a certain time instant.

Call after camera initialization

Definition at line 145 of file water.cpp.

References computeHeight(), computeNormal(), g_CameraX, g_CameraY, g_CameraZ, g_H, g_hf, g_hf_normals, g_W, g_xe, g_ye, g_ze, and normal.

Referenced by initWater(), and timerCallback().

00146 {
00147   // Compute eye position
00148   g_xe = g_CameraX; // cos( g_fCameraX*M_PI/180.0f ) * g_fViewDistance;
00149   g_ze = g_CameraZ; //sin( g_fCameraX*M_PI/180.0f ) * g_fViewDistance;
00150   g_ye = g_CameraY;//cos( g_fCameraY*M_PI/180.0f ) * g_fViewDistance;
00151 
00152   // Init height field
00153   float *p = g_hf;
00154   for (int y=0; y<g_H; y++) {
00155     for (int x=0; x<g_W; x++) {
00156       *p = computeHeight( x,y, fTime );
00157       p++;
00158     }
00159   }
00160 
00161   // Init normals
00162   normal *pN = g_hf_normals;
00163   for (int y=0; y<g_H; y++) {
00164     for (int x=0; x<g_W; x++) {
00165       computeNormal( x,y, (*pN)[0], (*pN)[1], (*pN)[2] );
00166       pN++;
00167     }
00168   }
00169 }

void drawWaterQuad int  x,
int  y,
float  xp,
float  yp
 

Definition at line 233 of file water.cpp.

References g_cellsize, g_fHeightScale, g_waterlevel, and streamVertex().

Referenced by drawWaterQuads().

00234 {
00235   // Compute water surface base z coord
00236   float zOff = g_waterlevel * g_fHeightScale;
00237   streamVertex( x  ,y+1, xp           , yp+g_cellsize,zOff );
00238   streamVertex( x+1,y+1, xp+g_cellsize, yp+g_cellsize,zOff );
00239   streamVertex( x+1,y  , xp+g_cellsize, yp           ,zOff );
00240   streamVertex( x  ,y  , xp           , yp           ,zOff );
00241 }

void drawWaterQuads const vector< _S_WaterQuad > &  water  ) 
 

Definition at line 244 of file water.cpp.

References drawWaterQuad().

00245 {
00246   /*if (g_bSkymap) {
00247     // Setup sky map as reflection texture
00248     glBindTexture( GL_TEXTURE_CUBE_MAP, cubeMap() );
00249     glEnable( GL_TEXTURE_CUBE_MAP );
00250     
00251     // Texture environment: MODULATE RGB, REPLACE ALPHA
00252     // Set up texture function for RGB and alpha channel
00253     glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE );
00254     glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE );
00255     glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE );
00256     // Multiply the RGB components of the texture and the primary color
00257     glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT );
00258     glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR );
00259     glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE );
00260     glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR );
00261     // Replace the alpha component
00262     glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_PREVIOUS_EXT );
00263     glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA );
00264   }
00265 */
00266   // Enable blending
00267   glEnable( GL_BLEND );
00268 
00269   // Render surface
00270   vector<_S_WaterQuad>::const_iterator it = water.begin();
00271   glBegin( GL_QUADS );
00272   while ( it != water.end() ) {
00273     drawWaterQuad( (*it).x, (*it).y, (*it).xp, (*it).yp );
00274     it++;
00275   }
00276   glEnd();
00277 
00278   // Reset old GL State
00279   glDisable( GL_BLEND );
00280   glDisable( GL_TEXTURE_CUBE_MAP );
00281 }

complex<float> fourier float  x,
float  y
 

Definition at line 75 of file water.cpp.

References gauss_rand().

Referenced by initWater().

00076 {
00077   const float windx = 1.0;
00078   const float windy = 0.8;
00079   const float gravity = 9.81;
00080   float wind_speed2 = windx*windx + windy*windy;
00081 
00082   float k2 = x*x + y*y;;
00083   float f1 = exp( -0.5*gravity*gravity / (k2 * wind_speed2 * wind_speed2)  );
00084   float f2 = abs(x*windx + y*windy) / k2;
00085   float phillips = f1*f2;
00086 
00087   return float(1.0 / sqrt(2.0)) * complex<float>( gauss_rand(), gauss_rand() ) * phillips;
00088 }

float fresnelTerm float  a  )  [inline]
 

Definition at line 173 of file water.cpp.

Referenced by streamVertex().

00174 {
00175   // Compute angle between normal and incoming ray
00176   float b = 1.0f / (1.0f+a);
00177   return b*b;
00178 }

double gauss_rand  ) 
 

Gaussian random number (bad algorithm using the "Gesetz der grossen Zahlen").

Definition at line 64 of file water.cpp.

Referenced by fourier().

00065 {
00066   int nSum = 0;
00067   for (unsigned i=0; i<100; i++) {
00068     nSum += (rand()%2);
00069   }
00070   return double(nSum-50) / 25.0;
00071 }

float gethf int  x,
int  y
[inline, static]
 

Get value of the height field at certain coordinate.

Definition at line 29 of file water.cpp.

References g_H, g_hf, and g_W.

Referenced by averageHeight(), computeNormal(), display(), drawModel(), gethfVertexData(), initGL(), initHeightField(), streamVertex(), and timerCallback().

00029                                           {
00030   while (x<0) x += g_W;
00031   while (y<0) y += g_H;
00032   return g_hf[ (x%g_W) + (y%g_H)*g_W ];
00033 }

const normal& getnormal int  x,
int  y
[inline, static]
 

Definition at line 35 of file water.cpp.

References g_H, g_hf_normals, g_W, and normal.

Referenced by streamVertex().

00036 {
00037   while (x<0) x += g_W;
00038   while (y<0) y += g_H;
00039   return g_hf_normals[ (x%g_W) + (y%g_H)*g_W ];
00040 }

void initWater int  W,
int  H
 

Initialize the water surface.

Definition at line 93 of file water.cpp.

References computeWater(), fourier(), g_H, g_hf, g_hf_fc_im, g_hf_fc_re, g_hf_normals, g_W, and normal.

Referenced by initGL().

00094 {
00095   // Validate params
00096   assert( W>0 && W*H > 0 );
00097   // Clear old data
00098   delete[] g_hf;
00099   delete[] g_hf_normals;
00100   delete[] g_hf_fc_re;
00101   delete[] g_hf_fc_im;
00102 
00103   // Init new data
00104   g_W = W;
00105   g_H = H;
00106   g_hf = new float[W*H];
00107   g_hf_normals = new normal[W*H];
00108   g_hf_fc_re = new float[W*H];
00109   g_hf_fc_im = new float[W*H];
00110 
00111   for (int x=0; x<g_W; x++) {
00112     for (int y=0; y<g_H; y++) {
00113       complex<float> fc = fourier( x,y );
00114       g_hf_fc_re[x+y*g_W] = real(fc);
00115       g_hf_fc_im[x+y*g_W] = imag(fc);
00116     }
00117   }
00118   g_hf_fc_re[0] = 0;
00119   g_hf_fc_im[0] = 0;
00120 
00121   computeWater( 0.0f );
00122 }

void streamVertex int  x,
int  y,
float  xp,
float  yp,
float  zoff
[inline]
 

Definition at line 181 of file water.cpp.

References colorSky, colorWaterGreen, day, fresnelTerm(), g_bFresnel, g_xe, g_ye, g_ze, gethf(), getnormal(), and normal.

Referenced by drawHeightField(), drawMultipassQuad(), and drawWaterQuad().

00182 {
00183   // Get normal
00184   const normal& n = getnormal( x,y );
00185   // Compute color and fresnel term
00186   float col[4];
00187 /*  if (g_bSkymap) {
00188     col[0] = 0.6;//colorSky[0]; 
00189     col[1] = 0.6;//colorSky[1]; 
00190     col[2] = 0.8;//colorSky[2];
00191   }
00192   else {*/
00193 if (day)
00194     {
00195     col[0] = colorSky[0];//White[0]; 
00196     col[1] = colorSky[1]; 
00197     col[2] = colorSky[2]; 
00198     }
00199 else
00200     {
00201     col[0] = colorWaterGreen[0];//White[0]; 
00202     col[1] = colorWaterGreen[1]; 
00203     col[2] = colorWaterGreen[2]; 
00204     }
00205 
00206   float zp = zoff + gethf(x,y);
00207 
00208   float ex = g_xe-xp; float ez = g_ye-yp; float ey = g_ze-zp;
00209   float l = sqrt( ex*ex + ey*ey + ez*ez );
00210   ex /= l; ey /= l; ez /= l;
00211   float a = ex*n[0] + ey*n[1] + ez*n[2];
00212   if (g_bFresnel) {
00213     col[3] = fresnelTerm( a );
00214   }
00215   else {
00216     col[3] = 0.5f;
00217   }
00218 
00219   // Compute the reflected ray and use as texture coord for
00220   // the sky map.
00221     float rx = -ex + 2*a*n[0];
00222     float ry = -ey + 2*a*n[1];
00223     float rz = -ez + 2*a*n[2];
00224     glTexCoord3f( rx,ry,rz );
00225 
00226   glColor4fv( col );
00227   glNormal3fv( n );
00228   glVertex3f( xp, zp, yp );
00229 }


Variable Documentation

int g_H = 0 [static]
 

Definition at line 23 of file water.cpp.

Referenced by computeHeight(), computeNormal(), computeWater(), gethf(), getnormal(), and initWater().

float* g_hf = NULL [static]
 

Definition at line 18 of file water.cpp.

Referenced by computeWater(), gethf(), and initWater().

float* g_hf_fc_im = NULL [static]
 

Definition at line 21 of file water.cpp.

Referenced by computeHeight(), and initWater().

float* g_hf_fc_re = NULL [static]
 

Definition at line 20 of file water.cpp.

Referenced by computeHeight(), and initWater().

normal* g_hf_normals = NULL [static]
 

Definition at line 19 of file water.cpp.

Referenced by computeWater(), getnormal(), and initWater().

int g_W = 0 [static]
 

Definition at line 22 of file water.cpp.

Referenced by computeHeight(), computeNormal(), computeWater(), gethf(), getnormal(), and initWater().

float g_xe [static]
 

Definition at line 25 of file water.cpp.

Referenced by computeWater(), and streamVertex().

float g_ye [static]
 

Definition at line 25 of file water.cpp.

Referenced by computeWater(), and streamVertex().

float g_ze [static]
 

Definition at line 25 of file water.cpp.

Referenced by computeWater(), and streamVertex().


Generated on Thu Jan 20 02:46:59 2005 for Main_Demo by doxygen 1.3.6