⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 walker.c

📁 嵌入式GUI OpenGL源代码。OpenGL是嵌入式开发中常用的一种GUI系统。
💻 C
📖 第 1 页 / 共 2 页
字号:
    else
      fStep = Step = (int)((float)x/glutGet(GLUT_WINDOW_WIDTH) * CYCLE_SIZE);
      
    CurveDownBtn = button;

    WasWalking = Walking;
    StopWalking();
    RedisplayBoth();
  } else if (button == CurveDownBtn) {
    CurveDownBtn = -1;
    if (WasWalking) {
      Walking = 1;
      agvSetAllowIdle(0);
      glutIdleFunc(IncrementStep);	
    }
  }
}

float CurveEditConstrain(float fx)
{
  if (CurvePickedPoint == 0)
    fx = 0;
  else if (CurvePickedPoint == RotCurve[EditingCurve].numpoints-1)
    fx = 1;
  else if (!(CurvePickedPoint % 3)) {  /* is a pivot */
    fx = MAX(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint-1]);
    fx = MIN(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint+1]);   
    fx = MAX(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint-3]);
    fx = MIN(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint+3]);       
  } else if (!((CurvePickedPoint - 1) % 3)) {   /* is right slope */
    fx = MAX(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint-1]);
  } else {
    fx = MIN(fx, RotCurve[EditingCurve].xcoords[CurvePickedPoint+1]);
  } 
  return fx;
}

void RemovePoint(int pt)
{
  int i;

  for (i = pt - 1; i < RotCurve[EditingCurve].numpoints; i++) {
    RotCurve[EditingCurve].xcoords[i] = RotCurve[EditingCurve].xcoords[i+3];
    RotCurve[EditingCurve].angles[i]  = RotCurve[EditingCurve].angles[i+3];
  }
  RotCurve[EditingCurve].numpoints -= 3;
}

void AddPoint(float fx)
{
  int i, j;

  if (fx < 0.05 || fx > 0.95 || RotCurve[EditingCurve].numpoints + 3 >=
                                MAX_CPOINTS)
    return;

  for (i = 3; i < RotCurve[EditingCurve].numpoints; i += 3) {
    if (fx < RotCurve[EditingCurve].xcoords[i]) {
      for (j = RotCurve[EditingCurve].numpoints + 2; j > i + 1; j--) { 
        RotCurve[EditingCurve].xcoords[j] =
                RotCurve[EditingCurve].xcoords[j-3];
        RotCurve[EditingCurve].angles[j] =
                RotCurve[EditingCurve].angles[j-3];
      }
    RotCurve[EditingCurve].xcoords[i]   = fx;
    RotCurve[EditingCurve].angles[i]    =
      Walk_cycle[0][EditingCurve][(int)(fx*CYCLE_SIZE)];
    RotCurve[EditingCurve].xcoords[i-1] = fx - 0.05;
    RotCurve[EditingCurve].angles[i-1]  =
      Walk_cycle[0][EditingCurve][(int)((fx-0.05)*CYCLE_SIZE)];
    RotCurve[EditingCurve].xcoords[i+1] = fx + 0.05;
    RotCurve[EditingCurve].angles[i+1]  = 
      Walk_cycle[0][EditingCurve][(int)((fx+0.05)*CYCLE_SIZE)];
    RotCurve[EditingCurve].numpoints += 3;
    break;
    }
  }  
}


