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