TP7 : Modélisation d´un liquide
Fichier : 2007/TP/buffer.h #ifndef __buffer_h__
#define __buffer_h__
#pragma once
static struct{
float (*LastBuffer)[MESH_SIZE][3],(*NewBuffer)[MESH_SIZE][3],(*NormalBuffer)[MESH_SIZE][3];
int BufferIndex,Width,Height;
float Mesh[3][MESH_SIZE][MESH_SIZE][3];
} Data={
Data.Mesh[0],Data.Mesh[1],Data.Mesh[2],
0
};
void swapBuffers(void){
Data.BufferIndex^=1;
Data.LastBuffer=Data.Mesh[!Data.BufferIndex];
Data.NewBuffer=Data.Mesh[Data.BufferIndex];
Data.NormalBuffer=Data.Mesh[2];
}
void initBuffer(void){
int i,j;
Data.BufferIndex=1;
swapBuffers();
for (i=0;i<MESH_SIZE;++i)
for (j=0;j<MESH_SIZE;++j){
Data.LastBuffer[i][j][0]=-1+2.*i/(MESH_SIZE-1);
Data.LastBuffer[i][j][1]=-1+2.*j/(MESH_SIZE-1);
Data.LastBuffer[i][j][2]=0;
Data.NewBuffer[i][j][0]=-1+2.*i/(MESH_SIZE-1);
Data.NewBuffer[i][j][1]=-1+2.*j/(MESH_SIZE-1);
Data.NewBuffer[i][j][2]=0;
}
}
#endif Fichier : 2007/TP/water.cpp #include <stdlib.h>
#include <math.h>
#include <assert.h>
#define MESH_SIZE 200
#include "glut_import.h"
#include "buffer.h"
/*********************************************************************
* GLUT CALLBACKS
*********************************************************************/
void reshapeFunc(int width,int height){
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(80,(float) width/height,0.1,20);
Data.Width=width;
Data.Height=height;
}
void displayFunc(void){
int i,j;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,-1.4,0,0,0,0,1,0);
glColor3f(1,1,1);
glEnable(GL_NORMALIZE);
for (i=1;i<MESH_SIZE-2;++i){
glBegin(GL_TRIANGLE_STRIP);
for (j=1;j<MESH_SIZE-1;++j){
glNormal3fv(Data.NormalBuffer[i][j]);
glVertex3fv(Data.NewBuffer[i][j]);
glNormal3fv(Data.NormalBuffer[i+1][j]);
glVertex3fv(Data.NewBuffer[i+1][j]);
}
glEnd();
}
glFlush();
glutSwapBuffers();
}
#define N 10
void keyboardFunc(unsigned char key,int x,int y){
int i=rand() % (MESH_SIZE-2-2*N);
int j=rand() % (MESH_SIZE-2-2*N);
int u,v;
float r;
for (u=-N;u<=N;++u)
for (v=-N;v<=N;++v){
r=u*u+v*v;
if (r<=N*N)
Data.NewBuffer[i+u+1+N][j+v+1+N][2]=0.1*sqrt(N*N-r)/N;
}
}
int coord(int i){
if (i<0)
return 0;
if (i>=MESH_SIZE)
return MESH_SIZE-1;
return i;
}
void calcNormal(void){
int i,j,u,v;
static float U[5][5]={
{ 0,-1, 0 , 1 , 0},
{-1,-2, 0 , 2 , 1},
{-1,-4, 0 , 4 , 1},
{-1,-2, 0 , 2 , 1},
{ 0,-1, 0 , 1 , 0}
};
static float M=MESH_SIZE/12.;//11.;
for (i=0;i<MESH_SIZE;++i)
for (j=0;j<MESH_SIZE;++j){
float su=0,sv=0;
for (u=1;u<4;++u)
for (v=1;v<4;++v){
su+=U[u][v]*Data.NewBuffer[coord(u+i-2)][coord(v+j-2)][2];
sv+=U[v][u]*Data.NewBuffer[coord(u+i-2)][coord(v+j-2)][2];
}
Data.NormalBuffer[i][j][0]=su*M;
Data.NormalBuffer[i][j][1]=sv*M;
Data.NormalBuffer[i][j][2]=-1;
}
}
void idleFunc(void){
static float T[3][3]={
{0.0,1.0,0.0},
{1.0,0.0,1.0},
{0.0,1.0,0.0}
};
swapBuffers();
int i,j,u,v;
float s;
for (i=1;i<MESH_SIZE-1;++i)
for (j=1;j<MESH_SIZE-1;++j){
s=0;
for (u=-1;u<=1;++u)
for (v=-1;v<=1;++v)
s+=Data.LastBuffer[i+u][j+v][2]*T[u+1][v+1];
Data.NewBuffer[i][j][2]=0.98*(0.5*s-Data.NewBuffer[i][j][2]);
}
calcNormal();
glutPostRedisplay();
}
float clamp(float x){
if (x<0 )
return 0;
if (x>1)
return 1;
return x;
}
void motionFunc(int x,int y){
float xx=clamp((float) x/Data.Width);
float yy=clamp((float) y/Data.Height);
int i=(int) ((MESH_SIZE-3-2*N)*(1-xx));
int j=(int) ((MESH_SIZE-3-2*N)*(1-yy));
int u,v;
float r;
for (u=-N;u<=N;++u)
for (v=-N;v<=N;++v){
r=u*u+v*v;
if (r<=N*N){
Data.NewBuffer[i+u+1+N][j+v+1+N][2]=0.2*sqrt(N*N-r)/N;
Data.LastBuffer[i+u+1+N][j+v+1+N][2]=0.2*sqrt(N*N-r)/N;
}
}
}
/*********************************************************************
* MAIN PROGRAM
*********************************************************************/
int main(int argc,char *argv[]){
int a=800,b=600,x,y;
initBuffer();
glutInit(&argc,argv);
x=glutGet(GLUT_SCREEN_WIDTH);
y=glutGet(GLUT_SCREEN_HEIGHT);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition((x-a)/2,(y-b)/2);
glutInitWindowSize(a,b);
glutCreateWindow("Water");
glutReshapeFunc(reshapeFunc);
glutDisplayFunc(displayFunc);
glutKeyboardFunc(keyboardFunc);
glutMotionFunc(motionFunc);
glutIdleFunc(idleFunc);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_MAP2_VERTEX_3);
glutMainLoop();
} Ce document a été traduit de LaTeX par HeVeA |