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