#include #include #include #include #ifdef _WIN32 #include #include #endif #ifdef __APPLE_CC__ #include #define max(a,b) (a>b?a:b) #define min(a,b) (a>b?b:a) #endif #include "gutil.h" #include "reduce.h" REDUCED_ARRAY::REDUCED_ARRAY() { rdata = 0; ftemp = 0; itemp = 0; reduce_method = REDUCE_METHOD_AVG; } REDUCED_ARRAY::~REDUCED_ARRAY() { if (rdata) free(rdata); if (ftemp) free(ftemp); if (itemp) free(itemp); } // (mx, my) are maximum reduced dimensions // (typically based on window size, e.g. half of window size in pixels) // void REDUCED_ARRAY::set_max_dims(int mx, int my) { rdimx_max = mx; rdimy_max = my; rdimx = rdimx_max; rdimy = rdimy_max; } // Prepare to receive a source array. // (sx, sy) are dimensions of source array // void REDUCED_ARRAY::init(int sx, int sy) { sdimx = sx; sdimy = sy; if (sdimx > rdimx_max) { rdimx = rdimx_max; } else { rdimx = sdimx; } if (sdimy > rdimy_max) { rdimy = rdimy_max; } else { rdimy = sdimy; } rdata = (float*)realloc(rdata, rdimx*rdimy*sizeof(float)); ftemp = (float*)realloc(ftemp, rdimx*sizeof(float)); itemp = (int*)realloc(itemp, rdimx*sizeof(int)); nvalid_rows = 0; ndrawn_rows = 0; scury = 0; last_ry = 0; last_ry_count = 0; rdata_max = 0; rdata_min = (float)1e20; } bool REDUCED_ARRAY::full() { return nvalid_rows==rdimy; } void REDUCED_ARRAY::reset() { nvalid_rows = 0; ndrawn_rows = 0; scury = 0; last_ry = 0; last_ry_count = 0; } void REDUCED_ARRAY::init_draw(float* p, float* s, double h0, double dh, float trans) { memcpy(draw_pos, p, sizeof(draw_pos)); memcpy(draw_size, s, sizeof(draw_size)); draw_deltax = draw_size[0]/rdimx; draw_deltaz = draw_size[2]/rdimy; hue0 = h0; dhue = dh; alpha = trans; } // reduce a single row. This is called only if sdimx > rdimx; // void REDUCED_ARRAY::reduce_source_row(float* in, float* out) { int i, ri; memset(out, 0, rdimx*sizeof(float)); memset(itemp, 0, rdimx*sizeof(int)); for (i=0; i 1) out[i] /= itemp[i]; } } } void REDUCED_ARRAY::update_max(int row) { int i; float* p = rrow(row); for (i=0; i rdata_max) rdata_max = p[i]; if (p[i] < rdata_min) rdata_min = p[i]; } } // Add a row of data from the source array // void REDUCED_ARRAY::add_source_row(float* in) { float* p; int i, ry; if (scury >= sdimy) { printf("too many calls to add_source_row()!\n"); *(int*)0 = 0; } if (rdimy == sdimy) { ry = scury; if (rdimx == sdimx) { memcpy(rrow(ry), in, rdimx*sizeof(float)); } else { reduce_source_row(in, rrow(ry)); } update_max(ry); nvalid_rows++; } else { ry = (scury*rdimy)/sdimy; if (scury == 0) memset(rrow(0), 0, rdimx*sizeof(float)); // if we've moved into a new row, finish up the previous one // if (ry > last_ry) { p = rrow(last_ry); if (last_ry_count > 1) { for (i=0; i 1) { for (i=0; i 1) hue -= 1; double sat = 1.; double lum = .5 + h/2; COLOR color; HLStoRGB(hue, lum, sat, color); glColor4f(color.r, color.g, color.b, alpha); glVertex3f(x0, y00, z0); glVertex3f(x1, y01, z0); glVertex3f(x1, y11, z1); glVertex3f(x0, y10, z1); } glEnd(); #if 0 // draw a black line on front and right edge of each quad // glLineWidth(4.0); glDisable(GL_LINE_SMOOTH); glBegin(GL_LINES); glColor4f(0., 0., 0., 1.0); for (i=0; i 1) hue -= 1; double sat = 1.; double lum = .5 + h/2; COLOR color; HLStoRGB(hue, lum, sat, color); glColor4f(color.r, color.g, color.b, alpha); //front glVertex3f(x0, y0, z0); glVertex3f(x1, y0, z0); glVertex3f(x1, y1, z0); glVertex3f(x0, y1, z0); } glEnd(); } void REDUCED_ARRAY::draw_row_rect_x(DrawType type,int row) { float z0=0,z1=0,x0=0,x1=0,y0=0,y1=0,h=0; int i=0; float* row0=0; int trow=row-1; float* trow0=0; switch(type) { case TYPE_QUAD: z0 = draw_pos[2] + (draw_size[2]*row)/rdimy; z1 = z0+.14f; row0 = rrow(row); glBegin(GL_QUADS); for (i=0; i 1) hue -= 1; double sat = 1.; double lum = .5 + h/2; COLOR color; HLStoRGB(hue, lum, sat, color); glColor4f(color.r, color.g, color.b, alpha); //front glVertex3f(x0, y0, z0); glVertex3f(x1, y0, z0); glVertex3f(x1, y1, z0); glVertex3f(x0, y1, z0); /* //back glVertex3f(x0, y0, z1); glVertex3f(x1, y0, z1); glVertex3f(x1, y1, z1); glVertex3f(x0, y1, z1); //left glVertex3f(x0, y0, z0); glVertex3f(x0, y0, z1); glVertex3f(x0, y1, z1); glVertex3f(x0, y1, z0); //right glVertex3f(x1, y0, z0); glVertex3f(x1, y0, z1); glVertex3f(x1, y1, z1); glVertex3f(x1, y1, z0); //top glVertex3f(x0, y1, z0); glVertex3f(x0, y1, z1); glVertex3f(x1, y1, z1); glVertex3f(x1, y1, z0); */ } glEnd(); //draw lines /* mode_unshaded(); glLineWidth(.5f); glBegin(GL_LINES); glColor4f(0,0,0,1); for (i=0; i 1) hue -= 1; double sat = 1.; double lum = .5 + h/2; COLOR color; HLStoRGB(hue, lum, sat, color); glColor4f(color.r, color.g, color.b, alpha); glVertex3f(x0+((x1-x0)/2.0f), y1, z0); if(row==0) { glVertex3f(x0,y0,z1); //close up back } else { float h2 = (trow0[i]-rdata_min)/(rdata_max-rdata_min); float z2 = draw_pos[2] + (draw_size[2]*trow)/rdimy; float y2 = draw_pos[1] + draw_size[1]*h2; glVertex3f(x0+((x1-x0)/2.0f), y2, z2); } } //close up right glVertex3f(draw_pos[0]+draw_size[0],draw_pos[1],z0); glVertex3f(draw_pos[0]+draw_size[0],draw_pos[1],draw_pos[2] + (draw_size[2]*trow)/rdimy); glEnd(); glBegin(GL_QUAD_STRIP); //close up front for (i=0; i 1) hue -= 1; double sat = 1.; double lum = .5 + h/2; COLOR color; HLStoRGB(hue, lum, sat, color); glColor4f(color.r, color.g, color.b, alpha); glVertex3f(x0+((x1-x0)/2.0f), y1, z0); float z2 = draw_pos[2] + (draw_size[2]*row+1)/rdimy; float y2 = draw_pos[1]; if(i==0) glVertex3f(x0,y2,z2); else if(i==rdimx-1) glVertex3f(x0+((x1-x0)/2.0f),y2,z2); else glVertex3f(x0+((x1-x0)/2.0f), y2, z2); } glEnd(); break; case TYPE_WAVE: glLineWidth(1.0f); z0 = draw_pos[2] + (draw_size[2]*row)/rdimy; z1 = z0+.14f; row0 = rrow(row); if(row!=0) trow0 = rrow(trow); glEnable(GL_LINE_SMOOTH); glBegin(GL_LINES); glVertex3f(draw_pos[0],draw_pos[1],z0); for (i=0; i 1) hue -= 1; double sat = 1.; double lum = .5 + h/2; COLOR color; HLStoRGB(hue, lum, sat, color); glColor4f(color.r, color.g, color.b, alpha); glVertex3f(x0+((x1-x0)/2.0f), y1, z0); //connect to the row before if(row!=0) { float h2 = (trow0[i]-rdata_min)/(rdata_max-rdata_min); float z2 = draw_pos[2] + (draw_size[2]*trow)/rdimy; float y2 = draw_pos[1] + draw_size[1]*h2; glVertex3f(x0+((x1-x0)/2.0f), y1, z0); glVertex3f(x0+((x1-x0)/2.0f), y2, z2); } // if(row==0) // { // float z2 = draw_pos[2] - (draw_size[2]*row)/rdimy; // float y2 = draw_pos[1]; // glVertex3f(x0+((x1-x0)/2.0f), y1, z0); // glVertex3f(x0+((x1-x0)/2.0f), y2, z2); // } // // if(row==rdimy-1) //last row // { // float z2 = draw_pos[2] + (draw_size[2]*row+1)/rdimy; // float y2 = draw_pos[1]; // glVertex3f(x0+((x1-x0)/2.0f), y1, z0); // glVertex3f(x0+((x1-x0)/2.0f), y2, z2); // } glVertex3f(x0+((x1-x0)/2.0f), y1, z0); } glVertex3f(x1,y0,z0); glEnd(); glDisable(GL_LINE_SMOOTH); break; case TYPE_STRIP: z0 = draw_pos[2] + (draw_size[2]*row)/rdimy; z1 = z0+.14f; row0 = rrow(row); i=0; x0 = draw_pos[0] + (draw_size[0]*i)/rdimx; x1 = x0 + draw_deltax*.8f; h = (row0[i]-rdata_min)/(rdata_max-rdata_min); y0 = draw_pos[1]; y1 = draw_pos[1] + draw_size[1]*h; glVertex3d(x0,y0,z0); glVertex3d(x0,y1,z0); glBegin(GL_QUAD_STRIP); for (i=0; i 1) hue -= 1; double sat = 1.; double lum = .5 + h/2; COLOR color; HLStoRGB(hue, lum, sat, color); glColor4f(color.r, color.g, color.b, alpha); glVertex3d(x1,y0,z0); glVertex3d(x1,y1,z0); } glEnd(); break; default: break; } } void REDUCED_ARRAY::draw_row_rect_y(int row) { float z0 = draw_pos[2] + (draw_size[2]*row)/rdimy; float z1 = z0 + draw_deltaz*.8f; float x0, y0, y1; float* row0 = rrow(row); int i; glBegin(GL_QUADS); for (i=0; i 1) hue -= 1; double sat = 1.; double lum = .5 + h/2; COLOR color; HLStoRGB(hue, lum, sat, color); glColor4f(color.r, color.g, color.b, alpha); glVertex3f(x0, y0, z0); glVertex3f(x0, y1, z0); glVertex3f(x0, y1, z1); glVertex3f(x0, y0, z1); } glEnd(); // draw a black line on top of rectangle // /* glBegin(GL_LINES); glColor4f(0., 0., 0., 1.0); for (i=0; i