227 lines
4.0 KiB
C
227 lines
4.0 KiB
C
|
|
/*
|
|
* Bouncing ball demo.
|
|
*
|
|
* This program is in the public domain
|
|
*
|
|
* Brian Paul
|
|
*
|
|
* Conversion to GLUT by Mark J. Kilgard
|
|
*/
|
|
|
|
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <GL/glut.h>
|
|
|
|
#define COS(X) cos( (X) * 3.14159/180.0 )
|
|
#define SIN(X) sin( (X) * 3.14159/180.0 )
|
|
|
|
#define RED 1
|
|
#define WHITE 2
|
|
#define CYAN 3
|
|
|
|
GLboolean IndexMode = GL_FALSE;
|
|
GLuint Ball;
|
|
GLenum Mode;
|
|
GLfloat Zrot = 0.0, Zstep = 180.0;
|
|
GLfloat Xpos = 0.0, Ypos = 1.0;
|
|
GLfloat Xvel = 2.0, Yvel = 0.0;
|
|
GLfloat Xmin = -4.0, Xmax = 4.0;
|
|
GLfloat Ymin = -3.8, Ymax = 4.0;
|
|
GLfloat G = -9.8;
|
|
|
|
static GLuint
|
|
make_ball(void)
|
|
{
|
|
GLuint list;
|
|
GLfloat a, b;
|
|
GLfloat da = 18.0, db = 18.0;
|
|
GLfloat radius = 1.0;
|
|
GLuint color;
|
|
GLfloat x, y, z;
|
|
|
|
list = glGenLists(1);
|
|
|
|
glNewList(list, GL_COMPILE);
|
|
|
|
color = 0;
|
|
for (a = -90.0; a + da <= 90.0; a += da) {
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
for (b = 0.0; b <= 360.0; b += db) {
|
|
|
|
if (color) {
|
|
glIndexi(RED);
|
|
glColor3f(1, 0, 0);
|
|
} else {
|
|
glIndexi(WHITE);
|
|
glColor3f(1, 1, 1);
|
|
}
|
|
|
|
x = radius * COS(b) * COS(a);
|
|
y = radius * SIN(b) * COS(a);
|
|
z = radius * SIN(a);
|
|
glVertex3f(x, y, z);
|
|
|
|
x = radius * COS(b) * COS(a + da);
|
|
y = radius * SIN(b) * COS(a + da);
|
|
z = radius * SIN(a + da);
|
|
glVertex3f(x, y, z);
|
|
|
|
color = 1 - color;
|
|
}
|
|
glEnd();
|
|
|
|
}
|
|
|
|
glEndList();
|
|
|
|
return list;
|
|
}
|
|
|
|
static void
|
|
reshape(int width, int height)
|
|
{
|
|
float aspect = (float) width / (float) height;
|
|
glViewport(0, 0, (GLint) width, (GLint) height);
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glOrtho(-6.0 * aspect, 6.0 * aspect, -6.0, 6.0, -6.0, 6.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
}
|
|
|
|
/* ARGSUSED1 */
|
|
static void
|
|
key(unsigned char k, int x, int y)
|
|
{
|
|
switch (k) {
|
|
case 27: /* Escape */
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
static void
|
|
draw(void)
|
|
{
|
|
GLint i;
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
glIndexi(CYAN);
|
|
glColor3f(0, 1, 1);
|
|
glBegin(GL_LINES);
|
|
for (i = -5; i <= 5; i++) {
|
|
glVertex2i(i, -5);
|
|
glVertex2i(i, 5);
|
|
}
|
|
for (i = -5; i <= 5; i++) {
|
|
glVertex2i(-5, i);
|
|
glVertex2i(5, i);
|
|
}
|
|
for (i = -5; i <= 5; i++) {
|
|
glVertex2i(i, -5);
|
|
glVertex2f(i * 1.15, -5.9);
|
|
}
|
|
glVertex2f(-5.3, -5.35);
|
|
glVertex2f(5.3, -5.35);
|
|
glVertex2f(-5.75, -5.9);
|
|
glVertex2f(5.75, -5.9);
|
|
glEnd();
|
|
|
|
glPushMatrix();
|
|
glTranslatef(Xpos, Ypos, 0.0);
|
|
glScalef(2.0, 2.0, 2.0);
|
|
glRotatef(8.0, 0.0, 0.0, 1.0);
|
|
glRotatef(90.0, 1.0, 0.0, 0.0);
|
|
glRotatef(Zrot, 0.0, 0.0, 1.0);
|
|
|
|
glCallList(Ball);
|
|
|
|
glPopMatrix();
|
|
|
|
glFlush();
|
|
glutSwapBuffers();
|
|
}
|
|
|
|
static void
|
|
idle(void)
|
|
{
|
|
static float vel0 = -100.0;
|
|
static double t0 = -1.;
|
|
double t, dt;
|
|
t = glutGet(GLUT_ELAPSED_TIME) / 1000.;
|
|
if (t0 < 0.)
|
|
t0 = t;
|
|
dt = t - t0;
|
|
t0 = t;
|
|
|
|
Zrot += Zstep*dt;
|
|
|
|
Xpos += Xvel*dt;
|
|
if (Xpos >= Xmax) {
|
|
Xpos = Xmax;
|
|
Xvel = -Xvel;
|
|
Zstep = -Zstep;
|
|
}
|
|
if (Xpos <= Xmin) {
|
|
Xpos = Xmin;
|
|
Xvel = -Xvel;
|
|
Zstep = -Zstep;
|
|
}
|
|
Ypos += Yvel*dt;
|
|
Yvel += G*dt;
|
|
if (Ypos < Ymin) {
|
|
Ypos = Ymin;
|
|
if (vel0 == -100.0)
|
|
vel0 = fabs(Yvel);
|
|
Yvel = vel0;
|
|
}
|
|
glutPostRedisplay();
|
|
}
|
|
|
|
static void
|
|
visible(int vis)
|
|
{
|
|
if (vis == GLUT_VISIBLE)
|
|
glutIdleFunc(idle);
|
|
else
|
|
glutIdleFunc(NULL);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
glutInit(&argc, argv);
|
|
glutInitWindowPosition(0, 0);
|
|
glutInitWindowSize(600, 450);
|
|
|
|
|
|
IndexMode = argc > 1 && strcmp(argv[1], "-ci") == 0;
|
|
if (IndexMode)
|
|
glutInitDisplayMode(GLUT_INDEX | GLUT_DOUBLE);
|
|
else
|
|
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
|
|
|
glutCreateWindow("Bounce");
|
|
Ball = make_ball();
|
|
glCullFace(GL_BACK);
|
|
glEnable(GL_CULL_FACE);
|
|
glDisable(GL_DITHER);
|
|
glShadeModel(GL_FLAT);
|
|
|
|
glutDisplayFunc(draw);
|
|
glutReshapeFunc(reshape);
|
|
glutVisibilityFunc(visible);
|
|
glutKeyboardFunc(key);
|
|
|
|
if (IndexMode) {
|
|
glutSetColor(RED, 1.0, 0.0, 0.0);
|
|
glutSetColor(WHITE, 1.0, 1.0, 1.0);
|
|
glutSetColor(CYAN, 0.0, 1.0, 1.0);
|
|
}
|
|
|
|
glutMainLoop();
|
|
return 0; /* ANSI C requires main to return int. */
|
|
}
|