简体   繁体   English

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

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

I am writing a code that receives heart sound from a hardware device using comports and plots the signal received. 我正在编写一个使用命令从硬件设备接收心音并绘制接收到的信号的代码。 I am using OpenGl to plot the signal received. 我正在使用OpenGl绘制接收到的信号。 I am able to plot when I receive the complete data. 收到完整的数据后,我便可以绘图。 But I want the graph to update with the updating of data received Here is my code: 但是我希望图形随着接收到的数据的更新而更新。这是我的代码:

    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. \n\r\0");
    // 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;
}

Basically when the samples buffer gets updated, the graph should also update. 基本上,当样本缓冲区更新时,图形也应更新。 But the graph is plotted in first iteration and then nothing happens. 但是该图是在第一次迭代中绘制的,然后什么也没有发生。 Can anyone tell me how to fix it? 谁能告诉我如何解决?

When you call glutMainLoop, it will draw the screen, handle window events, and call the idle function repeatedly. 当您调用glutMainLoop时,它将绘制屏幕,​​处理窗口事件并重复调用空闲函数。 Since all your idle function does now is to ask for the screen to be redrawn, it will not be reading additional samples from your input serial port. 由于您现在的所有空闲功能都是要求重新绘制屏幕,​​因此它将不会从您的输入串行端口读取其他样本。

You should try reading from the serial port and populating additional samples when your idle function is called. 在调用idle函数时,您应该尝试从串行端口读取并填充其他示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM