串口通信的上位机程序(openGL画图)

来源:互联网 发布:sql入门经典好不好 编辑:程序博客网 时间:2024/05/19 08:43

//*******************************************************************************************
/*          上位机程序
本程序实现两个功能:
1.从串口接收数据,并将字符串转化成整型数据。
2.利用整型数据,转化成角度,对虚拟模型进行旋转
*/
//*******************************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <math.h>
#include <gl/glut.h>
#include <windows.h>

HANDLE hComm;
OVERLAPPED m_ov;
COMSTAT comstat;
DWORD m_dwCommEvents;

#define WIDTH 400
#define HEIGHT 400
#define ColoredVertex(c, v) do{ glColor3fv(c); glVertex3fv(v); }while(0)
#define MAX_CHAR       128
GLfloat angle = 0.0f,anglex = 0.0f;//旋转动画角度初始值

static int Dxx=0,Dyy=0,Dzz=0;//旋转方向
int xx,yy,zz;//从串口得到的坐标变化
//对应关系:zz+1->Dyy-1  xx+1->Dxx-1 yy+1->Dzz-1
int tempb=0;//zz用于保存上次的读取结果
int tempab=0;//计算zz偏移角的变量

int tempx=0;//xx用于保存上次的读取结果
int tempax=0;//计算xx偏移角的变量

int limitx,limity,limitz;//旋转的最大角度

char input[40]="c=+000";
char tempd[2]=" ";//暂存RXBuff

int tt=0;//字符串序号移位
int inputflag=0;//接收字符类型判断,1=a,2=b,3=c

 

 

/*******************串口部分***************************/

bool openport(char *portname)//打开一个串口
{
 hComm = CreateFile(portname,
 GENERIC_READ | GENERIC_WRITE,
 0,
 0,
 OPEN_EXISTING,
 FILE_FLAG_OVERLAPPED,
 0);
 if (hComm == INVALID_HANDLE_VALUE)
 return FALSE;
 else
 return true;
}

bool setupdcb(int rate_arg)
{
 DCB dcb;
 int rate= rate_arg;
 memset(&dcb,0,sizeof(dcb));
 if(!GetCommState(hComm,&dcb))//获取当前DCB配置
 {
 return FALSE;
 }
 /* -------------------------------------------------------------------- */
 // set DCB to configure the serial port
 dcb.DCBlength = sizeof(dcb);
 /* ---------- Serial Port Config ------- */
 dcb.BaudRate = rate;
 dcb.Parity = NOPARITY;
 dcb.fParity = 0;
 dcb.StopBits = ONESTOPBIT;
 dcb.ByteSize = 8;
 dcb.fOutxCtsFlow = 0;
 dcb.fOutxDsrFlow = 0;
 dcb.fDtrControl = DTR_CONTROL_DISABLE;
 dcb.fDsrSensitivity = 0;
 dcb.fRtsControl = RTS_CONTROL_DISABLE;
 dcb.fOutX = 0;
 dcb.fInX = 0;
 /* ----------------- misc parameters ----- */
 dcb.fErrorChar = 0;
 dcb.fBinary = 1;
 dcb.fNull = 0;
 dcb.fAbortOnError = 0;
 dcb.wReserved = 0;
 dcb.XonLim = 2;
 dcb.XoffLim = 4;
 dcb.XonChar = 0x13;
 dcb.XoffChar = 0x19;
 dcb.EvtChar = 0;
 /* -------------------------------------------------------------------- */
 // set DCB
 if(!SetCommState(hComm,&dcb))
 {
 return false;
 }
 else
 return true;
 }
 bool setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORD WriteTotalMultiplier,DWORD WriteTotalconstant)
 {
 COMMTIMEOUTS timeouts;
 timeouts.ReadIntervalTimeout=ReadInterval;
 timeouts.ReadTotalTimeoutConstant=ReadTotalconstant;
 timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier;
 timeouts.WriteTotalTimeoutConstant=WriteTotalconstant;
 timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier;
 if(!SetCommTimeouts(hComm, &timeouts))
 {
 return false;
 }
 else
 return true;
}

