示例#1
0
/*
 * Load colors from a file.
 */
static void load_colors( LUI_COLORBAR *cb )
{
   char filename[1000];
/* 16Nov05  Phil McDonald */
   char *p_tmp;
/* end PM */
   FILE *f;
   float min, max;
   int i, j, r[MAX_TABLE], g[MAX_TABLE], b[MAX_TABLE], a[MAX_TABLE];
   float val;
   int entries;

   printf("Enter filename to load colors from: ");
   fgets(filename,1000,stdin);
/* 16Nov05  Phil McDonald */
   if ((p_tmp = strchr (filename, '\n')) != NULL) *p_tmp = '\0';
/* end PM */
   if (filename[0]==0) {
      printf("Load aborted\n");
      return;
   }

   f = fopen( filename, "r" );
   if (!f) {
      printf("Error: couldn't open %s for reading\n", filename );
      return;
   }

   fscanf( f, "%d %f %f %f %f\n", &entries, &min, &max,
           &cb->params[CURVE], &cb->params[BIAS] );
   for (i=0;i<cb->table_size;i++) {
      fscanf( f, "%d %d %d %d\n", &r[i], &g[i], &b[i], &a[i] );
   }
   fclose(f);

   /* now map colors from range specified in file to the range in */
   /* the color widget */

   for (i=0;i<entries;i++) {
      /* convert i to a value in [cb->minval,cb->maxval] */
      val = cb->minval + (float) i / (float) entries * (cb->maxval-cb->minval);
      /* convert val to j in [0..cb->table_size] */
      j = (int) (cb->table_size * (val-min) / (max-min));
      if (j<0) j = 0;
      else if (j>=cb->table_size) j = cb->table_size-1;

      cb->table[i] = PACK_COLOR( r[j], g[j], b[j], a[j] );
   }

   printf("Done\n");
}
示例#2
0
/*
 * Given an XEvent, process it if it pertains to a ColorBar, else do
 * nothing with it.
 * Input:  event - the X event
 * Output:  whichcb - which colorbar this event pertained to.
 * Return: 1 - if color table was changed.
 *         2 - if reset key was pressed
 *         3 - if <shift>+reset key was pressed
 *         0 - if no change
 */
