用OpenGL绘制的三维场景的简单机器人

这是慕课上的计算机图形学的作业,作业要求是:

具体要求:
(1)构建一个三维场景:
可利用glut提供的各种简单形体来搭建;或者读入别的模型来构成场景。
加入光照效果。
(2)用键盘操纵一个物体(如一艘飞船,或一个机器人)在三维场景中漫游。
视点可以放在物体上,或跟随物体;可利用gluLookAt( )函数来实现对视点的控制。
撰写的作业文档中包括:
(1)程序功能的描述,效果请附图;
(2)论述实现漫游的程序思路;
(3)漫游操作顺畅,效果良好。

因为刚开始学,真的体会到了绘图的奥妙,光照纹理这些神奇的计算,也体会到了数学对于计算机的重要性,这里画的机器人其实在做许多重复的事情,其中的重点就是坐标的计算和glPushMatrix、glPopMatrix的使用。下面是效果:
用OpenGL绘制的三维场景的简单机器人_第1张图片
用OpenGL绘制的三维场景的简单机器人_第2张图片
用OpenGL绘制的三维场景的简单机器人_第3张图片
下面是实现的代码:
注释都在代码中

#include 
#include 
#include 
using namespace std;
const GLfloat Pi = 3.1415926536f;
//摄像机离物体的距离
float G_fDistance = 3.6f;
//机器人的旋转角度 
float G_fAngle_horizon = 0.0;
float G_fAngle_vertical = 0.0f;

float G_left_upper_arm1 = 0.0;//左上臂运动角度(左右运动)
float G_left_upper_arm2 = 0.0;//左上臂运动角度(前后运动)
float G_left_lower_arm1 = 0.0f;//左下臂运动角度(左右运动)
float G_left_lower_arm2 = 0.0f;//左下臂运动角度(前后运动)
float G_right_upper_arm1 = 0.0;//右上臂运动角度(左右运动)
float G_right_upper_arm2 = 0.0;//右上臂运动角度(前后运动)
float G_right_lower_arm1 = 0.0f;//右下臂运动角度(左右运动)
float G_right_lower_arm2 = 0.0f;//右下臂运动角度(前后运动)

float G_left_upper_leg = 0.0;//左大腿运动角度(前后运动)
float G_left_lower_leg = 0.0f;//左小腿运动角度(前后运动)
float G_right_upper_leg = 0.0;//右大腿运动角度(前后运动)
float G_right_lower_leg = 0.0f;//右小腿运动角度(前后运动)

void myinit(void);
void myReshape(GLsizei w, GLsizei h);
void display(void);
void processSpecialKeys(int key, int x, int y);
void processNormalKeys(unsigned char key,int x,int y);
void timer(int value);

//主函数
int main(int argc, char* argv[])
{
	glutInit(&argc, argv);

	//初始化OPENGL显示方式
	glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA);

	//设定OPENGL窗口位置和大小
	glutInitWindowSize (500, 800); 
	glutInitWindowPosition (100, 100);

	//打开窗口
	glutCreateWindow ("简单机器人");
	cout<<"w,s,a,d控制机器人右上臂前后左右"<<"\n";
	cout<<"5、2、1、3控制机器人左臂上臂前后左右"<<"\n";
	cout<<"t、g、f、h控制机器人右下臂前后左右"<<"\n";
	cout<<"i、k、j、l控制机器人左臂下臂前后左右"<<"\n";
	cout<<"6、7控制机器人右大腿前后"<<"\n";
	cout<<"8、9控制机器人左大腿前后"<<"\n";
	cout<<"z、x控制机器人右小腿前后"<<"\n";
	cout<<"c、v控制机器人左小腿前后"<<"\n";
	cout<<"‘[’、‘]’用来控制机器人离屏幕远近"<<"\n";
	cout<<"键盘上的上下左右键可以旋转机器人"<<"\n";
	//调用初始化函数
    myinit();

	//设定窗口大小变化的回调函数
	glutReshapeFunc(myReshape);

	//设定键盘控制的回调函数
	glutSpecialFunc(processSpecialKeys);
	glutKeyboardFunc(processNormalKeys);

	//开始OPENGL的循环
	glutDisplayFunc(display); 
	glutMainLoop();

	return 0;
}

