glTranslate*, glScale*, glRotate*的使用练习

来源:互联网 发布:右下角淘宝广告弹窗 编辑:程序博客网 时间:2024/04/27 21:19
#include <iostream>
#include <map>
#include "gl/glew.h"
#include "gl/glut.h"
using namespace std;
enum FingerJoint
{
 Shoulder_Joint,   //The joint which connects the shoulder to the body.
 Elbow_Joint,   //The joint which connects the two parts of arm.
 Wrist_Joint,   //The joint which connects the wrist to the arm.
 Thumb_1st_Joint,  //The joint which connects the thumb to palm
 Thumb_2nd_Joint,  //The joint which connects two parts of the thumb
 Forefinger_1st_Joint, //The joint which connects the forefinger to palm
 Forefinger_2nd_Joint, //The joint which connects the two parts of the forefinger
 Forefinger_3rd_Joint,
 MiddleFinger_1st_Joint, //The joint which connects the middle finger to palm
 MiddleFinger_2nd_Joint, 
 MiddleFinger_3rd_Joint,
 Ringfinger_1st_Joint, //The joint which connects the ring finger to palm
 Ringfinger_2nd_Joint, 
 Ringfinger_3rd_Joint,
 LittleFinger_1st_Joint, //The joint which connects the little finger to palm
 LittleFinger_2nd_Joint, //
 LittleFinger_3rd_Joint,
 JointCount    //Total joints count
};
//The rotation angels of all joints
GLfloat gFingerJointRotations[JointCount];
//The limit of the rotation angel for all fingers is between 0~90
const GLfloat FingerJointRotationMax = 90.0f; //Max rotation angel
const GLfloat FingerJointRotationMin = 0.0f; //Min rotation angel
const GLfloat RotationDelta = 5.0f;
//The rotation Angel of the Shoulder, range between -45.0~90
const GLfloat ShoulderRotationMax = 90.0f;
const GLfloat ShoulderRotationMin = -45.0f;
//The rotation angel of the elbow, range between 0~160
const GLfloat ElbowRotationMax = 160.0f;
const GLfloat ElbowRotationMin = 0.0f;
  
