📄 dinospin.c
字号:
GLfloat m[4][4];
glPopMatrix();
glPushMatrix();
build_rotmatrix(m, curquat);
glMultMatrixf(&m[0][0]);
if (scalefactor == 1.0) {
glEnable(GL_NORMALIZE);
} else {
glEnable(GL_NORMALIZE);
}
}
void
showMessage(GLfloat x, GLfloat y, GLfloat z, char *message)
{
glPushMatrix();
glDisable(GL_LIGHTING);
glTranslatef(x, y, z);
glScalef(.02, .02, .02);
while (*message) {
glutStrokeCharacter(GLUT_STROKE_ROMAN, *message);
message++;
}
glEnable(GL_LIGHTING);
glPopMatrix();
}
typedef GLfloat point3[3];
// List all vertices in array and reference later by index
/* six equidistant points lying on the unit sphere */
#define XPLUS { 1, 0, 0 } /* X */
#define XMIN { -1, 0, 0 } /* -X */
#define YPLUS { 0, 1, 0 } /* Y */
#define YMIN { 0, -1, 0 } /* -Y */
#define ZPLUS { 0, 0, 1 } /* Z */
#define ZMIN { 0, 0, -1 } /* -Z */
/* for icosahedron */
#define CZ (0.89442719099991) /* 2/sqrt(5) */
#define SZ (0.44721359549995) /* 1/sqrt(5) */
#define C1 (0.95105651629515) /* cos(18), */
#define S1 (0.30901699437495) /* sin(18) */
#define C2 (0.58778525229247) /* cos(54), */
#define S2 (0.80901699437495) /* sin(54) */
#define X1 (C1*CZ)
#define Y1 (S1*CZ)
#define X2 (C2*CZ)
#define Y2 (S2*CZ)
#define Ip0 {0., 0., 1.}
#define Ip1 {-X2, -Y2, SZ}
#define Ip2 {X2, -Y2, SZ}
#define Ip3 {X1, Y1, SZ}
#define Ip4 {0, CZ, SZ}
#define Ip5 {-X1, Y1, SZ}
#define Im0 {-X1, -Y1, -SZ}
#define Im1 {0, -CZ, -SZ}
#define Im2 {X1, -Y1, -SZ}
#define Im3 {X2, Y2, -SZ}
#define Im4 {-X2, Y2, -SZ}
#define Im5 {0., 0., -1.}
/* vertices of a unit icosahedron */
static point3 p[20][3]= {
/* front pole */
{ Ip0, Ip1, Ip2 },
{ Ip0, Ip5, Ip1 },
{ Ip0, Ip4, Ip5 },
{ Ip0, Ip3, Ip4 },
{ Ip0, Ip2, Ip3 },
/* mid */
{ Ip1, Ip5, Im0 },
{ Ip5, Ip4, Im4 },
{ Ip4, Ip3, Im3 },
{ Ip3, Ip2, Im2 },
{ Ip2, Ip1, Im1 },
{ Im0, Im1, Ip1 },
{ Im1, Im2, Ip2 },
{ Im2, Im3, Ip3 },
{ Im3, Im4, Ip4 },
{ Im4, Im0, Ip5 },
/* back pole */
{ Im5, Im3, Im2 },
{ Im5, Im4, Im3 },
{ Im5, Im0, Im4 },
{ Im5, Im1, Im0 },
{ Im5, Im2, Im1 },
};
int depth; //recursion depth
void sub(point3 p2,point3 p1,point3 diff){
// diff = p2 - p1
int i;
for(i=0;i<3;i++)
{
diff[i]=p2[i]-p1[i];
}
}
void findNormal(point3 p1,point3 p2,point3 p3,point3 n){
// n = (p2-p1) x (p3-p2)
point3 u,v;
sub(p2,p1,u);
sub(p3,p2,v);
n[0]=u[1]*v[2]-u[2]*v[1];
n[1]=u[2]*v[0]-u[0]*v[2];
n[2]=u[0]*v[1]-u[1]*v[0];
}
void normalize(point3 p){
int i;
GLfloat x=0;
for(i=0;i<3;i++)x+=p[i]*p[i];
for(i=0;i<3;i++)p[i]/=sqrt(x);
}
void drawFace(int depth,point3 p1,point3 p2,point3 p3){
// Draw polygon p1 p2 p3, or recursively subdivide
if(depth<=0){
point3 n;
findNormal(p1,p2,p3,n);
glBegin(GL_POLYGON);
glNormal3fv(n);
glVertex3fv(p1);
glVertex3fv(p2);
glVertex3fv(p3);
glEnd();
}else{
point3 p23,p12,p31;
int i;
for(i=0;i<3;i++){
p23[i]=(p2[i]+p3[i])/2;
p12[i]=(p1[i]+p2[i])/2;
p31[i]=(p3[i]+p1[i])/2;
}
// make new points same distance from origin as original points
normalize(p23);
normalize(p12);
normalize(p31);
// draw 4 faces in place of 1
drawFace(depth-1,p23,p3,p31);
drawFace(depth-1,p31,p1,p12);
drawFace(depth-1,p12,p2,p23);
//drawFace(depth-1,p12,p23,p31);
}
}
void drawface(int depth,int i1,int i2,int i3,int i){
//to pass indices instead of points on initial call
drawFace(depth,p[i][i1],p[i][i2],p[i][i3]);
}
void myinit(void)
{
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light_position[] = { 1.0, 0.0, 4.0, 0.0 };
/* For real-world objects, diffuse and ambient reflectance are normally
the same color. For this reason, OpenGL provides you with a convenient
way of assigning the same value to both simultaneously with glMaterial*():
*/
GLfloat mat_amb_diff[] = { 0.1, 0.5, 0.8, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE,
mat_amb_diff);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glClearColor(1.0, 1.0, 1.0, 1.0); /* white background */
/* set up viewing */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(40.0, 1.0, 2.0, 200.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//glGetFloatv(GL_MODELVIEW_MATRIX, modelmatrix);
//float w=0.1;
// glFrustum(-0.1,0.1,-0.1,0.1,.2,10);
}
void drawCube(int depth)
{
drawface(depth,0,1,2,0);
drawface(depth,0,1,2,1);
drawface(depth,0,1,2,2);
drawface(depth,0,1,2,3);
drawface(depth,0,1,2,4);
drawface(depth,0,1,2,5);
drawface(depth,0,1,2,6);
drawface(depth,0,1,2,7);
drawface(depth,0,1,2,8);
drawface(depth,0,1,2,9);
drawface(depth,0,1,2,10);
drawface(depth,0,1,2,11);
drawface(depth,0,1,2,12);
drawface(depth,0,1,2,13);
drawface(depth,0,1,2,14);
drawface(depth,0,1,2,15);
drawface(depth,0,1,2,16);
drawface(depth,0,1,2,17);
drawface(depth,0,1,2,18);
drawface(depth,0,1,2,19);
}
/* void display( void )
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0,0,4,0,0,0,0,1,0);
drawCube(depth);
glFlush();
} */
void key(unsigned char k,int x, int y){
if(k==' ')depth++;
else if(depth>0)depth--;
glutPostRedisplay();
}
void
redraw(void)
{
recalcModelView();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glutSolidIcosahedron();
drawCube(depth);
glutSwapBuffers();
}
/*void
myReshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 40.0,1.0*w/h,1.0,800.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}*/
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 1.0, -1.0 * (GLfloat) h / (GLfloat) w,
1.0 * (GLfloat) h / (GLfloat) w, -30.0, 30.0);
else
glOrtho(-1.0 * (GLfloat) w / (GLfloat) h,
1.0 * (GLfloat) w / (GLfloat) h, -1.0, 1.0, -30.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
void
mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
spinning = 0;
glutIdleFunc(NULL);
moving = 1;
beginx = x;
beginy = y;
if (glutGetModifiers() & GLUT_ACTIVE_SHIFT) {
scaling = 1;
} else {
scaling = 0;
}
}
if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
moving = 0;
}
}
void
animate(void)
{
add_quats(lastquat, curquat, curquat);
glutPostRedisplay();
}
void
motion(int x, int y)
{
if (scaling) {
scalefactor = scalefactor * (1.0 + (((float) (beginy - y)) / H));
beginx = x;
beginy = y;
glutPostRedisplay();
return;
}
if (moving) {
trackball(lastquat,
(2.0 * beginx - W) / W,
(H - 2.0 * beginy) / H,
(2.0 * x - W) / W,
(H - 2.0 * y) / H
);
beginx = x;
beginy = y;
spinning = 1;
glutIdleFunc(animate);
}
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
depth=1;
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
trackball(curquat, 0.0, 0.0, 0.0, 0.0);
glutInitWindowSize(400,400);
glutInitWindowPosition(200,100);
glutCreateWindow("spin");
glutDisplayFunc(redraw);
glutReshapeFunc(reshape);
glutKeyboardFunc(key);
glutMouseFunc(mouse);
glutMotionFunc(motion);
//glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
//glEnable(GL_LIGHTING);
//glMatrixMode(GL_PROJECTION);
//glMatrixMode(GL_MODELVIEW);
//gluLookAt(0.0, 0.0, 6.0, /* eye is at (0,0,3) */
//0.0, 0.0, 0.0, /* center is at (0,0,0) */
//0.0, 1.0, 0.); /* up is in positive Y direction */
//glPushMatrix(); /* dummy push so we can pop on model*/
myinit();
/*glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
glLightfv(GL_LIGHT0, GL_POSITION, lightZeroPosition);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightZeroColor);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05);
glLightfv(GL_LIGHT1, GL_POSITION, lightOnePosition);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightOneColor);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);*/
glEnable(GL_SMOOTH); /* Enable smooth shading and color interpolation */
glEnable(GL_NORMALIZE);
//glLineWidth(5.0);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -