[英]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.