static int colorbar_process( LUI_COLORBAR *cb, XEvent *event )
{
   static int p1 = 0, p2 = 0, p3 = 0, p4 = 0; /* red, green, blue, alpha */
   static int pentry;
   int i, modify, entry, result;
   static int move_marker;

   result = modify = 0;

   if (event->type==KeyPress) {
      char keybuf[50];
      KeySym key;
      XComposeStatus compose;
      int count;
      count = XLookupString( &event->xkey, keybuf, 50, &key, &compose );
      if (count==1) {
         if (keybuf[0]=='r') {
            /* Reset RGB */
            cb->params[DRAWFLAG] = 0.0;
            result = LUI_RGB_RESET;
         }
         else if (keybuf[0]=='R') {
            /* Reset alpha */
            result = LUI_ALPHA_RESET;
            cb->params[DRAWFLAG] = 0.0;
         }
         else if (keybuf[0]=='c' || keybuf[0]=='C') {
            /* Copy current colors to clipboard */
            copy_colors( cb );
         }
         else if (keybuf[0]=='p' || keybuf[0]=='P') {
            /* Paste clipboard colors to current color widget */
            paste_colors( cb );
            LUI_ColorBarRedraw( cb );
            result = LUI_RGB_CHANGE | LUI_ALPHA_CHANGE;
            cb->params[DRAWFLAG] = 0.0;
            result = LUI_RGB_CHANGE | LUI_ALPHA_CHANGE;
         }

/* WLH 7-18-96 */
         else if (keybuf[0]=='s' || keybuf[0]=='S') {
            /* save colors to a file */
            save_colors( cb );
         }
         else if (keybuf[0]=='l' || keybuf[0]=='L') {
            /* load colors from a file */
            load_colors( cb );
            LUI_ColorBarRedraw( cb );
            return 1;
         }

         else {
            /* if unused key, toggle help display */
            cb->helpflag = !cb->helpflag;
            LUI_ColorBarRedraw( cb );
         }
      }
      else if (key == XK_Left) {
         /* rotate left */
         cb->params[BIAS] -= 0.03/cb->params[CURVE];
         result = LUI_RGB_SHAPE;
         cb->params[DRAWFLAG] = 0.0;
      }
      else if (key == XK_Right) {
         /* rotate right */
         cb->params[BIAS] += 0.03/cb->params[CURVE];
         result = LUI_RGB_SHAPE;
         cb->params[DRAWFLAG] = 0.0;
      }
      else if (key == XK_Up) {
         /* expand color map */
         if (event->xkey.state & ANY_MODIFIER) {
            cb->params[ALPHAPOW] -= 0.1;
            if (cb->params[ALPHAPOW]<0.0)
              cb->params[ALPHAPOW] = 0.0;
            result = LUI_ALPHA_SHAPE;
            cb->params[DRAWFLAG] = 0.0;
         }
         else {
            cb->params[CURVE] -= 0.1;
            result = LUI_RGB_SHAPE;
            cb->params[DRAWFLAG] = 0.0;
         }
      }
      else if (key == XK_Down) {
         /* compress color map */
         if (event->xkey.state & ANY_MODIFIER) {
            cb->params[ALPHAPOW] += 0.1;
            result = LUI_ALPHA_SHAPE;
            cb->params[DRAWFLAG] = 0.0;
         }
         else {
            cb->params[CURVE] += 0.1;
            result = LUI_RGB_SHAPE;
            cb->params[DRAWFLAG] = 0.0;
         }
      }
   }
   else if (event->type==Expose && event->xexpose.count==0) {
      LUI_ColorBarRedraw( cb );
      result = 0;
   }
   else if (event->type==ConfigureNotify) {
/* MJK 4.15.99 */
      LUI_ColorBarSetSize( cb, event->xconfigure.width, event->xconfigure.height );
      result = 0;
   }
   else if (event->type==ButtonPress ) {
      if (event->xbutton.y<cb->wedge_y) {
         /* change color function */
         move_marker = 0;
      }
      else {
         /* change marker position */
         move_marker = 1;
      }
      /* determine which curve to modify */
      if (event->xbutton.state&ANY_MODIFIER) {
         p4 = 1;
      }
      else {
         if (event->xbutton.button==Button1)  p1 = 1;
         if (event->xbutton.button==Button2)  p2 = 1;
         if (event->xbutton.button==Button3)  p3 = 1;
      }
      pentry = x_to_index( cb, event->xbutton.x );
      modify = 1;
   }
   else if (event->type==ButtonRelease) {
      if (p1 || p2 || p3) {
         result = LUI_RGB_CHANGE;
      }
      else {
         result = LUI_ALPHA_CHANGE;
      }
      if (event->xbutton.button==Button1)  p1 = 0;
      if (event->xbutton.button==Button2)  p2 = 0;
      if (event->xbutton.button==Button3)  p3 = 0;
      p4 = 0;
   }
   else if (event->type==MotionNotify) {
      /* Flush extra MotionNotify events */
      while (QLength(LUI_Display)>0) {
         XEvent next;
         XPeekEvent(LUI_Display, &next);
         if (next.type!=MotionNotify)
            break;
         XNextEvent(LUI_Display, event);
      }
      modify = 1;
   }


   /* Modify one or more of the color curves */

   if (modify && (p1 || p2 || p3 || p4)) {
      /* calculate which entry in color table to change */
      entry = x_to_index( cb, event->xbutton.x );
      /* update */
      if (move_marker) {
         /* changing marker position */
         cb->markerpos = entry;
         redraw_marker( cb );
      }
      else {
         /* changing color graph */
         int a, b, value;

         value = y_to_intensity( cb, event->xbutton.y );

         if (pentry<=entry) {
            a = pentry;
            b = entry;
         }
         else {
            a = entry;
            b = pentry;
         }

         /* update entries from 'pentry' to 'entry' */
         for (i=a; i<=b; i++) {
            int red, green, blue, alpha;
            red = UNPACK_RED(cb->table[i]);
            green = UNPACK_GREEN(cb->table[i]);
            blue = UNPACK_BLUE(cb->table[i]);
            alpha = UNPACK_ALPHA(cb->table[i]);
            if (p1) {
               /* modify red */
               red = value;
            }
            if (p2) {
               /* modify green */
               green = value;
            }
            if (p3) {
               /* modify blue */
               blue = value;
            }
            if (p4) {
               /* modify alpha */
               alpha = value;
            }
            /* change the color table entry */
            cb->table[i] = PACK_COLOR(red,green,blue,alpha);
         } /* for */

         /* redraw the color curves */
         if (pentry<entry)
           redraw_range( cb, pentry-1, entry+1 );
         else
           redraw_range( cb, entry-1, pentry+1 );

         pentry = entry;

         if (p4) {
            /* update min,max alpha values */
            cb->minalpha = 256;
            cb->maxalpha = 0;
            for (i=0;i<cb->table_size;i++) {
               int a = UNPACK_ALPHA( cb->table[i] );
               if (a<cb->minalpha)  cb->minalpha = a;
               if (a>cb->maxalpha)  cb->maxalpha = a;
            }
         }

         if (p4) {
			  result = LUI_ALPHA_MODIFY;
			  /*
            result = LUI_ALPHA_CHANGE;
			  */
         }
         else {
            result = LUI_RGB_MODIFY;
				/*
            result = LUI_RGB_CHANGE;
				*/
         }
         cb->params[DRAWFLAG] = 1.0;
      }
   } /*modify*/


   if (result!=0 && cb->callback) {
      (*cb->callback)(cb, result);
   }

   return result;
}
示例#3
0
文件: box.c 项目: drafnel/Vis5d
void draw_tick_marks( Display_Context dtx )
{
    float verts[2][3];
    /* base and up vectors for text drawn along x,y,z axes. */
    static float bx[3] = { 0.05, 0.0, 0.0 },      ux[3] = { 0.0, 0.05, 0.05 };
    /*
    static float by[3] = { -0.035, 0.0, -0.035 },  uy[3] = { 0.0, 0.07, 0.0 };
    static float bz[3] = { -0.035, -0.035, 0.0 }, uz[3] = { 0.0, 0.0, 0.07 };
    */
    float tick_inc, i, row, col, lev;
    char str[100];

    /* set depth cueing & line color */
    /* MJK 3.29.99 */
    if (dtx->Reversed) {
        set_color( PACK_COLOR(0,0,0,255) );
    }
    else {
        set_color( dtx->BoxColor );
    }


    set_depthcue( dtx->DepthCue );

    /* go in the order.. low south side, low east side,
       go counter-clock-wise, then high south side, couterclockwise,
       then southeast side, and work coutner-clockwise, so there are
       12 sides to loop through */

    dtx->tick_do[0] = 1;
    dtx->tick_type[0] = 1;
    dtx->tick_num[0] = 10;
    if (dtx->tick_do[0]) {
        tick_inc = (float)(dtx->Nc)/(float)(dtx->tick_num[0]-1);
        row = dtx->Nr-1;
        lev = 0;
        for (i = tick_inc; i < dtx->Nc; i += tick_inc) {
            col = i;
            vis5d_gridPRIME_to_xyzPRIME(dtx->dpy_context_index, 0, 0,
                                        row, col, lev, &verts[0][0], &verts[0][1], &verts[0][2]);
            verts[1][0] = verts[0][0];
            verts[1][1] = verts[0][1] - 0.05;
            verts[1][2] = verts[0][2] - 0.062;
            polyline( verts, 2);
            if (dtx->tick_type[0] == 0) {
                float lat, lon, hgt;
                vis5d_gridPRIME_to_geo(dtx->dpy_context_index, 0, 0,
                                       row, col, lev, &lat, &lon, &hgt);
                /*float2string(lon, str); */
                if (strlen(str) <2) {
                    plot_string( str, verts[1][0]-.009, verts[1][1]-.05, verts[1][2]-0.062, bx, ux, 0);
                }
                else if (strlen(str) <4) {
                    plot_string( str, verts[1][0]-.02, verts[1][1]-.05, verts[1][2]-0.062, bx, ux, 0);
                }
                else {
                    plot_string( str, verts[1][0]-.05, verts[1][1]-.05, verts[1][2]-0.062, bx, ux, 0);
                }
            }
            else if (dtx->tick_type[0] == 1) {
                /* float2string(col, str); */
                if (strlen(str) <2) {
                    plot_string( str, verts[1][0]-.009, verts[1][1]-.05, verts[1][2]-0.062, bx, ux, 0);
                }
                else if (strlen(str) <4) {
                    plot_string( str, verts[1][0]-.02, verts[1][1]-.05, verts[1][2]-0.062, bx, ux, 0);
                }
                else {
                    plot_string( str, verts[1][0]-.05, verts[1][1]-.05, verts[1][2]-0.062, bx, ux, 0);
                }
            }
        }
    }
}
示例#4
0
文件: box.c 项目: drafnel/Vis5d
/*
 * Draw the 3-D box.
 * Input:  it - time step.
 */
