From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / glx / superquadrics.c
index cfc2999a56d7a8938ba9f125423063e9636e8e0f..5ab7ef5109353ba4ac6eab5b389e18079b8f60c2 100644 (file)
@@ -1,9 +1,8 @@
 /* -*- Mode: C; tab-width: 4 -*- */
 /* superquadrics --- 3D mathematical shapes */
 
-#if !defined( lint ) && !defined( SABER )
+#if 0
 static const char sccsid[] = "@(#)superquadrics.c      4.07 97/11/24 xlockmore";
-
 #endif
 
 /*-
@@ -71,22 +70,16 @@ static const char sccsid[] = "@(#)superquadrics.c   4.07 97/11/24 xlockmore";
  * Ed Mackey
  */
 
-/*-
- * due to a Bug/feature in VMS X11/Intrinsic.h has to be placed before xlock.
- * otherwise caddr_t is not defined correctly
- */
-
-#include <X11/Intrinsic.h>
-
 #ifdef STANDALONE
-# define PROGCLASS                                     "Superquadrics"
-# define HACK_INIT                                     init_superquadrics
-# define HACK_DRAW                                     draw_superquadrics
-# define superquadrics_opts                    xlockmore_opts
-# define DEFAULTS      "*delay:                100     \n"                     \
+# define DEFAULTS      "*delay:                40000   \n"                     \
                                        "*count:                25      \n"                     \
                                        "*cycles:               40      \n"                     \
-                                       "*wireframe:    False   \n"
+                                       "*showFPS:      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 */
 # include "xlock.h"                                    /* from the xlockmore distribution */
@@ -107,31 +100,29 @@ static float spinspeed;
 
 static XrmOptionDescRec opts[] =
 {
-  {"-spinspeed", ".superquadrics.spinspeed", XrmoptionSepArg, (caddr_t) NULL}
+  {"-spinspeed", ".superquadrics.spinspeed", XrmoptionSepArg, 0}
 };
 static argtype vars[] =
 {
-  {(caddr_t *) & spinspeed, "spinspeed", "Spinspeed", DEF_SPINSPEED, t_Float}
+  {&spinspeed, "spinspeed", "Spinspeed", DEF_SPINSPEED, t_Float}
 };
 static OptionStruct desc[] =
 {
        {"-spinspeed num", "speed of rotation, in degrees per frame"}
 };
 
-ModeSpecOpt superquadrics_opts =
+ENTRYPOINT ModeSpecOpt superquadrics_opts =
 {sizeof opts / sizeof opts[0], opts, sizeof vars / sizeof vars[0], vars, desc};
 
 #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};
 
 #endif
 
-#include <GL/glu.h>
-
 #define MaxRes          50
 #define MinRes          5
 
@@ -157,6 +148,10 @@ typedef struct {
        double      xExponent, yExponent, Mode;
        int         resolution;
        state       now, later;
+
+    int         pats[4][4];
+       int             cullmode;
+
 } superquadricsstruct;
 
 static superquadricsstruct *superquadrics = NULL;
@@ -228,14 +223,6 @@ Cosine(double x, double e)
 static void
 MakeUpStuff(int allstuff, superquadricsstruct * sp)
 {
-       static int  pats[4][4] =
-       {
-               {0, 0, 0, 0},
-               {0, 1, 0, 1},
-               {0, 0, 1, 1},
-               {0, 1, 1, 0}
-       };
-
        int         dostuff;
        int         t, pat;
        GLfloat     r, g, b, r2, g2, b2;
@@ -289,9 +276,9 @@ MakeUpStuff(int allstuff, superquadricsstruct * sp)
 
                pat = myrand(4);
                for (t = 0; t < 4; ++t) {
-                       sp->later.r[t] = pats[pat][t] ? r : r2;
-                       sp->later.g[t] = pats[pat][t] ? g : g2;
-                       sp->later.b[t] = pats[pat][t] ? b : b2;
+                       sp->later.r[t] = sp->pats[pat][t] ? r : r2;
+                       sp->later.g[t] = sp->pats[pat][t] ? g : g2;
+                       sp->later.b[t] = sp->pats[pat][t] ? b : b2;
                }
        }
        if (dostuff & 8) {
@@ -360,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..... */
@@ -390,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. */
@@ -422,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) {
@@ -431,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);
@@ -453,6 +445,7 @@ DoneScale(superquadricsstruct * sp)
 
                }               /* next */
        }                       /* next */
+    return polys;
 }
 
 /**** End of really old code ****/