/***************************寻找有效数值zz  ***************************/
int findnum(char stringi[],int toz)
{
 int ii;
 char tempz[4];//,tempy[4],tempz[4];
 for(ii=0;ii<strlen(stringi);ii++)
 {
  if((stringi[ii]=='c')&&((stringi[ii+1]=='-')||(stringi[ii+1]=='+'))&&((stringi[ii+2]=='0')||(stringi[ii+2]=='1')||(stringi[ii+2]=='2')||(stringi[ii+2]=='3')||(stringi[ii+2]=='4')||(stringi[ii+2]=='5')||(stringi[ii+2]=='6')||(stringi[ii+2]=='7')||(stringi[ii+2]=='8')||(stringi[ii+2]=='9')))
   {
    //读数
    tempz[0]=stringi[ii+1];//读符号位
    tempz[1]=stringi[ii+2];//读符百位
    tempz[2]=stringi[ii+3];//读符十位
    tempz[3]=stringi[ii+4];//读符个位
    //转换为整型
    toz=(int)(tempz[1]-'0')*100+(int)(tempz[2]-'0')*10+(int)(tempz[3]-'0');    
    if(tempz[0]=='-')toz=-toz;
    else if(tempz[0]=='+')toz=toz;
    break;
   }
 }
 return toz;  
}
/***************************寻找有效数值xx  ***************************/
int findnum_x(char stringi1[],int tox)
{
 int i1;
 char tempx[3];//,tempy[4],tempz[4];
 for(i1=0;i1<strlen(stringi1);i1++)
 {
  if((stringi1[i1]=='a')&&((stringi1[i1+1]=='-')||(stringi1[i1+1]=='+'))&&((stringi1[i1+2]=='0')||(stringi1[i1+2]=='1')||(stringi1[i1+2]=='2')||(stringi1[i1+2]=='3')||(stringi1[i1+2]=='4')||(stringi1[i1+2]=='5')||(stringi1[i1+2]=='6')||(stringi1[i1+2]=='7')||(stringi1[i1+2]=='8')||(stringi1[i1+2]=='9')))
   {
    //读数
    tempx[0]=stringi1[i1+1];//读符号位
    tempx[1]=stringi1[i1+2];//读符百位
    tempx[2]=stringi1[i1+3];//读符十位
//    tempx[3]=stringi1[i1+4];//读符个位
    //转换为整型
    tox=(int)(tempx[1]-'0')*10+(int)(tempx[2]-'0');  
    if(tempx[0]=='-')tox=-tox;
    else if(tempx[0]=='+')tox=tox;
    break;
   }
 }
 return tox;  
}

/***************************从串口获取信息***************************/
void ReceiveChar( )
{
 BOOL bRead = TRUE;
 BOOL bResult = TRUE;
 DWORD dwError = 0;
 DWORD BytesRead = 0;
 char RXBuff;
 int times=1;
 for (;times<2;times++)////只执行一次//for(;;)//读取的死循环
 {
 bResult = ClearCommError(hComm, &dwError, &comstat);
 if (comstat.cbInQue == 0)
 continue;
 if (bRead)
 {
  bResult = ReadFile(hComm, // Handle to COMM port
  &RXBuff, // RX Buffer Pointer
  1, // Read one byte
  &BytesRead, // Stores number of bytes read
  &m_ov); // pointer to the m_ov structure
 // printf("%c",RXBuff);//********************************************************************************/!一个一个地读
  //用字符串接收
  //有外部变量 整型tt,xx,yy,zz,字符串input,容量为2的字符串tempd
     //tempd[0]=RXBuff;//字符放进字符串
  if(RXBuff=='a'||inputflag==2){
   //printf("find_a ");
   inputflag=2;//进行标记,为了下次继续进入
   input[tt]=RXBuff;//读取   
   if(tt==3) {
    tt=0;inputflag=0;xx=findnum_x(input,xx);
//    printf("xx=%4d ",xx);
   }//如果已经tt为5,则应归0,退出读取。printf("%s",input);
   else tt++;//否则移位
   
   
  }
  if(RXBuff=='c'||inputflag==3){
   //printf("find_c ");//确认进入读取
   inputflag=3;//进行标记,为了下次继续进入
   input[tt]=RXBuff;//读取   
   if(tt==4) {
    tt=0;inputflag=0; zz=findnum(input,zz);
//    printf("zz=%4d\n ",zz);
   }//如果已经tt为5,则应归0,退出读取。printf("%s",input);
   else tt++;//否则移位
   
   //printf("zz=%4d\n ",zz);
  }

 


 
 if (!bResult)
  {
   switch (dwError = GetLastError())
   {
    case ERROR_IO_PENDING:
     {
     bRead = FALSE;
     break;
     }
    default:{break;}
   }//swtch(dwError = GetLastError())
  }// if (!bResult)
 else{ bRead = TRUE; }
 } // close if (bRead)
 if (!bRead)
  {
   bRead = TRUE;
   bResult = GetOverlappedResult(hComm, // Handle to COMM port
   &m_ov, // Overlapped structure
   &BytesRead, // Stores number of bytes read
   TRUE); // Wait flag
  }//if (!bRead)
 }//for
}//ReceiveChar()