void draw_box( Display_Context dtx, int it )
{
    /* base and up vectors for text drawn along x,y,z axes. */
    static float bx[3] = { 0.05, 0.0, 0.0 },      ux[3] = { 0.0, 0.05, 0.05 };
    static float by[3] = { -0.035, 0.0, -0.035 },  uy[3] = { 0.0, 0.07, 0.0 };
    static float bz[3] = { -0.035, -0.035, 0.0 }, uz[3] = { 0.0, 0.0, 0.07 };
    float x1, y1, z1, x2, y2, z2;
    char str[100], xdir1[8], xdir2[8], ydir1[8], ydir2[8];

    /* set depth cueing & line color */
    /* MJK 3.29.99 */
    if (dtx->Reversed) {
        set_color( PACK_COLOR(0,0,0,255) );
    }
    else {
        set_color( dtx->BoxColor );
    }
    /*MiB*/
    xdir1[0] = ' ';
    xdir2[0] = ' ';
    xdir1[1] = '\0';
    xdir2[1] = '\0';
    ydir1[0] = ' ';
    ydir2[0] = ' ';
    ydir1[1] = '\0';
    ydir2[1] = '\0';

    set_depthcue( dtx->DepthCue );

    if(dtx->NumBoxVerts > 0) {
        if (dtx->Reversed) {
            draw_multi_lines( dtx->NumBoxVerts, dtx->BoxVerts, PACK_COLOR(0,0,0,255) );
        }
        else {
            draw_multi_lines( dtx->NumBoxVerts, dtx->BoxVerts, dtx->BoxColor );
        }
    }


    if (dtx->TickMarks) {
        /* Draw axis labels. */
        if (dtx->CoordFlag) {
            x1 = 1.0;
            x2 = (float) dtx->Nc;
            y1 = 1.0;
            y2 = (float) dtx->Nr;
            z1 = 1.0;
            z2 = (float) dtx->MaxNl;
        }
        else {
            x1 = dtx->WestBound;
            x2 = dtx->EastBound;

            y1 = dtx->NorthBound;
            y2 = dtx->SouthBound;

            /*MiB   03/2001 limit range to -180, 180 */
            if (x1 < -180.) {
                x1 = 360. + x1;
            }
            if (x2 < -180.) {
                x2 = 360. + x2;
            }
            if (x1 > 180.) {
                x1 = -360. + x1;
            }
            if (x2 > 180.) {
                x2 = -360. + x2;
            }
            /*MiB   03/2001 Define East/West  */
            if (x1 > 0.) {
                xdir1[0] = 'W';
            } else {
                xdir1[0] = 'E';
                x1 = x1 *(-1.);
            }
            if (x2 > 0.) {
                xdir2[0] = 'W';
            } else {
                xdir2[0] = 'E';
                x2 = x2 *(-1.);
            }
            /*MiB   03/2001 Define North/South  */
            if (y1 > 0.) {
                ydir1[0] = 'N';
            } else {
                ydir1[0] = 'S';
                y1 = y1 *(-1.);
            }
            if (y2 > 0.) {
                ydir2[0] = 'N';
            } else {
                ydir2[0] = 'S';
                y2 = y2 *(-1.);
            }


#ifdef LEVELTYPES
            z1 = dtx->BottomCoordinate;
            z2 = dtx->TopCoordinate;
#else
            z1 = dtx->BottomBound;
            z2 = dtx->TopBound;
#endif
            z1 = VERT(z1);
            z2 = VERT(z2);
        }

        if (dtx->CursorX - dtx->Xmin > 0.1 || dtx->DisplayCursor==0) {
            /* MJK 12.02.98 */
            float2string (dtx, 0, x1, str);
            /*MiB*/  strcat(str,xdir1);
            plot_string( str, dtx->Xmin-0.02, dtx->Ymin-0.1, dtx->Zmin-0.125, bx, ux, 0 );
        }

        if (dtx->Xmax - dtx->CursorX > 0.1 || dtx->DisplayCursor==0) {
            /* MJK 12.02.98 */
            float2string (dtx, 0, x2, str);
            /*MiB*/  strcat(str,xdir2);
            plot_string( str, dtx->Xmax-0.05, dtx->Ymin-0.1, dtx->Zmin-0.125, bx, ux, 0 );
        }

        if (dtx->Ymax - dtx->CursorY > 0.1 || dtx->DisplayCursor==0) {
            /* MJK 12.02.98 */
            float2string (dtx, 1, y1, str);
            /*MiB*/  strcat(str,ydir1);
            plot_string( str, dtx->Xmin-0.075, dtx->Ymax-0.03, dtx->Zmin-0.075, by, uy, 1 );
        }

        if (dtx->CursorY-dtx->Ymin > 0.1 || dtx->DisplayCursor==0) {
            /* MJK 12.02.98 */
            float2string (dtx, 2, y2, str);
            /*MiB*/  strcat(str,ydir2);
            plot_string( str, dtx->Xmin-0.075, dtx->Ymin-0.02, dtx->Zmin-0.075, by, uy, 1 );
        }

        if (dtx->CursorZ-dtx->Zmin > 0.1 || dtx->DisplayCursor==0) {
            /* MJK 12.02.98 */
            float2string (dtx, 2, z1, str);
            plot_string( str, dtx->Xmin-0.07, dtx->Ymin-0.07, dtx->Zmin+0.005, bz, uz, 1 );
        }

        if (dtx->Zmax-dtx->CursorZ > 0.1 || dtx->DisplayCursor==0) {
            /* MJK 12.02.98 */
            float2string(dtx, 2, z2, str);
            plot_string( str, dtx->Xmin-0.07, dtx->Ymin-0.07, dtx->Zmax+0.005, bz, uz, 1 );
        }
    }

    set_depthcue( 0 );

}
示例#5
0
文件: topo.c 项目: huangynj/Vis5dPlus
/*
 * Initialize the topography color table.
 * Input:  ct - the color table
 *         size - number of entries in the table
 *         minhgt, maxhgt - the range of height values
 */
