gLineChart improvements, antialiasing support

This commit is contained in:
Mark Watkins 2011-06-17 01:44:24 +10:00
parent 3c807ab98e
commit e013e6dad9
3 changed files with 126 additions and 76 deletions

View File

@ -8309,7 +8309,7 @@
1308026543 D 1308026543 D
1308221530 /home/mark/projects/git/sleepyhead/src/version.h 1308238797 /home/mark/projects/git/sleepyhead/src/version.h
1308003040 ent of cb2ab33... Linux wx2.8 & wx2.9 builds fixed 1308003040 ent of cb2ab33... Linux wx2.8 & wx2.9 builds fixed
<wx/dcbuffer.h> <wx/dcbuffer.h>
@ -8362,7 +8362,7 @@
"sleeplib/profiles.h" "sleeplib/profiles.h"
"sleeplib/machine_loader.h" "sleeplib/machine_loader.h"
1308221527 source:/home/mark/projects/git/sleepyhead/src/graphs/graph.cpp 1308238538 source:/home/mark/projects/git/sleepyhead/src/graphs/graph.cpp
"freetype-gl/font-manager.h" "freetype-gl/font-manager.h"
"freetype-gl/texture-font.h" "freetype-gl/texture-font.h"
"graph.h" "graph.h"

View File

@ -565,7 +565,7 @@ void gGraphWindow::ZoomX(double mult,int origin_px)
double q=span*mult; double q=span*mult;
if (q>hardspan) q=hardspan; if (q>hardspan) q=hardspan;
if (q<hardspan/100) q=hardspan/100; if (q<hardspan/400) q=hardspan/400;
min=min+(origin-(q/2.0)); min=min+(origin-(q/2.0));
max=min+q; max=min+q;
@ -2017,6 +2017,7 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
if (m_report_empty) { if (m_report_empty) {
wxString msg=_("No Waveform Available"); wxString msg=_("No Waveform Available");
float x,y; float x,y;
//TextMarkup...
GetTextExtent(msg,x,y,bigfont); GetTextExtent(msg,x,y,bigfont);
DrawText(msg,start_px+(width/2.0)-(x/2.0),start_py+(height/2.0)-(y/2.0),0,*wxDARK_GREY,bigfont); DrawText(msg,start_px+(width/2.0)-(x/2.0),start_py+(height/2.0)-(y/2.0),0,*wxDARK_GREY,bigfont);
} }
@ -2024,58 +2025,83 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
} }
bool accel=m_accelerate; bool accel=m_accelerate;
double sfit,sam,sr; double sfit,sr;
int dp; int dp,sam;
wxColor & col=color[0]; wxColor & col=color[0];
// Selected the plot line color // Selected the plot line color
glColor4ub(col.Red(),col.Green(),col.Blue(),col.Alpha());
// Crop to inside the margins.
glScissor(w.GetLeftMargin(),w.GetBottomMargin(),width,height);
glEnable(GL_SCISSOR_TEST);
glLineWidth (.25);
//glEnable(GL_LINE_SMOOTH);
//glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
const int maxverts=65536*2; // Resolution dependant.. const int maxverts=65536*2; // Resolution dependant..
int vertcnt=0; int vertcnt=0;
static GLshort vertarray[maxverts+8]; static GLshort vertarray[maxverts+8];
//glBegin (GL_LINES); //_LOOP);
float lastpx,lastpy; float lastpx,lastpy;
float px,py; float px,py;
for (int n=0;n<data->VC();n++) { int idx,idxend,np;
dp=0; bool done,first;
int & siz=data->np[n]; double x0,x1,xL;
// Don't bother drawing 1 point or less.
if (siz<=1) continue; for (int n=0;n<data->VC();n++) { // for each segment
int siz=data->np[n];
if (siz<=1) continue; // Don't bother drawing 1 point or less.
bool done=false;
bool first=true;
wxPoint2DDouble * point=data->point[n]; wxPoint2DDouble * point=data->point[n];
sr=point[1].m_x-point[0].m_x;// Time distance between points x0=point[0].m_x;
xL=point[siz-1].m_x;
// Calculate the number of points to skip when too much data. if (maxx<x0) continue;
if (accel) { if (xL<minx) continue;
sfit=xx/sr; if (x0>xL) {
sam=sfit/width; if (siz==2) { // this happens on CPAP
if (sam<=8) { // Don't accelerate if threshold less than this. wxPoint2DDouble t=point[0];
accel=false; point[0]=point[siz-1];
sam=1; point[siz-1]=t;
x0=point[0].m_x;
} else { } else {
sam/=18; // lower this number the more data is skipped over (and the faster things run) wxLogDebug(wxT("Reversed order sample fed to gLineChart - ignored."));
if (sam<=1) { continue;
sam=1; //assert(x1<x2);
accel=false;
}
} }
}
done=false;
first=true;
dp=0;
} else sam=1; x1=point[1].m_x;
// if (accel) {
sr=x1-x0; // Time distance between samples
double qx=xL-x0; // Full time range of this segment
double gx=xx/qx; // ratio of how much of the whole data set this represents
double segwidth=width*gx;
double XR=xx/sr;
double Z1=MAX(x0,minx);
double Z2=MIN(xL,maxx);
double ZD=Z2-Z1;
double ZR=ZD/sr;
double ZQ=ZR/XR;
double ZW=ZR/(width*ZQ);
const int num_averages=15; // Number of samples taken from samples per pixel for better min/max values
if (accel && n>0) {
sam=1;
}
if (ZW<num_averages) {
sam=1;
accel=false;
} else {
sam=ZW/num_averages;
if (sam<1) {
sam=1;
accel=false;
}
}
//}
wxString a;
a << sam;
DrawText(a,3,scry-w.GetTopMargin()-10);
// Prepare the min max y values if we still are accelerating this plot // Prepare the min max y values if we still are accelerating this plot
if (accel) { if (accel) {
@ -2087,27 +2113,30 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
int minz=width,maxz=0; int minz=width,maxz=0;
// Technically shouldn't never ever get fed reverse data. // Technically shouldn't never ever get fed reverse data.
double x1=point[0].m_x;
double x2=point[siz-1].m_x;
assert(x1<x2);
if (minx>x2) continue; // don't even bother this round (segments could be out of order)
if (maxx<x1) continue;
int idx=0; // these calculations over estimate
int idxend=0; // The Z? values are much more accurate
int np=0;
idx=0;
idxend=0;
np=0;
if (m_accelerate) { if (m_accelerate) {
if (minx>x1) { if (minx>x1) {
double j=minx-x1; // == starting min of first sample in this segment double j=minx-x0; // == starting min of first sample in this segment
idx=floor(j/sr); idx=floor(j/sr);
// Loose the precision
idx-=idx % sam;
} // else just start from the beginning } // else just start from the beginning
idxend=floor(xx/sr); idxend=floor(xx/sr);
idxend/=sam; // devide by number of samples skips idxend/=sam; // devide by number of samples skips
np=(idxend-idx)+sam; np=(idxend-idx)+sam;
np /= sam; np /= sam;
} else { } else {
np=siz; np=siz;
} }
@ -2136,10 +2165,10 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
if (point[i].m_x > maxx) done=true; // Let this iteration finish.. (This point will be in far clipping) if (point[i].m_x > maxx) done=true; // Let this iteration finish.. (This point will be in far clipping)
px=1+((point[i].m_x - minx) * xmult); // Scale the time scale X to pixel scale X px=1+((point[i].m_x - minx) * xmult); // Scale the time scale X to pixel scale X
py=1+((point[i].m_y - miny) * ymult); // Same for Y scale
if (!accel) { if (!accel) {
py=1+((point[i].m_y - miny) * ymult); // Same for Y scale
if (firstpx) { if (firstpx) {
firstpx=false; firstpx=false;
} else { } else {
@ -2150,13 +2179,9 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
vertarray[vertcnt++]=lastpy; vertarray[vertcnt++]=lastpy;
vertarray[vertcnt++]=start_px+px; vertarray[vertcnt++]=start_px+px;
vertarray[vertcnt++]=lastpy; vertarray[vertcnt++]=lastpy;
//glVertex2f(lastpx,lastpy);
//glVertex2f(start_px+px,lastpy);
//glVertex2f(start_px+px,lastpy);
} else { } else {
vertarray[vertcnt++]=lastpx; vertarray[vertcnt++]=lastpx;
vertarray[vertcnt++]=lastpy; vertarray[vertcnt++]=lastpy;
//glVertex2f(lastpx,lastpy);
} }
vertarray[vertcnt++]=start_px+px; vertarray[vertcnt++]=start_px+px;
@ -2164,28 +2189,35 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
#if defined(EXTRA_ASSERTS) #if defined(EXTRA_ASSERTS)
assert(vertcnt<maxverts); assert(vertcnt<maxverts);
#endif #endif
//glVertex2f(start_px+px,start_py+py);
} }
lastpx=start_px+px; lastpx=start_px+px;
lastpy=start_py+py; lastpy=start_py+py;
} else { } else {
// Just clip ugly in accel mode.. Too darn complicated otherwise // Just clip ugly in accel mode.. Too darn complicated otherwise
if (px<0) { /* if (px<0) {
px=0; px=0;
} }
if (px>width) { if (px>width) {
px=width; px=width;
} } */
// In accel mode, each pixel has a min/max Y value. // In accel mode, each pixel has a min/max Y value.
// m_drawlist's index is the pixel index for the X pixel axis. // m_drawlist's index is the pixel index for the X pixel axis.
float zz=(maxy-miny)/2.0; // centreline
float jy=fabs(point[i].m_y);
int y1=1+(jy-miny)*ymult;
int y2=1+(-jy-miny)*ymult;
//py=1+((point[i].m_y - miny) * ymult); // Same for Y scale
int z=round(px); int z=round(px);
if (z<minz) minz=z; // minz=First pixel if (z<minz) minz=z; // minz=First pixel
if (z>maxz) maxz=z; // maxz=Last pixel if (z>maxz) maxz=z; // maxz=Last pixel
// Update the Y pixel bounds. // Update the Y pixel bounds.
if (py<m_drawlist[z].x) m_drawlist[z].x=py; if (y2<m_drawlist[z].x) m_drawlist[z].x=y2;
if (py>m_drawlist[z].y) m_drawlist[z].y=py; if (y1>m_drawlist[z].y) m_drawlist[z].y=y1;
} }
@ -2203,23 +2235,41 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
#if defined(EXTRA_ASSERTS) #if defined(EXTRA_ASSERTS)
assert(vertcnt<maxverts); assert(vertcnt<maxverts);
#endif #endif
//glVertex2f(start_px+i+1,start_py+m_drawlist[i].x);
//glVertex2f(start_px+i+1,start_py+m_drawlist[i].y);
} }
} }
wxString b;
glEnableClientState(GL_VERTEX_ARRAY); int j=vertcnt/2;
glVertexPointer(2, GL_SHORT, 0, vertarray); if (accel) j/=2;
glDrawArrays(GL_LINES, 0, vertcnt>>1); b << siz << wxT(" ") << (idx) << wxT(" ") << (siz/sam) << wxT(" ") << j;
// deactivate vertex arrays after drawing DrawText(b,scrx-190,scry-w.GetTopMargin()-14);
glDisableClientState(GL_VERTEX_ARRAY);
} }
//glEnd ();
//glDisable(GL_LINE_SMOOTH);
glDisable(GL_SCISSOR_TEST);
glColor4ub(col.Red(),col.Green(),col.Blue(),255);
// Crop to inside the margins.
//glScissor(w.GetLeftMargin(),w.GetBottomMargin(),width,height);
//glEnable(GL_SCISSOR_TEST);
glLineWidth (1);
bool antialias=pref["UseAntiAliasing"];
if (antialias) {
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_SHORT, 0, vertarray);
glDrawArrays(GL_LINES, 0, vertcnt>>1);
glDisableClientState(GL_VERTEX_ARRAY);
if (antialias) {
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
//glDisable(GL_SCISSOR_TEST);
} }
gLineOverlayBar::gLineOverlayBar(gPointData *d,const wxColor * col,wxString _label,LO_Type _lot) gLineOverlayBar::gLineOverlayBar(gPointData *d,const wxColor * col,wxString _label,LO_Type _lot)

View File

@ -4,7 +4,7 @@
namespace AutoVersion{ namespace AutoVersion{
//Date Version Types //Date Version Types
static const char _DATE[] = "16"; static const char _DATE[] = "17";
static const char _MONTH[] = "06"; static const char _MONTH[] = "06";
static const char _YEAR[] = "2011"; static const char _YEAR[] = "2011";
static const char _UBUNTU_VERSION_STYLE[] = "11.06"; static const char _UBUNTU_VERSION_STYLE[] = "11.06";
@ -16,14 +16,14 @@ namespace AutoVersion{
//Standard Version Type //Standard Version Type
static const long _MAJOR = 0; static const long _MAJOR = 0;
static const long _MINOR = 7; static const long _MINOR = 7;
static const long _BUILD = 6296; static const long _BUILD = 6388;
static const long _REVISION = 17689; static const long _REVISION = 18175;
//Miscellaneous Version Types //Miscellaneous Version Types
static const long _BUILDS_COUNT = 7222; static const long _BUILDS_COUNT = 7450;
#define _RC_FILEVERSION 0,7,6296,17689 #define _RC_FILEVERSION 0,7,6388,18175
#define _RC_FILEVERSION_STRING "0, 7, 6296, 17689\0" #define _RC_FILEVERSION_STRING "0, 7, 6388, 18175\0"
static const char _FULLVERSION_STRING[] = "0.7.6296.17689"; static const char _FULLVERSION_STRING[] = "0.7.6388.18175";
//These values are to keep track of your versioning state, don't modify them. //These values are to keep track of your versioning state, don't modify them.
static const long _BUILD_HISTORY = 0; static const long _BUILD_HISTORY = 0;