112 #if defined(MULTIPLOT_FLTK) || defined(MULTIPLOT_WIN32) 115 #define MULTIPLOT_FLTK 117 #define MULTIPLOT_WIN32 135 #ifdef MULTIPLOT_FLTK // tell multiplot to use Fltk to create an Opengl-Window 138 #include <FL/Fl_Gl_Window.H> 139 #include <FL/fl_draw.H> 144 #if defined(_WIN32) && !defined(APIENTRY) 145 #define WIN32_LEAN_AND_MEAN 1 149 #ifndef MULTIPLOT_FLTK // don't include default gl.h, if using fltk, because fltk comes with its own gl.h 179 #ifdef MULTIPLOT_FLTK 181 class Multiplot_base :
public Fl_Gl_Window
184 unsigned int width = 0;
185 unsigned int height = 0;
192 Multiplot_base(
int x,
int y,
int w,
int h,
const std::wstring& title_,
bool fullscreen_) : Fl_Gl_Window(x,y,w,h)
204 return (
bool)Fl::check();
215 Fl_Gl_Window::draw();
220 void set_caption(
const std::string& t)
223 this->label(caption.c_str());
225 void set_caption(
const std::wstring& t)
228 using convert_type = std::codecvt_utf8<wchar_t>;
229 caption = std::wstring_convert<convert_type, wchar_t>().to_bytes(t);
230 this->label(caption.c_str());
236 #ifdef MULTIPLOT_WIN32 239 #pragma message(" _Adding library: opengl32.lib" ) 240 #pragma comment ( lib, "opengl32.lib") 262 static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
267 if(uMsg == WM_CREATE)
269 pParent = (
Multiplot_base*)((LPCREATESTRUCT)lParam)->lpCreateParams;
270 SetWindowLongPtr(hWnd, GWLP_USERDATA,(LONG_PTR)pParent);
275 if(!pParent)
return DefWindowProc(hWnd,uMsg,wParam,lParam);
278 pParent->hWnd = hWnd;
279 return pParent->WndProc(uMsg,wParam,lParam);
309 case SC_MONITORPOWER:
335 width = LOWORD(lParam);
336 height = HIWORD(lParam);
343 return DefWindowProc(hWnd,uMsg,wParam,lParam);
355 bool CreateGLWindow(
int x,
int y,
int width,
int height,
const std::wstring& title, BYTE bits=0,
bool fullscreenflag=
false)
362 WindowRect.left=(long)0;
363 WindowRect.right=(long)width;
364 WindowRect.top=(long)0;
365 WindowRect.bottom=(long)height;
367 fullscreen=fullscreenflag;
369 hInstance = GetModuleHandle(NULL);
370 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
371 wc.lpfnWndProc = (WNDPROC) (Multiplot_base::StaticWndProc);
374 wc.hInstance = hInstance;
375 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
376 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
377 wc.hbrBackground = NULL;
378 wc.lpszMenuName = NULL;
379 wc.lpszClassName = L
"OpenGL";
382 if (!RegisterClass(&wc))
384 throw(std::exception(
"Failed To Register The Window Class."));
389 DEVMODE dmScreenSettings;
390 memset(&dmScreenSettings,0,
sizeof(dmScreenSettings));
391 dmScreenSettings.dmSize=
sizeof(dmScreenSettings);
392 dmScreenSettings.dmPelsWidth = width;
393 dmScreenSettings.dmPelsHeight = height;
394 dmScreenSettings.dmBitsPerPel = bits;
395 dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
398 if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
401 std::cerr <<
"The Requested Fullscreen Mode is not supported by your Video Card. Using Windowed Mode instead." << std::endl;
408 dwExStyle=WS_EX_APPWINDOW;
414 dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
415 dwStyle=WS_OVERLAPPEDWINDOW;
418 AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);
421 if (!(hWnd=CreateWindowEx( dwExStyle,
428 WindowRect.right-WindowRect.left,
429 WindowRect.bottom-WindowRect.top,
436 throw(std::exception(
"Window Creation Error."));
439 static PIXELFORMATDESCRIPTOR pfd=
441 sizeof(PIXELFORMATDESCRIPTOR),
461 if (!(hDC=GetDC(hWnd)))
464 throw(std::exception(
"Can't Create A GL Device Context."));
467 if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))
470 throw(std::exception(
"Can't Find A Suitable PixelFormat."));
473 if(!SetPixelFormat(hDC,PixelFormat,&pfd))
476 throw(std::exception(
"Can't Set The PixelFormat."));
479 if (!(hRC=wglCreateContext(hDC)))
481 throw(std::exception(
"Can't Create A GL Rendering Context."));
484 if(!wglMakeCurrent(hDC,hRC))
486 throw(std::exception(
"Can't Activate The GL Rendering Context."));
489 ShowWindow(hWnd,SW_SHOW);
490 SetForegroundWindow(hWnd);
504 void DestroyGLWindow()
509 ChangeDisplaySettings(NULL,0);
515 if (!wglMakeCurrent(NULL,NULL))
517 throw(std::exception(
"Release Of DC And RC Failed."));
520 if (!wglDeleteContext(hRC))
522 throw(std::exception(
"Release Rendering Context Failed."));
527 if (hDC && !ReleaseDC(hWnd,hDC))
529 throw(std::exception(
"Release Device Context Failed."));
533 if (hWnd && !DestroyWindow(hWnd))
535 throw(std::exception(
"Could Not Release hWnd."));
539 if (!UnregisterClass(L
"OpenGL",hInstance))
541 throw(std::exception(
"Could Not Unregister Class."));
546 static LRESULT CALLBACK window_handler( HWND hWnd,
572 case SC_MONITORPOWER:
599 int xx = LOWORD(lParam);
610 return DefWindowProc(hWnd,uMsg,wParam,lParam);
622 Multiplot_base(
int x,
int y,
int w,
int h,
const std::wstring& ttitle,
bool fullscreen)
625 CreateGLWindow(x, y, w, h, ttitle, 32, fullscreen);
641 if(GetAsyncKeyState(VK_ESCAPE) & 0x8000)
645 if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
647 TranslateMessage(&msg);
648 DispatchMessage(&msg);
656 unsigned int w() {
return width; }
657 unsigned int h() {
return height; }
658 bool valid() {
return valid_; }
659 void valid(
bool v) { valid_=v; }
665 void set_caption(
const std::wstring& t)
698 float point_size = 0.0f;
699 float line_width = 1.0f;
702 Point2d(
float xx,
float yy,
float rr=1,
float gg=1,
float bb=1,
float _lwidth=1.0,
float _point_size=0.0)
706 point_size=_point_size;
721 class Trace :
public std::vector<Point2d>
724 unsigned int max_points;
728 float cur_line_width;
729 float cur_point_size;
739 float line_width=at(start%size()).line_width;
740 glLineWidth(line_width);
742 for(
unsigned int a=start;a<start+size()-1;a++)
746 p1=(*this)[a % size()];
747 p2=(*this)[(a+1) % size()];
757 if(p1.line_width != line_width)
760 line_width = p1.line_width;
761 glLineWidth(line_width);
764 glColor3f(p1.r,p1.g,p1.b);
765 glVertex2f((p1.x-offset.x)*scale.x,(p1.y-offset.y)*scale.y);
766 glColor3f(p2.r,p2.g,p2.b);
767 glVertex2f((p2.x-offset.x)*scale.x,(p2.y-offset.y)*scale.y);
769 if(p1.x>maximum.x)maximum.x=p1.x;
770 if(p1.x<minimum.x)minimum.x=p1.x;
771 if(p1.y>maximum.y)maximum.y=p1.y;
772 if(p1.y<minimum.y)minimum.y=p1.y;
775 if(p2.x>maximum.x)maximum.x=p2.x;
776 if(p2.x<minimum.x)minimum.x=p2.x;
777 if(p2.y>maximum.y)maximum.y=p2.y;
778 if(p2.y<minimum.y)minimum.y=p2.y;
781 float point_size=at(start%size()).line_width;
782 glPointSize(point_size);
784 for(
unsigned int a=start;a<start+size();a++)
790 if(p.point_size != point_size)
793 point_size = p.point_size;
794 glPointSize(point_size);
797 glColor3f(p.r,p.g,p.b);
798 glVertex2f((p.x-offset.x)*scale.x,(p.y-offset.y)*scale.y);
854 cur_col[0]=cur_col[1]=cur_col[2]=1.0;
866 void plot(
const float x,
const float y)
869 Point2d p(x,y, cur_col[0], cur_col[1], cur_col[2], cur_line_width, cur_point_size);
929 if(max_points_to_plot<=0)
936 max_points=max_points_to_plot;
947 void clear() { std::vector<Point2d>::clear(); pos=0; }
954 Multiplot(
const int x,
const int y,
const int w,
const int h,
const std::wstring& ttitle=L
"Multiplot - updates on www.andre-krause.net",
bool fullscreen=
false) :
Multiplot_base(x,y,w,h,ttitle,fullscreen)
962 scaling_ = MP_AUTO_SCALE;
963 maximum.x=maximum.y=-FLT_MAX;
964 minimum.x=minimum.y=FLT_MAX;
965 Point2d range_min, range_max;
967 traces.push_back( Trace() );
1002 if (cur_trace < 0) { cur_trace = 0; }
1003 if(traces.size() <= cur_trace )
1005 for(
size_t a = 0; a < cur_trace - traces.size() + 1; a++)
1006 traces.push_back(
Trace());
1008 return traces[_trace];
1015 void plot(
const float x,
const float y) { traces[cur_trace].plot(x,y); }
1022 template<
class T>
void plot(
const std::vector<T>& v)
1024 for(
size_t x=0;x<v.size();x++)
1026 traces[cur_trace].plot(
float(x),
float(v[x]));
1033 void color3f(
float r,
float g,
float b) { traces[cur_trace].color3f(r,g,b); }
1051 void set_scrolling(
int max_points_to_plot){ traces[cur_trace].set_scrolling(max_points_to_plot); }
1059 void set_scaling(
enum MP_SCALING sc,
float x_min=-10,
float x_max= 10,
float y_min=-10,
float y_max=10)
1062 range_min.x = x_min;
1063 range_min.y = y_min;
1064 range_max.x = x_max;
1065 range_max.y = y_max;
1077 void set_grid(
enum MP_GRIDSTYLE ggridx=MP_LINEAR_GRID,
enum MP_GRIDSTYLE ggridy=MP_LINEAR_GRID,
float ggridx_step=-1.0,
float ggridy_step=-1.0,
float w=1.0)
1081 gridx_step=ggridx_step;
1082 gridy_step=ggridy_step;
1094 glClearColor(bg_color.r, bg_color.g, bg_color.b, 1);
1114 for(
unsigned int a=0;a<traces.size();a++)
1124 float cur_point_size;
1125 unsigned int cur_trace;
1132 Point2d range_min, range_max;
1133 Point2d minimum, maximum;
1138 std::vector< Trace > traces;
1143 float gridx_step, gridy_step, grid_linewidth;
1144 Point2d grid_spacing;
1148 glViewport(0 , 0,width ,height);
1149 glMatrixMode(GL_PROJECTION);
1151 glOrtho( 0, width, 0, height, -1, 1 );
1153 glMatrixMode(GL_MODELVIEW);
1155 glDisable(GL_DEPTH_TEST);
1156 glDisable(GL_LIGHTING);
1157 glShadeModel(GL_SMOOTH);
1158 glClearColor(bg_color.r, bg_color.g, bg_color.b, 1);
1159 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1166 if(gridx==MP_LINEAR_GRID)
1168 double diff=maximum.x - minimum.x;
1169 if(diff==0)
return Point2d(0,0);
1170 double exp=floor(log10(fabs(diff)));
1171 double shiftscale=pow(10.0,exp);
1173 double startx=shiftscale*floor(minimum.x / shiftscale);
1181 xstep=shiftscale*1.0;
1194 glLineWidth(grid_linewidth);
1195 glColor3f(grid_color.r, grid_color.g, grid_color.b);
1198 while(x<maximum.x && bailout<100)
1202 glVertex2f((GLfloat)(x-offset.x)*scale.x ,0.0f );
1203 glVertex2f((GLfloat)(x-offset.x)*scale.x ,(
float)height);
1207 if(gridy==MP_LINEAR_GRID)
1209 double diff=maximum.y - minimum.y;
1210 if(diff==0)
return Point2d(0,0);
1211 double exp=floor(log10(fabs(diff)));
1212 double shiftscale=pow(10.0,exp);
1214 double starty=shiftscale*floor(minimum.y / shiftscale);
1222 ystep=shiftscale*1.0;
1235 glColor3f(grid_color.r, grid_color.g, grid_color.b);
1238 while(y<maximum.y && bailout<100)
1242 glVertex2f(0.0f ,(GLfloat)(y-offset.y)*scale.y);
1243 glVertex2f((
float)width ,(GLfloat)(y-offset.y)*scale.y);
1247 #ifdef MULTIPLOT_FLTK // gl_font is only available with fltk... 1260 while(y<maximum.y && bailout<100)
1264 s = std::to_string(y);
1265 glRasterPos2f(0.5f, (GLfloat)(y-offset.y)*scale.y + 1 );
1266 gl_draw(s.c_str(), int(s.length()));
1272 return Point2d((
float)xstep,(
float)ystep);
1285 Multiplot_base::draw();
1287 glClear(GL_COLOR_BUFFER_BIT);
1291 grid_spacing=draw_grid();
1294 glLineWidth(2.0f*grid_linewidth);
1295 glColor3f(grid_color.r, grid_color.g, grid_color.b);
1297 glVertex2f(0.0f ,0-offset.y*scale.y);
1298 glVertex2f((
float)width ,0-offset.y*scale.y);
1299 glVertex2f(0-offset.x*scale.x ,0.0f );
1300 glVertex2f(0-offset.x*scale.x ,(
float)height);
1305 maximum.x=maximum.y=-FLT_MAX;
1306 minimum.x=minimum.y=FLT_MAX;
1308 for(
unsigned int t=0;t<traces.size();t++)
1310 traces[t].draw(minimum, maximum, scale, offset);
1318 float diff_x = maximum.x-minimum.x;
1319 float diff_y = maximum.y-minimum.y;
1323 if(diff_x!=0.0)scale.x=width/diff_x;
1324 if(diff_y!=0.0)scale.y=height/diff_y;
1326 case MP_AUTO_SCALE_EQUAL:
1327 if(max(diff_x, diff_y) != 0)
1329 scale.x=scale.y=min(width, height) / max(diff_x, diff_y);
1333 case MP_FIXED_SCALE:
1334 scale.x = width /(range_max.x - range_min.x);
1335 scale.y = height/(range_max.y - range_min.y);
1336 offset.x = range_min.x;
1337 offset.y = range_min.y;
1343 std::wstringstream ss;
1344 ss <<
"x=[" << minimum.x <<
"; " << maximum.x <<
"] ";
1345 ss <<
"y=[" << minimum.y <<
"; " << maximum.y <<
"] ";
1346 if(gridx != MP_NO_GRID || gridy != MP_NO_GRID)
1348 ss <<
"dx=[" << grid_spacing.x <<
"] ";
1349 ss <<
"dy=[" << grid_spacing.y <<
"] ";
1351 set_caption( (ss.str() + title).c_str() );
1359 #ifdef __TEST_THIS_MODULE__ 1367 using namespace std;
1368 using namespace multiplot;
1376 #ifdef MULTIPLOT_FLTK 1378 #pragma comment(lib, "fltk14/bin/lib/Debug/fltkd.lib") 1379 #pragma comment(lib, "fltk14/bin/lib/Debug/fltk_gld.lib") 1382 #pragma comment(lib, "fltk14/bin/lib/Release/fltk.lib") 1383 #pragma comment(lib, "fltk14/bin/lib/Release/fltk_gl.lib") 1388 #pragma comment(lib, "wsock32.lib") 1389 #pragma comment(lib, "comctl32.lib") 1390 #pragma comment(lib, "glu32.lib") 1391 #pragma comment(lib, "opengl32.lib") 1392 #pragma comment(lib, "Ws2_32.lib") 1393 #pragma comment(lib, "User32.lib") 1406 using namespace multiplot;
1417 for(
int x=0;x<300;x++)
1420 m.plot(
float(x), 0.1f*x*sin(0.1f*x));
1425 if (!m.check()) {
break; }
1445 m.set_grid(MP_LINEAR_GRID,MP_LINEAR_GRID);
1448 m.set_bg_color(0,0,0.5);
1451 m[0].set_scrolling(100);
1452 m[1].set_scrolling(100);
1457 for(
int x=0;x<300;x++)
1462 m.plot(
float(x), 0.1f*x*sin(x/5.0f));
1466 m.plot(
float(x), 0.1f*x*sin(x/6.0f));
1470 if (!m.check()) {
break; }
1486 m.set_grid(MP_LINEAR_GRID, MP_LOG_GRID);
1488 m.set_scrolling(100);
1495 for(
int x=0;x<1000;x++)
1499 m[0].set_pointsize(4.0f + (x%10));
1500 m[0].color3f(1, 0.01f*(x%100), 0.05f*(x%20) );
1501 m[0].plot(0.1f*x*cos(x/5.0f), 0.1f*x*sin(x/5.0f));
1503 m[1].color3f(0.1f*(x%10), 0.05f*(x%20), 0.01f*(x%100) );
1504 m[1].plot(0.1f*x*cos(x/20.0f), 0.1f*x*sin(x/5.0f));
1507 if (!m.check()) {
break; }
1522 m.set_linewidth(0.0);
1524 for(
int x=0;x<3000;x++)
1526 m.color3f(1, 0.01f*(x%100), 0.05f*(x%20) );
1530 for(
int b=0;b<10;b++)
1533 float rx = -5 + 10.0f*rand()/RAND_MAX;
1534 float ry = -5 + 10.0f*rand()/RAND_MAX;
1536 float gval = exp(-(rx*rx + ry*ry));
1537 if(1.0*rand()/RAND_MAX < gval)
1539 m.set_pointsize(1 + 5*gval);
1545 if (!m.check()) {
break; }
1560 for(
int x=0;x<1000;x++)
1562 m.plot(
float(x), 0.1f*x*sin(0.1f*x));
1564 if (!m.check()) {
break; }
1575 vector<float> v1,v2;
1576 for(
int a=0;a<100;a++)
1578 v1.push_back( sin(0.3f*a) );
1579 v2.push_back( cos(0.3f*a)+2.5f );
1595 m.set_scaling(MP_FIXED_SCALE, 0, 300, -20, 20);
1598 for (
int x = 0; x < 300; x++)
1600 m.plot(
float(x), 0.1f*x*sin(0.1f*x));
1602 if (!m.check()) {
break; }
1604 while (m.check()) { m.redraw(); }
1609 #include <FL/Fl_Gl_Window.H> 1610 #include <FL/Fl_Button.H> 1628 std::cout <<
"Several multiplot demos. press ESC inside the multiplot window to stop a demo and test the next demo." << std::endl << std::endl;
1630 int demo_number = 0;
1632 std::cout <<
"\n(1) demo: most basic/ simple usage. plots a sine wave.";
1633 std::cout <<
"\n(2) demo: two traces in a multiplot window with colors and scrolling.";
1634 std::cout <<
"\n(3) demo: more settings (point size, line-width and grid).";
1635 std::cout <<
"\n(4) demo: how to do a scatter plot (random gauss distribution).";
1636 std::cout <<
"\n(5) demo: fullscreen (win32 only at the moment)";
1637 std::cout <<
"\n(6) demo: plot values in a std::vector<float>";
1638 std::cout <<
"\n(7) demo: no auto-scaling, set fixed scaling of both x and y axis.";
1639 std::cout <<
"\n(8) exit.";
1640 std::cout <<
"\nenter number of demo (1..6):";
1641 std::cin >> demo_number;
1642 switch (demo_number)
1644 case 1:demo1();
break;
1645 case 2:demo2();
break;
1646 case 3:demo3();
break;
1647 case 4:demo4();
break;
1648 case 5:demo5();
break;
1649 case 6:demo6();
break;
1650 case 7:demo7();
break;
1651 case 8:
return;
break;
1652 default:demo1();
break;
void plot(const std::vector< T > &v)
Definition: multiplot.h:1022
void clear_all()
Definition: multiplot.h:1112
void set_max_points(int mx)
Definition: multiplot.h:920
void set_scaling(enum MP_SCALING sc, float x_min=-10, float x_max=10, float y_min=-10, float y_max=10)
Definition: multiplot.h:1059
void plot(const float x, const float y)
Definition: multiplot.h:1015
Multiplot_base(int x, int y, int w, int h, const std::wstring &ttitle, bool fullscreen)
Definition: multiplot.h:622
Definition: multiplot.h:687
void plot(const float x, const float y)
Definition: multiplot.h:866
void color3f(float r, float g, float b)
Definition: multiplot.h:1033
Definition: multiplot.h:690
void clear()
Definition: multiplot.h:947
void set_pointsize(float psize)
Definition: multiplot.h:1047
void set_linewidth(float width)
Definition: multiplot.h:1043
void set_grid_color(float r, float g, float b)
Definition: multiplot.h:1101
void set_scrolling(int max_points_to_plot)
Definition: multiplot.h:927
Trace & operator[](int _trace)
Definition: multiplot.h:989
Trace & trace(int _trace)
Definition: multiplot.h:999
void color3f(float r, float g, float b)
Definition: multiplot.h:893
void clear(int trace)
Definition: multiplot.h:1122
void set_grid(enum MP_GRIDSTYLE ggridx=MP_LINEAR_GRID, enum MP_GRIDSTYLE ggridy=MP_LINEAR_GRID, float ggridx_step=-1.0, float ggridy_step=-1.0, float w=1.0)
Definition: multiplot.h:1077
void set_bg_color(float r, float g, float b)
Definition: multiplot.h:1089
void set_pointsize(float psize)
Definition: multiplot.h:912
void set_title(const std::wstring &title_)
Definition: multiplot.h:1038
Definition: multiplot.h:247
void redraw()
Definition: multiplot.h:673
void set_linewidth(float width)
Definition: multiplot.h:905
void show()
Definition: multiplot.h:632
Trace & operator()(int _trace)
Definition: multiplot.h:993
Definition: multiplot.h:721
void set_scrolling(int max_points_to_plot)
Definition: multiplot.h:1051