From http://www.jwz.org/xscreensaver/xscreensaver-5.16.tar.gz
[xscreensaver] / hacks / glx / pipes.c
index e47361eaaaf8a1e0fffdacbd1fe3ee4ec8049e4a..104f880be23103df37780f661cb8f04a422a710b 100644 (file)
@@ -49,6 +49,7 @@ static const char sccsid[] = "@(#)pipes.c     4.07 97/11/24 xlockmore";
                                        "*size:                 500     \n"                     \
                        "*showFPS:      False   \n"                 \
                        "*fpsSolid:     True    \n"
+
 # define refresh_pipes 0
 # define pipes_handle_event 0
 # include "xlockmore.h"                                /* from the xscreensaver distribution */
@@ -58,7 +59,21 @@ static const char sccsid[] = "@(#)pipes.c    4.07 97/11/24 xlockmore";
 
 #ifdef USE_GL
 
+#ifdef HAVE_COCOA
+# include "jwxyz.h"
+#else
+# include <X11/Xlib.h>
+# include <GL/gl.h>
+# include <GL/glu.h>
+#endif
+
+#ifdef HAVE_JWZGLES
+# include "jwzgles.h"
+#endif /* HAVE_JWZGLES */
+
+#include "sphere.h"
 #include "buildlwo.h"
+#include "teapot.h"
 
 #define DEF_FACTORY     "2"
 #define DEF_FISHEYE     "True"
@@ -153,7 +168,8 @@ typedef struct {
        const float *system_color;
        GLfloat     initial_rotation;
        GLuint      valve, bolts, betweenbolts, elbowbolts, elbowcoins;
-       GLuint      guagehead, guageface, guagedial, guageconnector;
+       GLuint      guagehead, guageface, guagedial, guageconnector, teapot;
+    int         teapot_polys;
     int         reset;
        GLXContext *glx_context;
 } pipesstruct;
@@ -213,14 +229,22 @@ MakeTube(ModeInfo *mi, int direction)
 }
 
 static void
-mySphere(float radius)
+mySphere(float radius, Bool wire)
 {
+#if 0
        GLUquadricObj *quadObj;
 
        quadObj = gluNewQuadric();
        gluQuadricDrawStyle(quadObj, (GLenum) GLU_FILL);
        gluSphere(quadObj, radius, 16, 16);
        gluDeleteQuadric(quadObj);
+#else
+    glPushMatrix();
+    glScalef (radius, radius, radius);
+    glRotatef (90, 1, 0, 0);
+    unit_sphere (16, 16, wire);
+    glPopMatrix();
+#endif
 }
 
 static void
@@ -461,18 +485,60 @@ MakeGuage(ModeInfo * mi, int newdir)
        return (1);
 }
 
+
+static GLuint
+build_teapot(ModeInfo *mi)
+{
+  pipesstruct *pp = &pipes[MI_SCREEN(mi)];
+  GLuint list = glGenLists(1);
+  if (!list) return 0;
+  glNewList(list, GL_COMPILE);
+  pp->teapot_polys = unit_teapot (12, MI_IS_WIREFRAME(mi));
+  glEndList();
+  return list;
+}
+
+
+static void
+MakeTeapot(ModeInfo * mi, int newdir)
+{
+  pipesstruct *pp = &pipes[MI_SCREEN(mi)];
+
+  switch (newdir) {
+  case dirUP:
+  case dirDOWN:
+    glRotatef(90.0, 1.0, 0.0, 0.0);
+    glRotatef(NRAND(3) * 90.0, 0.0, 0.0, 1.0);
+    break;
+  case dirLEFT:
+  case dirRIGHT:
+    glRotatef(90.0, 0.0, -1.0, 0.0);
+    glRotatef((NRAND(3) * 90.0) - 90.0, 0.0, 0.0, 1.0);
+    break;
+  case dirNEAR:
+  case dirFAR:
+    glRotatef(NRAND(4) * 90.0, 0.0, 0.0, 1.0);
+    break;
+  }
+
+  glCallList(pp->teapot);
+  mi->polygon_count += pp->teapot_polys;
+  glFrontFace(GL_CCW);
+}
+
+
 static void
 MakeShape(ModeInfo * mi, int newdir)
 {
-       switch (NRAND(2)) {
-               case 1:
-                       if (!MakeGuage(mi, newdir))
-                               MakeTube(mi, newdir);
-                       break;
-               default:
-                       MakeValve(mi, newdir);
-                       break;
-       }
+  int n = NRAND(100);
+  if (n < 50) {
+    if (!MakeGuage(mi, newdir))
+      MakeTube(mi, newdir);
+  } else if (n < 98) {
+    MakeValve(mi, newdir);
+  } else {
+    MakeTeapot(mi,newdir);
+  }
 }
 
 static void
