/**********************************************************************
Foutain + Water Simulation
May, 7th, 2003
This opengl sample was written by Philipp Crocoll
Contact:
philipp.crocoll@web.de
www.codecolony.de
Every comment would be appreciated.
If you want to use parts of any code of mine:
let me know and
use it!
***********************************************************************
Keys to use
===========
1-7 : Re-initialize scene with another shape of the fountain
w,s : move camera forward/backward
a,d : turn camera right/left
r,f : move camera up/down
x,y : turn camera up/down
c,v : strafe left/right
Esc : Exit
How does it work?
=================
The classes CCamera and COGLTexture are described in tutorials on
www.codecolony.de/OpenGL
The files vectors.h/.cpp provide help with vector maths.
The class CPool was made from my SwimmingPool example (also on CodeColony).
The class CAirFountain was made from my Fountain Tutorial (online, too).
Changes in those classes:
-> Fountain gets a "Pool Pointer". Each time a drop falls into the water
(y < 0) I search for the pool's oscillator which is closest to the
drops position. This oscillator is put down a bit (y-value is decreased).
-> When a fountain has many drops, a whole pool area is often put so strongly
down that it is below the bowl and becomes invisible! This is unrealistic
anyway, so the "AffectOscillator" method does not allow to put an oscillator
too deep. The corresponding line of code should be replaced when using
the pool for other purposes.
-> The pool has a kind of damping (which is not physically correct). Otherwise
the waves would become too strong after a while.
The method "RenderBowl" is not very interesting - it simply renders a bowl!
***********************************************************************/
#include <GL\glut.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include "pool.h"
#include "AirFountain.h"
#include "camera.h" //This is my old camera, but it's easier to control
//for the user and the third rotation axis is not required here
#include "textures.h"
//lighting:
GLfloat LightAmbient[]= { 0.2f, 0.2f, 0.2f, 0.0f };
GLfloat LightDiffuse[]= { 0.8f, 0.8f, 0.8f, 0.0f };
GLfloat LightPosition[]= { 1.0f, -0.5f, -0.5f, 0.0f };
//Constants:
#define NUM_X_OSCILLATORS 170
#define NUM_Z_OSCILLATORS 170
#define OSCILLATOR_DISTANCE 0.015
#define OSCILLATOR_WEIGHT 0.0001
#define MAXX (NUM_X_OSCILLATORS*OSCILLATOR_DISTANCE)
#define MAXZ (NUM_Z_OSCILLATORS*OSCILLATOR_DISTANCE)
#define POOL_HEIGHT 0.3
//Camera object:
CCamera Camera;
//The "pool" which represents the water within the fountain bowl
CPool Pool;
//water outside the bowl is in the air:
CAirFountain AirFountain;
//Textures:
COGLTexture WaterTexture; //the image does not contain a water texture,
//but it is applied to the water
COGLTexture RockTexture;
COGLTexture GroundTexture;
bool g_bRain = true;
bool g_bFillModePoints = true;
bool g_bLighting = true;
void KeyDown(unsigned char key, int x, int y)
{
switch(key)
{
case 27: //ESC
exit(0);
break;
case 'a':
Camera.RotateY(5.0f);
break;
case 'd':
Camera.RotateY(-5.0f);
break;
case 'w':
Camera.MoveForwards(-0.15f ) ;
break;
case 's':
Camera.MoveForwards( 0.15f ) ;
break;
case 'x':
Camera.RotateX(5.0f);
break;
case 'y':
Camera.RotateX(-5.0f);
break;
case 'c':
Camera.StrafeRight(-0.05f);
break;
case 'v':
Camera.StrafeRight(0.05f);
break;
case 'f':
Camera.Move(F3dVector(0.0,-0.1,0.0));
break;
case 'r':
Camera.Move(F3dVector(0.0,0.1,0.0));
break;
//*************************************
//Several initialization calls:
case '1':
Pool.Reset();
AirFountain.Delete();
AirFountain.Initialize(3,8,35,76,90,0.5,0.11);
break;
case '2':
Pool.Reset();
AirFountain.Delete();
AirFountain.Initialize(1,20,100,70,70,5.0,0.15);
break;
case '3':
Pool.Reset();
AirFountain.Initialize(1,20,200,85,85,10,0.1);
break;
case '4':
Pool.Reset();
AirFountain.Initialize(5,20,85,90,90,1.0,0.15);
break;
case '5':
Pool.Reset();
AirFountain.Initialize(2,20,50,40,70,1.5,0.2);
break;
case '6':
Pool.Reset();
AirFountain.Initialize(3,50,25,76,90,0.2,0.11);
break;
case '7':
Pool.Reset();
AirFountain.Initialize(4,100,45,76,90,0.2,0.11);
break;
}
}
void RenderBowl(void)
{
float bowlheight = 0.2 + POOL_HEIGHT;
float bowlwidth = 0.2;
float TexBorderDistance = bowlwidth / (MAXX+2*bowlwidth);
GroundTexture.SetActive();
glBegin(GL_QUADS);
float minX = -4.0;
float minZ = -4.0;
float maxX = 8.0;
float maxZ = 8.0;
//******************
//ground
//******************
glNormal3f(0.0f,1.0f,0.0);
glTexCoord2f(0.0,0.0);
glVertex3f(minX,0.0,minZ);
glTexCoord2f(1.0,0.0);
glVertex3f(maxX,0.0,minZ);
glTexCoord2f(1.0,1.0);
glVertex3f(maxX,0.0,maxZ);
glTexCoord2f(0.0,1.0);
glVertex3f(minX,0.0,maxZ);
glEnd();
RockTexture.SetActive();
glBegin(GL_QUADS);
//******************
//top
//******************
glNormal3f(0.0f,1.0f,0.0);
glTexCoord2f(TexBorderDistance,TexBorderDistance);
glVertex3f(0.0f,bowlheight,0.0);
glTexCoord2f(1.0-TexBorderDistance,TexBorderDistance);
glVertex3f(MAXX,bowlheight,0.0);
glTexCoord2f(1.0-TexBorderDistance,0.0);
glVertex3f(MAXX,bowlheight,-bowlwidth);
glTexCoord2f(TexBorderDistance,0.0);
glVertex3f(0.0f,bowlheight,-bowlwidth);
glTexCoord2f(TexBorderDistance,0.0);
glVertex3f(0.0f,bowlheight,-bowlwidth);
glTexCoord2f(0.0,0.0);
glVertex3f(-bowlwidth,bowlheight,-bowlwidth);
glTexCoord2f(0.0,1.0-TexBorderDistance);
glVertex3f(-bowlwidth,bowlheight,MAXZ);
glTexCoord2f(TexBorderDistance,1.0-TexBorderDistance);
glVertex3f(0.0f,bowlheight,MAXZ);
glTexCoord2f(1.0,0.0);
glVertex3f(MAXX+bowlwidth,bowlheight,-bowlwidth);
glTexCoord2f(1.0-TexBorderDistance,0.0);
glVertex3f(MAXX,bowlheight,-bowlwidth);
glTexCoord2f(1.0-TexBorderDistance,1.0-TexBorderDistance);
glVertex3f(MAXX,bowlheight,MAXZ);
glTexCoord2f(1.0,1.0-TexBorderDistance);
glVertex3f(MAXX+bowlwidth,bowlheight,MAXZ);
glTexCoord2f(1.0,1.0-TexBorderDistance);
glVertex3f(MAXX+bowlwidth,bowlheight,MAXZ);
glTexCoord2f(0.0,1.0-TexBorderDistance);
glVertex3f(-bowlwidth,bowlheight,MAXZ);
glTexCoord2f(0.0,1.0);
glVertex3f(-bowlwidth,bowlheight,MAXZ+bowlwidth);
glTexCoord2f(1.0,1.0);
glVertex3f(MAXX+bowlwidth,bowlheight,MAXZ+bowlwidth);
//******************
//front
//******************
glNormal3f(0.0f,0.0f,1.0f);
glTexCoord2f(TexBorderDistance,TexBorderDistance);
glVertex3f(0.0f,bowlheight,0.0);
glTexCoord2f(1.0-TexBorderDistance,TexBorderDistance);
glVertex3f(MAXX,bowlheight,0.0);
glTexCoord2f(1.0-TexBorderDistance,0.0);
glVertex3f(MAXX,0.0f,0.0);
glTexCoord2f(TexBorderDistance,0.0);
glVertex3f(0.0f,0.0f,0.0);
glTexCoord2f(0.0,1.0-TexBorderDistance);
glVertex3f(-bowlwidth,bowlheight,MAXZ+bowlwidth);
glTexCoord2f(1.0,1.0-TexBorderDistance);
glVertex3f(MAXX+bowlwidth,bowlheight,MAXZ+bowlwidth);
glTexCoord2f(1.0,1.0);
glVertex3f(MAXX+bowlwidth,0.0f,MAXZ+bowlwidth);
glTexCoord2f(0.0,1.0);
glVertex3f(-bowlwidth,0.0f,MAXZ+bowlwidth);
//******************
//back
//******************
glNormal3f(0.0,0.0,-1.0f);
glTexCoord2f(TexBorderDistance,TexBorderDistance);
glVertex3f(0.0f,bowlheight,MAXZ);
glTexCoord2f(1.0-TexBorderDistance,TexBorderDistance);
glVertex3f(MAXX,bowlheight,MAXZ);
glTexCoord2f(1.0-TexBorderDistance,0.0);
glVertex3f(MAXX,0.0f,MAXZ);
glTexCoord2f(TexBorderDistance,0.0);
glVertex3f(0
- 1
- 2
- 3
前往页