📄 bounce.c
字号:
}
for (i=0; i <= wallgrid; i++) {
for (j=0; j <= wallgrid; j++) {
wallnorms[i][j][X] = wallobj[i][j][X] + wallnorm[X]*0.1;
wallnorms[i][j][Y] = wallobj[i][j][Y] + wallnorm[Y]*0.1;
wallnorms[i][j][Z] = wallobj[i][j][Z] + wallnorm[Z]*0.1;
}
}
}
int MOUSEX, MOUSEY;
static void
mouse(int button, int state, int x, int y)
{
MOUSEX = x;
MOUSEY = y;
tbMouse(button, state, x, y);
}
static void
motion(int x, int y)
{
DELTAX -= MOUSEX - x;
DELTAY += MOUSEY - y;
MOUSEX = x;
MOUSEY = y;
tbMotion(x, y);
}
/* ARGSUSED1 */
void
keyboard(unsigned char key, int x, int y)
{
switch(key) {
case 27: /* ESC */
exit(0);
break;
case '+':
wallgrid++;
if (wallgrid > WALLGRIDMAX)
wallgrid = WALLGRIDMAX;
initobjects();
break;
case '-':
wallgrid--;
if (wallgrid < 1)
wallgrid = 1;
initobjects();
break;
}
}
void
initialize(void)
{
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
window = glutCreateWindow("bounce");
initobjects();
srand(glutGet(GLUT_ELAPSED_TIME));
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, light_Ka);
plane_material = glGenLists(1);
glNewList(plane_material, GL_COMPILE);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, plane_Ka);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, plane_Kd);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, plane_Ks);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, plane_Ke);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, plane_Se);
glEndList();
wall_material = glGenLists(1);
glNewList(wall_material, GL_COMPILE);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, wall_Ka);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, wall_Kd);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, wall_Ks);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, wall_Ke);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, wall_Se);
glEndList();
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_Ka);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_Kd);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, attenuation[0]);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, attenuation[1]);
/* OpenGL's light0 has different specular properties than the rest
of the lights.... */
glLightfv(GL_LIGHT0, GL_SPECULAR, light_Ks);
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_Ka);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_Kd);
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, attenuation[0]);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, attenuation[1]);
glLightfv(GL_LIGHT2, GL_AMBIENT, light2_Ka);
glLightfv(GL_LIGHT2, GL_DIFFUSE, light2_Kd);
glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, attenuation[0]);
glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, attenuation[1]);
glutMotionFunc(motion);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
}
void
calcball(void)
{
register short i,j;
for (j=0; j < TOTALBALLS; j++) {
for (i=0; i < 3; i++) {
balls[j].p[i] += balls[j].d[i];
if (fabs(balls[j].p[i]) > ballscale) {
balls[j].p[i] = (balls[j].p[i] > 0.0) ?
ballscale : -ballscale;
balls[j].d[i] = -balls[j].d[i];
}
}
}
}
static void menu(int value);
static void idle(void);
static void
make_menu(void)
{
static int main_menu = 0;
if (main_menu)
glutDestroyMenu(main_menu);
main_menu = glutCreateMenu(menu);
glutAddMenuEntry("bounce", 0);
glutAddMenuEntry("", 0);
if (lighton[0])
glutAddMenuEntry("red light off", 1);
else
glutAddMenuEntry("red light on", 1);
if (lighton[1])
glutAddMenuEntry("green light off", 2);
else
glutAddMenuEntry("green light on", 2);
if (lighton[2])
glutAddMenuEntry("blue light off", 3);
else
glutAddMenuEntry("blue light on", 3);
if (freeze)
glutAddMenuEntry("unfreeze lights", 4);
else
glutAddMenuEntry("freeze lights", 4);
if (normson)
glutAddMenuEntry("normals off", 7);
else
glutAddMenuEntry("normals on", 7);
if (performance)
glutAddMenuEntry("frame rate off", 8);
else
glutAddMenuEntry("frame rate on", 8);
if (obj)
{
if (objecton)
glutAddMenuEntry("object off", 5);
else
glutAddMenuEntry("object on", 5);
if (spin)
glutAddMenuEntry("object spin off", 6);
else
glutAddMenuEntry("object spin on", 6);
}
glutAddMenuEntry("", 0);
glutAddMenuEntry("exit", 9);
glutAttachMenu(GLUT_RIGHT_BUTTON);
}
static void
menu(int value)
{
switch(value) {
case 1:
if ((lighton[0] = !lighton[0]))
glEnable(GL_LIGHT0);
else
glDisable(GL_LIGHT0);
break;
case 2:
if ((lighton[1] = !lighton[1]))
glEnable(GL_LIGHT1);
else
glDisable(GL_LIGHT1);
break;
case 3:
if ((lighton[2] = !lighton[2]))
glEnable(GL_LIGHT2);
else
glDisable(GL_LIGHT2);
break;
case 4:
freeze = !freeze;
if (!freeze || spinning) {
glutIdleFunc(idle);
} else {
glutIdleFunc(NULL);
}
break;
case 5:
if (obj)
objecton = !objecton;
else
exit(1);
break;
case 6:
spin = !spin;
break;
case 7:
normson = !normson;
break;
case 8:
performance = !performance;
break;
case 9:
exit(0);
break;
}
glutPostWindowRedisplay(window);
make_menu();
}
/**********************************************************/
/* XXX - The following is a clone of fastobj.c from spin */
/**********************************************************/
fastobj*
readfastobj(char *name)
{
FILE *inf;
fastobj *obj;
int i;
int nlongs;
int magic;
GLint *ip;
char filename[512];
inf = fopen(name,"r");
if(!inf) {
sprintf(filename,"%s",name);
inf = fopen(filename,"r");
if(!inf) {
fprintf(stderr,"readfast: can't open input file %s\n",name);
exit(1);
}
}
fread(&magic,sizeof(int),1,inf);
if(magic != FASTMAGIC) {
fprintf(stderr,"readfast: bad magic in object file\n");
fclose(inf);
exit(1);
}
obj = (fastobj *)malloc(sizeof(fastobj));
fread(&obj->npoints,sizeof(int),1,inf);
fread(&obj->colors,sizeof(int),1,inf);
/*
* Insure that the data is quad-word aligned and begins on a page
* boundary. This shields us from the performance loss which occurs
* whenever we try to fetch data which straddles a page boundary (the OS
* has to map in the next virtual page and re-start the DMA transfer).
*/
nlongs = 8 * obj->npoints;
obj->data = (GLint *) malloc(nlongs*sizeof(int) + 4096);
obj->data = (GLint *) (((int)(obj->data)) + 0xfff);
obj->data = (GLint *) (((int)(obj->data)) & 0xfffff000);
/* XXX Careful, sizeof(GLint) could change from implementation
to implementation making this file format implementation
dependent. -mjk */
for (i = 0, ip = obj->data; i < nlongs/4; i++, ip += 4)
fread(ip, 3 * sizeof(GLint), 1, inf);
fclose(inf);
return obj;
}
/*
* objmaxpoint
*
* find the vertex farthest from the origin,
* so we can set the near and far clipping planes tightly.
*/
#define MAXVERT(v) if ( (len = sqrt( (*(v)) * (*(v)) + \
(*(v+1)) * (*(v+1)) + \
(*(v+2)) * (*(v+2)) )) > max) \
max = len;
float
objmaxpoint(obj)
fastobj *obj;
{
register float *p, *end;
register int npolys;
register float len;
register float max = 0.0;
p = (float *) (obj->data);
if (obj->colors) {
npolys = obj->npoints/4;
while(npolys--) {
MAXVERT(p+4);
MAXVERT(p+12);
MAXVERT(p+20);
MAXVERT(p+28);
p += 32;
}
} else {
end = p + 8 * obj->npoints;
while ( p < end) {
MAXVERT(p+4);
MAXVERT(p+12);
MAXVERT(p+20);
MAXVERT(p+28);
p += 32;
}
}
return max;
}
static void
idle(void)
{
assert(!freeze || spinning);
if (!freeze) {
calcball();
}
if (spinning) {
tbStepAnimation();
}
glutPostWindowRedisplay(window);
}
/* When not visible, stop animating. Restart when visible again. */
static void
visible(int vis)
{
if (vis == GLUT_VISIBLE) {
if (!freeze || spinning)
glutIdleFunc(idle);
} else {
if (!freeze || spinning)
glutIdleFunc(NULL);
}
}
static void
reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (float)width/height, EYEZ-2.0, EYEZ+2.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.25, -EYEZ);
tbReshape(width, height);
gluiReshape(width, height);
}
void
update_fatt(float value)
{
fatt = 5 * value;
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, fatt);
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, fatt);
glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, fatt);
glutPostWindowRedisplay(window);
}
void
update_grid(float value)
{
wallgrid = WALLGRIDMAX*value;
if (wallgrid < 1)
wallgrid = 1;
initobjects();
glutPostWindowRedisplay(window);
}
void
spinChange(int state)
{
spinning = state;
if (spinning || !freeze) {
glutIdleFunc(idle);
} else {
glutIdleFunc(NULL);
}
}
int
main(int argc, char **argv)
{
glutInitWindowSize(512, 512);
glutInitWindowPosition(64, 64);
glutInit(&argc, argv);
if (argc > 1)
{
int i;
for (i=0; argv[1][i] != '/' && argv[1][i] != '\0'; i++);
if (argv[1][i] != '/')
{
strcpy(ofile, "/usr/demos/data/models/");
strcat(ofile, argv[1]);
}
else
strcpy(ofile, argv[1]);
if (obj = readfastobj(ofile))
objecton = GL_TRUE;
}
ballsize = .04;
ballscale = 1.0 - ballsize;
initialize();
make_menu();
resetballs();
/* Use local lights for the box */
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
make_menu();
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(drawimage);
glutReshapeFunc(reshape);
glutVisibilityFunc(visible);
gluiHorizontalSlider(window, 130, -10, -10, 20,
(float)wallgrid/WALLGRIDMAX, update_grid);
gluiHorizontalSlider(window, 130, -40, -10, 20, fatt/5.0, update_fatt);
tbInit(GLUT_LEFT_BUTTON);
tbAnimate(1);
tbAnimateFunc(spinChange);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -