//小机器人程序,通过鼠标的 左 右 中 三个键 和键盘
//控制小机器人
//
#include
#include //
Glaux库的头文件
#include //
标准输入/输出库的头文件
在此处加入程序要求的库到链接器中:
#pragma comment( lib, "glaux.lib" ) // 链接时查找glaux.lib
#define MAXTEXTURE 3
GLuint texture[MAXTEXTURE]; // 纹理数组,保存纹理名字
bool leftDrag = false; //记录鼠标左键是否拖动
bool rightDrag = false; //记录鼠标右键是否拖动
static GLfloat prevX=0.0f; //记录原X
static GLfloat prevY=0.0f; //记录原Y
//记录身体各部分旋转角度
GLfloat lShoulder = 0.0f;
GLfloat rShoulder = 0.0f;
GLfloat lElbow=0.0f;
GLfloat rElbow=0.0f;
GLfloat body=0.0f;
GLfloat neck=0.0f;
GLfloat head=0.0f;
GLfloat lHand=0.0f;
GLfloat rHand=0.0f;
GLfloat lThigh=0.0f;
GLfloat rThigh=0.0f;
GLfloat lCalf=0.0f;
GLfloat rCalf=0.0f;
//记录行走参数
GLfloat flag_rShoulder=0.0f;
GLfloat flag_lShoulder=0.0f;
GLfloat flag_lThign=0.0f;
GLfloat flag_rThign=0.0f;
GLfloat flag_lElbow=0.0f;
GLfloat flag_rElbow=0.0f;
GLfloat flag_lCalf=0.0f;
GLfloat flag_rCalf=0.0f;
//平移距离
GLfloat xTranslation = 0.0f;
GLfloat yTranslation = 0.0f;
GLfloat zTranslation = 0.0f;
//旋转角度
GLfloat xRotation = 0.0f;
GLfloat yRotation = 0.0f;
//鼠标状态
bool mouse_Lbutton_pressed =
false;
bool mouse_Rbutton_pressed =
false;
bool mouse_Mbutton_pressed =
false;
GLfloat mouse_Rdownx = 0.0f ;
GLfloat mouse_Rdowny = 0.0f;
GLfloat mouse_Ldownx = 0.0f ;
GLfloat mouse_Ldowny = 0.0f;
GLfloat mouse_Mdownx = 0.0f ;
GLfloat mouse_Mdowny = 0.0f;
AUX_RGBImageRec *LoadImage(char *Filename) // 加载一个图片
{
FILE *File = NULL; // 文件句柄
if (!Filename) // 确保文件名已经提供
{
return NULL; // 如果没有则返回NULL
}
File = fopen(Filename,"r"); // 检查文件是否存在
if (File) // 文件存在吗?
{
fclose(File); // 关闭File文件句柄
return auxDIBImageLoad(Filename); // 载入图片并返回其指针
}
return NULL; // 如果加载错误则返回NULL
}
bool LoadTextureGL(GLvoid) // 加载图片并转换为纹理
{
bool State = FALSE; // 状态指示
//注意下面这行代码
AUX_RGBImageRec *TextureImage[MAXTEXTURE]; // 为纹理开辟存储空间
memset(TextureImage, 0, sizeof(void *)*MAXTEXTURE);
// 清除图像记录,确保其内容为空并使指针指向NULL
//加载图片并检查是否出错 ,如果图片不存在则返回
if ((TextureImage[0] =
LoadImage("blcu_robot.bmp"))
&& (TextureImage[1] =
LoadImage("Envroll.bmp"))
&& (TextureImage[2] =
LoadImage("Flare.bmp")))
{
State = true; // 设置状态变量为true
glGenTextures(MAXTEXTURE, &texture[0]); //
返回唯一的纹理名字来标识纹理,保存在texture中
// 用图片数据产生纹理
for (int loop=0; loop
循环处理MAXTEXTURE张纹理
{
glBindTexture(GL_TEXTURE_2D, texture[loop]);
//设置当前的纹理为texture[0]
//创建真正的纹理。下面一行告诉OpenGL此纹理是一个2D纹理(GL_TEXTURE_2D)。TextureImage[loop]->data告诉OpenGL纹理数据的来源。
glTexImage2D(GL_TEXTURE_2D, 0, 3,
TextureImage[loop]->sizeX,
TextureImage[loop]->sizeY, 0, GL_RGB,
GL_UNSIGNED_BYTE, TextureImage[loop]->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);//纹理参数设置
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);//纹理参数设置
}
}
for (int loop=0; loop
{
if (TextureImage[loop])
{
if (TextureImage[loop]->data) // 如果纹理存在
{
free(TextureImage[loop]->data); //
释放纹理存储空间
}
free(TextureImage[loop]);
}
}
return State; // 返回State
}
bool init(void) //初始化
{
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
glShadeModel(GL_SMOOTH); // 明暗处理采用平滑方式
// 载入纹理
if (!LoadTextureGL())
{
return false;
}
glEnable(GL_TEXTURE_2D); // 开启2D纹理映射
return true;
}
void DrawPoly(GLfloat width, GLfloat height, GLfloat
depth)
{
GLfloat x = width/2, y = height/2, z = depth/2;
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f); // 法线方向朝Z轴正向
//注意下面画顶点的方式:先设置纹理坐标,然后设置顶点值
glTexCoord2f(0.0f, 0.0f);glVertex3f(-x,-y, z); //
四边形的左下顶点(正视)
glTexCoord2f(1.0f, 0.0f);glVertex3f( x,-y, z); //
四边形的右下顶点
glTexCoord2f(1.0f, 1.0f);glVertex3f( x, y,
z); // 四边形的右上顶点
glTexCoord2f(0.0f, 1.0f);glVertex3f(-x, y, z); //
四边形的左上顶点
// (1)请在这里添加画图函数,多画几个四边形,并设置其纹理坐标。
glTexCoord2f(0.0f, 0.0f);glVertex3f(-x,-y, -z); //
四边形的左下顶点(正视)
glTexCoord2f(1.0f, 0.0f);glVertex3f( x,-y, -z); //
四边形的右下顶点
glTexCoord2f(1.0f, 1.0f);glVertex3f( x, y,
-z); // 四边形的右上顶点
glTexCoord2f(0.0f, 1.0f);glVertex3f(-x, y, -z); //
四边形的左上顶点
glTexCoord2f(0.0f, 0.0f);glVertex3f(-x,-y, -z); //
四边形的左下顶点(正视)
glTexCoord2f(1.0f, 0.0f);glVertex3f( -x,-y, z); //
四边形的右下顶点
glTexCoord2f(1.0f, 1.0f);glVertex3f( -x, y,
z); // 四边形的右上顶点
glTexCoord2f(0.0f, 1.0f);glVertex3f(-x, y, -z); //
四边形的左上顶点
glTexCoord2f(0.0f, 0.0f);glVertex3f(x,-y, -z); //
四边形的左下顶点(正视)
glTexCoord2f(1.0f, 0.0f);glVertex3f(x,-y, z); //
四边形的右下顶点
glTexCoord2f(1.0f, 1.0f);glVertex3f(x, y,
z); // 四边形的右上顶点
glTexCoord2f(0.0f, 1.0f);glVertex3f(x, y, -z); //
四边形的左上顶点
glTexCoord2f(0.0f, 0.0f);glVertex3f(-x,y,z); //
四边形的左下顶点(正视)
glTexCoord2f(1.0f, 0.0f);glVertex3f( x,y,z); // 四边形的右下顶点
glTexCoord2f(1.0f, 1.0f);glVertex3f( x,
y,-z); // 四边形的右上顶点
glTexCoord2f(0.0f, 1.0f);glVertex3f(-x, y, -z); //
四边形的左上顶点
glEnd();
}
void drawleftlimb()
{
glPushMatrix();
glRotatef (lShoulder, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (2.0f, 0.4f, 0.5f);
glutWireCube (1.0f);//绘制胳膊的上臂
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glTranslatef (1.0f, 0.0f, 0.0f);
glRotatef (lElbow, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (2.0f, 0.4f, 0.5f);
glutWireCube (1.0);//绘制胳膊的前臂
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
///
glRotatef (lHand, 1.0f, 0.0f, 0.0f);
glTranslatef (1.2f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (0.4f, 0.4f, 0.5f);
glutWireCube (1.0f);//绘制手
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glPopMatrix();
}
void drawrightlimb()
{
glPushMatrix();
glRotatef (rShoulder, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (2.0f, 0.4f, 0.5f);
glutWireCube (1.0f);//绘制胳膊的上臂
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glTranslatef (1.0f, 0.0f, 0.0f);
///
glRotatef (rElbow, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (2.0f, 0.4f, 0.5f);
glutWireCube (1.0);//绘制胳膊的前臂
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glRotatef (rHand, 1.0f, 0.0f, 0.0f);
glTranslatef (1.2f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (0.4f, 0.4f, 0.5f);
glutWireCube (1.0f);//绘制手
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glPopMatrix();
}
void drawbody()
{
glPushMatrix();
glRotatef (body, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (3.0f, 1.0f, 2.0f);
glutWireCube (1.0f);
glTranslatef
(0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[0]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glPopMatrix();
}
void drawhead()
{
glPushMatrix();
glRotatef (neck, 1.0f, 0.0f, 0.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (0.5f, 0.5f, 0.5f);
glutWireCube(1.0f) ;
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glRotatef (head, 1.0f, 0.0f, 0.0f);
glTranslatef (-0.5f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (0.5f, 0.5f, 0.5f);
glutWireSphere(1.0f,10.0f,10.0f) ;
glPopMatrix();//弹出矩阵
glPopMatrix();
}
void drawleftleg()
{
glPushMatrix();
glRotatef (lThigh, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (2.0f, 0.4f, 0.5f);
glutWireCube (1.0f);
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glTranslatef (1.0f, 0.0f, 0.0f);
glRotatef (lCalf, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (2.0f, 0.4f, 0.5f);
glutWireCube (1.0f);
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glPopMatrix();
}
void drawrightleg()
{
glPushMatrix();
glRotatef (rThigh, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (2.0f, 0.4f, 0.5f);
glutWireCube (1.0f);
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glTranslatef (1.0f, 0.0f, 0.0f);
glRotatef (rCalf, 0.0f, 0.0f, 1.0f);
glTranslatef (1.0f, 0.0f, 0.0f);
glPushMatrix();//将当前矩阵压入堆栈
glScalef (2.0f, 0.4f, 0.5f);
glutWireCube (1.0f);
glTranslatef (0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,texture[1]);
DrawPoly(1.0f, 1.0f, 1.0f);
glPopMatrix();//弹出矩阵
glPopMatrix();
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(xTranslation , yTranslation , 5.0f
+ zTranslation , xTranslation, yTranslation , 0.0
+ zTranslation , 0.0f, 1.0f , 0.0f);
glRotatef(xRotation , 1.0f,0.0f,0.0f);
glRotatef(yRotation , 0.0f,1.0f,0.0f);
//画左胳膊
glPushMatrix();//将当前矩阵压入堆栈,即保存当前矩阵
glTranslatef (0.0f, 0.0f, 1.25f);
drawleftlimb();
glPopMatrix();//弹出矩阵
//画右胳膊
glPushMatrix();//将当前矩阵压入堆栈,即保存当前矩阵
glTranslatef (0.0f, 0.0f, -1.25f);//注意这里的z向偏移
drawrightlimb();
glPopMatrix();//弹出矩阵
//画左腿
glPushMatrix();//将当前矩阵压入堆栈,即保存当前矩阵
glTranslatef (2.5f, 0.0f, 0.5f);
drawleftleg();
glPopMatrix();//弹出矩阵
//画右腿
glPushMatrix();//将当前矩阵压入堆栈,即保存当前矩阵
glTranslatef (2.5f, 0.0f, -0.5f);//注意这里的z向偏移
drawrightleg();
glPopMatrix();//弹出矩阵
//画躯干
glPushMatrix();//将当前矩阵压入堆栈,即保存当前矩阵
glTranslatef (0.0f, 0.0f, 0.0f);//注意这里的z向偏移
drawbody();
glPopMatrix();//弹出矩阵
//画脑袋
glPushMatrix();//将当前矩阵压入堆栈,即保存当前矩阵
glTranslatef (-1.7f, 0.0f, 0.0f);//注意这里的z向偏移
drawhead();
glPopMatrix();//弹出矩阵
glutSwapBuffers();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei)
h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(65.0f, (GLfloat) w/(GLfloat) h, 1.0f,
200.0f);
glMatrixMode(GL_MODELVIEW);
}
GLfloat move90Positive(GLfloat degree,
GLfloat &flag)
{
if (degree
< -45.0f || degree > 45.0f)
{
degree = 0.0f;
}
if (flag == 0)
{
degree += 5.0f;
if (degree == 45.0f)
{
flag = 1;
}
return degree;
}
else
{
degree = degree - 5.0f;
if (degree == -45.0f)
{
flag = 0;
}
return degree;
}
}
GLfloat move90Negative(GLfloat degree, GLfloat
&flag)
{
if (degree
< -45.0f || degree > 45.0f)
{
degree = 0.0f;
}
if (flag == 0)
{
degree -= 5.0f;
if (degree == -45.0f)
{
flag = 1;
}
return degree;
}
else
{
degree = degree + 5.0f;
if (degree == 45.0f)
{
flag = 0;
}
return degree;
}
}
GLfloat move45Positive(GLfloat degree, GLfloat
&flag )
{
if (degree
< 0.0f || degree > 45.0f)
{
degree = 0.0f;
}
if (flag == 0)
{
degree += 5.0f;
if
(degree == 45.0f)
{
flag = 1;
}
return
degree ;
}
else
{
degree
-= 5.0f;
if (degree == 0.0f)
{
flag = 0;
}
return degree ;
}
}
GLfloat move45Negative(GLfloat degree, GLfloat
&flag)
{
if (degree < -45.0f || degree >
0.0f)
{
degree = 0.0f;
}
if (flag == 0)
{
degree -= 5.0f;
if
(degree ==- 45.0f)
{
flag = 1;
}
return
degree ;
}
else
{
degree
+= 5.0f;
if (degree == 0.0f)
{
flag = 0;
}
return degree ;
}
}
void keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 's': //转动左肩
lShoulder = ((int)lShoulder + 5) %
360;
glutPostRedisplay();
break;
case 'd': //转动右肩
rShoulder = ((int)rShoulder - 5) %
360;
glutPostRedisplay();
break;
case 'e': //转动左肘
lElbow = ((int)lElbow + 5) % 360;
glutPostRedisplay();
break;
case 'r': //转动右肘
rElbow = ((int)rElbow + 5) % 360;
glutPostRedisplay();
break;
case 'h': //转动左手
lHand = ((int)lHand-5)
0;
glutPostRedisplay();
break;
case 'j': //转动右手
rHand = ((int)rHand+5)
0;
glutPostRedisplay();
break;
case 'q': //转动头部
head = ((int)head-5) 0;
glutPostRedisplay();
break;
case 'n': //转动脖子
neck = ((int)neck-5) 0;
glutPostRedisplay();
break;
case 't': //转动左胯
lThigh = ((int)lThigh+5)
0;
glutPostRedisplay();
break;
case 'y': //转动右胯
rThigh = ((int)rThigh+5)
0;
glutPostRedisplay();
break;
case 'c': //转动右膝
lCalf = ((int)lCalf+5)
0;
glutPostRedisplay();
break;
case 'v': //转动右膝
rCalf = ((int)rCalf-5)
0;
glutPostRedisplay();
break;
case 'w': //行走
rShoulder=move90Positive(rShoulder,
flag_rShoulder);
lShoulder=move90Negative(lShoulder, flag_lShoulder);
rElbow=move45Positive(rElbow,
flag_rElbow);
lElbow=move45Positive(lElbow,
flag_lElbow);
lThigh=move90Positive(lThigh,
flag_lThign);
lCalf=move45Negative(lCalf,
flag_lCalf);
rThigh=move90Negative(rThigh,
flag_rThign);
rCalf=move45Negative(rCalf,
flag_rCalf);
glutPostRedisplay();
break;
default:
break;
}
}
void mouse(int button, int state, int
x, int y)
{
if(button == GLUT_LEFT_BUTTON){
if(state ==
GLUT_DOWN)//如果鼠标器左键按下,mouse_Lbutton_pressed置位并记录光标位置
{
mouse_Lbutton_pressed =
true;
mouse_Ldownx =
x;
mouse_Ldowny =
y;
leftDrag = true;
prevX = x;
prevY = y;
}
else{
mouse_Lbutton_pressed =
false;
leftDrag=false;
}
}
if(button == GLUT_RIGHT_BUTTON){
if(state ==
GLUT_DOWN)//如果鼠标器右键按下,mouse_Rbutton_pressed置位并记录光标位置
{
mouse_Rbutton_pressed =
true;
mouse_Rdownx =
x;
mouse_Rdowny =
y;
rightDrag = true;
prevX = x;
prevY = y;
}
else{
mouse_Rbutton_pressed =
false;
rightDrag=false;
}
}
if(button == GLUT_MIDDLE_BUTTON){
if(state ==
GLUT_DOWN)//如果鼠标器中键按下,mouse_Mbutton_pressed置位并记录光标位置
{
mouse_Mbutton_pressed =
true;
mouse_Mdownx =
x;
mouse_Mdowny =
y;
}
else{
mouse_Mbutton_pressed =
false;
}
}
}
void mouseMove(int x,int y)
{
if (mouse_Lbutton_pressed) {
xTranslation += (mouse_Ldownx - x) /
50.0f;
yTranslation -= (mouse_Ldowny - y) / 50.0f;
mouse_Ldownx = x;
mouse_Ldowny = y;
glutPostRedisplay();
}
if (mouse_Rbutton_pressed) {
yRotation -= (mouse_Rdownx - x) /
3.0f;
xRotation -= (mouse_Rdowny - y) / 3.0f;
mouse_Rdownx = x;
mouse_Rdowny = y;
glutPostRedisplay();
}
if (mouse_Mbutton_pressed) {
zTranslation += (mouse_Mdownx - x) / 10.0f;
mouse_Mdownx = x;
glutPostRedisplay();
}
if(leftDrag == true){
prevX=x;
prevY=y;
glutPostRedisplay();
}
if(rightDrag == true){
prevX=x;
prevY=y;
glutPostRedisplay();
}
}
int main()
{
glutInitDisplayMode (GLUT_DOUBLE |
GLUT_RGB);//使用双缓存和RGB颜色模式
glutInitWindowSize (1000, 1000);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Robot");
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(mouseMove);
glutMainLoop();
return 0;
}