00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00037 #define VMDANARIREPGROUPING 1
00038
00039 #include <math.h>
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <string.h>
00043
00044 #if defined(__linux)
00045 #include <unistd.h>
00046 #endif
00047
00048 #include "Inform.h"
00049 #include "ImageIO.h"
00050 #include "ANARIRenderer.h"
00051 #include "Matrix4.h"
00052 #include "utilities.h"
00053 #include "WKFUtils.h"
00054
00055
00056
00057
00058
00059
00060
00061 #if defined(VMDANARI_INTERACTIVE_OPENGL)
00062 #if (defined(WIN32) || defined(_WIN64)) && defined(_MSC_VER)
00063 #include <windows.h>
00064 #endif
00065
00066 #include <GL/gl.h>
00067 #endif
00068
00069 #if 0
00070 #define DBG()
00071 #else
00072 #define DBG() printf("ANARIRenderer) ++ %s\n", __func__);
00073 #endif
00074
00075 #include <algorithm>
00076
00077 static void vmd_anari_status_callback(void *userData,
00078 ANARIDevice dev,
00079 ANARIObject src,
00080 ANARIDataType srctype,
00081 ANARIStatusSeverity sev,
00082 ANARIStatusCode code,
00083 const char *message) {
00084 switch (sev) {
00085 case ANARI_SEVERITY_FATAL_ERROR:
00086 printf("ANARIRenderer) FATAL: %s\n", message);
00087 break;
00088
00089 case ANARI_SEVERITY_ERROR:
00090 printf("ANARIRenderer) ERROR: %s\n", message);
00091 break;
00092
00093 case ANARI_SEVERITY_WARNING:
00094 printf("ANARIRenderer) WARN: %s\n", message);
00095 break;
00096
00097 case ANARI_SEVERITY_PERFORMANCE_WARNING:
00098 printf("ANARIRenderer) PERF: %s\n", message);
00099 break;
00100
00101 case ANARI_SEVERITY_INFO:
00102 printf("ANARIRenderer) INFO: %s\n", message);
00103 break;
00104
00105 default:
00106 printf("ANARIRenderer) STATUS: %s\n", message);
00107 break;
00108 }
00109 }
00110
00111
00112
00113 void ANARIRender::ANARI_Global_Init(void) {
00114
00115 }
00116
00117
00118
00119 void ANARIRender::ANARI_Global_Shutdown(void) {
00120 }
00121
00123 #if defined(VMDOPENGL)
00124 extern "C" {
00125 typedef void ( *__GLXextFuncPtr)(void);
00126 __GLXextFuncPtr glXGetProcAddress (const GLubyte *procName);
00127 }
00128 #endif
00129
00131 ANARIRender::ANARIRender(void) {
00132 DBG();
00133
00134 anr_timer = wkf_timer_create();
00135 wkf_timer_start(anr_timer);
00136
00137 dev = NULL;
00138 rendererworkarounds = ANARI_NONE;
00139 memset(lastcommentstring, 0, sizeof(lastcommentstring));
00140 seqgrp = 0;
00141
00142
00143 anariRenderer = NULL;
00144 anariFrameBuffer = NULL;
00145 anariCamera = NULL;
00146 anariWorld = NULL;
00147 anariLightData = NULL;
00148
00149
00150 lastrepmesh=0;
00151 lastrepspheres=0;
00152 lastrepcyls=0;
00153
00154 lasterror = 0;
00155 context_created = 0;
00156 buffers_allocated = 0;
00157 scene_created = 0;
00158
00159
00160 time_ctx_create = 0.0;
00161 time_ctx_setup = 0.0;
00162 time_ctx_validate = 0.0;
00163 time_ctx_AS_build = 0.0;
00164 time_ray_tracing = 0.0;
00165 time_image_io = 0.0;
00166
00167
00168 scene_background_mode = RT_BACKGROUND_TEXTURE_SOLID;
00169 memset(scene_bg_color, 0, sizeof(scene_bg_color));
00170 memset(scene_bg_grad_top, 0, sizeof(scene_bg_grad_top));
00171 memset(scene_bg_grad_bot, 0, sizeof(scene_bg_grad_bot));
00172 memset(scene_gradient, 0, sizeof(scene_gradient));
00173 scene_gradient_topval = 1.0f;
00174 scene_gradient_botval = 0.0f;
00175
00176 scene_gradient_invrange = 1.0f / (scene_gradient_topval - scene_gradient_botval);
00177
00178 cam_zoom = 1.0f;
00179 cam_stereo_eyesep = 0.06f;
00180 cam_stereo_convergence_dist = 2.0f;
00181
00182 headlight_enabled = 0;
00183
00184 shadows_enabled = RT_SHADOWS_OFF;
00185 aa_samples = 0;
00186
00187 ao_samples = 0;
00188 ao_direct = 0.3f;
00189 ao_ambient = 0.7f;
00190
00191 dof_enabled = 0;
00192 cam_dof_focal_dist = 2.0f;
00193 cam_dof_fnumber = 64.0f;
00194
00195 fog_mode = RT_FOG_NONE;
00196 fog_start = 0.0f;
00197 fog_end = 10.0f;
00198 fog_density = 0.32f;
00199
00200 rendererworkarounds = ANARI_NONE;
00201 anari_rendermode = ANARI_PATHTRACER;
00202 anari_matclass = ANARI_MATTE;
00203
00204
00205 printf("debugging PID: %d\n", getpid());
00206 if (getenv("VMDANARISLEEP")) {
00207 int sleepsecs = atoi(getenv("VMDANARISLEEP"));
00208 sleep(sleepsecs);
00209 }
00210
00211
00212 if (getenv("VMDANARIUSD")) {
00213 printf("ANARIRenderer) Attempting to load library: 'usd'\n");
00214 lib = anariLoadLibrary("usd", vmd_anari_status_callback, NULL);
00215 dev = anariNewDevice(lib, "usd");
00216
00217 if (!dev) {
00218 printf("ANARIRenderer: failed to load USD ANARI library! Exiting!\n");
00219 exit(-1);
00220 }
00221
00222 int usdConnLogVerbosity = 0;
00223 anariSetParameter(dev, dev, "usd::connection.logverbosity", ANARI_INT32, &usdConnLogVerbosity);
00224
00225 int usdOutputOmniverse = (getenv("VMDUSEOMNIVERSE") != NULL);
00226 if (usdOutputOmniverse) {
00227 if (!getenv("VMDOMNIVERSEHOST")) {
00228 anariSetParameter(dev, dev, "usd::serialize.hostname", ANARI_STRING, "localhost");
00229 } else {
00230 anariSetParameter(dev, dev, "usd::serialize.hostname", ANARI_STRING, getenv("VMDOMNIVERSEHOST"));
00231 }
00232 }
00233
00234 if (!getenv("VMDUSDOUTPUTPATH")) {
00235 anariSetParameter(dev, dev, "usd::serialize.outputpath", ANARI_STRING, "vmdanariusd");
00236 } else {
00237 anariSetParameter(dev, dev, "usd::serialize.outputpath", ANARI_STRING, getenv("VMDUSDOUTPUTPATH"));
00238 }
00239
00240 int usdOutputBinary = (getenv("VMDANARIUSDASCII") != NULL);
00241 anariSetParameter(dev, dev, "usd::serialize.outputbinary", ANARI_BOOL, &usdOutputBinary);
00242
00243 anariCommit(dev, dev);
00244
00245 rendererworkarounds = ANARI_USD;
00246 }
00247
00248
00249
00250 if (!dev) {
00251 const char *userdev = getenv("VMDANARIDEVICE");
00252 if (userdev) {
00253 printf("ANARIRenderer) attempting to load ANARI device '%s'\n", userdev);
00254 lib = anariLoadLibrary(userdev, vmd_anari_status_callback, NULL);
00255
00256 } else {
00257 printf("ANARIRenderer) No library loaded, trying 'example'\n");
00258 lib = anariLoadLibrary("example", vmd_anari_status_callback, NULL);
00259 }
00260
00261
00262 const char **devices = anariGetDeviceSubtypes(lib);
00263 if (!devices) {
00264 printf("ANARIRenderer) No device subtypes returned.\n");
00265 } else {
00266 printf("ANARIRenderer) Available devices:\n");
00267 for (const char **d = devices; *d != NULL; d++)
00268 printf("ANARIRenderer) %s\n", *d);
00269 }
00270
00271
00272 int havepathtracer = 0;
00273 const char **renderers = anariGetObjectSubtypes(lib, "default", ANARI_RENDERER);
00274 if (renderers) {
00275 printf("ANARIRenderer) Available renderers:\n");
00276 for (const char **r = renderers; *r != NULL; r++) {
00277 printf("ANARIRenderer) %s\n", *r);
00278 if (strcmp(*r, "pathtracer") == 0)
00279 havepathtracer = 1;
00280 }
00281 } else {
00282 printf("ANARIRenderer) No renderers available!\n");
00283 }
00284
00285 const char *rendererstr = "default";
00286 if (havepathtracer)
00287 rendererstr = "pathtracer";
00288
00289
00290 const ANARIParameter *rendparams = anariGetObjectParameters(lib, "default", "pathtracer", ANARI_RENDERER);
00291
00292 if (!rendparams) {
00293 printf("ANARIRenderer) Renderer '%s' has no parameters.\n", rendererstr);
00294 } else {
00295 printf("ANARIRenderer) Parameters of '%s':\n", rendererstr);
00296 for (const ANARIParameter *p = rendparams; p->name != NULL; p++) {
00297 const char *desc = (const char *) anariGetParameterInfo(lib,
00298 "default",
00299 "pathtracer",
00300 ANARI_RENDERER,
00301 p->name,
00302 p->type,
00303 "description",
00304 ANARI_STRING);
00305
00306 const int *required = (const int *) anariGetParameterInfo(lib,
00307 "default",
00308 "pathtracer",
00309 ANARI_RENDERER,
00310 p->name,
00311 p->type,
00312 "required",
00313 ANARI_BOOL);
00314
00315 printf("ANARIRenderer) [%d] %s, %s: %s\n",
00316 int(p->type), p->name, required && *required ? "REQ" : "OPT", desc);
00317 }
00318 }
00319
00320 dev = anariNewDevice(lib, "default");
00321
00322 if (!dev) {
00323 printf("ANARIRenderer: failed to load ANARI library! Exiting!\n");
00324 exit(-1);
00325 }
00326
00327 anariCommit(dev, dev);
00328
00329 rendererworkarounds = ANARI_NONE;
00330 anari_rendermode = ANARI_PATHTRACER;
00331 }
00332
00333
00334 if (getenv("VMDANARITRACE")) {
00335
00336
00337 anariLoadLibrary("debug", vmd_anari_status_callback, NULL);
00338 }
00339
00340
00341
00342 #if 0
00343 #if 1
00344 if (getenv("VMDANARITRACE")) {
00345
00346
00347 lib = anariLoadLibrary("debug", vmd_anari_status_callback, NULL);
00348 }
00349
00350 if (getenv("VMDANARINVGL")) {
00351 printf("ANARIRenderer) Attempting to load library: 'nvgl'\n");
00352 lib = anariLoadLibrary("nvgl", vmd_anari_status_callback, NULL);
00353 dev = anariNewDevice(lib, "nvgl");
00354 rendererworkarounds = ANARI_NVGL;
00355 #if defined(VMDOPENGL)
00356 const void *ptr = (const void*) glXGetProcAddress;
00357 anariSetParameter(dev, dev, "oglGetProcAddress", ANARI_VOID_PTR, &ptr);
00358 #endif
00359 } else if (getenv("VMDANARIUSD")) {
00360 printf("ANARIRenderer) Attempting to load library: 'usd'\n");
00361 lib = anariLoadLibrary("usd", vmd_anari_status_callback, NULL);
00362 dev = anariNewDevice(lib, "usd");
00363 anariSetParameter(dev, dev, "serialize.location", ANARI_STRING, "/tmp/foobar");
00364 rendererworkarounds = ANARI_USD;
00365 } else if (getenv("VMDANARIOSPRAY")) {
00366 printf("ANARIRenderer) Attempting to load library: 'ospray'\n");
00367 lib = anariLoadLibrary("ospray", vmd_anari_status_callback, NULL);
00368 dev = anariNewDevice(lib, "ospray");
00369 rendererworkarounds = ANARI_OSPRAY;
00370 }
00371 #endif
00372
00373 if (!dev) {
00374 printf("ANARIRenderer) No devices loaded, trying 'example'\n");
00375 lib = anariLoadLibrary("example", vmd_anari_status_callback, NULL);
00376 dev = anariNewDevice(lib, "example");
00377 }
00378
00379 if (getenv("VMDANARIOWL") == NULL) {
00380 int loglevel = ANARI_LOG_INFO;
00381 loglevel = ANARI_LOG_DEBUG;
00382 printf("ANARIRenderer) setting device log level property...\n");
00383 anariSetParameter(dev, dev, "logLevel", ANARI_INT32, &loglevel);
00384 }
00385 anariCommit(dev, dev);
00386
00387 printf("ANARIRenderer) setting renderer mode\n");
00388 anari_rendermode = ANARI_PATHTRACER;
00389 if (getenv("VMDANARISCIVIS")) {
00390 printf("ANARIRenderer) Renderer mode set to 'scivis'\n");
00391 anari_rendermode = ANARI_SCIVIS;
00392 }
00393 if (getenv("VMDANARIPATHTRACER")) {
00394 printf("ANARIRenderer) Renderer mode set to 'pathtracer'\n");
00395 anari_rendermode = ANARI_PATHTRACER;
00396 }
00397 #endif
00398
00399
00400
00401
00402 verbose = RT_VERB_DEBUG;
00403 check_verbose_env();
00404
00405 printf("ANARIRenderer) clear/init scene data structures\n");
00406 destroy_scene();
00407 anariInstances.clear();
00408
00409 init_materials();
00410
00411 directional_lights.clear();
00412 positional_lights.clear();
00413
00414
00415 trimesh_v3f_n3f_c3f.clear();
00416 spheres_color.clear();
00417 cylinders_color.clear();
00418 surfbufs.clear();
00419
00420 double starttime = wkf_timer_timenow(anr_timer);
00421
00422 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating context...\n");
00423
00424
00425
00426
00427
00428 const char *rstr;
00429 switch (anari_rendermode) {
00430 case ANARI_PATHTRACER: rstr = "pathtracer"; break;
00431 case ANARI_DEFAULT: rstr = "default"; break;
00432 case ANARI_SCIVIS: rstr = "scivis"; break;
00433 case ANARI_AO: rstr = "ambientocclusion"; break;
00434 default: rstr = "default"; break;
00435 }
00436
00437 if (rendererworkarounds == ANARI_NVGL) {
00438 rstr = "default";
00439 anari_rendermode = ANARI_DEFAULT;
00440 printf("ANARIRenderer) INFO: NVGL back-end requires default renderer\n");
00441 }
00442
00443 if ((anariRenderer = anariNewRenderer(dev, rstr)) == NULL) {
00444 printf("ANARIRenderer) Failed to load renderer '%s'!\n", rstr);
00445 }
00446 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
00447 printf("ANARIRenderer) created renderer '%s'\n", rstr);
00448 }
00449
00450 time_ctx_create = wkf_timer_timenow(anr_timer) - starttime;
00451
00452 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
00453 printf("ANARIRenderer) context creation time: %.2f\n", time_ctx_create);
00454 }
00455
00456 context_created = 1;
00457 }
00458
00459
00461 ANARIRender::~ANARIRender(void) {
00462 DBG();
00463
00464 destroy_scene();
00465
00466 if (context_created && (anariRenderer != NULL))
00467 anariRelease(dev, anariRenderer);
00468
00469 anariRenderer=NULL;
00470 context_created=0;
00471
00472 if (dev != NULL)
00473 anariRelease(dev, dev);
00474 dev=NULL;
00475
00476
00477 lib=NULL;
00478
00479 materialcache.clear();
00480
00481 directional_lights.clear();
00482 positional_lights.clear();
00483
00484 wkf_timer_destroy(anr_timer);
00485 }
00486
00487
00488 void ANARIRender::check_verbose_env() {
00489 DBG();
00490
00491 char *verbstr = getenv("VMDANARIVERBOSE");
00492 if (verbstr != NULL) {
00493
00494 if (!strupcmp(verbstr, "MIN")) {
00495 verbose = RT_VERB_MIN;
00496 printf("ANARIRenderer) verbose setting: minimum\n");
00497 } else if (!strupcmp(verbstr, "TIMING")) {
00498 verbose = RT_VERB_TIMING;
00499 printf("ANARIRenderer) verbose setting: timing data\n");
00500 } else if (!strupcmp(verbstr, "DEBUG")) {
00501 verbose = RT_VERB_DEBUG;
00502 printf("ANARIRenderer) verbose setting: full debugging data\n");
00503 }
00504 }
00505 }
00506
00507
00508 void ANARIRender::setup_context(int w, int h) {
00509 DBG();
00510 double starttime = wkf_timer_timenow(anr_timer);
00511 time_ctx_setup = 0;
00512
00513 lasterror = 0;
00514 width = w;
00515 height = h;
00516
00517 if (!context_created)
00518 return;
00519
00520 check_verbose_env();
00521
00522
00523 if (getenv("VMDANARIMAXDEPTH")) {
00524 int maxdepth = atoi(getenv("VMDANARIMAXDEPTH"));
00525 if (maxdepth > 0 && maxdepth <= 20) {
00526 printf("ANARIRenderer) Setting maxdepth to %d...\n", maxdepth);
00527 anariSetParameter(dev, anariRenderer, "maxPathLength", ANARI_INT32, &maxdepth);
00528 } else {
00529 printf("ANARIRenderer) ignoring out-of-range maxdepth: %d...\n", maxdepth);
00530 }
00531 } else {
00532 int maxdepth = 20;
00533 anariSetParameter(dev, anariRenderer, "maxPathLength", ANARI_INT32, &maxdepth);
00534 }
00535
00536 #if 0
00537
00538
00539
00540 const int one = 1;
00541 anariSetParameter(dev, anariRenderer, "aoTransparencyEnabled", ANARI_INT32, &one);
00542 #endif
00543
00544 time_ctx_setup = wkf_timer_timenow(anr_timer) - starttime;
00545 }
00546
00547
00548 void ANARIRender::destroy_scene() {
00549 DBG();
00550
00551 double starttime = wkf_timer_timenow(anr_timer);
00552 time_ctx_destroy_scene = 0;
00553
00554
00555 cylinder_array_cnt = 0;
00556 cylinder_array_color_cnt = 0;
00557 ring_array_color_cnt = 0;
00558 sphere_array_cnt = 0;
00559 sphere_array_color_cnt = 0;
00560 tricolor_cnt = 0;
00561 trimesh_c4u_n3b_v3f_cnt = 0;
00562 trimesh_n3b_v3f_cnt = 0;
00563 trimesh_n3f_v3f_cnt = 0;
00564 trimesh_v3f_cnt = 0;
00565
00566
00567 lastrepmesh=0;
00568 lastrepspheres=0;
00569 lastrepcyls=0;
00570
00571
00572
00573 framebuffer_destroy();
00574
00575
00576 int i;
00577 for (i=0; i<trimesh_v3f_n3f_c3f.num(); i++) {
00578 free(trimesh_v3f_n3f_c3f[i].v);
00579 trimesh_v3f_n3f_c3f[i].v = NULL;
00580 free(trimesh_v3f_n3f_c3f[i].n);
00581 trimesh_v3f_n3f_c3f[i].n = NULL;
00582 free(trimesh_v3f_n3f_c3f[i].c);
00583 trimesh_v3f_n3f_c3f[i].c = NULL;
00584 free(trimesh_v3f_n3f_c3f[i].f);
00585 trimesh_v3f_n3f_c3f[i].f = NULL;
00586 }
00587 trimesh_v3f_n3f_c3f.clear();
00588
00589 for (i=0; i<spheres_color.num(); i++) {
00590 free(spheres_color[i].xyz);
00591 spheres_color[i].xyz = NULL;
00592 free(spheres_color[i].radii);
00593 spheres_color[i].radii = NULL;
00594 free(spheres_color[i].colors);
00595 spheres_color[i].colors = NULL;
00596 }
00597 spheres_color.clear();
00598
00599 for (i=0; i<cylinders_color.num(); i++) {
00600 free(cylinders_color[i].cyls);
00601 cylinders_color[i].cyls = NULL;
00602 free(cylinders_color[i].rads);
00603 cylinders_color[i].rads = NULL;
00604 free(cylinders_color[i].ind);
00605 cylinders_color[i].ind = NULL;
00606 free(cylinders_color[i].cols);
00607 cylinders_color[i].cols = NULL;
00608 }
00609 cylinders_color.clear();
00610
00611 for (i=0; i<surfbufs.num(); i++) {
00612 free(surfbufs[i]);
00613 surfbufs[i] = NULL;
00614 }
00615 surfbufs.clear();
00616
00617 anariInstances.clear();
00618
00619 for (i=0; i<materialcache.num(); i++) {
00620 if (materialcache[i].isvalid)
00621 anariRelease(dev, materialcache[i].mat);
00622 }
00623 materialcache.clear();
00624
00625 int lcnt = anariLights.num();
00626 for (i = 0; i < lcnt; ++i) {
00627 anariRelease(dev, anariLights[i]);
00628 }
00629 anariLights.clear();
00630
00631
00632 if (anariCamera != NULL) {
00633 anariRelease(dev, anariCamera);
00634 anariCamera = NULL;
00635 }
00636
00637 if (anariWorld != NULL) {
00638 anariRelease(dev, anariWorld);
00639 anariWorld = NULL;
00640 }
00641
00642
00643 double endtime = wkf_timer_timenow(anr_timer);
00644 time_ctx_destroy_scene = endtime - starttime;
00645
00646 scene_created = 0;
00647 }
00648
00649
00650 void ANARIRender::update_rendering_state(int interactive) {
00651 DBG();
00652 if (!context_created)
00653 return;
00654
00655 wkf_timer_start(anr_timer);
00656
00657
00658
00659
00660
00661
00662 interactive_renderer = interactive;
00663
00664
00665
00666 long totaltris = tricolor_cnt + trimesh_c4u_n3b_v3f_cnt +
00667 trimesh_n3b_v3f_cnt + trimesh_n3f_v3f_cnt + trimesh_v3f_cnt;
00668
00669 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
00670 printf("ANARIRenderer) cyl %ld, ring %ld, sph %ld, tri %ld, tot: %ld lt %ld\n",
00671 cylinder_array_cnt + cylinder_array_color_cnt,
00672 ring_array_color_cnt,
00673 sphere_array_cnt + sphere_array_color_cnt,
00674 totaltris,
00675 cylinder_array_cnt + cylinder_array_color_cnt + ring_array_color_cnt + sphere_array_cnt + sphere_array_color_cnt + totaltris,
00676 directional_lights.num() + positional_lights.num());
00677 }
00678
00679 if (verbose == RT_VERB_DEBUG) {
00680 printf("ANARIRenderer) using fully general shader and materials.\n");
00681 }
00682
00683
00684
00685 if (verbose == RT_VERB_DEBUG) {
00686 printf("ANARIRenderer) scene bg mode: %d\n", scene_background_mode);
00687
00688 printf("ANARIRenderer) scene bgsolid: %.2f %.2f %.2f\n",
00689 scene_bg_color[0], scene_bg_color[1], scene_bg_color[2]);
00690
00691 printf("ANARIRenderer) scene bggradT: %.2f %.2f %.2f\n",
00692 scene_bg_grad_top[0], scene_bg_grad_top[1], scene_bg_grad_top[2]);
00693
00694 printf("ANARIRenderer) scene bggradB: %.2f %.2f %.2f\n",
00695 scene_bg_grad_bot[0], scene_bg_grad_bot[1], scene_bg_grad_bot[2]);
00696
00697 printf("ANARIRenderer) bg gradient: %f %f %f top: %f bot: %f\n",
00698 scene_gradient[0], scene_gradient[1], scene_gradient[2],
00699 scene_gradient_topval, scene_gradient_botval);
00700 }
00701
00702
00703 scene_gradient_invrange = 1.0f / (scene_gradient_topval - scene_gradient_botval);
00704
00705
00706
00707
00708 if (verbose == RT_VERB_DEBUG) {
00709 printf("ANARIRenderer) adding lights: dir: %ld pos: %ld\n",
00710 directional_lights.num(), positional_lights.num());
00711 }
00712
00713
00714
00715 if (verbose == RT_VERB_DEBUG)
00716 printf("ANARIRenderer) Finalizing ANARI scene graph...\n");
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727 if (verbose == RT_VERB_DEBUG) {
00728 printf("ANARIRenderer) cam zoom factor %f\n", cam_zoom);
00729 printf("ANARIRenderer) cam stereo eye separation %f\n", cam_stereo_eyesep);
00730 printf("ANARIRenderer) cam stereo convergence distance %f\n",
00731 cam_stereo_convergence_dist);
00732 printf("ANARIRenderer) cam DoF focal distance %f\n", cam_dof_focal_dist);
00733 printf("ANARIRenderer) cam DoF f/stop %f\n", cam_dof_fnumber);
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 if (verbose == RT_VERB_DEBUG) {
00748 printf("ANARIRenderer) setting sample counts: AA %d AO %d\n", aa_samples, ao_samples);
00749 printf("ANARIRenderer) setting AO factors: AOA %f AOD %f\n", ao_ambient, ao_direct);
00750 }
00751
00752
00753
00754
00755
00756
00757
00758 #if 1
00759 ext_aa_loops = std::max(aa_samples, 1) * std::max(ao_samples, 1);
00760 #else
00761 ext_aa_loops = 1;
00762 if (ao_samples > 0 || (aa_samples > 4)) {
00763
00764
00765 ext_aa_loops = 1 + aa_samples;
00766
00767 } else {
00768
00769
00770
00771 }
00772
00773 #endif
00774
00775 if (verbose == RT_VERB_DEBUG) {
00776 if (ext_aa_loops > 1)
00777 printf("ANARIRenderer) Running ANARI multi-pass: %d loops\n", ext_aa_loops);
00778 else
00779 printf("ANARIRenderer) Running ANARI single-pass: %d total samples\n", 1+aa_samples);
00780 }
00781
00782
00783
00784
00785
00786
00787
00788
00789 }
00790
00791
00792 void ANARIRender::framebuffer_config(int fbwidth, int fbheight) {
00793 DBG();
00794 if (!context_created)
00795 return;
00796
00797 width = fbwidth;
00798 height = fbheight;
00799
00800
00801 if (buffers_allocated) {
00802
00803
00804 if (verbose == RT_VERB_DEBUG) {
00805 printf("ANARIRenderer) resizing framebuffer\n");
00806 }
00807 framebuffer_resize(width, height);
00808 } else {
00809
00810
00811
00812 if (verbose == RT_VERB_DEBUG) {
00813 printf("ANARIRenderer) creating framebuffer and accum. buffer\n");
00814 }
00815
00816
00817
00818 buffers_allocated = 1;
00819 }
00820 }
00821
00822
00823 void ANARIRender::framebuffer_resize(int fbwidth, int fbheight) {
00824 DBG();
00825 if (!context_created)
00826 return;
00827
00828 width = fbwidth;
00829 height = fbheight;
00830
00831 if (buffers_allocated) {
00832 if (verbose == RT_VERB_DEBUG)
00833 printf("ANARIRenderer) framebuffer_resize(%d x %d)\n", width, height);
00834 framebuffer_destroy();
00835 }
00836
00837
00838
00839 buffers_allocated = 1;
00840 }
00841
00842
00843 void ANARIRender::framebuffer_destroy() {
00844 DBG();
00845 if (!context_created)
00846 return;
00847
00848
00849
00850
00851 buffers_allocated = 0;
00852 }
00853
00854
00855
00856 void ANARIRender::commit_rep() {
00857 #if defined(VMDANARIREPGROUPING)
00858 int i;
00859 int nmeshbufs = trimesh_v3f_n3f_c3f.num() - lastrepmesh;
00860 int nspherebufs = spheres_color.num() - lastrepspheres;
00861 int ncylbufs = cylinders_color.num() - lastrepcyls;
00862 int numsurfs = nmeshbufs + nspherebufs + ncylbufs;
00863
00864 if (verbose == RT_VERB_DEBUG)
00865 printf("ANARIRenderer) Committing rep, %d surfs: %d meshbufs, %d spbufs, %d cylbufs\n", numsurfs, nmeshbufs, nspherebufs, ncylbufs);
00866
00867 if (numsurfs < 1)
00868 return;
00869
00870 ANARISurface *surfs = (ANARISurface *) calloc(1, numsurfs * sizeof(ANARISurface));
00871 surfbufs.append(surfs);
00872 int cursurf=0;
00873
00874
00875 for (i=lastrepmesh; i<trimesh_v3f_n3f_c3f.num(); i++) {
00876 if (verbose == RT_VERB_DEBUG)
00877 printf("ANARIRenderer) Adding triangle mesh[%d]: %d tris ...\n",
00878 i, trimesh_v3f_n3f_c3f[i].num);
00879
00880 surfs[cursurf++] = trimesh_v3f_n3f_c3f[i].surf;
00881 }
00882 lastrepmesh=trimesh_v3f_n3f_c3f.num();
00883
00884
00885
00886 for (i=lastrepspheres; i<spheres_color.num(); i++) {
00887 if (verbose == RT_VERB_DEBUG)
00888 printf("ANARIRenderer) Adding sphere_color array [%d]: %d spheres ...\n",
00889 i, spheres_color[i].num);
00890
00891 surfs[cursurf++] = spheres_color[i].surf;
00892 }
00893 lastrepspheres=spheres_color.num();
00894
00895
00896
00897 for (i=lastrepcyls; i<cylinders_color.num(); i++) {
00898 if (verbose == RT_VERB_DEBUG)
00899 printf("ANARIRenderer) Adding cylinders_color array [%d]: %d cylinders...\n",
00900 i, cylinders_color[i].num);
00901
00902 surfs[cursurf++] = cylinders_color[i].surf;
00903 }
00904 lastrepcyls=cylinders_color.num();
00905
00906
00907
00908 ANARIGroup group = anariNewGroup(dev);
00909 #if 1
00910 printf("ANARIRenderer) Assigning group name.\n");
00911
00912 if (rendererworkarounds == ANARI_USD && (strlen(lastcommentstring) > 0)) {
00913 char strbuf[2048];
00914 sprintf(strbuf, "%s_seqgrp%d", lastcommentstring, seqgrp);
00915 anariSetParameter(dev, group, "name", ANARI_STRING, strbuf);
00916 seqgrp++;
00917 }
00918 #endif
00919
00920 printf("ANARIRenderer) Generating surface array...\n");
00921 ANARIArray1D surfobj = anariNewArray1D(dev, &surfs[0], 0, 0, ANARI_SURFACE, numsurfs, 0);
00922 anariCommit(dev, surfobj);
00923
00924 printf("ANARIRenderer) Generating group.\n");
00925 anariSetParameter(dev, group, "surface", ANARI_ARRAY1D, &surfobj);
00926
00927 printf("ANARIRenderer) Committing group.\n");
00928 anariCommit(dev, group);
00929 anariRelease(dev, surfobj);
00930
00931 for (i=0; i<numsurfs; i++) {
00932 anariRelease(dev, surfs[i]);
00933 }
00934
00935 ANARIInstance instance = anariNewInstance(dev);
00936 anariSetParameter(dev, instance, "group", ANARI_GROUP, &group);
00937 anariCommit(dev, instance);
00938 anariRelease(dev, group);
00939
00940 anariInstances.append(instance);
00941 #endif
00942 }
00943
00944
00945 void ANARIRender::render_compile_and_validate(void) {
00946 int i;
00947
00948 DBG();
00949 if (!context_created)
00950 return;
00951
00952
00953
00954
00955 double startctxtime = wkf_timer_timenow(anr_timer);
00956
00957
00958
00959
00960 commit_rep();
00961
00962 if ((anariWorld = anariNewWorld(dev)) == NULL) {
00963 printf("ANARIRenderer) Failed to create new world!\n");
00964 }
00965
00966 if (verbose == RT_VERB_DEBUG)
00967 printf("ANARIRenderer) num spheres = %ld\n", spheres_color.num());
00968
00969
00970
00971
00972
00973 float cam_pos_orig[3] = {0.0f, 0.0f, 2.0f};
00974 float cam_U_orig[3] = {1.0f, 0.0f, 0.0f};
00975 float cam_V_orig[3] = {0.0f, 1.0f, 0.0f};
00976 float cam_W_orig[3] = {0.0f, 0.0f, -1.0f};
00977
00978 float cam_pos[3], cam_U[3], cam_V[3], cam_W[3];
00979 vec_copy(cam_pos, cam_pos_orig);
00980 vec_copy(cam_U, cam_U_orig);
00981 vec_copy(cam_V, cam_V_orig);
00982 vec_copy(cam_W, cam_W_orig);
00983
00984 if (camera_projection == ANARIRender::RT_ORTHOGRAPHIC) {
00985 if(!anariCamera) anariCamera = anariNewCamera(dev, "orthographic");
00986
00987 float orthoheight = 2.0f * cam_zoom;
00988 anariSetParameter(dev, anariCamera, "height", ANARI_FLOAT32, &orthoheight);
00989
00990 if (dof_enabled) {
00991 msgWarn << "ANARIRenderer) DoF not implemented for orthographic camera!" << sendmsg;
00992 }
00993 } else {
00994 if(!anariCamera) anariCamera = anariNewCamera(dev, "perspective");
00995
00996 float camfovy = 2.0f*180.0f*(atanf(cam_zoom)/M_PI);
00997 anariSetParameter(dev, anariCamera, "fovy", ANARI_FLOAT32, &camfovy);
00998
00999 if (dof_enabled) {
01000 anariSetParameter(dev, anariCamera, "focusDistance", ANARI_FLOAT32, &cam_dof_focal_dist);
01001 float dofaprad = cam_dof_focal_dist / (2.0f * cam_zoom * cam_dof_fnumber);
01002 anariSetParameter(dev, anariCamera, "apertureRadius", ANARI_FLOAT32, &dofaprad);
01003 } else {
01004 float dofaprad = 0.0f;
01005 anariSetParameter(dev, anariCamera, "apertureRadius", ANARI_FLOAT32, &dofaprad);
01006 }
01007 }
01008
01009 if (anariCamera) {
01010 float camaspect = width / ((float) height);
01011 anariSetParameter(dev, anariCamera, "aspect", ANARI_FLOAT32, &camaspect);
01012 anariSetParameter(dev, anariCamera, "position", ANARI_FLOAT32_VEC3, cam_pos);
01013 anariSetParameter(dev, anariCamera, "direction", ANARI_FLOAT32_VEC3, cam_W);
01014 anariSetParameter(dev, anariCamera, "up", ANARI_FLOAT32_VEC3, cam_V);
01015 anariCommit(dev, anariCamera);
01016 }
01017
01018
01019
01020
01021 framebuffer_config(width, height);
01022
01023
01024
01025
01026 if (verbose == RT_VERB_DEBUG)
01027 printf("ANARIRenderer) setting lights...\n");
01028
01029
01030 float lightscale = 1.0f;
01031 if (ao_samples != 0)
01032 lightscale = ao_direct;
01033
01034 for (i = 0; i < directional_lights.num(); ++i) {
01035 ANARILight light = anariNewLight(dev, "directional");
01036 anariSetParameter(dev, light, "color", ANARI_FLOAT32_VEC3, directional_lights[i].color);
01037
01038
01039
01040
01041
01042 float lightDir[3];
01043 vec_negate(lightDir, directional_lights[i].dir);
01044 vec_normalize(lightDir);
01045 anariSetParameter(dev, light, "direction", ANARI_FLOAT32_VEC3, lightDir);
01046 anariCommit(dev, light);
01047 anariLights.append(light);
01048 }
01049
01050
01051
01052
01053
01054
01055 if (ao_samples != 0) {
01056
01057 if (getenv("VMDANARIDEVICE") && !strcmp(getenv("VMDANARIDEVICE"), "visrtx")) {
01058 float tmp = ao_ambient * 1.5f;
01059 anariSetParameter(dev, anariRenderer, "ambientLight", ANARI_FLOAT32, &tmp);
01060 } else {
01061 ANARILight light = anariNewLight(dev, "ambient");
01062
01063
01064 anariSetParameter(dev, light, "intensity", ANARI_FLOAT32, &ao_ambient);
01065
01066 float whitecol[] = { 1.0f, 1.0f, 1.0f };
01067 anariSetParameter(dev, light, "color", ANARI_FLOAT32_VEC3, whitecol);
01068
01069 anariCommit(dev, light);
01070 anariLights.append(light);
01071 }
01072 }
01073
01074 if (verbose == RT_VERB_DEBUG)
01075 printf("ANARIRenderer) setting sample counts...\n");
01076
01077
01078 float bgcoltmp[4];
01079 vec_copy(bgcoltmp, scene_bg_color);
01080 bgcoltmp[3] = 1.0f;
01081 anariSetParameter(dev, anariRenderer, "backgroundColor", ANARI_FLOAT32_VEC4, bgcoltmp);
01082
01083 if (rendererworkarounds != ANARI_USD) {
01084 if (ao_samples && interactive_renderer) {
01085 const int one = 1;
01086 anariSetParameter(dev, anariRenderer, "pixelSamples", ANARI_INT32, &one);
01087 if (anari_rendermode == ANARI_SCIVIS)
01088 anariSetParameter(dev, anariRenderer, "aoSamples", ANARI_INT32, &one);
01089 } else {
01090 anariSetParameter(dev, anariRenderer, "pixelSamples", ANARI_INT32, &aa_samples);
01091 if (anari_rendermode == ANARI_SCIVIS)
01092 anariSetParameter(dev, anariRenderer, "aoSamples", ANARI_INT32, &ao_samples);
01093 }
01094
01095 if (getenv("VMDANARIAOMAXDIST")) {
01096 float tmp = atof(getenv("VMDANARIAOMAXDIST"));
01097 if (verbose == RT_VERB_DEBUG) {
01098 printf("ANARIRenderer) setting AO maxdist: %f\n", tmp);
01099 }
01100 anariSetParameter(dev, anariRenderer, "aoRadius", ANARI_FLOAT32, &tmp);
01101 }
01102 }
01103
01104 if (rendererworkarounds != ANARI_USD) {
01105 #if 1
01106
01107
01108 msgInfo << "Shadow rendering enabled." << sendmsg;
01109 #else
01110 if (shadows_enabled || ao_samples) {
01111 if (shadows_enabled && !ao_samples)
01112 msgInfo << "Shadow rendering enabled." << sendmsg;
01113
01114 const int one = 1;
01115 anariSetParameter(dev, anariRenderer, "shadowsEnabled", ANARI_INT32, &one);
01116 } else {
01117 const int zero = 0;
01118 anariSetParameter(dev, anariRenderer, "shadowsEnabled", ANARI_INT32, &zero);
01119 }
01120 #endif
01121 }
01122
01123
01124 if (ao_samples) {
01125 msgInfo << "Ambient occlusion enabled." << sendmsg;
01126
01127 }
01128
01129 if (verbose == RT_VERB_DEBUG)
01130 printf("ANARIRenderer) Committing geometry buffers...\n");
01131
01132 #if !defined(VMDANARIREPGROUPING)
01133 if (verbose == RT_VERB_DEBUG)
01134 printf("ANARIRenderer) Committing %ld trimesh buffers...\n", trimesh_v3f_n3f_c3f.num());
01135
01136
01137 for (i=0; i<trimesh_v3f_n3f_c3f.num(); i++) {
01138 if (verbose == RT_VERB_DEBUG)
01139 printf("ANARIRenderer) Adding triangle mesh[%d]: %d tris ...\n",
01140 i, trimesh_v3f_n3f_c3f[i].num);
01141
01142 ANARIGroup group = anariNewGroup(dev);
01143 #if 1
01144
01145 if (rendererworkarounds == ANARI_USD && (strlen(lastcommentstring) > 0)) {
01146
01147
01148 char strbuf[2048];
01149 sprintf(strbuf, "%s_seqgrp%d", lastcommentstring, seqgrp);
01150 anariSetParameter(dev, group, "name", ANARI_STRING, strbuf);
01151 seqgrp++;
01152 }
01153 #endif
01154 ANARIArray1D surfs = anariNewArray1D(dev, &trimesh_v3f_n3f_c3f[i].surf, 0, 0, ANARI_SURFACE, 1, 0);
01155 anariCommit(dev, surfs);
01156 anariRelease(dev, trimesh_v3f_n3f_c3f[i].surf);
01157 anariSetParameter(dev, group, "surface", ANARI_ARRAY1D, &surfs);
01158 anariCommit(dev, group);
01159 anariRelease(dev, surfs);
01160
01161 ANARIInstance instance = anariNewInstance(dev);
01162 anariSetParameter(dev, instance, "group", ANARI_GROUP, &group);
01163 anariCommit(dev, instance);
01164 anariRelease(dev, group);
01165
01166 anariInstances.append(instance);
01167 }
01168
01169 if (verbose == RT_VERB_DEBUG)
01170 printf("ANARIRenderer) Committing %ld sphere buffers...\n", spheres_color.num());
01171
01172
01173 for (i=0; i<spheres_color.num(); i++) {
01174 if (verbose == RT_VERB_DEBUG)
01175 printf("ANARIRenderer) Adding sphere_color array [%d]: %d spheres ...\n",
01176 i, spheres_color[i].num);
01177
01178 ANARIGroup group = anariNewGroup(dev);
01179 #if 1
01180
01181 if (rendererworkarounds == ANARI_USD && (strlen(lastcommentstring) > 0)) {
01182
01183
01184 char strbuf[2048];
01185 sprintf(strbuf, "%s_seqgrp%d", lastcommentstring, seqgrp);
01186 anariSetParameter(dev, group, "name", ANARI_STRING, strbuf);
01187 seqgrp++;
01188 }
01189 #endif
01190 ANARIArray1D surfs = anariNewArray1D(dev, &spheres_color[i].surf, 0, 0, ANARI_SURFACE, 1, 0);
01191 anariCommit(dev, surfs);
01192 anariRelease(dev, spheres_color[i].surf);
01193 anariSetParameter(dev, group, "surface", ANARI_ARRAY1D, &surfs);
01194 anariCommit(dev, group);
01195 anariRelease(dev, surfs);
01196
01197 ANARIInstance instance = anariNewInstance(dev);
01198 anariSetParameter(dev, instance, "group", ANARI_GROUP, &group);
01199 anariCommit(dev, instance);
01200 anariRelease(dev, group);
01201
01202 anariInstances.append(instance);
01203 }
01204
01205 if (verbose == RT_VERB_DEBUG)
01206 printf("ANARIRenderer) Committing %ld cylinder buffers...\n", cylinders_color.num());
01207
01208
01209 for (i=0; i<cylinders_color.num(); i++) {
01210 if (verbose == RT_VERB_DEBUG)
01211 printf("ANARIRenderer) Adding cylinders_color array [%d]: %d cylinders...\n",
01212 i, cylinders_color[i].num);
01213
01214 ANARIGroup group = anariNewGroup(dev);
01215 #if 1
01216
01217 if (rendererworkarounds == ANARI_USD && (strlen(lastcommentstring) > 0)) {
01218
01219
01220 char strbuf[2048];
01221 sprintf(strbuf, "%s_seqgrp%d", lastcommentstring, seqgrp);
01222 anariSetParameter(dev, group, "name", ANARI_STRING, strbuf);
01223 seqgrp++;
01224 }
01225 #endif
01226 ANARIArray1D surfs = anariNewArray1D(dev, &cylinders_color[i].surf, 0, 0, ANARI_SURFACE, 1, 0);
01227 anariCommit(dev, surfs);
01228 anariRelease(dev, cylinders_color[i].surf);
01229 anariSetParameter(dev, group, "surface", ANARI_ARRAY1D, &surfs);
01230 anariCommit(dev, group);
01231 anariRelease(dev, surfs);
01232
01233 ANARIInstance instance = anariNewInstance(dev);
01234 anariSetParameter(dev, instance, "group", ANARI_GROUP, &group);
01235 anariCommit(dev, instance);
01236 anariRelease(dev, group);
01237
01238 anariInstances.append(instance);
01239 }
01240 #endif
01241
01242
01243 if (verbose == RT_VERB_DEBUG)
01244 printf("ANARIRenderer) Attaching instances to scene...\n");
01245
01246
01247 ANARIArray1D instances = anariNewArray1D(dev, &anariInstances[0], 0, 0, ANARI_INSTANCE, anariInstances.num(), 0);
01248 anariCommit(dev, instances);
01249 anariSetParameter(dev, anariWorld, "instance", ANARI_ARRAY1D, &instances);
01250 anariRelease(dev, instances);
01251 for (i=0; i<anariInstances.num(); i++) {
01252 anariRelease(dev, anariInstances[i]);
01253 }
01254 anariInstances.clear();
01255
01256 if (verbose == RT_VERB_DEBUG)
01257 printf("ANARIRenderer) Attaching %ld lights to scene...\n", anariLights.num());
01258
01259 if (verbose == RT_VERB_DEBUG)
01260 printf("ANARIRenderer) Committing anariWorld...\n");
01261
01262
01263 if (rendererworkarounds == ANARI_USD && (strlen(lastcommentstring) > 0)) {
01264 anariSetParameter(dev, anariWorld, "name", ANARI_STRING, "VMD World");
01265 }
01266
01267 if (anariLights.num() > 0) {
01268
01269 ANARIArray1D lights = anariNewArray1D(dev, &anariLights[0], 0, 0, ANARI_LIGHT, anariLights.num(), 0);
01270 anariCommit(dev, lights);
01271 anariSetParameter(dev, anariWorld, "light", ANARI_ARRAY1D, &lights);
01272 anariCommit(dev, anariWorld);
01273 anariRelease(dev, lights);
01274 } else {
01275 anariCommit(dev, anariWorld);
01276 }
01277
01278
01279 float worldBounds[6] = {};
01280 if (anariGetProperty(dev, anariWorld, "bounds", ANARI_FLOAT32_BOX3,
01281 worldBounds, sizeof(worldBounds), ANARI_WAIT)) {
01282 printf("ANARIRenderer) world bounds: ({%f, %f, %f}, {%f, %f, %f}\n\n",
01283 worldBounds[0], worldBounds[1], worldBounds[2],
01284 worldBounds[3], worldBounds[4], worldBounds[5]);
01285 }
01286
01287 if (verbose == RT_VERB_DEBUG)
01288 printf("ANARIRenderer) Committing anariRenderer...\n");
01289
01290 anariCommit(dev, anariRenderer);
01291
01292 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) Finalizing ANARI rendering kernels...\n");
01293
01294
01295 double contextinittime = wkf_timer_timenow(anr_timer);
01296 time_ctx_validate = contextinittime - startctxtime;
01297
01298
01299
01300
01301
01302
01303 time_ctx_AS_build = wkf_timer_timenow(anr_timer) - contextinittime;
01304 if (verbose == RT_VERB_DEBUG) {
01305 printf("ANARIRenderer) launching render: %d x %d\n", width, height);
01306 }
01307 }
01308
01309
01310 #if defined(VMDANARI_INTERACTIVE_OPENGL)
01311
01312 static void *createanariraywindow(const char *wintitle, int width, int height) {
01313 printf("ANARIRenderer) Creating ANARI window: %d x %d...\n", width, height);
01314
01315 void *win = glwin_create(wintitle, width, height);
01316 while (glwin_handle_events(win, GLWIN_EV_POLL_NONBLOCK) != 0);
01317
01318 glDrawBuffer(GL_BACK);
01319 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
01320 glClearColor(0.0, 0.0, 0.0, 1.0);
01321 glViewport(0, 0, width, height);
01322 glClear(GL_COLOR_BUFFER_BIT);
01323
01324 glShadeModel(GL_FLAT);
01325 glMatrixMode(GL_PROJECTION);
01326 glLoadIdentity();
01327 glOrtho(0.0, width, height, 0.0, -1.0, 1.0);
01328 glMatrixMode(GL_MODELVIEW);
01329 glLoadIdentity();
01330
01331 glDrawBuffer(GL_BACK);
01332 glClear(GL_COLOR_BUFFER_BIT);
01333
01334 glwin_swap_buffers(win);
01335
01336 return win;
01337 }
01338
01339
01340 static void interactive_viewer_usage(void *win) {
01341 printf("ANARIRenderer) VMD TachyonL-ANARI Interactive Ray Tracer help:\n");
01342 printf("ANARIRenderer) ================================================\n");
01343
01344
01345 int havespaceball = ((glwin_spaceball_available(win)) && (getenv("VMDDISABLESPACEBALLXDRV") == NULL));
01346 printf("ANARIRenderer) Spaceball/SpaceNavigator/Magellan: %s\n",
01347 (havespaceball) ? "Available" : "Not available");
01348
01349
01350 int havestereo, havestencil;
01351 glwin_get_wininfo(win, &havestereo, &havestencil);
01352 printf("ANARIRenderer) Stereoscopic display: %s\n",
01353 (havestereo) ? "Available" : "Not available");
01354
01355
01356 int vsync=0, rc=0;
01357 if ((rc = glwin_query_vsync(win, &vsync)) == GLWIN_SUCCESS) {
01358 printf("ANARIRenderer) Vert retrace sync: %s\n", (vsync) ? "On" : "Off");
01359 } else {
01360 printf("ANARIRenderer) Vert retrace sync: indeterminate\n");
01361 }
01362
01363 printf("ANARIRenderer)\n");
01364 printf("ANARIRenderer) General controls:\n");
01365 printf("ANARIRenderer) space: save numbered snapshot image\n");
01366 printf("ANARIRenderer) =: reset to initial view\n");
01367 printf("ANARIRenderer) h: print this help info\n");
01368 printf("ANARIRenderer) p: print current rendering parameters\n");
01369 printf("ANARIRenderer) ESC,q: quit viewer\n");
01370 printf("ANARIRenderer)\n");
01371 printf("ANARIRenderer) Display controls\n");
01372 printf("ANARIRenderer) F1: override shadows on/off (off=AO off too)\n");
01373 printf("ANARIRenderer) F2: override AO on/off\n");
01374 printf("ANARIRenderer) F3: override DoF on/off\n");
01375 printf("ANARIRenderer) F4: override Depth cueing on/off\n");
01376
01377
01378
01379
01380 printf("ANARIRenderer) F12: toggle full-screen display on/off\n");
01381 printf("ANARIRenderer) 1-9,0: override samples per update auto-FPS off\n");
01382 printf("ANARIRenderer) Up: increase DoF focal distance\n");
01383 printf("ANARIRenderer) Down: decrease DoF focal distance\n");
01384 printf("ANARIRenderer) Left: decrease DoF f/stop\n");
01385 printf("ANARIRenderer) Right: increase DoF f/stop\n");
01386 printf("ANARIRenderer) S: toggle stereoscopic display on/off (if avail)\n");
01387 printf("ANARIRenderer) a: toggle AA/AO auto-FPS tuning on/off (on)\n");
01388 printf("ANARIRenderer) g: toggle gradient sky xforms on/off (on)\n");
01389 printf("ANARIRenderer) l: toggle light xforms on/off (on)\n");
01390 printf("ANARIRenderer)\n");
01391 printf("ANARIRenderer) Mouse controls:\n");
01392 printf("ANARIRenderer) f: mouse depth-of-field mode\n");
01393 printf("ANARIRenderer) r: mouse rotation mode\n");
01394 printf("ANARIRenderer) s: mouse scaling mode\n");
01395 printf("ANARIRenderer) t: mouse translation mode\n");
01396
01397 int movie_recording_enabled = (getenv("VMDANARILIVEMOVIECAPTURE") != NULL);
01398 if (movie_recording_enabled) {
01399 printf("ANARIRenderer)\n");
01400 printf("ANARIRenderer) Movie recording controls:\n");
01401 printf("ANARIRenderer) R: start/stop movie recording\n");
01402 printf("ANARIRenderer) F: toggle movie FPS (24, 30, 60)\n");
01403 }
01404 }
01405
01406
01407 void ANARIRender::render_to_glwin(const char *filename) {
01408 DBG();
01409 int i;
01410
01411 if (!context_created)
01412 return;
01413
01414 enum RtMouseMode { RTMM_ROT=0, RTMM_TRANS=1, RTMM_SCALE=2, RTMM_DOF=3 };
01415 enum RtMouseDown { RTMD_NONE=0, RTMD_LEFT=1, RTMD_MIDDLE=2, RTMD_RIGHT=3 };
01416 RtMouseMode mm = RTMM_ROT;
01417 RtMouseDown mousedown = RTMD_NONE;
01418
01419
01420 int gl_shadows_on=(shadows_enabled) ? RT_SHADOWS_ON : RT_SHADOWS_OFF;
01421
01422 int gl_fs_on=0;
01423 int owsx=0, owsy=0;
01424 int gl_ao_on=(ao_samples > 0);
01425 int gl_dof_on, gl_dof_on_old;
01426 gl_dof_on=gl_dof_on_old=dof_enabled;
01427 int gl_fog_on=(fog_mode != RT_FOG_NONE);
01428
01429
01430
01431
01432
01433
01434
01435 int movie_recording_enabled = (getenv("VMDANARILIVEMOVIECAPTURE") != NULL);
01436 int movie_recording_on = 0;
01437 double movie_recording_start_time = 0.0;
01438 int movie_recording_fps = 30;
01439 int movie_framecount = 0;
01440 int movie_lastframeindex = 0;
01441 const char *movie_recording_filebase = "vmdlivemovie.%05d.tga";
01442 if (getenv("VMDANARILIVEMOVIECAPTUREFILEBASE"))
01443 movie_recording_filebase = getenv("VMDANARILIVEMOVIECAPTUREFILEBASE");
01444
01445
01446 int spaceballenabled=(getenv("VMDDISABLESPACEBALLXDRV") == NULL) ? 1 : 0;
01447 int spaceballmode=0;
01448 int spaceballflightmode=0;
01449 if (getenv("VMDANARISPACEBALLFLIGHT"))
01450 spaceballflightmode=1;
01451
01452
01453
01454 int totalsamplecount=0;
01455
01456
01457 int snapshotcount=0;
01458
01459
01460 int autosamplecount=1;
01461
01462
01463
01464 int xformlights=1, xformgradientsphere=1;
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476 int wsx=width, wsy=height;
01477 const char *imageszstr = getenv("VMDANARIIMAGESIZE");
01478 if (imageszstr) {
01479 if (sscanf(imageszstr, "%d %d", &width, &height) != 2) {
01480 width=wsx;
01481 height=wsy;
01482 }
01483 }
01484 framebuffer_config(width, height);
01485
01486
01487
01488 update_rendering_state(1);
01489 render_compile_and_validate();
01490
01491
01492
01493 int samples_per_pass = 1;
01494 int cur_aa_samples = aa_samples;
01495 int cur_ao_samples = ao_samples;
01496 float cam_zoom_orig = cam_zoom;
01497 float scene_gradient_orig[3] = {0.0f, 1.0f, 0.0f};
01498 vec_copy(scene_gradient_orig, scene_gradient);
01499
01500 float cam_pos_orig[3] = {0.0f, 0.0f, 2.0f};
01501 float cam_U_orig[3] = {1.0f, 0.0f, 0.0f};
01502 float cam_V_orig[3] = {0.0f, 1.0f, 0.0f};
01503 float cam_W_orig[3] = {0.0f, 0.0f, -1.0f};
01504 float cam_pos[3], cam_U[3], cam_V[3], cam_W[3];
01505 float hmd_U[3], hmd_V[3], hmd_W[3];
01506
01507 vec_copy(cam_pos, cam_pos_orig);
01508 vec_copy(cam_U, cam_U_orig);
01509 vec_copy(cam_V, cam_V_orig);
01510 vec_copy(cam_W, cam_W_orig);
01511
01512
01513 anr_directional_light *cur_dlights = (anr_directional_light *) calloc(1, directional_lights.num() * sizeof(anr_directional_light));
01514 for (i=0; i<directional_lights.num(); i++) {
01515 vec_copy((float*)&cur_dlights[i].color, directional_lights[i].color);
01516 vec_copy((float*)&cur_dlights[i].dir, directional_lights[i].dir);
01517 vec_normalize((float*)&cur_dlights[i].dir);
01518 }
01519
01520
01521 void *win = createanariraywindow("VMD TachyonL-ANARI Interactive Ray Tracer", width, height);
01522 interactive_viewer_usage(win);
01523
01524
01525 int havestereo=0, havestencil=0;
01526 int stereoon=0, stereoon_old=0;
01527 glwin_get_wininfo(win, &havestereo, &havestencil);
01528
01529
01530
01531
01532
01533
01534
01535 cur_aa_samples = samples_per_pass;
01536 if (cur_ao_samples > 0) {
01537 cur_aa_samples = 1;
01538 cur_ao_samples = samples_per_pass;
01539 }
01540
01541 const char *statestr = "|/-\\.";
01542 int done=0, winredraw=1, accum_count=0;
01543 int state=0, mousedownx=0, mousedowny=0;
01544 float cur_cam_zoom = cam_zoom_orig;
01545
01546 double fpsexpave=0.0;
01547
01548 double oldtime = wkf_timer_timenow(anr_timer);
01549 while (!done) {
01550 int winevent=0;
01551
01552 while ((winevent = glwin_handle_events(win, GLWIN_EV_POLL_NONBLOCK)) != 0) {
01553 int evdev, evval;
01554 char evkey;
01555
01556 glwin_get_lastevent(win, &evdev, &evval, &evkey);
01557 glwin_get_winsize(win, &wsx, &wsy);
01558
01559 if (evdev == GLWIN_EV_WINDOW_CLOSE) {
01560 printf("ANARIRenderer) display window closed, exiting...\n");
01561 done = 1;
01562 winredraw = 0;
01563 } else if (evdev == GLWIN_EV_KBD) {
01564 switch (evkey) {
01565 case '1': autosamplecount=0; samples_per_pass=1; winredraw=1; break;
01566 case '2': autosamplecount=0; samples_per_pass=2; winredraw=1; break;
01567 case '3': autosamplecount=0; samples_per_pass=3; winredraw=1; break;
01568 case '4': autosamplecount=0; samples_per_pass=4; winredraw=1; break;
01569 case '5': autosamplecount=0; samples_per_pass=5; winredraw=1; break;
01570 case '6': autosamplecount=0; samples_per_pass=6; winredraw=1; break;
01571 case '7': autosamplecount=0; samples_per_pass=7; winredraw=1; break;
01572 case '8': autosamplecount=0; samples_per_pass=8; winredraw=1; break;
01573 case '9': autosamplecount=0; samples_per_pass=9; winredraw=1; break;
01574 case '0': autosamplecount=0; samples_per_pass=10; winredraw=1; break;
01575
01576 case '=':
01577 vec_copy(scene_gradient, scene_gradient_orig);
01578 cam_zoom = cam_zoom_orig;
01579 vec_copy(cam_pos, cam_pos_orig);
01580 vec_copy(cam_U, cam_U_orig);
01581 vec_copy(cam_V, cam_V_orig);
01582 vec_copy(cam_W, cam_W_orig);
01583
01584
01585 for (i=0; i<directional_lights.num(); i++) {
01586 vec_copy((float*)&cur_dlights[i].dir, directional_lights[i].dir);
01587 vec_normalize((float*)&cur_dlights[i].dir);
01588 }
01589 winredraw = 1;
01590 break;
01591
01592 case ' ':
01593 {
01594 char snapfilename[256];
01595 sprintf(snapfilename, "vmdsnapshot.%04d.tga", snapshotcount);
01596 const unsigned char *FB = (const unsigned char*)anariMapFrame(dev, anariFrameBuffer, "color");
01597 if (write_image_file_rgb4u(snapfilename, FB, width, height)) {
01598 printf("ANARIRenderer) Failed to write output image!\n");
01599 } else {
01600 printf("ANARIRenderer) Saved snapshot to '%s' \n",
01601 snapfilename);
01602 }
01603 anariUnmapFrame(dev, anariFrameBuffer, "color");
01604 snapshotcount++;
01605 }
01606 break;
01607
01608 case 'a':
01609 autosamplecount = !(autosamplecount);
01610 printf("\nANARIRenderer) Automatic AO sample count FPS tuning %s\n",
01611 (autosamplecount) ? "enabled" : "disabled");
01612 break;
01613
01614 case 'f':
01615 mm = RTMM_DOF;
01616 printf("\nANARIRenderer) Mouse DoF aperture and focal dist. mode\n");
01617 break;
01618
01619 case 'g':
01620 xformgradientsphere = !(xformgradientsphere);
01621 printf("\nANARIRenderer) Gradient sky sphere transformations %s\n",
01622 (xformgradientsphere) ? "enabled" : "disabled");
01623 break;
01624
01625 case 'h':
01626 printf("\n");
01627 interactive_viewer_usage(win);
01628 break;
01629
01630 case 'l':
01631 xformlights = !(xformlights);
01632 printf("\nANARIRenderer) Light transformations %s\n",
01633 (xformlights) ? "enabled" : "disabled");
01634 break;
01635
01636 case 'p':
01637 printf("\nANARIRenderer) Current Ray Tracing Parameters:\n");
01638 printf("ANARIRenderer) -------------------------------\n");
01639 printf("ANARIRenderer) Camera zoom: %f\n", cur_cam_zoom);
01640 printf("ANARIRenderer) Shadows: %s Ambient occlusion: %s\n",
01641 (gl_shadows_on) ? "on" : "off",
01642 (gl_ao_on) ? "on" : "off");
01643 printf("ANARIRenderer) Antialiasing samples per-pass: %d\n",
01644 cur_aa_samples);
01645 printf("ANARIRenderer) Ambient occlusion samples per-pass: %d\n",
01646 cur_ao_samples);
01647 printf("ANARIRenderer) Depth-of-Field: %s f/num: %.1f Foc. Dist: %.2f\n",
01648 (gl_dof_on) ? "on" : "off",
01649 cam_dof_fnumber, cam_dof_focal_dist);
01650 printf("ANARIRenderer) Image size: %d x %d\n", width, height);
01651 break;
01652
01653 case 'r':
01654 mm = RTMM_ROT;
01655 printf("\nANARIRenderer) Mouse rotation mode\n");
01656 break;
01657
01658 case 's':
01659 mm = RTMM_SCALE;
01660 printf("\nANARIRenderer) Mouse scaling mode\n");
01661 break;
01662
01663 case 'F':
01664 if (movie_recording_enabled) {
01665 switch (movie_recording_fps) {
01666 case 24: movie_recording_fps = 30; break;
01667 case 30: movie_recording_fps = 60; break;
01668 case 60:
01669 default: movie_recording_fps = 24; break;
01670 }
01671 printf("\nANARIRenderer) Movie recording FPS rate: %d\n",
01672 movie_recording_fps);
01673 } else {
01674 printf("\nANARIRenderer) Movie recording not available.\n");
01675 }
01676 break;
01677
01678 case 'R':
01679 if (movie_recording_enabled) {
01680 movie_recording_on = !(movie_recording_on);
01681 printf("\nANARIRenderer) Movie recording %s\n",
01682 (movie_recording_on) ? "STARTED" : "STOPPED");
01683 if (movie_recording_on) {
01684 movie_recording_start_time = wkf_timer_timenow(anr_timer);
01685 movie_framecount = 0;
01686 movie_lastframeindex = 0;
01687 } else {
01688 printf("ANARIRenderer) Encode movie with:\n");
01689 printf("ANARIRenderer) ffmpeg -f image2 -i vmdlivemovie.%%05d.tga -c:v libx264 -profile:v baseline -level 3.0 -pix_fmt yuv420p -b:v 15000000 output.mp4\n");
01690 }
01691 } else {
01692 printf("\nANARIRenderer) Movie recording not available.\n");
01693 }
01694 break;
01695
01696 case 'S':
01697 if (havestereo) {
01698 stereoon = (!stereoon);
01699 printf("\nANARIRenderer) Stereoscopic display %s\n",
01700 (stereoon) ? "enabled" : "disabled");
01701 winredraw = 1;
01702 } else {
01703 printf("\nANARIRenderer) Stereoscopic display unavailable\n");
01704 }
01705 break;
01706
01707 case 't':
01708 mm = RTMM_TRANS;
01709 printf("\nANARIRenderer) Mouse translation mode\n");
01710 break;
01711
01712 case 'q':
01713 case 'Q':
01714 case 0x1b:
01715 printf("\nANARIRenderer) Exiting on user input. \n");
01716 done=1;
01717 break;
01718 }
01719 } else if (evdev != GLWIN_EV_NONE) {
01720 switch (evdev) {
01721 case GLWIN_EV_KBD_F1:
01722 gl_shadows_on=(!gl_shadows_on) ? RT_SHADOWS_ON : RT_SHADOWS_OFF;
01723
01724 printf("\n");
01725 printf("ANARIRenderer) Shadows %s\n",
01726 (gl_shadows_on) ? "enabled" : "disabled");
01727 winredraw = 1;
01728 break;
01729
01730 case GLWIN_EV_KBD_F2:
01731 gl_ao_on = (!gl_ao_on);
01732 printf("\n");
01733 printf("ANARIRenderer) Ambient occlusion %s\n",
01734 (gl_ao_on) ? "enabled" : "disabled");
01735 winredraw = 1;
01736 break;
01737
01738 case GLWIN_EV_KBD_F3:
01739 gl_dof_on = (!gl_dof_on);
01740 printf("\n");
01741 if ((camera_projection == RT_ORTHOGRAPHIC) && gl_dof_on) {
01742 gl_dof_on=0;
01743 printf("ANARIRenderer) Depth-of-field not available in orthographic mode\n");
01744 }
01745 printf("ANARIRenderer) Depth-of-field %s\n",
01746 (gl_dof_on) ? "enabled" : "disabled");
01747 winredraw = 1;
01748 break;
01749
01750 case GLWIN_EV_KBD_F4:
01751 gl_fog_on = (!gl_fog_on);
01752 printf("\n");
01753 printf("ANARIRenderer) Depth cueing %s\n",
01754 (gl_fog_on) ? "enabled" : "disabled");
01755 winredraw = 1;
01756 break;
01757
01758 case GLWIN_EV_KBD_F12:
01759 gl_fs_on = (!gl_fs_on);
01760 printf("\nANARIRenderer) Toggling fullscreen window %s\n",
01761 (gl_fs_on) ? "on" : "off");
01762 if (gl_fs_on) {
01763 if (glwin_fullscreen(win, gl_fs_on, 0) == 0) {
01764 owsx = wsx;
01765 owsy = wsy;
01766 glwin_get_winsize(win, &wsx, &wsy);
01767 } else {
01768 printf("ANARIRenderer) Fullscreen mode note available\n");
01769 }
01770 } else {
01771 glwin_fullscreen(win, gl_fs_on, 0);
01772 glwin_resize(win, owsx, owsy);
01773 }
01774 winredraw = 1;
01775 break;
01776
01777 case GLWIN_EV_KBD_UP:
01778 cam_dof_focal_dist *= 1.02f;
01779 printf("\nANARIRenderer) DoF focal dist: %f\n", cam_dof_focal_dist);
01780 winredraw = 1;
01781 break;
01782
01783 case GLWIN_EV_KBD_DOWN:
01784 cam_dof_focal_dist *= 0.96f;
01785 if (cam_dof_focal_dist < 0.02f) cam_dof_focal_dist = 0.02f;
01786 printf("\nANARIRenderer) DoF focal dist: %f\n", cam_dof_focal_dist);
01787 winredraw = 1;
01788 break;
01789
01790 case GLWIN_EV_KBD_RIGHT:
01791 cam_dof_fnumber += 1.0f;
01792 printf("\nANARIRenderer) DoF f/stop: %f\n", cam_dof_fnumber);
01793 winredraw = 1;
01794 break;
01795
01796 case GLWIN_EV_KBD_LEFT:
01797 cam_dof_fnumber -= 1.0f;
01798 if (cam_dof_fnumber < 1.0f) cam_dof_fnumber = 1.0f;
01799 printf("\nANARIRenderer) DoF f/stop: %f\n", cam_dof_fnumber);
01800 winredraw = 1;
01801 break;
01802
01803 case GLWIN_EV_MOUSE_MOVE:
01804 if (mousedown != RTMD_NONE) {
01805 int x, y;
01806 glwin_get_mousepointer(win, &x, &y);
01807
01808 float zoommod = 2.0f*cur_cam_zoom/cam_zoom_orig;
01809 float txdx = (x - mousedownx) * zoommod / wsx;
01810 float txdy = (y - mousedowny) * zoommod / wsy;
01811 if (mm != RTMM_SCALE) {
01812 mousedownx = x;
01813 mousedowny = y;
01814 }
01815
01816 if (mm == RTMM_ROT) {
01817 Matrix4 rm;
01818 if (mousedown == RTMD_LEFT) {
01819
01820
01821 rm.rotate_axis(cam_V, -txdx);
01822 rm.rotate_axis(cam_U, -txdy);
01823 } else if (mousedown == RTMD_MIDDLE ||
01824 mousedown == RTMD_RIGHT) {
01825 rm.rotate_axis(cam_W, txdx);
01826 }
01827 rm.multpoint3d(cam_pos, cam_pos);
01828 rm.multnorm3d(cam_U, cam_U);
01829 rm.multnorm3d(cam_V, cam_V);
01830 rm.multnorm3d(cam_W, cam_W);
01831
01832 if (xformgradientsphere) {
01833 rm.multnorm3d(scene_gradient, scene_gradient);
01834 }
01835
01836 if (xformlights) {
01837
01838 for (i=0; i<directional_lights.num(); i++) {
01839 rm.multnorm3d((float*)&cur_dlights[i].dir, (float*)&cur_dlights[i].dir);
01840 }
01841 }
01842
01843 winredraw = 1;
01844 } else if (mm == RTMM_TRANS) {
01845 if (mousedown == RTMD_LEFT) {
01846 float dU[3], dV[3];
01847 vec_scale(dU, -txdx, cam_U);
01848 vec_scale(dV, txdy, cam_V);
01849 vec_add(cam_pos, cam_pos, dU);
01850 vec_add(cam_pos, cam_pos, dV);
01851 } else if (mousedown == RTMD_MIDDLE ||
01852 mousedown == RTMD_RIGHT) {
01853 float dW[3];
01854 vec_scale(dW, txdx, cam_W);
01855 vec_add(cam_pos, cam_pos, dW);
01856 }
01857 winredraw = 1;
01858 } else if (mm == RTMM_SCALE) {
01859 float txdx = (x - mousedownx) * 2.0 / wsx;
01860 float zoominc = 1.0 - txdx;
01861 if (zoominc < 0.01) zoominc = 0.01;
01862 cam_zoom = cur_cam_zoom * zoominc;
01863 winredraw = 1;
01864 } else if (mm == RTMM_DOF) {
01865 cam_dof_fnumber += txdx * 20.0f;
01866 if (cam_dof_fnumber < 1.0f) cam_dof_fnumber = 1.0f;
01867 cam_dof_focal_dist += -txdy;
01868 if (cam_dof_focal_dist < 0.01f) cam_dof_focal_dist = 0.01f;
01869 winredraw = 1;
01870 }
01871 }
01872 break;
01873
01874 case GLWIN_EV_MOUSE_LEFT:
01875 case GLWIN_EV_MOUSE_MIDDLE:
01876 case GLWIN_EV_MOUSE_RIGHT:
01877 if (evval) {
01878 glwin_get_mousepointer(win, &mousedownx, &mousedowny);
01879 cur_cam_zoom = cam_zoom;
01880
01881 if (evdev == GLWIN_EV_MOUSE_LEFT) mousedown = RTMD_LEFT;
01882 else if (evdev == GLWIN_EV_MOUSE_MIDDLE) mousedown = RTMD_MIDDLE;
01883 else if (evdev == GLWIN_EV_MOUSE_RIGHT) mousedown = RTMD_RIGHT;
01884 } else {
01885 mousedown = RTMD_NONE;
01886 }
01887 break;
01888
01889 case GLWIN_EV_MOUSE_WHEELUP:
01890 cam_zoom /= 1.1f; winredraw = 1; break;
01891
01892 case GLWIN_EV_MOUSE_WHEELDOWN:
01893 cam_zoom *= 1.1f; winredraw = 1; break;
01894 }
01895 }
01896 }
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907 if (spaceballenabled) {
01908
01909 int tx=0, ty=0, tz=0, rx=0, ry=0, rz=0, buttons=0;
01910 if (glwin_get_spaceball(win, &rx, &ry, &rz, &tx, &ty, &tz, &buttons)) {
01911
01912 if (spaceballflightmode) {
01913 rx= -rx;
01914 ry= -ry;
01915 rz= -rz;
01916
01917 tx= -tx;
01918 ty= -ty;
01919 tz= -tz;
01920 }
01921
01922
01923 if (buttons & 1) {
01924 printf("ANARIRenderer) spaceball button 1 pressed: reset view\n");
01925 vec_copy(scene_gradient, scene_gradient_orig);
01926 cam_zoom = cam_zoom_orig;
01927 vec_copy(cam_pos, cam_pos_orig);
01928 vec_copy(cam_U, cam_U_orig);
01929 vec_copy(cam_V, cam_V_orig);
01930 vec_copy(cam_W, cam_W_orig);
01931
01932
01933 for (i=0; i<directional_lights.num(); i++) {
01934 vec_copy((float*)&cur_dlights[i].dir, directional_lights[i].dir);
01935 vec_normalize((float*)&cur_dlights[i].dir);
01936 }
01937 winredraw = 1;
01938 }
01939
01940
01941 if (buttons & 2) {
01942 spaceballmode = !(spaceballmode);
01943 printf("ANARIRenderer) spaceball mode: %s \n",
01944 (spaceballmode) ? "scaling" : "rotation/translation");
01945 }
01946
01947
01948 if (spaceballmode == 0) {
01949 float zoommod = 2.0f*cam_zoom/cam_zoom_orig;
01950 float divlen = sqrtf(wsx*wsx + wsy*wsy) * 50;
01951
01952
01953 if (rx != 0 || ry !=0 || rz !=0) {
01954 Matrix4 rm;
01955 rm.rotate_axis(cam_U, -rx * zoommod / divlen);
01956 rm.rotate_axis(cam_V, -ry * zoommod / divlen);
01957 rm.rotate_axis(cam_W, -rz * zoommod / divlen);
01958
01959 rm.multpoint3d(cam_pos, cam_pos);
01960 rm.multnorm3d(cam_U, cam_U);
01961 rm.multnorm3d(cam_V, cam_V);
01962 rm.multnorm3d(cam_W, cam_W);
01963
01964 if (xformgradientsphere) {
01965 rm.multnorm3d(scene_gradient, scene_gradient);
01966 }
01967
01968 if (xformlights) {
01969
01970 for (i=0; i<directional_lights.num(); i++) {
01971 rm.multnorm3d((float*)&cur_dlights[i].dir, (float*)&cur_dlights[i].dir);
01972 }
01973 }
01974 winredraw = 1;
01975 }
01976
01977
01978 if (tx != 0 || ty !=0 || tz !=0) {
01979 float dU[3], dV[3], dW[3];
01980 vec_scale(dU, -tx * zoommod / divlen, cam_U);
01981 vec_scale(dV, -ty * zoommod / divlen, cam_V);
01982 vec_scale(dW, -tz * zoommod / divlen, cam_W);
01983 vec_add(cam_pos, cam_pos, dU);
01984 vec_add(cam_pos, cam_pos, dV);
01985 vec_add(cam_pos, cam_pos, dW);
01986 winredraw = 1;
01987 }
01988 }
01989
01990
01991 if (spaceballmode == 1) {
01992 const float sbscale = 1.0f / (1024.0f * 8.0f);
01993 float zoominc = 1.0f - (rz * sbscale);
01994 if (zoominc < 0.01) zoominc = 0.01;
01995 cam_zoom *= zoominc;
01996 winredraw = 1;
01997 }
01998
01999 }
02000 }
02001
02002
02003
02004 vec_copy(hmd_U, cam_U);
02005 vec_copy(hmd_V, cam_V);
02006 vec_copy(hmd_W, cam_W);
02007
02008
02009
02010
02011
02012
02013
02014 int resize_buffers=0;
02015
02016 if (wsx != width) {
02017 width = wsx;
02018 resize_buffers=1;
02019 }
02020
02021 if (wsy != height || (stereoon != stereoon_old)) {
02022 if (stereoon) {
02023 if (height != wsy * 2) {
02024 height = wsy * 2;
02025 resize_buffers=1;
02026 }
02027 } else {
02028 height = wsy;
02029 resize_buffers=1;
02030 }
02031 }
02032
02033
02034
02035
02036 if ((stereoon != stereoon_old) || (gl_dof_on != gl_dof_on_old)) {
02037
02038
02039 if (stereoon != stereoon_old) {
02040 resize_buffers=1;
02041 }
02042
02043
02044 stereoon_old = stereoon;
02045 gl_dof_on_old = gl_dof_on;
02046
02047
02048
02049
02050 winredraw=1;
02051 }
02052
02053 if (resize_buffers) {
02054 framebuffer_resize(width, height);
02055
02056
02057
02058
02059 if (movie_recording_enabled) {
02060 printf("\rANARIRenderer) Window resize: %d x %d \n", width, height);
02061 }
02062
02063 winredraw=1;
02064 }
02065
02066 int frame_ready = 1;
02067 unsigned int subframe_count = 1;
02068 if (!done) {
02069
02070
02071
02072
02073
02074 if (winredraw) {
02075
02076 anariSetParameter(dev, anariCamera, "position", ANARI_FLOAT32_VEC3, cam_pos);
02077 anariSetParameter(dev, anariCamera, "direction", ANARI_FLOAT32_VEC3, hmd_W);
02078 anariSetParameter(dev, anariCamera, "up", ANARI_FLOAT32_VEC3, hmd_V);
02079 float camaspect = width / ((float) height);
02080 anariSetParameter(dev, anariCamera, "aspect", ANARI_FLOAT32, &camaspect);
02081
02082 float camfovy = 2.0f*180.0f*(atanf(cam_zoom)/M_PI);
02083 anariSetParameter(dev, anariCamera, "fovy", ANARI_FLOAT32, &camfovy);
02084
02085
02086
02087
02088
02089 if (gl_shadows_on && gl_ao_on) {
02090 const int one = 1;
02091 if (anari_rendermode == ANARI_SCIVIS)
02092 anariSetParameter(dev, anariRenderer, "aoSamples", ANARI_INT32, &one);
02093 } else {
02094 const int zero = 0;
02095 if (anari_rendermode == ANARI_SCIVIS)
02096 anariSetParameter(dev, anariRenderer, "aoSamples", ANARI_INT32, &zero);
02097 }
02098
02099
02100
02101
02102
02103
02104
02105 if (camera_projection == ANARIRender::RT_PERSPECTIVE) {
02106 if (gl_dof_on) {
02107 anariSetParameter(dev, anariCamera, "focusDistance", ANARI_FLOAT32, &cam_dof_focal_dist);
02108 float camaprad = cam_dof_focal_dist / (2.0f * cam_zoom * cam_dof_fnumber);
02109 anariSetParameter(dev, anariCamera, "apertureRadius", ANARI_FLOAT32, &camaprad);
02110 } else {
02111 float camaprad = 0.0f;
02112 anariSetParameter(dev, anariCamera, "apertureRadius", ANARI_FLOAT32, &camaprad);
02113 }
02114 }
02115
02116
02117 anariCommit(dev, anariCamera);
02118
02119
02120
02121
02122 if (xformlights) {
02123
02124
02125 float lightscale = 1.0f;
02126 if (ao_samples != 0)
02127 lightscale = ao_direct;
02128
02129
02130
02131
02132
02133 for (i=0; i<directional_lights.num(); i++) {
02134 anariSetParameter(dev, anariLights[i], "intensity", ANARI_FLOAT32, &lightscale);
02135 anariSetParameter(dev, anariLights[i], "color", ANARI_FLOAT32_VEC3, cur_dlights[i].color);
02136
02137 float ltmp[3];
02138 vec_negate(ltmp, cur_dlights[i].dir);
02139 anariSetParameter(dev, anariLights[i], "direction", ANARI_FLOAT32_VEC3, ltmp);
02140 anariCommit(dev, anariLights[i]);
02141 }
02142 }
02143
02144
02145 anariCommit(dev, anariRenderer);
02146
02147
02148 accum_count=0;
02149 totalsamplecount=0;
02150 if (anariFrameBuffer != NULL) {
02151
02152 }
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162 if (autosamplecount) {
02163 if (fpsexpave > 37)
02164 samples_per_pass++;
02165 else if (fpsexpave < 30)
02166 samples_per_pass--;
02167
02168
02169 if (samples_per_pass > 14)
02170 samples_per_pass=14;
02171 if (samples_per_pass < 1)
02172 samples_per_pass=1;
02173 }
02174
02175
02176
02177 if (gl_shadows_on && gl_ao_on) {
02178 if (gl_dof_on) {
02179 if (samples_per_pass < 4) {
02180 cur_aa_samples=samples_per_pass;
02181 cur_ao_samples=1;
02182 } else {
02183 int s = (int) sqrtf(samples_per_pass);
02184 cur_aa_samples=s;
02185 cur_ao_samples=s;
02186 }
02187 } else {
02188 cur_aa_samples=1;
02189 cur_ao_samples=samples_per_pass;
02190 }
02191 } else {
02192 cur_aa_samples=samples_per_pass;
02193 cur_ao_samples=0;
02194 }
02195
02196
02197
02198
02199
02200
02201 if (gl_shadows_on && gl_ao_on) {
02202
02203 } else {
02204 cur_ao_samples = 0;
02205
02206 }
02207 }
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222 anariSetParameter(dev, anariFrameBuffer, "renderer", ANARI_RENDERER, &anariRenderer);
02223 anariSetParameter(dev, anariFrameBuffer, "camera", ANARI_CAMERA, &anariCamera);
02224 anariSetParameter(dev, anariFrameBuffer, "world", ANARI_WORLD, &anariWorld);
02225 anariCommit(dev, anariFrameBuffer);
02226
02227
02228
02229
02230
02231 frame_ready = 1;
02232 subframe_count = 1;
02233 if (lasterror == 0 ) {
02234 if (winredraw) {
02235
02236 winredraw=0;
02237 }
02238
02239
02240 anariRenderFrame(dev, anariFrameBuffer);
02241 anariFrameReady(dev, anariFrameBuffer, ANARI_WAIT);
02242
02243 subframe_count++;
02244 totalsamplecount += samples_per_pass;
02245 accum_count += cur_aa_samples;
02246
02247
02248
02249
02250
02251 if (lasterror == 0 ) {
02252 if (frame_ready) {
02253
02254 const unsigned char * img;
02255 img = (const unsigned char*)anariMapFrame(dev, anariFrameBuffer, "color");
02256
02257 #if 0
02258 glwin_draw_image_tex_rgb3u(win, (stereoon!=0)*GLWIN_STEREO_OVERUNDER, width, height, img);
02259 #else
02260 glwin_draw_image_rgb3u(win, (stereoon!=0)*GLWIN_STEREO_OVERUNDER, width, height, img);
02261 #endif
02262 anariUnmapFrame(dev, anariFrameBuffer, "color");
02263
02264
02265
02266
02267
02268 if (movie_recording_enabled && movie_recording_on) {
02269 char moviefilename[2048];
02270
02271
02272
02273 double now = wkf_timer_timenow(anr_timer);
02274 double frametime = now - movie_recording_start_time;
02275 int fidx = frametime * movie_recording_fps;
02276
02277
02278 if (movie_framecount==0)
02279 fidx=0;
02280 movie_framecount++;
02281
02282 #if defined(__linux)
02283
02284
02285
02286
02287 sprintf(moviefilename, movie_recording_filebase,
02288 movie_lastframeindex);
02289 int symidx;
02290 for (symidx=movie_lastframeindex; symidx<fidx; symidx++) {
02291 char symlinkfilename[2048];
02292 sprintf(symlinkfilename, movie_recording_filebase, symidx);
02293 symlink(moviefilename, symlinkfilename);
02294 }
02295 #endif
02296
02297
02298 sprintf(moviefilename, movie_recording_filebase, fidx);
02299 const unsigned char *FB = (const unsigned char*)anariMapFrame(dev, anariFrameBuffer, "color");
02300 if (write_image_file_rgb4u(moviefilename, FB, width, height)) {
02301 movie_recording_on = 0;
02302 printf("\n");
02303 printf("ANARIRenderer) ERROR during writing image during movie recording!\n");
02304 printf("ANARIRenderer) Movie recording STOPPED\n");
02305 }
02306 anariUnmapFrame(dev, anariFrameBuffer, "color");
02307
02308 movie_lastframeindex = fidx;
02309 }
02310 }
02311 } else {
02312 printf("ANARIRenderer) An error occured during rendering. Rendering is aborted.\n");
02313 done=1;
02314 break;
02315 }
02316 } else {
02317 printf("ANARIRenderer) An error occured in AS generation. Rendering is aborted.\n");
02318 done=1;
02319 break;
02320 }
02321 }
02322
02323 if (!done && frame_ready) {
02324 double newtime = wkf_timer_timenow(anr_timer);
02325 double frametime = (newtime-oldtime) + 0.00001f;
02326 oldtime=newtime;
02327
02328
02329 double framefps = 1.0f/frametime;
02330 fpsexpave = (fpsexpave * 0.90) + (framefps * 0.10);
02331
02332 printf("ANARIRenderer) %c AA:%2d AO:%2d, %4d tot RT FPS: %.1f %.4f s/frame sf: %d \r",
02333 statestr[state], cur_aa_samples, cur_ao_samples,
02334 totalsamplecount, fpsexpave, frametime, subframe_count);
02335
02336 fflush(stdout);
02337 state = (state+1) & 3;
02338 }
02339
02340 }
02341
02342 printf("\n");
02343
02344
02345 if (lasterror == 0 ) {
02346 wkf_timer_start(anr_timer);
02347
02348 const unsigned char *FB = (const unsigned char*)anariMapFrame(dev, anariFrameBuffer, "color");
02349 if (write_image_file_rgb4u(filename, FB, width, height)) {
02350 printf("ANARIRenderer) Failed to write output image!\n");
02351 }
02352 anariUnmapFrame(dev, anariFrameBuffer, "color");
02353 wkf_timer_stop(anr_timer);
02354
02355 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
02356 printf("ANARIRenderer) image file I/O time: %f secs\n", wkf_timer_time(anr_timer));
02357 }
02358 }
02359
02360 glwin_destroy(win);
02361 }
02362
02363 #endif
02364
02365
02366 void ANARIRender::render_to_file(const char *filename) {
02367 DBG();
02368 if (!context_created)
02369 return;
02370
02371
02372
02373 int wsx=width, wsy=height;
02374 const char *imageszstr = getenv("VMDANARIIMAGESIZE");
02375 if (imageszstr) {
02376 if (sscanf(imageszstr, "%d %d", &width, &height) != 2) {
02377 width=wsx;
02378 height=wsy;
02379 }
02380 }
02381
02382
02383 framebuffer_config(width, height);
02384
02385 update_rendering_state(0);
02386 render_compile_and_validate();
02387 double starttime = wkf_timer_timenow(anr_timer);
02388
02389
02390 if (rendererworkarounds == ANARI_USD) {
02391 printf("ANARIRenderer) *** extra anariWorld commit for USD...\n");
02392 anariCommit(dev, anariWorld);
02393 }
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404 anariFrameBuffer = anariNewFrame(dev);
02405 int imgsz[2];
02406 imgsz[0] = width;
02407 imgsz[1] = height;
02408 anariSetParameter(dev, anariFrameBuffer, "size", ANARI_UINT32_VEC2, &imgsz);
02409
02410
02411
02412
02413 ANARIDataType format = ANARI_UFIXED8_VEC4;
02414 anariSetParameter(dev, anariFrameBuffer, "color", ANARI_DATA_TYPE, &format);
02415
02416 anariSetParameter(dev, anariFrameBuffer, "renderer", ANARI_RENDERER, &anariRenderer);
02417 anariSetParameter(dev, anariFrameBuffer, "camera", ANARI_CAMERA, &anariCamera);
02418 anariSetParameter(dev, anariFrameBuffer, "world", ANARI_WORLD, &anariWorld);
02419 anariCommit(dev, anariFrameBuffer);
02420
02421
02422
02423
02424
02425 if (lasterror == 0 ) {
02426
02427
02428
02429
02430 if (getenv("VMDANARINORENDER") == NULL) {
02431 if (rendererworkarounds == ANARI_USD) {
02432 anariRenderFrame(dev, anariFrameBuffer);
02433 anariFrameReady(dev, anariFrameBuffer, ANARI_WAIT);
02434 } else {
02435 int accum_sample;
02436 for (accum_sample=0; accum_sample<ext_aa_loops; accum_sample++) {
02437
02438
02439 anariRenderFrame(dev, anariFrameBuffer);
02440 anariFrameReady(dev, anariFrameBuffer, ANARI_WAIT);
02441 }
02442 }
02443 }
02444
02445
02446
02447 double rtendtime = wkf_timer_timenow(anr_timer);
02448 time_ray_tracing = rtendtime - starttime;
02449
02450 if (rendererworkarounds != ANARI_USD) {
02451 if (lasterror == 0 ) {
02452
02453 if (getenv("VMDANARINOSAVE") == NULL) {
02454 const unsigned char *FB = (const unsigned char*)anariMapFrame(dev, anariFrameBuffer, "color");
02455 if (write_image_file_rgb4u(filename, FB, width, height)) {
02456 printf("ANARIRenderer) Failed to write output image!\n");
02457 }
02458 anariUnmapFrame(dev, anariFrameBuffer, "color");
02459 }
02460 time_image_io = wkf_timer_timenow(anr_timer) - rtendtime;
02461 } else {
02462 printf("ANARIRenderer) Error during rendering. Rendering aborted.\n");
02463 }
02464 }
02465
02466 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
02467 printf("ANARIRenderer) ctx setup %.2f valid %.2f AS %.2f RT %.2f io %.2f\n", time_ctx_setup, time_ctx_validate, time_ctx_AS_build, time_ray_tracing, time_image_io);
02468 }
02469 } else {
02470 printf("ANARIRenderer) Error during AS generation. Rendering aborted.\n");
02471 }
02472 }
02473
02474
02475 void ANARIRender::add_material(int matindex,
02476 float ambient, float diffuse,
02477 float specular,
02478 float shininess, float reflectivity,
02479 float opacity,
02480 float outline, float outlinewidth,
02481 int transmode) {
02482 if (dev == NULL) {
02483 printf("add_material() ANARI device is NULL!!!\n");
02484 return;
02485 }
02486
02487
02488 printf("ANARI Add mat[%d]\n", matindex);
02489 int oldmatcount = materialcache.num();
02490 if (oldmatcount <= matindex) {
02491 anr_material m;
02492 memset(&m, 0, sizeof(m));
02493
02494
02495 m.ambient = 0.5f;
02496 m.diffuse = 0.7f;
02497 m.specular = 0.0f;
02498 m.shininess = 10.0f;
02499 m.reflectivity = 0.0f;
02500 m.opacity = 1.0f;
02501 m.transmode = 0;
02502
02503 materialcache.appendN(m, matindex - oldmatcount + 1);
02504 }
02505
02506 if (materialcache[matindex].isvalid) {
02507 return;
02508 } else {
02509 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) Adding material[%d]\n", matindex);
02510
02511 materialcache[matindex].ambient = ambient;
02512 materialcache[matindex].diffuse = diffuse;
02513 materialcache[matindex].specular = specular;
02514 materialcache[matindex].shininess = shininess;
02515 materialcache[matindex].reflectivity = reflectivity;
02516 materialcache[matindex].opacity = opacity;
02517 materialcache[matindex].outline = outline;
02518 materialcache[matindex].outlinewidth = outlinewidth;
02519 materialcache[matindex].transmode = transmode;
02520
02521
02522 float mtmp[3];
02523 ANARIMaterial anariMat;
02524
02525 if (rendererworkarounds == ANARI_USD) {
02526 anari_matclass = ANARI_MATTE;
02527 }
02528
02529
02530
02531
02532 switch (anari_matclass) {
02533 case ANARI_MATTE:
02534 {
02535 if (opacity < 1.0f) {
02536
02537 anariMat = anariNewMaterial(dev, "transparentMatte");
02538 } else {
02539 anariMat = anariNewMaterial(dev, "matte");
02540 }
02541
02542 mtmp[0] = mtmp[1] = mtmp[2] = materialcache[matindex].diffuse;
02543 anariSetParameter(dev, anariMat, "kd", ANARI_FLOAT32_VEC3, mtmp);
02544 anariSetParameter(dev, anariMat, "d", ANARI_FLOAT32, &materialcache[matindex].opacity);
02545 }
02546 break;
02547
02548 default:
02549 case ANARI_OBJ:
02550 {
02551 anariMat = anariNewMaterial(dev, "obj");
02552
02553 mtmp[0] = mtmp[1] = mtmp[2] = materialcache[matindex].diffuse;
02554 anariSetParameter(dev, anariMat, "kd", ANARI_FLOAT32_VEC3, mtmp);
02555 anariSetParameter(dev, anariMat, "d", ANARI_FLOAT32, &materialcache[matindex].opacity);
02556
02557 mtmp[0] = mtmp[1] = mtmp[2] = materialcache[matindex].specular;
02558 anariSetParameter(dev, anariMat, "ks", ANARI_FLOAT32_VEC3, mtmp);
02559
02560 anariSetParameter(dev, anariMat, "ns", ANARI_FLOAT32, &materialcache[matindex].shininess);
02561 }
02562 break;
02563 }
02564
02565
02566 if (rendererworkarounds == ANARI_USD) {
02567 int usetrue = 1;
02568 anariSetParameter(dev, anariMat, "usevertexcolors", ANARI_BOOL, &usetrue);
02569
02570
02571 if (rendererworkarounds == ANARI_USD && (strlen(lastcommentstring) > 0)) {
02572 char strbuf[2048];
02573 sprintf(strbuf, "VMD material %d", matindex);
02574 anariSetParameter(dev, anariMat, "name", ANARI_STRING, strbuf);
02575 }
02576 }
02577
02578 anariCommit(dev, anariMat);
02579 materialcache[matindex].mat = anariMat;
02580 materialcache[matindex].isvalid = 1;
02581 }
02582 }
02583
02584
02585
02586 void ANARIRender::comment(const char *s) {
02587 commit_rep();
02588
02589 printf("ANARIRenderer) comment: '%s'\n", s);
02590 strncpy(lastcommentstring, s, sizeof(lastcommentstring) - 1);
02591 lastcommentstring[sizeof(lastcommentstring)-1] = '\0';
02592 }
02593
02594
02595 void ANARIRender::init_materials() {
02596 DBG();
02597 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) init_materials()\n");
02598
02599 materialcache.clear();
02600 }
02601
02602
02603 void ANARIRender::set_material(ANARISurface &surf, int matindex, float *uniform_color) {
02604 if (!context_created)
02605 return;
02606
02607 if (verbose == RT_VERB_DEBUG)
02608 printf("ANARIRenderer) setting material %d\n", matindex);
02609 anariSetParameter(dev, surf, "material", ANARI_MATERIAL, &materialcache[matindex].mat);
02610 }
02611
02612
02613 void ANARIRender::attach_mesh(int numverts, int numfacets, int matindex,
02614 anr_trimesh_v3f_n3f_c3f &mesh) {
02615 mesh.matindex = matindex;
02616 mesh.verts = anariNewArray1D(dev, mesh.v, 0, 0, ANARI_FLOAT32_VEC3, numverts, 0);
02617 anariCommit(dev, mesh.verts);
02618 mesh.norms = anariNewArray1D(dev, mesh.n, 0, 0, ANARI_FLOAT32_VEC3, numverts, 0);
02619 anariCommit(dev, mesh.norms);
02620 mesh.cols = anariNewArray1D(dev, mesh.c, 0, 0, ANARI_FLOAT32_VEC4, numverts, 0);
02621 anariCommit(dev, mesh.cols);
02622 mesh.ind = anariNewArray1D(dev, mesh.f, 0, 0, ANARI_UINT32_VEC3, numfacets, 0);
02623 anariCommit(dev, mesh.ind);
02624
02625 mesh.geom = anariNewGeometry(dev, "triangle");
02626
02627 anariSetParameter(dev, mesh.geom, "vertex.position", ANARI_ARRAY1D, &mesh.verts);
02628 anariRelease(dev, mesh.verts);
02629
02630 anariSetParameter(dev, mesh.geom, "vertex.normal", ANARI_ARRAY1D, &mesh.norms);
02631 anariRelease(dev, mesh.norms);
02632
02633 anariSetParameter(dev, mesh.geom, "primitive.index", ANARI_ARRAY1D, &mesh.ind);
02634 anariRelease(dev, mesh.ind);
02635
02636 anariSetParameter(dev, mesh.geom, "vertex.color", ANARI_ARRAY1D, &mesh.cols);
02637 anariRelease(dev, mesh.cols);
02638
02639 anariCommit(dev, mesh.geom);
02640
02641 mesh.surf = anariNewSurface(dev);
02642 anariSetParameter(dev, mesh.surf, "geometry", ANARI_GEOMETRY, &mesh.geom);
02643 set_material(mesh.surf, matindex, NULL);
02644
02645 anariCommit(dev, mesh.surf);
02646 anariRelease(dev, mesh.geom);
02647 trimesh_v3f_n3f_c3f.append(mesh);
02648 }
02649
02650
02651 void ANARIRender::attach_sphere_array(int numsp, int matindex,
02652 anr_sphere_array_color &sparray) {
02653 sparray.matindex = matindex;
02654
02655 sparray.cents = anariNewArray1D(dev, sparray.xyz, 0, 0, ANARI_FLOAT32_VEC3, numsp, 0);
02656 anariCommit(dev, sparray.cents);
02657 sparray.rads = anariNewArray1D(dev, sparray.radii, 0, 0, ANARI_FLOAT32, numsp, 0);
02658 anariCommit(dev, sparray.rads);
02659 sparray.cols = anariNewArray1D(dev, sparray.colors, 0, 0, ANARI_FLOAT32_VEC4, numsp, 0);
02660 anariCommit(dev, sparray.cols);
02661
02662 sparray.geom = anariNewGeometry(dev, "sphere");
02663 anariSetParameter(dev, sparray.geom, "vertex.position", ANARI_ARRAY1D, &sparray.cents);
02664 anariSetParameter(dev, sparray.geom, "vertex.radius", ANARI_ARRAY1D, &sparray.rads);
02665 anariSetParameter(dev, sparray.geom, "vertex.color", ANARI_ARRAY1D, &sparray.cols);
02666 anariCommit(dev, sparray.geom);
02667 anariRelease(dev, sparray.cents);
02668 anariRelease(dev, sparray.rads);
02669 anariRelease(dev, sparray.cols);
02670
02671 sparray.surf = anariNewSurface(dev);
02672 anariSetParameter(dev, sparray.surf, "geometry", ANARI_GEOMETRY, &sparray.geom);
02673 set_material(sparray.surf, matindex, NULL);
02674 anariCommit(dev, sparray.surf);
02675 anariRelease(dev, sparray.geom);
02676
02677 spheres_color.append(sparray);
02678 }
02679
02680
02681 void ANARIRender::attach_cylinder_array(int numcyl, int matindex,
02682 anr_cylinder_array_color &cylarray) {
02683 cylarray.matindex = matindex;
02684 cylarray.cyls = anariNewArray1D(dev, cylarray.verts, 0, 0, ANARI_FLOAT32_VEC3, numcyl * 2, 0);
02685 anariCommit(dev, cylarray.cyls);
02686 cylarray.rads = anariNewArray1D(dev, cylarray.radii, 0, 0, ANARI_FLOAT32, numcyl, 0);
02687 anariCommit(dev, cylarray.rads);
02688 cylarray.cols = anariNewArray1D(dev, cylarray.colors, 0, 0, ANARI_FLOAT32_VEC4, numcyl, 0);
02689 anariCommit(dev, cylarray.cols);
02690 cylarray.ind = anariNewArray1D(dev, cylarray.indices, 0, 0, ANARI_UINT32, numcyl * 1, 0);
02691 anariCommit(dev, cylarray.ind);
02692
02693 cylarray.geom = anariNewGeometry(dev, "curve");
02694 anariSetParameter(dev, cylarray.geom, "vertex.position", ANARI_ARRAY1D, &cylarray.cyls);
02695 anariSetParameter(dev, cylarray.geom, "vertex.radius", ANARI_ARRAY1D, &cylarray.rads);
02696 anariSetParameter(dev, cylarray.geom, "vertex.index", ANARI_ARRAY1D, &cylarray.ind);
02697
02698 cylarray.surf = anariNewSurface(dev);
02699 anariSetParameter(dev, cylarray.surf, "geometry", ANARI_GEOMETRY, &cylarray.geom);
02700 anariSetParameter(dev, cylarray.surf, "primitive.color", ANARI_ARRAY1D, &cylarray.cols);
02701 set_material(cylarray.surf, matindex, NULL);
02702 anariCommit(dev, cylarray.surf);
02703 anariRelease(dev, cylarray.geom);
02704
02705 free(cylarray.cyls);
02706 cylarray.cyls = NULL;
02707 free(cylarray.rads);
02708 cylarray.rads = NULL;
02709 free(cylarray.ind);
02710 cylarray.ind = NULL;
02711 free(cylarray.cols);
02712 cylarray.cols = NULL;
02713
02714 cylinders_color.append(cylarray);
02715 }
02716
02717
02718
02719 void ANARIRender::add_directional_light(const float *dir, const float *color) {
02720 DBG();
02721 anr_directional_light l;
02722 vec_copy(l.dir, dir);
02723 vec_copy(l.color, color);
02724
02725 directional_lights.append(l);
02726 }
02727
02728
02729 void ANARIRender::add_positional_light(const float *pos, const float *color) {
02730 DBG();
02731 anr_positional_light l;
02732 vec_copy(l.pos, pos);
02733 vec_copy(l.color, color);
02734
02735 positional_lights.append(l);
02736 }
02737
02738
02739 void ANARIRender::cylinder_array(Matrix4 *wtrans, float radius,
02740 float *uniform_color,
02741 int cylnum, float *points, int matindex) {
02742 DBG();
02743 if (!context_created) return;
02744 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating cylinder array: %d...\n", cylnum);
02745
02746 cylinder_array_cnt += cylnum;
02747
02748 anr_cylinder_array_color ca;
02749 memset(&ca, 0, sizeof(ca));
02750 ca.num = cylnum;
02751 ca.verts = (float *) calloc(1, cylnum * 6 * sizeof(float));
02752 ca.radii = (float *) calloc(1, cylnum * 1 * sizeof(float));
02753 ca.colors = (float *) calloc(1, cylnum * 4 * sizeof(float));
02754 ca.indices = (unsigned int *) calloc(1, cylnum * 2 * sizeof(unsigned int));
02755
02756 int i,ind4,ind6;
02757 if (wtrans == NULL) {
02758 for (i=0,ind4=0,ind6=0; i<cylnum; i++,ind4+=4,ind6+=6) {
02759 vec_copy(&ca.verts[ind6 ], &points[ind6 ]);
02760 vec_copy(&ca.verts[ind6+3], &points[ind6+3]);
02761 ca.radii[i] = radius;
02762 vec_copy(&ca.colors[ind4], &uniform_color[0]);
02763 ca.colors[ind4 + 3] = 1.0f;
02764 ca.indices[i] = i*2;
02765 }
02766 } else {
02767 for (i=0,ind4=0,ind6=0; i<cylnum; i++,ind4+=4,ind6+=6) {
02768
02769 wtrans->multpoint3d(&points[ind6 ], &ca.verts[ind6 ]);
02770 wtrans->multpoint3d(&points[ind6+3], &ca.verts[ind6+3]);
02771 ca.radii[i] = radius;
02772 vec_copy(&ca.colors[ind4], &uniform_color[0]);
02773 ca.colors[ind4 + 3] = 1.0f;
02774 ca.indices[i] = i*2;
02775 }
02776 }
02777
02778 attach_cylinder_array(cylnum, matindex, ca);
02779 }
02780
02781
02782 void ANARIRender::cylinder_array_color(Matrix4 & wtrans, float rscale,
02783 int cylnum, float *points,
02784 float *radii, float *colors,
02785 int matindex) {
02786 DBG();
02787 if (!context_created) return;
02788 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating color cylinder array: %d...\n", cylnum);
02789 cylinder_array_color_cnt += cylnum;
02790
02791 anr_cylinder_array_color cac;
02792 memset(&cac, 0, sizeof(cac));
02793 cac.num = cylnum;
02794 cac.verts = (float *) calloc(1, cylnum * 6 * sizeof(float));
02795 cac.radii = (float *) calloc(1, cylnum * 1 * sizeof(float));
02796 cac.colors = (float *) calloc(1, cylnum * 4 * sizeof(float));
02797 cac.indices = (unsigned int *) calloc(1, cylnum * 2 * sizeof(unsigned int));
02798
02799 int i, ind3, ind4, ind6;
02800 for (i=0,ind3=0,ind4=0,ind6=0; i<cylnum; i++,ind3+=3,ind4+=4,ind6+=6) {
02801
02802 wtrans.multpoint3d(&points[ind6 ], &cac.verts[ind6 ]);
02803 wtrans.multpoint3d(&points[ind6+3], &cac.verts[ind6+3]);
02804 cac.radii[i] = radii[i] * rscale;
02805 vec_copy(&cac.colors[ind4], &colors[ind3]);
02806 cac.colors[ind4 + 3] = 1.0f;
02807 cac.indices[i] = i*2;
02808 }
02809
02810 attach_cylinder_array(cylnum, matindex, cac);
02811 }
02812
02813 #if 0
02814 void ANARIRender::ring_array_color(Matrix4 & wtrans, float rscale,
02815 int rnum, float *centers,
02816 float *norms, float *radii,
02817 float *colors, int matindex) {
02818 }
02819 #endif
02820
02821
02822 void ANARIRender::sphere_array(Matrix4 *wtrans, float rscale,
02823 float *uniform_color,
02824 int numsp, float *centers,
02825 float *radii,
02826 int matindex) {
02827 DBG();
02828 if (!context_created) return;
02829 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating sphere array: %d...\n", numsp);
02830 sphere_array_cnt += numsp;
02831
02832 const rgba c = { uniform_color[0], uniform_color[1], uniform_color[2], 1.0f};
02833
02834 anr_sphere_array_color sp;
02835 memset(&sp, 0, sizeof(sp));
02836 sp.num = numsp;
02837 sp.xyz = (float *) calloc(1, numsp * 3*sizeof(float));
02838 sp.radii = (float *) calloc(1, numsp * sizeof(float));
02839 sp.colors = (float *) calloc(1, numsp * 4*sizeof(float));
02840
02841 int i, ind3, ind4;
02842 if (wtrans == NULL) {
02843 if (radii == NULL) {
02844 for (i=0,ind3=0,ind4=0; i<numsp; i++,ind3+=3,ind4+=4) {
02845
02846 vec_copy((float*) &sp.xyz[ind3], ¢ers[ind3]);
02847 sp.radii[i] = rscale;
02848 memcpy((float*) &sp.colors[ind4], &c, 4*sizeof(float));
02849 }
02850 } else {
02851 for (i=0,ind3=0,ind4=0; i<numsp; i++,ind3+=3,ind4+=4) {
02852
02853 vec_copy((float*) &sp.xyz[ind3], ¢ers[ind3]);
02854 sp.radii[i] = radii[i] * rscale;
02855 memcpy((float*) &sp.colors[ind4], &c, 4*sizeof(float));
02856 }
02857 }
02858 } else {
02859 if (radii == NULL) {
02860 for (i=0,ind3=0,ind4=0; i<numsp; i++,ind3+=3,ind4+=4) {
02861 wtrans->multpoint3d(¢ers[ind3], &sp.xyz[ind3]);
02862 sp.radii[i] = rscale;
02863 memcpy((float*) &sp.colors[ind4], &c, 4*sizeof(float));
02864 }
02865 } else {
02866 for (i=0,ind3=0,ind4=0; i<numsp; i++,ind3+=3,ind4+=4) {
02867
02868 wtrans->multpoint3d(¢ers[ind3], &sp.xyz[ind3]);
02869 sp.radii[i] = radii[i] * rscale;
02870 memcpy((float*) &sp.colors[ind4], &c, 4*sizeof(float));
02871 }
02872 }
02873 }
02874
02875 attach_sphere_array(numsp, matindex, sp);
02876 }
02877
02878
02879 void ANARIRender::sphere_array_color(Matrix4 & wtrans, float rscale,
02880 int numsp, float *centers,
02881 float *radii, float *colors,
02882 int matindex) {
02883 DBG();
02884 if (!context_created) return;
02885 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating sphere array color: %d...\n", numsp);
02886 sphere_array_color_cnt += numsp;
02887
02888 anr_sphere_array_color sp;
02889 memset(&sp, 0, sizeof(sp));
02890 sp.num = numsp;
02891 sp.xyz = (float *) calloc(1, numsp * 3*sizeof(float));
02892 sp.radii = (float *) calloc(1, numsp * sizeof(float));
02893 sp.colors = (float *) calloc(1, numsp * 4*sizeof(float));
02894
02895 int i, ind3, ind4;
02896 for (i=0,ind3=0,ind4=0; i<numsp; i++,ind3+=3,ind4+=4) {
02897 wtrans.multpoint3d(¢ers[ind3], &sp.xyz[ind3]);
02898 sp.radii[i] = radii[i] * rscale;
02899 vec_copy((float*) &sp.colors[ind4], &colors[ind3]);
02900 sp.colors[ind4 + 3] = 1.0f;
02901 }
02902
02903 attach_sphere_array(numsp, matindex, sp);
02904 }
02905
02906
02907 void ANARIRender::tricolor_list(Matrix4 & wtrans, int numtris, float *vnc,
02908 int matindex) {
02909 if (!context_created) return;
02910
02911 tricolor_cnt += numtris;
02912
02913
02914 anr_trimesh_v3f_n3f_c3f mesh;
02915 memset(&mesh, 0, sizeof(mesh));
02916 mesh.num = numtris;
02917 mesh.v = (float *) calloc(1, numtris * 9*sizeof(float));
02918 mesh.n = (float *) calloc(1, numtris * 9*sizeof(float));
02919 mesh.c = (float *) calloc(1, numtris * 12*sizeof(float));
02920 mesh.f = (int *) calloc(1, numtris * 3*sizeof(int));
02921
02922 float alpha = 1.0f;
02923
02924
02925 int i, ind, ind9, ind12;
02926 for (i=0,ind=0,ind9=0,ind12=0; i<numtris; i++,ind+=27,ind9+=9,ind12+=12) {
02927
02928 wtrans.multpoint3d(&vnc[ind ], (float*) &mesh.v[ind9 ]);
02929 wtrans.multpoint3d(&vnc[ind + 3], (float*) &mesh.v[ind9 + 3]);
02930 wtrans.multpoint3d(&vnc[ind + 6], (float*) &mesh.v[ind9 + 6]);
02931
02932 wtrans.multnorm3d(&vnc[ind + 9], (float*) &mesh.n[ind9 ]);
02933 wtrans.multnorm3d(&vnc[ind + 12], (float*) &mesh.n[ind9 + 3]);
02934 wtrans.multnorm3d(&vnc[ind + 15], (float*) &mesh.n[ind9 + 6]);
02935
02936 vec_copy(&mesh.c[ind12 ], &vnc[ind + 18]);
02937 mesh.c[ind12 + 3] = alpha;
02938 vec_copy(&mesh.c[ind12 + 4], &vnc[ind + 21]);
02939 mesh.c[ind12 + 7] = alpha;
02940 vec_copy(&mesh.c[ind12 + 8], &vnc[ind + 24]);
02941 mesh.c[ind12 + 11] = alpha;
02942
02943 mesh.f[i*3 ] = i*3;
02944 mesh.f[i*3+1] = i*3 + 1;
02945 mesh.f[i*3+2] = i*3 + 2;
02946 }
02947
02948 attach_mesh(numtris * 3, numtris, matindex, mesh);
02949 }
02950
02951
02952 void ANARIRender::trimesh_c4n3v3(Matrix4 & wtrans, int numverts,
02953 float *cnv, int numfacets, int * facets,
02954 int matindex) {
02955 if (!context_created) return;
02956 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating trimesh_c4n3v3: %d...\n", numfacets);
02957 trimesh_c4u_n3b_v3f_cnt += numfacets;
02958
02959
02960 anr_trimesh_v3f_n3f_c3f mesh;
02961 memset(&mesh, 0, sizeof(mesh));
02962 mesh.num = numfacets;
02963 mesh.v = (float *) calloc(1, numfacets * 9*sizeof(float));
02964 mesh.n = (float *) calloc(1, numfacets * 9*sizeof(float));
02965 mesh.c = (float *) calloc(1, numfacets * 12*sizeof(float));
02966 mesh.f = (int *) calloc(1, numfacets * 3*sizeof(int));
02967
02968 float alpha = 1.0f;
02969
02970
02971
02972
02973 int i, ind, ind9, ind12;
02974 for (i=0,ind=0,ind9=0,ind12=0; i<numfacets; i++,ind+=3,ind9+=9,ind12+=12) {
02975 int v0 = facets[ind ] * 10;
02976 int v1 = facets[ind + 1] * 10;
02977 int v2 = facets[ind + 2] * 10;
02978
02979
02980 wtrans.multpoint3d(cnv + v0 + 7, (float*) &mesh.v[ind9 ]);
02981 wtrans.multpoint3d(cnv + v1 + 7, (float*) &mesh.v[ind9 + 3]);
02982 wtrans.multpoint3d(cnv + v2 + 7, (float*) &mesh.v[ind9 + 6]);
02983
02984 wtrans.multnorm3d(cnv + v0 + 4, (float*) &mesh.n[ind9 ]);
02985 wtrans.multnorm3d(cnv + v1 + 4, (float*) &mesh.n[ind9 + 3]);
02986 wtrans.multnorm3d(cnv + v2 + 4, (float*) &mesh.n[ind9 + 6]);
02987
02988 vec_copy(&mesh.c[ind12 ], cnv + v0);
02989 mesh.c[ind12 + 3] = alpha;
02990 vec_copy(&mesh.c[ind12 + 4], cnv + v1);
02991 mesh.c[ind12 + 7] = alpha;
02992 vec_copy(&mesh.c[ind12 + 8], cnv + v2);
02993 mesh.c[ind12 + 11] = alpha;
02994
02995 mesh.f[i*3 ] = i*3;
02996 mesh.f[i*3+1] = i*3 + 1;
02997 mesh.f[i*3+2] = i*3 + 2;
02998 }
02999
03000 attach_mesh(numfacets * 3, numfacets, matindex, mesh);
03001 }
03002
03003
03004
03005
03006
03007
03008
03009 void ANARIRender::trimesh_c4u_n3b_v3f(Matrix4 & wtrans, unsigned char *c,
03010 signed char *n, float *v,
03011 int numfacets, int matindex) {
03012 if (!context_created) return;
03013 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating trimesh_c4u_n3b_v3f: %d...\n", numfacets);
03014 trimesh_n3b_v3f_cnt += numfacets;
03015
03016
03017 anr_trimesh_v3f_n3f_c3f mesh;
03018 memset(&mesh, 0, sizeof(mesh));
03019 mesh.num = numfacets;
03020 mesh.v = (float *) calloc(1, numfacets * 9*sizeof(float));
03021 mesh.n = (float *) calloc(1, numfacets * 9*sizeof(float));
03022 mesh.c = (float *) calloc(1, numfacets * 12*sizeof(float));
03023 mesh.f = (int *) calloc(1, numfacets * 3*sizeof(int));
03024
03025 float alpha = 1.0f;
03026
03027
03028
03029
03030 int i, ind, ind9, ind12;
03031
03032 const float ci2f = 1.0f / 255.0f;
03033 const float cn2f = 1.0f / 127.5f;
03034 for (i=0,ind=0,ind9=0,ind12=0; i<numfacets; i++,ind+=3,ind9+=9,ind12+=12) {
03035 float norm[9];
03036
03037
03038
03039 norm[0] = n[ind9 ] * cn2f + ci2f;
03040 norm[1] = n[ind9 + 1] * cn2f + ci2f;
03041 norm[2] = n[ind9 + 2] * cn2f + ci2f;
03042 norm[3] = n[ind9 + 3] * cn2f + ci2f;
03043 norm[4] = n[ind9 + 4] * cn2f + ci2f;
03044 norm[5] = n[ind9 + 5] * cn2f + ci2f;
03045 norm[6] = n[ind9 + 6] * cn2f + ci2f;
03046 norm[7] = n[ind9 + 7] * cn2f + ci2f;
03047 norm[8] = n[ind9 + 8] * cn2f + ci2f;
03048
03049
03050 wtrans.multpoint3d(v + ind9 , (float*) &mesh.v[ind9 ]);
03051 wtrans.multpoint3d(v + ind9 + 3, (float*) &mesh.v[ind9 + 3]);
03052 wtrans.multpoint3d(v + ind9 + 6, (float*) &mesh.v[ind9 + 6]);
03053
03054 wtrans.multnorm3d(norm , (float*) &mesh.n[ind9 ]);
03055 wtrans.multnorm3d(norm + 3, (float*) &mesh.n[ind9 + 3]);
03056 wtrans.multnorm3d(norm + 6, (float*) &mesh.n[ind9 + 6]);
03057
03058 float col[9];
03059
03060
03061
03062 col[0] = c[ind12 ] * ci2f;
03063 col[1] = c[ind12 + 1] * ci2f;
03064 col[2] = c[ind12 + 2] * ci2f;
03065 col[3] = c[ind12 + 4] * ci2f;
03066 col[4] = c[ind12 + 5] * ci2f;
03067 col[5] = c[ind12 + 6] * ci2f;
03068 col[6] = c[ind12 + 8] * ci2f;
03069 col[7] = c[ind12 + 9] * ci2f;
03070 col[8] = c[ind12 + 10] * ci2f;
03071
03072 vec_copy(&mesh.c[ind12 ], col );
03073 mesh.c[ind12 + 3] = alpha;
03074 vec_copy(&mesh.c[ind12 + 4], col + 3);
03075 mesh.c[ind12 + 7] = alpha;
03076 vec_copy(&mesh.c[ind12 + 8], col + 6);
03077 mesh.c[ind12 + 11] = alpha;
03078
03079 mesh.f[i*3 ] = i*3;
03080 mesh.f[i*3+1] = i*3 + 1;
03081 mesh.f[i*3+2] = i*3 + 2;
03082 }
03083
03084 attach_mesh(numfacets * 3, numfacets, matindex, mesh);
03085 }
03086
03087
03088
03089 void ANARIRender::trimesh_c4u_n3f_v3f(Matrix4 & wtrans, unsigned char *c,
03090 float *n, float *v,
03091 int numfacets, int matindex) {
03092 if (!context_created) return;
03093 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating trimesh_c4u_n3f_v3f: %d...\n", numfacets);
03094 tricolor_cnt += numfacets;
03095
03096
03097 anr_trimesh_v3f_n3f_c3f mesh;
03098 memset(&mesh, 0, sizeof(mesh));
03099 mesh.num = numfacets;
03100 mesh.v = (float *) calloc(1, numfacets * 9*sizeof(float));
03101 mesh.n = (float *) calloc(1, numfacets * 9*sizeof(float));
03102 mesh.c = (float *) calloc(1, numfacets * 12*sizeof(float));
03103 mesh.f = (int *) calloc(1, numfacets * 3*sizeof(int));
03104
03105 float alpha = 1.0f;
03106
03107
03108
03109
03110 int i, ind, ind9, ind12;
03111
03112 const float ci2f = 1.0f / 255.0f;
03113 for (i=0,ind=0,ind9=0,ind12=0; i<numfacets; i++,ind+=3,ind9+=9,ind12+=12) {
03114
03115 wtrans.multpoint3d(v + ind9 , (float*) &mesh.v[ind9 ]);
03116 wtrans.multpoint3d(v + ind9 + 3, (float*) &mesh.v[ind9 + 3]);
03117 wtrans.multpoint3d(v + ind9 + 6, (float*) &mesh.v[ind9 + 6]);
03118
03119 wtrans.multnorm3d(n + ind9 , &mesh.n[ind9 ]);
03120 wtrans.multnorm3d(n + ind9 + 3, &mesh.n[ind9 + 3]);
03121 wtrans.multnorm3d(n + ind9 + 6, &mesh.n[ind9 + 3]);
03122
03123
03124
03125 float col[9];
03126 col[0] = c[ind12 ] * ci2f;
03127 col[1] = c[ind12 + 1] * ci2f;
03128 col[2] = c[ind12 + 2] * ci2f;
03129 col[3] = c[ind12 + 4] * ci2f;
03130 col[4] = c[ind12 + 5] * ci2f;
03131 col[5] = c[ind12 + 6] * ci2f;
03132 col[6] = c[ind12 + 8] * ci2f;
03133 col[7] = c[ind12 + 9] * ci2f;
03134 col[8] = c[ind12 + 10] * ci2f;
03135
03136 vec_copy(&mesh.c[ind12 ], col );
03137 mesh.c[ind12 + 3] = alpha;
03138 vec_copy(&mesh.c[ind12 + 4], col + 3);
03139 mesh.c[ind12 + 7] = alpha;
03140 vec_copy(&mesh.c[ind12 + 8], col + 6);
03141 mesh.c[ind12 + 11] = alpha;
03142
03143 mesh.f[i*3 ] = i*3;
03144 mesh.f[i*3+1] = i*3 + 1;
03145 mesh.f[i*3+2] = i*3 + 2;
03146 }
03147
03148 attach_mesh(numfacets * 3, numfacets, matindex, mesh);
03149 }
03150
03151
03152 void ANARIRender::trimesh_n3b_v3f(Matrix4 & wtrans, float *uniform_color,
03153 signed char *n, float *v,
03154 int numfacets, int matindex) {
03155 if (!context_created) return;
03156 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating trimesh_n3b_v3f: %d...\n", numfacets);
03157 trimesh_n3b_v3f_cnt += numfacets;
03158
03159
03160 anr_trimesh_v3f_n3f_c3f mesh;
03161 memset(&mesh, 0, sizeof(mesh));
03162 mesh.num = numfacets;
03163 mesh.v = (float *) calloc(1, numfacets * 9*sizeof(float));
03164 mesh.n = (float *) calloc(1, numfacets * 9*sizeof(float));
03165 mesh.c = (float *) calloc(1, numfacets * 12*sizeof(float));
03166 mesh.f = (int *) calloc(1, numfacets * 3*sizeof(int));
03167
03168 float alpha = 1.0f;
03169
03170
03171
03172 int i, ind, ind9, ind12;
03173
03174 const float ci2f = 1.0f / 255.0f;
03175 const float cn2f = 1.0f / 127.5f;
03176 for (i=0,ind=0,ind9=0,ind12=0; i<numfacets; i++,ind+=3,ind9+=9,ind12+=12) {
03177 float norm[9];
03178
03179
03180
03181 norm[0] = n[ind9 ] * cn2f + ci2f;
03182 norm[1] = n[ind9 + 1] * cn2f + ci2f;
03183 norm[2] = n[ind9 + 2] * cn2f + ci2f;
03184 norm[3] = n[ind9 + 3] * cn2f + ci2f;
03185 norm[4] = n[ind9 + 4] * cn2f + ci2f;
03186 norm[5] = n[ind9 + 5] * cn2f + ci2f;
03187 norm[6] = n[ind9 + 6] * cn2f + ci2f;
03188 norm[7] = n[ind9 + 7] * cn2f + ci2f;
03189 norm[8] = n[ind9 + 8] * cn2f + ci2f;
03190
03191
03192 wtrans.multpoint3d(v + ind9 , (float*) &mesh.v[ind9 ]);
03193 wtrans.multpoint3d(v + ind9 + 3, (float*) &mesh.v[ind9 + 3]);
03194 wtrans.multpoint3d(v + ind9 + 6, (float*) &mesh.v[ind9 + 6]);
03195
03196 wtrans.multnorm3d(norm , (float*) &mesh.n[ind9 ]);
03197 wtrans.multnorm3d(norm + 3, (float*) &mesh.n[ind9 + 3]);
03198 wtrans.multnorm3d(norm + 6, (float*) &mesh.n[ind9 + 6]);
03199
03200 vec_copy(&mesh.c[ind12 ], uniform_color);
03201 mesh.c[ind12 + 3] = alpha;
03202 vec_copy(&mesh.c[ind12 + 4], uniform_color);
03203 mesh.c[ind12 + 7] = alpha;
03204 vec_copy(&mesh.c[ind12 + 8], uniform_color);
03205 mesh.c[ind12 + 11] = alpha;
03206
03207 mesh.f[i*3 ] = i*3;
03208 mesh.f[i*3+1] = i*3 + 1;
03209 mesh.f[i*3+2] = i*3 + 2;
03210 }
03211
03212 attach_mesh(numfacets * 3, numfacets, matindex, mesh);
03213 }
03214
03215
03216
03217
03218 void ANARIRender::trimesh_n3f_v3f(Matrix4 & wtrans, float *uniform_color,
03219 float *n, float *v, int numfacets,
03220 int matindex) {
03221 DBG();
03222 if (!context_created) return;
03223 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating trimesh_n3f_v3f: %d...\n", numfacets);
03224 trimesh_n3f_v3f_cnt += numfacets;
03225
03226 anr_trimesh_v3f_n3f_c3f mesh;
03227 memset(&mesh, 0, sizeof(mesh));
03228 mesh.num = numfacets;
03229 mesh.v = (float *) calloc(1, numfacets * 9*sizeof(float));
03230 mesh.n = (float *) calloc(1, numfacets * 9*sizeof(float));
03231 mesh.c = (float *) calloc(1, numfacets * 12*sizeof(float));
03232 mesh.f = (int *) calloc(1, numfacets * 3*sizeof(int));
03233
03234 float alpha = 1.0f;
03235
03236
03237 int i, ind, ind9, ind12;
03238
03239 for (i=0,ind=0,ind9=0,ind12=0; i<numfacets; i++,ind+=3,ind9+=9,ind12+=12) {
03240
03241 wtrans.multpoint3d(v + ind9 , (float*) &mesh.v[ind9 ]);
03242 wtrans.multpoint3d(v + ind9 + 3, (float*) &mesh.v[ind9 + 3]);
03243 wtrans.multpoint3d(v + ind9 + 6, (float*) &mesh.v[ind9 + 6]);
03244
03245 wtrans.multnorm3d(n + ind9 , (float*) &mesh.n[ind9 ]);
03246 wtrans.multnorm3d(n + ind9 + 3, (float*) &mesh.n[ind9 + 3]);
03247 wtrans.multnorm3d(n + ind9 + 6, (float*) &mesh.n[ind9 + 6]);
03248
03249 vec_copy(&mesh.c[ind12 ], uniform_color);
03250 mesh.c[ind12 + 3] = alpha;
03251 vec_copy(&mesh.c[ind12 + 4], uniform_color);
03252 mesh.c[ind12 + 7] = alpha;
03253 vec_copy(&mesh.c[ind12 + 8], uniform_color);
03254 mesh.c[ind12 + 11] = alpha;
03255
03256 mesh.f[i*3 ] = i*3;
03257 mesh.f[i*3+1] = i*3 + 1;
03258 mesh.f[i*3+2] = i*3 + 2;
03259 }
03260
03261 attach_mesh(numfacets * 3, numfacets, matindex, mesh);
03262 }
03263
03264
03265 #if 0
03266 void ANARIRender::trimesh_v3f(Matrix4 & wtrans, float *uniform_color,
03267 float *v, int numfacets, int matindex) {
03268 if (!context_created) return;
03269 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating trimesh_v3f: %d...\n", numfacets);
03270 trimesh_v3f_cnt += numfacets;
03271
03272 set_material(geom, matindex, NULL);
03273 append_objects(buf, geom, instance);
03274 }
03275
03276 #endif
03277
03278
03279
03280 void ANARIRender::tristrip(Matrix4 & wtrans, int numverts, const float * cnv,
03281 int numstrips, const int *vertsperstrip,
03282 const int *facets, int matindex) {
03283 if (!context_created) return;
03284 int i;
03285 int numfacets = 0;
03286 for (i=0; i<numstrips; i++)
03287 numfacets += (vertsperstrip[i] - 2);
03288
03289 if (verbose == RT_VERB_DEBUG) printf("ANARIRenderer) creating tristrip: %d...\n", numfacets);
03290 tricolor_cnt += numfacets;
03291
03292
03293 anr_trimesh_v3f_n3f_c3f mesh;
03294 memset(&mesh, 0, sizeof(mesh));
03295 mesh.num = numfacets;
03296 mesh.v = (float *) calloc(1, numfacets * 9*sizeof(float));
03297 mesh.n = (float *) calloc(1, numfacets * 9*sizeof(float));
03298 mesh.c = (float *) calloc(1, numfacets * 12*sizeof(float));
03299 mesh.f = (int *) calloc(1, numfacets * 3*sizeof(int));
03300
03301 float alpha = 1.0f;
03302
03303
03304
03305
03306
03307
03308
03309
03310 int strip, t, v = 0;
03311 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
03312
03313
03314 i=0;
03315 int ind9, ind12;
03316 for (strip=0,ind9=0,ind12=0; strip < numstrips; strip++) {
03317
03318 for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
03319
03320 int v0 = facets[v + (stripaddr[t & 0x01][0])] * 10;
03321 int v1 = facets[v + (stripaddr[t & 0x01][1])] * 10;
03322 int v2 = facets[v + (stripaddr[t & 0x01][2])] * 10;
03323
03324
03325 wtrans.multpoint3d(cnv + v0 + 7, (float*) &mesh.v[ind9 ]);
03326 wtrans.multpoint3d(cnv + v1 + 7, (float*) &mesh.v[ind9 + 3]);
03327 wtrans.multpoint3d(cnv + v2 + 7, (float*) &mesh.v[ind9 + 6]);
03328
03329 wtrans.multnorm3d(cnv + v0 + 4, (float*) &mesh.n[ind9 ]);
03330 wtrans.multnorm3d(cnv + v1 + 4, (float*) &mesh.n[ind9 + 3]);
03331 wtrans.multnorm3d(cnv + v2 + 4, (float*) &mesh.n[ind9 + 6]);
03332
03333 vec_copy(&mesh.c[ind12 ], cnv + v0);
03334 mesh.c[ind12 + 3] = alpha;
03335 vec_copy(&mesh.c[ind12 + 4], cnv + v1);
03336 mesh.c[ind12 + 7] = alpha;
03337 vec_copy(&mesh.c[ind12 + 8], cnv + v2);
03338 mesh.c[ind12 + 11] = alpha;
03339
03340 mesh.f[i*3 ] = i*3;
03341 mesh.f[i*3+1] = i*3 + 1;
03342 mesh.f[i*3+2] = i*3 + 2;
03343
03344 v++;
03345 i++;
03346 ind9+=9;
03347 ind12+=12;
03348 }
03349 v+=2;
03350 }
03351
03352 attach_mesh(numfacets * 3, numfacets, matindex, mesh);
03353 }
03354
03355
03356