openGPMP
Open Source Mathematics Package
openGL_bounce.c
Go to the documentation of this file.
1 /*
2  * Testing openGL with drawing an animate torus
3  */
4 #include <GL/glut.h>
5 #include <cmath>
6 #include <math.h>
7 #include <stdio.h>
8 
9 #define pi 3.142857
10 
11 // Colors
12 GLfloat WHITE[] = {1, 1, 1};
13 GLfloat RED[] = {1, 0, 0};
14 GLfloat GREEN[] = {0, 1, 0};
15 GLfloat MAGENTA[] = {1, 0, 1};
16 
17 // A camera. It moves horizontally in a circle centered at the origin
18 // of radius 10. It moves vertically straight up and down.
19 class Camera {
20  double theta; // determines the x and z positions
21  double y; // the current y position
22  double dTheta; // increment in theta for swinging the camera around
23  double dy; // increment in y for moving the camera up/down
24 
25  public:
26  Camera() : theta(0), y(3), dTheta(0.04), dy(0.2) {
27  }
28 
29  double getX() {
30  return 10 * cos(theta);
31  }
32 
33  double getY() {
34  return y;
35  }
36 
37  double getZ() {
38  return 10 * sin(theta);
39  }
40 
41  void moveRight() {
42  theta += dTheta;
43  }
44 
45  void moveLeft() {
46  theta -= dTheta;
47  }
48 
49  void moveUp() {
50  y += dy;
51  }
52 
53  void moveDown() {
54  if (y > dy)
55  y -= dy;
56  }
57 };
58 
59 // A ball. A ball has a radius, a color, and bounces up and down
60 // between a maximum height and the xz plane. Therefore its x and z
61 // coordinates are fixed. It uses a lame bouncing algorithm, simply
62 // moving up or down by 0.05 units at each frame.
63 class Ball {
64  double radius;
65  GLfloat *color;
66  double maximumHeight;
67  double x;
68  double y;
69  double z;
70  int direction;
71 
72  public:
73  Ball(double r, GLfloat *c, double h, double x, double z)
74  : radius(r), color(c), maximumHeight(h), direction(-1), y(h), x(x),
75  z(z) {
76  }
77 
78  void update() {
79  y += direction * 0.05;
80 
81  if (y > maximumHeight) {
82  y = maximumHeight;
83  direction = -1;
84  }
85 
86  else if (y < radius) {
87  y = radius;
88  direction = 1;
89  }
90 
91  glPushMatrix();
92  glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
93  glTranslated(x, y, z);
94  glutSolidSphere(radius, 30, 30);
95  glPopMatrix();
96  }
97 };
98 
99 // A checkerboard class. A checkerboard has alternating red and white
100 // squares. The number of squares is set in the constructor. Each
101 // square is 1 x 1. One corner of the board is (0, 0) and the board
102 // stretches out along positive x and positive z. It rests on the xz
103 // plane. I put a spotlight at (4, 3, 7).
106  int width;
107  int depth;
108 
109  public:
111  }
112 
113  double centerx() {
114  return width / 2;
115  }
116  double centerz() {
117  return depth / 2;
118  }
119 
120  void create() {
121  displayListId = glGenLists(1);
122  glNewList(displayListId, GL_COMPILE);
123  GLfloat lightPosition[] = {4, 3, 7, 1};
124  glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
125  glBegin(GL_QUADS);
126  glNormal3d(0, 1, 0);
127 
128  for (int x = 0; x < width - 1; x++) {
129  for (int z = 0; z < depth - 1; z++) {
130  glMaterialfv(GL_FRONT,
131  GL_AMBIENT_AND_DIFFUSE,
132  (x + z) % 2 == 0 ? RED : WHITE);
133 
134  glVertex3d(x, 0, z);
135  glVertex3d(x + 1, 0, z);
136  glVertex3d(x + 1, 0, z + 1);
137  glVertex3d(x, 0, z + 1);
138  }
139  }
140  glEnd();
141  glEndList();
142  }
143 
144  void draw() {
145  glCallList(displayListId);
146  }
147 };
148 
149 // Global variables: a camera, a checkerboard and some balls.
152 Ball balls[] = {Ball(1, GREEN, 7, 6, 1),
153  Ball(1.5, MAGENTA, 6, 3, 4),
154  Ball(0.4, WHITE, 5, 1, 7)};
155 
156 // Application-specific initialization: Set up global lighting
157 // parameters and create display lists.
158 void init() {
159  glEnable(GL_DEPTH_TEST);
160  glLightfv(GL_LIGHT0, GL_DIFFUSE, WHITE);
161  glLightfv(GL_LIGHT0, GL_SPECULAR, WHITE);
162  glMaterialfv(GL_FRONT, GL_SPECULAR, WHITE);
163  glMaterialf(GL_FRONT, GL_SHININESS, 30);
164  glEnable(GL_LIGHTING);
165  glEnable(GL_LIGHT0);
167 }
168 
169 // Draws one frame, the checkerboard then the balls, from the current
170 // camera position.
171 void display() {
172  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
173  glLoadIdentity();
174  gluLookAt(camera.getX(),
175  camera.getY(),
176  camera.getZ(),
178  0.0,
180  0.0,
181  1.0,
182  0.0);
183  checkerboard.draw();
184  for (int i = 0; i < sizeof balls / sizeof(Ball); i++) {
185  balls[i].update();
186  }
187  glFlush();
188  glutSwapBuffers();
189 }
190 
191 // On reshape, constructs a camera that perfectly fits the window.
192 void reshape(GLint w, GLint h) {
193  glViewport(0, 0, w, h);
194  glMatrixMode(GL_PROJECTION);
195  glLoadIdentity();
196  gluPerspective(40.0, GLfloat(w) / GLfloat(h), 1.0, 150.0);
197  glMatrixMode(GL_MODELVIEW);
198 }
199 
200 // Requests to draw the next frame.
201 void timer(int v) {
202  glutPostRedisplay();
203  glutTimerFunc(1000 / 60, timer, v);
204 }
205 
206 // Moves the camera according to the key pressed, then ask to refresh
207 // the display.
208 void special(int key, int, int) {
209  switch (key) {
210  case GLUT_KEY_LEFT:
211  camera.moveLeft();
212  break;
213  case GLUT_KEY_RIGHT:
214  camera.moveRight();
215  break;
216  case GLUT_KEY_UP:
217  camera.moveUp();
218  break;
219  case GLUT_KEY_DOWN:
220  camera.moveDown();
221  break;
222  }
223  glutPostRedisplay();
224 }
225 
226 // Initializes GLUT and enters the main loop.
227 int main(int argc, char **argv) {
228  glutInit(&argc, argv);
229  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
230  glutInitWindowPosition(80, 80);
231  glutInitWindowSize(800, 600);
232  glutCreateWindow("Bouncing Balls");
233  glutDisplayFunc(display);
234  glutReshapeFunc(reshape);
235  glutSpecialFunc(special);
236  glutTimerFunc(100, timer, 0);
237  init();
238  glutMainLoop();
239 }
double y
Definition: openGL_bounce.c:68
double maximumHeight
Definition: openGL_bounce.c:66
double x
Definition: openGL_bounce.c:67
Ball(double r, GLfloat *c, double h, double x, double z)
Definition: openGL_bounce.c:73
GLfloat * color
Definition: openGL_bounce.c:65
int direction
Definition: openGL_bounce.c:70
double z
Definition: openGL_bounce.c:69
double radius
Definition: openGL_bounce.c:64
void update()
Definition: openGL_bounce.c:78
double getY()
Definition: openGL_bounce.c:33
double getX()
Definition: openGL_bounce.c:29
double dy
Definition: openGL_bounce.c:23
void moveUp()
Definition: openGL_bounce.c:49
double y
Definition: openGL_bounce.c:21
double theta
Definition: openGL_bounce.c:20
void moveDown()
Definition: openGL_bounce.c:53
double dTheta
Definition: openGL_bounce.c:22
void moveLeft()
Definition: openGL_bounce.c:45
void moveRight()
Definition: openGL_bounce.c:41
double getZ()
Definition: openGL_bounce.c:37
Checkerboard(int width, int depth)
double centerz()
double centerx()
void init()
GLfloat RED[]
Definition: openGL_bounce.c:13
void display()
Camera camera
void reshape(GLint w, GLint h)
GLfloat MAGENTA[]
Definition: openGL_bounce.c:15
int main(int argc, char **argv)
void special(int key, int, int)
GLfloat GREEN[]
Definition: openGL_bounce.c:14
void timer(int v)
Ball balls[]
Checkerboard checkerboard(8, 8)
GLfloat WHITE[]
Definition: openGL_bounce.c:12