//从串口发送信息
bool WriteChar(char *m_szWriteBuffer,DWORD m_nToSend)
 {
 BOOL bWrite = TRUE;
 BOOL bResult = TRUE;
 DWORD BytesSent = 0;
 HANDLE m_hWriteEvent;
 ResetEvent(m_hWriteEvent);
 if (bWrite)
 {
  m_ov.Offset = 0;
  m_ov.OffsetHigh = 0;
  // Clear buffer
  bResult = WriteFile(hComm, // Handle to COMM Port
  m_szWriteBuffer, // Pointer to message buffer in calling finction
  m_nToSend, // Length of message to send
  &BytesSent, // Where to store the number of bytes sent
  &m_ov ); // Overlapped structure
  if (!bResult)
  {
  DWORD dwError = GetLastError();
  switch (dwError)
   {
   case ERROR_IO_PENDING:
   {
   // continue to GetOverlappedResults()
   BytesSent = 0;
   bWrite = FALSE;
   break;
   }
   default:
    {
    // all other error codes
    break;
    }//default
   }//switch
  }//if(!bR)
 } // end if(bWrite)
 if (!bWrite)
  {
 bWrite = TRUE;
 bResult = GetOverlappedResult(hComm, // Handle to COMM port
 &m_ov, // Overlapped structure
 &BytesSent, // Stores number of bytes sent
 TRUE); // Wait flag
 // deal with the error code
 if (!bResult)
  {
   printf("GetOverlappedResults() in WriteFile()");
  }
 } // end if (!bWrite)
 // Verify that the data size send equals what we tried to send
 if (BytesSent != m_nToSend)
  {
   printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer));
  }
  return true;
}
/******读取串口*******/
void initgetter()
{
 int baud=1200;//波特率
 if(openport("com1"))//端口号
 printf("open comport success,port=com1\n");
 if(setupdcb(baud)) 
 printf("setupDCB success,Baud=%d\n",baud);
 if(setuptimeout(0,0,0,0,0))
 printf("setuptimeout success\n");
 PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
 //WriteChar("please send data now",20);
 printf("received data:\n");
 
}


