Changeset 4874 for nanovis/branches/1.1/nanovis.cpp
- Timestamp:
- Dec 18, 2014 5:45:38 PM (9 years ago)
- Location:
- nanovis/branches/1.1
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
nanovis/branches/1.1
- Property svn:mergeinfo changed
/trunk/packages/vizservers/nanovis merged: 3607
- Property svn:mergeinfo changed
-
nanovis/branches/1.1/nanovis.cpp
r4820 r4874 16 16 */ 17 17 18 #include <assert.h>19 #include <errno.h>20 #include <fcntl.h>21 #include <getopt.h>22 #include <memory.h>23 #include <signal.h>24 #include <sys/resource.h>25 #include <sys/stat.h>26 18 #include <sys/time.h> 27 #include <sys/times.h>28 19 #include <sys/types.h> 29 #include <sys/uio.h> // for readv/writev 30 #include <time.h> 20 #include <sys/uio.h> // for writev in ppmWrite 31 21 #include <unistd.h> 32 22 23 #include <cassert> 33 24 #include <cstdlib> 34 25 #include <cstdio> … … 36 27 #include <cmath> 37 28 38 #include <iostream>39 #include <fstream>40 #include <sstream>41 29 #include <string> 42 30 … … 44 32 #include <GL/glut.h> 45 33 46 #include <RpEncode.h>47 48 34 #include <graphics/RenderContext.h> 49 35 #include <vrmath/Vector3f.h> … … 57 43 #include "config.h" 58 44 #include "nanovis.h" 45 #include "nanovisServer.h" 59 46 #include "define.h" 60 47 … … 66 53 #include "NvShader.h" 67 54 #include "NvLIC.h" 68 #include "NvZincBlendeReconstructor.h"69 55 #include "PlaneRenderer.h" 70 56 #include "Switch.h" 71 57 #include "Trace.h" 58 #include "TransferFunction.h" 72 59 #include "Unirect.h" 73 60 #include "VelocityArrowsSlice.h" 74 61 #include "VolumeInterpolator.h" 75 62 #include "VolumeRenderer.h" 76 #include "ZincBlendeVolume.h" 77 63 64 using namespace nv; 78 65 using namespace nv::graphics; 79 66 using namespace nv::util; … … 89 76 // STATIC MEMBER DATA 90 77 91 FILE *NanoVis::stdin = NULL; 92 FILE *NanoVis::logfile = NULL; 93 FILE *NanoVis::recfile = NULL; 94 95 NanoVis::Stats NanoVis::stats; 96 int NanoVis::statsFile = -1; 78 Tcl_Interp *NanoVis::interp = NULL; 97 79 98 80 unsigned int NanoVis::flags = 0; … … 105 87 unsigned char *NanoVis::screenBuffer = NULL; 106 88 Texture2D *NanoVis::legendTexture = NULL; 107 Grid *NanoVis::grid = NULL;108 89 Fonts *NanoVis::fonts; 109 90 int NanoVis::updir = Y_POS; … … 132 113 NvLIC *NanoVis::licRenderer = NULL; 133 114 PlaneRenderer *NanoVis::planeRenderer = NULL; 134 135 Tcl_Interp *NanoVis::interp; 115 Grid *NanoVis::grid = NULL; 136 116 137 117 // Image based flow visualization slice location … … 210 190 flags |= REDRAW_PENDING; 211 191 } 212 }213 214 #ifdef KEEPSTATS215 216 #ifndef STATSDIR217 #define STATSDIR "/var/tmp/visservers"218 #endif /*STATSDIR*/219 220 int221 NanoVis::getStatsFile(Tcl_Obj *objPtr)222 {223 Tcl_DString ds;224 char fileName[33];225 char pidstr[200];226 const char *path;227 md5_state_t state;228 md5_byte_t digest[16];229 char *string;230 int length;231 232 if ((objPtr == NULL) || (statsFile >= 0)) {233 return statsFile;234 }235 /* By itself the client's key/value pairs aren't unique. Add in the236 * process id of this render server. */237 sprintf(pidstr, "%ld", (long)stats.pid);238 239 /* Create an md5 hash of the key/value pairs and use it as the file name. */240 string = Tcl_GetStringFromObj(objPtr, &length);241 md5_init(&state);242 md5_append(&state, (const md5_byte_t *)string, strlen(string));243 md5_append(&state, (const md5_byte_t *)pidstr, strlen(pidstr));244 md5_finish(&state, digest);245 for (int i = 0; i < 16; i++) {246 sprintf(fileName + i * 2, "%02x", digest[i]);247 }248 Tcl_DStringInit(&ds);249 Tcl_DStringAppend(&ds, STATSDIR, -1);250 Tcl_DStringAppend(&ds, "/", 1);251 Tcl_DStringAppend(&ds, fileName, 32);252 path = Tcl_DStringValue(&ds);253 254 statsFile = open(path, O_EXCL | O_CREAT | O_WRONLY, 0600);255 Tcl_DStringFree(&ds);256 if (statsFile < 0) {257 ERROR("can't open \"%s\": %s", fileName, strerror(errno));258 return -1;259 }260 return statsFile;261 }262 263 int264 NanoVis::writeToStatsFile(int f, const char *s, size_t length)265 {266 if (f >= 0) {267 ssize_t numWritten;268 269 numWritten = write(f, s, length);270 if (numWritten == (ssize_t)length) {271 close(dup(f));272 }273 }274 return 0;275 }276 277 static int278 serverStats(int code)279 {280 double start, finish;281 char buf[BUFSIZ];282 Tcl_DString ds;283 int result;284 285 {286 struct timeval tv;287 288 /* Get ending time. */289 gettimeofday(&tv, NULL);290 finish = CVT2SECS(tv);291 tv = NanoVis::stats.start;292 start = CVT2SECS(tv);293 }294 /*295 * Session information:296 * - Name of render server297 * - Process ID298 * - Hostname where server is running299 * - Start date of session300 * - Start date of session in seconds301 * - Number of frames returned302 * - Number of bytes total returned (in frames)303 * - Number of commands received304 * - Total elapsed time of all commands305 * - Total elapsed time of session306 * - Exit code of vizserver307 * - User time308 * - System time309 * - User time of children310 * - System time of children311 */312 313 Tcl_DStringInit(&ds);314 315 Tcl_DStringAppendElement(&ds, "render_stop");316 /* renderer */317 Tcl_DStringAppendElement(&ds, "renderer");318 Tcl_DStringAppendElement(&ds, "nanovis");319 /* pid */320 Tcl_DStringAppendElement(&ds, "pid");321 sprintf(buf, "%d", NanoVis::stats.pid);322 Tcl_DStringAppendElement(&ds, buf);323 /* host */324 Tcl_DStringAppendElement(&ds, "host");325 gethostname(buf, BUFSIZ-1);326 buf[BUFSIZ-1] = '\0';327 Tcl_DStringAppendElement(&ds, buf);328 /* date */329 Tcl_DStringAppendElement(&ds, "date");330 strcpy(buf, ctime(&NanoVis::stats.start.tv_sec));331 buf[strlen(buf) - 1] = '\0';332 Tcl_DStringAppendElement(&ds, buf);333 /* date_secs */334 Tcl_DStringAppendElement(&ds, "date_secs");335 sprintf(buf, "%ld", NanoVis::stats.start.tv_sec);336 Tcl_DStringAppendElement(&ds, buf);337 /* num_frames */338 Tcl_DStringAppendElement(&ds, "num_frames");339 sprintf(buf, "%lu", (unsigned long)NanoVis::stats.nFrames);340 Tcl_DStringAppendElement(&ds, buf);341 /* frame_bytes */342 Tcl_DStringAppendElement(&ds, "frame_bytes");343 sprintf(buf, "%lu", (unsigned long)NanoVis::stats.nBytes);344 Tcl_DStringAppendElement(&ds, buf);345 /* num_commands */346 Tcl_DStringAppendElement(&ds, "num_commands");347 sprintf(buf, "%lu", (unsigned long)NanoVis::stats.nCommands);348 Tcl_DStringAppendElement(&ds, buf);349 /* cmd_time */350 Tcl_DStringAppendElement(&ds, "cmd_time");351 sprintf(buf, "%g", NanoVis::stats.cmdTime);352 Tcl_DStringAppendElement(&ds, buf);353 /* session_time */354 Tcl_DStringAppendElement(&ds, "session_time");355 sprintf(buf, "%g", finish - start);356 Tcl_DStringAppendElement(&ds, buf);357 /* status */358 Tcl_DStringAppendElement(&ds, "status");359 sprintf(buf, "%d", code);360 Tcl_DStringAppendElement(&ds, buf);361 {362 long clocksPerSec = sysconf(_SC_CLK_TCK);363 double clockRes = 1.0 / clocksPerSec;364 struct tms tms;365 366 memset(&tms, 0, sizeof(tms));367 times(&tms);368 /* utime */369 Tcl_DStringAppendElement(&ds, "utime");370 sprintf(buf, "%g", tms.tms_utime * clockRes);371 Tcl_DStringAppendElement(&ds, buf);372 /* stime */373 Tcl_DStringAppendElement(&ds, "stime");374 sprintf(buf, "%g", tms.tms_stime * clockRes);375 Tcl_DStringAppendElement(&ds, buf);376 /* cutime */377 Tcl_DStringAppendElement(&ds, "cutime");378 sprintf(buf, "%g", tms.tms_cutime * clockRes);379 Tcl_DStringAppendElement(&ds, buf);380 /* cstime */381 Tcl_DStringAppendElement(&ds, "cstime");382 sprintf(buf, "%g", tms.tms_cstime * clockRes);383 Tcl_DStringAppendElement(&ds, buf);384 }385 Tcl_DStringAppend(&ds, "\n", -1);386 int f = NanoVis::getStatsFile(NULL);387 result = NanoVis::writeToStatsFile(f, Tcl_DStringValue(&ds),388 Tcl_DStringLength(&ds));389 close(f);390 Tcl_DStringFree(&ds);391 return result;392 }393 394 #endif395 396 static void397 initService()398 {399 TRACE("Enter");400 401 const char* user = getenv("USER");402 char* logName = NULL;403 int logNameLen = 0;404 405 if (user == NULL) {406 logNameLen = 20+1;407 logName = (char *)calloc(logNameLen, sizeof(char));408 strncpy(logName, "/tmp/nanovis_log.txt", logNameLen);409 } else {410 logNameLen = 17+1+strlen(user);411 logName = (char *)calloc(logNameLen, sizeof(char));412 strncpy(logName, "/tmp/nanovis_log_", logNameLen);413 strncat(logName, user, strlen(user));414 }415 416 //open log and map stderr to log file417 NanoVis::logfile = fopen(logName, "w");418 dup2(fileno(NanoVis::logfile), 2);419 /* dup2(2,1); */420 421 // clean up malloc'd memory422 if (logName != NULL) {423 free(logName);424 }425 426 TRACE("Leave");427 }428 429 static void430 exitService(int code)431 {432 TRACE("Enter: %d", code);433 434 NanoVis::removeAllData();435 436 NvShader::exitCg();437 438 //close log file439 if (NanoVis::logfile != NULL) {440 fclose(NanoVis::logfile);441 NanoVis::logfile = NULL;442 }443 444 #ifdef KEEPSTATS445 serverStats(code);446 #endif447 closelog();448 449 exit(code);450 }451 452 static int453 executeCommand(Tcl_Interp *interp, Tcl_DString *dsPtr)454 {455 struct timeval tv;456 double start, finish;457 int result;458 459 #ifdef WANT_TRACE460 char *str = Tcl_DStringValue(dsPtr);461 std::string cmd(str);462 cmd.erase(cmd.find_last_not_of(" \n\r\t")+1);463 TRACE("command %lu: '%s'", NanoVis::stats.nCommands+1, cmd.c_str());464 #endif465 466 gettimeofday(&tv, NULL);467 start = CVT2SECS(tv);468 469 if (NanoVis::recfile != NULL) {470 fprintf(NanoVis::recfile, "%s", Tcl_DStringValue(dsPtr));471 fflush(NanoVis::recfile);472 }473 result = Tcl_Eval(interp, Tcl_DStringValue(dsPtr));474 Tcl_DStringSetLength(dsPtr, 0);475 476 gettimeofday(&tv, NULL);477 finish = CVT2SECS(tv);478 479 NanoVis::stats.cmdTime += finish - start;480 NanoVis::stats.nCommands++;481 TRACE("Leave status=%d", result);482 return result;483 192 } 484 193 … … 615 324 planeRenderer->render(); 616 325 617 // INSOO326 //glPixelStorei(GL_PACK_ALIGNMENT, 1); 618 327 glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, screenBuffer); 619 //glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, screenBuffer); // INSOO's620 621 328 { 622 329 char prefix[200]; 623 ssize_t nWritten;624 330 625 331 TRACE("Sending ppm legend image %s min:%g max:%g", volArg, min, max); 626 332 sprintf(prefix, "nv>legend %s %g %g", volArg, min, max); 627 333 ppmWrite(prefix); 628 nWritten = write(1, "\n", 1);629 assert(nWritten == 1);630 334 } 631 335 planeRenderer->removePlane(index); … … 639 343 640 344 //initialize frame buffer objects for offscreen rendering 641 void 345 bool 642 346 NanoVis::initOffscreenBuffer() 643 347 { … … 678 382 if (!CheckFBO(&status)) { 679 383 PrintFBOStatus(status, "finalFbo"); 680 exitService(3);384 return false; 681 385 } 682 386 683 387 TRACE("Leave"); 388 return true; 684 389 } 685 390 686 391 //resize the offscreen buffer 687 void 392 bool 688 393 NanoVis::resizeOffscreenBuffer(int w, int h) 689 394 { 690 395 TRACE("Enter (%d, %d)", w, h); 691 396 if ((w == winWidth) && (h == winHeight)) { 692 return ;397 return true; 693 398 } 694 399 winWidth = w; … … 751 456 if (!CheckFBO(&status)) { 752 457 PrintFBOStatus(status, "finalFbo"); 753 exitService(3);458 return false; 754 459 } 755 460 … … 760 465 761 466 TRACE("Leave (%d, %d)", w, h); 467 return true; 762 468 } 763 469 … … 767 473 if (!NvShader::printErrorInfo()) { 768 474 TRACE("Cg error, exiting..."); 769 exit Service(-1);770 } 771 } 772 773 voidNanoVis::init(const char* path)475 exit(1); 476 } 477 } 478 479 bool NanoVis::init(const char* path) 774 480 { 775 481 // print OpenGL driver information … … 782 488 if (path == NULL) { 783 489 ERROR("No path defined for shaders or resources"); 784 exitService(1);490 return false; 785 491 } 786 492 GLenum err = glewInit(); 787 493 if (GLEW_OK != err) { 788 494 ERROR("Can't init GLEW: %s", glewGetErrorString(err)); 789 exitService(1);495 return false; 790 496 } 791 497 TRACE("Using GLEW %s", glewGetString(GLEW_VERSION)); … … 795 501 if (!GLEW_VERSION_2_1) { 796 502 ERROR("OpenGL version 2.1 or greater is required"); 797 exitService(1);503 return false; 798 504 } 799 505 … … 802 508 if (!GLEW_ARB_pixel_buffer_object) { 803 509 ERROR("Pixel buffer objects are not supported by driver, please check that the user running nanovis has permissions to create a direct rendering context (e.g. user has read/write access to /dev/nvidia* device nodes in Linux)."); 804 exitService(1);510 return false; 805 511 } 806 512 … … 810 516 if (!GLEW_EXT_framebuffer_object) { 811 517 ERROR("EXT_framebuffer_oject extension is required"); 812 exitService(1);518 return false; 813 519 } 814 520 // Rectangle textures were promoted in 3.1 … … 816 522 if (!GLEW_ARB_texture_rectangle) { 817 523 ERROR("ARB_texture_rectangle extension is required"); 818 exitService(1);524 return false; 819 525 } 820 526 #ifdef HAVE_FLOAT_TEXTURES … … 823 529 !GLEW_ARB_color_buffer_float) { 824 530 ERROR("ARB_texture_float and ARB_color_buffer_float extensions are required"); 825 exitService(1);531 return false; 826 532 } 827 533 #endif … … 830 536 !GLEW_NV_fragment_program2) { 831 537 ERROR("NV_vertex_program3 and NV_fragment_program2 extensions are required"); 832 exitService(1);538 return false; 833 539 } 834 540 835 541 if (!FilePath::getInstance()->setPath(path)) { 836 542 ERROR("can't set file path to %s", path); 837 exitService(1);543 return false; 838 544 } 839 545 … … 852 558 grid = new Grid(); 853 559 grid->setFont(fonts); 854 } 855 856 void 560 561 return true; 562 } 563 564 bool 857 565 NanoVis::initGL() 858 566 { … … 889 597 glLightfv(GL_LIGHT1, GL_SPECULAR, white_light); 890 598 891 initOffscreenBuffer(); //frame buffer object for offscreen rendering 892 893 //create volume renderer 599 //frame buffer object for offscreen rendering 600 if (!initOffscreenBuffer()) { 601 return false; 602 } 603 894 604 volRenderer = new VolumeRenderer(); 895 605 896 // create897 606 renderContext = new RenderContext(); 898 607 899 //create a 2D plane renderer900 608 planeRenderer = new PlaneRenderer(winWidth, winHeight); 901 609 … … 903 611 904 612 TRACE("leaving initGL"); 613 614 return true; 905 615 } 906 616 … … 1035 745 char string[200]; 1036 746 sprintf(string, "%s %d\n", prefix, fsize); 1037 nWritten = write( 1, string, strlen(string));747 nWritten = write(g_fdOut, string, strlen(string)); 1038 748 assert(nWritten == (ssize_t)strlen(string)); 1039 749 header[pos++] = 'B'; … … 1088 798 } 1089 799 1090 nWritten = write( 1, header, SIZEOF_BMP_HEADER);800 nWritten = write(g_fdOut, header, SIZEOF_BMP_HEADER); 1091 801 assert(nWritten == SIZEOF_BMP_HEADER); 1092 nWritten = write( 1, screenBuffer, (3*winWidth+pad)*winHeight);802 nWritten = write(g_fdOut, screenBuffer, (3*winWidth+pad)*winHeight); 1093 803 assert(nWritten == (3*winWidth+pad)*winHeight); 1094 stats.nFrames++;1095 stats.nBytes += (3*winWidth+pad)*winHeight;804 g_stats.nFrames++; 805 g_stats.nFrameBytes += (3*winWidth+pad)*winHeight; 1096 806 } 1097 807 … … 1154 864 srcRowPtr += bytesPerRow; 1155 865 } 1156 if (writev( 1, iov, nRecs) < 0) {866 if (writev(g_fdOut, iov, nRecs) < 0) { 1157 867 ERROR("write failed: %s", strerror(errno)); 1158 868 } 1159 869 free(iov); 1160 stats.nFrames++;1161 stats.nBytes += (bytesPerRow * winHeight);870 g_stats.nFrames++; 871 g_stats.nFrameBytes += (bytesPerRow * winHeight); 1162 872 TRACE("Leave (%dx%d)", winWidth, winHeight); 1163 }1164 1165 void1166 NanoVis::sendDataToClient(const char *command, const char *data, size_t dlen)1167 {1168 size_t numRecords = 2;1169 1170 struct iovec *iov = new iovec[numRecords];1171 1172 // Write the nanovisviewer command, then the image header and data.1173 // Command1174 // FIXME: shouldn't have to cast this1175 iov[0].iov_base = (char *)command;1176 iov[0].iov_len = strlen(command);1177 // Data1178 // FIXME: shouldn't have to cast this1179 iov[1].iov_base = (char *)data;1180 iov[1].iov_len = dlen;1181 if (writev(1, iov, numRecords) < 0) {1182 ERROR("write failed: %s", strerror(errno));1183 }1184 delete [] iov;1185 }1186 1187 void1188 NanoVis::idle()1189 {1190 TRACE("Enter");1191 1192 glutSetWindow(renderWindow);1193 1194 processCommands();1195 1196 TRACE("Leave");1197 873 } 1198 874 … … 1539 1215 TRACE("Setting bgcolor to %g %g %g", color[0], color[1], color[2]); 1540 1216 glClearColor(color[0], color[1], color[2], 1); 1217 } 1218 1219 void 1220 NanoVis::removeVolume(Volume *volume) 1221 { 1222 VolumeHashmap::iterator itr = volumeTable.find(volume->name()); 1223 if (itr != volumeTable.end()) { 1224 volumeTable.erase(itr); 1225 } 1226 delete volume; 1541 1227 } 1542 1228 … … 1794 1480 draw3dAxis(); 1795 1481 } 1796 if (grid->isVisible()) { 1797 grid->render(); 1798 } 1482 grid->render(); 1799 1483 if ((licRenderer != NULL) && (licRenderer->active())) { 1800 1484 licRenderer->render(); … … 1803 1487 velocityArrowsSlice->render(); 1804 1488 } 1805 if (!flowTable.empty()) { 1806 renderFlows(); 1807 } 1489 renderFlows(); 1808 1490 1809 1491 volRenderer->renderAll(); 1810 1492 1811 TRACE("Render heightmaps");1812 1493 HeightMapHashmap::iterator itr; 1813 1494 for (itr = heightMapTable.begin(); … … 1824 1505 } 1825 1506 1826 void1827 NanoVis::processCommands()1828 {1829 flags &= ~REDRAW_PENDING;1830 1831 TRACE("Enter");1832 1833 int flags = fcntl(0, F_GETFL, 0);1834 fcntl(0, F_SETFL, flags & ~O_NONBLOCK);1835 1836 int status = TCL_OK;1837 1838 // Read and execute as many commands as we can from stdin...1839 Tcl_DString cmdbuffer;1840 Tcl_DStringInit(&cmdbuffer);1841 int nCommands = 0;1842 bool isComplete = false;1843 while ((!feof(NanoVis::stdin)) && (status == TCL_OK)) {1844 //1845 // Read the next command from the buffer. First time through we1846 // block here and wait if necessary until a command comes in.1847 //1848 // BE CAREFUL: Read only one command, up to a newline. The "volume1849 // data follows" command needs to be able to read the data1850 // immediately following the command, and we shouldn't consume it1851 // here.1852 //1853 while (!feof(NanoVis::stdin)) {1854 int c = fgetc(NanoVis::stdin);1855 char ch;1856 if (c <= 0) {1857 if (errno == EWOULDBLOCK) {1858 break;1859 }1860 exitService(100);1861 }1862 ch = (char)c;1863 Tcl_DStringAppend(&cmdbuffer, &ch, 1);1864 if (ch == '\n') {1865 isComplete = Tcl_CommandComplete(Tcl_DStringValue(&cmdbuffer));1866 if (isComplete) {1867 break;1868 }1869 }1870 }1871 // no command? then we're done for now1872 if (Tcl_DStringLength(&cmdbuffer) == 0) {1873 break;1874 }1875 if (isComplete) {1876 // back to original flags during command evaluation...1877 fcntl(0, F_SETFL, flags & ~O_NONBLOCK);1878 status = executeCommand(interp, &cmdbuffer);1879 // non-blocking for next read -- we might not get anything1880 fcntl(0, F_SETFL, flags | O_NONBLOCK);1881 isComplete = false;1882 nCommands++;1883 CHECK_FRAMEBUFFER_STATUS();1884 }1885 }1886 fcntl(0, F_SETFL, flags);1887 1888 if (status != TCL_OK) {1889 char *msg;1890 char hdr[200];1891 int msgSize, hdrSize;1892 Tcl_Obj *objPtr;1893 1894 objPtr = Tcl_GetObjResult(interp);1895 msg = Tcl_GetStringFromObj(objPtr, &msgSize);1896 hdrSize = sprintf(hdr, "nv>viserror -type internal_error -bytes %d\n", msgSize);1897 {1898 struct iovec iov[2];1899 1900 iov[0].iov_base = hdr;1901 iov[0].iov_len = hdrSize;1902 iov[1].iov_base = msg;1903 iov[1].iov_len = msgSize;1904 if (writev(1, iov, 2) < 0) {1905 ERROR("write failed: %s", strerror(errno));1906 }1907 }1908 TRACE("Leaving on ERROR");1909 return;1910 }1911 if (feof(NanoVis::stdin)) {1912 TRACE("Exiting server on EOF from client");1913 exitService(90);1914 }1915 1916 update();1917 1918 bindOffscreenBuffer(); //enable offscreen render1919 render();1920 readScreen();1921 1922 if (feof(NanoVis::stdin)) {1923 exitService(90);1924 }1925 1926 ppmWrite("nv>image -type image -bytes");1927 1928 TRACE("Leave");1929 }1930 1931 int1932 main(int argc, char **argv)1933 {1934 const char *path;1935 char *newPath;1936 1937 newPath = NULL;1938 path = NULL;1939 NanoVis::stdin = stdin;1940 1941 fprintf(stdout, "NanoVis %s (build %s)\n", NANOVIS_VERSION, SVN_VERSION);1942 fflush(stdout);1943 1944 openlog("nanovis", LOG_CONS | LOG_PERROR | LOG_PID, LOG_USER);1945 memset(&NanoVis::stats, 0, sizeof(NanoVis::Stats));1946 NanoVis::stats.pid = getpid();1947 gettimeofday(&NanoVis::stats.start, NULL);1948 1949 /* Initialize GLUT here so it can parse and remove GLUT-specific1950 * command-line options before we parse the command-line below. */1951 glutInit(&argc, argv);1952 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);1953 glutInitWindowSize(NanoVis::winWidth, NanoVis::winHeight);1954 glutInitWindowPosition(10, 10);1955 NanoVis::renderWindow = glutCreateWindow("nanovis");1956 glutIdleFunc(NanoVis::idle);1957 1958 glutDisplayFunc(NanoVis::render);1959 glutReshapeFunc(NanoVis::resizeOffscreenBuffer);1960 1961 while (1) {1962 static struct option long_options[] = {1963 {"infile", required_argument, NULL, 0},1964 {"path", required_argument, NULL, 2},1965 {"debug", no_argument, NULL, 3},1966 {"record", required_argument, NULL, 4},1967 {0, 0, 0, 0}1968 };1969 int option_index = 0;1970 int c;1971 1972 c = getopt_long(argc, argv, ":dp:i:l:r:", long_options, &option_index);1973 if (c == -1) {1974 break;1975 }1976 switch (c) {1977 case '?':1978 fprintf(stderr, "unknown option -%c\n", optopt);1979 return 1;1980 case ':':1981 if (optopt < 4) {1982 fprintf(stderr, "argument missing for --%s option\n",1983 long_options[optopt].name);1984 } else {1985 fprintf(stderr, "argument missing for -%c option\n", optopt);1986 }1987 return 1;1988 case 2:1989 case 'p':1990 path = optarg;1991 break;1992 case 3:1993 case 'd':1994 NanoVis::debugFlag = true;1995 break;1996 case 0:1997 case 'i':1998 NanoVis::stdin = fopen(optarg, "r");1999 if (NanoVis::stdin == NULL) {2000 perror(optarg);2001 return 2;2002 }2003 break;2004 case 4:2005 case 'r':2006 Tcl_DString ds;2007 char buf[200];2008 2009 Tcl_DStringInit(&ds);2010 Tcl_DStringAppend(&ds, optarg, -1);2011 sprintf(buf, ".%d", getpid());2012 Tcl_DStringAppend(&ds, buf, -1);2013 NanoVis::recfile = fopen(Tcl_DStringValue(&ds), "w");2014 if (NanoVis::recfile == NULL) {2015 perror(optarg);2016 return 2;2017 }2018 break;2019 default:2020 fprintf(stderr,"unknown option '%c'.\n", c);2021 return 1;2022 }2023 }2024 if (path == NULL) {2025 char *p;2026 2027 // See if we can derive the path from the location of the program.2028 // Assume program is in the form <path>/bin/nanovis.2029 path = argv[0];2030 p = strrchr((char *)path, '/');2031 if (p != NULL) {2032 *p = '\0';2033 p = strrchr((char *)path, '/');2034 }2035 if (p == NULL) {2036 TRACE("path not specified");2037 return 1;2038 }2039 *p = '\0';2040 newPath = new char[(strlen(path) + 15) * 2 + 1];2041 sprintf(newPath, "%s/lib/shaders:%s/lib/resources", path, path);2042 path = newPath;2043 }2044 2045 FilePath::getInstance()->setWorkingDirectory(argc, (const char**) argv);2046 2047 #ifdef notdef2048 signal(SIGPIPE, SIG_IGN);2049 #endif2050 initService();2051 2052 NanoVis::init(path);2053 if (newPath != NULL) {2054 delete [] newPath;2055 }2056 NanoVis::initGL();2057 2058 NanoVis::interp = initTcl();2059 2060 NanoVis::resizeOffscreenBuffer(NanoVis::winWidth, NanoVis::winHeight);2061 2062 glutMainLoop();2063 2064 exitService(80);2065 }2066 2067 void2068 NanoVis::removeVolume(Volume *volume)2069 {2070 VolumeHashmap::iterator itr = volumeTable.find(volume->name());2071 if (itr != volumeTable.end()) {2072 volumeTable.erase(itr);2073 }2074 delete volume;2075 }
Note: See TracChangeset
for help on using the changeset viewer.