Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OSPRayDisplayDevice.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 2013-2014 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010 * RCS INFORMATION:
00011 *
00012 *      $RCSfile: OSPRayDisplayDevice.C,v $
00013 *      $Author: johns $      $Locker:  $               $State: Exp $
00014 *      $Revision: 1.19 $         $Date: 2021/12/21 22:59:38 $
00015 *
00016 ***************************************************************************/
00038 #include <math.h>
00039 #include <stdlib.h>
00040 #include <stdio.h>
00041 #include <string.h>
00042 
00043 #include "VMDApp.h"    // needed for accelerator memory management
00044 #include "QuickSurf.h" // needed for accelerator memory management
00045 
00046 #include "DispCmds.h"  // CYLINDER_TRAILINGCAP, etc..
00047 #include "OSPRayDisplayDevice.h"
00048 #include "OSPRayRenderer.h"
00049 #include "config.h"    // needed for default image viewer
00050 #include "Hershey.h"   // needed for Hershey font rendering fctns
00051 
00052 
00053 // The default radius for points and lines (which are displayed
00054 // as small spheres or cylinders, respectively)
00055 #define DEFAULT_RADIUS  0.0025f
00056 
00057 
00058 // Global OSPRay initialization routine -- call it only ONCE...
00059 int OSPRayDisplayDevice::OSPRay_Global_Init(void) {
00060   return OSPRayRenderer::OSPRay_Global_Init(); // call only ONCE
00061 }
00062 
00063 // Global OSPRay shutdown routine -- call it only ONCE...
00064 void OSPRayDisplayDevice::OSPRay_Global_Shutdown(void) {
00065   OSPRayRenderer::OSPRay_Global_Shutdown(); // call only ONCE
00066 }
00067 
00068 
00070 OSPRayDisplayDevice::OSPRayDisplayDevice(VMDApp *app, int interactive) : FileRenderer((interactive) ? 
00071                "TachyonLOSPRayInteractive" : "TachyonLOSPRayInternal", 
00072                (interactive) ? 
00073                "TachyonL-OSPRay (interactive, SSE+AVX-accelerated)" : "TachyonL-OSPRay (internal, in-memory, SSE+AVX-accelerated)",
00074                "vmdscene.ppm", DEF_VMDIMAGEVIEWER) {
00075   vmdapp = app; // save VMDApp handle for init or memory management routines
00076 
00077   reset_vars(); // initialize material cache
00078 
00079   // flag interactive or not
00080   isinteractive = interactive;
00081 
00082   // Add supported file formats
00083   formats.add_name("PPM", 0);
00084 
00085   // Default image format depends on platform
00086   curformat = 0;
00087 
00088   // Set default aa level
00089   has_aa = TRUE;
00090   aasamples = 12;
00091   aosamples = 12;
00092 
00093   ort = new OSPRayRenderer();
00094   ort_timer = wkf_timer_create();
00095 }
00096         
00098 OSPRayDisplayDevice::~OSPRayDisplayDevice(void) {
00099   delete ort;
00100   wkf_timer_destroy(ort_timer);
00101 }
00102 
00103 void OSPRayDisplayDevice::add_material(void) {
00104   ort->add_material(materialIndex,
00105                     mat_ambient, mat_diffuse, mat_specular, mat_shininess,
00106                     mat_mirror, mat_opacity, mat_outline, mat_outlinewidth, 
00107                     mat_transmode > 0.5f);
00108 }
00109 
00110 
00112 void OSPRayDisplayDevice::reset_vars(void) {
00113   inclipgroup = 0; // not currently in a clipping group
00114 
00115   reset_cylinder_buffer();
00116   reset_triangle_buffer();
00117 }
00118 
00119 
00120 void OSPRayDisplayDevice::send_cylinder_buffer() {
00121   if (cylinder_vert_buffer.num() > 0) {
00122     // send the cylinders...
00123     ort->cylinder_array_color(*cylinder_xform, cylinder_radius_scalefactor,
00124                               cylinder_vert_buffer.num()/6,
00125                               &cylinder_vert_buffer[0],
00126                               &cylinder_radii_buffer[0],
00127                               &cylinder_color_buffer[0],
00128                               cylinder_matindex);
00129 
00130 #if 0
00131     // send the cylinder end caps, if any
00132     if (cylcap_vert_buffer.num() > 0) {
00133       ort->ring_array_color(*cylinder_xform, cylinder_radius_scalefactor,
00134                               cylcap_vert_buffer.num()/3,
00135                               &cylcap_vert_buffer[0],
00136                               &cylcap_norm_buffer[0],
00137                               &cylcap_radii_buffer[0],
00138                               &cylcap_color_buffer[0],
00139                               cylinder_matindex);
00140     }
00141 #endif
00142 
00143     delete cylinder_xform;
00144     cylinder_xform=NULL;
00145   }
00146   reset_cylinder_buffer();
00147 }
00148 
00149 
00150 #if defined(VMDOSPRAY_ENABLE_CYLINDERS)
00151 
00152 // draw a cylinder
00153 void OSPRayDisplayDevice::cylinder(float *a, float *b, float r, int filled) {
00154   // if we have a change in transformation matrix, color, or material state,
00155   // we have to emit all accumulated cylinders to OSPRay and begin a new batch
00156   if (cylinder_xform != NULL && ((cylinder_matindex != materialIndex) || (memcmp(cylinder_xform->mat, transMat.top().mat, sizeof(cylinder_xform->mat))))) {
00157     send_cylinder_buffer(); // render the accumulated cylinder buffer...
00158   }
00159 
00160   // record all transformation/material/color state on first cylinder call
00161   if (cylinder_xform == NULL) {
00162     // record material, color, and transformation state
00163     cylinder_matindex = materialIndex;
00164     cylinder_xform = new Matrix4(transMat.top());
00165     cylinder_radius_scalefactor = scale_factor();
00166     add_material(); // cause OSPRay to cache the current material
00167   }
00168 
00169   // record vertex data
00170   cylinder_vert_buffer.append2x3(&a[0], &b[0]);
00171   cylinder_radii_buffer.append(r);
00172   cylinder_color_buffer.append3(&matData[colorIndex][0]);
00173 
00174 #if 0
00175   // XXX Cylinder caps not yet supported in OSPRay
00176   // Cylinder caps?
00177   if (filled) {
00178     float norm[3];
00179     norm[0] = b[0] - a[0];
00180     norm[1] = b[1] - a[1];
00181     norm[2] = b[2] - a[2];
00182 
00183     float div = 1.0f / sqrtf(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
00184     norm[0] *= div;
00185     norm[1] *= div;
00186     norm[2] *= div;
00187 
00188     if (filled & CYLINDER_TRAILINGCAP) {
00189       cylcap_vert_buffer.append3(&a[0]);
00190       cylcap_norm_buffer.append3(&norm[0]);
00191       cylcap_radii_buffer.append2(0.0f, r);
00192       cylcap_color_buffer.append3(&matData[colorIndex][0]);
00193     }
00194 
00195     if (filled & CYLINDER_LEADINGCAP) {
00196       cylcap_vert_buffer.append3(&b[0]);
00197       norm[0] *= -1;
00198       norm[1] *= -1;
00199       norm[2] *= -1;
00200       cylcap_norm_buffer.append3(&norm[0]);
00201       cylcap_radii_buffer.append2(0.0f, r);
00202       cylcap_color_buffer.append3(&matData[colorIndex][0]);
00203     }
00204   }
00205 #endif
00206 }
00207 #endif
00208 
00209 
00210 // draw a sphere array
00211 void OSPRayDisplayDevice::sphere_array(int spnum, int spres, float *centers, 
00212                                       float *radii, float *colors) {
00213   add_material();
00214   ort->sphere_array_color(transMat.top(), scale_factor(), spnum, 
00215                           centers, radii, colors, materialIndex);
00216   
00217   // set final color state after array has been drawn
00218   int ind=(spnum-1)*3;
00219   super_set_color(nearest_index(colors[ind], colors[ind+1], colors[ind+2]));
00220 }
00221 
00222 
00223 #if defined(VMDOSPRAY_ENABLE_CYLINDERS)
00224 
00225 //
00226 // XXX text needs cylinders to be performant...
00227 //
00228 void OSPRayDisplayDevice::text(float *pos, float size, float thickness,
00229                               const char *str) {
00230   float textpos[3];
00231   float textsize, textthickness;
00232   hersheyhandle hh;
00233 
00234   // transform the world coordinates
00235   (transMat.top()).multpoint3d(pos, textpos);
00236   textsize = size * 1.5f;
00237   textthickness = thickness*DEFAULT_RADIUS;
00238 
00239   ResizeArray<float> text_spheres;
00240   ResizeArray<float> text_cylinders;
00241 
00242   while (*str != '\0') {
00243     float lm, rm, x, y, ox, oy;
00244     int draw, odraw;
00245     ox=oy=x=y=0.0f;
00246     draw=odraw=0;
00247 
00248     hersheyDrawInitLetter(&hh, *str, &lm, &rm);
00249     textpos[0] -= lm * textsize;
00250 
00251     while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
00252       float oldpt[3], newpt[3];
00253       if (draw) {
00254         newpt[0] = textpos[0] + textsize * x;
00255         newpt[1] = textpos[1] + textsize * y;
00256         newpt[2] = textpos[2];
00257 
00258         if (odraw) {
00259           // if we have both previous and next points, connect them...
00260           oldpt[0] = textpos[0] + textsize * ox;
00261           oldpt[1] = textpos[1] + textsize * oy;
00262           oldpt[2] = textpos[2];
00263 
00264           text_cylinders.append2x3(&oldpt[0], &newpt[0]);
00265           text_spheres.append3(&newpt[0]);
00266         } else {
00267           // ...otherwise, just draw the next point
00268           text_spheres.append3(&newpt[0]);
00269         }
00270       }
00271 
00272       ox=x;
00273       oy=y;
00274       odraw=draw;
00275     }
00276     textpos[0] += rm * textsize;
00277 
00278     str++;
00279   }
00280 
00281   add_material();
00282   // add spheres, which are already in world coordinates
00283   if (text_cylinders.num() > 0) {
00284     ort->cylinder_array(NULL, textthickness, matData[colorIndex],
00285                         text_cylinders.num() / 6, &text_cylinders[0],
00286                         materialIndex);
00287   }
00288   if (text_spheres.num() > 0) {
00289     ort->sphere_array(NULL, textthickness, matData[colorIndex],
00290                       text_spheres.num() / 3, &text_spheres[0], NULL, 
00291                       materialIndex);
00292   }
00293 }
00294 
00295 #endif
00296 
00297 
00298 void OSPRayDisplayDevice::send_triangle_buffer() {
00299   if (triangle_vert_buffer.num() > 0) {
00300     ort->trimesh_n3f_v3f(*triangle_xform, 
00301                          matData[triangle_cindex],
00302                          &triangle_norm_buffer[0],
00303                          &triangle_vert_buffer[0],
00304                          triangle_vert_buffer.num()/9,
00305                          triangle_matindex);
00306     delete triangle_xform;
00307     triangle_xform=NULL;
00308   }
00309   reset_triangle_buffer();
00310 }
00311 
00312 
00313 // draw a triangle
00314 void OSPRayDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, const float *n2, const float *n3) {
00315   // if we have a change in transformation matrix, color, or material state,
00316   // we have to emit all accumulated triangles to OSPRay and begin a new batch
00317   if (triangle_xform != NULL && ((triangle_cindex != colorIndex) || (triangle_matindex != materialIndex) || (memcmp(triangle_xform->mat, transMat.top().mat, sizeof(triangle_xform->mat))))) {
00318     send_triangle_buffer(); // render the accumulated triangle buffer...
00319   } 
00320 
00321   // record all transformation/material/color state on first triangle call
00322   if (triangle_xform == NULL) {
00323     // record material, color, and transformation state
00324     triangle_cindex = colorIndex;
00325     triangle_matindex = materialIndex;
00326     triangle_xform = new Matrix4(transMat.top());
00327     add_material(); // cause OSPRay to cache the current material
00328   }
00329 
00330   // record vertex data 
00331   triangle_vert_buffer.append3x3(&a[0], &b[0], &c[0]);
00332 
00333   // record normal data 
00334   triangle_norm_buffer.append3x3(&n1[0], &n2[0], &n3[0]);
00335 }
00336 
00337 
00338 // draw a tricolor
00339 void OSPRayDisplayDevice::tricolor(const float *a, const float *b, const float *c,
00340                       const float *n1, const float *n2, const float *n3,
00341                       const float *c1, const float *c2, const float *c3) {
00342   add_material();
00343 
00344   float vnc[27];
00345   vec_copy(&vnc[ 0], a);
00346   vec_copy(&vnc[ 3], b);
00347   vec_copy(&vnc[ 6], c);
00348 
00349   vec_copy(&vnc[ 9], n1);
00350   vec_copy(&vnc[12], n2);
00351   vec_copy(&vnc[15], n3);
00352 
00353   vec_copy(&vnc[18], c1);
00354   vec_copy(&vnc[21], c2);
00355   vec_copy(&vnc[24], c3);
00356 
00357   ort->tricolor_list(transMat.top(), 1, vnc, materialIndex);
00358 }
00359 
00360 
00361 void OSPRayDisplayDevice::trimesh_c4u_n3b_v3f(unsigned char *c, signed char *n,
00362                                              float *v, int numfacets) {
00363   add_material();
00364   ort->trimesh_c4u_n3b_v3f(transMat.top(), c, n, v, numfacets, materialIndex);
00365 }
00366 
00367 
00368 void OSPRayDisplayDevice::trimesh_c4u_n3f_v3f(unsigned char *c, float *n,
00369                                              float *v, int numfacets) {
00370   add_material();
00371   ort->trimesh_c4u_n3f_v3f(transMat.top(), c, n, v, numfacets, materialIndex);
00372 }
00373 
00374 void OSPRayDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
00375                                              int numfacets, int * facets) {
00376   add_material();
00377   ort->trimesh_c4n3v3(transMat.top(), numverts, cnv, numfacets, facets, 
00378                       materialIndex);
00379 }
00380 
00381 void OSPRayDisplayDevice::trimesh_n3b_v3f(signed char *n, float *v, int numfacets) {
00382   add_material();
00383   ort->trimesh_n3b_v3f(transMat.top(), matData[colorIndex], n, v, numfacets,  materialIndex);
00384 }
00385 
00386 void OSPRayDisplayDevice::trimesh_n3f_v3f(float *n, float *v, int numfacets) {
00387   add_material();
00388   ort->trimesh_n3f_v3f(transMat.top(), matData[colorIndex], n, v, numfacets,  materialIndex);
00389 }
00390 
00391 
00392 #if 0
00393 void OSPRayDisplayDevice::trimesh_n3fopt_v3f(float *n, float *v, int numfacets) {
00394   add_material();
00395   ort->trimesh_v3f(transMat.top(), matData[colorIndex], v, numfacets,  materialIndex);
00396 }
00397 
00398 #endif
00399 
00400 void OSPRayDisplayDevice::tristrip(int numverts, const float * cnv,
00401                          int numstrips, const int *vertsperstrip,
00402                          const int *facets) {
00403   add_material();
00404   ort->tristrip(transMat.top(), numverts, cnv, numstrips, vertsperstrip, 
00405                 facets, materialIndex);
00406 }
00407 
00408 
00409 
00410 void OSPRayDisplayDevice::write_lights() {
00411   int i;
00412   int lightcount = 0;
00413 
00414   // clear all existing lights before (re)appending the current lights,
00415   // otherwise if the OSPRay context is reused, we will crash and burn.
00416   ort->clear_all_lights();
00417 
00418   // directional lights
00419   for (i=0; i<DISP_LIGHTS; i++) {
00420     if (lightState[i].on) {
00421       ort->add_directional_light(lightState[i].pos, lightState[i].color);
00422       lightcount++;
00423     }
00424   }
00425 
00426 #if 0
00427   // advanced positional lights
00428   for (i=0; i<DISP_LIGHTS; i++) {
00429     if (advLightState[i].on) {
00430       float pos[3];
00431 
00432       // always use world coordinates for now
00433       vec_copy(pos, advLightState[i].pos);
00434 
00435       if (advLightState[i].spoton) {
00436         printf("OSPRayDisplayDevice) SpotLight not implemented yet ...\n");
00437       } else {
00438         apitexture tex;
00439         memset(&tex, 0, sizeof(apitexture));
00440 
00441         tex.col.r=advLightState[i].color[0];
00442         tex.col.g=advLightState[i].color[1];
00443         tex.col.b=advLightState[i].color[2];
00444 
00445         void *l = rt_light(rtscene,
00446                            rt_texture(rtscene, &tex),
00447                            /* negate position to correct handedness... */
00448                            rt_vector(pos[0], pos[1], -pos[2]), 0.0f);
00449 
00450         /* emit light attentuation parameters if needed */
00451         if (advLightState[i].constfactor != 1.0f ||
00452             advLightState[i].linearfactor != 0.0f ||
00453             advLightState[i].quadfactor != 0.0f) {
00454           rt_light_attenuation(l,
00455                                advLightState[i].constfactor,
00456                                advLightState[i].linearfactor,
00457                                advLightState[i].quadfactor);
00458         }
00459       }
00460 
00461       lightcount++;
00462     }
00463   }
00464 #endif
00465 
00466   if (lightcount < 1) {
00467     msgWarn << "No lights defined in molecular scene!!" << sendmsg;
00468   }
00469 }
00470 
00471 
00472 void OSPRayDisplayDevice::write_materials() {
00473   ort->set_bg_color(backColor);
00474 
00475   // Specify OSPRay background sky sphere if background gradient
00476   // mode is enabled.
00477   if (backgroundmode == 1) {
00478     float bspheremag = 0.5f;
00479 
00480     // compute positive/negative magnitude of sphere gradient
00481     switch (projection()) {
00482       case DisplayDevice::ORTHOGRAPHIC:
00483         // For orthographic views, Tachyon uses the dot product between
00484         // the incident ray origin and the sky sphere gradient "up" vector,
00485         // since all camera rays have the same direction and differ only
00486         // in their origin.
00487         bspheremag = vSize / 4.0f;
00488         break;
00489 
00490       case DisplayDevice::PERSPECTIVE:
00491       default:
00492         // For perspective views, Tachyon uses the dot product between
00493         // the incident ray and the sky sphere gradient "up" vector,
00494         // so for larger values of vSize, we have to clamp the maximum
00495         // magnitude to 1.0.
00496         bspheremag = (vSize / 2.0f) / (eyePos[2] - zDist);
00497         if (bspheremag > 1.0f)
00498           bspheremag = 1.0f;
00499         break;
00500     }
00501 
00502     if (projection() == DisplayDevice::ORTHOGRAPHIC)
00503       ort->set_bg_mode(OSPRayRenderer::RT_BACKGROUND_TEXTURE_SKY_ORTHO_PLANE);
00504     else
00505       ort->set_bg_mode(OSPRayRenderer::RT_BACKGROUND_TEXTURE_SKY_SPHERE);
00506 
00507     float updir[3] = { 0.0f, 1.0f, 0.0f };
00508     ort->set_bg_color_grad_top(backgradienttopcolor);
00509     ort->set_bg_color_grad_bot(backgradientbotcolor);
00510     ort->set_bg_gradient(updir);
00511     ort->set_bg_gradient_topval(bspheremag);
00512     ort->set_bg_gradient_botval(-bspheremag);
00513   } else {
00514     ort->set_bg_mode(OSPRayRenderer::RT_BACKGROUND_TEXTURE_SOLID);
00515   }
00516 }
00517 
00518 
00520 
00521 void OSPRayDisplayDevice::write_header() {
00522   wkf_timer_start(ort_timer);
00523 
00524   ort->setup_context(xSize, ySize);
00525   write_materials();
00526   write_lights();
00527 
00528   ort->set_aa_samples(aasamples); // set with current FileRenderer values
00529 
00530   // render with/without shadows
00531   if (shadows_enabled() || ao_enabled()) {
00532     if (shadows_enabled() && !ao_enabled())
00533       msgInfo << "Shadow rendering enabled." << sendmsg;
00534 
00535     ort->shadows_on(1); // shadowing mode required
00536   } else {
00537     ort->shadows_on(0); // disable shadows by default
00538   }
00539 
00540   // render with ambient occlusion, but only if shadows are also enabled
00541   if (ao_enabled()) {
00542     msgInfo << "Ambient occlusion enabled." << sendmsg;
00543     msgInfo << "Shadow rendering enabled." << sendmsg;
00544     ort->set_ao_samples(aosamples); // set with current FileRenderer values
00545   } else {
00546     ort->set_ao_samples(0); // disable AO rendering entirely
00547   }
00548 
00549   // Always set the AO parameters, that way the user can enable/disable
00550   // AO on-the-fly in the interactive renderer
00551   ort->set_ao_ambient(get_ao_ambient());
00552   ort->set_ao_direct(get_ao_direct());
00553 
00554   // render with depth of field, but only for perspective projection
00555   if (dof_enabled()) {
00556     msgInfo << "DoF focal blur enabled." << sendmsg;
00557     ort->dof_on(1); // enable DoF rendering
00558     ort->set_camera_dof_fnumber(get_dof_fnumber());
00559     ort->set_camera_dof_focal_dist(get_dof_focal_dist());
00560   } else {
00561     ort->dof_on(0); // disable DoF rendering
00562   }
00563 
00564   // set depth cueing parameters
00565   float start = get_cue_start();
00566   float end = get_cue_end();
00567   float density = get_cue_density();
00568   if (cueingEnabled) {
00569     switch (cueMode) {
00570       case CUE_LINEAR:
00571         ort->set_cue_mode(OSPRayRenderer::RT_FOG_LINEAR, start, end, density);
00572         break;
00573 
00574       case CUE_EXP:
00575         ort->set_cue_mode(OSPRayRenderer::RT_FOG_EXP, start, end, density);
00576         break;
00577 
00578       case CUE_EXP2:
00579         ort->set_cue_mode(OSPRayRenderer::RT_FOG_EXP2, start, end, density);
00580         break;
00581 
00582       case NUM_CUE_MODES:
00583         // this should never happen
00584         break;
00585     }
00586   } else {
00587     ort->set_cue_mode(OSPRayRenderer::RT_FOG_NONE, start, end, density);
00588   }
00589 }
00590 
00591 
00592 void OSPRayDisplayDevice::write_trailer(void){
00593   send_cylinder_buffer(); // send any unsent accumulated cylinder buffer...
00594   send_triangle_buffer(); // send any unsent accumulated triangle buffer...
00595 
00596 #if 0
00597   printf("OSPRay: z: %f zDist: %f vSize %f\n", eyePos[2], zDist, vSize);
00598 #endif
00599   switch (projection()) {
00600     case DisplayDevice::ORTHOGRAPHIC:
00601       ort->set_camera_projection(OSPRayRenderer::RT_ORTHOGRAPHIC);
00602       ort->set_camera_zoom(0.5f / (1.0f / (vSize / 2.0f)));
00603       break;
00604 
00605     case DisplayDevice::PERSPECTIVE:
00606     default:
00607       ort->set_camera_projection(OSPRayRenderer::RT_PERSPECTIVE);
00608       // ort->set_camera_zoom(0.5f / ((eyePos[2] - zDist) / vSize));
00609       ort->set_camera_zoom(0.5f * vSize / (eyePos[2] - zDist));
00610   }
00611 
00612   // set stereoscopic display parameters
00613   ort->set_camera_stereo_eyesep(eyeSep);
00614   ort->set_camera_stereo_convergence_dist(eyeDist);
00615 
00616   char *verbstr = getenv("VMDOSPRAYVERBOSE");
00617   if (verbstr != NULL) {
00618     if (!strupcmp(verbstr, "TIMING") || !strupcmp(verbstr, "DEBUG")) {
00619       double time_scene_graph = wkf_timer_timenow(ort_timer);
00620       printf("OSPRayDisplayDevice) scene graph construction time %.2f\n",
00621              time_scene_graph);
00622     }
00623   }
00624 
00625 #if defined(VMDOSPRAY_INTERACTIVE_OPENGL)
00626   if (isinteractive)
00627     ort->render_to_glwin(my_filename); // interactive progressive ray tracer
00628   else
00629 #endif
00630     ort->render_to_file(my_filename);  // render the scene in batch mode...
00631 
00632 
00633   if (getenv("VMDOSPRAYNODESTROYCONTEXT") == NULL) {
00634     // destroy the current context, because we haven't done enough to ensure
00635     // that we're managing memory well without tearing it all down.
00636     delete ort;
00637 
00638     // make a new OSPRayRenderer object so we're ready for the next run...
00639     ort = new OSPRayRenderer();
00640   } else {
00641     // reset internal state between renders
00642     // reinitialize material cache, clean context state
00643     ort->destroy_scene();
00644   }
00645 
00646   wkf_timer_stop(ort_timer);
00647   printf("OSPRayDisplayDevice) Total rendering time: %.2f sec\n", wkf_timer_time(ort_timer));
00648 
00649   reset_vars(); 
00650 }
00651 
00652 
00653 
00654 #if 0
00655 
00656 void OSPRayDisplayDevice::start_clipgroup(void) {
00657   int i;
00658   int planesenabled = 0;
00659 
00660   for (i=0; i<VMD_MAX_CLIP_PLANE; i++) {
00661     if (clip_mode[i] > 0) {
00662       planesenabled++;  /* count number of active clipping planes */
00663       if (clip_mode[i] > 1)
00664         warningflags |= FILERENDERER_NOCLIP; /* emit warnings */
00665     }
00666   }
00667 
00668   if (planesenabled > 0) {
00669     float *planes = (float *) malloc(planesenabled * 4 * sizeof(float));
00670 
00671     int j=0;
00672     for (i=0; i<VMD_MAX_CLIP_PLANE; i++) {
00673       if (clip_mode[i] > 0) {
00674         float ospray_clip_center[3];
00675         float ospray_clip_normal[3];
00676         float ospray_clip_distance;
00677 
00678         inclipgroup = 1; // we're in a clipping group presently
00679 
00680         // Transform the plane center and the normal
00681         (transMat.top()).multpoint3d(clip_center[i], ospray_clip_center);
00682         (transMat.top()).multnorm3d(clip_normal[i], ospray_clip_normal);
00683         vec_negate(ospray_clip_normal, ospray_clip_normal);
00684 
00685         // Tachyon uses the distance from the origin to the plane for its
00686         // representation, instead of the plane center
00687         ospray_clip_distance = dot_prod(ospray_clip_normal, ospray_clip_center);
00688 
00689         planes[j * 4    ] =  ospray_clip_normal[0];
00690         planes[j * 4 + 1] =  ospray_clip_normal[1];
00691         planes[j * 4 + 2] = -ospray_clip_normal[2];
00692         planes[j * 4 + 3] =  ospray_clip_distance;
00693 
00694 //        ort->clip_fv(planesenabled, planes); // add the clipping planes
00695         j++;
00696       }
00697     }
00698 
00699     free(planes);
00700   } else {
00701     inclipgroup = 0; // Not currently in a clipping group
00702   }
00703 }
00704 
00705 
00706 void OSPRayDisplayDevice::end_clipgroup(void) {
00707   if (inclipgroup) {
00708 //    ort->clip_off();      // disable clipping planes
00709     inclipgroup = 0;      // we're not in a clipping group anymore
00710   }
00711 }
00712 
00713 #endif
00714 
00715 
00716 

Generated on Fri Apr 19 02:45:06 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002