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