void CurveEditHandleButton(int button, int state, int x, int y)
{
  float fx, fy;
  int point;

  fy = -(((float)y - ((float)CurveWHeight/NUM_JOINTS * EditingCurve)) /
       ((float)CurveWHeight/NUM_JOINTS) - 0.5) * 180.0,
  fx = (float)x/CurveWWidth;
  
  if (state == GLUT_DOWN && button == GLUT_LEFT_BUTTON &&
                            CurveDownBtn == -1) {
    CurvePickedPoint = -1;
    
    for (point = 0; point < RotCurve[EditingCurve].numpoints; point++) {
      if (fabs(RotCurve[EditingCurve].xcoords[point] - fx) < 0.01 &&
	  fabs(RotCurve[EditingCurve].angles[point] - fy) < 4) {
	CurvePickedPoint = point;
	CurveLastX = x;
	CurveLastY = y;
	glutIdleFunc(CurveCPointDrag);
	break;
      }
    }
   if (CurvePickedPoint == -1)
     CurveHandleButton(button, state, x, y);
    CurveDownBtn = button;


  } else if (state == GLUT_DOWN && button == GLUT_MIDDLE_BUTTON &&
                                   CurveDownBtn == -1) {

    for (point = 3; point < RotCurve[EditingCurve].numpoints - 1; point += 3) {
      if (fabs(RotCurve[EditingCurve].xcoords[point] - fx) < 0.01 &&
	  fabs(RotCurve[EditingCurve].angles[point] - fy) < 4) {
	break;
      }
    }
    if (point >= 3 && point < RotCurve[EditingCurve].numpoints - 1)
      RemovePoint(point);
    else if (fabs(Walk_cycle[0][EditingCurve][(int)(fx*CYCLE_SIZE)] - fy) < 4)
      AddPoint(fx);
    ComputeCurve(EditingCurve);
    MakeJointLists(EditingCurve);    
    RedisplayBoth();

  } else if (button == GLUT_LEFT_BUTTON && button == CurveDownBtn) {

    y = MAX(y, 0); y = MIN(y, CurveWHeight);
    x = MAX(x, 0); x = MIN(x, CurveWWidth);
    fy = -(((float)y - ((float)CurveWHeight/NUM_JOINTS * EditingCurve)) /
         ((float)CurveWHeight/NUM_JOINTS) - 0.5) * 180.0,
    fx = (float)x/CurveWWidth;
    CurveDownBtn = -1;
    if (CurvePickedPoint != -1) {
      fx = CurveEditConstrain(fx);
      RotCurve[EditingCurve].xcoords[CurvePickedPoint] = fx;
      RotCurve[EditingCurve].angles[CurvePickedPoint] = fy;        
      ComputeCurve(EditingCurve);
      MakeJointLists(EditingCurve);
      glutIdleFunc(NULL);
      RedisplayBoth();
    }
  }
}  


void CurveHandleMotion(int x, int y)
{
  if (CurvePickedPoint == -1) { 
    
    if (CurveDownBtn == GLUT_LEFT_BUTTON || CurveDownBtn ==
                                            GLUT_MIDDLE_BUTTON) {
      Step = (int)((float)x/glutGet(GLUT_WINDOW_WIDTH) * CYCLE_SIZE)
	% CYCLE_SIZE;
      if (Step < 0)
	Step = CYCLE_SIZE + Step;
      fStep = Step;

    RedisplayBoth();
    }
  } else {
    y = MAX(y, 0); y = MIN(y, CurveWHeight);
    x = MAX(x, 0); x = MIN(x, CurveWWidth);
    CurveLastX = x;
    CurveLastY = y;
  }
}

void CurveCPointDrag(void)
{
  float fx, fy;

  if (CurveDownBtn == GLUT_LEFT_BUTTON && CurvePickedPoint != -1) {
    fy = -(((float)CurveLastY -
           ((float)CurveWHeight/NUM_JOINTS * EditingCurve)) /
          ((float)CurveWHeight/NUM_JOINTS) - 0.5) * 180.0,
    fx = (float)CurveLastX/CurveWWidth;

    fx = CurveEditConstrain(fx);
    RotCurve[EditingCurve].xcoords[CurvePickedPoint] = fx;
    RotCurve[EditingCurve].angles[CurvePickedPoint] = fy;        
    ComputeCurve(EditingCurve);
    MakeJointLists(EditingCurve);
    RedisplayBoth();
  }
}

/* ARGSUSED1 */
void CurveHandleKeys(unsigned char key, int x, int y)
{
  if (key > '0' && key < '9')
    CurveHandleEditMenu((key-'0')-1);
  else if (key == 'd')
    CurveHandleMenu(CMENU_DONEEDIT);
  else {
    switch(key) {
      case 'f':
      case ' ': Step++;
                StopWalking(); break;
      case 'F': Step += 5;
                StopWalking(); break;
      case 'b': Step--;
                StopWalking(); break;
      case 'B': Step -= 5; 
                StopWalking(); break;
    }
    Step %= CYCLE_SIZE;
    if (Step < 0)
      Step = CYCLE_SIZE + Step;
    fStep = Step;
    RedisplayBoth();
  }
}

void CurveHandleEditMenu(int curve)
{
  if (curve >= NUM_JOINTS)
    return;
  if (EditingCurve == -1) {
    WasWalking = Walking;
    Walking = 0;
    agvSetAllowIdle(0);   /* don't allow spinning, just slows us down */
    glutIdleFunc(NULL);
    glutMouseFunc(CurveEditHandleButton);
  }
  EditingCurve = curve;
  glutPostRedisplay();
}

void CurveHandleSZMenu(int size)
{
  IncStep = (float)size/100;
}

void CurveHandleMenu(int value)
{
  switch (value) {
    case CMENU_QUIT:
      exit(0);
      break;
    case CMENU_CURVE:
      CurveAsPoints = !CurveAsPoints;
      glutPostRedisplay();
      break;
    case CMENU_HORIZ:
      DrawHorizontals = !DrawHorizontals;
      glutPostRedisplay();
      break;
    case CMENU_WALK:
      if (EditingCurve != -1)
	break;
      Walking = !Walking;
      if (Walking) {
        agvSetAllowIdle(0);
	glutIdleFunc(IncrementStep);	
      } else {
        agvSetAllowIdle(1);
      }
      break;
    case CMENU_DONEEDIT:
      glutMouseFunc(CurveHandleButton);
      EditingCurve = -1;
      CurvePickedPoint = -1;
      Walking = WasWalking;
      if (Walking)
	glutIdleFunc(IncrementStep);
      else
        agvSetAllowIdle(1);
      glutPostRedisplay();
      break;
    case CMENU_RESET:
      FlatCSet();
      ComputeCSetAndMakeLists();
      glutPostRedisplay();
      break;
    case CMENU_MIRROR:
      MirrorLegs = !MirrorLegs;
      ComputeCSetAndMakeLists();
      glutPostRedisplay();      
    }
}

void CurveMenuInit(void)
{
  int i;
  char label[3];

  if (CurveEditMenu != -1) {
    glutDestroyMenu(CurveEditMenu);
    glutDestroyMenu(CurveMenu);
    glutDestroyMenu(StepSizeMenu);
  }

  CurveEditMenu = glutCreateMenu(CurveHandleEditMenu);
  for (i = 0; i < NUM_JOINTS; i++) {
    sprintf(label, " %d ", i+1);
    glutAddMenuEntry(label, i);
  }
  StepSizeMenu = glutCreateMenu(CurveHandleSZMenu);
  glutAddMenuEntry("0.25", 25);
  glutAddMenuEntry("0.5",  50);
  glutAddMenuEntry("1.0", 100);
  glutAddMenuEntry("2.0", 200);
  glutAddMenuEntry("3.0", 300);
  glutAddMenuEntry("5.0", 500);
  CurveMenu = glutCreateMenu(CurveHandleMenu);
  glutAddSubMenu("Load Curve Set", LoadMenu);
  glutAddSubMenu("Save As Curve Set", SaveMenu);
  glutAddSubMenu("Edit Curve", CurveEditMenu);
  glutAddMenuEntry("Done Editing", CMENU_DONEEDIT);
  glutAddMenuEntry("Flatten Curve Set", CMENU_RESET);
  glutAddMenuEntry("Toggle mirrored", CMENU_MIRROR);
  glutAddSubMenu("Step size", StepSizeMenu);
  glutAddMenuEntry("Toggle dotted", CMENU_CURVE);
  glutAddMenuEntry("Toggle horizontals", CMENU_HORIZ);
  glutAddMenuEntry("Toggle walking", CMENU_WALK);
  glutAddMenuEntry("Quit", CMENU_QUIT);
  glutSetWindow(CurveWindow);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}

void CurveVisible(int v)
{
  if (v == GLUT_VISIBLE)
    CurveWindowVisible = 1;
  else 
    CurveWindowVisible = 0;
}

/***************************************************************/
/*********************** GUY WINDOW ****************************/
/***************************************************************/

void GuyDisplay(void)
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glFlush();

  glLoadIdentity();

  agvViewTransform();

  if (DrawAxes)
    glCallList(AxesList);

  switch(GuyModel) {
    case WIRECUBE:   DrawTheGuy_WC();  break;
    case SOLIDCUBE:  DrawTheGuy_SC();  break;
    case CYLINDER1:  DrawTheGuy_SL();  break;
    case CYLINDER2:  DrawTheGuy_SL2(); break;
  }

  glutSwapBuffers();
  glFlush();
}

void GuyReshape(int w, int h)
{
  glViewport(0,0,w,h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  if (ViewPerspective)
    gluPerspective(60.0, (GLdouble)w/h, 0.01, 100);
  else
    glOrtho(-1.2, 1.2, -1.2, 1.2, 0.1, 100);
  glMatrixMode(GL_MODELVIEW);
  glFlush();
}


void GuyGLInit(void)
{
  GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
  GLfloat light_position[] = { 0.3, 0.5, 0.8, 0.0 };
  GLfloat lm_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
  
  glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
  glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lm_ambient);
  
  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  glDepthFunc(GL_LESS);
  glEnable(GL_DEPTH_TEST);
  glEnable(GL_NORMALIZE);
  glShadeModel(GL_SMOOTH);
  /* Cylinder stuff */
  StoreTheGuy_SL();
  StoreTheGuy_SL2();
}

void GuyHandleKeys(unsigned char key, int x, int y)
{
  switch(key) {
    case 'f':
    case ' ': Step++;
              StopWalking(); break;
    case 'F': Step += 5;
              StopWalking(); break;
    case 'b': Step--;
              StopWalking(); break;
    case 'B': Step -= 5; 
              StopWalking(); break;
  }
  Step %= CYCLE_SIZE;
  if (Step < 0)
    Step = CYCLE_SIZE + Step;
  agvHandleKeys(key, x, y);
  RedisplayBoth();
}

