bounce.c revision 32001f49
1
2/*
3 * Bouncing ball demo.
4 *
5 * This program is in the public domain
6 *
7 * Brian Paul
8 *
9 * Conversion to GLUT by Mark J. Kilgard
10 */
11
12
13#include <math.h>
14#include <stdlib.h>
15#include <string.h>
16#include "glut_wrap.h"
17
18#define COS(X)   cos( (X) * 3.14159/180.0 )
19#define SIN(X)   sin( (X) * 3.14159/180.0 )
20
21#define RED 1
22#define WHITE 2
23#define CYAN 3
24
25GLboolean IndexMode = GL_FALSE;
26GLuint Ball;
27GLenum Mode;
28GLfloat Zrot = 0.0, Zstep = 180.0;
29GLfloat Xpos = 0.0, Ypos = 1.0;
30GLfloat Xvel = 2.0, Yvel = 0.0;
31GLfloat Xmin = -4.0, Xmax = 4.0;
32GLfloat Ymin = -3.8, Ymax = 4.0;
33GLfloat G = -9.8;
34
35static GLuint
36make_ball(void)
37{
38  GLuint list;
39  GLfloat a, b;
40  GLfloat da = 18.0, db = 18.0;
41  GLfloat radius = 1.0;
42  GLuint color;
43  GLfloat x, y, z;
44
45  list = glGenLists(1);
46
47  glNewList(list, GL_COMPILE);
48
49  color = 0;
50  for (a = -90.0; a + da <= 90.0; a += da) {
51
52    glBegin(GL_QUAD_STRIP);
53    for (b = 0.0; b <= 360.0; b += db) {
54
55      if (color) {
56	glIndexi(RED);
57        glColor3f(1, 0, 0);
58      } else {
59	glIndexi(WHITE);
60        glColor3f(1, 1, 1);
61      }
62
63      x = radius * COS(b) * COS(a);
64      y = radius * SIN(b) * COS(a);
65      z = radius * SIN(a);
66      glVertex3f(x, y, z);
67
68      x = radius * COS(b) * COS(a + da);
69      y = radius * SIN(b) * COS(a + da);
70      z = radius * SIN(a + da);
71      glVertex3f(x, y, z);
72
73      color = 1 - color;
74    }
75    glEnd();
76
77  }
78
79  glEndList();
80
81  return list;
82}
83
84static void
85reshape(int width, int height)
86{
87  float aspect = (float) width / (float) height;
88  glViewport(0, 0, (GLint) width, (GLint) height);
89  glMatrixMode(GL_PROJECTION);
90  glLoadIdentity();
91  glOrtho(-6.0 * aspect, 6.0 * aspect, -6.0, 6.0, -6.0, 6.0);
92  glMatrixMode(GL_MODELVIEW);
93}
94
95/* ARGSUSED1 */
96static void
97key(unsigned char k, int x, int y)
98{
99  switch (k) {
100  case 27:  /* Escape */
101    exit(0);
102  }
103}
104
105static void
106draw(void)
107{
108  GLint i;
109
110  glClear(GL_COLOR_BUFFER_BIT);
111
112  glIndexi(CYAN);
113  glColor3f(0, 1, 1);
114  glBegin(GL_LINES);
115  for (i = -5; i <= 5; i++) {
116    glVertex2i(i, -5);
117    glVertex2i(i, 5);
118  }
119  for (i = -5; i <= 5; i++) {
120    glVertex2i(-5, i);
121    glVertex2i(5, i);
122  }
123  for (i = -5; i <= 5; i++) {
124    glVertex2i(i, -5);
125    glVertex2f(i * 1.15, -5.9);
126  }
127  glVertex2f(-5.3, -5.35);
128  glVertex2f(5.3, -5.35);
129  glVertex2f(-5.75, -5.9);
130  glVertex2f(5.75, -5.9);
131  glEnd();
132
133  glPushMatrix();
134  glTranslatef(Xpos, Ypos, 0.0);
135  glScalef(2.0, 2.0, 2.0);
136  glRotatef(8.0, 0.0, 0.0, 1.0);
137  glRotatef(90.0, 1.0, 0.0, 0.0);
138  glRotatef(Zrot, 0.0, 0.0, 1.0);
139
140  glCallList(Ball);
141
142  glPopMatrix();
143
144  glFlush();
145  glutSwapBuffers();
146}
147
148static void
149idle(void)
150{
151  static float vel0 = -100.0;
152  static double t0 = -1.;
153  double t, dt;
154  t = glutGet(GLUT_ELAPSED_TIME) / 1000.;
155  if (t0 < 0.)
156     t0 = t;
157  dt = t - t0;
158  t0 = t;
159
160  Zrot += Zstep*dt;
161
162  Xpos += Xvel*dt;
163  if (Xpos >= Xmax) {
164    Xpos = Xmax;
165    Xvel = -Xvel;
166    Zstep = -Zstep;
167  }
168  if (Xpos <= Xmin) {
169    Xpos = Xmin;
170    Xvel = -Xvel;
171    Zstep = -Zstep;
172  }
173  Ypos += Yvel*dt;
174  Yvel += G*dt;
175  if (Ypos < Ymin) {
176    Ypos = Ymin;
177    if (vel0 == -100.0)
178      vel0 = fabs(Yvel);
179    Yvel = vel0;
180  }
181  glutPostRedisplay();
182}
183
184static void
185visible(int vis)
186{
187  if (vis == GLUT_VISIBLE)
188    glutIdleFunc(idle);
189  else
190    glutIdleFunc(NULL);
191}
192
193int main(int argc, char *argv[])
194{
195  glutInitWindowSize(600, 450);
196  glutInit(&argc, argv);
197
198  IndexMode = argc > 1 && strcmp(argv[1], "-ci") == 0;
199  if (IndexMode)
200     glutInitDisplayMode(GLUT_INDEX | GLUT_DOUBLE);
201  else
202     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
203
204  glutCreateWindow("Bounce");
205  Ball = make_ball();
206  glCullFace(GL_BACK);
207  glEnable(GL_CULL_FACE);
208  glDisable(GL_DITHER);
209  glShadeModel(GL_FLAT);
210
211  glutDisplayFunc(draw);
212  glutReshapeFunc(reshape);
213  glutVisibilityFunc(visible);
214  glutKeyboardFunc(key);
215
216  if (IndexMode) {
217    glutSetColor(RED, 1.0, 0.0, 0.0);
218    glutSetColor(WHITE, 1.0, 1.0, 1.0);
219    glutSetColor(CYAN, 0.0, 1.0, 1.0);
220  }
221
222  glutMainLoop();
223  return 0;             /* ANSI C requires main to return int. */
224}
225