]> git.tdb.fi Git - netvis.git/blob - source/history.cpp
Support IPv6
[netvis.git] / source / history.cpp
1 /* $Id$
2
3 This file is part of NetVis
4 Copyright @ 2008 Mikko Rasa, Mikkosoft Productions
5 Distributed unter the GPL
6 */
7
8 #include <msp/gl/extension.h>
9 #include <msp/gl/immediate.h>
10 #include <msp/gl/matrix.h>
11 #include <msp/gl/meshbuilder.h>
12 #include <msp/gl/misc.h>
13 #include <msp/strings/format.h>
14 #include <msp/time/units.h>
15 #include "history.h"
16 #include "netvis.h"
17
18 using namespace std;
19 using namespace Msp;
20
21 History::History(NetVis &n, unsigned w, unsigned h):
22         netvis(n),
23         width(w),
24         height(h),
25         buffer(w),
26         scale(1024),
27         mesh((GL::COLOR4_UBYTE, GL::TEXCOORD2, GL::VERTEX2))
28 {
29         unsigned texw = height;
30         unsigned texh = width;
31         if(!GL::is_supported("ARB_texture_non_power_of_two"))
32         {
33                 for(texw=1; texw<height; texw<<=1) ;
34                 for(texh=1; texh<width; texh<<=1) ;
35         }
36         texture.storage(GL::RGBA, texw, texh);
37         texture.image(0, GL::RGBA, GL::UNSIGNED_BYTE, 0);
38         texture.set_min_filter(GL::LINEAR);
39         float wf = static_cast<float>(height)/texw;
40         float hf = static_cast<float>(width)/texh;
41         GL::MeshBuilder bld(mesh);
42         bld.color(1.0f, 1.0f, 1.0f);
43         bld.begin(GL::QUADS);
44         bld.texcoord(0, hf);
45         bld.vertex(0, 0);
46         bld.texcoord(0, 0);
47         bld.vertex(width, 0);
48         bld.texcoord(wf, 0);
49         bld.vertex(width, height);
50         bld.texcoord(wf, hf);
51         bld.vertex(0, height);
52         bld.end();
53 }
54
55 void History::activity(unsigned down, unsigned up)
56 {
57         accum.down += down;
58         accum.up += up;
59 }
60
61 void History::tick(const Time::TimeStamp &t)
62 {
63         if(t>next_push)
64         {
65                 buffer.push(accum);
66                 accum = Bandwidth();
67                 next_push += Time::sec;
68                 if(next_push<t)
69                         next_push = t+Time::sec;
70
71                 unsigned m = 0;
72                 for(unsigned i=0; i<width; ++i)
73                 {
74                         const Bandwidth &bw = buffer.get(i);
75                         m = max(m, max(bw.down, bw.up));
76                 }
77                 scale = 1;
78                 while(m>=scale*1000)
79                         scale *= 1024;
80                 while(m>=scale*5)
81                         scale *= 10;
82                 if(m>scale*2)
83                         scale *= 5;
84                 else if(m>scale)
85                         scale *= 2;
86
87                 create_texture();
88         }
89 }
90
91 void History::render() const
92 {
93         texture.bind();
94         mesh.draw();
95
96         char suffix = 'B';
97         unsigned value = scale;
98         if(value>=1024)
99         {
100                 value /= 1024;
101                 suffix = 'k';
102         }
103         if(value>=1024)
104         {
105                 value /= 1024;
106                 suffix = 'M';
107         }
108         GL::MatrixStack::Push push_(GL::MatrixStack::modelview());
109         GL::MatrixStack::modelview() *= GL::Matrix::translation(width+5, height-10, 0);
110         GL::MatrixStack::modelview() *= GL::Matrix::scaling(10);
111         netvis.get_font().draw_string(format("%d%c", value, suffix));
112         GL::MatrixStack::modelview() *= GL::Matrix::translation(0, (height-12)*-0.05, 0);
113         netvis.get_font().draw_string(format("%g%c", value*0.5, suffix));
114         GL::MatrixStack::modelview() *= GL::Matrix::translation(0, (height-12)*-0.05, 0);
115         netvis.get_font().draw_string(format("0%c", suffix));
116         GL::Texture::unbind();
117 }
118
119 void History::create_texture()
120 {
121         vector<unsigned> data(width*height);
122         for(unsigned y=0; y<width; ++y)
123         {
124                 const Bandwidth &bw = buffer.get(y);
125                 unsigned down = bw.down*height/scale;
126                 unsigned up = bw.up*height/scale;
127                 unsigned up_min = up;
128                 unsigned up_max = up;
129                 if(y>0)
130                 {
131                         unsigned value = (up+buffer.get(y-1).up*height/scale)/2;
132                         up_min = min(value+1, up_min);
133                         up_max = max(value, up_max);
134                 }
135                 if(y<width-1)
136                 {
137                         unsigned value = (up+buffer.get(y+1).up*height/scale)/2;
138                         up_min = min(value+1, up_min);
139                         up_max = max(value, up_max);
140                 }
141                 unsigned *row = &data[y*height];
142                 for(unsigned x=0; x<height; ++x)
143                 {
144                         if(x>=up_min && x<=up_max)
145                                 row[x] = 0xFF8000FF;
146                         else if(x<=down)
147                                 row[x] = 0xFF80FF80;
148                         else if((x*4+4)%height==0 || y%60==0)
149                                 row[x] = 0x40FFFFFF;
150                         else
151                                 row[x] = 0x00000000;
152                 }
153         }
154         texture.sub_image(0, 0, 0, height, width, GL::RGBA, GL::UNSIGNED_BYTE, data.data());
155 }
156
157
158 History::Bandwidth::Bandwidth():
159         down(0),
160         up(0)
161 { }