From http://www.jwz.org/xscreensaver/xscreensaver-5.31.tar.gz
[xscreensaver] / hacks / glx / stonerview-view.c
1 /* StonerView: An eccentric visual toy.
2    Copyright 1998-2001 by Andrew Plotkin (erkyrath@eblong.com)
3    http://www.eblong.com/zarf/stonerview.html
4  
5    Permission to use, copy, modify, distribute, and sell this software and its
6    documentation for any purpose is hereby granted without fee, provided that
7    the above copyright notice appear in all copies and that both that
8    copyright notice and this permission notice appear in supporting
9    documentation.  No representations are made about the suitability of this
10    software for any purpose.  It is provided "as is" without express or 
11    implied warranty.
12 */
13
14 /* Ported away from GLUT (so that it can do `-root' and work with xscreensaver)
15    by Jamie Zawinski <jwz@jwz.org>, 22-Jan-2001.
16  */
17
18 #ifdef HAVE_CONFIG_H
19 # include "config.h"
20 #endif
21
22 #ifdef HAVE_COCOA
23 # include "jwxyz.h"
24 #elif defined(HAVE_ANDROID)
25 # include <GLES/gl.h>
26 #else /* real Xlib */
27 # include <GL/glx.h>
28 # include <GL/glu.h>
29 #endif /* !HAVE_COCOA */
30
31 #ifdef HAVE_JWZGLES
32 # include "jwzgles.h"
33 #endif /* HAVE_JWZGLES */
34
35 #include <stdlib.h>
36 #include "stonerview.h"
37
38 static GLfloat view_rotx = -45.0, view_roty = 0.0, view_rotz = 15.0;
39 static GLfloat view_scale = 4.0;
40
41
42 stonerview_state *
43 stonerview_init_view(int wireframe_p, int transparent_p)
44 {
45   stonerview_state *st = (stonerview_state *) calloc (1, sizeof(*st));
46
47   st->wireframe = wireframe_p;
48   st->transparent = transparent_p;
49   st->num_els = NUM_ELS;
50   st->elist = (stonerview_elem_t *) calloc (st->num_els, sizeof(*st->elist));
51
52   st->osctail = &st->oscroot;
53
54   /* for trackball, two-sided lighting and no face culling */
55   glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
56
57   glEnable(GL_CULL_FACE);
58   glEnable(GL_LIGHTING);
59   glEnable(GL_LIGHT0);
60   glEnable(GL_DEPTH_TEST);
61
62   glEnable(GL_NORMALIZE);
63
64   glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
65   glEnable(GL_LINE_SMOOTH);
66   glEnable(GL_BLEND);
67
68   if (st->transparent)
69     glBlendFunc(GL_SRC_ALPHA,GL_ONE);
70
71   return st;
72 }
73
74 /* callback: draw everything */
75 void
76 stonerview_win_draw(stonerview_state *st)
77 {
78   int ix;
79   static const GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
80   static const GLfloat gray[]  = { 0.6, 0.6, 0.6, 1.0 };
81
82   glDrawBuffer(GL_BACK);
83
84   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
85
86   glPushMatrix();
87   glScalef(view_scale, view_scale, view_scale);
88   glRotatef(view_rotx, 1.0, 0.0, 0.0);
89   glRotatef(view_roty, 0.0, 1.0, 0.0);
90   glRotatef(view_rotz, 0.0, 0.0, 1.0);
91
92   glShadeModel(GL_FLAT);
93
94   for (ix=0; ix < st->num_els; ix++) {
95     stonerview_elem_t *el = &st->elist[ix];
96
97     glNormal3f(0.0, 0.0, 1.0);
98
99     /* outline the square */
100     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (st->wireframe ? white : gray));
101     glBegin(GL_LINE_LOOP);
102     glVertex3f(el->pos[0]-el->vervec[0], el->pos[1]-el->vervec[1], el->pos[2]);
103     glVertex3f(el->pos[0]+el->vervec[1], el->pos[1]-el->vervec[0], el->pos[2]);
104     glVertex3f(el->pos[0]+el->vervec[0], el->pos[1]+el->vervec[1], el->pos[2]);
105     glVertex3f(el->pos[0]-el->vervec[1], el->pos[1]+el->vervec[0], el->pos[2]);
106     glEnd();
107
108     if (st->wireframe) continue;
109
110     /* fill the square */
111     {
112       GLfloat col[4];
113       col[0] = el->col[0]; col[1] = el->col[1];
114       col[2] = el->col[2]; col[3] = el->col[3];
115       glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col);
116     }
117     glBegin(GL_QUADS);
118     glVertex3f(el->pos[0]-el->vervec[0], el->pos[1]-el->vervec[1], el->pos[2]);
119     glVertex3f(el->pos[0]+el->vervec[1], el->pos[1]-el->vervec[0], el->pos[2]);
120     glVertex3f(el->pos[0]+el->vervec[0], el->pos[1]+el->vervec[1], el->pos[2]);
121     glVertex3f(el->pos[0]-el->vervec[1], el->pos[1]+el->vervec[0], el->pos[2]);
122     glEnd();
123   }
124
125   glPopMatrix();
126 }
127
128 void
129 stonerview_win_release(stonerview_state *st)
130 {
131   free (st->elist);
132   /*free (st->oscroot);  -- #### how do we free this? */
133   free (st);
134 }