TP7 : Modélisation d´un liquide
Énoncé :2007/TP/TP7.pdf
Sources :2007/TP/TP7-src.zip
Exécutables pour Windows :2007/TP/TP7-win32exe.zip
#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
#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(); }
Dernière modification le 18/3/2010
Ce document a été traduit de LaTeX par HeVeA