#include <gl/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifndef PI
#define PI 3.14159265
#endif
static GLfloat viewRotateX=20.0,viewRotateY=30.0,viewRotateZ=0.0;
static GLfloat angle=0.0;
static GLfloat viewDist=40.0;
static GLint gear1,gear2,gear3;
static GLint T0=0;
static GLint Frames=0;
static GLint autoexit=0;
static GLint win=0;
static GLboolean visible=GL_TRUE;
static GLboolean animate=GL_TRUE;
void gear(GLfloat innerRadius,GLfloat outerRadius,GLfloat width,GLint teeth,GLfloat toothDepth)
{
GLfloat r0,r1,r2;
GLfloat angle,da;
GLfloat u,v,len;
GLint i;
r0=innerRadius;
r1=outerRadius-toothDepth/2.0;
r2=outerRadius+toothDepth/2.0;
da=2.0*PI/teeth/4.0;
glShadeModel(GL_FLAT);
glNormal3f(0.0,0.0,1.0);
//正面圆
glBegin(GL_QUAD_STRIP);
for(i=0;i<=teeth;i++)
{
angle=i*2.0*PI/teeth;
glVertex3f(r0*cos(angle),r0*sin(angle),width*0.5);
glVertex3f(r1*cos(angle),r1*sin(angle),width*0.5);
if(i<teeth)
{
glVertex3f(r0*cos(angle),r0*sin(angle),width*0.5);
glVertex3f(r1*cos(angle+3*da),r1*sin(angle+3*da),width*0.5);
}
}
glEnd();
//正面齿轮
glBegin(GL_QUADS);
for(i=0;i<=teeth;i++)
{
angle=i*2.0*PI/teeth;
glVertex3f(r1*cos(angle),r1*sin(angle),width*0.5);
glVertex3f(r2*cos(angle+da),r2*sin(angle+da),width*0.5);
glVertex3f(r2*cos(angle+2*da),r2*sin(angle+2*da),width*0.5);
glVertex3f(r1*cos(angle+3*da),r1*sin(angle+3*da),width*0.5);
}
glEnd();
glNormal3f(0.0,0.0,-1.0);
//背面圆
glBegin(GL_QUAD_STRIP);
for(i=0;i<=teeth;i++)
{
angle=i*2.0*PI/teeth;
glVertex3f(r1*cos(angle),r1*sin(angle),-width*0.5);
glVertex3f(r0*cos(angle),r0*sin(angle),-width*0.5);
//glVertex3f(r1*cos(angle),r1*sin(angle),-width*0.5);????????????????
if(i<teeth)
{
glVertex3f(r1*cos(angle+3*da),r1*sin(angle+3*da),-width*0.5);
glVertex3f(r0*cos(angle),r0*sin(angle),-width*0.5);
//glVertex3f(r1*cos(angle+3*da),r1*sin(angle+3*da),-width*0.5);?????????????????
}
}
glEnd();
//背面齿轮
glBegin(GL_QUADS);
for(i=0;i<=teeth;i++)
{
angle=i*2.0*PI/teeth;
glVertex3f(r1*cos(angle+3*da),r1*sin(angle+3*da),-width*0.5);
glVertex3f(r2*cos(angle+2*da),r2*sin(angle+2*da),-width*0.5);
glVertex3f(r2*cos(angle+da),r2*sin(angle+da),-width*0.5);
glVertex3f(r1*cos(angle),r1*sin(angle),-width*0.5);
}
glEnd();
//齿轮外观
glBegin(GL_QUAD_STRIP);
for(i=0;i<=teeth;i++)
{
angle=i*2.0*PI/teeth;
glVertex3f(r1*cos(angle),r1*sin(angle),width*0.5);
glVertex3f(r1*cos(angle),r1*sin(angle),-width*0.5);
u=r2*cos(angle+da)-r1*cos(angle);
v=r2*sin(angle+da)-r1*sin(angle);
len=sqrt(u*u+v*v);
u/=len;
v/=len;
glNormal3f(v,-u,0.0);
glVertex3f(r2*cos(angle+da),r2*sin(angle+da),width*0.5);
glVertex3f(r2*cos(angle+da),r2*sin(angle+da),-width*0.5);
glNormal3f(cos(angle),sin(angle),0.0);
glVertex3f(r2*cos(angle+2*da),r2*sin(angle+2*da),width*0.5);
glVertex3f(r2*cos(angle+2*da),r2*sin(angle+2*da),-width*0.5);
u=r1*cos(angle+3*da)-r2*cos(angle+2*da);
v=r1*sin(angle+3*da)-r2*sin(angle+2*da);
glNormal3f(v,-u,0.0);
glVertex3f(r1*cos(angle+3*da),r1*sin(angle+3*da),width*0.5);
glVertex3f(r1*cos(angle+3*da),r1*sin(angle+3*da),-width*0.5);
glNormal3f(cos(angle),sin(angle),0.0);
}
glVertex3f(r1*cos(0),r1*sin(0),width*0.5);
glVertex3f(r1*cos(0),r1*sin(0),-width*0.5);
glEnd();
glShadeModel(GL_SMOOTH);
//圆心外观
glBegin(GL_QUAD_STRIP);
for(i=0;i<=teeth;i++)
{
angle=i*2.0*PI/teeth;
glNormal3f(-cos(angle),-sin(angle),0.0);
glVertex3f(r0*cos(angle),r0*sin(angle),-width*0.5);
glVertex3f(r0*cos(angle),r0*sin(angle),width*0.5);
}
glEnd();
}
void Initial(int argc,char** argv)
{
static GLfloat lightPosition[4]={5.0,5.0,10.0,0.0};
static GLfloat red[4]={0.8,0.1,0.0,1.0};
static GLfloat green[4]={0.0,0.8,0.2,1.0};
static GLfloat blue[4]={0.2,0.2,1.0,1.0};
GLint i;
glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
gear1=glGenLists(1);
glNewList(gear1,GL_COMPILE);
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,red);
gear(1.0, 4.0, 1.0, 20, 0.7);
glEndList();
gear2=glGenLists(1);
glNewList(gear2,GL_COMPILE);
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,green);
gear(0.5, 2.0, 2.0, 10, 0.7);
glEndList();
gear3=glGenLists(1);
glNewList(gear3,GL_COMPILE);
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,blue);
gear(1.3, 2.0, 0.5, 10, 0.7);
glEndList();
glEnable(GL_NORMALIZE);
for(i=1;i<argc;i++)
{
if(strcmp(argv[i],"-info")==0)
{
printf("GL_RENDERER = %s/n", (char *) glGetString(GL_RENDERER));//渲染器
printf("GL_VERSION = %s/n", (char *) glGetString(GL_VERSION));//版本号
printf("GL_VENDOR = %s/n", (char *) glGetString(GL_VENDOR));//厂商名
printf("GL_EXTENSIONS = %s/n", (char *) glGetString(GL_EXTENSIONS));//到支持的扩展
}
else if(strcmp(argv[i],"-exit")==0)
{
autoexit=30;
printf("Auto Exit after %i seconds./n",autoexit);
}
}
}
void cleanUp(void)
{
glDeleteLists(gear1,1);//void glDeleteLists(GLuint list,GLsizei range);该函数删除从list起的连续range个显示序列
glDeleteLists(gear2,1);
glDeleteLists(gear3,1);
glutDestroyWindow(win);//销毁以win标记的窗口
}
void idle(void)
{
static double t0=-1;
double dt,t=glutGet(GLUT_ELAPSED_TIME)/1000.0;
if(t0<0.0)
t0=t;
dt=t-t0;
t0=t;
angle+=70.0*dt;
angle=fmod(angle,360.0);
glutPostRedisplay();
}
void updateIdleFunc(void)
{
if(visible&&animate)
glutIdleFunc(idle);
else
glutIdleFunc(NULL);
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0,0.0,-viewDist);
glRotatef(viewRotateX,1.0,0.0,0.0);
glRotatef(viewRotateY,0.0,1.0,0.0);
glRotatef(viewRotateZ,0.0,0.0,1.0);
glPushMatrix();
glTranslatef(-3.0, -2.0, 0.0);
glRotatef(angle, 0.0, 0.0, 1.0);
glCallList(gear1);
glPopMatrix();
glPushMatrix();
glTranslatef(3.1, -2.0, 0.0);
glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
glCallList(gear2);
glPopMatrix();
glPushMatrix();
glTranslatef(-3.1, 4.2, 0.0);
glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
glCallList(gear3);
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
Frames++;
{
GLint t=glutGet(GLUT_ELAPSED_TIME);
if(t-T0>=5000)
{
GLfloat seconds=(t-T0)/1000.0;
GLfloat fps=Frames/seconds;
printf("%d frames in %6.3f seconds = %6.3f FPS/n",Frames,seconds,fps);
T0=t;
Frames=0;
if((t>=999.0*autoexit)&&autoexit)
{
cleanUp();
exit(0);
}
}
}
}
//Z,z控制Z轴;D,d控制大小;a控制暂停;Esc控制退出
void myKeyboard(unsigned char k,int x,int y)
{
switch(k)
{
case 'Z':
viewRotateZ+=5.0;
break;
case 'z':
viewRotateZ-=5.0;
break;
case 'D':
viewDist+=1.0;
break;
case 'd':
viewDist-=1.0;;
break;
case 'a':
animate=!animate;
updateIdleFunc();
break;
case 27:
cleanUp();
exit(0);
break;
default:
return;
}
glutPostRedisplay();
}
void myReshape(GLsizei w,GLsizei h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-(GLfloat)h/(GLfloat)w,(GLfloat)h/(GLfloat)w,5.0,200.0);//void glFrustum(GLdouble left,GLdouble Right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);
glMatrixMode(GL_MODELVIEW);
}
上下左右,控制XY轴旋转
void mySpecial(int k,int x,int y)
{
switch(k)
{
case GLUT_KEY_UP:
viewRotateX+=5.0;
break;
case GLUT_KEY_DOWN:
viewRotateX-=5.0;
break;
case GLUT_KEY_LEFT:
viewRotateY+=5.0;
break;
case GLUT_KEY_RIGHT:
viewRotateY-=5.0;
break;
default:
return;
}
glutPostRedisplay();
}
void myVisible(int vis)
{
visible=vis;
updateIdleFunc();
}
int main(int argc,char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);
glutInitWindowSize(300,300);
glutInitWindowPosition(100,100);
win=glutCreateWindow("Gears");
Initial(argc,argv);
glutDisplayFunc(myDisplay);
glutReshapeFunc(myReshape);
glutKeyboardFunc(myKeyboard);
glutSpecialFunc(mySpecial);
glutVisibilityFunc(myVisible);
updateIdleFunc();
glutMainLoop();
return 0;
}
复杂的齿轮动画
最新推荐文章于 2024-06-19 09:48:36 发布