void init_topo_color_table( unsigned int ct[], int size,
                            float minhgt, float maxhgt )
{
#define OCEAN
#ifdef OCEAN
   /* Change submitted by Mike McCann to give better under-water */
   /* topography colors. */
   static float red[7]   = { 5.0, 45.0,  20.0, 20.0,  70.0, 165.0, 200.0};
   static float green[7] = {10.0, 50.0, 170.0,170.0, 200.0,  42.0, 200.0};
   static float blue[7]  = {30.0,150.0,  42.0, 42.0,   0.0,  42.0, 200.0};
   static float range[7] = {-5.0, -0.020,-0.015, 0.0,   0.1,  1.0,   2.8};
#else
   static float red[4]   = { 20.0,  70.0, 165.0, 200.0};
   static float green[4] = {170.0, 200.0,  42.0, 200.0};
   static float blue[4]  = { 42.0,   0.0,  42.0, 200.0};
   static float range[4] = {  0.0,   0.1,  1.0,   2.8};
#endif
   int i, j;
   float x0, x1;
   float r, g, b, dr, dg, db;

   /* initialize to all white to start */
   for (i=0;i<size-1;i++) {
      ct[i] = 0xffffffff;
   }
   ct[size-1] = PACK_COLOR( 25, 25, 255, 255 );  /* r=25, g=25, b=255 */


#ifdef OCEAN
   for (i=0;i<6;i++) {
#else
   for (i=0;i<3;i++) {
#endif
      if (minhgt==maxhgt) {
         r = g = b = 0;
         dr = dg = db = 0;
         x0 = x1 = 0;
      }
      else {
         x0 = (range[i] - minhgt)
                / (maxhgt - minhgt) * (float)(size-1);
         x1 = (range[i+1] - minhgt)
                / (maxhgt - minhgt) * (float)(size-1);
         dr = (red[i+1]-red[i]) / (x1-x0);
         dg = (green[i+1]-green[i]) / (x1-x0);
         db = (blue[i+1]-blue[i]) / (x1-x0);
         r = red[i];
         g = green[i];
         b = blue[i];
      }
      for (j=(int) x0; j<(int) x1; j++) {
         if (j>=0 && j<size-1) {
            ct[j] = PACK_COLOR( (int) r, (int) g, (int) b, 0xff );
         }
         r += dr;
         g += dg;
         b += db;
      }
   }
}




/*
 * Generate the topography quadmesh.  This must be called after the
 * grid data set has been loaded.
 * Input:  toponame - name of topography file
 *         textureflag - 1 = use texture mapping, 0 = don't texture map
 *         hi_res - 1=high resolution topography, 0=normal resolution
 * Return:  1 = ok,  0 = error
 */
int init_topo( Display_Context dtx, char *toponame, int textureflag, int hi_res )
{
   double dx, dy;
   float lat, lon;
   float topo_dlat, topo_dlon;
   float *topoheight;
   int i, j;
   int topoflag = -1;
   int qr, qc;
   uint_1 *indexes;
   struct Topo *topo;


   /* MJK 12.02.98 begin */
   if (dtx->UserTopoFlag) {
      topoflag = read_user_topo( dtx, toponame );
      if (topoflag == 0) return 0;
   }


   if (topoflag == -1) {
      topoflag = read_topo( dtx->topo, toponame );
   }
   topo = dtx->topo;  
   /* MJK 12.02.98 end */



   if (!topoflag && !textureflag) {
      return 0;
   }
   
   /* qrows, qcols - size of topography quadmesh in rows and columns */
   if (topo->Topo_cols==dtx->Nc && topo->Topo_rows==dtx->Nr) {
      /* use same topography resolution as grid resolution */
      qc = topo->Topo_cols;
      qr = topo->Topo_rows;
   }
   else {
      int maxverts = hi_res ? HI_RES_VERTS : LO_RES_VERTS;
      float r;
		if(((dtx->Xmax - dtx->Xmin)*(dtx->Ymax - dtx->Ymin))==0){
		  fprintf(stderr,"Error in init_topo %f %f %f %f\n",dtx->Xmax,dtx->Xmin,dtx->Ymax,dtx->Ymin);
		  return -1;
		}

      r = sqrt( (float) maxverts
                      / ((dtx->Xmax - dtx->Xmin)*(dtx->Ymax - dtx->Ymin)) );
      qc = (int) (r * (dtx->Xmax - dtx->Xmin) + 0.5);
      qr = (int) (r * (dtx->Ymax - dtx->Ymin) + 0.5);
   }

   /* allocate space for topography vertex and color arrays */
   if (topo->TopoVertex){
      free(topo->TopoVertex);
      free(topo->TopoNormal);
      free(topo->TopoTexcoord);
      free(topo->TopoFlatVertex);
      /* MJK 12.02.98 begin */
      for (i = 0; i <= MAXTIMES; i++)
      {
         if (topo->TopoIndexes[i] != NULL)
            free (topo->TopoIndexes[i]), topo->TopoIndexes[i] = NULL;
      }
      /* MJK 12.02.98 end */


      /*
      free(topo->TopoIndexes[MAXTIMES]);
      */
   }
   topo->TopoVertex     = (float *) malloc( qr*qc*3*sizeof(float) );
   topo->TopoNormal     = (float *) malloc( qr*qc*3*sizeof(float) );
   topo->TopoTexcoord   = (float *) malloc( qr*qc*2*sizeof(float) );
   topo->TopoFlatVertex = (float *) malloc( qr*qc*3*sizeof(float) );
   topoheight = (float *) malloc( qr*qc*sizeof(float) );
   /* topoheight = (float *) allocate( dtx, qr*qc*sizeof(float) ); */

   indexes = malloc( qr*qc*1*sizeof(uint_1) );
   topo->TopoIndexes[MAXTIMES] = indexes;

   /*
    * Compute topography vertices.
    */
   if (dtx->CurvedBox==0) {
      /* Rectangular box:  generate vertices in graphics coords */
      int k;
      float x, y, z;

      /* MJK 12.15.98 */
      double xx, yy, texture_s, texture_t, delta_s, delta_t;

      dx = (dtx->Xmax-dtx->Xmin) / (float) (qc-1);
      dy = (dtx->Ymax-dtx->Ymin) / (float) (qr-1);

      delta_s = 1.0 / (float) (qc-1);
      delta_t = 1.0 / (float) (qr-1);

      /* calculate sampling size */
      if (topo->Topo_cols==dtx->Nc && topo->Topo_rows==dtx->Nr) {
         topo->LatSample = topo->LonSample = 1;
      }
      else {
         topo_dlat = (topo->Topo_northlat-topo->Topo_southlat) / topo->Topo_rows;
         topo->LatSample = CLAMP( (int) (2.0*dy/topo_dlat), 2, 20 );
         topo_dlon = (topo->Topo_westlon-topo->Topo_eastlon) / topo->Topo_cols;
         topo->LonSample = CLAMP( (int) (2.0*dx/topo_dlon), 2, 20 );
      }
      k = 0;
      yy = dtx->Ymax;
      texture_t = 0.0;
      for (i=0; i<qr; i++) {
         xx = dtx->Xmin;
         texture_s = 0.0;
         y = yy;
         for (j=0; j<qc; j++) {
            int water;
            float hgt;

            x = xx;
            xyzPRIME_to_geo( dtx, -1, -1, x, y, 0.0, &lat, &lon, &hgt );
            hgt = elevation( dtx, dtx->topo, lat, lon, &water ) / 1000.0;  /* hgt in km */
/* MJK 2.17.99
            z = height_to_zPRIME( dtx, hgt );
*/
            z = height_to_zTOPO( dtx, hgt );

            /* WLH 3 Nov 98 - kludge topo for inverted VERT_GENERIC */
            if (dtx->VerticalSystem == VERT_GENERIC &&
                dtx->TopBound < dtx->BottomBound) {
              z = dtx->Zmin + hgt / (dtx->BottomBound-dtx->TopBound)
                       * (dtx->Zmax-dtx->Zmin);
            }

            z = ABS(dtx->Zmin - z) < 0.01 ? dtx->Zmin+0.01 : z;
            topo->TopoVertex[k*3+0] = x;
            topo->TopoVertex[k*3+1] = y;
            topo->TopoVertex[k*3+2] = z;

            topoheight[k] = hgt;  /* save topo height at this vertex */
            /* if water flag is set, index will be 255 */
            indexes[k] = (water) ? 255 : 0;

            topo->TopoFlatVertex[k*3+0] = x;
            topo->TopoFlatVertex[k*3+1] = y;
            topo->TopoFlatVertex[k*3+2] = dtx->Zmin;

            topo->TopoTexcoord[k*2+0] = texture_s;
            topo->TopoTexcoord[k*2+1] = texture_t;

            k++;
            xx += dx;
            texture_s += delta_s;
         }
         yy -= dy;
         texture_t += delta_t;
      }
	

   }
   else {
      /* Curved box:  generate vertices in geographic coordinates */

      float lat, lon;
      double latlat, lonlon;
      double dlat, dlon;
      int k;
      float texture_s, texture_t, delta_s, delta_t;

      dlat = (dtx->NorthBound - dtx->SouthBound) / (float) (qr-1);
      dlon = (dtx->WestBound - dtx->EastBound) / (float) (qc-1);

      delta_s = 1.0 / (float) (qc-1);
      delta_t = 1.0 / (float) (qr-1);

      k = 0;
      latlat = dtx->NorthBound;
      texture_t = 0.0;
      for (i=0; i<qr; i++) {
         lonlon = dtx->WestBound;
         lat = latlat;
         texture_s = 0.0;
         for (j=0; j<qc; j++) {
            int water;
            float hgt, x, y, z;

            lon = lonlon;
            hgt = elevation( dtx, dtx->topo, lat, lon, &water ) / 1000.0;  /* hgt in km */
/* MJK 2.17.99
            geo_to_xyzPRIME( dtx, -1, -1, 1, &lat, &lon, &hgt, &x, &y, &z );
*/
            geo_to_xyzTOPO( dtx, -1, -1, 1, &lat, &lon, &hgt, &x, &y, &z );
            topo->TopoVertex[k*3+0] = x;
            topo->TopoVertex[k*3+1] = y;
            topo->TopoVertex[k*3+2] = z;

            topoheight[k] = hgt;
            /* if water flag is set, index will be 255 */
            indexes[k] = (water) ? 255 : 0;

            hgt = dtx->BottomBound;
/* MJK 2.17.99            
            geo_to_xyzPRIME( dtx, -1, -1, 1, &lat, &lon, &hgt, &x, &y, &z );
*/
            geo_to_xyzTOPO( dtx, -1, -1, 1, &lat, &lon, &hgt, &x, &y, &z );
            topo->TopoFlatVertex[k*3+0] = x;
            topo->TopoFlatVertex[k*3+1] = y;
            topo->TopoFlatVertex[k*3+2] = z;

            topo->TopoTexcoord[k*2+0] = texture_s;
            topo->TopoTexcoord[k*2+1] = texture_t;

            k++;
            lonlon -= dlon;
            texture_s += delta_s;
         }
         latlat -= dlat;
         texture_t += delta_t;
      }

   }

   /* Find MinTopoHgt and MaxTopoHgt */
   topo->MinTopoHgt = 10000.0;
   topo->MaxTopoHgt = -10000.0;
   for (i=0;i<qr*qc;i++) {
      if (topoheight[i]<topo->MinTopoHgt) {
         topo->MinTopoHgt = topoheight[i];
      }
      if (topoheight[i]>topo->MaxTopoHgt) {
         topo->MaxTopoHgt = topoheight[i];
      }
   }

   /* Compute topography color table indexes. */
   for (i=0;i<qr*qc;i++) {
	  float hgt = topoheight[i];
	  if (indexes[i]!=255) {   /* if not water */
		 if (topo->MinTopoHgt==topo->MaxTopoHgt) {
			indexes[i] = 0;
		 }
		 else {
			int index;
			index = (int) ( (hgt-topo->MinTopoHgt)
								 / (topo->MaxTopoHgt-topo->MinTopoHgt) * 254.0 );
			indexes[i] = CLAMP( index, 0, 254 );
		 }
	  }
   }

   /* done with topoheight array */
   free( topoheight );

   /* compute quadmesh normal vectors */
   {
      float *qnorm;

      qnorm = (float *) malloc( qc * qr * 3 * sizeof(float) );
      /* qnorm = (float *) allocate( dtx, qc * qr * 3 * sizeof(float) ); */

      /* step 1: compute surface normal for each quadrilateral. */
      for (i=0;i<qr-1;i++) {
         for (j=0;j<qc-1;j++) {
            float a[3], b[3];
            int index;

            index = (i*qc+j)*3;
            /* a is the down vector, b is the right vector */
            a[0] = topo->TopoVertex[index+qc*3+0] - topo->TopoVertex[index+0];
            a[1] = topo->TopoVertex[index+qc*3+1] - topo->TopoVertex[index+1];
            a[2] = topo->TopoVertex[index+qc*3+2] - topo->TopoVertex[index+2];
            b[0] = topo->TopoVertex[index+3+0] - topo->TopoVertex[index+0];
            b[1] = topo->TopoVertex[index+3+1] - topo->TopoVertex[index+1];
            b[2] = topo->TopoVertex[index+3+2] - topo->TopoVertex[index+2];
            /* a cross b is the quad's facet normal */
            qnorm[index+0] =  a[1]*b[2]-a[2]*b[1];
            qnorm[index+1] = -a[0]*b[2]+a[2]*b[0];
            qnorm[index+2] =  a[0]*b[1]-a[1]*b[0];
         }
      }

      /* step 2: compute vertex normals by averaging adjacent */
      /* quadrilateral normals. */
      for (i=0;i<qr;i++) {
         for (j=0;j<qc;j++) {
            float n[3], mag;
            int index;

            index = (i*qc+j)*3;

            n[0] = n[1] = n[2] = 0.0;
            /* upper-left quad */
            if (i>0 && j>0) {
               n[0] += qnorm[ index-qc*3-3+0 ];
               n[1] += qnorm[ index-qc*3-3+1 ];
               n[2] += qnorm[ index-qc*3-3+2 ];
            }
            /* upper-right quad */
            if (i>0 && j<qc-1) {
               n[0] += qnorm[ index-qc*3+0 ];
               n[1] += qnorm[ index-qc*3+1 ];
               n[2] += qnorm[ index-qc*3+2 ];
            }
            /* lower-left quad */
            if (i<qr-1 && j>0) {
               n[0] += qnorm[ index-3+0 ];
               n[1] += qnorm[ index-3+1 ];
               n[2] += qnorm[ index-3+2 ];
            }
            /* lower-right quad */
            if (i<qr-1 && j<qc-1) {
               n[0] += qnorm[ index+0 ];
               n[1] += qnorm[ index+1 ];
               n[2] += qnorm[ index+2 ];
            }

            mag = sqrt( n[0]*n[0] + n[1]*n[1] + n[2]*n[2] );
            if (mag>0.0) {
               mag = 1.0 / mag;
               topo->TopoNormal[index+0] = n[0] * mag;
               topo->TopoNormal[index+1] = n[1] * mag;
               topo->TopoNormal[index+2] = n[2] * mag;
            }
         }
      }

      free (qnorm);
      /* deallocate( dtx, qnorm, qc * qr * 3 * sizeof(float) ); */
   }

   topo->qcols = qc;
   topo->qrows = qr;

   /* Define the initial quadmesh vertex colors */
	if(dtx->ColorTable[VIS5D_TOPO_CT]==NULL){
	  dtx->ColorTable[VIS5D_TOPO_CT] = (struct ColorTable *) calloc(1,sizeof(struct ColorTable));
	}
   init_topo_color_table( dtx->ColorTable[VIS5D_TOPO_CT]->Colors[MAXVARS*VIS5D_MAX_CONTEXTS], 256,
                          topo->MinTopoHgt, topo->MaxTopoHgt );
   topo->TopoColorVar = -1;


   /* MJK 12.02.98 */
   make_topo_strips (dtx);

 
   return 1;
   
}
示例#6
0
文件: topo.c 项目: huangynj/Vis5dPlus
/*
 * Draw the topography.
 * Input:  time - the timestep number
 *         texture_flag - 0=no texture, 1=texture map
 *         flat_flag - 0=draw w/ topo heights, 1=draw flat
 */
void draw_topo( Display_Context dtx, int time, int texture_flag, int flat_flag )
{
   /* MJK 12.02.98 begin */
   int         i, j, n, ir, ic, nr, nc, nr2, nc2;
   int_vert2       *verts;
   int_1       *norms;
   uint_1      *color;
   /* MJK 12.02.98 end */

	struct Topo *topo;
	topo = dtx->topo;


   set_color( 0xffffffff );

   if (flat_flag) {
      if (texture_flag) {
         /* flat texture map */
         use_texture( dtx, time );
         texture_quadmeshnorm( topo->qrows, topo->qcols,
                               (void*) topo->TopoFlatVertex,
                               NULL,  
                               (void*) topo->TopoTexcoord ); 
      }
      else {
         /* draw nothing */
      }
   }
   else {
      if (texture_flag) {
         /* textured topo */
         use_texture( dtx, time );
         texture_quadmeshnorm( topo->qrows, topo->qcols,
                               (void*) topo->TopoVertex,
                               (void*) topo->TopoNormal,
                               (void*) topo->TopoTexcoord ); 
      }
      else {
         /* untextured topo */
         uint_1 *indexes;
         unsigned int *color_table;

         if (topo->TopoColorVar<0) {
            color_table = dtx->ColorTable[VIS5D_TOPO_CT]->Colors[MAXVARS*VIS5D_MAX_CONTEXTS];
            indexes = topo->TopoIndexes[MAXTIMES];
         }
         else {
            color_table = dtx->ColorTable[VIS5D_TOPO_CT]->Colors[ topo->TopoColorVarOwner * MAXVARS + topo->TopoColorVar ];
            indexes = topo->TopoIndexes[time];
            if (!indexes) {
               indexes = topo->TopoIndexes[MAXTIMES];
            }
         }

         /* MJK 12.02.98 begin */
         if (topo->TopoStripsVerts == NULL) return;
         if (topo->TopoStripsNorms == NULL) return;

         verts = topo->TopoStripsVerts;
         norms = topo->TopoStripsNorms;
         nr    = topo->qrows;
         nc    = topo->qcols;
         nr2   = nr * 2;
         nc2   = nc * 2;

         n     = (nr > nc) ? nr : nc;
         color = (uint_1 *) malloc ((n * 2 * sizeof (uint_1)));
         if (color == NULL) return;


         /* topography */

         j = 0;
         i = nc;
         for (ir = 1; ir < nr; ir++)
         {
             n = 0;
             for (ic = 0; ic < nc; ic++)
             {
                color[n++] = indexes[i++];
                color[n++] = indexes[j++];
             }

             draw_colored_triangle_strip (nc2,
                                          (void *) verts, (void *) norms,
                                          color, color_table, 255);
             verts += nc2 * 3;
             norms += nc2 * 3;
         }
         if (topo->DisplayTopoBase)
         {
             unsigned int    base_color = TOPO_BASE_COLOR;
             int             norm_dir = 1;

             /* MJK 3.29.99 */
             clipping_off();


             n = (nr > nc) ? nr : nc;
             memset (color, 0, (n * 2 * sizeof (uint_1)));

/* MJK reversed this 2.16.99
             norm_dir = (topo->TopoBaseLev < 0.0) ? -1 : 1;
*/
/* MJK 3.29.99 don't know why this is here
             norm_dir = (topo->TopoBaseLev < 0.0) ? -1 : 1; 
*/
             norm_dir = 1;

             /* north side */

             if ((check_face_norm(verts) * norm_dir > 0))
                 draw_colored_triangle_strip (nc2,
                                              (void *) verts,
                                              (void *) norms,
                                              color, &base_color, 255);
             verts += nc2 * 3;
             norms += nc2 * 3;

             /* south side */

             if ((check_face_norm(verts) * norm_dir) > 0)
                 draw_colored_triangle_strip (nc2,
                                              (void *) verts,
                                              (void *) norms,
                                              color, &base_color, 255);
             verts += nc2 * 3;
             norms += nc2 * 3;

             /* west side */

             if ((check_face_norm(verts) * norm_dir) > 0)
                 draw_colored_triangle_strip (nr2,
                                              (void *) verts,
                                              (void *) norms,
                                              color, &base_color, 255);
             verts += nr2 * 3;
             norms += nr2 * 3;

             /* east side */

             if ((check_face_norm(verts) * norm_dir) > 0)
                 draw_colored_triangle_strip (nr2,
                                              (void *) verts,
                                              (void *) norms,
                                              color, &base_color, 255);
             verts += nr2 * 3;
             norms += nr2 * 3;

             /* bottom */

             if ((check_face_norm(verts) * norm_dir) > 0)
             {
                 float       r, g, b, a, fac = 0.90;

                 /* color the bottom slightly darker than the sides */
                 r = (((float) UNPACK_RED (base_color)) / 255.0) * fac;
                 g = (((float) UNPACK_GREEN (base_color)) / 255.0) * fac;
                 b = (((float) UNPACK_BLUE (base_color)) / 255.0) * fac;
                 a = ((float) UNPACK_ALPHA (base_color)) / 255.0;
                 base_color = PACK_COLOR ((int) (r * 255.0),
                                          (int) (g * 255.0),
                                          (int) (b * 255.0),
                                          (int) (a * 255.0));

                 for (ir = 1; ir < nr; ir++)
                 {
                     draw_colored_triangle_strip (nc2,
                                                  (void *) verts,
                                                  (void *) norms,
                                                  color, &base_color, 255);
                     verts += nc2 * 3;
                     norms += nc2 * 3;
                 }
             }
             /* MJK 3.29.99 */
             clipping_on();
         }
         free (color);
      }
   }
}