Changeset 455 for trunk


Ignore:
Timestamp:
Jun 2, 2006, 9:38:14 PM (18 years ago)
Author:
mmc
Message:

Added a new "legend" command, which can be used to request the
legend strip for a transfer function.

Location:
trunk/gui/vizservers/nanovis
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/gui/vizservers/nanovis/Makefile

    r453 r455  
    1515NANOSCALESRC = ./nanoscale
    1616
    17 LIB_NANOVIS = -ltcl8.4 -L/opt/render/lib -lGL -lglut -lglui -lGLEW -lCg -lCgGL -pthread -lstdc++
     17LIB_NANOVIS = -ltcl8.3 -L/opt/render/lib -lGL -lglut -lglui -lGLEW -lCg -lCgGL -pthread -lstdc++
    1818LIB_CLIENT = -L/opt/render/lib -lGL -lglut -pthread -lstdc++
    19 INCLUDES = -I../core -I/opt/render/include -I/autohome/u76/qiaow/Cg/usr/include
     19INCLUDES = -I../../src2/core -I/opt/render/include -I/autohome/u76/qiaow/Cg/usr/include
    2020CFLAG = -g -c $(INCLUDES)
    2121
     
    2626
    2727nanovis: $(OBJ_NANOVIS)
    28         gcc -g -o nanovis $(OBJ_NANOVIS) $(LIB_NANOVIS) ../core/*.o
     28        gcc -g -o nanovis $(OBJ_NANOVIS) $(LIB_NANOVIS) ../../src2/core/*.o
    2929
    3030ColorGradient.o: Color.o $(TFSRC)/ColorGradient.cpp
  • trunk/gui/vizservers/nanovis/PlaneRenderer.cpp

    r432 r455  
    5656}
    5757
     58void
     59PlaneRenderer::remove_plane(int index) {
     60  vector<Texture2D*>::iterator piter = plane.begin()+index;
     61  vector<TransferFunction*>::iterator tfiter = tf.begin()+index;
     62
     63  plane.erase(piter);
     64  tf.erase(tfiter);
     65
     66  n_planes--;
     67}
     68
    5869
    5970void PlaneRenderer::render(){
    60   if(n_planes == 0)
     71  if (n_planes == 0)
    6172    return;
    6273
     
    108119}
    109120
    110 void PlaneRenderer::set_active_plane(int index) { active_plane = index; }
    111 void PlaneRenderer::set_screen_size(int w, int h) { render_width = w;  render_height = h;}
     121void
     122 PlaneRenderer::set_active_plane(int index) {
     123  active_plane = index;
     124}
    112125
     126void
     127PlaneRenderer::set_screen_size(int w, int h) {
     128  render_width = w;
     129  render_height = h;
     130}
  • trunk/gui/vizservers/nanovis/PlaneRenderer.h

    r432 r455  
    6363                                                //we require a transfer function when a
    6464                                                //plane is added.
     65  void remove_plane(int index);
    6566  void set_active_plane(int index);             //set the active plane to be rendered
    6667  void set_screen_size(int w, int h);           //change the rendering size
  • trunk/gui/vizservers/nanovis/Volume.cpp

    r449 r455  
    2020Volume::Volume(float x, float y, float z,
    2121                int w, int h, int d, float s,
    22                 int n, float* data):
     22                int n, float* data, double v0, double v1):
    2323        width(w),
    2424        height(h),
     
    2626        size(s),
    2727        n_components(n),
     28        vmin(v0),
     29        vmax(v1),
    2830        enabled(true),
    2931        n_slice(256), // default value
  • trunk/gui/vizservers/nanovis/Volume.h

    r449 r455  
    4646
    4747        Texture3D* tex; //OpenGL texture storing the volume
     48    double vmin;    //minimum (unscaled) value in data
     49    double vmax;    //maximum (unscaled) value in data
     50
    4851        float specular; //specular lighting parameter
    4952        float diffuse;  //diffuse lighting parameter
     
    7982        Volume(float x, float y, float z,
    8083                        int width, int height, int depth, float size,
    81                         int n_component, float* data);
     84                        int n_component, float* data, double vmin, double vmax);
    8285        ~Volume();
    8386       
     
    8790        bool is_enabled();
    8891        Vector3* get_location();
     92
     93        double range_min() { return vmin; }
     94        double range_max() { return vmax; }
    8995
    9096        void set_n_slice(int val); //set number of slices
  • trunk/gui/vizservers/nanovis/VolumeRenderer.cpp

    r452 r455  
    7474    }
    7575  }
     76}
     77
     78TransferFunction*
     79VolumeRenderer::get_volume_shading(Volume* _vol)
     80{
     81  for (int i=0; i < volume.size(); i++) {
     82    if (volume[i] == _vol) {
     83      return tf[i];
     84    }
     85  }
     86  return NULL;
    7687}
    7788
     
    891902
    892903  //x
    893   glColor3f(0., 0., 0.5);
    894 
    895   int length = strlen(vol->label[0]);
     904  glColor3f(0.5, 0.5, 0.5);
     905
     906  int length = vol->label[0].size();
    896907  glPushMatrix();
    897908 
    898     glTranslatef(.5*vol->aspect_ratio_width, vol->aspect_ratio_height, -0.2*vol->aspect_ratio_depth);
     909    glTranslatef(.5*vol->aspect_ratio_width, vol->aspect_ratio_height, -0.1*vol->aspect_ratio_depth);
    899910    glRotatef(180, 0, 0, 1);
    900911    glRotatef(90, 1, 0, 0);
    901912
    902     glScalef(0.00035, 0.00035, 0.00035);
     913    glScalef(0.0008, 0.0008, 0.0008);
    903914    for(int i=0; i<length; i++){
    904       glutStrokeCharacter(GLUT_STROKE_ROMAN, vol->label[0][i]);
     915      glutStrokeCharacter(GLUT_STROKE_ROMAN, vol->label[0].c_str()[i]);
    905916      glTranslatef(0.04, 0., 0.);
    906917    }
     
    908919
    909920  //y
    910   length = strlen(vol->label[1]);
     921  length = vol->label[1].size();
    911922  glPushMatrix();
    912     glTranslatef(vol->aspect_ratio_width, 0.5*vol->aspect_ratio_height, -0.2*vol->aspect_ratio_depth);
     923    glTranslatef(vol->aspect_ratio_width, 0.5*vol->aspect_ratio_height, -0.1*vol->aspect_ratio_depth);
    913924    glRotatef(90, 0, 1, 0);
    914925    glRotatef(90, 0, 0, 1);
    915926
    916     glScalef(0.00035, 0.00035, 0.00035);
     927    glScalef(0.0008, 0.0008, 0.0008);
    917928    for(int i=0; i<length; i++){
    918       glutStrokeCharacter(GLUT_STROKE_ROMAN, vol->label[1][i]);
     929      glutStrokeCharacter(GLUT_STROKE_ROMAN, vol->label[1].c_str()[i]);
    919930      glTranslatef(0.04, 0., 0.);
    920931    }
     
    923934
    924935  //z
    925   length = strlen(vol->label[2]);
     936  length = vol->label[2].size();
    926937  glPushMatrix();
    927938    glTranslatef(0., 1.*vol->aspect_ratio_height, 0.5*vol->aspect_ratio_depth);
    928939    glRotatef(90, 0, 1, 0);
    929940
    930     glScalef(0.00035, 0.00035, 0.00035);
     941    glScalef(0.0008, 0.0008, 0.0008);
    931942    for(int i=0; i<length; i++){
    932       glutStrokeCharacter(GLUT_STROKE_ROMAN, vol->label[2][i]);
     943      glutStrokeCharacter(GLUT_STROKE_ROMAN, vol->label[2].c_str()[i]);
    933944      glTranslatef(0.04, 0., 0.);
    934945    }
  • trunk/gui/vizservers/nanovis/VolumeRenderer.h

    r451 r455  
    8787                                                //volume is added.
    8888  void shade_volume(Volume* _vol, TransferFunction* _tf);
     89  TransferFunction* get_volume_shading(Volume* _vol);
     90
    8991  void render(int volume_index);
    9092  void render_all();    //render all enabled volumes;
  • trunk/gui/vizservers/nanovis/nanovis.cpp

    r453 r455  
    9494void get_slice_vectors();
    9595Rappture::Outcome load_volume_file(int index, char *fname);
    96 void load_volume(int index, int width, int height, int depth, int n_component, float* data);
     96void load_volume(int index, int width, int height, int depth, int n_component, float* data, double vmin, double vmax);
    9797TransferFunction* get_transfunc(char *name);
     98void resize_offscreen_buffer(int w, int h);
     99void bmp_header_add_int(unsigned char* header, int& pos, int data);
     100void bmp_write(const char* cmd);
    98101
    99102ParticleSystem* psys;
     
    149152static int CameraCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    150153static int CutplaneCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    151 static int ClearCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     154static int LegendCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    152155static int ScreenCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    153156static int TransfuncCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    154157static int VolumeCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    155 static int VolumeLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    156 static int VolumeMoveCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    157 static int RefreshCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    158158static int PlaneNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
    159159static int PlaneLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     
    367367}
    368368
    369 void resize_offscreen_buffer(int w, int h);
    370 
    371 //change screen size
     369/*
     370 * ----------------------------------------------------------------------
     371 * CLIENT COMMAND:
     372 *   legend <volumeIndex> <width> <height>
     373 *
     374 * Clients use this to generate a legend image for the specified
     375 * transfer function.  The legend image is a color gradient from 0
     376 * to one, drawn in the given transfer function.  The resulting image
     377 * is returned in the size <width> x <height>.
     378 * ----------------------------------------------------------------------
     379 */
     380static int
     381LegendCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     382{
     383    if (argc != 4) {
     384        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     385            " transfunc width height\"", (char*)NULL);
     386        return TCL_ERROR;
     387    }
     388
     389    TransferFunction *tf = NULL;
     390    int ivol;
     391    if (Tcl_GetInt(interp, argv[1], &ivol) != TCL_OK) {
     392        return TCL_ERROR;
     393    }
     394    if (ivol < n_volumes) {
     395        tf = vol_render->get_volume_shading(volume[ivol]);
     396    }
     397    if (tf == NULL) {
     398        Tcl_AppendResult(interp, "transfer function not defined for volume ", argv[1], (char*)NULL);
     399        return TCL_ERROR;
     400    }
     401
     402    int old_width = win_width;
     403    int old_height = win_height;
     404
     405    int width, height;
     406    if (Tcl_GetInt(interp, argv[2], &width) != TCL_OK) {
     407        return TCL_ERROR;
     408    }
     409    if (Tcl_GetInt(interp, argv[3], &height) != TCL_OK) {
     410        return TCL_ERROR;
     411    }
     412
     413    resize_offscreen_buffer(width, height);
     414
     415    // generate data for the legend
     416    float data[512];
     417    for (int i=0; i < 256; i++) {
     418        data[i] = data[i+256] = (float)(i/255.0);
     419    }
     420    plane[0] = new Texture2D(256, 2, GL_FLOAT, GL_LINEAR, 1, data);
     421    int index = plane_render->add_plane(plane[0], tf);
     422    plane_render->set_active_plane(index);
     423    plane_render->set_screen_size(width, height);
     424    plane_render->render();
     425
     426    glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, screen_buffer);
     427
     428    std::ostringstream result;
     429    result << "nv>legend " << argv[1];
     430    result << " " << volume[ivol]->range_min();
     431    result << " " << volume[ivol]->range_max();
     432    bmp_write(result.str().c_str());
     433    write(0, "\n", 1);
     434
     435    plane_render->remove_plane(index);
     436    resize_offscreen_buffer(old_width, old_height);
     437
     438    return TCL_OK;
     439}
     440
     441
     442
     443/*
     444 * ----------------------------------------------------------------------
     445 * CLIENT COMMAND:
     446 *   screen <width> <height>
     447 *
     448 * Clients send this command to set the size of the rendering area.
     449 * Future images are generated at the specified width/height.
     450 * ----------------------------------------------------------------------
     451 */
    372452static int
    373453ScreenCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    374454{
    375 
    376         fprintf(stderr, "screen size cmd\n");
    377         double w, h;
    378 
    379         if (argc != 3) {
    380                 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    381                         " width height \"", (char*)NULL);
    382                 return TCL_ERROR;
    383         }
    384         if (Tcl_GetDouble(interp, argv[1], &w) != TCL_OK) {
    385                 return TCL_ERROR;
    386         }
    387         if (Tcl_GetDouble(interp, argv[2], &h) != TCL_OK) {
    388                 return TCL_ERROR;
    389         }
    390 
    391         resize_offscreen_buffer((int)w, (int)h);
    392 fprintf(stdin,"new screen size: %d %d\n",w,h);
    393         return TCL_OK;
    394 }
    395 
    396 
    397 static int
    398 RefreshCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    399 {
    400   fprintf(stderr, "refresh cmd\n");
    401   return TCL_OK;
    402 }
    403 
    404 void set_object(float x, float y, float z){
    405   live_obj_x = x;
    406   live_obj_y = y;
    407   live_obj_z = z;
     455    int w, h;
     456
     457    if (argc != 3) {
     458        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     459            " width height\"", (char*)NULL);
     460        return TCL_ERROR;
     461    }
     462    if (Tcl_GetInt(interp, argv[1], &w) != TCL_OK) {
     463        return TCL_ERROR;
     464    }
     465    if (Tcl_GetInt(interp, argv[2], &h) != TCL_OK) {
     466        return TCL_ERROR;
     467    }
     468    resize_offscreen_buffer(w, h);
     469
     470    return TCL_OK;
    408471}
    409472
     
    9531016}
    9541017
    955 static int
    956 VolumeLinkCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    957 {
    958   fprintf(stderr, "link volume command\n");
    959 
    960   double volume_index, tf_index;
    961 
    962   if (argc != 3) {
    963     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    964         " volume_index tf_index \"", (char*)NULL);
    965     return TCL_ERROR;
    966   }
    967   if (Tcl_GetDouble(interp, argv[1], &volume_index) != TCL_OK) {
    968         return TCL_ERROR;
    969   }
    970   if (Tcl_GetDouble(interp, argv[2], &tf_index) != TCL_OK) {
    971         return TCL_ERROR;
    972   }
    973 
    974   //vol_render->add_volume(volume[(int)volume_index], tf[(int)tf_index]);
    975 
    976   return TCL_OK;
    977 }
    978 
    979 
    980 static int
    981 VolumeResizeCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    982 {
    983   fprintf(stderr, "resize drawing size of the volume command\n");
    984 
    985   double volume_index, size;
    986 
    987   if (argc != 3) {
    988     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    989                 " volume_index size \"", (char*)NULL);
    990     return TCL_ERROR;
    991   }
    992   if (Tcl_GetDouble(interp, argv[1], &volume_index) != TCL_OK) {
    993         return TCL_ERROR;
    994   }
    995   if (Tcl_GetDouble(interp, argv[2], &size) != TCL_OK) {
    996         return TCL_ERROR;
    997   }
    998 
    999   volume[(int)volume_index]->set_size((float) size);
    1000   return TCL_OK;
    1001 }
    1002 
    1003 static int
    1004 VolumeMoveCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    1005 {
    1006 
    1007         fprintf(stderr, "move volume cmd\n");
    1008         double index, x, y, z;
    1009 
    1010         if (argc != 5) {
    1011                 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    1012                         " index x_coord y_coord z_coord\"", (char*)NULL);
    1013                 return TCL_ERROR;
    1014         }
    1015         if (Tcl_GetDouble(interp, argv[1], &index) != TCL_OK) {
    1016                 return TCL_ERROR;
    1017         }
    1018         if (Tcl_GetDouble(interp, argv[2], &x) != TCL_OK) {
    1019                 return TCL_ERROR;
    1020         }
    1021         if (Tcl_GetDouble(interp, argv[3], &y) != TCL_OK) {
    1022                 return TCL_ERROR;
    1023         }
    1024         if (Tcl_GetDouble(interp, argv[4], &z) != TCL_OK) {
    1025                 return TCL_ERROR;
    1026         }
    1027        
    1028         //set_object(x, y, z);
    1029         volume[(int)index]->move(Vector3(x, y, z));
    1030         return TCL_OK;
    1031 }
    1032 
    10331018/*
    10341019 * ----------------------------------------------------------------------
     
    11521137  fprintf(stderr, "load plane for 2D visualization command\n");
    11531138
    1154   double index, w, h;
     1139  int index, w, h;
    11551140
    11561141  if (argc != 4) {
     
    11591144    return TCL_ERROR;
    11601145  }
    1161   if (Tcl_GetDouble(interp, argv[1], &index) != TCL_OK) {
     1146  if (Tcl_GetInt(interp, argv[1], &index) != TCL_OK) {
    11621147        return TCL_ERROR;
    11631148  }
    1164   if (Tcl_GetDouble(interp, argv[2], &w) != TCL_OK) {
     1149  if (Tcl_GetInt(interp, argv[2], &w) != TCL_OK) {
    11651150        return TCL_ERROR;
    11661151  }
    1167   if (Tcl_GetDouble(interp, argv[3], &h) != TCL_OK) {
     1152  if (Tcl_GetInt(interp, argv[3], &h) != TCL_OK) {
    11681153        return TCL_ERROR;
    11691154  }
     
    11771162  }
    11781163 
    1179   plane[(int)index] = new Texture2D(w, h, GL_FLOAT, GL_LINEAR, 1, (float*)tmp);
     1164  plane[index] = new Texture2D(w, h, GL_FLOAT, GL_LINEAR, 1, (float*)tmp);
    11801165 
    11811166  delete[] tmp;
     
    11881173  fprintf(stderr, "link the plane to the 2D renderer command\n");
    11891174
    1190   double plane_index, tf_index;
     1175  int plane_index, tf_index;
    11911176
    11921177  if (argc != 3) {
     
    11951180    return TCL_ERROR;
    11961181  }
    1197   if (Tcl_GetDouble(interp, argv[1], &plane_index) != TCL_OK) {
     1182  if (Tcl_GetInt(interp, argv[1], &plane_index) != TCL_OK) {
    11981183        return TCL_ERROR;
    11991184  }
    1200   if (Tcl_GetDouble(interp, argv[2], &tf_index) != TCL_OK) {
     1185  if (Tcl_GetInt(interp, argv[2], &tf_index) != TCL_OK) {
    12011186        return TCL_ERROR;
    12021187  }
    12031188
    1204   //plane_render->add_plane(plane[(int)plane_index], tf[(int)tf_index]);
     1189  //plane_render->add_plane(plane[plane_index], tf[tf_index]);
    12051190
    12061191  return TCL_OK;
     
    12141199  fprintf(stderr, "enable a plane so the 2D renderer can render it command\n");
    12151200
    1216   double plane_index, mode;
     1201  int plane_index, mode;
    12171202
    12181203  if (argc != 3) {
     
    12211206    return TCL_ERROR;
    12221207  }
    1223   if (Tcl_GetDouble(interp, argv[1], &plane_index) != TCL_OK) {
     1208  if (Tcl_GetInt(interp, argv[1], &plane_index) != TCL_OK) {
    12241209        return TCL_ERROR;
    12251210  }
    1226   if (Tcl_GetDouble(interp, argv[2], &mode) != TCL_OK) {
     1211  if (Tcl_GetInt(interp, argv[2], &mode) != TCL_OK) {
    12271212        return TCL_ERROR;
    12281213  }
     
    13971382        }
    13981383
    1399         load_volume(index, nx, ny, nz, 3, data);
     1384        load_volume(index, nx, ny, nz, 3, data, vmin, vmax);
    14001385        delete [] data;
    14011386    } else {
     
    16241609            }
    16251610
    1626             load_volume(index, nx, ny, nz, 4, data);
     1611            load_volume(index, nx, ny, nz, 4, data,
     1612                field.valueMin(), field.valueMax());
     1613
    16271614            delete [] data;
    16281615
     
    17281715            }
    17291716
    1730             load_volume(index, nx, ny, nz, 4, data);
     1717            load_volume(index, nx, ny, nz, 4, data,
     1718                field.valueMin(), field.valueMax());
     1719
    17311720            delete [] data;
    17321721        }
     
    17551744 * width, height and depth: number of points in each dimension
    17561745 */
    1757 void load_volume(int index, int width, int height, int depth, int n_component, float* data){
     1746void load_volume(int index, int width, int height, int depth,
     1747    int n_component, float* data, double vmin, double vmax) {
    17581748  if(volume[index]!=0){
    17591749    delete volume[index];
     
    17611751  }
    17621752
    1763   volume[index] = new Volume(0.f, 0.f, 0.f, width, height, depth, 1.,  n_component, data);
     1753  volume[index] = new Volume(0.f, 0.f, 0.f, width, height, depth, 1.,  n_component, data, vmin, vmax);
    17641754  assert(volume[index]!=0);
    17651755
     
    21322122        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
    21332123
     2124    // request the legend for a plot (transfer function)
     2125    Tcl_CreateCommand(interp, "legend", LegendCmd,
     2126        (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
     2127
    21342128    // change the size of the screen (size of picture generated)
    21352129    Tcl_CreateCommand(interp, "screen", ScreenCmd,
     
    21492143        fprintf(stdin, Tcl_GetStringResult(interp));
    21502144    }
    2151 
    2152 
    2153   //link an EXISTING volume and transfer function to the volume renderer.
    2154   //Only after being added, can a volume be rendered. This command does not create a volume nor a transfer function
    2155   Tcl_CreateCommand(interp, "volume_link", VolumeLinkCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    2156   //move an volume
    2157   Tcl_CreateCommand(interp, "volume_move", VolumeMoveCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    2158   //resize volume
    2159   Tcl_CreateCommand(interp, "volume_resize", VolumeResizeCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    2160 
    2161   //refresh the screen (render again)
    2162   Tcl_CreateCommand(interp, "refresh", RefreshCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    21632145}
    21642146
     
    22182200    header[pos++] = (data >> 16) & 0xff;
    22192201    header[pos++] = (data >> 24) & 0xff;
     2202}
     2203
     2204void
     2205bmp_write(const char* cmd)
     2206{
     2207    unsigned char header[54];
     2208    int pos = 0;
     2209    header[pos++] = 'B';
     2210    header[pos++] = 'M';
     2211
     2212    // file size in bytes
     2213    int fsize = win_width*win_height*3 + sizeof(header);
     2214    bmp_header_add_int(header, pos, fsize);
     2215
     2216    // reserved value (must be 0)
     2217    bmp_header_add_int(header, pos, 0);
     2218
     2219    // offset in bytes to start of bitmap data
     2220    bmp_header_add_int(header, pos, sizeof(header));
     2221
     2222    // size of the BITMAPINFOHEADER
     2223    bmp_header_add_int(header, pos, 40);
     2224
     2225    // width of the image in pixels
     2226    bmp_header_add_int(header, pos, win_width);
     2227
     2228    // height of the image in pixels
     2229    bmp_header_add_int(header, pos, win_height);
     2230
     2231    // 1 plane + 24 bits/pixel << 16
     2232    bmp_header_add_int(header, pos, 1572865);
     2233
     2234    // no compression
     2235    // size of image for compression
     2236    bmp_header_add_int(header, pos, 0);
     2237    bmp_header_add_int(header, pos, 0);
     2238
     2239    // x pixels per meter
     2240    // y pixels per meter
     2241    bmp_header_add_int(header, pos, 0);
     2242    bmp_header_add_int(header, pos, 0);
     2243
     2244    // number of colors used (0 = compute from bits/pixel)
     2245    // number of important colors (0 = all colors important)
     2246    bmp_header_add_int(header, pos, 0);
     2247    bmp_header_add_int(header, pos, 0);
     2248
     2249    // BE CAREFUL: BMP format wants BGR ordering for screen data
     2250    for (int i=0; i < 3*win_width*win_height; i += 3) {
     2251        unsigned char tmp = screen_buffer[i+2];
     2252        screen_buffer[i+2] = screen_buffer[i];
     2253        screen_buffer[i] = tmp;
     2254    }
     2255
     2256    std::ostringstream result;
     2257    result << cmd << " " << fsize << "\n";
     2258    write(0, result.str().c_str(), result.str().size());
     2259
     2260    write(0, header, sizeof(header));
     2261    write(0, screen_buffer, 3*win_width*win_height);
    22202262}
    22212263
     
    22952337    write(0, rle, rle_size);    //unsigned byte
    22962338#else
    2297     unsigned char header[54];
    2298     int pos = 0;
    2299     header[pos++] = 'B';
    2300     header[pos++] = 'M';
    2301 
    2302     // file size in bytes
    2303     int fsize = win_width*win_height*3 + sizeof(header);
    2304     bmp_header_add_int(header, pos, fsize);
    2305 
    2306     // reserved value (must be 0)
    2307     bmp_header_add_int(header, pos, 0);
    2308 
    2309     // offset in bytes to start of bitmap data
    2310     bmp_header_add_int(header, pos, sizeof(header));
    2311 
    2312     // size of the BITMAPINFOHEADER
    2313     bmp_header_add_int(header, pos, 40);
    2314 
    2315     // width of the image in pixels
    2316     bmp_header_add_int(header, pos, win_width);
    2317 
    2318     // height of the image in pixels
    2319     bmp_header_add_int(header, pos, win_height);
    2320 
    2321     // 1 plane + 24 bits/pixel << 16
    2322     bmp_header_add_int(header, pos, 1572865);
    2323 
    2324     // no compression
    2325     // size of image for compression
    2326     bmp_header_add_int(header, pos, 0);
    2327     bmp_header_add_int(header, pos, 0);
    2328 
    2329     // x pixels per meter
    2330     // y pixels per meter
    2331     bmp_header_add_int(header, pos, 0);
    2332     bmp_header_add_int(header, pos, 0);
    2333 
    2334     // number of colors used (0 = compute from bits/pixel)
    2335     // number of important colors (0 = all colors important)
    2336     bmp_header_add_int(header, pos, 0);
    2337     bmp_header_add_int(header, pos, 0);
    2338 
    2339     // BE CAREFUL: BMP format wants BGR ordering for screen data
    2340     for (int i=0; i < 3*win_width*win_height; i += 3) {
    2341         unsigned char tmp = screen_buffer[i+2];
    2342         screen_buffer[i+2] = screen_buffer[i];
    2343         screen_buffer[i] = tmp;
    2344     }
    2345 
    2346     std::ostringstream result;
    2347     result << "nv>image -bytes " << fsize << "\n";
    2348     write(0, result.str().c_str(), result.str().size());
    2349 
    2350     write(0, header, sizeof(header));
    2351     write(0, screen_buffer, 3*win_width*win_height);
     2339    bmp_write("nv>image -bytes");
    23522340#endif
    23532341}
Note: See TracChangeset for help on using the changeset viewer.