Changeset 427


Ignore:
Timestamp:
May 3, 2006 3:20:33 PM (18 years ago)
Author:
mmc
Message:

Integrated Wei's latest changes with the commands that Rappture is
using to view 3D volumes.

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

Legend:

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

    r415 r427  
    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../src2/core -I/opt/render/include -I/autohome/u76/qiaow/Cg/usr/include
    20 CFLAG = -g -c -Wall $(INCLUDES)
     19INCLUDES = -I../../src2/core -I/opt/render/include -I/autohome/u76/qiaow/Cg/usr/include
     20CFLAG = -g -c $(INCLUDES)
    2121
    22 all: nanovis
    23 #  simclient
     22all: nanovis
    2423
    2524clean:
     
    2726
    2827nanovis: $(OBJ_NANOVIS)
    29         gcc -g -o nanovis $(OBJ_NANOVIS) $(LIB_NANOVIS) ../src2/core/*.o
     28        gcc -g -o nanovis $(OBJ_NANOVIS) $(LIB_NANOVIS) ../../src2/core/*.o
    3029
    3130ColorGradient.o: Color.o $(TFSRC)/ColorGradient.cpp
  • trunk/gui/vizservers/nanovis/config.h

    r396 r427  
    1616
    1717#define NV40      //Uncomment if using 6 series card. By default we assume older card the 5xxx series
    18 //#define XINETD  //enable render server
     18#define XINETD  //enable render server
    1919//#define EVENTLOG  //enable event logging
    2020//#define DO_RLE  //do run length compression
  • trunk/gui/vizservers/nanovis/nanovis.cpp

    r426 r427  
    55 * ======================================================================
    66 *  AUTHOR:  Wei Qiao <qiaow@purdue.edu>
     7 *           Michael McLennan <mmclennan@purdue.edu>
    78 *           Purdue Rendering and Perceptualization Lab (PURPL)
    89 *
     
    1819#include <fstream>
    1920#include <iostream>
     21#include <sstream>
    2022#include <string>
    2123#include <sys/time.h>
     
    3840Camera* cam;
    3941
     42// color table for built-in transfer function editor
    4043float color_table[256][4];     
     44
     45// default transfer function
     46float def_tf[24] = {
     47  1, 1, 1, 0.5,  // red
     48  1, 1, 0, 0.5,  // yellow
     49  0, 1, 0, 0.5,  // green
     50  0, 1, 1, 0.5,  // cyan
     51  0, 0, 1, 0.5,  // blue
     52  1, 0, 1, 0.5,  // magenta
     53};
     54int def_tf_size = 6;
    4155
    4256#ifdef XINETD
     
    6175Lic* lic;
    6276
    63 unsigned char* screen_buffer = new unsigned char[3*win_width*win_height+1];     //buffer to store data read from the screen
     77unsigned char* screen_buffer = NULL;
    6478NVISid final_fbo, final_color_tex, final_depth_rb;      //frame buffer for final rendering
    6579
     
    95109using namespace std;
    96110
    97 static void set_camera(float x_angle, float y_angle, float z_angle){
    98   live_rot_x = x_angle;
    99   live_rot_y = y_angle;
    100   live_rot_z = z_angle;
    101 }
    102 
    103111
    104112// Tcl interpreter for incoming messages
    105113static Tcl_Interp *interp;
    106114
    107 //Tcl callback functions
     115static int CameraCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     116static int CutplaneCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     117static int ClearCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     118static int ScreenResizeCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     119static int TransferFunctionNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     120static int TransferFunctionUpdateCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     121static int VolumeNewCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     122static int VolumeLinkCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     123static int VolumeMoveCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     124static int VolumeEnableCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     125static int OutlineCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     126static int RefreshCmd _ANSI_ARGS_((ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[]));
     127
     128static int DecodeAxis _ANSI_ARGS_((Tcl_Interp *interp, char *str, int *valPtr));
     129
     130/*
     131 * ----------------------------------------------------------------------
     132 * CLIENT COMMAND:
     133 *   camera aim <x0> <y0> <z0>
     134 *   camera angle <xAngle> <yAngle> <zAngle>
     135 *   camera zoom <factor>
     136 *
     137 * Clients send these commands to manipulate the camera.  The "angle"
     138 * operation controls the angle of the camera around the focal point.
     139 * The "zoom" operation sets the zoom factor, moving the camera in
     140 * and out.
     141 * ----------------------------------------------------------------------
     142 */
    108143static int
    109144CameraCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    110145{
    111 
    112         fprintf(stderr, "camera cmd\n");
    113         double angle_x, angle_y, angle_z, aim_x, aim_y, aim_z;
    114 
    115         if (argc != 7) {
     146        if (argc < 2) {
    116147                Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    117                         " x_angle y_angle z_angle aim_x aim_y aim_z\"", (char*)NULL);
     148                        " option arg arg...\"", (char*)NULL);
    118149                return TCL_ERROR;
     150    }
     151
     152    char c = *argv[1];
     153        if (c == 'a' && strcmp(argv[1],"angle") == 0) {
     154        if (argc != 5) {
     155                    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     156                            " angle xangle yangle zangle\"", (char*)NULL);
     157                    return TCL_ERROR;
     158        }
     159
     160        double xangle, yangle, zangle;
     161            if (Tcl_GetDouble(interp, argv[2], &xangle) != TCL_OK) {
     162                    return TCL_ERROR;
     163            }
     164            if (Tcl_GetDouble(interp, argv[3], &yangle) != TCL_OK) {
     165                    return TCL_ERROR;
     166            }
     167            if (Tcl_GetDouble(interp, argv[4], &zangle) != TCL_OK) {
     168                    return TCL_ERROR;
     169            }
     170            cam->rotate(xangle, yangle, zangle);
     171
     172            return TCL_OK;
    119173        }
    120         if (Tcl_GetDouble(interp, argv[1], &angle_x) != TCL_OK) {
    121                 return TCL_ERROR;
     174        else if (c == 'a' && strcmp(argv[1],"aim") == 0) {
     175        if (argc != 5) {
     176                    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     177                            " aim x y z\"", (char*)NULL);
     178                    return TCL_ERROR;
     179        }
     180
     181        double x0, y0, z0;
     182            if (Tcl_GetDouble(interp, argv[2], &x0) != TCL_OK) {
     183                    return TCL_ERROR;
     184            }
     185            if (Tcl_GetDouble(interp, argv[3], &y0) != TCL_OK) {
     186                    return TCL_ERROR;
     187            }
     188            if (Tcl_GetDouble(interp, argv[4], &z0) != TCL_OK) {
     189                    return TCL_ERROR;
     190            }
     191            cam->aim(x0, y0, z0);
     192
     193            return TCL_OK;
    122194        }
    123         if (Tcl_GetDouble(interp, argv[2], &angle_y) != TCL_OK) {
    124                 return TCL_ERROR;
    125         }
    126         if (Tcl_GetDouble(interp, argv[3], &angle_z) != TCL_OK) {
    127                 return TCL_ERROR;
    128         }
    129         if (Tcl_GetDouble(interp, argv[4], &aim_x) != TCL_OK) {
    130                 return TCL_ERROR;
    131         }
    132         if (Tcl_GetDouble(interp, argv[5], &aim_y) != TCL_OK) {
    133                 return TCL_ERROR;
    134         }
    135         if (Tcl_GetDouble(interp, argv[6], &aim_z) != TCL_OK) {
    136                 return TCL_ERROR;
    137         }
    138 
    139         //set_camera(x, y, z);
    140         cam->rotate(angle_x, angle_y, angle_z);
    141         cam->aim(aim_x, aim_y, aim_z);
    142         return TCL_OK;
    143 }
    144 
     195        else if (c == 'z' && strcmp(argv[1],"zoom") == 0) {
     196        if (argc != 3) {
     197                    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     198                            " zoom factor\"", (char*)NULL);
     199                    return TCL_ERROR;
     200        }
     201
     202        double zoom;
     203            if (Tcl_GetDouble(interp, argv[2], &zoom) != TCL_OK) {
     204                    return TCL_ERROR;
     205            }
     206
     207        live_obj_z = -2.5/zoom;
     208                cam->move(live_obj_x, live_obj_y, live_obj_z);
     209
     210            return TCL_OK;
     211    }
     212
     213        Tcl_AppendResult(interp, "bad option \"", argv[1],
     214                "\": should be aim, angle, or zoom", (char*)NULL);
     215        return TCL_ERROR;
     216}
     217
     218/*
     219 * ----------------------------------------------------------------------
     220 * CLIENT COMMAND:
     221 *   cutplane state on|off <axis> ?<volume>...?
     222 *   cutplane position <relvalue> <axis> ?<volume>...?
     223 *
     224 * Clients send these commands to manipulate the cutplanes in one or
     225 * more data volumes.  The "state" command turns a cutplane on or
     226 * off.  The "position" command changes the position to a relative
     227 * value in the range 0-1.  The <axis> can be x, y, or z.  These
     228 * operations are applied to the volumes represented by one or more
     229 * <volume> indices.  If no volumes are specified, then all volumes
     230 * are updated.
     231 * ----------------------------------------------------------------------
     232 */
     233static int
     234CutplaneCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
     235{
     236    if (argc < 2) {
     237        Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     238            " option ?arg arg...?\"", (char*)NULL);
     239        return TCL_ERROR;
     240    }
     241
     242    char c = *argv[1];
     243    if (c == 's' && strcmp(argv[1],"state") == 0) {
     244        if (argc < 4) {
     245            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     246                " state on|off axis ?volume ...? \"", (char*)NULL);
     247            return TCL_ERROR;
     248        }
     249
     250        int state;
     251        if (Tcl_GetBoolean(interp, argv[2], &state) != TCL_OK) {
     252            return TCL_ERROR;
     253        }
     254
     255        int axis;
     256        if (DecodeAxis(interp, argv[3], &axis) != TCL_OK) {
     257            return TCL_ERROR;
     258        }
     259
     260        int ivol;
     261        if (argc < 5) {
     262            for (ivol=0; ivol < n_volumes; ivol++) {
     263                if (state) {
     264                    volume[ivol]->enable_cutplane(axis);
     265                } else {
     266                    volume[ivol]->disable_cutplane(axis);
     267                }
     268            }
     269        } else {
     270            for (int n=4; n < argc; n++) {
     271                if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     272                    return TCL_ERROR;
     273                }
     274                if (ivol < 0 || ivol > n_volumes) {
     275                    Tcl_AppendResult(interp, "bad volume index \"", argv[n],
     276                        "\": out of range", (char*)NULL);
     277                    return TCL_ERROR;
     278                }
     279                if (state) {
     280                    volume[ivol]->enable_cutplane(axis);
     281                } else {
     282                    volume[ivol]->disable_cutplane(axis);
     283                }
     284            }
     285        }
     286        return TCL_OK;
     287    }
     288    else if (c == 'p' && strcmp(argv[1],"position") == 0) {
     289        if (argc < 4) {
     290            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
     291                " position relval axis ?volume ...? \"", (char*)NULL);
     292            return TCL_ERROR;
     293        }
     294
     295        double relval;
     296        if (Tcl_GetDouble(interp, argv[2], &relval) != TCL_OK) {
     297            return TCL_ERROR;
     298        }
     299
     300        int axis;
     301        if (DecodeAxis(interp, argv[3], &axis) != TCL_OK) {
     302            return TCL_ERROR;
     303        }
     304
     305        int ivol;
     306        if (argc < 5) {
     307            for (ivol=0; ivol < n_volumes; ivol++) {
     308                volume[ivol]->move_cutplane(axis, (float)relval);
     309            }
     310        } else {
     311            for (int n=4; n < argc; n++) {
     312                if (Tcl_GetInt(interp, argv[n], &ivol) != TCL_OK) {
     313                    return TCL_ERROR;
     314                }
     315                if (ivol < 0 || ivol > n_volumes) {
     316                    Tcl_AppendResult(interp, "bad volume index \"", argv[n],
     317                        "\": out of range", (char*)NULL);
     318                    return TCL_ERROR;
     319                }
     320                volume[ivol]->move_cutplane(axis, (float)relval);
     321            }
     322        }
     323        return TCL_OK;
     324    }
     325
     326    Tcl_AppendResult(interp, "bad option \"", argv[1],
     327        "\": should be position or state", (char*)NULL);
     328    return TCL_ERROR;
     329}
     330
     331/*
     332 * ----------------------------------------------------------------------
     333 * FUNCTION: DecodeAxis()
     334 *
     335 * Used internally to decode an axis value from a string ("x", "y",
     336 * or "z") to its index (0, 1, or 2).  Returns TCL_OK if successful,
     337 * along with a value in valPtr.  Otherwise, it returns TCL_ERROR
     338 * and an error message in the interpreter.
     339 * ----------------------------------------------------------------------
     340 */
     341static int
     342DecodeAxis(Tcl_Interp *interp, char *str, int *valPtr)
     343{
     344    if (strcmp(str,"x") == 0) {
     345        *valPtr = 0;
     346        return TCL_OK;
     347    }
     348    else if (strcmp(str,"y") == 0) {
     349        *valPtr = 1;
     350        return TCL_OK;
     351    }
     352    else if (strcmp(str,"z") == 0) {
     353        *valPtr = 2;
     354        return TCL_OK;
     355    }
     356    Tcl_AppendResult(interp, "bad axis \"", str,
     357        "\": should be x, y, or z", (char*)NULL);
     358    return TCL_ERROR;
     359}
    145360
    146361void resize_offscreen_buffer(int w, int h);
     
    167382
    168383        resize_offscreen_buffer(w, h);
     384fprintf(stdin,"new screen size: %d %d\n",w,h);
    169385        return TCL_OK;
    170386}
     
    372588        //set_object(x, y, z);
    373589        volume[(int)index]->move(Vector3(x, y, z));
    374         return TCL_OK;
    375 }
    376 
    377 
    378 static int
    379 CutMoveCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    380 {
    381 
    382         fprintf(stderr, "move cutplane cmd\n");
    383         double volume_index, cut_index, location;
    384 
    385         if (argc != 4) {
    386                 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    387                         " vol_index cut_index cut_location\"", (char*)NULL);
    388                 return TCL_ERROR;
    389         }
    390         if (Tcl_GetDouble(interp, argv[1], &volume_index) != TCL_OK) {
    391                 return TCL_ERROR;
    392         }
    393         if (Tcl_GetDouble(interp, argv[2], &cut_index) != TCL_OK) {
    394                 return TCL_ERROR;
    395         }
    396         if (Tcl_GetDouble(interp, argv[3], &location) != TCL_OK) {
    397                 return TCL_ERROR;
    398         }
    399        
    400         volume[(int)volume_index]->move_cutplane((int)cut_index, (float)location);
    401         return TCL_OK;
    402 }
    403 
    404 
    405 static int
    406 CutEnableCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    407 {
    408   fprintf(stderr, "cutplane enable/disable command\n");
    409 
    410   double volume_index, cut_index, mode;
    411 
    412   if (argc != 4) {
    413     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
    414                 " volume_index cut_index mode\"", (char*)NULL);
    415     return TCL_ERROR;
    416   }
    417   if (Tcl_GetDouble(interp, argv[1], &volume_index) != TCL_OK) {
    418         return TCL_ERROR;
    419   }
    420   if (Tcl_GetDouble(interp, argv[2], &cut_index) != TCL_OK) {
    421         return TCL_ERROR;
    422   }
    423   if (Tcl_GetDouble(interp, argv[3], &mode) != TCL_OK) {
    424         return TCL_ERROR;
    425   }
    426 
    427   if(mode==0)
    428     volume[(int)volume_index]->disable_cutplane((int)cut_index);
    429   else
    430     volume[(int)volume_index]->enable_cutplane((int)cut_index);
    431 
    432   return TCL_OK;
    433 }
    434 
    435 static int
    436 HelloCmd(ClientData cdata, Tcl_Interp *interp, int argc, CONST84 char *argv[])
    437 {
    438         //send back 4 bytes as confirmation
    439         char ack[4]="ACK";
    440         fprintf(stderr, "wrote %d\n", write(fileno(stdout), ack, 4));
    441         fflush(stdout);
    442590        return TCL_OK;
    443591}
     
    9921140//resize the offscreen buffer
    9931141void resize_offscreen_buffer(int w, int h){
    994   delete[] screen_buffer;
    995 
    9961142  win_width = w;
    9971143  win_height = h;
    9981144
     1145  if (screen_buffer) {
     1146      delete[] screen_buffer;
     1147  }
    9991148  screen_buffer = new unsigned char[3*win_width*win_height+1];
    10001149
     
    10061155  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, final_depth_rb);
    10071156  glDeleteRenderbuffersEXT(1, &final_depth_rb);
     1157fprintf(stdin,"  after glDeleteRenderbuffers\n");
    10081158
    10091159  //change the camera setting
     
    10141164  glGenTextures(1, &final_color_tex);
    10151165  glGenRenderbuffersEXT(1, &final_depth_rb);
     1166fprintf(stdin,"  after glGenRenderbuffers\n");
    10161167
    10171168  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, final_fbo);
     
    10311182                            GL_COLOR_ATTACHMENT0_EXT,
    10321183                            GL_TEXTURE_2D, final_color_tex, 0);
     1184fprintf(stdin,"  after glFramebufferTexture2DEXT\n");
    10331185       
    10341186  // initialize final depth renderbuffer
     
    10391191                               GL_DEPTH_ATTACHMENT_EXT,
    10401192                               GL_RENDERBUFFER_EXT, final_depth_rb);
     1193fprintf(stdin,"  after glFramebufferRenderEXT\n");
    10411194
    10421195  // Check framebuffer completeness at the end of initialization.
    10431196  CHECK_FRAMEBUFFER_STATUS();
    10441197  assert(glGetError()==0);
     1198fprintf(stdin,"  after assert\n");
    10451199}
    10461200
     
    11111265
    11121266void init_transfer_function(){
    1113   float data[256*4];
    1114 
    1115   //alternatively, a default transfer function also works.
    1116   memset(data, 0, 4*256*sizeof(float));
    1117 
    1118   tf[0] = new TransferFunction(256, data);
     1267  tf[0] = new TransferFunction(def_tf_size, def_tf);
    11191268}
    11201269
     
    11441293   system_info();
    11451294   init_glew();
     1295
     1296   //buffer to store data read from the screen
     1297   if (screen_buffer) {
     1298       delete[] screen_buffer;
     1299   }
     1300   screen_buffer = new unsigned char[3*win_width*win_height+1];
    11461301
    11471302   //create the camera with default setting
     
    12101365   //volume[3]->move(Vector3(0.2, -0.1, -0.1));
    12111366   //vol_render->add_volume(volume[3], tf[0]);
    1212 
    12131367   //volume[4]->move(Vector3(0.2,  0.1, -0.1));
    12141368   //vol_render->add_volume(volume[4], tf[0]);
     
    12241378  Tcl_MakeSafe(interp);
    12251379
    1226   //hello test
    1227   Tcl_CreateCommand(interp, "hello", HelloCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    1228 
    12291380  //set camera (viewing)
    12301381  Tcl_CreateCommand(interp, "camera", CameraCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
     1382
     1383  Tcl_CreateCommand(interp, "cutplane", CutplaneCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    12311384
    12321385  //resize the width and height of render screen
     
    12471400  //enable or disable an existing volume
    12481401  Tcl_CreateCommand(interp, "volume_enable", VolumeEnableCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    1249 
    1250   //move a cut plane
    1251   Tcl_CreateCommand(interp, "cut_move", CutMoveCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    1252   //enable or disable a cut plane
    1253   Tcl_CreateCommand(interp, "cut_enable", CutEnableCmd, (ClientData)0, (Tcl_CmdDeleteProc*)NULL);
    12541402
    12551403  //refresh the screen (render again)
     
    13371485      exit(0);
    13381486    }
    1339     fprintf(stderr, "read %d\n", status);
    13401487    data = tmp;
    13411488
    13421489    if(Tcl_Eval(interp, (char*)data.c_str()) != TCL_OK) {
    13431490      //error to log file...
    1344       fprintf(stderr, "Tcl error: parser\n");
     1491      printf("Tcl error: %s\n", Tcl_GetStringResult(interp));
    13451492      return;
    13461493    }
     
    13621509
    13631510    // file size in bytes
    1364     bmp_header_add_int(header, pos, win_width*win_height*3 + sizeof(header));
     1511    int fsize = win_width*win_height*3 + sizeof(header);
     1512    bmp_header_add_int(header, pos, fsize);
    13651513
    13661514    // reserved value (must be 0)
     
    13961544    bmp_header_add_int(header, pos, 0);
    13971545    bmp_header_add_int(header, pos, 0);
     1546
     1547    std::ostringstream buffer;
     1548    buffer << "nv>image -bytes " << fsize << "\n";
     1549    write(0, buffer.str().c_str(), buffer.str().size());
    13981550
    13991551    write(0, header, sizeof(header));
     
    19082060
    19092061void end_service();
    1910 
    1911 void resize(int w, int h){
    1912   resize_offscreen_buffer(w, h);
    1913 }
    1914 
    19152062
    19162063void keyboard(unsigned char key, int x, int y){
     
    21072254
    21082255   glutDisplayFunc(display);
     2256#ifndef XINETD
    21092257   glutMouseFunc(mouse);
    21102258   glutMotionFunc(motion);
    21112259   glutKeyboardFunc(keyboard);
     2260#endif
    21122261   glutIdleFunc(idle);
    2113    glutReshapeFunc(resize);
     2262   glutReshapeFunc(resize_offscreen_buffer);
    21142263
    21152264   initGL();
Note: See TracChangeset for help on using the changeset viewer.