//The rotation angel of the wrist, range between -60~80
const GLfloat WristRotationMax = 80.0f;
const GLfloat WristRotationMin = -60.0f;
class ControlData
{
public:
 ControlData()
 {}
 ControlData(int index, GLfloat delta, GLfloat min, GLfloat max)
  :Index(index), Delta(delta), MinValue(min), MaxValue(max)
 {}
 ControlData(const ControlData &other)
  :Index(other.Index), Delta(other.Delta), MinValue(other.MinValue), MaxValue(other.MaxValue)
 {}
 ControlData& operator = (const ControlData &other)
 {
  Index = other.Index;
  MaxValue = other.MaxValue;
  MinValue = other.MinValue;
  Delta = other.Delta;
  return *this;
 }
 int Index;   //Index of Joint Rotation Angel
 GLfloat MaxValue; //Max angel
 GLfloat MinValue; //Min angel
 GLfloat Delta;  //Delta value
};
std::map<GLubyte, ControlData> gKeyControlDataMap;
/*
 Initialize Key-Rotation Data mapping.
**/
void initControlMapping()
{
 //All char press without shift will rotate deasil
 //All char press with shift will rotate widdershins
 gKeyControlDataMap['a'] = ControlData(Shoulder_Joint, RotationDelta, ShoulderRotationMin, ShoulderRotationMax);
 gKeyControlDataMap['A'] = ControlData(Shoulder_Joint, -RotationDelta, ShoulderRotationMin, ShoulderRotationMax);
 gKeyControlDataMap['s'] = ControlData(Elbow_Joint, RotationDelta, ElbowRotationMin, ElbowRotationMax);
 gKeyControlDataMap['S'] = ControlData(Elbow_Joint, -RotationDelta, ElbowRotationMin, ElbowRotationMax);
 gKeyControlDataMap['d'] = ControlData(Wrist_Joint, RotationDelta, WristRotationMin, WristRotationMax);
 gKeyControlDataMap['D'] = ControlData(Wrist_Joint, -RotationDelta, WristRotationMin, WristRotationMax);
 gKeyControlDataMap['n'] = ControlData(Thumb_1st_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['N'] = ControlData(Thumb_1st_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['h'] = ControlData(Thumb_2nd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['H'] = ControlData(Thumb_2nd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['m'] = ControlData(Forefinger_1st_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['M'] = ControlData(Forefinger_1st_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['j'] = ControlData(Forefinger_2nd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['J'] = ControlData(Forefinger_2nd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['u'] = ControlData(Forefinger_3rd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['U'] = ControlData(Forefinger_3rd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap[','] = ControlData(MiddleFinger_1st_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['<'] = ControlData(MiddleFinger_1st_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['k'] = ControlData(MiddleFinger_2nd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['K'] = ControlData(MiddleFinger_2nd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['i'] = ControlData(MiddleFinger_3rd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['I'] = ControlData(MiddleFinger_3rd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['.'] = ControlData(Ringfinger_1st_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['>'] = ControlData(Ringfinger_1st_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['l'] = ControlData(Ringfinger_2nd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['L'] = ControlData(Ringfinger_2nd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['o'] = ControlData(Ringfinger_3rd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['O'] = ControlData(Ringfinger_3rd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['/'] = ControlData(LittleFinger_1st_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['?'] = ControlData(LittleFinger_1st_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap[';'] = ControlData(LittleFinger_2nd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap[':'] = ControlData(LittleFinger_2nd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['p'] = ControlData(LittleFinger_3rd_Joint, RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
 gKeyControlDataMap['P'] = ControlData(LittleFinger_3rd_Joint, -RotationDelta, FingerJointRotationMin, FingerJointRotationMax);
}
void init()
{
 initControlMapping();
 //Set background color : black
 glClearColor(0.0, 0.0, 0.0, 0.0);
 glShadeModel(GL_SMOOTH);
 //Enable Depth test
 glEnable(GL_DEPTH_TEST);
 //Enable lighting
 glEnable(GL_LIGHTING);
 //Set Light source 0
 static GLfloat light0_position[] = {1.0, 1.0, 1.0, 0.0};
 glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
 //Blue light
 static GLfloat light0_diffuse[] = {1.0, 1.0, 1.0, 1.0};
 glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
 //Enable the 1st light source.
 glEnable(GL_LIGHT0);
}

/*
 Window reshape event callback, call the function once the window size changed.
**/
void reshape(GLsizei w, GLsizei h)
{
 //Avoid divide 0
 if(0==h)
    h=1;
 //Set the view port
 glViewport(0, 0, w, h);
 //All matrix operations will affect projection matrix
 glMatrixMode(GL_PROJECTION);
 //Load an identity matrix
 glLoadIdentity();
 //Set projection matrix
 gluPerspective(45.0, (GLfloat)w/(GLfloat)h, 0.1, 500.0);
 //All matrix operations will affect model veiw matrix
 glMatrixMode(GL_MODELVIEW);
}

/*
 Redraw callback, call this function every time the display need to refresh.
**/
void display()
{
 //Clear color buffer and depth buffer
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glLoadIdentity();
 //Set camera parameters
 gluLookAt(0.0, 0.0, 60.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
 //Rotate camera
 glRotatef(150.0, 0.0, 1.0, 0.0);
 //Draw the shoulder
 glTranslatef(6.0, 0.0, 0.0);
 glRotatef(gFingerJointRotations[Shoulder_Joint], 0.0, 0.0, 1.0);
 glScalef(12.0, 2.0, 4.0);
 glutSolidCube(1.0);
 //Eliminate the impact to following objects
 glScalef(1.0/12.0, 1.0/2.0, 1.0/4.0);
 
 //Draw the elbow, use the transform matrix of shoulder as parent matrix
 glTranslatef(6.0, 0.0, 0.0);
 glRotatef(gFingerJointRotations[Elbow_Joint], 0.0, 0.0, 1.0);
 //Translate twice, make sure the rotation center at the end of the elbow
 glTranslatef(6.0, 0.0, 0.0);  
 glScalef(12.0, 2.0, 4.0);
 glutSolidCube(1.0);
 //Eliminate the impact to following objects
 glScalef(1.0/12.0, 1.0/2.0, 1.0/4.0);
 {
  //Draw the palm, use the transform matrix of elbow as parent matrix
  glPushMatrix();  //push current matrix to stack
  glTranslatef(6.0, 0.0, 0.0);
  glRotatef(gFingerJointRotations[Wrist_Joint], 0.0, 0.0, 1.0);
  glTranslatef(3.0, 0.0, 0.0);
  glScalef(6.0, 1.0, 4.0);
  glutSolidCube(1.0);
  //Eliminate the impact to following objects
  glScalef(1.0/6.0, 1.0, 1.0/4.0);
  {
   //Draw thumb, use the transform matrix of palm as parent matrix
   glPushMatrix();
   glTranslatef(-1.0, 0.0, -1.0);
   glRotatef(-gFingerJointRotations[Thumb_1st_Joint], 0.0, 0.0, 1.0);
   glRotatef(gFingerJointRotations[Thumb_1st_Joint], 1.0, 0.0, 0.0);
   //Translate twice, make sure the rotation center at the end of the thumb
   glTranslatef(-1.0, 0.0, -2.0);
   glScalef(1.0, 1.0, 2.0);
   glutSolidCube(1.0);
   //Eliminate the impact to following objects
   glScalef(1.0, 1.0, 1.0/2.0);
   {
    //Draw the 2nd part of thumb,
    //use the transform matrix of the first part of thumb as parent matrix
    glPushMatrix();
    glTranslatef(0.0, 0.0, -1.0);
    glRotatef(gFingerJointRotations[Thumb_2nd_Joint], 1.0, 0.0, 0.0);
    glTranslatef(0.0, 0.0, 0.0);
    glScalef(1.0, 1.0, 2.0);
    glutSolidCube(1.0);
    glPopMatrix();
   }
   glPopMatrix();
  }
  {
   //Draw the forefinger, use the transform matrix of palm as parent matrix
   glPushMatrix();
   glTranslatef(3.0, 0.0, -1.5);
   glRotatef(gFingerJointRotations[Forefinger_1st_Joint], 0.0, 0.0, 1.0);
   //Translate twice, make sure the rotation center at the end of the 1st part of forefinger
   glTranslatef(1.0, 0.0, 0.0);
   glScalef(2.0, 1.0, 1.0);
   glutSolidCube(1.0);
   //Eliminate the impact to following objects
   glScalef(1.0/2.0, 1.0, 1.0);
   {
    //Draw the 2nd part of forefinger,
    //use the transform matrix of the first part of forefinger as parent matrix
    glPushMatrix();
    glTranslatef(1.0, 0.0, 0.0);
    glRotatef(gFingerJointRotations[Forefinger_2nd_Joint], 0.0, 0.0, 1.0);
    glTranslatef(1.25, 0.0, 0.0);
    glScalef(2.5, 1.0, 1.0);
    glutSolidCube(1.0);
    glPopMatrix();
   }
   glPopMatrix();
  }
  {
   //Draw middle finger, use the transform matrix of palm as parent matrix
   glPushMatrix();
   glTranslatef(3.0, 0.0, -0.5);
   glRotatef(gFingerJointRotations[MiddleFinger_1st_Joint], 0.0, 0.0, 1.0);
   //Translate twice, make sure the rotation center at the end of the 1st part of middle finger
   glTranslatef(1.25, 0.0, 0.0);
   glScalef(2.5, 1.0, 1.0);
   glutSolidCube(1.0);
   //Eliminate the impact to following objects
   glScalef(1.0/2.5, 1.0, 1.0);
   {
    //Draw the 2nd part of middle finger,
    //use the transform matrix of the first part of middle finger as parent matrix
    glPushMatrix();
    glTranslatef(1.25, 0.0, 0.0);
    glRotatef(gFingerJointRotations[MiddleFinger_2nd_Joint], 0.0, 0.0, 1.0);
    //Translate twice, make sure the rotation center at the end of the 2nd part of middle finger
    glTranslatef(1.5, 0.0, 0.0);
    glScalef(3.0, 1.0, 1.0);
    glutSolidCube(1.0);
    glPopMatrix();
   }
   glPopMatrix();
  }
  {
   //Draw ring finger, use the transform matrix of palm as parent matrix
   glPushMatrix();
   glTranslatef(3.0, 0.0, 0.5);
   glRotatef(gFingerJointRotations[Ringfinger_1st_Joint], 0.0, 0.0, 1.0);
   //Translate twice, make sure the rotation center at the end of the 1st part of ring finger
   glTranslatef(1.0, 0.0, 0.0);
   glScalef(2.0, 1.0, 1.0);
   glutSolidCube(1.0);
   //Eliminate the impact to following objects
   glScalef(1.0/2.0, 1.0, 1.0);
   {
    //Draw the 2nd part of ring finger,
    //use the transform matrix of the first part of ring finger as parent matrix
    glPushMatrix();
    glTranslatef(1.0, 0.0, 0.0);
    glRotatef(gFingerJointRotations[Ringfinger_2nd_Joint], 0.0, 0.0, 1.0);
    //Translate twice, make sure the rotation center at the end of the 2nd part of ring finger
    glTranslatef(1.5, 0.0, 0.0);
    glScalef(3.0, 1.0, 1.0);
    glutSolidCube(1.0);
    glPopMatrix();
   }
   glPopMatrix();
  }
  {
   //Draw little finger, use the transform matrix of palm as parent matrix
   glPushMatrix();
   glTranslatef(3.0, 0.0, 1.5);
   glRotatef(gFingerJointRotations[LittleFinger_1st_Joint], 0.0, 0.0, 1.0);
   //Translate twice, make sure the rotation center at the end of the 1st part of little finger
   glTranslatef(0.75, 0.0, 0.0);
   glScalef(1.5, 1.0, 1.0);
   glutSolidCube(1.0);
   //Eliminate the impact to following objects
   glScalef(1.0/1.5, 1.0, 1.0);
   {
    //Draw the 2nd part of little finger,
    //use the transform matrix of the first part of little finger as parent matrix
    glPushMatrix();
    glTranslatef(0.75, 0.0, 0.0);
    glRotatef(gFingerJointRotations[LittleFinger_2nd_Joint], 0.0, 0.0, 1.0);
    //Translate twice, make sure the rotation center at the end of the 2nd part of little finger
    glTranslatef(1.0, 0.0, 0.0);
    glScalef(2.0, 1.0, 1.0);
    glutSolidCube(1.0);
    glPopMatrix();
   }
   glPopMatrix();
  }
  glPopMatrix(); //pop the palm matrix out
 }
 //Swap the buffers
 glutSwapBuffers();
}
/*
 Keyboard event callback
 Handle key down event
**/
void keyboard(GLubyte key, GLint, GLint)
{
 std::map<GLubyte, ControlData>::iterator it = gKeyControlDataMap.find(key);
 if(it != gKeyControlDataMap.end())
 {//If find the registed key, update the rotation of joint
  if ( gFingerJointRotations[it->second.Index] >= it->second.MinValue &&
   it->second.Delta < 0.0f )
  {
   gFingerJointRotations[it->second.Index] += it->second.Delta;
   glutPostRedisplay();
  }
  else if ( gFingerJointRotations[it->second.Index] <= it->second.MaxValue &&
   it->second.Delta > 0.0f)
  {//Within limit
   //Update Rotation Angel
   gFingerJointRotations[it->second.Index] += it->second.Delta;
   //Refresh window
   glutPostRedisplay();
  }
 }
}
int main(int argc, char** argv)
{
 //Initialize glut
 glutInit(&argc, argv);
 //Initialize display mode, use double buffers
 //Color buffer use RGBA format
 //Create depth buffer
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
 //Create rendering target
 glutInitWindowPosition(200, 100);
 glutInitWindowSize(400, 300);
 glutCreateWindow("Robot");
 
 init();
 //Register redraw callback
 glutDisplayFunc(display);
 //Register window reshape callback
 glutReshapeFunc(reshape);
 //Register keyboard event callback
 glutKeyboardFunc(keyboard);
 //Start message loop
 glutMainLoop();
 return 0;
}