132001f49Smrg
232001f49Smrg/*
332001f49Smrg * Bouncing ball demo.
432001f49Smrg *
532001f49Smrg * This program is in the public domain
632001f49Smrg *
732001f49Smrg * Brian Paul
832001f49Smrg *
932001f49Smrg * Conversion to GLUT by Mark J. Kilgard
1032001f49Smrg */
1132001f49Smrg
1232001f49Smrg
1332001f49Smrg#include <math.h>
1432001f49Smrg#include <stdlib.h>
1532001f49Smrg#include <string.h>
1632001f49Smrg#include "glut_wrap.h"
1732001f49Smrg
1832001f49Smrg#define COS(X)   cos( (X) * 3.14159/180.0 )
1932001f49Smrg#define SIN(X)   sin( (X) * 3.14159/180.0 )
2032001f49Smrg
2132001f49Smrg#define RED 1
2232001f49Smrg#define WHITE 2
2332001f49Smrg#define CYAN 3
2432001f49Smrg
2532001f49SmrgGLboolean IndexMode = GL_FALSE;
2632001f49SmrgGLuint Ball;
2732001f49SmrgGLenum Mode;
2832001f49SmrgGLfloat Zrot = 0.0, Zstep = 180.0;
2932001f49SmrgGLfloat Xpos = 0.0, Ypos = 1.0;
3032001f49SmrgGLfloat Xvel = 2.0, Yvel = 0.0;
3132001f49SmrgGLfloat Xmin = -4.0, Xmax = 4.0;
3232001f49SmrgGLfloat Ymin = -3.8, Ymax = 4.0;
3332001f49SmrgGLfloat G = -9.8;
3432001f49Smrg
3532001f49Smrgstatic GLuint
3632001f49Smrgmake_ball(void)
3732001f49Smrg{
3832001f49Smrg  GLuint list;
3932001f49Smrg  GLfloat a, b;
4032001f49Smrg  GLfloat da = 18.0, db = 18.0;
4132001f49Smrg  GLfloat radius = 1.0;
4232001f49Smrg  GLuint color;
4332001f49Smrg  GLfloat x, y, z;
4432001f49Smrg
4532001f49Smrg  list = glGenLists(1);
4632001f49Smrg
4732001f49Smrg  glNewList(list, GL_COMPILE);
4832001f49Smrg
4932001f49Smrg  color = 0;
5032001f49Smrg  for (a = -90.0; a + da <= 90.0; a += da) {
5132001f49Smrg
5232001f49Smrg    glBegin(GL_QUAD_STRIP);
5332001f49Smrg    for (b = 0.0; b <= 360.0; b += db) {
5432001f49Smrg
5532001f49Smrg      if (color) {
5632001f49Smrg	glIndexi(RED);
5732001f49Smrg        glColor3f(1, 0, 0);
5832001f49Smrg      } else {
5932001f49Smrg	glIndexi(WHITE);
6032001f49Smrg        glColor3f(1, 1, 1);
6132001f49Smrg      }
6232001f49Smrg
6332001f49Smrg      x = radius * COS(b) * COS(a);
6432001f49Smrg      y = radius * SIN(b) * COS(a);
6532001f49Smrg      z = radius * SIN(a);
6632001f49Smrg      glVertex3f(x, y, z);
6732001f49Smrg
6832001f49Smrg      x = radius * COS(b) * COS(a + da);
6932001f49Smrg      y = radius * SIN(b) * COS(a + da);
7032001f49Smrg      z = radius * SIN(a + da);
7132001f49Smrg      glVertex3f(x, y, z);
7232001f49Smrg
7332001f49Smrg      color = 1 - color;
7432001f49Smrg    }
7532001f49Smrg    glEnd();
7632001f49Smrg
7732001f49Smrg  }
7832001f49Smrg
7932001f49Smrg  glEndList();
8032001f49Smrg
8132001f49Smrg  return list;
8232001f49Smrg}
8332001f49Smrg
8432001f49Smrgstatic void
8532001f49Smrgreshape(int width, int height)
8632001f49Smrg{
8732001f49Smrg  float aspect = (float) width / (float) height;
8832001f49Smrg  glViewport(0, 0, (GLint) width, (GLint) height);
8932001f49Smrg  glMatrixMode(GL_PROJECTION);
9032001f49Smrg  glLoadIdentity();
9132001f49Smrg  glOrtho(-6.0 * aspect, 6.0 * aspect, -6.0, 6.0, -6.0, 6.0);
9232001f49Smrg  glMatrixMode(GL_MODELVIEW);
9332001f49Smrg}
9432001f49Smrg
9532001f49Smrg/* ARGSUSED1 */
9632001f49Smrgstatic void
9732001f49Smrgkey(unsigned char k, int x, int y)
9832001f49Smrg{
9932001f49Smrg  switch (k) {
10032001f49Smrg  case 27:  /* Escape */
10132001f49Smrg    exit(0);
10232001f49Smrg  }
10332001f49Smrg}
10432001f49Smrg
10532001f49Smrgstatic void
10632001f49Smrgdraw(void)
10732001f49Smrg{
10832001f49Smrg  GLint i;
10932001f49Smrg
11032001f49Smrg  glClear(GL_COLOR_BUFFER_BIT);
11132001f49Smrg
11232001f49Smrg  glIndexi(CYAN);
11332001f49Smrg  glColor3f(0, 1, 1);
11432001f49Smrg  glBegin(GL_LINES);
11532001f49Smrg  for (i = -5; i <= 5; i++) {
11632001f49Smrg    glVertex2i(i, -5);
11732001f49Smrg    glVertex2i(i, 5);
11832001f49Smrg  }
11932001f49Smrg  for (i = -5; i <= 5; i++) {
12032001f49Smrg    glVertex2i(-5, i);
12132001f49Smrg    glVertex2i(5, i);
12232001f49Smrg  }
12332001f49Smrg  for (i = -5; i <= 5; i++) {
12432001f49Smrg    glVertex2i(i, -5);
12532001f49Smrg    glVertex2f(i * 1.15, -5.9);
12632001f49Smrg  }
12732001f49Smrg  glVertex2f(-5.3, -5.35);
12832001f49Smrg  glVertex2f(5.3, -5.35);
12932001f49Smrg  glVertex2f(-5.75, -5.9);
13032001f49Smrg  glVertex2f(5.75, -5.9);
13132001f49Smrg  glEnd();
13232001f49Smrg
13332001f49Smrg  glPushMatrix();
13432001f49Smrg  glTranslatef(Xpos, Ypos, 0.0);
13532001f49Smrg  glScalef(2.0, 2.0, 2.0);
13632001f49Smrg  glRotatef(8.0, 0.0, 0.0, 1.0);
13732001f49Smrg  glRotatef(90.0, 1.0, 0.0, 0.0);
13832001f49Smrg  glRotatef(Zrot, 0.0, 0.0, 1.0);
13932001f49Smrg
14032001f49Smrg  glCallList(Ball);
14132001f49Smrg
14232001f49Smrg  glPopMatrix();
14332001f49Smrg
14432001f49Smrg  glFlush();
14532001f49Smrg  glutSwapBuffers();
14632001f49Smrg}
14732001f49Smrg
14832001f49Smrgstatic void
14932001f49Smrgidle(void)
15032001f49Smrg{
15132001f49Smrg  static float vel0 = -100.0;
15232001f49Smrg  static double t0 = -1.;
15332001f49Smrg  double t, dt;
15432001f49Smrg  t = glutGet(GLUT_ELAPSED_TIME) / 1000.;
15532001f49Smrg  if (t0 < 0.)
15632001f49Smrg     t0 = t;
15732001f49Smrg  dt = t - t0;
15832001f49Smrg  t0 = t;
15932001f49Smrg
16032001f49Smrg  Zrot += Zstep*dt;
16132001f49Smrg
16232001f49Smrg  Xpos += Xvel*dt;
16332001f49Smrg  if (Xpos >= Xmax) {
16432001f49Smrg    Xpos = Xmax;
16532001f49Smrg    Xvel = -Xvel;
16632001f49Smrg    Zstep = -Zstep;
16732001f49Smrg  }
16832001f49Smrg  if (Xpos <= Xmin) {
16932001f49Smrg    Xpos = Xmin;
17032001f49Smrg    Xvel = -Xvel;
17132001f49Smrg    Zstep = -Zstep;
17232001f49Smrg  }
17332001f49Smrg  Ypos += Yvel*dt;
17432001f49Smrg  Yvel += G*dt;
17532001f49Smrg  if (Ypos < Ymin) {
17632001f49Smrg    Ypos = Ymin;
17732001f49Smrg    if (vel0 == -100.0)
17832001f49Smrg      vel0 = fabs(Yvel);
17932001f49Smrg    Yvel = vel0;
18032001f49Smrg  }
18132001f49Smrg  glutPostRedisplay();
18232001f49Smrg}
18332001f49Smrg
18432001f49Smrgstatic void
18532001f49Smrgvisible(int vis)
18632001f49Smrg{
18732001f49Smrg  if (vis == GLUT_VISIBLE)
18832001f49Smrg    glutIdleFunc(idle);
18932001f49Smrg  else
19032001f49Smrg    glutIdleFunc(NULL);
19132001f49Smrg}
19232001f49Smrg
19332001f49Smrgint main(int argc, char *argv[])
19432001f49Smrg{
19532001f49Smrg  glutInitWindowSize(600, 450);
19632001f49Smrg  glutInit(&argc, argv);
19732001f49Smrg
19832001f49Smrg  IndexMode = argc > 1 && strcmp(argv[1], "-ci") == 0;
19932001f49Smrg  if (IndexMode)
20032001f49Smrg     glutInitDisplayMode(GLUT_INDEX | GLUT_DOUBLE);
20132001f49Smrg  else
20232001f49Smrg     glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
20332001f49Smrg
20432001f49Smrg  glutCreateWindow("Bounce");
20532001f49Smrg  Ball = make_ball();
20632001f49Smrg  glCullFace(GL_BACK);
20732001f49Smrg  glEnable(GL_CULL_FACE);
20832001f49Smrg  glDisable(GL_DITHER);
20932001f49Smrg  glShadeModel(GL_FLAT);
21032001f49Smrg
21132001f49Smrg  glutDisplayFunc(draw);
21232001f49Smrg  glutReshapeFunc(reshape);
21332001f49Smrg  glutVisibilityFunc(visible);
21432001f49Smrg  glutKeyboardFunc(key);
21532001f49Smrg
21632001f49Smrg  if (IndexMode) {
21732001f49Smrg    glutSetColor(RED, 1.0, 0.0, 0.0);
21832001f49Smrg    glutSetColor(WHITE, 1.0, 1.0, 1.0);
21932001f49Smrg    glutSetColor(CYAN, 0.0, 1.0, 1.0);
22032001f49Smrg  }
22132001f49Smrg
22232001f49Smrg  glutMainLoop();
22332001f49Smrg  return 0;             /* ANSI C requires main to return int. */
22432001f49Smrg}
225