/*******************动画部分***************************/
/****************绘制字符串*********************/
void drawString(const char* str) {
    static int isFirstCall = 1;
    static GLuint lists;

    if( isFirstCall ) { // 如果是第一次调用,执行初始化
                        // 为每一个ASCII字符产生一个显示列表
        isFirstCall = 0;

        // 申请MAX_CHAR个连续的显示列表编号
        lists = glGenLists(MAX_CHAR);

        // 把每个字符的绘制命令都装到对应的显示列表中
        wglUseFontBitmaps(wglGetCurrentDC(), 0, MAX_CHAR, lists);
    }
    // 调用每个字符对应的显示列表,绘制每个字符
    for(; *str!='\0'; ++str)
        glCallList(lists + *str);
}
/********************整型到字符串**************************/
void findString(int n2string)
{
 switch(n2string)
 {
  // case 0:{drawString("0");break;}
  case 1:{drawString("1");break;}
  case 2:{drawString("2");break;}
  case 3:{drawString("3");break;}
  case 4:{drawString("4");break;}
  case 5:{drawString("5");break;}
  case 6:{drawString("6");break;}
  case 7:{drawString("7");break;}
  case 8:{drawString("8");break;}
  case 9:{drawString("9");break;}
  default:{drawString("0");}
 }
 
}
/**********OPENGL的x轴运动角度调整(加速度计的x轴)************/
int to_degree(int turnx)
{
 
 turnx=turnx*3.9;
 if(turnx>99)turnx=100;
 else if(turnx<-99)turnx=-100;
 turnx=((float)turnx*0.9);// printf("turnx=%4d\n",turnx);//调试信息,检查输入
 return turnx;
}