void myinit(void)//初始化
{
	glEnable(GL_DEPTH);
}  
void myReshape(GLsizei w, GLsizei h)//设定窗口大小变化的回调函数
{
	glViewport(0,0,w,h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(60,(GLfloat)w/(GLfloat)h,1,30);
}
void drawstar(GLfloat a,GLfloat x,GLfloat y)//画星星的函数
{//a为星星的半径,x,y为平移的量
	GLfloat bx = a * cos(18 * Pi/180);
	GLfloat by = a * sin(18 * Pi/180);
	GLfloat cy = -a * cos(36 * Pi/180);
	GLfloat cx = a * sin(36 * Pi/180);
	GLfloat
		PointA[2] = { 0, a },
		PointB[2] = { bx, by },
		PointC[2] = { cx, cy },
		PointD[2] = { -cx, cy },
		PointE[2] = { -bx, by };
	// 按照A->C->E->B->D->A的顺序,可以一笔将五角星画出
	glTranslatef(x,y,0.0);
	glColor3f(1.0,1.0,0.0);
	glBegin(GL_LINE_LOOP);
		glVertex2fv(PointA);
		glVertex2fv(PointC);
		glVertex2fv(PointE);
		glVertex2fv(PointB);
		glVertex2fv(PointD);
	glEnd();
}
void drawfinger(GLfloat x,GLfloat y,GLfloat z)//画手指
{
	glPushMatrix();
		glColor3f(0.0,0.0,1.0);
		glTranslatef(x,y,z);
		glPushMatrix();
			glScalef(0.025,0.05,0.025);
			glutSolidCube(1.0);	
		glPopMatrix();
	glPopMatrix();
}
void drawfoot(GLfloat x,GLfloat y,GLfloat z)//画脚
{
	glPushMatrix();
		glColor3f(0.0,0.0,1.0);
		glTranslatef(x,y,z);
		glPushMatrix();
			glScalef(0.25,0.05,0.25);
			glutSolidCube(1.0);	
		glPopMatrix();
	glPopMatrix();
}
void display(void)
{
	//清除颜色和深度缓存
	glClearColor(0.0,0.0,0.0,0.0);
	glClearDepth(1.0f);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	//视角的变化
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glTranslatef(0.0,0.0,-G_fDistance);
	glRotatef(G_fAngle_horizon, 0.0f, 1.0f, 0.0f);
	glRotatef(G_fAngle_vertical, 1.0f, 0.0f, 0.0f);
	//身体
	glColor3f(1.0,0.0,0.0);
	glPushMatrix();
		glScalef(1.0,0.75,0.5);
		glutSolidCube(1.0);
	glPopMatrix();
	//画五星红旗
	glPushMatrix();
		GLfloat distance=0.15;//大的五角星到小的五角星的距离
		GLfloat x1=distance*cos(54*Pi/180);
		GLfloat y1=distance*sin(54*Pi/180);
		GLfloat x2=distance*cos(18*Pi/180);
		GLfloat y2=distance*sin(18*Pi/180);
		drawstar(0.1,-0.4,0.225);
		glPushMatrix();
		drawstar(0.05,x1,y1);
		glPopMatrix();
		glPushMatrix();
		drawstar(0.05,x2,y2);
		glPopMatrix();
		glPushMatrix();
		drawstar(0.05,x1,-y1);
		glPopMatrix();
		glPushMatrix();
		drawstar(0.05,x2,-y2);
		glPopMatrix();
	glPopMatrix();
	//头和眼
	glPushMatrix();
		//头
		glTranslatef(0.0,0.625,0.0);
		glColor3f(0.8,0.5,0.2);
		glutSolidSphere(0.25,20,20);
		//绿帽子
		glPushMatrix();
			glColor3f(0.0,1.0,0.0);
			glTranslatef(0.0,0.25,0.0);
			glRotatef(90,1.0,0.0,0.0);
			glutSolidTorus(0.1,0.15,20,20);
		glPopMatrix();
		//左眼
		glPushMatrix();
			glColor3f(1.0,0.0,0.0);
			glTranslatef(-0.12,0.0,0.0);
			glScalef(1.0,0.75,0.5);
			glutSolidSphere(0.1,20,20);
		glPopMatrix();
		//右眼
		glPushMatrix();
			glColor3f(1.0,0.0,0.0);
			glTranslatef(0.12,0.0,0.0);
			glScalef(1.0,0.75,0.5);
			glutSolidSphere(0.1,20,20);
		glPopMatrix();
	glPopMatrix();
	//左臂
	glPushMatrix();
		//左上臂
		glColor3f(1.0,0.0,1.0);
		glTranslatef(-0.575,0.375,0.0);
		glRotatef(G_left_upper_arm1,0.0,0.0,1.0);
		glRotatef(G_left_upper_arm2,1.0,0.0,0.0);
		glTranslatef(0.0,-0.225,0.0);
		glPushMatrix();
			glScalef(0.125,0.45,0.3);
			glutSolidCube(1.0);	
		glPopMatrix();
		//左肘
		glColor3f(0.0,1.0,1.0);
		glTranslatef(0.0,-0.25625,0.0);
		glutSolidSphere(0.0625,20,20);	
		//左下臂
		glColor3f(1.0,0.0,1.0);
		glTranslatef(0.0,-0.03125,0.0);
		glRotatef(G_left_lower_arm1,0.0,0.0,1.0);
		glRotatef(G_left_lower_arm2,1.0,0.0,0.0);
		glTranslatef(0.0,-0.225,0.0);
		glPushMatrix();
			glScalef(0.125,0.45,0.15);
			glutSolidCube(1.0);	
		glPopMatrix();
		//画手指
		drawfinger(-0.0675,-0.25,0.075);
		drawfinger(0.0675,-0.25,0.075);
		drawfinger(0,-0.25,-0.075);
	glPopMatrix();
	//右臂
	glPushMatrix();
		//右上臂
		glColor3f(1.0,0.0,1.0);
		glTranslatef(0.575,0.375,0.0);
		glRotatef(G_right_upper_arm1,0.0,0.0,1.0);
		glRotatef(G_right_upper_arm2,1.0,0.0,0.0);
		glTranslatef(0.0,-0.225,0.0);
		glPushMatrix();
			glScalef(0.125,0.45,0.3);
			glutSolidCube(1.0);	
		glPopMatrix();
		//右肘
		glColor3f(0.0,1.0,1.0);
		glTranslatef(0.0,-0.25625,0.0);
		glutSolidSphere(0.0625,20,20);	
		//右下臂
		glColor3f(1.0,0.0,1.0);
		glTranslatef(0.0,-0.03125,0.0);
		glRotatef(G_right_lower_arm1,0.0,0.0,1.0);
		glRotatef(G_right_lower_arm2,1.0,0.0,0.0);
		glTranslatef(0.0,-0.225,0.0);
		glPushMatrix();
			glScalef(0.125,0.45,0.15);
			glutSolidCube(1.0);	
		glPopMatrix();
		//画手指
		drawfinger(-0.0675,-0.25,0.075);
		drawfinger(0.0675,-0.25,0.075);
		drawfinger(0,-0.25,-0.075);
	glPopMatrix();
	//左腿
	glPushMatrix();
		//左大腿
		glColor3f(1.0,0.0,1.0);
		glTranslatef(0.15,-0.375,0.0);
		glRotatef(G_left_upper_leg,1.0,0.0,0.0);
		glTranslatef(0.0,-0.225,0.0);
		glPushMatrix();
			glScalef(0.25,0.45,0.3);
			glutSolidCube(1.0);	
		glPopMatrix();
		//左膝盖
		glColor3f(0.0,1.0,1.0);
		glTranslatef(0.0,-0.25625,0.0);
		glutSolidSphere(0.0625,20,20);	
		//左小腿
		glColor3f(1.0,0.0,1.0);
		glTranslatef(0.0,-0.0625,0.0);
		glRotatef(G_left_lower_leg,1.0,0.0,0.0);
		glTranslatef(0.0,-0.225,0.0);
		glPushMatrix();
			glScalef(0.125,0.45,0.3);
			glutSolidCube(1.0);	
		glPopMatrix();
		drawfoot(0.0,-0.25,0.0);
	glPopMatrix();
	//右腿
	glPushMatrix();
		//右大腿
		glColor3f(1.0,0.0,1.0);
		glTranslatef(-0.15,-0.375,0.0);
		glRotatef(G_right_upper_leg,1.0,0.0,0.0);
		glTranslatef(0.0,-0.225,0.0);
		glPushMatrix();
			glScalef(0.25,0.45,0.3);
			glutSolidCube(1.0);	
		glPopMatrix();
		//右膝盖
		glColor3f(0.0,1.0,1.0);
		glTranslatef(0.0,-0.25625,0.0);
		glutSolidSphere(0.0625,20,20);	
		//右小腿
		glColor3f(1.0,0.0,1.0);
		glTranslatef(0.0,-0.0625,0.0);
		glRotatef(G_right_lower_leg,1.0,0.0,0.0);
		glTranslatef(0.0,-0.225,0.0);
		glPushMatrix();
			glScalef(0.125,0.45,0.3);
			glutSolidCube(1.0);	
		glPopMatrix();
		drawfoot(0.0,-0.25,0.0);
	glPopMatrix();
	//交换前后缓冲区
	glutSwapBuffers();
}

//响应键盘输入, 从而设定物体移近移远以及旋转的回调函数
void processSpecialKeys(int key, int x, int y)
{
	switch(key) {
		case GLUT_KEY_LEFT:
			G_fAngle_horizon -= 5.0f;
			break;
		case GLUT_KEY_RIGHT:
			G_fAngle_horizon += 5.0f;
			break;
		case GLUT_KEY_UP:
			G_fAngle_vertical -= 5.0f;
			break;
		case GLUT_KEY_DOWN:
			G_fAngle_vertical += 5.0f;
			break;
	}
	glutPostRedisplay();
}
void processNormalKeys(unsigned char key,int x,int y)
{
	switch(key) {
		case 91:	//"["
			G_fDistance -= 0.3f;
			break;
		case 93:		//"]"
			G_fDistance += 0.3f;
			break;
		case 49:	//1
			G_left_upper_arm1-=15.0;
			break;
		case 51:	//3
			G_left_upper_arm1+=15.0;
			break;
		case 50:	//2
			G_left_upper_arm2-=15.0;
			break;
		case 53:	//5
			G_left_upper_arm2+=15.0;
			break;
		//i、k、j、l控制机器人左臂下臂前后左右
		case 106:	//j
			G_left_lower_arm1-=15.0;
			break;
		case 108:	//l
			G_left_lower_arm1+=15.0;
			break;
		case 105:	//i
			G_left_lower_arm2-=15.0;
			break;
		case 107:	//k
			G_left_lower_arm2+=15.0;
			break;
		case  97:	//a
			G_right_upper_arm1-=15.0;
			break;
		case  100:	//d
			G_right_upper_arm1+=15.0;
			break;
		case  119:	//w
			G_right_upper_arm2-=15.0;
			break;
		case  115:	//s
			G_right_upper_arm2+=15.0;
			break;
		case  102:	//f
			G_right_lower_arm1-=15.0;
			break;
		case  104:	//h
			G_right_lower_arm1+=15.0;
			break;
		case  116:	//t
			G_right_lower_arm2-=15.0;
			break;
		case  103:	//g
			G_right_lower_arm2+=15.0;
			break;
		case 56://8
			G_left_upper_leg-=15.0;
			break;
		case 57://9
			G_left_upper_leg+=15.0;
			break;
		case 99://c
			G_left_lower_leg-=15.0;
			break;
		case 118://v
			G_left_lower_leg+=15.0;
			break;
		case 54://6
			G_right_upper_leg-=15.0;
			break;
		case 55://7
			G_right_upper_leg+=15.0;
			break;
		case 122://z
			G_right_lower_leg-=15.0;
			break;
		case 120://x
			G_right_lower_leg+=15.0;
			break;
		case 27:	//"esc"
			exit(0);
	}
	glutPostRedisplay();
}


你可能感兴趣的:(计算机图形学学习总结)