plvDrawCmds.cc
上传用户:kellyonhid
上传日期:2013-10-12
资源大小:932k
文件大小:21k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. #ifdef WIN32
  2. # include "winGLdecs.h"
  3. #else
  4. # include <sys/time.h>
  5. #endif
  6. #include <GL/glu.h>
  7. #include <tk.h>
  8. #include <stdlib.h>
  9. #include "togl.h"
  10. #include "plvDraw.h"
  11. #include "plvGlobals.h"
  12. #include "plvDrawCmds.h"
  13. #include "plvMeshCmds.h"
  14. #include "plvScene.h"
  15. #include "ToglHash.h"
  16. #include "DisplayMesh.h"
  17. #include "ToglCache.h"
  18. #include "plvClipBoxCmds.h"
  19. #include "TextureObj.h"
  20. #include "plvViewerCmds.h"
  21. #include "TclCmdUtils.h"
  22. static const char ToglPaneName[] = ".toglFrame.toglPane";
  23. static void resizeMainTogl (struct Togl* togl);
  24. class DisplayListValidityCheck
  25. {
  26. public:
  27.   DisplayListValidityCheck (RenderParams* rp)
  28.     {
  29.       assert (rp != NULL);
  30.       realData = rp;
  31.       memcpy (&oldData, rp, sizeof(oldData));
  32.     };
  33.   ~DisplayListValidityCheck()
  34.     {
  35.       if (memcmp (&oldData, realData, sizeof(oldData))) {
  36. //render params changed -- kill display lists
  37. theScene->invalidateDisplayCaches();
  38. if (toglCurrent && Togl_Interp (toglCurrent)) {
  39.   DisplayCache::InvalidateToglCache (toglCurrent);
  40.   Tcl_Eval (Togl_Interp (toglCurrent), "renderParamsChanged");
  41. }
  42.       }
  43.     };
  44. private:
  45.   RenderParams *realData;
  46.   RenderParams oldData;
  47. };
  48. static void
  49. SetResultFromColorU (Tcl_Interp* interp, uchar* color)
  50. {
  51.   char buffer[20];
  52.   sprintf (buffer, "#%02x%02x%02x",
  53.    (int)color[0], (int)color[1], (int)color[2]);
  54.   Tcl_SetResult (interp, buffer, TCL_VOLATILE);
  55. }
  56. static void
  57. SetResultFromColorF (Tcl_Interp* interp, float* color)
  58. {
  59.   char buffer[20];
  60.   sprintf (buffer, "#%02x%02x%02x",
  61.    (int)(255*color[0]), (int)(255*color[1]), (int)(255*color[2]));
  62.   Tcl_SetResult (interp, buffer, TCL_VOLATILE);
  63. }
  64. int
  65. PlvDrawStyleCmd(ClientData clientData, Tcl_Interp *interp, 
  66. int argc, char *argv[])
  67. {
  68.   if (g_bNoUI)
  69.     return TCL_OK;
  70.   DisplayListValidityCheck dlvc (theRenderParams);
  71.   for (int i = 1; i < argc; i++) {
  72.     if (!strcmp(argv[i], "-shademodel")) {
  73.       i++;
  74.       if (!strcmp(argv[i], "realflat")) {
  75. theRenderParams->shadeModel = realPerFace;
  76.       } 
  77.       else if (!strcmp(argv[i], "fakeflat")) {
  78. theRenderParams->shadeModel = fakePerFace;
  79.       } 
  80.       else if (!strcmp(argv[i], "smooth")){
  81. theRenderParams->shadeModel = perVertex;
  82.       }
  83.       else {
  84. interp->result = "bad arg to plv_drawstyle -shademodel";
  85. return TCL_ERROR;
  86.       }
  87.     }
  88.     else if (!strcmp(argv[i], "-polymode")) {
  89.       i++;
  90.       if (!strcmp(argv[i], "fill")) {
  91. theRenderParams->polyMode = GL_FILL;
  92. theRenderParams->hiddenLine = FALSE;
  93.       } 
  94.       else if (!strcmp(argv[i], "line")){
  95. theRenderParams->polyMode = GL_LINE;
  96. theRenderParams->hiddenLine = FALSE;
  97.       }
  98.       else if (!strcmp(argv[i], "hiddenline")){
  99. theRenderParams->polyMode = GL_LINE;
  100. theRenderParams->hiddenLine = TRUE;
  101.       }
  102.       else if (!strcmp(argv[i], "point")){
  103. theRenderParams->polyMode = GL_POINT;
  104. theRenderParams->hiddenLine = FALSE;
  105.       }
  106.       else if (!strcmp(argv[i], "hiddenpoint")){
  107. theRenderParams->polyMode = GL_POINT;
  108. theRenderParams->hiddenLine = TRUE;
  109.       }
  110.       else {
  111. interp->result = "bad arg to plv_drawstyle -polymode";
  112. return TCL_ERROR;
  113.       }
  114.     }
  115.     else if (!strcmp(argv[i], "-blend")) {
  116.       SetBoolFromArgIndex (++i, theRenderParams->blend);
  117.     }
  118.     else if (!strcmp(argv[i], "-cull")) {
  119.       SetBoolFromArgIndex (++i, theRenderParams->cull);
  120.     }
  121.     else if (!strcmp(argv[i], "-bbox")) {
  122.       SetBoolFromArgIndex (++i, theRenderParams->boundSelection);
  123.     }
  124.     else if (!strcmp(argv[i], "-cachetogl")) {
  125.       if (!toglCurrent)
  126. continue;  // too early
  127.       bool bCache;
  128.       SetBoolFromArgIndex (++i, bCache);
  129.       DisplayCache::EnableToglCache (toglCurrent, bCache);
  130.     }
  131.     else if (!strcmp(argv[i], "-clearbuffer")) {
  132.       SetBoolFromArgIndex (++i, theRenderParams->clearBeforeRender);
  133.     }
  134.     else if (!strcmp(argv[i], "-displaylist")) {
  135.       bool bDispList;
  136.       SetBoolFromArgIndex (++i, bDispList);
  137.       for (int k = 0; k < theScene->meshSets.size(); k++) {
  138. theScene->meshSets[k]->useDisplayList (bDispList);
  139.       } 
  140.     }
  141.     else if (!strcmp(argv[i], "-flipnorm")) {
  142.       SetBoolFromArgIndex (++i, theRenderParams->flipnorm);
  143.     }
  144.     else if (!strcmp(argv[i], "-lighting")) {
  145.       SetBoolFromArgIndex (++i, theRenderParams->light);
  146.     }
  147.     else if (!strcmp(argv[i], "-tstrip")) {
  148.       SetBoolFromArgIndex (++i, theRenderParams->useTstrips);
  149.     }
  150.     else if (!strcmp(argv[i], "-background")) {
  151.       i++;
  152.       if (i == argc) { // query
  153. SetResultFromColorU (interp, theRenderParams->background);
  154. return TCL_OK;
  155.       } else {
  156. theRenderParams->background[0] = 255 * atof(argv[i]);  i++;
  157. theRenderParams->background[1] = 255 * atof(argv[i]);  i++;
  158. theRenderParams->background[2] = 255 * atof(argv[i]);
  159.       }
  160.     }
  161.     else if (!strcmp(argv[i], "-pointsize")) {
  162.       i++;
  163.       theRenderParams->pointSize = atof(argv[i]);
  164.     }
  165.     else if (!strcmp(argv[i], "-linewidth")) {
  166.       i++;
  167.       theRenderParams->lineWidth = atof(argv[i]);
  168.     }
  169.     else if (!strcmp(argv[i], "-emissive")) {
  170.       SetBoolFromArgIndex (++i, theRenderParams->useEmissive);
  171.     }
  172.     /* two sided lighting takes care of backface emissive
  173.     else if (!strcmp(argv[i], "-backfaceemissive")) {
  174.       SetBoolFromArgIndex (++i, theRenderParams->backFaceEmissive);
  175.     } */
  176.     else if (!strcmp(argv[i], "-twosidedlighting")) {
  177.       SetBoolFromArgIndex (++i, theRenderParams->twoSidedLighting);
  178.     }
  179.     else if (!strcmp(argv[i], "-antialias")) {
  180.       SetBoolFromArgIndex (++i, theRenderParams->antiAlias);
  181.     }
  182.     else if (!strcmp(argv[i], "-depthoffield")) {
  183.       if (i + 4 > argc) {
  184. interp->result = "bad # args to plv_drawstyle -depthoffield";
  185. return TCL_ERROR;
  186.       }
  187.       // arg format: [X jitter pixels] [Y jitter pixels] [center]
  188.       theRenderParams->dofJitterX = atof (argv[i + 1]);
  189.       theRenderParams->dofJitterY = atof (argv[i + 2]);
  190.       theRenderParams->dofCenter = atof (argv[i + 3]);
  191.       i += 4;      
  192.     }
  193.     else if (!strcmp(argv[i], "-shadows")) {
  194.       SetBoolFromArgIndex (++i, theRenderParams->shadows);
  195.     }
  196.     else if (!strcmp(argv[i], "-softshadowlength")) {
  197.       i++;
  198.       theRenderParams->shadowLength = atof (argv[i]);
  199.     }
  200.     else if (!strcmp(argv[i], "-fromlightpov")) {
  201.       SetBoolFromArgIndex (++i, theRenderParams->fromLightPOV);
  202.     }
  203.     else if (!strcmp(argv[i], "-aasamps")) {
  204.       i++;
  205.       int aasamps = atoi(argv[i]); i++;
  206.       switch (aasamps) {
  207.       case 2:
  208. theRenderParams->numAntiAliasSamps = 2;
  209. theRenderParams->jitterArray = (jitter_point *)j2;
  210. break;
  211.       case 3:
  212. theRenderParams->numAntiAliasSamps = 3;
  213. theRenderParams->jitterArray = (jitter_point *)j3;
  214. break;
  215.       case 4:
  216. theRenderParams->numAntiAliasSamps = 4;
  217. theRenderParams->jitterArray = (jitter_point *)j4;
  218. break;
  219.       case 8:
  220. theRenderParams->numAntiAliasSamps = 8;
  221. theRenderParams->jitterArray = (jitter_point *)j8;
  222. break;
  223.       case 15:
  224. theRenderParams->numAntiAliasSamps = 15;
  225. theRenderParams->jitterArray = (jitter_point *)j15;
  226. break;
  227.       case 24:
  228. theRenderParams->numAntiAliasSamps = 24;
  229. theRenderParams->jitterArray = (jitter_point *)j24;
  230. break;
  231.       case 66:
  232. theRenderParams->numAntiAliasSamps = 66;
  233. theRenderParams->jitterArray = (jitter_point *)j66;
  234. break;
  235.       default:
  236. interp->result = "bad args to plv_drawstyle -aasamps"
  237.   "  -  should be [2, 3, 4, 8, 15, 24, 66]";
  238. return TCL_ERROR;
  239.       }
  240.     }
  241.     else {
  242.       interp->result = "bad args to plv_drawstyle";
  243.       return TCL_ERROR;
  244.     }
  245.   }
  246.   
  247.   return TCL_OK;
  248. }
  249. int
  250. PlvFillPhotoCmd(ClientData clientData, Tcl_Interp *interp, 
  251. int argc, char *argv[])
  252. {
  253.   uchar *cbuf;
  254.   GLint lastBuffer;
  255.    
  256.   if (argc != 3) {
  257.     interp->result = "Usage: plv_fillphoto <togl-widget> <photo-widget>";
  258.     return TCL_ERROR;
  259.   }    
  260. #if TK_MAJOR_VERSION >= 8
  261.   Tk_PhotoHandle handle = Tk_FindPhoto(interp, argv[2]);
  262. #else
  263.   Tk_PhotoHandle handle = Tk_FindPhoto(argv[2]);
  264. #endif
  265.   if (handle == NULL) {
  266.     interp->result = "Could not find photo widget.";
  267.     return TCL_ERROR;
  268.   }
  269.    
  270.   prepareDrawInWin(argv[1]);
  271.   cbuf = (uchar *)malloc(theWidth*theHeight*4);
  272.   glGetIntegerv(GL_DRAW_BUFFER, &lastBuffer);
  273.   glDrawBuffer(GL_FRONT);
  274.   glReadPixels(0, 0, theWidth, theHeight, GL_RGBA, GL_UNSIGNED_BYTE, cbuf);
  275.   glDrawBuffer(GLenum(lastBuffer));
  276.   Tk_PhotoSetSize(handle, theWidth, theHeight);
  277.   Tk_PhotoImageBlock block;
  278.     
  279.   block.pixelPtr = cbuf;
  280.   block.pitch = theWidth*4;
  281.   block.pixelSize = 4;
  282.   block.offset[0] = 0;
  283.   block.offset[1] = 1;
  284.   block.offset[2] = 2;
  285.   block.width = theWidth;
  286.   block.height = theHeight;
  287.   Tk_PhotoPutBlock(handle, &block, 0, 0, theWidth, theHeight);
  288.   free(cbuf);
  289.   return TCL_OK;
  290. }
  291. int
  292. PlvDrawCmd(ClientData clientData, Tcl_Interp *interp, 
  293.    int argc, char *argv[])
  294. {
  295.   prepareDrawInWin(argv[1]);
  296.   drawInTogl (toglCurrent);
  297.     
  298.   return TCL_OK;
  299. }
  300. int
  301. PlvClearWinCmd(ClientData clientData, Tcl_Interp *interp, 
  302.        int argc, char *argv[])
  303. {
  304.   prepareDrawInWin(argv[1]);
  305.   glClear(GL_COLOR_BUFFER_BIT);
  306.   Togl_SwapBuffers (toglCurrent);
  307.     
  308.   return TCL_OK;
  309. }
  310. int
  311. PlvMaterialCmd(ClientData clientData, Tcl_Interp *interp, 
  312.        int argc, char *argv[])
  313. {
  314.   if (g_bNoUI)
  315.     return TCL_OK;
  316.   DisplayListValidityCheck dlvc (theRenderParams);
  317.   int i;
  318.   if (argc == 1) {
  319.     char* colorModeName = NULL;
  320.     switch (theRenderParams->colorMode) {
  321.     case grayColor:       colorModeName = "gray";       break;
  322.     case falseColor:      colorModeName = "false";      break;
  323.     case confidenceColor: colorModeName = "confidence"; break;
  324.     case boundaryColor:   colorModeName = "boundary";   break;
  325.     case intensityColor:  colorModeName = "intensity";  break;
  326.     case trueColor:       colorModeName = "true";       break;
  327.     case textureColor:    colorModeName = "texture";    break;
  328.     case registrationColor: colorModeName = "registration"; break;
  329.     }
  330.     printf("Command: %s [-option value]n", argv[0]);
  331.     printf("  -diffuse <float> <float> <float> (%f %f %f)n", 
  332.    theRenderParams->diffuse[0] / 255.,
  333.    theRenderParams->diffuse[1] / 255., 
  334.    theRenderParams->diffuse[2] / 255.);
  335.     printf("  -specular <float> <float> <float> (%f %f %f)n", 
  336.    theRenderParams->specular[0] / 255.,
  337.    theRenderParams->specular[1] / 255., 
  338.    theRenderParams->specular[2] / 255.);
  339.     printf("  -shininess <float> (%f)n", theRenderParams->shininess);
  340.     printf("  -confscale <float> (%f)n", theRenderParams->confScale);
  341.     printf("  -colormode [gray|false|intensity|true|confidence|"
  342.    "boundary|registration|texture (%s)n",
  343.    colorModeName);
  344.   }
  345.   else {
  346.     for (i = 1; i < argc; i++) {
  347.       if (!strcmp(argv[i], "-shininess")) {
  348. i++;
  349. theRenderParams->shininess = atof(argv[i]);
  350.       }
  351.       else if (!strcmp(argv[i], "-specular")) {
  352. i++;
  353. if (i == argc) { // query
  354.   SetResultFromColorU (interp, theRenderParams->specular);
  355.   return TCL_OK;
  356. }
  357. theRenderParams->specular[0] = 255 * atof(argv[i]);  i++;
  358. theRenderParams->specular[1] = 255 * atof(argv[i]);  i++;
  359. theRenderParams->specular[2] = 255 * atof(argv[i]);
  360.       }
  361.       else if (!strcmp(argv[i], "-diffuse")) {
  362. i++;
  363. if (i == argc) { // query
  364.   SetResultFromColorU (interp, theRenderParams->diffuse);
  365.   return TCL_OK;
  366. }
  367. theRenderParams->diffuse[0] = 255 * atof(argv[i]);  i++;
  368. theRenderParams->diffuse[1] = 255 * atof(argv[i]);  i++;
  369. theRenderParams->diffuse[2] = 255 * atof(argv[i]);
  370.       }
  371.       // backDiffuse added by kberg 6/5/01
  372.       else if (!strcmp(argv[i], "-backDiffuse")) {
  373. i++;
  374. if (i == argc) { // query
  375.   SetResultFromColorU (interp, theRenderParams->backDiffuse);
  376.   return TCL_OK;
  377. }
  378. theRenderParams->backDiffuse[0] = 255 * atof(argv[i]);  i++;
  379. theRenderParams->backDiffuse[1] = 255 * atof(argv[i]);  i++;
  380. theRenderParams->backDiffuse[2] = 255 * atof(argv[i]);
  381.       }
  382.       else if (!strcmp(argv[i], "-backSpecular")) {
  383. i++;
  384. if (i == argc) { // query
  385.   SetResultFromColorU (interp, theRenderParams->backSpecular);
  386.   return TCL_OK;
  387. }
  388. theRenderParams->backSpecular[0] = 255 * atof(argv[i]);  i++;
  389. theRenderParams->backSpecular[1] = 255 * atof(argv[i]);  i++;
  390. theRenderParams->backSpecular[2] = 255 * atof(argv[i]);
  391.       }
  392.       else if (!strcmp(argv[i], "-lightambient")) {
  393. i++;
  394. if (i == argc) { // query
  395.   SetResultFromColorF (interp, theRenderParams->lightAmbient);
  396.   return TCL_OK;
  397. }
  398. theRenderParams->lightAmbient[0] = atof(argv[i]);  i++;
  399. theRenderParams->lightAmbient[1] = atof(argv[i]);  i++;
  400. theRenderParams->lightAmbient[2] = atof(argv[i]);
  401.       }
  402.       else if (!strcmp(argv[i], "-lightspecular")) {
  403. i++;
  404. if (i == argc) { // query
  405.   SetResultFromColorF (interp, theRenderParams->lightSpecular);
  406.   return TCL_OK;
  407. }
  408. theRenderParams->lightSpecular[0] = atof(argv[i]);  i++;
  409. theRenderParams->lightSpecular[1] = atof(argv[i]);  i++;
  410. theRenderParams->lightSpecular[2] = atof(argv[i]);
  411.       }
  412.       else if (!strcmp(argv[i], "-lightdiffuse")) {
  413. i++;
  414. if (i == argc) { // query
  415.   SetResultFromColorF (interp, theRenderParams->lightDiffuse);
  416.   return TCL_OK;
  417. }
  418. theRenderParams->lightDiffuse[0] = atof(argv[i]);  i++;
  419. theRenderParams->lightDiffuse[1] = atof(argv[i]);  i++;
  420. theRenderParams->lightDiffuse[2] = atof(argv[i]);
  421.       }
  422.       else if (!strcmp(argv[i], "-backfacemode")) {
  423. i++;
  424. if (!strcmp(argv[i], "lit")) {
  425.   theRenderParams->backfaceMode = lit;
  426. }
  427. else if (!strcmp(argv[i], "emissive")) {
  428.   theRenderParams->backfaceMode = emissive;
  429. }
  430.       }
  431.       else if (!strcmp(argv[i], "-colormode")) {
  432. i++;
  433. if (     !strcmp (argv[i], "gray")) {
  434.   theRenderParams->colorMode = grayColor;
  435. }
  436. else if (!strcmp (argv[i], "false")) {
  437.   theRenderParams->colorMode = falseColor;
  438. }
  439. else if (!strcmp (argv[i], "intensity")) {
  440.   theRenderParams->colorMode = intensityColor;
  441. }
  442. else if (!strcmp (argv[i], "true")) {
  443.   theRenderParams->colorMode = trueColor;
  444. }
  445. else if (!strcmp (argv[i], "confidence")) {
  446.   theRenderParams->colorMode = confidenceColor;
  447. }
  448. else if (!strcmp (argv[i], "boundary")) {
  449.   theRenderParams->colorMode = boundaryColor;
  450. }
  451. else if (!strcmp (argv[i], "registration")) {
  452.   theRenderParams->colorMode = registrationColor;
  453. }
  454. else if (!strcmp (argv[i], "texture")) {
  455.   theRenderParams->colorMode = textureColor;
  456. }
  457. else {
  458.   interp->result = "Bad argument to plv_material -color";
  459.   return TCL_ERROR;
  460. }
  461.       }
  462.       else if (!strcmp(argv[i], "-confscale")) {
  463. i++;
  464. theRenderParams->confScale = atof(argv[i]);
  465.       }
  466.       else {
  467. interp->result = "bad arg to plv_material";
  468. return TCL_ERROR;
  469.       }
  470.     }
  471.   }
  472.   
  473.   return TCL_OK;
  474. }
  475. int
  476. PlvLoadProjectiveTexture(ClientData clientData, Tcl_Interp *interp, 
  477.   int argc, char *argv[])
  478. {
  479.   if (g_bNoUI)
  480.     return TCL_OK;
  481.   if (argc < 2) {
  482.     printf("Usage: %s filename.rgb [green] [nomipmap]n", argv[0]);
  483.     printf("       green : Don't actually load image, just use a green projectionn");
  484.     return TCL_OK;
  485.   }
  486.   int mesh;
  487.   // This applies the perspective texture to all visible meshes, so
  488.   // check whether anything's visible...
  489.   int nMeshes = theScene->meshSets.size();
  490.   if (!nMeshes)
  491.     return TCL_OK;
  492.   for (mesh = 0; mesh < nMeshes; mesh++) {
  493.     if (theScene->meshSets[mesh]->getVisible())
  494. break;
  495.   }
  496.   if (mesh == nMeshes)
  497.     return TCL_OK;
  498.   // Try to load the texture 
  499.   bool actuallyLoad=true, use_mipmaps=true;
  500.   for (int arg = 2; arg < argc; arg++) {
  501.    if (argv[arg][0] == 'g')
  502. actuallyLoad = false;
  503. else if (argv[arg][0] == 'n')
  504. use_mipmaps = false;
  505.   }
  506.   Ref<ProjectiveTexture> thetexture =
  507.    ProjectiveTexture::loadImage(argv[1], NULL, NULL, NULL, NULL,
  508.      actuallyLoad, use_mipmaps);
  509.   
  510.   if (!thetexture)
  511.     return TCL_OK;
  512.   for (mesh = 0; mesh < nMeshes; mesh++)
  513.     if (theScene->meshSets[mesh]->getVisible()) {
  514. DisplayableMesh *themesh = theScene->meshSets[mesh];
  515. const float *meshxform = (float *)(themesh->getMeshData()->getXform());
  516. themesh->setTexture(MeshAffixedProjectiveTexture::AffixToMesh(thetexture, meshxform));
  517.     }
  518.   return TCL_OK;
  519. }
  520. int 
  521. prepareDrawInWin(char *name)
  522. {
  523.   toglCurrent = toglHash.FindTogl (name);
  524.   assert (toglCurrent != NULL);
  525.   Togl_MakeCurrent (toglCurrent);
  526.   return 1;
  527. }
  528. void
  529. catchToglCreate (struct Togl *togl)
  530. {
  531.   toglHash.AddToHash (Togl_Ident (togl), togl);
  532.   if (!strcmp (Togl_Ident(togl), ToglPaneName)) {
  533.     toglCurrent = togl;
  534.     Togl_SetReshapeFunc (togl, resizeMainTogl);
  535.     new DisplayCache (togl);
  536.     Tcl_Eval (Togl_Interp (togl), "prefs_setRendererBasedDefaults");
  537.   }
  538. }
  539. void
  540. redraw (bool bForceRender)
  541. {
  542.   //just so other modules don't have to know about toglCurrent
  543.   if (bForceRender)
  544.     DisplayCache::InvalidateToglCache (toglCurrent);
  545.   Togl_PostRedisplay (toglCurrent);
  546. }
  547. void
  548. resizeMainTogl (struct Togl* togl)
  549. {
  550.   //printf ("from %dx%d to %dx%dn", theWidth, theHeight,
  551.   //  Togl_Width (togl), Togl_Height (togl));
  552.   resizeSelectionToWindow (togl);
  553. }
  554. void
  555. drawInTogl(struct Togl *togl)
  556. {
  557.   // don't redraw if redraw is disabled
  558.   if (atoi (Tcl_GetVar (g_tclInterp, "noRedraw", TCL_GLOBAL_ONLY)) <= 0) {
  559.     
  560.     // ok, we have permission to draw
  561.     drawInToglBuffer (togl, GL_FRONT, true);
  562.   }
  563. }
  564. void
  565. drawInToglBuffer (struct Togl *togl, int buffer, bool bCacheable)
  566. {
  567.   //puts ("drawInToglBuffer");
  568.   // Take ms time at start of render
  569.   unsigned long startTime = Get_Milliseconds();
  570.   
  571.   // update global size info
  572.   theWidth = Togl_Width (togl);
  573.   theHeight = Togl_Height (togl);
  574.   if (togl == toglCurrent) { // only if in main window, update trackball too
  575.     tbView->setSize (theWidth, theHeight);
  576.   }
  577.   //Tcl_Eval (g_tclInterp, "redrawStatus start");
  578. #if TOGLCACHE_DEBUG
  579.   cout << "rendering manually" << endl;
  580. #endif
  581.   glDrawBuffer (GL_BACK);
  582.   drawScene();
  583.   if (bCacheable) {
  584.     if (isManipulatingRender()) {
  585. #if TOGLCACHE_DEBUG
  586.       cout << "uncacheable data: clearing cache" << endl;
  587. #endif
  588.       DisplayCache::InvalidateToglCache (togl);
  589.     } else {
  590. #if TOGLCACHE_DEBUG
  591.       cout << "data is cacheable" << endl;
  592. #endif
  593.       //Tcl_Eval (g_tclInterp, "redrawStatus cache");
  594.       DisplayCache::UpdateToglCache (togl);
  595.     }
  596.   }
  597.   if (buffer == GL_FRONT)    
  598.     Togl_SwapBuffers (togl);
  599.   else
  600.     glFinish();
  601.   // Take time at end of render and save
  602.   unsigned long endTime = Get_Milliseconds();
  603.   lastRenderTime(endTime-startTime);
  604.   
  605.   //puts ("Leaving drawinTOglBuffer");
  606.   //Tcl_Eval (g_tclInterp, "redrawStatus end");
  607. }
  608. int
  609. PlvSetSlowPolyCountCmd(ClientData clientData, Tcl_Interp *interp, 
  610.        int argc, char *argv[])
  611. {
  612.   if (argc != 2) {
  613.     interp->result = "Bad args to PlvSetSlowPolyCountCmd";
  614.     return TCL_ERROR;
  615.   }
  616.   theScene->setSlowPolyCount (atoi (argv[1]));
  617.   return TCL_OK;
  618. }
  619. int
  620. PlvInvalidateToglCacheCmd(ClientData clientData, Tcl_Interp *interp, 
  621.        int argc, char *argv[])
  622. {
  623.   DisplayCache::InvalidateToglCache (toglCurrent);
  624.   return TCL_OK;
  625. }
  626. /* drawOverlayAndSwap
  627.  * ------------------
  628.  * function to draw the overlay and then swap the buffer.  Used
  629.  * when overlay planes are not available, but are being simulated
  630.  */
  631. void drawOverlayAndSwap(struct Togl* togl)
  632. {
  633.   drawOverlay(togl);
  634.   Togl_SwapBuffers(togl);
  635. }
  636. void
  637. drawOverlay (struct Togl* togl)
  638. {
  639. #ifndef no_overlay_support
  640.   Togl_UseLayer (togl, TOGL_OVERLAY);
  641.   glClear(GL_COLOR_BUFFER_BIT);
  642. #else
  643.   // overlay planes not supported - use a work around
  644.   // make the togl current (should be the main frame) since 
  645.   Togl_MakeCurrent(togl);
  646.   //glDrawBuffer (GL_BACK);
  647.   // save all the bits just so I don't turn off something
  648.   // that someone else expects to be on
  649.   glPushAttrib(GL_ALL_ATTRIB_BITS);
  650.   
  651.   glDisable (GL_DEPTH_TEST);
  652.   glDisable (GL_LIGHTING);
  653.   glDisable (GL_BLEND);
  654.   
  655.   glMatrixMode(GL_MODELVIEW);
  656.   glPushMatrix();
  657.   glLoadIdentity();
  658.   glViewport(0,0,theWidth, theHeight);
  659.   glMatrixMode(GL_PROJECTION);
  660.   glPushMatrix();
  661.   
  662.   glLoadIdentity();
  663.   gluOrtho2D(0, theWidth, 0, theHeight);
  664.   glRasterPos2i(0,0);
  665.   
  666.   glDrawPixels(theRenderParams->savedImageWidth, 
  667.        theRenderParams->savedImageHeight, GL_RGBA, GL_UNSIGNED_BYTE,
  668.        theRenderParams->savedImage);
  669.   
  670.   glPopMatrix();
  671.   glMatrixMode(GL_MODELVIEW);
  672.   glPopMatrix();
  673.   glFinish();
  674.   
  675. #endif
  676.   
  677.   // selection tools
  678.   drawSelection (togl);
  679.   // mouseover hint
  680.   drawScanHilites();
  681.   
  682. #ifndef no_overlay_support
  683.   Togl_UseLayer (togl, TOGL_NORMAL);
  684. #else  
  685.   glPopAttrib();
  686.   //Togl_SwapBuffers (togl); 
  687. #endif
  688. }
  689. int
  690. PlvRenderThicknessCmd(ClientData clientData, Tcl_Interp *interp, 
  691.       int argc, char *argv[])
  692. {
  693.   Togl_MakeCurrent (toglCurrent);
  694.   if (!drawSceneThicknessColored()) {
  695.     return TCL_ERROR;
  696.   }
  697.   Togl_SwapBuffers (toglCurrent);
  698.   return TCL_OK;
  699. }
  700. unsigned long Get_Milliseconds(void)
  701. {
  702.   unsigned long time;
  703. #ifdef WIN32
  704.   time = GetTickCount();
  705. #else
  706.   struct timeval mytime;
  707.   static unsigned long base=0;
  708.   gettimeofday(&mytime, NULL);
  709.   time=(mytime.tv_sec-base)*1000 + (mytime.tv_usec/1000) ;
  710. #endif
  711.   return time;
  712. }
  713. // Read and optionally set the amount of time the last render took.
  714. // We record this whenever a render takes place and then expose an
  715. // interface to read this value.
  716. long lastRenderTime(long milliseconds)
  717. {
  718.   static long lastDrawTime=0;
  719.   long tmpSaveTime = lastDrawTime;
  720.   
  721.   if (milliseconds != -1)
  722.     lastDrawTime = milliseconds;
  723.   return tmpSaveTime;
  724. }
  725. int
  726. PlvLastRenderTime(ClientData clientData, Tcl_Interp *interp, 
  727.       int argc, char *argv[])
  728. {
  729.  
  730.   sprintf(interp->result,"%ld",lastRenderTime());
  731.   return TCL_OK;
  732. }