/**********初始化,加入显示列表************/
void myDisplay(void)
{
     static int list = 0;
  int tx;
//  ReceiveChar(); //需要死循环来不断读取
 
     if( list == 0 )
     {
         // 如果显示列表不存在,则创建
   //四个点的坐标
         GLfloat
//船底
   PointA[] = {  0   ,  0.1f  , 1.2f },//RED
   PointD[] = {  0   , -0.1f  , 1.0f  },//YELLOW

   PointB[] = { -0.23f,  0    , 0.8f},//GREEN
   PointE[] = { -0.21f, -0.1f , 0.8f},

   PointC[] = {  0.23f,  0    ,0.8f  },//BLUE   
   PointF[] = {  0.21f, -0.1f , 0.8f},

   PointG[] = {-0.2f,  0    ,-0.6f},
   PointI[] = {-0.2f, -0.1f, -0.6f},

   PointH[] = { 0.2f,  0   , -0.6f},
   PointJ[] = { 0.2f, -0.1f, -0.6f},

//船舱

    PointK[] = {-0.15f,  0     ,0.6f },   
   PointL[] = {-0.15f,  -0.1f , -0.3f},
   PointM[] = { 0.15f,  -0.1f , -0.3f},
   PointN[] = { 0.15f,  0     , 0.6f},

   PointO[] = {-0.15f,  0.15f  ,  0.5f },
   PointP[] = {-0.15f,  0.15f  ,  0.05f },   
   PointQ[] = { 0.15f,  0.15f  ,  0.05f  },   
   PointR[] = { 0.15f,  0.15f  ,  0.5f },

   PointS[] = {-0.15f,  0.1f  ,  0.03f},
   PointT[] = {-0.15f,  0.1f  ,  -0.3f },
   PointU[] = { 0.15f,  0.1f  ,  -0.3f },
   PointV[] = { 0.15f,  0.1f  ,  0.03f },


//指挥塔 
      Pointd21[] = {-0.13f,  0.15f  ,  0.4f },
   Pointd22[] = {-0.13f,  0.15f  ,  0.06f },   
   Pointd23[] = { 0.13f,  0.15f  ,  0.06f  },   
   Pointd24[] = { 0.13f,  0.15f  ,  0.4f },

   Pointd11[] = {-0.13f,  0.22f  ,  0.45f },
   Pointd12[] = {-0.13f,  0.22f  ,  0.06f },
   Pointd13[] = { 0.13f,  0.22f  ,  0.06f },
   Pointd14[] = { 0.13f,  0.22f  ,  0.45f },

//瞭望塔
   Points21[] = {-0.03f,  0.22f  ,  0.15f },
   Points22[] = {-0.03f,  0.22f  ,  0.06f },
   Points23[] = { 0.03f,  0.22f  ,  0.06f },
   Points24[] = { 0.03f,  0.22f  ,  0.15f },

      Points11[] = {-0.03f,  0.45f  ,  0.09f },
   Points12[] = {-0.03f,  0.45f  ,  0.06f },   
   Points13[] = { 0.03f,  0.45f  ,  0.06f  },   
   Points14[] = { 0.03f,  0.45f  ,  0.09f };


  
         GLfloat
   ColorR[] = {1, 0, 0},
   ColorG[] = {0, 1, 0},
   ColorB[] = {0, 0, 1},
   ColorW[] = {0.7, 0.7, 0.7},
   ColorY[] = {1, 1, 0};

         list = glGenLists(1);// 自动分配一个没有使用的显示列表编号,参数表示要分配i个连续的未使用的显示列表编号。返回的是分配的若干连续编号中最小的一个
         glNewList(list, GL_COMPILE);
         glBegin(GL_QUADS);//(GL_LINE_LOOP);//???
  
         // 上表面ABGHC
         ColoredVertex(ColorR, PointA);
         ColoredVertex(ColorR, PointB);
   ColoredVertex(ColorR, PointG);
   ColoredVertex(ColorR, PointC);

         ColoredVertex(ColorR, PointA);
         ColoredVertex(ColorR, PointC);
   ColoredVertex(ColorR, PointH);
         ColoredVertex(ColorR, PointG);

         // 下表面 DEIJF
         ColoredVertex(ColorG, PointD);
         ColoredVertex(ColorG, PointE);
         ColoredVertex(ColorG, PointI);
   ColoredVertex(ColorG, PointF);

         ColoredVertex(ColorG, PointE);
         ColoredVertex(ColorG, PointI);
         ColoredVertex(ColorG, PointJ);
         ColoredVertex(ColorG, PointF);

         // 右前侧ADFC
         ColoredVertex(ColorB, PointA);
         ColoredVertex(ColorB, PointD);
         ColoredVertex(ColorB, PointF);
   ColoredVertex(ColorB, PointC);
         //左前侧ADEB
   ColoredVertex(ColorB, PointA);
         ColoredVertex(ColorB, PointD);
         ColoredVertex(ColorB, PointE);
         ColoredVertex(ColorB, PointB);
   //右侧CFJH
   ColoredVertex(ColorB, PointC);
         ColoredVertex(ColorB, PointF);
         ColoredVertex(ColorB, PointJ);
         ColoredVertex(ColorB, PointH);
   //左侧BEI
   ColoredVertex(ColorB, PointB);
         ColoredVertex(ColorB, PointE);
         ColoredVertex(ColorB, PointI);
         ColoredVertex(ColorB, PointG);
   //后侧GIJH
   ColoredVertex(ColorB, PointG);
         ColoredVertex(ColorB, PointI);
         ColoredVertex(ColorB, PointJ);
         ColoredVertex(ColorB, PointH);
   //船舱正面
   ColoredVertex(ColorB, PointK);
         ColoredVertex(ColorB, PointO);
         ColoredVertex(ColorB, PointR);
         ColoredVertex(ColorB, PointN);
   //船舱顶1
   ColoredVertex(ColorB, PointO);
         ColoredVertex(ColorB, PointP);
         ColoredVertex(ColorB, PointQ);
         ColoredVertex(ColorB, PointR);
   //船舱顶2
   ColoredVertex(ColorB, PointS);
         ColoredVertex(ColorB, PointT);
         ColoredVertex(ColorB, PointU);
         ColoredVertex(ColorB, PointV);
   //船舱背1
   ColoredVertex(ColorB, PointP);
         ColoredVertex(ColorB, PointS);
         ColoredVertex(ColorB, PointV);
         ColoredVertex(ColorB, PointQ);
   //船舱背2
   ColoredVertex(ColorB, PointT);
         ColoredVertex(ColorB, PointL);
         ColoredVertex(ColorB, PointM);
         ColoredVertex(ColorB, PointU);
   //船舱左
   ColoredVertex(ColorY, PointO);
         ColoredVertex(ColorY, PointP);
         ColoredVertex(ColorY, PointS);
         ColoredVertex(ColorY, PointK);

   ColoredVertex(ColorY, PointS);
         ColoredVertex(ColorY, PointT);
         ColoredVertex(ColorY, PointL);
         ColoredVertex(ColorY, PointK);
   //船舱右
   ColoredVertex(ColorG, PointQ);
         ColoredVertex(ColorG, PointV);
         ColoredVertex(ColorG, PointN);
         ColoredVertex(ColorG, PointR);

   ColoredVertex(ColorG, PointV);
         ColoredVertex(ColorG, PointU);
         ColoredVertex(ColorG, PointM);
         ColoredVertex(ColorG, PointN);
   //指挥塔正面
   ColoredVertex(ColorY, Pointd11);
         ColoredVertex(ColorY, Pointd21);
         ColoredVertex(ColorY, Pointd24);
         ColoredVertex(ColorY, Pointd14);
   //指挥塔顶面
   ColoredVertex(ColorB, Pointd11);
         ColoredVertex(ColorB, Pointd12);
         ColoredVertex(ColorB, Pointd13);
         ColoredVertex(ColorB, Pointd14);
   //指挥塔左面
   ColoredVertex(ColorG, Pointd11);
         ColoredVertex(ColorG, Pointd21);
         ColoredVertex(ColorG, Pointd22);
         ColoredVertex(ColorG, Pointd12);
   //指挥塔右面
   ColoredVertex(ColorY, Pointd14);
         ColoredVertex(ColorY, Pointd13);
         ColoredVertex(ColorY, Pointd23);
         ColoredVertex(ColorY, Pointd24);
   //指挥塔背面
   ColoredVertex(ColorY, Pointd12);
         ColoredVertex(ColorY, Pointd22);
         ColoredVertex(ColorY, Pointd23);
         ColoredVertex(ColorY, Pointd13);

   //瞭望塔正面
   ColoredVertex(ColorB, Points11);
         ColoredVertex(ColorB, Points21);
         ColoredVertex(ColorB, Points24);
         ColoredVertex(ColorB, Points14);
   //瞭望塔顶面
   ColoredVertex(ColorR, Points11);
         ColoredVertex(ColorR, Points12);
         ColoredVertex(ColorR, Points13);
         ColoredVertex(ColorR, Points14);
   //瞭望塔左面
   ColoredVertex(ColorG, Points11);
         ColoredVertex(ColorG, Points21);
         ColoredVertex(ColorG, Points22);
         ColoredVertex(ColorG, Points12);
   //瞭望塔右面
   ColoredVertex(ColorY, Points14);
         ColoredVertex(ColorY, Points13);
         ColoredVertex(ColorY, Points23);
         ColoredVertex(ColorY, Points24);
   //瞭望塔背面
   ColoredVertex(ColorR, Points12);
         ColoredVertex(ColorR, Points22);
         ColoredVertex(ColorR, Points23);
         ColoredVertex(ColorR, Points13);
/*glEnd();*/
         glEnd();
         glEndList();
         glEnable(GL_DEPTH_TEST);
     }
     // 已经创建了显示列表,在每次绘制正四面体时将调用它
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glPushMatrix();//进入
  /**/
  glMatrixMode(GL_PROJECTION); //要操作投影矩阵,需要以GL_PROJECTION为参数调用glMatrixMode函数。
     glLoadIdentity();// 变换前把当前矩阵设置为单位矩阵。
     gluPerspective(75, 1, 1, 200);// 将当前的可视空间设置为透视投影空间// gluPerspective(视角,高宽比,最近距离,最远距离)//0为水平,90为正下方,所在点为观察点
     glMatrixMode(GL_MODELVIEW);// 在进行变换前,先设置当前操作的矩阵为"模型视图矩阵"。
     glLoadIdentity();// 变换前把当前矩阵设置为单位矩阵。//为什么两次???
     gluLookAt(0, 1, -2, 0, 0, 0, 0, 0, 1);// 改变观察点的位置,前三个参数表示了观察点的位置,中间三个参数表示了观察目标的位置,最后三个参数代表从(0,0,0)到 (x,y,z)的直线,它表示了观察者认为的"上"方向。

//   glRotatef(angle, 0, 1, 0);//向右旋转//绕着这个向量顺时针转动
//  glRotatef(angle, -1, 0, 0);//向上转
/****************************动画旋转方向*******************************<XXXXXXXXXXXXXXXXXXXXXX---------XXXXXXXXXXXXXXXXXXXXXXX*/
//对应关系:zz+1->Dyy1左转  xx+1->Dxx-1上转 yy+1->Dzz+1自右旋

//仰角
    {
  tx=to_degree(xx); // printf("x=%4d",xx);printf("tx=%4d\n",tx);
  if(anglex<tx)anglex+=1;//-90~90
  else if(anglex>tx)anglex-=1;
  else anglex=tx;
 }
//  printf("水平偏移=%f , 仰角=%f\n",angle*Dyy,anglex);
  glRotatef(angle, 0,Dyy, 0);//先进行水平旋转
     glRotatef(anglex,-1,0 , 0);//后按照仰角旋转,使仰角处于运动后的坐标系,保证抬起的是船头
//***********显示字符串
  /*
 glColor3f(1.0f, 0.0f, 0.0f);
 glRasterPos2f(-0.5f, 0.5f);
 drawString("x=");
 if(anglex<0)drawString("-");
 else drawString("+");
 findString((int)anglex%1000/100);findString((int)anglex%100/10);findString((int)anglex%10);

 glColor3f(0.0f, 1.0f, 0.0f);
 glRasterPos2f(0.0f, 0.5f);
 drawString("y=");
 if(angle<0)drawString("-");
 else drawString("+");
 findString((int)angle%1000/100);findString((int)angle%100/10);findString((int)angle%10);
*/
     glCallList(list);
     glPopMatrix();//退出
     glutSwapBuffers();
}

