📄 bounce.c
字号:
/**************************************************************************
* *
* Copyright (C) 1988, 1989, 1990, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
/*
* foo $Revision: 1.4 $
*/
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
#include "tb.h"
#include "glui.h"
/* Some <math.h> files do not define M_PI... */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define UDIV 12
#define VDIV 12
#define WALLGRIDMAX 32
#define EYEZ 3.3
#define TOTALBALLS 3
#define R 0
#define G 1
#define B 2
#define X 0
#define Y 1
#define Z 2
#define W 3
int wallgrid = 8; /* sqrt of the number of quads in a wall */
float fatt = 1.0;
int freeze = GL_FALSE;
int spin = GL_FALSE;
int spinning = GL_FALSE;
int objecton = GL_FALSE;
int normson = GL_FALSE;
int lighton[3] = {GL_TRUE, GL_TRUE, GL_TRUE};
int window; /* main window id */
GLboolean performance = GL_FALSE; /* performance indicator */
struct {
float p[3];
float d[3];
unsigned char color[3];
} balls[TOTALBALLS];
float ballobj[UDIV+1][VDIV+1][4];
float wallobj[WALLGRIDMAX+1][WALLGRIDMAX+1][4];
float wallnorms[WALLGRIDMAX+1][WALLGRIDMAX+1][3];
float wallnorm[3] = { 0.0, 0.0, -1.0 };
int orx, ory;
float ballscale;
float ballsize;
int DELTAX, DELTAY;
int lflag = 0;
float newpos[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_Ka[] = { 0.3, 0.3, 0.3, 1.0 }; /* ambient */
GLfloat light_Ks[] = { 0.0, 0.0, 0.0, 1.0 }; /* specular */
GLfloat light0_Ka[] = { 0.0, 0.0, 0.0, 1.0 }; /* ambient */
GLfloat light0_Kd[] = { 1.0, 0.1, 0.1, 1.0 }; /* diffuse */
GLfloat light0_pos[] = { 0.0, 0.0, 0.0, 1.0 }; /* position */
GLfloat light1_Ka[] = { 0.0, 0.0, 0.0, 1.0 }; /* ambient */
GLfloat light1_Kd[] = { 0.1, 1.0, 0.1, 1.0 }; /* diffuse */
GLfloat light1_pos[] = { 0.0, 0.0, 0.0, 1.0 }; /* position */
GLfloat light2_Ka[] = { 0.0, 0.0, 0.0, 1.0 }; /* ambient */
GLfloat light2_Kd[] = { 0.1, 0.1, 1.0, 1.0 }; /* diffuse */
GLfloat light2_pos[] = { 0.0, 0.0, 0.0, 1.0 }; /* position */
GLfloat attenuation[] = { 1.0, 3.0 };
GLfloat plane_Ka[] = { 0.0, 0.0, 0.0, 1.0 }; /* ambient */
GLfloat plane_Kd[] = { 0.4, 0.4, 0.4, 1.0 }; /* diffuse */
GLfloat plane_Ks[] = { 1.0, 1.0, 1.0, 1.0 }; /* specular */
GLfloat plane_Ke[] = { 0.0, 0.0, 0.0, 1.0 }; /* emission */
GLfloat plane_Se = 30.0; /* shininess */
GLfloat wall_Ka[] = { 0.1, 0.1, 0.1, 1.0 }; /* ambient */
GLfloat wall_Kd[] = { 0.8, 0.8, 0.8, 1.0 }; /* diffuse */
GLfloat wall_Ks[] = { 1.0, 1.0, 1.0, 1.0 }; /* specular */
GLfloat wall_Ke[] = { 0.0, 0.0, 0.0, 1.0 }; /* emission */
GLfloat wall_Se = 20.0; /* shininess */
GLuint wall_material, plane_material; /* material display lists */
char ofile[80];
/************************************************************/
/* XXX - The following is an excerpt from spin.h from spin */
/************************************************************/
#define POLYGON 1
#define LINES 2
#define TRANSPERENT 3
#define DISPLAY 4
#define LMATERIAL 5
#define FASTMAGIC 0x5423
typedef struct fastobj {
int npoints;
int colors;
int type;
int material;
int display;
int ablend;
GLint *data;
} fastobj;
/*
* Wrappers to do either lines or polygons
*/
#define PolyOrLine() if (lflag == LINES) { \
glBegin(GL_LINE_LOOP); \
} else { \
glBegin(GL_POLYGON); \
}
#define EndPolyOrLine() if (lflag == LINES) { \
glEnd(); \
} else { \
glEnd(); \
}
/************************* end of spin.h excerpt *************************/
fastobj *obj = NULL;
/*
general purpose text routine. draws a string according to the
format in a stroke font at x, y after scaling it by the scale
specified. x, y and scale are all in window-space [i.e., pixels]
with origin at the lower-left.
*/
void
text(GLuint x, GLuint y, GLfloat scale, char* format, ...)
{
va_list args;
char buffer[255], *p;
GLfloat font_scale = 119.05 + 33.33;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT));
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glTranslatef(x, y, 0.0);
glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
for(p = buffer; *p; p++)
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
glPopAttrib();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
float
frand(void)
{
return 2.0*(rand()/32768.0 - .5);
}
void
resetballs(void)
{
register short i;
balls[0].color[R] = 255;
balls[0].color[G] = 64;
balls[0].color[B] = 64;
balls[1].color[R] = 64;
balls[1].color[G] = 255;
balls[1].color[B] = 64;
balls[2].color[R] = 64;
balls[2].color[G] = 64;
balls[2].color[B] = 255;
for (i = 0; i < TOTALBALLS; i++) {
balls[i].p[0] = 0.0;
balls[i].p[1] = 0.0;
balls[i].p[2] = 0.0;
balls[i].d[0] = .1*frand();
balls[i].d[1] = .1*frand();
balls[i].d[2] = .1*frand();
}
}
void
drawface(void)
{
register int i,j;
glNormal3fv(wallnorm);
for (i=0; i < wallgrid; i++) {
glBegin(GL_TRIANGLE_STRIP);
for (j=0; j <= wallgrid; j++) {
glVertex3fv(wallobj[i][j]);
glVertex3fv(wallobj[i+1][j]);
}
glEnd();
}
}
void
drawnorms(void)
{
register int i,j;
glDisable(GL_LIGHTING);
glColor3ub(255, 255, 0);
for (i=0; i <= wallgrid; i++) {
for (j=0; j <= wallgrid; j++) {
glBegin(GL_LINES);
glVertex3fv(wallobj[i][j]);
glVertex3fv(wallnorms[i][j]);
glEnd();
}
}
glEnable(GL_LIGHTING);
}
void
drawbox(void)
{
glPushMatrix();
/* drawface(); */
glRotatef(90.0, 0.0, 1.0, 0.0);
drawface();
if (normson) drawnorms();
glRotatef(90.0, 0.0, 1.0, 0.0);
drawface();
if (normson) drawnorms();
glRotatef(90.0, 0.0, 1.0, 0.0);
/* drawface(); */
glRotatef(-90.0, 1.0, 0.0, 0.0);
drawface();
if (normson) drawnorms();
glRotatef(180.0, 1.0, 0.0, 0.0);
/* drawface(); */
glPopMatrix();
}
void
drawfastobj(fastobj *obj)
{
register GLint *p, *end;
register int npolys;
p = obj->data;
end = p + 8 * obj->npoints;
if(obj->colors) {
npolys = obj->npoints/4;
while(npolys--) {
PolyOrLine();
glColor3iv(p);
glVertex3fv((float *)p+4);
glColor3iv(p+8);
glVertex3fv((float *)p+12);
glColor3iv(p+16);
glVertex3fv((float *)p+20);
glColor3iv(p+24);
glVertex3fv((float *)p+28);
EndPolyOrLine();
p += 32;
}
} else {
while ( p < end) {
PolyOrLine();
glNormal3fv((float *)p);
glVertex3fv((float *)p+4);
glNormal3fv((float *)p+8);
glVertex3fv((float *)p+12);
glNormal3fv((float *)p+16);
glVertex3fv((float *)p+20);
glNormal3fv((float *)p+24);
glVertex3fv((float *)p+28);
EndPolyOrLine();
p += 32;
}
}
}
void
drawball(void)
{
register int i,j;
for (i=0; i < UDIV; i++) {
for (j=0; j < VDIV; j++) {
glBegin(GL_POLYGON);
glVertex4fv( ballobj[i][j] );
glVertex4fv( ballobj[i+1][j] );
glVertex4fv( ballobj[i+1][j+1] );
glVertex4fv( ballobj[i][j+1] );
glEnd();
}
}
}
void
drawimage(void)
{
register short i;
static int start, end, last;
glutSetWindow(window);
if (performance)
start = glutGet(GLUT_ELAPSED_TIME);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
tbMatrix();
for (i=0; i < TOTALBALLS; i++) {
newpos[0] = balls[i].p[0];
newpos[1] = balls[i].p[1];
newpos[2] = balls[i].p[2];
glLightfv(GL_LIGHT0 + i, GL_POSITION, newpos);
}
glCallList(wall_material);
glEnable(GL_LIGHTING);
drawbox();
glEnable(GL_DEPTH_TEST);
if (objecton)
{
glCallList(plane_material);
glPushMatrix();
glScalef(1.5, 1.5, 1.5);
glRotatef(180.0, 0.0, 0.0, 1.0);
if (spin)
{
orx += 50;
ory += 50;
}
glRotatef(orx/10.0, 1.0, 0.0, 0.0);
glRotatef(ory/10.0, 0.0, 1.0, 0.0);
drawfastobj(obj);
glPopMatrix();
}
glDisable(GL_LIGHTING);
for (i=0; i < TOTALBALLS; i++) {
if (lighton[i])
{
glPushMatrix();
glTranslatef(balls[i].p[0],balls[i].p[1],balls[i].p[2]);
glColor3ubv(balls[i].color);
drawball();
glPopMatrix();
}
}
glColor3f(1.0, 1.0, 1.0);
if (performance) {
if (end - last == 0) {
text(10, 73, 20, "unknown fps");
} else {
text(10, 73, 20, "%.0f fps", 1.0 / ((end - last) / 1000.0));
}
last = start;
}
text(10, 43, 14, "Attenuation [%.2f]", fatt);
text(10, 13, 14, "Tesselation [%3d]", wallgrid);
glPopMatrix();
glutSwapBuffers();
if (performance)
end = glutGet(GLUT_ELAPSED_TIME);
}
void
initobjects(void)
{
register float u,v,du,dv;
register short i,j;
du = 2.0*M_PI/UDIV;
dv = M_PI/VDIV;
u = 0.;
for (i=0; i <= UDIV; i++) {
v = 0.;
for (j=0; j <= VDIV; j++) {
ballobj[i][j][X] = ballsize*cos(u)*sin(v);
ballobj[i][j][Y] = ballsize*sin(u)*sin(v);
ballobj[i][j][Z] = ballsize*cos(v);
ballobj[i][j][W] = 1.0;
v += dv;
}
u += du;
}
for (i=0; i <= wallgrid; i++) {
for (j=0; j <= wallgrid; j++) {
wallobj[i][j][X] = -1.0 + 2.0*i/wallgrid;
wallobj[i][j][Y] = -1.0 + 2.0*j/wallgrid;
wallobj[i][j][Z] = 1.0;
wallobj[i][j][W] = 1.0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -