使用opengl画的一个运动的机器人

来源:互联网 发布:visio有mac版吗 编辑:程序博客网 时间:2024/05/18 03:24
#define WIN32_LEAN_AND_MEAN
#include <gl/GLUT.H>
#include <windows.h>
#pragma comment(lib, "openGL32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
float angle=0.0f;
HDC g_HDC;
bool fullScreen=false;
float legAngle[2]={0.0f,0.0f};
float armAngle[2]={0.0f,0.0f};
//绘制单位立方体
void DrawCube(float xPos,float yPos,float zPos)
{
 glPushMatrix();
 glTranslatef(xPos,yPos,zPos);
  glBegin(GL_POLYGON);
   glVertex3f(0.0f,0.0f,0.0f);  //顶面
   glVertex3f(0.0f,0.0f,-1.0f);
   glVertex3f(-1.0f,0.0f,-1.0f);
   glVertex3f(-1.0f,0.0f,0.0f);
   glVertex3f(0.0f,0.0f,0.0f);  //正面
   glVertex3f(-1.0f,0.0f,0.0f);
   glVertex3f(-1.0f,-1.0f,0.0f);
   glVertex3f(0.0f,-1.0f,0.0f);
   glVertex3f(0.0f,0.0f,0.0f);  //右面
   glVertex3f(0.0f,-1.0f,0.0f);
   glVertex3f(0.0f,-1.0f,-1.0f);
   glVertex3f(0.0f,0.0f,-1.0f);
   glVertex3f(-1.0f,0.0f,0.0f); //左面
   glVertex3f(-1.0f,0.0f,-1.0f);
   glVertex3f(-1.0f,-1.0f,-1.0f);
   glVertex3f(-1.0f,-1.0f,0.0f);
   glVertex3f(0.0f,-1.0f,0.0f);  //底面
   glVertex3f(0.0f,-1.0f,-1.0f);
   glVertex3f(-1.0f,-1.0f,-1.0f);
   glVertex3f(-1.0f,-1.0f,0.0f);
   glVertex3f(0.0f,0.0f,-1.0f);  //背面
   glVertex3f(-1.0f,0.0f,-1.0f);
   glVertex3f(-1.0f,-1.0f,-1.0f);
   glVertex3f(0.0f,-1.0f,-1.0f);
  glEnd();
 glPopMatrix();
}
//绘制手臂
void DrawArm(float xPos,float yPos,float zPos)
{
 glPushMatrix();
  glColor3f(1.0f,0.0f,0.0f);   //红色
  glTranslatef(xPos,yPos,zPos);
  glScalef(1.0f,4.0f,1.0f);   //机器人的手臂是一个1*4*1的立方体
  DrawCube(0.0f,0.0f,0.0f);
 glPopMatrix();
}
//绘制头部
void DrawHead(float xPos,float yPos,float zPos)
{
 glPushMatrix();
  glColor3f(1.0f,1.0f,1.0f);   //白色
  glTranslatef(xPos,yPos,zPos);
  glScalef(2.0f,2.0f,2.0f);   //机器人的头是一个2*2*2的立方体
  DrawCube(0.0f,0.0f,0.0f);
 glPopMatrix();
}
//绘制躯干
void DrawTorso(float xPos,float yPos,float zPos)
{
 glPushMatrix();
  glColor3f(0.0f,0.0f,1.0f);   //蓝色
  glTranslatef(xPos,yPos,zPos);
  glScalef(3.0f,5.0f,2.0f);   //机器人的躯干是一个3*5*2的立方体
  DrawCube(0.0f,0.0f,0.0f);
 glPopMatrix();
}
//绘制腿
void DrawLeg(float xPos,float yPos,float zPos)
{
 glPushMatrix();
  glColor3f(1.0f,1.0f,0.0f);   //黄色
  glTranslatef(xPos,yPos,zPos);
  glScalef(1.0f,5.0f,1.0f);   //机器人的腿是一个1*5*1的立方体
  DrawCube(0.0f,0.0f,0.0f);
 glPopMatrix();
}
//绘制机器人
void DrawRobot(float xPos,float yPos,float zPos)
{
 static bool leg1=true;     //机器人腿的状态
 static bool leg2=false;     //true=前,false=后
 
 static bool arm1=true;     //机器人手臂的状态
 static bool arm2=false;     //true=前,false=后
 glPushMatrix();
  glTranslatef(xPos,yPos,zPos);  //在所期望的坐标处绘制机器人
  //绘制部件
  DrawHead(-5.0f,2.0f,1.0f);
  DrawTorso(-4.5f,0.0f,1.0f);
  glPushMatrix();
 //如果手臂向前移动,就增大角度,否则减小角度
  if(arm1)
   armAngle[0]=armAngle[0]+0.1f;
  else
   armAngle[0]=armAngle[0]-0.1f;
 //一旦手臂在一个方向上达到了其最大角度值就将其反转
  if(armAngle[0]>=15.0f)
   arm1=false;
  if(armAngle[0]<=-15.0f)
   arm1=true;
 //称动并旋转手臂,以产生"行走"的效果
  glTranslatef(0.0f,-0.5f,0.0f);
  glRotatef(armAngle[0],1.0,0.0f,0.0f);
  DrawArm(-3.5f,0.0f,0.25f);
  glPopMatrix();
  glPushMatrix();
 //如果手臂向前移动,就增大角度,否则减小角度
  if(arm2)
   armAngle[1]=armAngle[1]+0.1f;
  else
   armAngle[1]=armAngle[1]-0.1f;
 //一旦手臂在一个方向上达到了其最大角度值就将其反转
  if(armAngle[1]>=15.0f)
   arm2=false;
  if(armAngle[1]<=-15.0f)
   arm2=true;
 //称动并旋转手臂,以产生"行走"的效果
  glTranslatef(0.0f,-0.5f,0.0f);
  glRotatef(armAngle[1],1.0,0.0f,0.0f);
  DrawArm(-7.5f,0.0f,0.25f);
  glPopMatrix();
 //对Leg1----机器人右腿的操作
  glPushMatrix();
 //如果腿向前移动,就增大角度,否则就减小角度
  if(leg1)
   legAngle[0]=legAngle[0]+0.1f;
  else
   legAngle[0]=legAngle[0]-0.1f;
 //一旦腿在一个方向达到了最大的角度值,就将其反转
  if(legAngle[0]>=15.0f)
   leg1=false;
  if(legAngle[0]<=-15.0f)
   leg1=true;
 //移动并旋转腿,以产生"行走"的效果
  glTranslatef(0.0f,-0.5f,0.0f);
  glRotatef(legAngle[0],1.0f,0.0f,0.0f);
 //绘制腿
  DrawLeg(-6.5f,-5.0f,0.25f);
  glPopMatrix();
 //对Leg2----机器人右腿的操作
  glPushMatrix();
 //如果腿向前移动,就增大角度,否则就减小角度
  if(leg2)
   legAngle[1]=legAngle[1]+0.1f;
  else
   legAngle[1]=legAngle[1]-0.1f;
 //一旦腿在一个方向达到了最大的角度值,就将其反转
  if(legAngle[1]>=15.0f)
   leg2=false;
  if(legAngle[1]<=-15.0f)
   leg2=true;
 //移动并旋转腿,以产生"行走"的效果
  glTranslatef(0.0f,-0.5f,0.0f);
  glRotatef(legAngle[1],1.0f,0.0f,0.0f);
 //绘制腿
  DrawLeg(-4.5f,-5.0f,0.25f);
  glPopMatrix();
 glPopMatrix();
}
//处理场景的绘制
void Render()
{
 glEnable(GL_DEPTH_TEST);   //启用深度检测
 //在此处绘制
 glClearColor(0.0f,0.0f,0.0f,0.0f); //设置清理色为黑色
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //清理颜色/深度缓存
 glLoadIdentity();     //复位旋转角度计数器
 angle=angle+0.1f;     //递增旋转角度计数器
 if(angle>=360.0f)     //如果已旋转一周,复位计数器
  angle=0.0f;
 glPushMatrix();      //将当前矩阵压入矩阵堆栈
  glLoadIdentity();    //复位矩阵
  glTranslatef(0.0f,0.0f,-30.0f); //平移至(0,0,-30)
  glRotatef(angle,0.0f,1.0f,0.0f);//绕其y轴旋转机器人
  DrawRobot(0.0f,0.0f,0.0f);  //绘制机器人
 glPopMatrix();      //弹出当前矩阵
 glFlush();       
 SwapBuffers(g_HDC);     //交换前后缓存
}
//为设备环境设置像素格式的函数
void SetupPixelFormat(HDC hDC)
{
 int nPixelFormat;
 static PIXELFORMATDESCRIPTOR pfd=
 {
  sizeof(PIXELFORMATDESCRIPTOR),
   1,
   PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
   PFD_TYPE_RGBA,
   32,
  0,0,0,0,0,0,
  0,
  0,
  0,
  0,0,0,0,
  16,
  0,
  0,
  PFD_MAIN_PLANE,
  0,
  0,0,0
 };
 nPixelFormat=ChoosePixelFormat(hDC,&pfd);
 SetPixelFormat(hDC,nPixelFormat,&pfd);
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 static HGLRC hRC;
 static HDC hDC;
 int width,height;
 switch(message)
 {
 case WM_CREATE:
  hDC=GetDC(hwnd);
  g_HDC=hDC;
  SetupPixelFormat(hDC);
  hRC=wglCreateContext(hDC);
  wglMakeCurrent(hDC,hRC);
  return 0;
  break;
  
 case WM_CLOSE:
  wglMakeCurrent(hDC,NULL);
  wglDeleteContext(hRC);
  PostQuitMessage(0);
  return 0;
  break;
  
 case WM_SIZE:
  height=HIWORD(lParam);
  width=LOWORD(lParam);
  if(height==0)
   height=1;
  glViewport(0,0,width,height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(54.0f,(GLfloat)width/(GLfloat)height,1.0f,1000.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  return 0;
  break;
 default:
  break;
 }
 return (DefWindowProc(hwnd,message,wParam,lParam));
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
 WNDCLASSEX windowClass;
 HWND hwnd;
 MSG msg;
 bool done;
 DWORD dwExStyle;
 DWORD dwStyle;
 RECT windowRect;
 int width=800;
 int height=600;
 int bits=32;
 windowRect.left=(long)0;
 windowRect.right=(long)width;
 windowRect.top=(long)0;
 windowRect.bottom=(long)height;
 windowClass.cbSize=sizeof(WNDCLASSEX);
 windowClass.style=CS_HREDRAW|CS_VREDRAW;
 windowClass.lpfnWndProc=WndProc;
 windowClass.cbClsExtra=0;
 windowClass.cbWndExtra=0;
 windowClass.hInstance=hInstance;
 windowClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 windowClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 windowClass.hbrBackground=NULL;
 windowClass.lpszMenuName=NULL;
 windowClass.lpszClassName="MyClass";
 windowClass.hIconSm=LoadIcon(NULL,IDI_WINLOGO);
 if(!RegisterClassEx(&windowClass))
  return 0;
 if(fullScreen)
 {
  DEVMODE dmScreenSettings;
  memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
  dmScreenSettings.dmSize=sizeof(dmScreenSettings);
  dmScreenSettings.dmPelsWidth=width;
  dmScreenSettings.dmPelsHeight=height;
  dmScreenSettings.dmBitsPerPel=bits;
  dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
  if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
  {
   MessageBox(NULL,"Display mode failed",NULL,MB_OK);
   fullScreen=FALSE;
  }
 }
 if(fullScreen)
 {
  dwExStyle=WS_EX_APPWINDOW;
  dwStyle=WS_POPUP;
  ShowCursor(FALSE);
 }
 else
 {
  dwExStyle=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;
  dwStyle=WS_OVERLAPPEDWINDOW;
 }
 AdjustWindowRectEx(&windowRect,dwStyle,FALSE,dwExStyle);
 hwnd=CreateWindowEx(dwExStyle,"MyClass",
  "OpenGL Robot",
  dwStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
  0,0,
  windowRect.right-windowRect.left,
  windowRect.bottom-windowRect.top,
  NULL,
  NULL,
  hInstance,
  NULL);
 if(!hwnd)
  return 0;
 ShowWindow(hwnd,SW_SHOW);
 UpdateWindow(hwnd);
 done=false;
 while(!done)
 {
  PeekMessage(&msg,hwnd,NULL,NULL,PM_REMOVE);
  if(msg.message==WM_QUIT)
  {
   done=true;
  }
  else
  {
   Render();
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
 }
 if(fullScreen)
 {
  ChangeDisplaySettings(NULL,0);
  ShowCursor(TRUE);
 }
 return msg.wParam;

}


转自:http://blog.sina.com.cn/s/blog_4b397765010006n6.html

0 0