@@ -460,28 +453,27 @@ DoneScale(superquadricsstruct * sp)
 static void
 SetCull(int init, superquadricsstruct * sp)
 {
-       static int  cullmode;
-
        if (init) {
-               cullmode = 0;
+        glDisable(GL_CULL_FACE);
+               sp->cullmode = 0;
                return;
        }
        if (sp->Mode < 1.0001) {
-               if (cullmode != 1) {
+               if (sp->cullmode != 1) {
                        glEnable(GL_CULL_FACE);
                        glCullFace(GL_BACK);
-                       cullmode = 1;
+                       sp->cullmode = 1;
                }
        } else if (sp->Mode > 2.9999) {
-               if (cullmode != 2) {
+               if (sp->cullmode != 2) {
                        glEnable(GL_CULL_FACE);
                        glCullFace(GL_FRONT);
-                       cullmode = 2;
+                       sp->cullmode = 2;
                }
        } else {
-               if (cullmode) {
+               if (sp->cullmode) {
                        glDisable(GL_CULL_FACE);
-                       cullmode = 0;
+                       sp->cullmode = 0;
                }
        }
 }
@@ -556,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);
@@ -567,7 +561,7 @@ DisplaySuperquadrics(superquadricsstruct * sp)
 
        if (sp->viewcount < 1) {
                sp->viewcount = sp->viewwait;
-               ReshapeSuperquadrics(-1, -1);
+/*             ReshapeSuperquadrics(-1, -1);*/
        }
        glPushMatrix();
        glTranslatef(0.0, 0.0, -((GLfloat) (sp->dist) / 16.0) - (sp->Mode * 3.0 - 1.0));        /* viewing transform  */
@@ -577,34 +571,40 @@ 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
 static void
 ReshapeSuperquadrics(int w, int h)
 {
-       static int  last_w = 0, last_h = 0;
+#if 0
        int         maxsize, cursize;
 
-       if (w < 0) {
-               w = last_w;
-               h = last_h;
-       } else {
-               last_w = w;
-               last_h = h;
-       }
        maxsize = (w < h) ? w : h;
        if (maxsize <= MINSIZE) {
                cursize = maxsize;
@@ -617,9 +617,13 @@ ReshapeSuperquadrics(int w, int h)
        } else {
                glViewport(0, 0, w, h);
        }
+#else
+    glViewport(0, 0, w, h);
+#endif
+
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
-       gluPerspective(30.0, (GLfloat) w / (GLfloat) h, 0.1, 200.0);
+       gluPerspective(15.0, (GLfloat) w / (GLfloat) h, 0.1, 200.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
 }
@@ -640,8 +644,12 @@ InitSuperquadrics(int wfmode, int snorm, int res, int count, float speed, superq
 
        int         t;
 
-       for (t = 0; t < 4; ++t)
+       for (t = 0; t < 4; ++t) {
+               sp->curmat[t][0] = 0.0;
+               sp->curmat[t][1] = 0.0;
+               sp->curmat[t][2] = 0.0;
                sp->curmat[t][3] = 1.0;
+    }
 
        sp->rotx = 35.0;
        sp->roty = 0.0;
@@ -654,6 +662,7 @@ InitSuperquadrics(int wfmode, int snorm, int res, int count, float speed, superq
        sp->maxwait = sp->maxcount >> 1;
        SetCull(1, sp);
 
+    sp->mono = 0;
        sp->spinspeed = speed;
        sp->viewcount = sp->viewwait = (sp->maxcount < 2) ? 1 : (sp->maxcount << 3);
 
@@ -671,6 +680,8 @@ InitSuperquadrics(int wfmode, int snorm, int res, int count, float speed, superq
        if (snorm)
                sp->shownorms = 1;
 
+    glClearDepth(1.0);
+
        if (sp->wireframe) {
                glShadeModel(GL_FLAT);
                glDisable(GL_LIGHTING);
@@ -707,7 +718,7 @@ InitSuperquadrics(int wfmode, int snorm, int res, int count, float speed, superq
 
 /* End of superquadrics main functions */
 
-void
+ENTRYPOINT void
 init_superquadrics(ModeInfo * mi)
 {
        Display    *display = MI_DISPLAY(mi);
@@ -716,21 +727,30 @@ 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);
 
+    sp->pats[1][1] = 1;
+    sp->pats[1][3] = 1;
+    sp->pats[2][2] = 1;
+    sp->pats[2][3] = 1;
+    sp->pats[3][1] = 1;
+    sp->pats[3][2] = 1;
+
+/*             {0, 0, 0, 0},
+               {0, 1, 0, 1},
+               {0, 0, 1, 1},
+               {0, 1, 1, 0}
+ */
+
        if ((sp->glx_context = init_GL(mi)) != NULL) {
 
                InitSuperquadrics(MI_IS_WIREFRAME(mi), 0,
                                  MI_COUNT(mi), MI_CYCLES(mi), spinspeed, sp);
                ReshapeSuperquadrics(MI_WIDTH(mi), MI_HEIGHT(mi));
 
-               DisplaySuperquadrics(sp);
+               DisplaySuperquadrics(mi);
                glFinish();
                glXSwapBuffers(display, window);
        } else {
@@ -738,7 +758,7 @@ init_superquadrics(ModeInfo * mi)
        }
 }
 
-void
+ENTRYPOINT void
 draw_superquadrics(ModeInfo * mi)
 {
        superquadricsstruct *sp = &superquadrics[MI_SCREEN(mi)];
@@ -750,29 +770,28 @@ 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);
 }
 
-void
+ENTRYPOINT void
 refresh_superquadrics(ModeInfo * mi)
 {
        /* Nothing happens here */
 }
 
-void
-release_superquadrics(ModeInfo * mi)
+ENTRYPOINT void
+reshape_superquadrics(ModeInfo * mi, int width, int height)
 {
-       if (superquadrics != NULL) {
-               (void) free((void *) superquadrics);
-               superquadrics = NULL;
-       }
-       FreeAllGL(mi);
+  ReshapeSuperquadrics(MI_WIDTH(mi), MI_HEIGHT(mi));
 }
 
 
 #endif
 
 /* End of superquadrics.c */
+
+XSCREENSAVER_MODULE ("Superquadrics", superquadrics)