From http://www.jwz.org/xscreensaver/xscreensaver-5.38.tar.gz
[xscreensaver] / hacks / glx / superquadrics.c
index 68dacee47dc8d396225da5a48d27520a8a11682f..3c0833543deedcefd181a6f37b100540316a65cb 100644 (file)
@@ -75,7 +75,11 @@ static const char sccsid[] = "@(#)superquadrics.c    4.07 97/11/24 xlockmore";
                                        "*count:                25      \n"                     \
                                        "*cycles:               40      \n"                     \
                                        "*showFPS:      False   \n"                     \
-                                       "*wireframe:    False   \n"
+                                       "*wireframe:    False   \n"                     \
+                                       "*suppressRotationAnimation: True\n" \
+
+# define free_superquadrics 0
+# define release_superquadrics 0
 # define superquadrics_handle_event 0
 # include "xlockmore.h"                                /* from the xscreensaver distribution */
 #else  /* !STANDALONE */
@@ -113,7 +117,7 @@ ENTRYPOINT ModeSpecOpt superquadrics_opts =
 
 #ifdef USE_MODULES
 ModStruct   superquadrics_description =
-{"superquadrics", "init_superquadrics", "draw_superquadrics", "release_superquadrics",
+{"superquadrics", "init_superquadrics", "draw_superquadrics", NULL,
  "refresh_superquadrics", "init_superquadrics", NULL, &superquadrics_opts,
  1000, 25, 40, 1, 4, 1.0, "",
  "Shows 3D mathematical shapes", 0, NULL};
@@ -344,12 +348,13 @@ inputs(superquadricsstruct * sp)
 }
 
 
-static void
+static int
 DoneScale(superquadricsstruct * sp)
 {
        double      xx, yy, zz, xp = 0, yp = 0, zp = 0, xn, yn, zn, xnp = 0,
                    ynp = 0, znp = 0;
        int         ih, iv;
+    int polys = 0;
 
        /* Hey don't knock my 2-letter variable names.  Simon's BASIC rules, man! ;-> */
        /* Just kidding..... */
@@ -374,10 +379,12 @@ DoneScale(superquadricsstruct * sp)
                                        if (ih > 1) {
                                                glVertex3f(xx, yy, zz);
                                                glVertex3f(sp->Prevxx[iv], sp->Prevyy[iv], sp->Prevzz[iv]);
+                        polys++;
                                        }
                                        if (iv > 1) {
                                                glVertex3f(xx, yy, zz);
                                                glVertex3f(sp->Prevxx[iv - 1], sp->Prevyy[iv - 1], sp->Prevzz[iv - 1]);
+                        polys++;
                                        }
 /* PURIFY 4.0.1 reports an unitialized memory read on the next line when using
    * MesaGL 2.2 and -mono.  This has been fixed in MesaGL 2.3 and later. */
@@ -406,6 +413,7 @@ DoneScale(superquadricsstruct * sp)
                                        if (!sp->flatshade)
                                                glNormal3f(sp->Prevxn[iv - 1], sp->Prevyn[iv - 1], sp->Prevzn[iv - 1]);
                                        glVertex3f(sp->Prevxx[iv - 1], sp->Prevyy[iv - 1], sp->Prevzz[iv - 1]);
+                    polys++;
                                        glEnd();
                                }
                                if (sp->shownorms) {
@@ -415,6 +423,7 @@ DoneScale(superquadricsstruct * sp)
                                        glBegin(GL_LINES);
                                        glVertex3f(xx, yy, zz);
                                        glVertex3f(xx + xn, yy + yn, zz + zn);
+                    polys++;
                                        glEnd();
                                        if (!sp->flatshade)
                                                glShadeModel(GL_SMOOTH);
@@ -437,6 +446,7 @@ DoneScale(superquadricsstruct * sp)
 
                }               /* next */
        }                       /* next */
+    return polys;
 }
 
 /**** End of really old code ****/
@@ -539,9 +549,11 @@ NextSuperquadric(superquadricsstruct * sp)
        }
 }
 
-static void
-DisplaySuperquadrics(superquadricsstruct * sp)
+static int
+DisplaySuperquadrics(ModeInfo *mi)
 {
+       superquadricsstruct *sp = &superquadrics[MI_SCREEN(mi)];
+    int polys = 0;
        glDrawBuffer(GL_BACK);
        if (sp->wireframe)
                glClear(GL_COLOR_BUFFER_BIT);
@@ -560,18 +572,31 @@ DisplaySuperquadrics(superquadricsstruct * sp)
 
        SetCull(0, sp);
 
-       DoneScale(sp);
+    glScalef(0.7, 0.7, 0.7);  /* jwz: scale it down a bit */
+
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+  {
+    GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+    int o = (int) current_device_rotation();
+    if (o != 0 && o != 180 && o != -180)
+      glScalef (1/h, 1/h, 1/h);
+  }
+# endif
+
+       polys = DoneScale(sp);
 
        glPopMatrix();
 
        /* Remember to flush & swap the buffers after calling this function! */
+    return polys;
 }
 
-static void
-NextSuperquadricDisplay(superquadricsstruct * sp)
+static int
+NextSuperquadricDisplay(ModeInfo *mi)
 {
+       superquadricsstruct *sp = &superquadrics[MI_SCREEN(mi)];
        NextSuperquadric(sp);
-       DisplaySuperquadrics(sp);
+       return DisplaySuperquadrics(mi);
 }
 
 #define MINSIZE 200
@@ -594,7 +619,14 @@ ReshapeSuperquadrics(int w, int h)
                glViewport(0, 0, w, h);
        }
 #else
-    glViewport(0, 0, w, h);
+    int y = 0;
+
+    if (w > h * 5) {   /* tiny window: show middle */
+      h = w;
+      y = -h/2;
+    }
+
+    glViewport(0, y, w, h);
 #endif
 
        glMatrixMode(GL_PROJECTION);
@@ -656,7 +688,6 @@ InitSuperquadrics(int wfmode, int snorm, int res, int count, float speed, superq
        if (snorm)
                sp->shownorms = 1;
 
-    glClearColor(0.0,0.0,0.0,1.0);
     glClearDepth(1.0);
 
        if (sp->wireframe) {
@@ -704,11 +735,7 @@ init_superquadrics(ModeInfo * mi)
 
        superquadricsstruct *sp;
 
-       if (superquadrics == NULL) {
-               if ((superquadrics = (superquadricsstruct *) calloc(MI_NUM_SCREENS(mi),
-                                     sizeof (superquadricsstruct))) == NULL)
-                       return;
-       }
+       MI_INIT (mi, superquadrics);
        sp = &superquadrics[screen];
        sp->mono = (MI_IS_MONO(mi) ? 1 : 0);
 
@@ -731,7 +758,7 @@ init_superquadrics(ModeInfo * mi)
                                  MI_COUNT(mi), MI_CYCLES(mi), spinspeed, sp);
                ReshapeSuperquadrics(MI_WIDTH(mi), MI_HEIGHT(mi));
 
-               DisplaySuperquadrics(sp);
+               DisplaySuperquadrics(mi);
                glFinish();
                glXSwapBuffers(display, window);
        } else {
@@ -751,18 +778,20 @@ draw_superquadrics(ModeInfo * mi)
 
        glXMakeCurrent(display, window, *(sp->glx_context));
 
-       NextSuperquadricDisplay(sp);
+    mi->polygon_count = NextSuperquadricDisplay(mi);
 
     if (mi->fps_p) do_fps (mi);
        glFinish();
        glXSwapBuffers(display, window);
 }
 
+#ifndef STANDALONE
 ENTRYPOINT void
 refresh_superquadrics(ModeInfo * mi)
 {
        /* Nothing happens here */
 }
+#endif
 
 ENTRYPOINT void
 reshape_superquadrics(ModeInfo * mi, int width, int height)
@@ -770,16 +799,6 @@ reshape_superquadrics(ModeInfo * mi, int width, int height)
   ReshapeSuperquadrics(MI_WIDTH(mi), MI_HEIGHT(mi));
 }
 
-ENTRYPOINT void
-release_superquadrics(ModeInfo * mi)
-{
-       if (superquadrics != NULL) {
-               (void) free((void *) superquadrics);
-               superquadrics = NULL;
-       }
-       FreeAllGL(mi);
-}
-
 
 #endif