typedef enum { GMENU_QUIT, GMENU_CURVE, GMENU_HORIZ,
               GMENU_AXES, GMENU_PERSP } GuyMenuChoices;


void GuyModelHandleMenu(int model)
{
  GuyModel = model;
  if (model == WIRECUBE)
    glDisable(GL_LIGHTING);
  else
    glEnable(GL_LIGHTING);
  glutPostRedisplay();
}

void GuyHandleMenu(int value)
{
  switch (value) {
    case GMENU_QUIT:
      exit(0);
      break;
    case GMENU_AXES:
      DrawAxes = !DrawAxes;
      glutPostRedisplay();
      break;
    case GMENU_PERSP:
      ViewPerspective = !ViewPerspective;
      GuyReshape(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
      glutPostRedisplay();
      break;
  }
}

void GuyMenuInit(void)
{
  int sub2, sub1 = glutCreateMenu(agvSwitchMoveMode);
  glutAddMenuEntry("Flying move",  FLYING);
  glutAddMenuEntry("Polar move",   POLAR);
  sub2 = glutCreateMenu(GuyModelHandleMenu);
  glutAddMenuEntry("Wire cubes",  WIRECUBE);
  glutAddMenuEntry("Solid cubes", SOLIDCUBE);
  glutAddMenuEntry("Cylinder 1",  CYLINDER1);
  glutAddMenuEntry("Cylinder 2",  CYLINDER2);
  glutCreateMenu(GuyHandleMenu);
  glutAddSubMenu("Viewing", sub1);
  glutAddSubMenu("Model", sub2);
  glutAddMenuEntry("Toggle Axes",    GMENU_AXES);
  glutAddMenuEntry("Toggle Perspective View", GMENU_PERSP);
  glutAddMenuEntry("Quit",           GMENU_QUIT);
  glutSetWindow(GuyWindow);
  glutAttachMenu(GLUT_RIGHT_BUTTON);
}

/***************************************************************/
/********************* BOTH WINDOWS ****************************/
/***************************************************************/

void RedisplayBoth(void)
{
  glutPostWindowRedisplay(GuyWindow);
  if (CurveWindowVisible) {
    glutPostWindowRedisplay(CurveWindow);
  }
}

void IncrementStep(void)
{
  fStep = fmod(fStep + IncStep, CYCLE_SIZE);
  Step = (int)fStep;
  if (agvMoving)
    agvMove();
  RedisplayBoth();
}

void StopWalking(void)
{
  if (Walking) {
    Walking = 0;
    agvSetAllowIdle(1);
  }
}

void SetWindowTitles(char *csetname)
{
  char windowtitle[MAX_CSETNAMELEN + 20];

  strcpy(windowtitle, "Rotation Curves: ");
  strcat(windowtitle, csetname);
  glutSetWindow(CurveWindow);
  glutSetWindowTitle(windowtitle);

  strcpy(windowtitle, "The Guy: ");
  strcat(windowtitle, csetname);
  glutSetWindow(GuyWindow);
  glutSetWindowTitle(windowtitle);
}

/***************************************************************/
/***************************** MAIN ****************************/
/***************************************************************/

int main(int argc, char** argv)
{
  glutInit(&argc, argv);

  glutInitWindowSize(512, 512);
  glutInitWindowPosition(700, 250);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  GuyWindow = glutCreateWindow("The Guy:");
  agvInit(!Walking);
  AxesList = glGenLists(1);
  agvMakeAxesList(AxesList);
  GuyGLInit();
  GuyMenuInit();
  glutDisplayFunc(GuyDisplay);
  glutReshapeFunc(GuyReshape);
  glutKeyboardFunc(GuyHandleKeys);

  glutInitWindowSize(512, 1024);
  glutInitWindowPosition(100, 0);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  CurveWindow = glutCreateWindow("Rotation Curves:");
  CurveGLInit();
  glutDisplayFunc(CurveDisplay);
  glutReshapeFunc(CurveReshape);
  glutMouseFunc(CurveHandleButton);
  glutMotionFunc(CurveHandleMotion);
  glutKeyboardFunc(CurveHandleKeys);
  glutVisibilityFunc(CurveVisible);

  FlatCSet();
  MakeLists();

  if (MakeLoadAndSaveMenus() > 0)  /* read first curve if there was one */
    HandleLoadMenu(0);

  CurveMenuInit();

  glutMainLoop();
  return 0;             /* ANSI C requires main to return int. */
}




⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -