From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / glx / superquadrics.c
index 68dacee47dc8d396225da5a48d27520a8a11682f..5ab7ef5109353ba4ac6eab5b389e18079b8f60c2 100644 (file)
@@ -75,7 +75,10 @@ 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 release_superquadrics 0
 # define superquadrics_handle_event 0
 # include "xlockmore.h"                                /* from the xscreensaver distribution */
 #else  /* !STANDALONE */
@@ -113,7 +116,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 +347,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 +378,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 +412,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 +422,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 +445,7 @@ DoneScale(superquadricsstruct * sp)
 
                }               /* next */
        }                       /* next */
+    return polys;
 }
 
 /**** End of really old code ****/
@@ -539,9 +548,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 +571,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
@@ -656,7 +680,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 +727,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, NULL);
        sp = &superquadrics[screen];
        sp->mono = (MI_IS_MONO(mi) ? 1 : 0);
 
@@ -731,7 +750,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,7 +770,7 @@ 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();
@@ -770,16 +789,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