/**********OPENGL的Y轴运动角度调整(陀螺仪的Z轴)************/
int not_turn_much(int turnc)
{
if((turnc>0)&&(turnc<=18))return turnc=10;
else if((turnc>18)&&(turnc<=50))return turnc=16;
else if((turnc>50)&&(turnc<=80))return turnc=29;
else if((turnc>80)&&(turnc<=200))return turnc=68;
else if((turnc>200)&&(turnc<=900))return turnc=100;
else if((turnc>900))return turnc=200;//人手没这么快,当然也为了以防万一出现乱码,还是要写上
else if((turnc<=-10)&&(turnc>=-30))return turnc=-17;//
else if((turnc<-30)&&(turnc>=-50))return turnc=-22;
else if((turnc<-50)&&(turnc>=-80))return turnc=-32;
else if((turnc<-80)&&(turnc>=-200))return turnc=-69;
else if((turnc<-200)&&(turnc>=-900))return turnc=-100;
else if((turnc<-900))return turnc=-200;//人手没这么快
}
/**********运动角度(速度)************/
void myIdle(void)//★注意★0度是一个确定的位置,就是起始位置
{
 ReceiveChar();
 int tz;
 //水平旋转
 if(zz>10||zz<-10)//舍弃抖动值
 {
  tz=not_turn_much(zz);//调整ZZ的值,使变化角度更合理
  tempab=(tz+tempb);//计算偏移变化角//左转正//右转负
/*
  if(tempab<0){limitz=-tempab/36;Dyy=-1;}//确定旋转角度和方向
  else {limitz=tempab/36;Dyy=1;}
*/      limitz=tempab/36;Dyy=1; 
  tempb=tempab;//用完刷新tempb
  angle=limitz;//

 }

 /******执行动画*******/
  myDisplay();
  

}

/************************主函数***************************/
int main(int argc, char* argv[])
{
 initgetter();//初始化串口

/* for(;;)ReceiveChar(); //需要死循环来不断读取,放在myDisplay里即可    
 */ 
 glutInit(&argc, argv);//动画初始化

 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);//双缓冲

 glutInitWindowPosition(200, 200);

 glutInitWindowSize(WIDTH, HEIGHT);

 glutCreateWindow("运动的四面体");

 glutDisplayFunc(&myDisplay);//形体准备

 glutIdleFunc(&myIdle);//旋转模型 
 
 glutMainLoop();//开始 运行动画

 

}

 

 

原创粉丝点击