Initialize libbullet git in 2.0_beta.
[platform/upstream/libbullet.git] / Extras / sph / main.cpp
1 /*
2   FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
3   Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
4
5   ZLib license
6   This software is provided 'as-is', without any express or implied
7   warranty.  In no event will the authors be held liable for any damages
8   arising from the use of this software.
9
10   Permission is granted to anyone to use this software for any purpose,
11   including commercial applications, and to alter it and redistribute it
12   freely, subject to the following restrictions:
13
14   1. The origin of this software must not be misrepresented; you must not
15      claim that you wrote the original software. If you use this software
16      in a product, an acknowledgment in the product documentation would be
17      appreciated but is not required.
18   2. Altered source versions must be plainly marked as such, and must not be
19      misrepresented as being the original software.
20   3. This notice may not be removed or altered from any source distribution.
21 */
22
23 #include <time.h>
24 #include <math.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28
29 #include "common_defs.h"
30
31 #ifdef BUILD_CUDA
32         #include "fluid_system_host.cuh"        
33 #endif
34 #include "fluid_system.h"
35 #include "gl_helper.h"
36
37 #ifdef _MSC_VER                                         // Windows
38         #include <gl/glut.h>
39 #else                                                           // Linux
40         #include <GL/glut.h>    
41 #endif
42
43 bool bTiming = false;
44 bool bRec = false;
45 int mFrame = 0;
46
47 // Globals
48 FluidSystem                     psys;
49
50 float window_width  = 1024;
51 float window_height = 768;
52
53 Vector3DF       cam_from, cam_angs, cam_to;                     // Camera stuff
54 Vector3DF       obj_from, obj_angs, obj_dang;
55 Vector3DF       light[2], light_to[2];                          // Light stuff
56 float           light_fov, cam_fov;     
57
58 int             psys_rate = 0;                                                  // Particle stuff
59 int             psys_freq = 1;
60 int             psys_demo = 0;
61 int             psys_nmax = 4096;
62
63 bool    bHelp = false;                                          // Toggles
64 int             iShade = 1;                     
65 int             iClrMode = 0;
66 bool    bPntDraw = false;
67 bool    bPause = false;
68
69 // View matricies
70 float view_matrix[16];                                  // View matrix (V)
71 float model_matrix[16];                                 // Model matrix (M)
72 float proj_matrix[16];                                  // Projective matrix
73
74 // Mouse control
75 #define DRAG_OFF                0                               // mouse states
76 #define DRAG_LEFT               1
77 #define DRAG_RIGHT              2
78 int             last_x = -1, last_y = -1;               // mouse vars
79 int             mode = 0;
80 int             dragging = 0;
81 int             psel;
82
83 GLuint  screen_id;
84 GLuint  depth_id;
85
86
87 // Different things we can move around
88 #define MODE_CAM                0
89 #define MODE_CAM_TO             1
90 #define MODE_OBJ                2
91 #define MODE_OBJPOS             3
92 #define MODE_OBJGRP             4
93 #define MODE_LIGHTPOS   5
94
95 #define MODE_DOF                6
96
97 GLuint screenBufferObject;
98 GLuint depthBufferObject;
99 GLuint envid;
100
101 void drawScene ( float* viewmat, bool bShade )
102 {
103         if ( iShade <= 1 && bShade ) {          
104                 glEnable ( GL_LIGHT0 );
105                 GLfloat diff[4];
106                 GLfloat spec[4];
107                 GLfloat shininess = 60.0;
108                 
109                 diff[0] = 0.8f; diff[1] = 0.8f; diff[2] = 0.8f; diff[3] = 1.0f;
110                 spec[0] = 1.0f; spec[1] = 1.0f; spec[2] = 1.0f; spec[3] = 1.0f;
111                 glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, &diff[0]);
112                 glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, &spec[0]);
113                 glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &shininess);             
114                 glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
115
116                 glColor3f ( 1, 1, 1 );
117                 glLoadMatrixf ( viewmat );
118                 glBegin ( GL_QUADS );
119                 glNormal3f ( 0, 0, 1 );
120                 glVertex3f ( -1000, -1000, 0.0 );
121                 glVertex3f ( 1000, -1000, 0.0 );
122                 glVertex3f ( 1000, 1000, 0.0 );
123                 glVertex3f ( -1000, 1000, 0.0 );
124                 glEnd ();
125                 glBegin ( GL_LINES );
126                 for (float n=-100; n <= 100; n += 20.0 ) {
127                         glVertex3f ( -100, n, 0.1 );
128                         glVertex3f ( 100, n, 0.1 );
129                         glVertex3f ( n, -100, 0.1 );
130                         glVertex3f ( n,  100, 0.1 );
131                 }
132                 glEnd ();
133
134                 psys.Draw ( &viewmat[0], 0.8 );                         // Draw particles               
135
136         } else {
137                 glDisable ( GL_LIGHTING );
138                 psys.Draw ( &viewmat[0], 0.55 );                        // Draw particles
139         }
140 }
141
142 void draw2D ()
143 {
144         
145         mint::Time start, stop;
146
147         #ifdef USE_SHADOWS
148                 disableShadows ();
149         #endif
150         glDisable ( GL_LIGHTING );  
151         glDisable ( GL_DEPTH_TEST );
152
153         glMatrixMode ( GL_PROJECTION );
154         glLoadIdentity ();  
155         glScalef ( 2.0/window_width, -2.0/window_height, 1 );           // Setup view (0,0) to (800,600)
156         glTranslatef ( -window_width/2.0, -window_height/2, 0.0);
157
158         glMatrixMode ( GL_MODELVIEW );
159         glLoadIdentity ();
160         glPushMatrix (); 
161         glGetFloatv ( GL_MODELVIEW_MATRIX, view_matrix ); 
162         glPopMatrix (); 
163
164         char disp[200];
165         glColor4f ( 1.0, 1.0, 1.0, 1.0 );
166
167         strcpy ( disp, "Press H for help." );           drawText ( 10, 20, disp );  
168
169         if ( bHelp ) {  
170
171                 if ( psys.GetToggle ( USE_CUDA ) ) {
172                         sprintf ( disp, "Kernel:  USING CUDA (GPU)" );                          drawText ( 20, 40,  disp );     
173                 } else {
174                         sprintf ( disp, "Kernel:  USING CPU" );                         drawText ( 20, 40,  disp );
175                 }               
176
177                 sprintf ( disp, "KEYBOARD" );                                           drawText ( 20, 60,  disp );
178                 sprintf ( disp, "[ ]    Next/Prev Demo" );                      drawText ( 20, 70,  disp );
179                 sprintf ( disp, "N M    Adjust Max Particles" );        drawText ( 20, 80,  disp );
180                 sprintf ( disp, "space  Pause" );                                       drawText ( 20, 90,  disp );
181                 sprintf ( disp, "S      Shading mode" );                        drawText ( 20, 100,  disp );    
182                 sprintf ( disp, "G      Toggle CUDA vs CPU" );          drawText ( 20, 110,  disp );    
183                 sprintf ( disp, "< >    Change emitter rate" );         drawText ( 20, 120,  disp );    
184                 sprintf ( disp, "C      Move camera /w mouse" );        drawText ( 20, 130,  disp );    
185                 sprintf ( disp, "I      Move emitter /w mouse" );       drawText ( 20, 140,  disp );    
186                 sprintf ( disp, "O      Change emitter angle" );        drawText ( 20, 150,  disp );    
187                 sprintf ( disp, "L      Move light /w mouse" );                         drawText ( 20, 160,  disp );                    
188                 sprintf ( disp, "X      Draw velocity/pressure/color" );        drawText ( 20, 170,  disp );
189
190                 Vector3DF vol = psys.GetVec(SPH_VOLMAX);
191                 vol -= psys.GetVec(SPH_VOLMIN);
192                 sprintf ( disp, "Volume Size:           %3.5f %3.2f %3.2f", vol.x, vol.y, vol.z );      drawText ( 20, 190,  disp );
193                 sprintf ( disp, "Time Step (dt):        %3.5f", psys.GetDT () );                                        drawText ( 20, 200,  disp );
194                 sprintf ( disp, "Num Particles:         %d", psys.NumPoints() );                                        drawText ( 20, 210,  disp );            
195                 sprintf ( disp, "Simulation Scale:      %3.5f", psys.GetParam(SPH_SIMSIZE) );           drawText ( 20, 220,  disp );
196                 sprintf ( disp, "Simulation Size (m):   %3.5f", psys.GetParam(SPH_SIMSCALE) );          drawText ( 20, 230,  disp );
197                 sprintf ( disp, "Smooth Radius (m):     %3.3f", psys.GetParam(SPH_SMOOTHRADIUS) );      drawText ( 20, 240,  disp );
198                 sprintf ( disp, "Particle Radius (m):   %3.3f", psys.GetParam(SPH_PRADIUS) );           drawText ( 20, 250,  disp );
199                 sprintf ( disp, "Particle Mass (kg):    %0.8f", psys.GetParam(SPH_PMASS) );                     drawText ( 20, 260,  disp );
200                 sprintf ( disp, "Rest Density (kg/m^3): %3.3f", psys.GetParam(SPH_RESTDENSITY) );       drawText ( 20, 270,  disp );
201                 sprintf ( disp, "Viscosity:             %3.3f", psys.GetParam(SPH_VISC) );                      drawText ( 20, 280,  disp );
202                 sprintf ( disp, "Internal Stiffness:    %3.3f", psys.GetParam(SPH_INTSTIFF) );          drawText ( 20, 290,  disp );
203                 sprintf ( disp, "Boundary Stiffness:    %6.0f", psys.GetParam(SPH_EXTSTIFF) );          drawText ( 20, 300,  disp );
204                 sprintf ( disp, "Boundary Dampening:    %4.3f", psys.GetParam(SPH_EXTDAMP) );           drawText ( 20, 310,  disp );
205                 sprintf ( disp, "Speed Limiting:        %4.3f", psys.GetParam(SPH_LIMIT) );                     drawText ( 20, 320,  disp );
206                 vol = psys.GetVec ( PLANE_GRAV_DIR );
207                 sprintf ( disp, "Gravity:               %3.2f %3.2f %3.2f", vol.x, vol.y, vol.z );      drawText ( 20, 330,  disp );
208         }
209 }
210
211 void computeFromPositions ()
212 {
213         cam_from.x = cam_to.x + sin( cam_angs.x * DEGtoRAD) * sin( cam_angs.y * DEGtoRAD) * cam_angs.z;
214         cam_from.y = cam_to.y + -cos( cam_angs.x * DEGtoRAD) * sin( cam_angs.y * DEGtoRAD) * cam_angs.z;
215         cam_from.z = cam_to.z + cos( cam_angs.y * DEGtoRAD) * cam_angs.z;       
216 }
217
218 void computeProjection ()
219 {
220         // ---- Create projection matrix for eye-coordinate transformations 
221         glMatrixMode( GL_PROJECTION );
222         glLoadIdentity();
223         gluPerspective ( cam_fov, window_width / ( float ) window_height, 10.0, 800.0 );
224         glPushMatrix (); 
225         glGetFloatv ( GL_MODELVIEW_MATRIX, proj_matrix ); 
226         glPopMatrix ();
227 }
228
229 void computeView ()
230 {
231         glMatrixMode ( GL_MODELVIEW );
232         glLoadIdentity ();
233         gluLookAt ( cam_from.x, cam_from.y, cam_from.z, cam_to.x, cam_to.y, cam_to.z, 0, 0, 1 );
234         glPushMatrix (); 
235         glGetFloatv ( GL_MODELVIEW_MATRIX, view_matrix ); 
236         glPopMatrix ();
237 }       
238
239 int frame;
240
241 void display () 
242 {
243         mint::Time start, stop; 
244
245 //      iso = sin(frame*0.01f );
246         
247         // Do simulation!
248         if ( !bPause ) psys.Run ();
249
250         frame++;
251         measureFPS ();
252
253         glEnable ( GL_DEPTH_TEST );
254
255         // Render depth map shadows
256         start.SetSystemTime ( ACC_NSEC );
257         disableShadows ();
258         #ifdef USE_SHADOWS
259                 if ( iShade==1 ) {
260                         renderDepthMap_FrameBuffer ( 0, window_width, window_height );
261                 } else {
262                         renderDepthMap_Clear ( window_width, window_height );           
263                 }
264         #endif  
265
266         // Clear frame buffer
267         if ( iShade<=1 )        glClearColor( 0.29, 0.29, 0.29, 1.0 );
268         else                            glClearColor ( 0, 0, 0, 0 );
269         glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
270         glDisable ( GL_CULL_FACE );
271         glShadeModel ( GL_SMOOTH );
272
273         // Compute camera view
274         computeFromPositions ();
275         computeProjection ();
276         computeView ();         
277
278         // Draw Shadows (if on)
279         #ifdef USE_SHADOWS      
280                 if ( iShade==1 )        renderShadows ( view_matrix );                  
281         #endif
282
283         // Draw 3D      
284         start.SetSystemTime ( ACC_NSEC );
285         glEnable ( GL_LIGHTING );  
286         glLoadMatrixf ( view_matrix );  
287         drawScene ( view_matrix, true );
288         if ( bTiming) { stop.SetSystemTime ( ACC_NSEC ); stop = stop - start; printf ( "SCENE: %s\n", stop.GetReadableTime().c_str() ); }
289
290         // Draw 2D overlay
291         draw2D ();
292  
293         // Swap buffers
294         glutSwapBuffers();  
295         glutPostRedisplay();
296 }
297
298 void reshape ( int width, int height ) 
299 {
300   // set window height and width
301   window_width  = (float) width;
302   window_height = (float) height;
303   glViewport( 0, 0, width, height );  
304 }
305
306 void UpdateEmit ()
307 {       
308         obj_from = psys.GetVec ( EMIT_POS );
309         obj_angs = psys.GetVec ( EMIT_ANG );
310         obj_dang = psys.GetVec ( EMIT_RATE );
311 }
312
313
314 void keyboard_func ( unsigned char key, int x, int y )
315 {
316         switch( key ) {
317         case 'M': case 'm': {
318                 psys_nmax *= 2;
319                 if ( psys_nmax > 65535 ) psys_nmax = 65535;             
320                 psys.SPH_CreateExample ( psys_demo, psys_nmax );
321                 } break;
322         case 'N': case 'n': {
323                 psys_nmax /= 2;
324                 if ( psys_nmax < 64 ) psys_nmax = 64;           
325                 psys.SPH_CreateExample ( psys_demo, psys_nmax );
326                 } break;
327         case '0':
328                 UpdateEmit ();
329                 psys_freq++;    
330                 psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
331                 break;  
332         case '9':
333                 UpdateEmit ();
334                 psys_freq--;  if ( psys_freq < 0 ) psys_freq = 0;
335                 psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
336                 break;
337         case '.': case '>':
338                 UpdateEmit ();
339                 if ( ++psys_rate > 100 ) psys_rate = 100;
340                 psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
341                 break;
342         case ',': case '<':
343                 UpdateEmit ();
344                 if ( --psys_rate < 0 ) psys_rate = 0;
345                 psys.SetVec ( EMIT_RATE, Vector3DF(psys_freq, psys_rate, 0) );
346         break;
347         case 'g': case 'G':     psys.Toggle ( USE_CUDA );       break;
348         case 'f': case 'F':     mode = MODE_DOF;        break;
349
350         case 'z': case 'Z':     mode = MODE_CAM_TO;     break;
351         case 'c': case 'C':     mode = MODE_CAM;        break; 
352         case 'h': case 'H':     bHelp = !bHelp; break;
353         case 'i': case 'I':     
354                 UpdateEmit ();
355                 mode = MODE_OBJPOS;     
356                 break;
357         case 'o': case 'O':     
358                 UpdateEmit ();
359                 mode = MODE_OBJ;
360                 break;  
361         case 'x': case 'X':
362                 if ( ++iClrMode > 2) iClrMode = 0;
363                 psys.SetParam ( CLR_MODE, iClrMode );
364                 break;
365         case 'l': case 'L':     mode = MODE_LIGHTPOS;   break;
366         case 'd': case 'D': {
367                 int d = psys.GetParam ( PNT_DRAWMODE ) + 1;
368                 if ( d > 2 ) d = 0;
369                 psys.SetParam ( PNT_DRAWMODE, d );
370                 } break;        
371         case 's': case 'S':     if ( ++iShade > 2 ) iShade = 0;         break;
372         case 27:                            exit( 0 ); break;
373         
374         case '`':
375                 bRec = !bRec; break;
376
377         case ' ':               
378                 //psys.Run (); ptris.Rebuild (); break;
379                 bPause = !bPause;       break;
380
381         case '\'': case ';':    psys.SPH_CreateExample ( psys_demo, psys_nmax ); break;
382         case 'r': case 'R':             psys.SPH_CreateExample ( psys_demo, psys_nmax ); break;  
383         case '[':
384                 psys_demo--;
385                 if (psys_demo < 0 ) psys_demo = 10;
386                 psys.SPH_CreateExample ( psys_demo, psys_nmax );
387                 UpdateEmit ();
388                 break;
389         case ']':
390                 psys_demo++;
391                 if (psys_demo > 10 ) psys_demo = 0;
392                 psys.SPH_CreateExample ( psys_demo, psys_nmax );
393                 UpdateEmit ();
394                 break;  
395         default:
396         break;
397   }
398 }
399
400
401 void mouse_click_func ( int button, int state, int x, int y )
402 {
403   if( state == GLUT_DOWN ) {
404     if ( button == GLUT_LEFT_BUTTON )           dragging = DRAG_LEFT;
405     else if ( button == GLUT_RIGHT_BUTTON ) dragging = DRAG_RIGHT;      
406     last_x = x;
407     last_y = y; 
408   } else {
409     dragging = DRAG_OFF;
410   }
411 }
412
413 void mouse_move_func ( int x, int y )
414 {
415         int dx = x - last_x;
416         int dy = y - last_y;
417
418         switch ( mode ) {
419         case MODE_CAM:
420                 if ( dragging == DRAG_LEFT ) {
421                         cam_angs.x += dx;
422                         cam_angs.y += dy;
423                         if ( cam_angs.x >= 360.0 )      cam_angs.x -= 360.0;
424                         if ( cam_angs.x < 0 )           cam_angs.x += 360.0;
425                         if ( cam_angs.y >= 180.0 )      cam_angs.y = 180.0;
426                         if ( cam_angs.y <= -180.0 )     cam_angs.y = -180.0;
427                         printf ( "Cam Ang: %f %f %f\n", cam_angs.x, cam_angs.y, cam_angs.z );
428                         printf ( "Cam To:  %f %f %f\n", cam_to.x, cam_to.y, cam_to.z );
429                         printf ( "Cam FOV: %f\n", cam_fov);
430                 } else if ( dragging == DRAG_RIGHT ) {
431                         cam_angs.z += dy*.15;
432                         if ( cam_angs.z < 0)            cam_angs.z = 0;
433                         printf ( "Cam Ang: %f %f %f\n", cam_angs.x, cam_angs.y, cam_angs.z );
434                         printf ( "Cam To:  %f %f %f\n", cam_to.x, cam_to.y, cam_to.z );
435                         printf ( "Cam FOV: %f\n", cam_fov );
436                 }
437                 break;
438         case MODE_CAM_TO:
439                 if ( dragging == DRAG_LEFT ) {
440                         cam_to.x += dx;
441                         cam_to.y += dy;                 
442                 } else if ( dragging == DRAG_RIGHT ) {
443                         cam_to.z += dy*.05;
444                         if ( cam_to.z < 0)      cam_to.z = 0;
445                 }
446                 break;  
447         case MODE_OBJ:
448                 if ( dragging == DRAG_LEFT ) {
449                         obj_angs.x -= dx*0.1;
450                         obj_angs.y += dy*0.1;
451                         printf ( "Obj Angs:  %f %f %f\n", obj_angs.x, obj_angs.y, obj_angs.z );
452                         //force_x += dx*.1;
453                         //force_y += dy*.1;
454                 } else if (dragging == DRAG_RIGHT) {
455                         obj_angs.z -= dy*.005;                  
456                         printf ( "Obj Angs:  %f %f %f\n", obj_angs.x, obj_angs.y, obj_angs.z );
457                 }
458                 psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) );
459                 break;
460         case MODE_OBJPOS:
461                 if ( dragging == DRAG_LEFT ) {
462                         obj_from.x -= dx*.1;
463                         obj_from.y += dy*.1;
464                         printf ( "Obj:  %f %f %f\n", obj_from.x, obj_from.y, obj_from.z );
465                 } else if (dragging == DRAG_RIGHT) {
466                         obj_from.z -= dy*.1;
467                         printf ( "Obj:  %f %f %f\n", obj_from.x, obj_from.y, obj_from.z );
468                 }
469                 psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) );
470                 //psys.setPos ( obj_x, obj_y, obj_z, obj_ang, obj_tilt, obj_dist );
471                 break;
472         case MODE_LIGHTPOS:
473                 if ( dragging == DRAG_LEFT ) {
474                         light[0].x -= dx*.1;
475                         light[0].y += dy*.1;            
476                         printf ( "Light: %f %f %f\n", light[0].x, light[0].y, light[0].z );
477                 } else if (dragging == DRAG_RIGHT) {
478                         light[0].z -= dy*.1;                    
479                         printf ( "Light: %f %f %f\n", light[0].x, light[0].y, light[0].z );
480                 }       
481                 #ifdef USE_SHADOWS
482                         setShadowLight ( light[0].x, light[0].y, light[0].z, light_to[0].x, light_to[0].y, light_to[0].z, light_fov );
483                 #endif
484                 break;
485         }
486
487         if ( x < 10 || y < 10 || x > 1000 || y > 700 ) {
488                 glutWarpPointer ( 1024/2, 768/2 );
489                 last_x = 1024/2;
490                 last_y = 768/2;
491         } else {
492                 last_x = x;
493                 last_y = y;
494         }
495 }
496
497
498 void idle_func ()
499 {
500 }
501
502 void init ()
503 {
504         
505         glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 
506         glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);      
507
508         srand ( time ( 0x0 ) );
509
510         glClearColor( 0.49, 0.49, 0.49, 1.0 );
511         glShadeModel( GL_SMOOTH );
512
513         glEnable ( GL_COLOR_MATERIAL );
514         glEnable (GL_DEPTH_TEST);  
515         glEnable (GL_BLEND);
516         glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
517         glDepthMask ( 1 );
518         glEnable ( GL_TEXTURE_2D );
519
520         // callbacks
521         glutDisplayFunc( display );
522         glutReshapeFunc( reshape );
523         glutKeyboardFunc( keyboard_func );
524         glutMouseFunc( mouse_click_func );  
525         glutMotionFunc( mouse_move_func );
526         glutIdleFunc( idle_func );
527         glutSetCursor ( GLUT_CURSOR_NONE );
528
529         cam_angs.x = 29;                cam_angs.y = 75;                cam_angs.z = 80.0;
530         cam_to.x = 0;           cam_to.y = 0;           cam_to.z = 5;
531         cam_fov = 35.0;
532
533         light[0].x = 39;                light[0].y = -60;       light[0].z = 43;
534         light_to[0].x = 0;      light_to[0].y = 0;      light_to[0].z = 0;
535
536         light[1].x = 15;                light[1].y = -5;        light[1].z = 145;       
537         light_to[1].x = 0;      light_to[1].y = 0;      light_to[1].z = 0;  
538
539         light_fov = 45;
540
541         #ifdef USE_SHADOWS
542                 createShadowTextures();
543                 createFrameBuffer ();
544                 setShadowLight ( light[0].x, light[0].y, light[0].z, light_to[0].x, light_to[0].y, light_to[0].z, light_fov );
545                 setShadowLightColor ( .7, .7, .7, 0.2, 0.2, 0.2 );              
546         #endif
547
548         obj_from.x = 0;         obj_from.y = 0;         obj_from.z = 20;                // emitter
549         obj_angs.x = 118.7;     obj_angs.y = 200;       obj_angs.z = 1.0;
550         obj_dang.x = 1; obj_dang.y = 1;         obj_dang.z = 0;
551
552         psys.Initialize ( BFLUID, psys_nmax );
553         psys.SPH_CreateExample ( 0, psys_nmax );
554         psys.SetVec ( EMIT_ANG, Vector3DF ( obj_angs.x, obj_angs.y, obj_angs.z ) );
555         psys.SetVec ( EMIT_POS, Vector3DF ( obj_from.x, obj_from.y, obj_from.z ) );
556
557         psys.SetParam ( PNT_DRAWMODE, int(bPntDraw ? 1:0) );
558         psys.SetParam ( CLR_MODE, iClrMode );   
559 }
560
561
562 int main ( int argc, char **argv )
563 {
564         #ifdef BUILD_CUDA
565                 // Initialize CUDA
566                 cudaInit( argc, argv );
567         #endif
568
569         // set up the window
570         glutInit( &argc, &argv[0] ); 
571         glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
572         glutInitWindowPosition( 100, 100 );
573         glutInitWindowSize( (int) window_width, (int) window_height );
574         glutCreateWindow ( "Fluids v.1 (c) 2008, R. Hoetzlein (ZLib)" );
575
576 //      glutFullScreen ();
577  
578         // initialize parameters
579         init();
580
581         // wait for something to happen
582         glutMainLoop();
583
584   return 0;
585 }
586
587 extern "C" {
588         void btCuda_exit(int val)
589         {
590                 fprintf(stderr, "Press ENTER key to terminate the program\n");
591                 getchar();
592                 exit(val);
593         }
594 }