Merge branch 'master' into i915-unification
[mesa.git] / progs / demos / fire.c
index 6bf39a57b78ec9e2f315d8cfd231f86951bf5956..dd70f6141dba4817452073aeb7a55cbf45fff744 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include <math.h>
 #include <time.h>
+#include <string.h>
 
 #ifdef WIN32
 #include <windows.h>
@@ -17,7 +18,7 @@
 #endif
 
 #include <GL/glut.h>
-#include "../util/readtex.c"
+#include "readtex.h"
 
 #ifdef XMESA
 #include "GL/xmesa.h"
@@ -71,7 +72,10 @@ static int fullscreen = 1;
 static int WIDTH = 640;
 static int HEIGHT = 480;
 
-#define FRAME 50
+static GLint T0 = 0;
+static GLint Frames = 0;
+static GLint NiceFog = 1;
+
 #define DIMP 20.0
 #define DIMTP 16.0
 
@@ -95,8 +99,8 @@ part;
 static float treepos[NUMTREE][3];
 
 static float black[3] = { 0.0, 0.0, 0.0 };
-static float blu[3] = { 0.0, 0.2, 1.0 };
-static float blu2[3] = { 0.0, 1.0, 1.0 };
+static float blu[3] = { 1.0, 0.2, 0.0 };
+static float blu2[3] = { 1.0, 1.0, 0.0 };
 
 static float fogcolor[4] = { 1.0, 1.0, 1.0, 1.0 };
 
@@ -133,24 +137,9 @@ static GLuint treeid;
 static float obs[3] = { 2.0, 1.0, 0.0 };
 static float dir[3];
 static float v = 0.0;
-static float alpha = -90.0;
+static float alpha = -84.0;
 static float beta = 90.0;
 
-static float
-gettime(void)
-{
-   static clock_t told = 0;
-   clock_t tnew, ris;
-
-   tnew = clock();
-
-   ris = tnew - told;
-
-   told = tnew;
-
-   return (ris / (float) CLOCKS_PER_SEC);
-}
-
 static float
 vrnd(void)
 {
@@ -269,6 +258,13 @@ calcposobs(void)
    dir[2] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
    dir[1] = cos(beta * M_PI / 180.0);
 
+   if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5)
+      dir[0] = 0;
+   if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5)
+      dir[1] = 0;
+   if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5)
+      dir[2] = 0;
+
    obs[0] += v * dir[0];
    obs[1] += v * dir[1];
    obs[2] += v * dir[2];
@@ -308,7 +304,7 @@ printhelp(void)
    printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Help");
 
    glRasterPos2i(60, 390);
-   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Togle Help");
+   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "h - Toggle Help");
 
    glRasterPos2i(60, 360);
    printstring(GLUT_BITMAP_TIMES_ROMAN_24, "t - Increase particle size");
@@ -321,9 +317,9 @@ printhelp(void)
    printstring(GLUT_BITMAP_TIMES_ROMAN_24, "R - Decrease emission radius");
 
    glRasterPos2i(60, 240);
-   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Togle Fog");
+   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "f - Toggle Fog");
    glRasterPos2i(60, 210);
-   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "s - Togle shadows");
+   printstring(GLUT_BITMAP_TIMES_ROMAN_24, "s - Toggle shadows");
    glRasterPos2i(60, 180);
    printstring(GLUT_BITMAP_TIMES_ROMAN_24, "Arrow Keys - Rotate");
    glRasterPos2i(60, 150);
@@ -334,7 +330,7 @@ printhelp(void)
    glRasterPos2i(60, 90);
    if (joyavailable)
       printstring(GLUT_BITMAP_TIMES_ROMAN_24,
-                 "j - Togle jostick control (Joystick control available)");
+                 "j - Toggle jostick control (Joystick control available)");
    else
       printstring(GLUT_BITMAP_TIMES_ROMAN_24,
                  "(No Joystick control available)");
@@ -387,13 +383,22 @@ dojoy(void)
 static void
 drawfire(void)
 {
-   static int count = 0;
-   static char frbuf[80];
+   static char frbuf[80] = "";
    int j;
-   float fr;
+   static double t0 = -1.;
+   double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
+   if (t0 < 0.0)
+      t0 = t;
+   dt = (t - t0) * 1.0;
+   t0 = t;
 
    dojoy();
 
+   if (NiceFog)
+      glHint(GL_FOG_HINT, GL_NICEST);
+   else
+      glHint(GL_FOG_HINT, GL_DONT_CARE);
+
    glEnable(GL_DEPTH_TEST);
 
    if (fog)
@@ -416,6 +421,7 @@ drawfire(void)
    glEnable(GL_TEXTURE_2D);
 
    glBindTexture(GL_TEXTURE_2D, groundid);
+#if 1
    glBegin(GL_QUADS);
    glTexCoord2fv(qt[0]);
    glVertex3fv(q[0]);
@@ -426,6 +432,26 @@ drawfire(void)
    glTexCoord2fv(qt[3]);
    glVertex3fv(q[3]);
    glEnd();
+#else
+   /* Subdivide the ground into a bunch of quads.  This improves fog
+    * if GL_FOG_HINT != GL_NICEST
+    */
+   {
+      float x, y;
+      float dx = 1.0, dy = 1.0;
+      glBegin(GL_QUADS);
+      for (y = -DIMP; y < DIMP; y += 1.0) {
+         for (x = -DIMP; x < DIMP; x += 1.0) {
+            glTexCoord2f(0, 0);   glVertex3f(x, 0, y);
+            glTexCoord2f(1, 0);   glVertex3f(x+dx, 0, y);
+            glTexCoord2f(1, 1);   glVertex3f(x+dx, 0, y+dy);
+            glTexCoord2f(0, 1);   glVertex3f(x, 0, y+dy);
+         }
+      }
+      glEnd();
+   }
+#endif
+
 
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GEQUAL, 0.9);
@@ -468,11 +494,6 @@ drawfire(void)
    }
    glEnd();
 
