如何在MVS中使用OpenGL绘制实时2D图形

How to draw real time 2D graph using OpenGL in MVS

本文关键字:绘制 OpenGL 实时 2D 图形 MVS      更新时间:2023-10-16

我正在编写一个代码,使用comports从硬件设备接收心音并绘制接收到的信号。我使用OpenGl来绘制接收到的信号。当我收到完整的数据时,我就能绘图了。但我希望图形更新与数据接收的更新这是我的代码:

    int num_samples = 100000;

long samples[100000];
DWORD        bytes_read    = 0;    // Number of bytes read from port

/* Function plotting func */
void draw( float x1, float x2, float y1, float y2, int N)
{
    float x, dx = 1.0/N; 
glPushMatrix(); /* GL_MODELVIEW is default */
glScalef(1.0 / (x2 - x1), 1.0 / (y2 - y1), 1.0);
glTranslatef(-x1, -y1, 0.0);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP); 
int k =0;
for(x = 0; x < num_samples; x += dx)
{
    glVertex2f(x, samples[k]);
    k=k+1;
}
glEnd();
glPopMatrix();
glFlush();
};
/* Redrawing func */
void redraw(void)
{
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    //long buf = getBuffer(samples);
    draw(0, num_samples,-693554432, 693554432, 1);
    //  draw(func, 0, 1000,0, 5000, 1);
    glutSwapBuffers();
    //glFlush();
};
/* Idle proc. Redisplays, if called. */
void idle(void)
{
    glutPostRedisplay();
};
/* Key press processing */
void key(unsigned char c, int x, int y)
{
    if(c == 27) exit(0);
};
/* Window reashape */
void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, 1, 0, 1, -1, 1);
    glMatrixMode(GL_MODELVIEW);
};
/*
long putBuffer(long[] buffer)
{
    return buffer;
}*/
 //Main function 
int j =0;
unsigned long size = 400000;
int main(int argc, char* argv[])
{
    unsigned char INBUFFER[400000];
    char OUTBUFFER[20];
    DWORD        bytes_read    = 0;    // Number of bytes read from port
    DWORD        bytes_written = 0;    // Number of bytes written to the port
    HANDLE       comport      = NULL;  // Handle COM port
 int   bStatus;
    DCB          comSettings;          // Contains various port settings
    COMMTIMEOUTS CommTimeouts;
    strcpy(&OUTBUFFER[0], "The quick brown fox jumped over the lazy dog. nr");
    // Open COM port
    if ((comport = 
         CreateFile("\\.\COM44",                // open com5:
                    GENERIC_READ | GENERIC_WRITE, // for reading and writing
                    0,                            // exclusive access
                    NULL,                         // no security attributes
                    OPEN_EXISTING,              
                    FILE_ATTRIBUTE_NORMAL,
                    NULL)) == INVALID_HANDLE_VALUE)
    {
       // cout<<"Port can't be opened"<<endl;
    }
    // Set timeouts in milliseconds
//  cout<<"Port opened"<<endl;
    //DCB dcb;
    CommTimeouts.ReadIntervalTimeout         = 0; 
    CommTimeouts.ReadTotalTimeoutMultiplier  = 0; 
    CommTimeouts.ReadTotalTimeoutConstant    = 100;
    CommTimeouts.WriteTotalTimeoutMultiplier = 0;
    CommTimeouts.WriteTotalTimeoutConstant   = 100;
    bStatus = SetCommTimeouts(comport,&CommTimeouts);
    if (bStatus != 0)
    {
        // error processing code goes here
    }
    // Set Port parameters.
    // Make a call to GetCommState() first in order to fill
    // the comSettings structure with all the necessary values.
    // Then change the ones you want and call SetCommState().
    GetCommState(comport, &comSettings);
   // memset(&dcb,0,sizeof(dcb));
    comSettings.fBinary = 1;
    comSettings.fDtrControl = DTR_CONTROL_ENABLE;
    comSettings.fRtsControl = RTS_CONTROL_ENABLE;
    comSettings.fOutxCtsFlow = 1;
    comSettings.fRtsControl = DTR_CONTROL_HANDSHAKE;

    comSettings.BaudRate = 921600;
    comSettings.StopBits = ONESTOPBIT;
    comSettings.ByteSize = 8;
    comSettings.Parity   = NOPARITY;
    comSettings.fParity  = FALSE;
    bStatus = SetCommState(comport, &comSettings);
    ofstream outdata;
     outdata.open("hsm.txt"); // opens the file
   if( !outdata ) { // file couldn't be opened
      cerr << "Error: file could not be opened" << endl;
      exit(1);
   }
    if (bStatus == 0)
    {
        // error processing code goes here
    }
    int flag = 1;
    int fl =1;
    glutInit(&argc, argv);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(500,200);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);

    //glutMainLoop();
  while(flag<120)
   {
        bStatus = ReadFile(comport,   // Handle
                &INBUFFER,            // Incoming data
                size,                  // Number of bytes to read
                &bytes_read,          // Number of bytes read
                NULL);
        if (bStatus != 0)
        {
            //cout<<"Error receiving"<<endl;
        }
//  long samples[100000];
 for (int i=0; i<bytes_read; i++)
 {
    if((unsigned char)INBUFFER[i]==0x99&&(unsigned char)INBUFFER[i+4]==0x99)
    {
    samples[j] = 0x00|(unsigned char)INBUFFER[i+1]<<8|(unsigned char)INBUFFER[i+2]<<16|(unsigned char)INBUFFER[i+3]<<24;
    if(samples[j]!=0)
         {
          outdata << samples[j] <<"n";
          j++;
         }      
    }

 } 
    flag++;
    glutCreateWindow("Graph plotter");
    glutDisplayFunc(redraw);
    glutReshapeFunc(reshape);
    glutIdleFunc(idle);
    glutMainLoop();
  }
  CloseHandle(comport);
outdata.close();

 return 0;
}

基本上,当样本缓冲区更新时,图也应该更新。但是图是在第一次迭代中绘制的,然后什么都没有发生。谁能告诉我怎么修理它?

当你调用glutMainLoop时,它会绘制屏幕,处理窗口事件,并反复调用空闲函数。由于您的所有空闲函数现在都要求重新绘制屏幕,因此它不会从您的输入串行端口读取额外的示例。

当调用idle函数时,您应该尝试从串行端口读取并填充其他示例。