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