@@ -485,7 +551,6 @@ pinit(ModeInfo * mi, int zera)
       mi->polygon_count = 0;
 
        glClearDepth(1.0);
-       glClearColor(0.0, 0.0, 0.0, 1.0);
        glColor3f(1.0, 1.0, 1.0);
 
        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);
@@ -623,6 +688,11 @@ init_pipes (ModeInfo * mi)
        }
        pp = &pipes[screen];
 
+#ifdef HAVE_JWZGLES
+    /* Single-buffering on iOS is so confusing! */
+    dbuf_p = True;
+#endif
+
        pp->window = MI_WINDOW(mi);
        if ((pp->glx_context = init_GL(mi)) != NULL) {
 
@@ -645,6 +715,7 @@ init_pipes (ModeInfo * mi)
                        pp->guageface = BuildLWO(MI_IS_WIREFRAME(mi), &LWO_GuageFace);
                        pp->guagedial = BuildLWO(MI_IS_WIREFRAME(mi), &LWO_GuageDial);
                        pp->guageconnector = BuildLWO(MI_IS_WIREFRAME(mi), &LWO_GuageConnector);
+                       pp->teapot = build_teapot(mi);
                }
                /* else they are all 0, thanks to calloc(). */
 
@@ -679,6 +750,7 @@ draw_pipes (ModeInfo * mi)
 
        Display    *display = MI_DISPLAY(mi);
        Window      window = MI_WINDOW(mi);
+    Bool        wire = MI_IS_WIREFRAME(mi);
 
        int         newdir;
        int         OPX, OPY, OPZ;
@@ -718,7 +790,7 @@ draw_pipes (ModeInfo * mi)
        if (pp->olddir == dirNone) {
                glPushMatrix();
                glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0);
-               mySphere(0.6);
+               mySphere(0.6, wire);
                glPopMatrix();
        }
        /* Check for stop conditions */
@@ -726,7 +798,7 @@ draw_pipes (ModeInfo * mi)
                glPushMatrix();
                glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0);
                /* Finish the system with another sphere */
-               mySphere(0.6);
+               mySphere(0.6, wire);
 
                glPopMatrix();
 
@@ -735,7 +807,7 @@ draw_pipes (ModeInfo * mi)
                if (++pp->system_number > pp->number_of_systems) {
           /* pause doing nothing for N seconds before clearing the screen. */
           int secs = 3;
-          pp->reset = secs * 1000000 / MI_PAUSE(mi);
+          pp->reset = secs * 1000000 / (MI_PAUSE(mi) ? MI_PAUSE(mi) : 100);
                } else {
                        pinit(mi, 0);
                }
@@ -789,7 +861,7 @@ draw_pipes (ModeInfo * mi)
                switch (sysT) {
                        case 1:
                                glTranslatef((pp->PX - 16) / 3.0 * 4.0, (pp->PY - 12) / 3.0 * 4.0, (pp->PZ - 16) / 3.0 * 4.0);
-                               mySphere(elbowradius);
+                               mySphere(elbowradius, wire);
                                break;
                        case 2:
                        case 3:
@@ -964,10 +1036,10 @@ draw_pipes (ModeInfo * mi)
 
        glFlush();
 
+    if (mi->fps_p) do_fps (mi);
+
     if (dbuf_p)
       glXSwapBuffers(display, window);
-
-    if (mi->fps_p) do_fps (mi);
 }
 
 #ifndef STANDALONE
@@ -1019,6 +1091,8 @@ release_pipes (ModeInfo * mi)
                                        glDeleteLists(pp->guagedial, 1);
                                if (pp->guageconnector)
                                        glDeleteLists(pp->guageconnector, 1);
+                               if (pp->teapot)
+                                       glDeleteLists(pp->teapot, 1);
                        }
                }