From http://www.jwz.org/xscreensaver/xscreensaver-5.18.tar.gz
[xscreensaver] / hacks / glx / teapot.c
1
2 /* Copyright (c) Mark J. Kilgard, 1994. */
3
4 /**
5 (c) Copyright 1993, Silicon Graphics, Inc.
6
7 ALL RIGHTS RESERVED
8
9 Permission to use, copy, modify, and distribute this software
10 for any purpose and without fee is hereby granted, provided
11 that the above copyright notice appear in all copies and that
12 both the copyright notice and this permission notice appear in
13 supporting documentation, and that the name of Silicon
14 Graphics, Inc. not be used in advertising or publicity
15 pertaining to distribution of the software without specific,
16 written prior permission.
17
18 THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
19 "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
20 OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
21 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  IN NO
22 EVENT SHALL SILICON GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE
23 ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
24 CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
25 INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
26 SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
27 NOT SILICON GRAPHICS, INC.  HAS BEEN ADVISED OF THE POSSIBILITY
28 OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
30 PERFORMANCE OF THIS SOFTWARE.
31
32 US Government Users Restricted Rights
33
34 Use, duplication, or disclosure by the Government is subject to
35 restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
36 (c)(1)(ii) of the Rights in Technical Data and Computer
37 Software clause at DFARS 252.227-7013 and/or in similar or
38 successor clauses in the FAR or the DOD or NASA FAR
39 Supplement.  Unpublished-- rights reserved under the copyright
40 laws of the United States.  Contractor/manufacturer is Silicon
41 Graphics, Inc., 2011 N.  Shoreline Blvd., Mountain View, CA
42 94039-7311.
43
44 OpenGL(TM) is a trademark of Silicon Graphics, Inc.
45 */
46
47 #ifdef HAVE_CONFIG_H
48 # include "config.h"
49 #endif
50
51 #include "teapot.h"
52
53 #ifndef HAVE_COCOA
54 # include <GL/gl.h>
55 #endif
56
57 #ifdef HAVE_JWZGLES
58 # include "jwzgles.h"
59 #else
60 # define HAVE_GLMAP
61 #endif
62
63
64 #ifdef HAVE_GLMAP
65
66 /* Rim, body, lid, and bottom data must be reflected in x
67    and y; handle and spout data across the y axis only.  */
68
69 static long patchdata[][16] =
70 {
71     /* rim */
72   {102, 103, 104, 105, 4, 5, 6, 7, 8, 9, 10, 11,
73     12, 13, 14, 15},
74     /* body */
75   {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
76     24, 25, 26, 27},
77   {24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36,
78     37, 38, 39, 40},
79     /* lid */
80   {96, 96, 96, 96, 97, 98, 99, 100, 101, 101, 101,
81     101, 0, 1, 2, 3,},
82   {0, 1, 2, 3, 106, 107, 108, 109, 110, 111, 112,
83     113, 114, 115, 116, 117},
84     /* bottom */
85   {118, 118, 118, 118, 124, 122, 119, 121, 123, 126,
86     125, 120, 40, 39, 38, 37},
87     /* handle */
88   {41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
89     53, 54, 55, 56},
90   {53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
91     28, 65, 66, 67},
92     /* spout */
93   {68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
94     80, 81, 82, 83},
95   {80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
96     92, 93, 94, 95}
97 };
98 /* *INDENT-OFF* */
99
100 static float cpdata[][3] =
101 {
102     {0.2, 0, 2.7}, {0.2, -0.112, 2.7}, {0.112, -0.2, 2.7}, {0,
103     -0.2, 2.7}, {1.3375, 0, 2.53125}, {1.3375, -0.749, 2.53125},
104     {0.749, -1.3375, 2.53125}, {0, -1.3375, 2.53125}, {1.4375,
105     0, 2.53125}, {1.4375, -0.805, 2.53125}, {0.805, -1.4375,
106     2.53125}, {0, -1.4375, 2.53125}, {1.5, 0, 2.4}, {1.5, -0.84,
107     2.4}, {0.84, -1.5, 2.4}, {0, -1.5, 2.4}, {1.75, 0, 1.875},
108     {1.75, -0.98, 1.875}, {0.98, -1.75, 1.875}, {0, -1.75,
109     1.875}, {2, 0, 1.35}, {2, -1.12, 1.35}, {1.12, -2, 1.35},
110     {0, -2, 1.35}, {2, 0, 0.9}, {2, -1.12, 0.9}, {1.12, -2,
111     0.9}, {0, -2, 0.9}, {-2, 0, 0.9}, {2, 0, 0.45}, {2, -1.12,
112     0.45}, {1.12, -2, 0.45}, {0, -2, 0.45}, {1.5, 0, 0.225},
113     {1.5, -0.84, 0.225}, {0.84, -1.5, 0.225}, {0, -1.5, 0.225},
114     {1.5, 0, 0.15}, {1.5, -0.84, 0.15}, {0.84, -1.5, 0.15}, {0,
115     -1.5, 0.15}, {-1.6, 0, 2.025}, {-1.6, -0.3, 2.025}, {-1.5,
116     -0.3, 2.25}, {-1.5, 0, 2.25}, {-2.3, 0, 2.025}, {-2.3, -0.3,
117     2.025}, {-2.5, -0.3, 2.25}, {-2.5, 0, 2.25}, {-2.7, 0,
118     2.025}, {-2.7, -0.3, 2.025}, {-3, -0.3, 2.25}, {-3, 0,
119     2.25}, {-2.7, 0, 1.8}, {-2.7, -0.3, 1.8}, {-3, -0.3, 1.8},
120     {-3, 0, 1.8}, {-2.7, 0, 1.575}, {-2.7, -0.3, 1.575}, {-3,
121     -0.3, 1.35}, {-3, 0, 1.35}, {-2.5, 0, 1.125}, {-2.5, -0.3,
122     1.125}, {-2.65, -0.3, 0.9375}, {-2.65, 0, 0.9375}, {-2,
123     -0.3, 0.9}, {-1.9, -0.3, 0.6}, {-1.9, 0, 0.6}, {1.7, 0,
124     1.425}, {1.7, -0.66, 1.425}, {1.7, -0.66, 0.6}, {1.7, 0,
125     0.6}, {2.6, 0, 1.425}, {2.6, -0.66, 1.425}, {3.1, -0.66,
126     0.825}, {3.1, 0, 0.825}, {2.3, 0, 2.1}, {2.3, -0.25, 2.1},
127     {2.4, -0.25, 2.025}, {2.4, 0, 2.025}, {2.7, 0, 2.4}, {2.7,
128     -0.25, 2.4}, {3.3, -0.25, 2.4}, {3.3, 0, 2.4}, {2.8, 0,
129     2.475}, {2.8, -0.25, 2.475}, {3.525, -0.25, 2.49375},
130     {3.525, 0, 2.49375}, {2.9, 0, 2.475}, {2.9, -0.15, 2.475},
131     {3.45, -0.15, 2.5125}, {3.45, 0, 2.5125}, {2.8, 0, 2.4},
132     {2.8, -0.15, 2.4}, {3.2, -0.15, 2.4}, {3.2, 0, 2.4}, {0, 0,
133     3.15}, {0.8, 0, 3.15}, {0.8, -0.45, 3.15}, {0.45, -0.8,
134     3.15}, {0, -0.8, 3.15}, {0, 0, 2.85}, {1.4, 0, 2.4}, {1.4,
135     -0.784, 2.4}, {0.784, -1.4, 2.4}, {0, -1.4, 2.4}, {0.4, 0,
136     2.55}, {0.4, -0.224, 2.55}, {0.224, -0.4, 2.55}, {0, -0.4,
137     2.55}, {1.3, 0, 2.55}, {1.3, -0.728, 2.55}, {0.728, -1.3,
138     2.55}, {0, -1.3, 2.55}, {1.3, 0, 2.4}, {1.3, -0.728, 2.4},
139     {0.728, -1.3, 2.4}, {0, -1.3, 2.4}, {0, 0, 0}, {1.425,
140     -0.798, 0}, {1.5, 0, 0.075}, {1.425, 0, 0}, {0.798, -1.425,
141     0}, {0, -1.5, 0.075}, {0, -1.425, 0}, {1.5, -0.84, 0.075},
142     {0.84, -1.5, 0.075}
143 };
144
145 static float tex[2][2][2] =
146 {
147   { {0, 0},
148     {1, 0}},
149   { {0, 1},
150     {1, 1}}
151 };
152
153
154 int
155 unit_teapot (int grid, int wire_p)
156 {
157   GLenum type = wire_p ? GL_LINE : GL_FILL;
158   float p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
159   long i, j, k, l;
160   int polys = 0;
161
162   glPushAttrib(GL_ENABLE_BIT | GL_EVAL_BIT);
163   glEnable(GL_AUTO_NORMAL);
164   glEnable(GL_NORMALIZE);
165   glEnable(GL_MAP2_VERTEX_3);
166   glEnable(GL_MAP2_TEXTURE_COORD_2);
167   glFrontFace (GL_CW);
168   glPushMatrix();
169   glRotatef(270.0, 1.0, 0.0, 0.0);
170   glScalef(0.5, 0.5, 0.5);
171   glTranslatef(0.0, 0.0, -1.5);
172   for (i = 0; i < 10; i++) {
173     for (j = 0; j < 4; j++) {
174       for (k = 0; k < 4; k++) {
175         for (l = 0; l < 3; l++) {
176           p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
177           q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];
178           if (l == 1)
179             q[j][k][l] *= -1.0;
180           if (i < 6) {
181             r[j][k][l] =
182               cpdata[patchdata[i][j * 4 + (3 - k)]][l];
183             if (l == 0)
184               r[j][k][l] *= -1.0;
185             s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
186             if (l == 0)
187               s[j][k][l] *= -1.0;
188             if (l == 1)
189               s[j][k][l] *= -1.0;
190           }
191         }
192       }
193     }
194     glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2,
195       &tex[0][0][0]);
196     glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
197       &p[0][0][0]);
198     glMapGrid2f(grid, 0.0, 1.0, grid, 0.0, 1.0);
199     glEvalMesh2(type, 0, grid, 0, grid);
200     polys += grid*grid*2;
201     glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
202       &q[0][0][0]);
203     glEvalMesh2(type, 0, grid, 0, grid);
204     polys += grid*grid*2;
205     if (i < 6) {
206       glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
207         &r[0][0][0]);
208       glEvalMesh2(type, 0, grid, 0, grid);
209       polys += grid*grid*2;
210       glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4,
211         &s[0][0][0]);
212       glEvalMesh2(type, 0, grid, 0, grid);
213       polys += grid*grid*2;
214     }
215   }
216   glPopMatrix();
217   glPopAttrib();
218
219   return polys;
220 }
221
222 #else  /* !HAVE_GLMAP */
223
224 # include "normals.h"
225 # include "teapot2.h"
226
227 int
228 unit_teapot (int grid, int wire_p)
229 {
230   int polys = sizeof (teapot_triangles) / sizeof (*teapot_triangles) / 9;
231   int i;
232   const GLfloat *p = teapot_triangles;
233   GLfloat scale = 1 / 2.3;
234
235   glPushMatrix();
236   glScalef (scale, scale, scale);
237   glTranslatef (0, -1.25, 0);
238
239   if (wire_p)
240     {
241       glBegin (GL_LINES);
242       for (i = 0; i < polys; i++)
243         {
244           XYZ p1, p2, p3;
245           p1.x = *p++; p1.y = *p++; p1.z = *p++;
246           p2.x = *p++; p2.y = *p++; p2.z = *p++;
247           p3.x = *p++; p3.y = *p++; p3.z = *p++;
248           glVertex3f (p1.x, p1.y, p1.z);   /* Draw 2 edges of each triangle */
249           glVertex3f (p2.x, p2.y, p2.z);
250           glVertex3f (p1.x, p1.y, p1.z);
251           glVertex3f (p3.x, p3.y, p3.z);
252           i++;                             /* Skip every other triangle */
253           p += 9;
254         }
255       glEnd();
256       polys /= 2;
257     }
258   else
259     {
260       glFrontFace (GL_CCW);
261       glBegin (GL_TRIANGLES);
262       for (i = 0; i < polys; i++)
263         {
264           XYZ p1, p2, p3;
265           p1.x = *p++; p1.y = *p++; p1.z = *p++;
266           p2.x = *p++; p2.y = *p++; p2.z = *p++;
267           p3.x = *p++; p3.y = *p++; p3.z = *p++;
268           do_normal (p1.x, p1.y, p1.z,
269                      p2.x, p2.y, p2.z,
270                      p3.x, p3.y, p3.z);
271           glVertex3f (p1.x, p1.y, p1.z);
272           glVertex3f (p2.x, p2.y, p2.z);
273           glVertex3f (p3.x, p3.y, p3.z);
274         }
275       glEnd();
276     }
277   glPopMatrix();
278
279   return polys;
280 }
281
282 #endif /* !HAVE_GLMAP */