-   if ((count % FRAME) == 0) {
-      fr = gettime();
-      sprintf(frbuf, "Frame rate: %f", FRAME / fr);
-   }
-
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_ALPHA_TEST);
    glDisable(GL_DEPTH_TEST);
@@ -499,7 +520,24 @@ drawfire(void)
 
    glutSwapBuffers();
 
-   count++;
+   Frames++;
+   {
+      GLint t = glutGet(GLUT_ELAPSED_TIME);
+      if (t - T0 >= 2000) {
+         GLfloat seconds = (t - T0) / 1000.0;
+         GLfloat fps = Frames / seconds;
+         sprintf(frbuf, "Frame rate: %f", fps);
+         T0 = t;
+         Frames = 0;
+      }
+   }
+}
+
+
+static void
+idle(void)
+{
+   glutPostRedisplay();
 }
 
 
@@ -520,6 +558,7 @@ special(int key, int x, int y)
       beta += 2.0;
       break;
    }
+   glutPostRedisplay();
 }
 
 static void
@@ -531,10 +570,10 @@ key(unsigned char key, int x, int y)
       break;
 
    case 'a':
-      v += 0.01;
+      v += 0.0005;
       break;
    case 'z':
-      v -= 0.01;
+      v -= 0.0005;
       break;
 
    case 'j':
@@ -567,7 +606,12 @@ key(unsigned char key, int x, int y)
       fullscreen = (!fullscreen);
       break;
 #endif
+   case 'n':
+      NiceFog = !NiceFog;
+      printf("NiceFog %d\n", NiceFog);
+      break;
    }
+   glutPostRedisplay();
 }
 
 static void
@@ -597,11 +641,12 @@ inittextures(void)
    glGenTextures(1, &treeid);
    glBindTexture(GL_TEXTURE_2D, treeid);
 
+   if (1)
    {
       int w, h;
       GLenum format;
       int x, y;
-      GLubyte *image = LoadRGBImage("../images/tree2.rgb", &w, &h, &format);
+      GLubyte *image = LoadRGBImage("../images/tree3.rgb", &w, &h, &format);
 
       if (!image) {
         fprintf(stderr, "Error reading a texture.\n");
@@ -622,11 +667,16 @@ inittextures(void)
 
       if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, 128, 128, GL_RGBA,
                                      GL_UNSIGNED_BYTE, (GLvoid *) (tex)))) {
-        fprintf(stderr, "GLULib%s\n", gluErrorString(gluerr));
+        fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr));
+        exit(-1);
+      }
+   }
+   else {
+      if (!LoadRGBMipmaps("../images/tree2.rgba", GL_RGBA)) {
+        fprintf(stderr, "Error reading a texture.\n");
         exit(-1);
       }
    }
-
 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@@ -665,15 +715,13 @@ main(int ac, char **av)
 
    /* Default settings */
 
-   WIDTH = 640;
-   HEIGHT = 480;
    np = 800;
-   eject_r = 0.1;
+   eject_r = -0.65;
    dt = 0.015;
    eject_vy = 4;
    eject_vl = 1;
    shadows = 1;
-   ridtri = 0.1;
+   ridtri = 0.25;
 
    maxage = 1.0 / dt;
 
@@ -710,11 +758,8 @@ main(int ac, char **av)
    glFogi(GL_FOG_MODE, GL_EXP);
    glFogfv(GL_FOG_COLOR, fogcolor);
    glFogf(GL_FOG_DENSITY, 0.1);
-#ifdef FX
-   glHint(GL_FOG_HINT, GL_NICEST);
-#endif
 
-   p = malloc(sizeof(part) * np);
+   p = (part *) malloc(sizeof(part) * np);
 
    for (i = 0; i < np; i++)
       setnewpart(&p[i]);
@@ -724,7 +769,7 @@ main(int ac, char **av)
    glutKeyboardFunc(key);
    glutSpecialFunc(special);
    glutDisplayFunc(drawfire);
-   glutIdleFunc(drawfire);
+   glutIdleFunc(idle);
    glutReshapeFunc(reshape);
    glutMainLoop();