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

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

Generated on Wed Apr 24 02:43:04 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002