d11eb9f10f79f9e83a8034793094ae89841a71c8
[xscreensaver] / hacks / glx / sphere.c
1 /* sphere, Copyright (c) 1998 David Konerding <dek@cgl.ucsf.edu>
2  * Utility function to create a unit sphere in GL.
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation.  No representations are made about the suitability of this
9  * software for any purpose.  It is provided "as is" without express or 
10  * implied warranty.
11  *
12  *  8-Oct-98: dek           Released initial version of "glplanet"
13  * 21-Mar-01: jwz@jwz.org   Broke sphere routine out into its own file.
14  */
15
16 #include "config.h"
17 #include <stdlib.h>
18 #include <math.h>
19 #include <GL/glx.h>
20 #include "tube.h"
21
22 /* Function for determining points on the surface of the sphere */
23 static void
24 parametric_sphere (float theta, float rho, GLfloat *vector)
25 {
26   vector[0] = -sin(theta) * sin(rho);
27   vector[1] = cos(theta) * sin(rho);
28   vector[2] = cos(rho);
29 }
30
31
32 void
33 unit_sphere (int stacks, int slices, Bool wire)
34 {
35   int i, j;
36   float drho, dtheta;
37   float rho, theta;
38   GLfloat vector[3];
39   GLfloat ds, dt, t, s;
40
41   if (!wire)
42     glShadeModel(GL_SMOOTH);
43
44   /* Generate a sphere with quadrilaterals.
45    * Quad vertices are determined using a parametric sphere function.
46    * For fun, you could generate practically any parameteric surface and
47    * map an image onto it. 
48    */
49   drho = M_PI / stacks;
50   dtheta = 2.0 * M_PI / slices;
51   ds = 1.0 / slices;
52   dt = 1.0 / stacks;
53
54   glFrontFace(GL_CCW);
55   glBegin (wire ? GL_LINE_LOOP : GL_QUADS);
56
57   t = 0.0;
58   for (i=0; i < stacks; i++) {
59     rho = i * drho;
60     s = 0.0;
61     for (j=0; j < slices; j++) {
62       theta = j * dtheta;
63
64       glTexCoord2f (s,t);
65       parametric_sphere (theta, rho, vector);
66       glNormal3fv (vector);
67       parametric_sphere (theta, rho, vector);
68       glVertex3f (vector[0], vector[1], vector[2]);
69
70       glTexCoord2f (s,t+dt);
71       parametric_sphere (theta, rho+drho, vector);
72       glNormal3fv (vector);
73       parametric_sphere (theta, rho+drho, vector);
74       glVertex3f (vector[0], vector[1], vector[2]);
75
76       glTexCoord2f (s+ds,t+dt);
77       parametric_sphere (theta + dtheta, rho+drho, vector);
78       glNormal3fv (vector);
79       parametric_sphere (theta + dtheta, rho+drho, vector);
80       glVertex3f (vector[0], vector[1], vector[2]);
81
82       glTexCoord2f (s+ds, t);
83       parametric_sphere (theta + dtheta, rho, vector);
84       glNormal3fv (vector);
85       parametric_sphere (theta + dtheta, rho, vector);
86       glVertex3f (vector[0], vector[1], vector[2]);
87
88       s = s + ds;
89     }
90     t = t + dt;
91   }
92   glEnd();
93 }