00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00075
00076
00077
00078 #include "OptiXRenderer.h"
00079 #include "OptiXShaders.h"
00080
00081 #include <optix.h>
00082 #include <math.h>
00083 #include <stdlib.h>
00084 #include <stdio.h>
00085 #include <string.h>
00086 #if OPTIX_VERSION >= 50200
00087 #include <cuda_runtime.h>
00088 #endif
00089
00090 #if defined(__linux)
00091 #include <unistd.h>
00092 #endif
00093
00094 #include "VMDApp.h"
00095 #include "VideoStream.h"
00096 #include "DisplayDevice.h"
00097
00098 #include "Inform.h"
00099 #include "ImageIO.h"
00100 #include "Matrix4.h"
00101 #include "utilities.h"
00102 #include "WKFUtils.h"
00103 #include "ProfileHooks.h"
00104 #if defined(VMDOPTIXRTRT)
00105 #include "DispCmds.h"
00106 #endif
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #if defined(VMDUSEOPENHMD)
00118 #define VMDOPTIX_USE_HMD 1
00119 #endif
00120
00121 #if defined(VMDOPTIX_USE_HMD)
00122 #include "HMDMgr.h"
00123 #endif
00124
00125
00126 #if defined(VMDUSEEVENTIO)
00127 #include "eventio.h"
00128 #endif
00129
00130
00131 #if defined(VMDOPTIX_INTERACTIVE_OPENGL)
00132 #if (defined(WIN32) || defined(_WIN64)) && defined(_MSC_VER)
00133 #include <windows.h>
00134 #endif
00135
00136 #include <GL/gl.h>
00137 #endif
00138
00139
00140
00141
00142 #if defined(ORT_USE_TEMPLATE_SHADERS)
00143 static const char *onoffstr(int onoff) {
00144 return (onoff) ? "on" : "off";
00145 }
00146 #endif
00147
00148
00149 #define ORT_USE_HW_TRIANGLES 1
00150
00151
00152 static OptiXRenderer::Verbosity get_verbose_flag(int inform=0) {
00153 OptiXRenderer::Verbosity verbose = OptiXRenderer::RT_VERB_MIN;
00154 char *verbstr = getenv("VMDOPTIXVERBOSE");
00155 if (verbstr != NULL) {
00156
00157 if (!strupcmp(verbstr, "MIN")) {
00158 verbose = OptiXRenderer::RT_VERB_MIN;
00159 if (inform)
00160 printf("OptiXRenderer) verbose setting: minimum\n");
00161 } else if (!strupcmp(verbstr, "TIMING")) {
00162 verbose = OptiXRenderer::RT_VERB_TIMING;
00163 if (inform)
00164 printf("OptiXRenderer) verbose setting: timing data\n");
00165 } else if (!strupcmp(verbstr, "DEBUG")) {
00166 verbose = OptiXRenderer::RT_VERB_DEBUG;
00167 if (inform)
00168 printf("OptiXRenderer) verbose setting: full debugging data\n");
00169 }
00170 }
00171 return verbose;
00172 }
00173
00174
00175 #if 0
00176
00177
00178 #define VMD_ENABLE_OPTIX_TIMEOUTS 1
00179
00180 static int vmd_timeout_init = 0;
00181 static wkf_timerhandle cbtimer;
00182 static float vmd_timeout_lastcallback = 0.0f;
00183
00184 static void vmd_timeout_reset(void) {
00185 if (vmd_timeout_init == 0) {
00186 vmd_timeout_init = 1;
00187 cbtimer = wkf_timer_create();
00188 }
00189 wkf_timer_start(cbtimer);
00190 vmd_timeout_lastcallback = wkf_timer_timenow(cbtimer);
00191 }
00192
00193 static void vmd_timeout_time(float &deltat, float &totalt) {
00194 double now = wkf_timer_timenow(cbtimer);
00195 deltat = now - vmd_timeout_lastcallback;
00196 totalt = now;
00197 vmd_timeout_lastcallback = now;
00198 }
00199
00200 static int vmd_timeout_cb(void) {
00201 int earlyexit = 0;
00202 float deltat, totalt;
00203
00204 if (vmd_timeout_init == 0)
00205 vmd_timeout_reset();
00206
00207 vmd_timeout_time(deltat, totalt);
00208 printf("OptiXRenderer) timeout callback: since last %f sec, total %f sec\n",
00209 deltat, totalt);
00210 return earlyexit;
00211 }
00212
00213 #endif
00214
00215
00216
00217 #define RTERR( func ) \
00218 { \
00219 RTresult code = func; \
00220 if (code != RT_SUCCESS) { \
00221 lasterror = code; \
00222 const char* message; \
00223 rtContextGetErrorString(ctx, code, &message); \
00224 msgErr << "OptiXRenderer) ERROR: " << message << " (" \
00225 << __FILE__ << ":" << __LINE__ << sendmsg; \
00226 } \
00227 }
00228
00229
00230
00231
00232
00233 #define RTERR2( func, code ) \
00234 { \
00235 code = func; \
00236 if (code != RT_SUCCESS) { \
00237 lasterror = code; \
00238 const char* message; \
00239 rtContextGetErrorString(ctx, code, &message); \
00240 msgErr << "OptiXRenderer) ERROR: " << message << " (" \
00241 << __FILE__ << ":" << __LINE__ << sendmsg; \
00242 } \
00243 }
00244
00245
00246 #if defined(ORT_USERTXAPIS)
00247
00248
00249
00250
00251
00252
00253
00254 __forceinline__ int hwtri_test_calc_Ngeom(const float3 * __restrict__ vertices,
00255 float3 &Ngeometric) {
00256
00257 float3 Ng = cross(vertices[1]-vertices[0], vertices[2]-vertices[0]);
00258
00259
00260 float area = length(Ng);
00261 if (area > 0.0f && !isinf(area)) {
00262
00263 Ngeometric = Ng * (1.0f / area);
00264 return 0;
00265 }
00266
00267 return 1;
00268 }
00269
00270
00271
00272 static void hwtri_alloc_bufs_v3f_n4u4_c4u(RTcontext ctx, int numfacets,
00273 RTbuffer &vbuf, float3 *&vertices,
00274 RTbuffer &nbuf, uint4 *&normals,
00275 RTbuffer &cbuf, int numcolors,
00276 uchar4 *&colors,
00277 const float *uniform_color) {
00278
00279 rtBufferCreate(ctx, RT_BUFFER_INPUT, &vbuf);
00280 rtBufferSetFormat(vbuf, RT_FORMAT_FLOAT3);
00281 rtBufferSetSize1D(vbuf, numfacets * 3);
00282
00283 rtBufferCreate(ctx, RT_BUFFER_INPUT, &nbuf);
00284 rtBufferSetFormat(nbuf, RT_FORMAT_UNSIGNED_INT4);
00285 rtBufferSetSize1D(nbuf, numfacets);
00286
00287 rtBufferCreate(ctx, RT_BUFFER_INPUT, &cbuf);
00288 rtBufferSetFormat(cbuf, RT_FORMAT_UNSIGNED_BYTE4);
00289 rtBufferSetSize1D(cbuf, numcolors);
00290
00291 rtBufferMap(vbuf, (void**) &vertices);
00292 rtBufferMap(nbuf, (void**) &normals);
00293 rtBufferMap(cbuf, (void**) &colors);
00294
00295 if ((numcolors == 1) && (uniform_color != NULL)) {
00296 colors[0].x = uniform_color[0] * 255.0f;
00297 colors[0].y = uniform_color[1] * 255.0f;
00298 colors[0].z = uniform_color[2] * 255.0f;
00299 colors[0].w = 255;
00300 }
00301 }
00302
00303
00304
00305
00306 static void hwtri_set_vertex_flags(RTcontext ctx,
00307 RTgeometryinstance instance_hwtri,
00308 RTbuffer nbuf, RTbuffer cbuf,
00309 int has_vertex_normals,
00310 int has_vertex_colors) {
00311 RTresult lasterror = RT_SUCCESS;
00312
00313
00314 RTvariable nbuf_v;
00315 RTERR( rtGeometryInstanceDeclareVariable(instance_hwtri, "normalBuffer", &nbuf_v) );
00316 RTERR( rtVariableSetObject(nbuf_v, nbuf) );
00317
00318
00319 RTvariable cbuf_v;
00320 RTERR( rtGeometryInstanceDeclareVariable(instance_hwtri, "colorBuffer", &cbuf_v) );
00321 RTERR( rtVariableSetObject(cbuf_v, cbuf) );
00322
00323
00324 RTvariable has_vertex_normals_v;
00325 RTERR( rtGeometryInstanceDeclareVariable(instance_hwtri, "has_vertex_normals", &has_vertex_normals_v) );
00326 RTERR( rtVariableSet1i(has_vertex_normals_v, has_vertex_normals) );
00327
00328
00329 RTvariable has_vertex_colors_v;
00330 RTERR( rtGeometryInstanceDeclareVariable(instance_hwtri, "has_vertex_colors", &has_vertex_colors_v) );
00331 RTERR( rtVariableSet1i(has_vertex_colors_v, has_vertex_colors) );
00332
00333 if (lasterror != RT_SUCCESS) {
00334 printf("OptiXRenderer::hwtri_set_vertex_flags() error!\n");
00335 }
00336 }
00337
00338 #endif
00339
00340
00341 #if defined(VMDOPTIX_INTERACTIVE_OPENGL)
00342
00343 static void print_ctx_devices(RTcontext ctx) {
00344 unsigned int devcount = 0;
00345 rtContextGetDeviceCount(ctx, &devcount);
00346 if (devcount > 0) {
00347 int *devlist = (int *) calloc(1, devcount * sizeof(int));
00348 rtContextGetDevices(ctx, devlist);
00349 printf("OptiXRenderer) Using %d device%s:\n",
00350 devcount, (devcount == 1) ? "" : "s");
00351
00352 unsigned int d;
00353 for (d=0; d<devcount; d++) {
00354 char devname[20];
00355 int cudadev=-1, kto=-1;
00356 RTsize totalmem;
00357 memset(devname, 0, sizeof(devname));
00358
00359 rtDeviceGetAttribute(devlist[d], RT_DEVICE_ATTRIBUTE_NAME, sizeof(devname), devname);
00360 rtDeviceGetAttribute(devlist[d], RT_DEVICE_ATTRIBUTE_EXECUTION_TIMEOUT_ENABLED, sizeof(int), &kto);
00361 rtDeviceGetAttribute(devlist[d], RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL, sizeof(int), &cudadev);
00362 rtDeviceGetAttribute(devlist[d], RT_DEVICE_ATTRIBUTE_TOTAL_MEMORY, sizeof(totalmem), &totalmem);
00363
00364 printf("OptiXRenderer) [%u] %-19s CUDA[%d], %.1fGB RAM",
00365 d, devname, cudadev, totalmem / (1024.0*1024.0*1024.0));
00366 if (kto) {
00367 printf(", KTO");
00368 }
00369 printf("\n");
00370 }
00371 printf("OptiXRenderer)\n");
00372
00373 free(devlist);
00374 }
00375 }
00376
00377 #endif
00378
00379
00380 static int query_meminfo_ctx_devices(RTcontext &ctx, unsigned long &freemem, unsigned long &physmem) {
00381 freemem=0;
00382 physmem=0;
00383 RTresult lasterror = RT_SUCCESS;
00384
00385 unsigned int devcount = 0;
00386 RTERR( rtContextGetDeviceCount(ctx, &devcount) );
00387 if (devcount > 0) {
00388 int *devlist = (int *) calloc(1, devcount * sizeof(int));
00389 RTERR( rtContextGetDevices(ctx, devlist) );
00390 unsigned int d;
00391 for (d=0; d<devcount; d++) {
00392 RTsize freememsz=0;
00393 RTsize physmemsz=0;
00394 int ordinal = devlist[d];
00395 RTERR( rtContextGetAttribute(ctx, static_cast<RTcontextattribute>(RT_CONTEXT_ATTRIBUTE_AVAILABLE_DEVICE_MEMORY+ordinal), sizeof(freememsz), &freememsz) );
00396 if (lasterror != RT_SUCCESS) {
00397 free(devlist);
00398 return -1;
00399 }
00400
00401 RTERR( rtDeviceGetAttribute(devlist[d], RT_DEVICE_ATTRIBUTE_TOTAL_MEMORY, sizeof(physmemsz), &physmemsz) );
00402 if (lasterror != RT_SUCCESS) {
00403 free(devlist);
00404 return -1;
00405 }
00406
00407 if (d==0) {
00408 freemem = freememsz;
00409 physmem = physmemsz;
00410 } else {
00411 if (freemem < freememsz)
00412 freemem = freememsz;
00413
00414 if (physmem < physmemsz)
00415 physmem = physmemsz;
00416 }
00417 }
00418 free(devlist);
00419 return 0;
00420 }
00421
00422 return -1;
00423 }
00424
00425
00426 int OptiXPrintRayStats(RTbuffer raystats1_buffer, RTbuffer raystats2_buffer,
00427 double rtruntime) {
00428 int rc = 0;
00429 RTcontext ctx;
00430 RTresult result;
00431 RTsize buffer_width, buffer_height;
00432 const char* error;
00433
00434 rtBufferGetContext(raystats1_buffer, &ctx);
00435
00436
00437 unsigned int bufdim;
00438 if (rtBufferGetDimensionality(raystats1_buffer, &bufdim) != RT_SUCCESS) {
00439 msgErr << "OptiXPrintRayStats: Failed to get ray stats buffer dimensions!" << sendmsg;
00440 return -1;
00441 }
00442 if (bufdim != 2) {
00443 msgErr << "OptiXPrintRayStats: Output buffer is not 2-D!" << sendmsg;
00444 return -1;
00445 }
00446
00447 result = rtBufferGetSize2D(raystats1_buffer, &buffer_width, &buffer_height);
00448 if (result != RT_SUCCESS) {
00449
00450 rtContextGetErrorString(ctx, result, &error);
00451 msgErr << "OptiXRenderer) Error getting dimensions of buffers: " << error << sendmsg;
00452 return -1;
00453 }
00454
00455 volatile uint4 *raystats1, *raystats2;
00456 result = rtBufferMap(raystats1_buffer, (void**) &raystats1);
00457 result = rtBufferMap(raystats2_buffer, (void**) &raystats2);
00458 if (result != RT_SUCCESS) {
00459 rtContextGetErrorString(ctx, result, &error);
00460 msgErr << "OptiXPrintRayStats: Error mapping stats buffers: "
00461 << error << sendmsg;
00462 return -1;
00463 }
00464
00465
00466 if (buffer_width < 1 || buffer_height < 1 ||
00467 raystats1 == NULL || raystats2 == NULL) {
00468 msgErr << "OptiXPrintRayStats: No data in ray stats buffers!" << sendmsg;
00469 return -1;
00470 }
00471
00472
00473 int i;
00474 int totalsz = buffer_width * buffer_height;
00475 unsigned long misses, transkips;
00476 unsigned long primaryrays, shadowlights, shadowao, transrays, reflrays;
00477 misses = transkips = primaryrays = shadowlights
00478 = shadowao = transrays = reflrays = 0;
00479
00480
00481 for (i=0; i<totalsz; i++) {
00482 primaryrays += raystats1[i].x;
00483 shadowlights += raystats1[i].y;
00484 shadowao += raystats1[i].z;
00485 misses += raystats1[i].w;
00486 transrays += raystats2[i].x;
00487 transkips += raystats2[i].y;
00488
00489 reflrays += raystats2[i].w;
00490 }
00491 unsigned long totalrays = primaryrays + shadowlights + shadowao
00492 + transrays + reflrays;
00493
00494 printf("OptiXRenderer)\n");
00495 printf("OptiXRenderer) VMD/OptiX Scene Ray Tracing Statistics:\n");
00496 printf("OptiXRenderer) ----------------------------------------\n");
00497 printf("OptiXRenderer) Image resolution: %lu x %lu \n",
00498 buffer_width, buffer_height);
00499 printf("OptiXRenderer) ----------------------------------------\n");
00500 printf("OptiXRenderer) Misses: %lu\n", misses);
00501 printf("OptiXRenderer) Transmission Any-Hit Skips: %lu\n", transkips);
00502 printf("OptiXRenderer) ----------------------------------------\n");
00503 printf("OptiXRenderer) Primary Rays: %lu\n", primaryrays);
00504 printf("OptiXRenderer) Dir-Light Shadow Rays: %lu\n", shadowlights);
00505 printf("OptiXRenderer) AO Shadow Rays: %lu\n", shadowao);
00506 printf("OptiXRenderer) Transmission Rays: %lu\n", transrays);
00507 printf("OptiXRenderer) Reflection Rays: %lu\n", reflrays);
00508 printf("OptiXRenderer) ----------------------------------------\n");
00509 printf("OptiXRenderer) Total Rays: %lu\n", totalrays);
00510 printf("OptiXRenderer) Total Rays: %g\n", totalrays * 1.0);
00511 if (rtruntime > 0.0) {
00512 printf("OptiXRenderer) Rays/sec: %g\n", totalrays / rtruntime);
00513 }
00514 printf("OptiXRenderer)\n");
00515
00516 result = rtBufferUnmap(raystats1_buffer);
00517 result = rtBufferUnmap(raystats2_buffer);
00518 if (result != RT_SUCCESS) {
00519 rtContextGetErrorString(ctx, result, &error);
00520 msgErr << "OptiXPrintRayStats: Error unmapping ray stats buffer: "
00521 << error << sendmsg;
00522 return -1;
00523 }
00524
00525 return rc;
00526 }
00527
00528
00529 int OptiXWriteImage(const char* filename, int writealpha,
00530 RTbuffer buffer, RTformat buffer_format,
00531 RTsize buffer_width, RTsize buffer_height) {
00532 RTresult result;
00533
00534 void * imageData;
00535 result = rtBufferMap(buffer, &imageData);
00536 if (result != RT_SUCCESS) {
00537 RTcontext ctx;
00538 const char* error;
00539 rtBufferGetContext(buffer, &ctx);
00540 rtContextGetErrorString(ctx, result, &error);
00541 msgErr << "OptiXWriteImage: Error mapping image buffer: "
00542 << error << sendmsg;
00543 return -1;
00544 }
00545
00546
00547 if (buffer_width < 1 || buffer_height < 1 || imageData == NULL) {
00548 msgErr << "OptiXWriteImage: No image data in output buffer!" << sendmsg;
00549 return -1;
00550 }
00551
00552
00553 int xs = buffer_width;
00554 int ys = buffer_height;
00555 int rc = 0;
00556 if (buffer_format == RT_FORMAT_FLOAT4) {
00557 if (writealpha) {
00558
00559 if (write_image_file_rgba4f(filename, (const float *) imageData, xs, ys))
00560 rc = -1;
00561 } else {
00562 if (write_image_file_rgb4f(filename, (const float *) imageData, xs, ys))
00563 rc = -1;
00564 }
00565 } else if (buffer_format == RT_FORMAT_UNSIGNED_BYTE4) {
00566 if (writealpha) {
00567
00568 if (write_image_file_rgba4u(filename, (const unsigned char *) imageData, xs, ys))
00569 rc = -1;
00570 } else {
00571 if (write_image_file_rgb4u(filename, (const unsigned char *) imageData, xs, ys))
00572 rc = -1;
00573 }
00574 } else {
00575 rc = -1;
00576 }
00577
00578 result = rtBufferUnmap(buffer);
00579 if (result != RT_SUCCESS) {
00580 RTcontext ctx;
00581 const char* error;
00582 rtBufferGetContext(buffer, &ctx);
00583 rtContextGetErrorString(ctx, result, &error);
00584 msgErr << "OptiXWriteImage: Error unmapping image buffer: "
00585 << error << sendmsg;
00586 return -1;
00587 }
00588
00589 return rc;
00590 }
00591
00592
00593 int OptiXWriteImage(const char* filename, int writealpha, RTbuffer buffer) {
00594 RTresult result;
00595 RTformat buffer_format;
00596 RTsize buffer_width, buffer_height;
00597
00598
00599 unsigned int bufdim;
00600 if (rtBufferGetDimensionality(buffer, &bufdim) != RT_SUCCESS) {
00601 msgErr << "OptiXWriteImage: Failed to get output buffer dimensions!" << sendmsg;
00602 return -1;
00603 }
00604
00605 if (bufdim != 2) {
00606 msgErr << "OptiXWriteImage: Output buffer is not 2-D!" << sendmsg;
00607 return -1;
00608 }
00609
00610 void * imageData;
00611 result = rtBufferMap(buffer, &imageData);
00612 if (result != RT_SUCCESS) {
00613 RTcontext ctx;
00614 const char* error;
00615 rtBufferGetContext(buffer, &ctx);
00616 rtContextGetErrorString(ctx, result, &error);
00617 msgErr << "OptiXWriteImage: Error mapping image buffer: "
00618 << error << sendmsg;
00619 return -1;
00620 }
00621
00622
00623 if (imageData == NULL) {
00624 msgErr << "OptiXWriteImage: No image data in output buffer!" << sendmsg;
00625 return -1;
00626 }
00627
00628 result = rtBufferGetSize2D(buffer, &buffer_width, &buffer_height);
00629 if (result != RT_SUCCESS) {
00630
00631 RTcontext ctx;
00632 const char* error;
00633 rtBufferGetContext(buffer, &ctx);
00634 rtContextGetErrorString(ctx, result, &error);
00635 msgErr << "OptiXRenderer) Error getting dimensions of buffer: " << error << sendmsg;
00636 return -1;
00637 }
00638
00639 if (rtBufferGetFormat(buffer, &buffer_format) != RT_SUCCESS) {
00640 msgErr << "OptiXWriteImage: failed to query output buffer format!"
00641 << sendmsg;
00642 return -1;
00643 }
00644
00645
00646 int xs = buffer_width;
00647 int ys = buffer_height;
00648 int rc = 0;
00649
00650 if (buffer_format == RT_FORMAT_FLOAT4) {
00651 if (writealpha) {
00652
00653 if (write_image_file_rgba4f(filename, (const float *) imageData, xs, ys))
00654 rc = -1;
00655 } else {
00656 if (write_image_file_rgb4f(filename, (const float *) imageData, xs, ys))
00657 rc = -1;
00658 }
00659 } else if (buffer_format == RT_FORMAT_UNSIGNED_BYTE4) {
00660 if (writealpha) {
00661
00662 if (write_image_file_rgba4u(filename, (const unsigned char *) imageData, xs, ys))
00663 rc = -1;
00664 } else {
00665 if (write_image_file_rgb4u(filename, (const unsigned char *) imageData, xs, ys))
00666 rc = -1;
00667 }
00668 } else {
00669 rc = -1;
00670 }
00671
00672 result = rtBufferUnmap(buffer);
00673 if (result != RT_SUCCESS) {
00674 RTcontext ctx;
00675 const char* error;
00676 rtBufferGetContext(buffer, &ctx);
00677 rtContextGetErrorString(ctx, result, &error);
00678 msgErr << "OptiXWriteImage: Error unmapping image buffer: "
00679 << error << sendmsg;
00680 return -1;
00681 }
00682
00683 return rc;
00684 }
00685
00686
00688 OptiXRenderer::OptiXRenderer(VMDApp *vmdapp) {
00689 PROFILE_PUSH_RANGE("OptiXRenderer::OptiXRenderer()", 0);
00690 app = vmdapp;
00691 ort_timer = wkf_timer_create();
00692 wkf_timer_start(ort_timer);
00693
00694
00695 const char *vmddir = getenv("VMDDIR");
00696 if (vmddir == NULL)
00697 vmddir = ".";
00698 sprintf(shaderpath, "%s/shaders/%s", vmddir, "OptiXShaders.ptx");
00699
00700
00701 if (getenv("VMDOPTIXSHADERPATH")) {
00702 strcpy(shaderpath, getenv("VMDOPTIXSHADERPATH"));
00703 msgInfo << "User-override of OptiX shader path: " << getenv("VMDOPTIXSHADERPATH") << sendmsg;
00704 }
00705
00706 #if defined(ORT_USERTXAPIS)
00707 rtx_enabled = 1;
00708 hwtri_enabled = 1;
00709 #endif
00710
00711 lasterror = RT_SUCCESS;
00712 context_created = 0;
00713 buffers_allocated = 0;
00714 buffers_progressive = 0;
00715 scene_created = 0;
00716
00717
00718 time_ctx_setup = 0.0;
00719 time_ctx_validate = 0.0;
00720 time_ctx_AS_build = 0.0;
00721 time_ray_tracing = 0.0;
00722 time_image_io = 0.0;
00723
00724
00725 scene_background_mode = RT_BACKGROUND_TEXTURE_SOLID;
00726 memset(scene_bg_color, 0, sizeof(scene_bg_color));
00727 memset(scene_bg_grad_top, 0, sizeof(scene_bg_grad_top));
00728 memset(scene_bg_grad_bot, 0, sizeof(scene_bg_grad_bot));
00729 memset(scene_gradient, 0, sizeof(scene_gradient));
00730 scene_gradient_topval = 1.0f;
00731 scene_gradient_botval = 0.0f;
00732
00733 scene_gradient_invrange = 1.0f / (scene_gradient_topval - scene_gradient_botval);
00734
00735
00736 memset(material_special_counts, 0, sizeof(material_special_counts));
00737
00738 cam_zoom = 1.0f;
00739 cam_stereo_eyesep = 0.06f;
00740 cam_stereo_convergence_dist = 2.0f;
00741
00742 clipview_mode = RT_CLIP_NONE;
00743 clipview_start = 1.0f;
00744 clipview_end = 0.2f;
00745
00746
00747 if (getenv("VMDOPTIXCLIPVIEW")) {
00748 clipview_mode = RT_CLIP_SPHERE;
00749 msgInfo << "OptiXRenderer) Overriding default clipping mode with RT_CLIP_SPHERE" << sendmsg;
00750 }
00751 if (getenv("VMDOPTIXCLIPVIEWSTART")) {
00752 clipview_start = float(atof(getenv("VMDOPTIXCLIPVIEWSTART")));
00753 msgInfo << "OptiXRenderer) Overriding default clipping start: "
00754 << clipview_start << sendmsg;
00755 }
00756 if (getenv("VMDOPTIXCLIPVIEWEND")) {
00757 clipview_start = float(atof(getenv("VMDOPTIXCLIPVIEWEND")));
00758 msgInfo << "OptiXRenderer) Overriding default clipping end: "
00759 << clipview_start << sendmsg;
00760 }
00761
00762 headlight_mode = RT_HEADLIGHT_OFF;
00763 if (getenv("VMDOPTIXHEADLIGHT")) {
00764 headlight_mode = RT_HEADLIGHT_ON;
00765 msgInfo << "OptiXRenderer) Overriding default headlight mode with RT_HEADLIGHT_ON" << sendmsg;
00766 }
00767
00768 shadows_enabled = RT_SHADOWS_OFF;
00769 aa_samples = 0;
00770
00771 ao_samples = 0;
00772 ao_direct = 0.3f;
00773 ao_ambient = 0.7f;
00774 ao_maxdist = RT_DEFAULT_MAX;
00775
00776 dof_enabled = 0;
00777 cam_dof_focal_dist = 2.0f;
00778 cam_dof_fnumber = 64.0f;
00779
00780 fog_mode = RT_FOG_NONE;
00781 fog_start = 0.0f;
00782 fog_end = 10.0f;
00783 fog_density = 0.32f;
00784
00785 verbose = RT_VERB_MIN;
00786 check_verbose_env();
00787
00788 create_context();
00789 destroy_scene();
00790
00791 PROFILE_POP_RANGE();
00792 }
00793
00795 OptiXRenderer::~OptiXRenderer(void) {
00796 PROFILE_PUSH_RANGE("OptiXRenderer::~OptiXRenderer()", 0);
00797
00798 if (context_created)
00799 destroy_context();
00800 wkf_timer_destroy(ort_timer);
00801
00802 PROFILE_POP_RANGE();
00803 }
00804
00805
00806 void OptiXRenderer::check_verbose_env() {
00807 verbose = get_verbose_flag(1);
00808 }
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 unsigned int OptiXRenderer::device_list(int **devlist, char ***devnames) {
00819 OptiXRenderer::Verbosity dl_verbose = get_verbose_flag();
00820 if (dl_verbose == RT_VERB_DEBUG)
00821 printf("OptiXRenderer) OptiXRenderer::device_list()\n");
00822
00823 unsigned int count=0;
00824 RTresult devcntresult = rtDeviceGetDeviceCount(&count);
00825 if (devcntresult != RT_SUCCESS) {
00826 #if OPTIX_VERSION >= 50200
00827 if (devcntresult == RT_ERROR_OPTIX_NOT_LOADED) {
00828 int cudadevcount = 0;
00829 cudaGetDeviceCount(&cudadevcount);
00830 if (cudadevcount > 0) {
00831 printf("OptiXRenderer) ERROR: Failed to load OptiX shared library.\n");
00832 printf("OptiXRenderer) NVIDIA driver may be too old.\n");
00833 printf("OptiXRenderer) Check/update NVIDIA driver\n");
00834 }
00835 }
00836 #endif
00837
00838 if (dl_verbose == RT_VERB_DEBUG) {
00839 printf("OptiXRenderer) rtDeviceGetDeviceCount() returned error %08x\n",
00840 devcntresult);
00841 printf("OptiXRenderer) No GPUs available\n");
00842 }
00843
00844 count = 0;
00845 if (devlist != NULL)
00846 *devlist = NULL;
00847 if (devnames != NULL)
00848 *devnames = NULL;
00849
00850 return 0;
00851 }
00852
00853 if (dl_verbose == RT_VERB_DEBUG) {
00854 printf("OptiXRenderer) OptiX rtDeviceGetDeviceCount() reports\n");
00855 printf("OptiXRenderer) that %d GPUs are available\n", count);
00856 }
00857
00858
00859 unsigned int gpumask = 0xffffffff;
00860 const char *gpumaskstr = getenv("VMDOPTIXDEVICEMASK");
00861 if (gpumaskstr != NULL) {
00862 unsigned int tmp;
00863 if (sscanf(gpumaskstr, "%x", &tmp) == 1) {
00864 gpumask = tmp;
00865 msgInfo << "Using OptiX device mask '"
00866 << gpumaskstr << "'" << sendmsg;
00867 } else {
00868 msgInfo << "Failed to parse OptiX GPU device mask string '"
00869 << gpumaskstr << "'" << sendmsg;
00870 }
00871 }
00872
00873 if (devlist != NULL) {
00874 *devlist = NULL;
00875 if (count > 0) {
00876 *devlist = (int *) calloc(1, count * sizeof(int));
00877 }
00878 }
00879 if (devnames != NULL) {
00880 *devnames = NULL;
00881 if (count > 0) {
00882 *devnames = (char **) calloc(1, count * sizeof(char *));
00883 }
00884 }
00885
00886
00887
00888 unsigned int i, goodcount;
00889 for (goodcount=0,i=0; i<count; i++) {
00890
00891 if (!(gpumask & (1 << i))) {
00892 if (dl_verbose == RT_VERB_DEBUG) {
00893 char msgbuf[1024];
00894 sprintf(msgbuf, " Excluded GPU[%d] due to user-specified device mask\n", i);
00895 msgInfo << msgbuf << sendmsg;
00896 }
00897 continue;
00898 }
00899
00900
00901 int timeoutenabled;
00902 rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_EXECUTION_TIMEOUT_ENABLED,
00903 sizeof(int), &timeoutenabled);
00904 if (timeoutenabled && getenv("VMDOPTIXNODISPLAYGPUS")) {
00905 if (dl_verbose == RT_VERB_DEBUG) {
00906 char msgbuf[1024];
00907 sprintf(msgbuf, " Excluded GPU[%d] due to user-specified display timeout exclusion \n", i);
00908 msgInfo << msgbuf << sendmsg;
00909 }
00910 continue;
00911 }
00912
00913
00914
00915
00916
00917
00918 int compute_capability[2];
00919 rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY,
00920 sizeof(compute_capability), compute_capability);
00921
00922 #if OPTIX_VERSION <= 3051
00923
00924 if (compute_capability[0] > 3) {
00925 if (dl_verbose == RT_VERB_DEBUG) {
00926 char msgbuf[1024];
00927 sprintf(msgbuf, " Excluded GPU[%d] due to unsupported compute capability\n", i);
00928 msgInfo << msgbuf << sendmsg;
00929 }
00930 continue;
00931 }
00932 #endif
00933
00934
00935 if (dl_verbose == RT_VERB_DEBUG) {
00936 char msgbuf[1024];
00937 sprintf(msgbuf, "Found usable GPU[%i]\n", i);
00938 msgInfo << msgbuf << sendmsg;
00939 }
00940
00941 if (devlist != NULL) {
00942 if (dl_verbose == RT_VERB_DEBUG) {
00943 char msgbuf[1024];
00944 sprintf(msgbuf, " Adding usable GPU[%i] to list[%d]\n", i, goodcount);
00945 msgInfo << msgbuf << sendmsg;
00946 }
00947 (*devlist)[goodcount] = i;
00948 }
00949
00950 if (devnames != NULL) {
00951 char *namebuf = (char *) calloc(1, 65 * sizeof(char));
00952 rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_NAME,
00953 64*sizeof(char), namebuf);
00954 if (dl_verbose == RT_VERB_DEBUG) {
00955 char msgbuf[1024];
00956 sprintf(msgbuf, " Adding usable GPU[%i] to list[%d]: '%s'\n", i, goodcount, namebuf);
00957 msgInfo << msgbuf << sendmsg;
00958 }
00959 (*devnames)[goodcount] = namebuf;
00960 }
00961 goodcount++;
00962 }
00963
00964 return goodcount;
00965 }
00966
00967
00968 unsigned int OptiXRenderer::device_count(void) {
00969 OptiXRenderer::Verbosity dl_verbose = get_verbose_flag();
00970 if (dl_verbose == RT_VERB_DEBUG)
00971 printf("OptiXRenderer) OptiXRenderer::device_count()\n");
00972
00973 #if 1
00974 return device_list(NULL, NULL);
00975 #else
00976 unsigned int count=0;
00977 if (rtDeviceGetDeviceCount(&count) != RT_SUCCESS)
00978 count = 0;
00979 return count;
00980 #endif
00981 }
00982
00983
00984 unsigned int OptiXRenderer::optix_version(void) {
00985 OptiXRenderer::Verbosity dl_verbose = get_verbose_flag();
00986 if (dl_verbose == RT_VERB_DEBUG)
00987 msgInfo << "OptiXRenderer) OptiXRenderer::optix_version()" << sendmsg;
00988
00989 unsigned int version=0;
00990 if (rtGetVersion(&version) != RT_SUCCESS)
00991 version = 0;
00992 return version;
00993 }
00994
00995
00996 int OptiXRenderer::material_shader_table_size(void) {
00997
00998 #if defined(ORT_USE_TEMPLATE_SHADERS)
00999 return ORTMTABSZ;
01000 #else
01001 return 1;
01002 #endif
01003 }
01004
01005
01006 void OptiXRenderer::create_context() {
01007 time_ctx_create = 0;
01008 if (context_created)
01009 return;
01010
01011 double starttime = wkf_timer_timenow(ort_timer);
01012
01013 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating context...\n");
01014
01015 #if defined(ORT_USERTXAPIS)
01016
01017
01018
01019
01020
01021 int rtxonoff = 1;
01022 if (getenv("VMDOPTIXNORTX") != NULL) {
01023 rtxonoff = 0;
01024
01025
01026 rtx_enabled = 0;
01027 hwtri_enabled = 0;
01028 }
01029
01030
01031
01032
01033
01034 if (rtGlobalSetAttribute(RT_GLOBAL_ATTRIBUTE_ENABLE_RTX, sizeof(rtxonoff), &rtxonoff) != RT_SUCCESS) {
01035 printf("OptiXRenderer) Error setting RT_GLOBAL_ATTRIBUTE_ENABLE_RTX!!!\n");
01036 } else {
01037 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG)
01038 printf("OptiXRenderer) OptiX RTX execution mode is %s.\n",
01039 (rtxonoff) ? "on" : "off");
01040 }
01041 #endif
01042
01043
01044 RTresult ctxrc;
01045 RTERR2( rtContextCreate(&ctx), ctxrc );
01046 if (ctxrc != RT_SUCCESS) {
01047 msgErr << "OptiXRenderer) Failed to create OptiX rendering context" << sendmsg;
01048 context_created=0;
01049 return;
01050 }
01051
01052
01053
01054
01055 if (getenv("VMDOPTIXDEVICEMASK") != NULL) {
01056 int *optixdevlist;
01057 int optixdevcount = device_list(&optixdevlist, NULL);
01058 if (optixdevcount > 0) {
01059 RTERR( rtContextSetDevices(ctx, optixdevcount, optixdevlist) );
01060 }
01061 free(optixdevlist);
01062 } else if (getenv("VMDOPTIXDEVICE") != NULL) {
01063 int optixdev = atoi(getenv("VMDOPTIXDEVICE"));
01064 msgInfo << "Setting OptiX GPU device to: " << optixdev << sendmsg;
01065 RTERR( rtContextSetDevices(ctx, 1, &optixdev) );
01066 }
01067
01068
01069 RTERR( rtContextSetRayTypeCount(ctx, RT_RAY_TYPE_COUNT) );
01070
01071
01072 RTERR( rtContextDeclareVariable(ctx, "progressive_enabled", &progressive_enabled_v) );
01073 RTERR( rtVariableSet1i(progressive_enabled_v, 0) );
01074
01075
01076 RTERR( rtContextDeclareVariable(ctx, "max_depth", &max_depth_v) );
01077 RTERR( rtContextDeclareVariable(ctx, "max_trans", &max_trans_v) );
01078 RTERR( rtContextDeclareVariable(ctx, "radiance_ray_type", &radiance_ray_type_v) );
01079 RTERR( rtContextDeclareVariable(ctx, "shadow_ray_type", &shadow_ray_type_v) );
01080 RTERR( rtContextDeclareVariable(ctx, "scene_epsilon", &scene_epsilon_v) );
01081
01082
01083 #if defined(VMDOPTIX_LIGHTUSEROBJS)
01084 RTERR( rtContextDeclareVariable(ctx, "dir_light_list", &dir_light_list_v) );
01085 RTERR( rtContextDeclareVariable(ctx, "pos_light_list", &pos_light_list_v) );
01086 #else
01087 RTERR( rtContextDeclareVariable(ctx, "dir_lights", &dir_lightbuffer_v) );
01088 RTERR( rtBufferCreate(ctx, RT_BUFFER_INPUT, &dir_lightbuffer) );
01089 RTERR( rtBufferSetFormat(dir_lightbuffer, RT_FORMAT_USER) );
01090 RTERR( rtBufferSetElementSize(dir_lightbuffer, sizeof(DirectionalLight)) );
01091
01092 RTERR( rtContextDeclareVariable(ctx, "pos_lights", &pos_lightbuffer_v) );
01093 RTERR( rtBufferCreate(ctx, RT_BUFFER_INPUT, &pos_lightbuffer) );
01094 RTERR( rtBufferSetFormat(pos_lightbuffer, RT_FORMAT_USER) );
01095 RTERR( rtBufferSetElementSize(pos_lightbuffer, sizeof(PositionalLight)) );
01096 #endif
01097
01098
01099
01100 RTERR( rtContextDeclareVariable(ctx, "accumCount", &accum_count_v) );
01101 RTERR( rtVariableSet1ui(accum_count_v, 0) );
01102
01103
01104 RTERR( rtContextDeclareVariable(ctx, "ao_direct", &ao_direct_v) );
01105 RTERR( rtContextDeclareVariable(ctx, "ao_ambient", &ao_ambient_v) );
01106 RTERR( rtContextDeclareVariable(ctx, "ao_maxdist", &ao_maxdist_v) );
01107
01108
01109 RTERR( rtContextDeclareVariable(ctx, "shadows_enabled", &shadows_enabled_v) );
01110 RTERR( rtContextDeclareVariable(ctx, "aa_samples", &aa_samples_v) );
01111 RTERR( rtContextDeclareVariable(ctx, "ao_samples", &ao_samples_v) );
01112
01113
01114 RTERR( rtContextDeclareVariable(ctx, "scene_bg_color", &scene_bg_color_v) );
01115 RTERR( rtContextDeclareVariable(ctx, "scene_bg_color_grad_top", &scene_bg_grad_top_v) );
01116 RTERR( rtContextDeclareVariable(ctx, "scene_bg_color_grad_bot", &scene_bg_grad_bot_v) );
01117 RTERR( rtContextDeclareVariable(ctx, "scene_gradient", &scene_gradient_v) );
01118 RTERR( rtContextDeclareVariable(ctx, "scene_gradient_topval", &scene_gradient_topval_v) );
01119 RTERR( rtContextDeclareVariable(ctx, "scene_gradient_botval", &scene_gradient_botval_v) );
01120 RTERR( rtContextDeclareVariable(ctx, "scene_gradient_invrange", &scene_gradient_invrange_v) );
01121
01122
01123 RTERR( rtContextDeclareVariable(ctx, "clipview_mode", &clipview_mode_v) );
01124 RTERR( rtContextDeclareVariable(ctx, "clipview_start", &clipview_start_v) );
01125 RTERR( rtContextDeclareVariable(ctx, "clipview_end", &clipview_end_v) );
01126 RTERR( rtContextDeclareVariable(ctx, "headlight_mode", &headlight_mode_v) );
01127
01128
01129 RTERR( rtContextDeclareVariable(ctx, "fog_mode", &fog_mode_v) );
01130 RTERR( rtContextDeclareVariable(ctx, "fog_start", &fog_start_v) );
01131 RTERR( rtContextDeclareVariable(ctx, "fog_end", &fog_end_v) );
01132 RTERR( rtContextDeclareVariable(ctx, "fog_density", &fog_density_v) );
01133
01134
01135 RTERR( rtContextDeclareVariable(ctx, "root_object", &root_object_v) );
01136 RTERR( rtContextDeclareVariable(ctx, "root_shadower", &root_shadower_v) );
01137
01138
01139 RTERR( rtContextDeclareVariable(ctx, "cam_zoom", &cam_zoom_v) );
01140 RTERR( rtContextDeclareVariable(ctx, "cam_pos", &cam_pos_v) );
01141 RTERR( rtContextDeclareVariable(ctx, "cam_U", &cam_U_v) );
01142 RTERR( rtContextDeclareVariable(ctx, "cam_V", &cam_V_v) );
01143 RTERR( rtContextDeclareVariable(ctx, "cam_W", &cam_W_v) );
01144
01145
01146 RTERR( rtContextDeclareVariable(ctx, "cam_stereo_eyesep", &cam_stereo_eyesep_v) );
01147 RTERR( rtContextDeclareVariable(ctx, "cam_stereo_convergence_dist", &cam_stereo_convergence_dist_v) );
01148
01149
01150 RTERR( rtContextDeclareVariable(ctx, "cam_dof_focal_dist", &cam_dof_focal_dist_v) );
01151 RTERR( rtContextDeclareVariable(ctx, "cam_dof_aperture_rad", &cam_dof_aperture_rad_v) );
01152
01153 RTERR( rtContextDeclareVariable(ctx, "accumulation_normalization_factor", &accum_norm_v) );
01154
01155
01156
01157
01158
01159
01160
01161 if (getenv("VMDOPTIXSHADERPATH")) {
01162 strcpy(shaderpath, getenv("VMDOPTIXSHADERPATH"));
01163 if (verbose == RT_VERB_DEBUG)
01164 printf("OptiXRenderer) user-override shaderpath: '%s'\n", shaderpath);
01165 }
01166
01167 if (verbose >= RT_VERB_TIMING) {
01168 printf("OptiXRenderer) creating shader programs...\n");
01169 fflush(stdout);
01170 }
01171
01172
01173 init_materials();
01174
01175 double time_materials = wkf_timer_timenow(ort_timer);
01176 if (verbose >= RT_VERB_TIMING) {
01177 printf("OptiXRenderer) ");
01178 printf("materials(%.1f) ", time_materials - starttime);
01179 fflush(stdout);
01180 }
01181
01182 #if defined(ORT_RAYSTATS)
01183
01184 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "clear_raystats_buffers", &clear_raystats_buffers_pgm) );
01185 #endif
01186
01187
01188 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "clear_accumulation_buffer", &clear_accumulation_buffer_pgm) );
01189
01190
01191 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "draw_accumulation_buffer", &draw_accumulation_buffer_pgm) );
01192
01193
01194 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "draw_accumulation_buffer_stub", &draw_accumulation_buffer_stub_pgm) );
01195
01196 double time_fbops = wkf_timer_timenow(ort_timer);
01197 if (verbose >= RT_VERB_TIMING) {
01198 printf("fbops(%.1f) ", time_fbops - time_materials);
01199 fflush(stdout);
01200 }
01201
01202
01203 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01204 "vmd_camera_cubemap", &ray_gen_pgm_cubemap) );
01205 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01206 "vmd_camera_cubemap_dof", &ray_gen_pgm_cubemap_dof) );
01207 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01208 "vmd_camera_cubemap_stereo", &ray_gen_pgm_cubemap_stereo) );
01209 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01210 "vmd_camera_cubemap_stereo_dof", &ray_gen_pgm_cubemap_stereo_dof) );
01211
01212
01213 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01214 "vmd_camera_dome_master", &ray_gen_pgm_dome_master) );
01215 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01216 "vmd_camera_dome_master_dof", &ray_gen_pgm_dome_master_dof) );
01217 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01218 "vmd_camera_dome_master_stereo", &ray_gen_pgm_dome_master_stereo) );
01219 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01220 "vmd_camera_dome_master_stereo_dof", &ray_gen_pgm_dome_master_stereo_dof) );
01221
01222
01223 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01224 "vmd_camera_equirectangular", &ray_gen_pgm_equirectangular) );
01225 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01226 "vmd_camera_equirectangular_dof", &ray_gen_pgm_equirectangular_dof) );
01227 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01228 "vmd_camera_equirectangular_stereo", &ray_gen_pgm_equirectangular_stereo) );
01229 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01230 "vmd_camera_equirectangular_stereo_dof", &ray_gen_pgm_equirectangular_stereo_dof) );
01231
01232
01233 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01234 "vmd_camera_oculus_rift", &ray_gen_pgm_oculus_rift) );
01235 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01236 "vmd_camera_oculus_rift_dof", &ray_gen_pgm_oculus_rift_dof) );
01237 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01238 "vmd_camera_oculus_rift_stereo", &ray_gen_pgm_oculus_rift_stereo) );
01239 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01240 "vmd_camera_oculus_rift_stereo_dof", &ray_gen_pgm_oculus_rift_stereo_dof) );
01241
01242
01243 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01244 "vmd_camera_perspective", &ray_gen_pgm_perspective) );
01245 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01246 "vmd_camera_perspective_dof", &ray_gen_pgm_perspective_dof) );
01247 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01248 "vmd_camera_perspective_stereo", &ray_gen_pgm_perspective_stereo) );
01249 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01250 "vmd_camera_perspective_stereo_dof", &ray_gen_pgm_perspective_stereo_dof) );
01251
01252
01253 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01254 "vmd_camera_orthographic", &ray_gen_pgm_orthographic) );
01255 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01256 "vmd_camera_orthographic_dof", &ray_gen_pgm_orthographic_dof) );
01257 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01258 "vmd_camera_orthographic_stereo", &ray_gen_pgm_orthographic_stereo) );
01259 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath,
01260 "vmd_camera_orthographic_stereo_dof", &ray_gen_pgm_orthographic_stereo_dof) );
01261
01262
01263 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "miss_gradient_bg_sky_sphere", &miss_pgm_sky_sphere) );
01264 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "miss_gradient_bg_sky_plane", &miss_pgm_sky_ortho_plane) );
01265 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "miss_solid_bg", &miss_pgm_solid) );
01266
01267
01268 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "exception", &exception_pgm) );
01269
01270 double time_cambgops = wkf_timer_timenow(ort_timer);
01271 if (verbose >= RT_VERB_TIMING) {
01272 printf("cambgops(%.1f) ", time_cambgops - time_fbops);
01273 fflush(stdout);
01274 }
01275
01276
01277 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "cylinder_array_bounds", &cylinder_array_bbox_pgm) );
01278 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "cylinder_array_intersect", &cylinder_array_isct_pgm) );
01279
01280
01281 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "cylinder_array_color_bounds", &cylinder_array_color_bbox_pgm) );
01282 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "cylinder_array_color_intersect", &cylinder_array_color_isct_pgm) );
01283
01284
01285 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "ring_array_color_bounds", &ring_array_color_bbox_pgm) );
01286 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "ring_array_color_intersect", &ring_array_color_isct_pgm) );
01287
01288
01289 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "sphere_array_bounds", &sphere_array_bbox_pgm) );
01290 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "sphere_array_intersect", &sphere_array_isct_pgm) );
01291
01292
01293 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "sphere_array_color_bounds", &sphere_array_color_bbox_pgm) );
01294 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "sphere_array_color_intersect", &sphere_array_color_isct_pgm) );
01295
01296
01297 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "tricolor_bounds", &tricolor_bbox_pgm) );
01298 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "tricolor_intersect", &tricolor_isct_pgm) );
01299
01300
01301 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "trimesh_c4u_n3b_v3f_bounds", &trimesh_c4u_n3b_v3f_bbox_pgm) );
01302 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "trimesh_c4u_n3b_v3f_intersect", &trimesh_c4u_n3b_v3f_isct_pgm) );
01303
01304
01305 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "trimesh_n3f_v3f_bounds", &trimesh_n3f_v3f_bbox_pgm) );
01306 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "trimesh_n3f_v3f_intersect", &trimesh_n3f_v3f_isct_pgm) );
01307
01308
01309 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "trimesh_n3b_v3f_bounds", &trimesh_n3b_v3f_bbox_pgm) );
01310 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "trimesh_n3b_v3f_intersect", &trimesh_n3b_v3f_isct_pgm) );
01311
01312
01313 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "trimesh_v3f_bounds", &trimesh_v3f_bbox_pgm) );
01314 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "trimesh_v3f_intersect", &trimesh_v3f_isct_pgm) );
01315
01316 double time_geompgms = wkf_timer_timenow(ort_timer);
01317 if (verbose >= RT_VERB_TIMING) {
01318 printf("geompgms(%.1f) ", time_geompgms - time_cambgops);
01319 fflush(stdout);
01320 }
01321
01322 if (verbose >= RT_VERB_TIMING) {
01323 printf("\n");
01324 }
01325
01326 time_ctx_create = wkf_timer_timenow(ort_timer) - starttime;
01327
01328 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
01329 printf("OptiXRenderer) context creation time: %.2f\n", time_ctx_create);
01330 }
01331
01332 context_created = 1;
01333 }
01334
01335
01336 void OptiXRenderer::setup_context(int w, int h) {
01337 double starttime = wkf_timer_timenow(ort_timer);
01338 time_ctx_setup = 0;
01339
01340 lasterror = RT_SUCCESS;
01341 width = w;
01342 height = h;
01343
01344 if (!context_created)
01345 return;
01346
01347 check_verbose_env();
01348
01349
01350
01351 scene_max_depth = 20;
01352 if (getenv("VMDOPTIXMAXDEPTH")) {
01353 int maxdepth = atoi(getenv("VMDOPTIXMAXDEPTH"));
01354 if (maxdepth > 0 && maxdepth <= 30) {
01355 printf("OptiXRenderer) Setting maxdepth to %d...\n", maxdepth);
01356 scene_max_depth = maxdepth;
01357 RTERR( rtVariableSet1ui(max_depth_v, scene_max_depth) );
01358 } else {
01359 printf("OptiXRenderer) ignoring out-of-range maxdepth to %d...\n", maxdepth);
01360 }
01361 }
01362
01363 scene_max_trans = scene_max_depth;
01364 if (getenv("VMDOPTIXMAXTRANS")) {
01365 int maxtrans = atoi(getenv("VMDOPTIXMAXTRANS"));
01366 if (maxtrans > 0 && maxtrans <= 30) {
01367 printf("OptiXRenderer) Setting maxtrans to %d...\n", maxtrans);
01368 scene_max_trans = maxtrans;
01369 RTERR( rtVariableSet1ui(max_trans_v, scene_max_trans) );
01370 } else {
01371 printf("OptiXRenderer) ignoring out-of-range maxtrans to %d...\n", maxtrans);
01372 }
01373 }
01374
01375
01376 RTERR( rtVariableSet1ui(max_depth_v, scene_max_depth) );
01377 RTERR( rtVariableSet1ui(max_trans_v, scene_max_trans) );
01378
01379
01380 RTERR( rtVariableSet1ui(radiance_ray_type_v, 0u) );
01381 RTERR( rtVariableSet1ui(shadow_ray_type_v, 1u) );
01382
01383
01384 float scene_epsilon = 5.e-5f;
01385 RTERR( rtVariableSet1f(scene_epsilon_v, scene_epsilon) );
01386
01387
01388
01389 RTERR( rtVariableSet1ui(accum_count_v, 0) );
01390
01391
01392 memset(material_special_counts, 0, sizeof(material_special_counts));
01393 time_ctx_setup = wkf_timer_timenow(ort_timer) - starttime;
01394 }
01395
01396
01397 void OptiXRenderer::report_context_stats() {
01398 if (!context_created)
01399 return;
01400
01401 unsigned int ctx_varcount=0;
01402 RTERR( rtContextGetVariableCount(ctx, &ctx_varcount) );
01403 printf("OptiXRenderer) ctx var cnt: %u\n", ctx_varcount);
01404 }
01405
01406
01407 void OptiXRenderer::destroy_scene() {
01408 double starttime = wkf_timer_timenow(ort_timer);
01409 time_ctx_destroy_scene = 0;
01410
01411
01412 cylinder_array_cnt = 0;
01413 cylinder_array_color_cnt = 0;
01414 ring_array_color_cnt = 0;
01415 sphere_array_cnt = 0;
01416 sphere_array_color_cnt = 0;
01417 tricolor_cnt = 0;
01418 trimesh_c4u_n3b_v3f_cnt = 0;
01419 trimesh_n3b_v3f_cnt = 0;
01420 trimesh_n3f_v3f_cnt = 0;
01421 trimesh_v3f_cnt = 0;
01422
01423 if (!context_created)
01424 return;
01425
01426 if (scene_created) {
01427 int i;
01428
01429 RTERR( rtAccelerationDestroy(acceleration) );
01430 #if defined(ORT_USERTXAPIS)
01431
01432 RTERR( rtAccelerationDestroy(trianglesacceleration) );
01433 #endif
01434
01435 RTERR( rtAccelerationDestroy(root_acceleration) );
01436 RTERR( rtGroupDestroy(root_group) );
01437
01438 RTERR( rtGeometryGroupDestroy(geometrygroup) );
01439 #if defined(ORT_USERTXAPIS)
01440
01441 RTERR( rtGeometryGroupDestroy(geometrytrianglesgroup) );
01442 #endif
01443
01444 int instcount = geominstancelist.num();
01445 for (i=0; i<instcount; i++) {
01446 RTERR( rtGeometryInstanceDestroy(geominstancelist[i]) );
01447 }
01448
01449 int geomcount = geomlist.num();
01450 for (i=0; i<geomcount; i++) {
01451 RTERR( rtGeometryDestroy(geomlist[i]) );
01452 }
01453
01454 geominstancelist.clear();
01455 geomlist.clear();
01456
01457 #if defined(ORT_USERTXAPIS)
01458
01459 #if (OPTIX_VERSION >= 60500)
01460
01461
01462
01463
01464
01465
01466
01467
01468 int insttrianglescount = geomtrianglesinstancelist.num();
01469 for (i=0; i<insttrianglescount; i++) {
01470 RTERR( rtGeometryInstanceDestroy(geomtrianglesinstancelist[i]) );
01471 }
01472 #endif
01473
01474 int geomtrianglescount = geomtriangleslist.num();
01475 for (i=0; i<geomtrianglescount; i++) {
01476 RTERR( rtGeometryTrianglesDestroy(geomtriangleslist[i]) );
01477 }
01478
01479 geomtrianglesinstancelist.clear();
01480 geomtriangleslist.clear();
01481 #endif
01482
01483 int bufcount = bufferlist.num();
01484 for (i=0; i<bufcount; i++) {
01485 RTERR( rtBufferDestroy(bufferlist[i]) );
01486 }
01487
01488 bufferlist.clear();
01489 }
01490
01491 materialcache.clear();
01492
01493 double endtime = wkf_timer_timenow(ort_timer);
01494 time_ctx_destroy_scene = endtime - starttime;
01495
01496 scene_created = 0;
01497 }
01498
01499
01500 int OptiXRenderer::set_accum_raygen_pgm(CameraProjection &proj,
01501 int stereo_on, int dof_on) {
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515 if (getenv("VMDOPTIXCUBEMAP") != NULL) {
01516 msgInfo << "Overriding VMD camera projection mode with VR cubemap" << sendmsg;
01517 proj = RT_CUBEMAP;
01518 }
01519
01520
01521 if (getenv("VMDOPTIXDOMEMASTER") != NULL) {
01522 msgInfo << "Overriding VMD camera projection mode with planetarium dome master" << sendmsg;
01523 proj = RT_DOME_MASTER;
01524 }
01525
01526
01527 if (getenv("VMDOPTIXEQUIRECTANGULAR") != NULL) {
01528 msgInfo << "Overriding VMD camera projection mode with spherical equirectangular projection" << sendmsg;
01529 proj = RT_EQUIRECTANGULAR;
01530 }
01531
01532
01533 if (getenv("VMDOPTIXOCULUSRIFT") != NULL) {
01534 msgInfo << "Overriding VMD camera projection mode with Oculus Rift projection" << sendmsg;
01535 proj = RT_OCULUS_RIFT;
01536 }
01537
01538
01539 if (getenv("VMDOPTIXSTEREO") != NULL) {
01540 msgInfo << "Overriding VMD camera, enabling stereo" << sendmsg;
01541 stereo_on = 1;
01542 }
01543
01544
01545 switch (proj) {
01546 default:
01547 msgErr << "OptiXRenderer) Illegal projection mode! Using perspective." << sendmsg;
01548
01549
01550 case RT_PERSPECTIVE:
01551 if (stereo_on) {
01552 if (dof_on) {
01553 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_perspective_stereo_dof) );
01554 } else {
01555 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_perspective_stereo) );
01556 }
01557 } else {
01558 if (dof_on) {
01559 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_perspective_dof) );
01560 } else {
01561 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_perspective) );
01562 }
01563 }
01564 break;
01565
01566 case RT_ORTHOGRAPHIC:
01567 if (stereo_on) {
01568 if (dof_on) {
01569 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_orthographic_stereo_dof) );
01570 } else {
01571 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_orthographic_stereo) );
01572 }
01573 } else {
01574 if (dof_on) {
01575 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_orthographic_dof) );
01576 } else {
01577 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_orthographic) );
01578 }
01579 }
01580 break;
01581
01582 case RT_CUBEMAP:
01583 if (stereo_on) {
01584 if (dof_on) {
01585 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_cubemap_stereo_dof) );
01586 } else {
01587 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_cubemap_stereo) );
01588 }
01589 } else {
01590 if (dof_on) {
01591 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_cubemap_dof) );
01592 } else {
01593 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_cubemap) );
01594 }
01595 }
01596 break;
01597
01598 case RT_DOME_MASTER:
01599 if (stereo_on) {
01600 if (dof_on) {
01601 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_dome_master_stereo_dof) );
01602 } else {
01603 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_dome_master_stereo) );
01604 }
01605 } else {
01606 if (dof_on) {
01607 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_dome_master_dof) );
01608 } else {
01609 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_dome_master) );
01610 }
01611 }
01612 break;
01613
01614 case RT_EQUIRECTANGULAR:
01615 if (stereo_on) {
01616 if (dof_on) {
01617 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_equirectangular_stereo_dof) );
01618 } else {
01619 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_equirectangular_stereo) );
01620 }
01621 } else {
01622 if (dof_on) {
01623 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_equirectangular_dof) );
01624 } else {
01625 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_equirectangular) );
01626 }
01627 }
01628 break;
01629
01630 case RT_OCULUS_RIFT:
01631 if (stereo_on) {
01632 if (dof_on) {
01633 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_oculus_rift_stereo_dof) );
01634 } else {
01635 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_oculus_rift_stereo) );
01636 }
01637 } else {
01638 if (dof_on) {
01639 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_oculus_rift_dof) );
01640 } else {
01641 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_ACCUMULATE, ray_gen_pgm_oculus_rift) );
01642 }
01643 }
01644 break;
01645 }
01646
01647 return 0;
01648 }
01649
01650
01651 void OptiXRenderer::update_rendering_state(int interactive) {
01652 if (!context_created)
01653 return;
01654
01655 #if defined(ORT_USERTXAPIS)
01656
01657
01658
01659
01660 if (getenv("VMDOPTIXNOHWTRIANGLES") != NULL) {
01661 hwtri_enabled = 0;
01662 }
01663 #endif
01664
01665
01666 if (getenv("VMDOPTIXSCENEEPSILON") != NULL) {
01667 float scene_epsilon = float(atof(getenv("VMDOPTIXSCENEEPSILON")));
01668 printf("OptiXRenderer) user override of scene epsilon: %g\n", scene_epsilon);
01669 RTERR( rtVariableSet1f(scene_epsilon_v, scene_epsilon) );
01670 }
01671
01672 int i;
01673 wkf_timer_start(ort_timer);
01674
01675
01676 RTERR( rtVariableSet1i(progressive_enabled_v, interactive) );
01677
01678 long totaltris = tricolor_cnt + trimesh_c4u_n3b_v3f_cnt +
01679 trimesh_n3b_v3f_cnt + trimesh_n3f_v3f_cnt + trimesh_v3f_cnt;
01680
01681 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
01682 printf("OptiXRenderer) cyl %ld, ring %ld, sph %ld, tri %ld, tot: %ld lt %ld\n",
01683 cylinder_array_cnt + cylinder_array_color_cnt,
01684 ring_array_color_cnt,
01685 sphere_array_cnt + sphere_array_color_cnt,
01686 totaltris,
01687 cylinder_array_cnt + cylinder_array_color_cnt + ring_array_color_cnt + sphere_array_cnt + sphere_array_color_cnt + totaltris,
01688 directional_lights.num() + positional_lights.num());
01689 }
01690
01691 if (verbose == RT_VERB_DEBUG) {
01692 #if defined(ORT_USE_TEMPLATE_SHADERS)
01693 if (getenv("VMDOPTIXFORCEGENERALSHADER") == NULL) {
01694 printf("OptiXRenderer) using template-specialized shaders and materials:\n");
01695 int i;
01696 for (i=0; i<ORTMTABSZ; i++) {
01697 if (material_special_counts[i] > 0) {
01698 printf("OptiXRenderer) material_special[%d] usage count: %d\n",
01699 i, material_special_counts[i]);
01700
01701 printf("OptiXRenderer) "
01702 "ClipView %s, "
01703 "Headlight %s, "
01704 "Fog %s, "
01705 "Shadows %s, "
01706 "AO %s, "
01707 "Outline %s, "
01708 "Refl %s, "
01709 "Trans %s\n",
01710 #if defined(VMDOPTIX_VCA_TABSZHACK)
01711 onoffstr(1),
01712 onoffstr(1),
01713 #else
01714 onoffstr(i & 128),
01715 onoffstr(i & 64),
01716 #endif
01717 onoffstr(i & 32),
01718 onoffstr(i & 16),
01719 onoffstr(i & 8),
01720 onoffstr(i & 4),
01721 onoffstr(i & 2),
01722 onoffstr(i & 1));
01723 }
01724 }
01725 printf("OptiXRenderer)\n");
01726 } else {
01727 printf("OptiXRenderer) using fully general shader and materials.\n");
01728 }
01729 #else
01730 printf("OptiXRenderer) using fully general shader and materials.\n");
01731 #endif
01732 }
01733
01734 RTERR( rtVariableSet3fv(scene_bg_color_v, scene_bg_color) );
01735 RTERR( rtVariableSet3fv(scene_bg_grad_top_v, scene_bg_grad_top) );
01736 RTERR( rtVariableSet3fv(scene_bg_grad_bot_v, scene_bg_grad_bot) );
01737 RTERR( rtVariableSet3fv(scene_gradient_v, scene_gradient) );
01738 RTERR( rtVariableSet1f(scene_gradient_topval_v, scene_gradient_topval) );
01739 RTERR( rtVariableSet1f(scene_gradient_botval_v, scene_gradient_botval) );
01740
01741 if (verbose == RT_VERB_DEBUG) {
01742 printf("OptiXRenderer) HMD/camera view clipping mode: %d start: %.2f end: %.2f\n",
01743 clipview_mode, clipview_start, clipview_end);
01744
01745 printf("OptiXRenderer) HMD/camera headlight mode: %d\n", headlight_mode);
01746
01747 printf("OptiXRenderer) scene bg mode: %d\n", scene_background_mode);
01748
01749 printf("OptiXRenderer) scene bgsolid: %.2f %.2f %.2f\n",
01750 scene_bg_color[0], scene_bg_color[1], scene_bg_color[2]);
01751
01752 printf("OptiXRenderer) scene bggradT: %.2f %.2f %.2f\n",
01753 scene_bg_grad_top[0], scene_bg_grad_top[1], scene_bg_grad_top[2]);
01754
01755 printf("OptiXRenderer) scene bggradB: %.2f %.2f %.2f\n",
01756 scene_bg_grad_bot[0], scene_bg_grad_bot[1], scene_bg_grad_bot[2]);
01757
01758 printf("OptiXRenderer) bg gradient: %f %f %f top: %f bot: %f\n",
01759 scene_gradient[0], scene_gradient[1], scene_gradient[2],
01760 scene_gradient_topval, scene_gradient_botval);
01761 }
01762
01763
01764 scene_gradient_invrange = 1.0f / (scene_gradient_topval - scene_gradient_botval);
01765 RTERR( rtVariableSet1f(scene_gradient_invrange_v, scene_gradient_invrange) );
01766
01767 RTERR( rtVariableSet1i(clipview_mode_v, clipview_mode) );
01768 RTERR( rtVariableSet1f(clipview_start_v, clipview_start) );
01769 RTERR( rtVariableSet1f(clipview_end_v, clipview_end) );
01770 RTERR( rtVariableSet1i(headlight_mode_v, (int) headlight_mode) );
01771
01772 RTERR( rtVariableSet1i(fog_mode_v, (int) fog_mode) );
01773 RTERR( rtVariableSet1f(fog_start_v, fog_start) );
01774 RTERR( rtVariableSet1f(fog_end_v, fog_end) );
01775 RTERR( rtVariableSet1f(fog_density_v, fog_density) );
01776
01777 if (verbose == RT_VERB_DEBUG) {
01778 printf("OptiXRenderer) adding lights: dir: %ld pos: %ld\n",
01779 directional_lights.num(), positional_lights.num());
01780 }
01781
01782 #if defined(VMDOPTIX_LIGHTUSEROBJS)
01783 DirectionalLightList dir_lights;
01784 memset(&dir_lights, 0, sizeof(DirectionalLightList));
01785 dir_lights.num_lights = directional_lights.num();
01786 int dlcount = directional_lights.num();
01787 dlcount = (dlcount > DISP_LIGHTS) ? DISP_LIGHTS : dlcount;
01788 for (i=0; i<dlcount; i++) {
01789 vec_copy((float*)(&dir_lights.dirs[i]), directional_lights[i].dir);
01790 vec_normalize((float*)&dir_lights.dirs[i]);
01791 }
01792 RTERR( rtVariableSetUserData(dir_light_list_v, sizeof(DirectionalLightList), &dir_lights) );
01793
01794 PositionalLightList pos_lights;
01795 memset(&pos_lights, 0, sizeof(PositionalLightList));
01796 pos_lights.num_lights = positional_lights.num();
01797 int plcount = positional_lights.num();
01798 plcount = (plcount > DISP_LIGHTS) ? DISP_LIGHTS : plcount;
01799 for (i=0; i<plcount; i++) {
01800 vec_copy((float*)(&pos_lights.posns[i]), positional_lights[i].pos);
01801 }
01802 RTERR( rtVariableSetUserData(pos_light_list_v, sizeof(PositionalLightList), &pos_lights) );
01803 #else
01804 DirectionalLight *dlbuf;
01805 RTERR( rtBufferSetSize1D(dir_lightbuffer, directional_lights.num()) );
01806 RTERR( rtBufferMap(dir_lightbuffer, (void **) &dlbuf) );
01807 for (i=0; i<directional_lights.num(); i++) {
01808 vec_copy((float*)&dlbuf[i].dir, directional_lights[i].dir);
01809 vec_normalize((float*)&dlbuf[i].dir);
01810 }
01811 RTERR( rtBufferUnmap(dir_lightbuffer) );
01812 RTERR( rtVariableSetObject(dir_lightbuffer_v, dir_lightbuffer) );
01813
01814 PositionalLight *plbuf;
01815 RTERR( rtBufferSetSize1D(pos_lightbuffer, positional_lights.num()) );
01816 RTERR( rtBufferMap(pos_lightbuffer, (void **) &plbuf) );
01817 for (i=0; i<positional_lights.num(); i++) {
01818 vec_copy((float*)&plbuf[i].pos, positional_lights[i].pos);
01819 }
01820 RTERR( rtBufferUnmap(pos_lightbuffer) );
01821 RTERR( rtVariableSetObject(pos_lightbuffer_v, pos_lightbuffer) );
01822 #endif
01823
01824 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) Finalizing OptiX scene graph...\n");
01825
01826
01827 int instcount = geominstancelist.num();
01828 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) instance objects: %d\n", instcount);
01829
01830 RTERR( rtGeometryGroupCreate(ctx, &geometrygroup) );
01831 RTERR( rtGeometryGroupSetChildCount(geometrygroup, instcount) );
01832 for (i=0; i<instcount; i++) {
01833 RTERR( rtGeometryGroupSetChild(geometrygroup, i, geominstancelist[i]) );
01834 }
01835
01836 #if defined(ORT_USERTXAPIS)
01837
01838
01839 int insttrianglescount = geomtrianglesinstancelist.num();
01840 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) triangle instance objects: %d\n", insttrianglescount);
01841
01842 RTERR( rtGeometryGroupCreate(ctx, &geometrytrianglesgroup) );
01843 RTERR( rtGeometryGroupSetChildCount(geometrytrianglesgroup, insttrianglescount) );
01844 for (i=0; i<insttrianglescount; i++) {
01845 RTERR( rtGeometryGroupSetChild(geometrytrianglesgroup, i, geomtrianglesinstancelist[i]) );
01846 }
01847 #endif
01848
01849
01850
01851
01852
01853
01854 RTERR( rtAccelerationCreate(ctx, &acceleration) );
01855
01856
01857
01858 const char *ort_builder = getenv("VMDOPTIXBUILDER");
01859 const char *ort_traverser = getenv("VMDOPTIXTRAVERSER");
01860 if (ort_builder && ort_traverser) {
01861 RTERR( rtAccelerationSetBuilder(acceleration, ort_builder) );
01862 RTERR( rtAccelerationSetTraverser(acceleration, ort_traverser) );
01863 if (verbose == RT_VERB_DEBUG) {
01864 printf("OptiXRenderer) user-override of AS: builder: '%s' traverser '%s'\n",
01865 ort_builder, ort_traverser);
01866 }
01867 } else if (ort_builder) {
01868 RTERR( rtAccelerationSetBuilder(acceleration, ort_builder) );
01869 RTERR( rtAccelerationSetTraverser(acceleration, "Bvh") );
01870 if (verbose == RT_VERB_DEBUG) {
01871 printf("OptiXRenderer) user-override of AS builder: '%s' (def traverser '%s')\n",
01872 ort_builder, "Bvh");
01873 }
01874 } else {
01875 #if (OPTIX_VERSION >= 3050) && (OPTIX_VERSION < 3060) || (OPTIX_VERSION == 3063) || (OPTIX_VERSION == 3080)
01876
01877
01878
01879 RTERR( rtAccelerationSetBuilder(acceleration, "Trbvh") );
01880 RTERR( rtAccelerationSetTraverser(acceleration, "Bvh") );
01881 #else
01882
01883
01884
01885
01886
01887
01888
01889 RTERR( rtAccelerationSetBuilder(acceleration, "MedianBvh") );
01890 RTERR( rtAccelerationSetTraverser(acceleration, "Bvh") );
01891 #endif
01892 }
01893
01894
01895
01896
01897 if (getenv("VMDOPTIXBUILDTYPE") != NULL) {
01898 const char *buildtypestr = getenv("VMDOPTIXBUILDTYPE");
01899 const char *curbuilderstr = NULL;
01900 RTERR( rtAccelerationGetBuilder(acceleration, &curbuilderstr) );
01901 if (!strcmp(curbuilderstr, "Trbvh")) {
01902 msgInfo << "OptiXRenderer) user-override of Trbvh AS build type: "
01903 << buildtypestr << sendmsg;
01904 RTERR( rtAccelerationSetProperty(acceleration, "build_type", buildtypestr) );
01905 } else {
01906 msgErr << "OptiXRenderer) Can't set build type for AS builders other than Trbvh" << sendmsg;
01907 }
01908 }
01909
01910
01911 RTERR( rtGeometryGroupSetAcceleration(geometrygroup, acceleration) );
01912 RTERR( rtAccelerationMarkDirty(acceleration) );
01913
01914 #if defined(ORT_USERTXAPIS)
01915
01916
01917 RTERR( rtAccelerationCreate(ctx, &trianglesacceleration) );
01918 RTERR( rtAccelerationSetBuilder(trianglesacceleration, "Trbvh") );
01919 RTERR( rtAccelerationSetTraverser(trianglesacceleration, "Bvh") );
01920 RTERR( rtGeometryGroupSetAcceleration(geometrytrianglesgroup, trianglesacceleration) );
01921 RTERR( rtAccelerationMarkDirty(trianglesacceleration) );
01922 #endif
01923
01924
01925
01926 RTERR( rtGroupCreate(ctx, &root_group) );
01927 #if defined(ORT_USERTXAPIS)
01928 RTERR( rtGroupSetChildCount(root_group, 2) );
01929 RTERR( rtGroupSetChild(root_group, 0, geometrygroup) );
01930 RTERR( rtGroupSetChild(root_group, 1, geometrytrianglesgroup) );
01931 #else
01932 RTERR( rtGroupSetChildCount(root_group, 1) );
01933 RTERR( rtGroupSetChild(root_group, 0, geometrygroup) );
01934 #endif
01935 RTERR( rtVariableSetObject(root_object_v, root_group) );
01936 RTERR( rtVariableSetObject(root_shadower_v, root_group) );
01937
01938
01939 RTERR( rtAccelerationCreate(ctx, &root_acceleration) );
01940 RTERR( rtAccelerationSetBuilder(root_acceleration,"NoAccel") );
01941 RTERR( rtAccelerationSetTraverser(root_acceleration,"NoAccel") );
01942 RTERR( rtGroupSetAcceleration(root_group, root_acceleration) );
01943 RTERR( rtAccelerationMarkDirty(root_acceleration) );
01944 scene_created=1;
01945
01946
01947
01948 if (verbose == RT_VERB_DEBUG) {
01949 printf("OptiXRenderer) cam zoom factor %f\n", cam_zoom);
01950 printf("OptiXRenderer) cam stereo eye separation %f\n", cam_stereo_eyesep);
01951 printf("OptiXRenderer) cam stereo convergence distance %f\n",
01952 cam_stereo_convergence_dist);
01953 printf("OptiXRenderer) cam DoF focal distance %f\n", cam_dof_focal_dist);
01954 printf("OptiXRenderer) cam DoF f/stop %f\n", cam_dof_fnumber);
01955 }
01956
01957
01958 RTERR( rtVariableSet1f(cam_zoom_v, cam_zoom) );
01959 RTERR( rtVariableSet3f( cam_pos_v, 0.0f, 0.0f, 2.0f) );
01960 RTERR( rtVariableSet3f( cam_U_v, 1.0f, 0.0f, 0.0f) );
01961 RTERR( rtVariableSet3f( cam_V_v, 0.0f, 1.0f, 0.0f) );
01962 RTERR( rtVariableSet3f( cam_W_v, 0.0f, 0.0f, -1.0f) );
01963
01964
01965 RTERR( rtVariableSet1f(cam_stereo_eyesep_v, cam_stereo_eyesep) );
01966 RTERR( rtVariableSet1f(cam_stereo_convergence_dist_v, cam_stereo_convergence_dist) );
01967
01968
01969 RTERR( rtVariableSet1f(cam_dof_focal_dist_v, cam_dof_focal_dist) );
01970 RTERR( rtVariableSet1f(cam_dof_aperture_rad_v, cam_dof_focal_dist / (2.0f * cam_zoom * cam_dof_fnumber)) );
01971
01972
01973
01974
01975
01976 RTERR( rtVariableSet1i(shadows_enabled_v,
01977 (shadows_enabled) ? RT_SHADOWS_ON : RT_SHADOWS_OFF) );
01978
01979 RTERR( rtVariableSet1i(ao_samples_v, ao_samples) );
01980 RTERR( rtVariableSet1f(ao_ambient_v, ao_ambient) );
01981 RTERR( rtVariableSet1f(ao_direct_v, ao_direct) );
01982 RTERR( rtVariableSet1f(ao_maxdist_v, ao_maxdist) );
01983 if (getenv("VMDOPTIXAOMAXDIST")) {
01984 float tmp = float(atof(getenv("VMDOPTIXAOMAXDIST")));
01985 if (verbose == RT_VERB_DEBUG) {
01986 printf("OptiXRenderer) setting AO maxdist: %f\n", tmp);
01987 }
01988 RTERR( rtVariableSet1f(ao_maxdist_v, tmp) );
01989 }
01990
01991 if (verbose == RT_VERB_DEBUG) {
01992 printf("OptiXRenderer) setting sample counts: AA %d AO %d\n", aa_samples, ao_samples);
01993 printf("OptiXRenderer) setting AO factors: AOA %f AOD %f\n", ao_ambient, ao_direct);
01994 }
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005 ext_aa_loops = 1;
02006 int totrays = (aa_samples + 1) * ((ao_samples > 0) ? ao_samples : 1);
02007 int maxrayspass = 16;
02008 if (getenv("VMDOPTIXMAXRAYSPERPASS") != NULL) {
02009 maxrayspass = atoi(getenv("VMDOPTIXMAXRAYSPERPASS"));
02010 printf("OptiXRenderer) User-override of max rays per pass: %d\n", maxrayspass);
02011 }
02012 if ((getenv("VMDOPTIXFORCEMULTIPASS") != NULL) || (totrays > maxrayspass)) {
02013
02014
02015 ext_aa_loops = 1 + aa_samples;
02016 RTERR( rtVariableSet1i(aa_samples_v, 1) );
02017 } else {
02018
02019
02020 RTERR( rtVariableSet1i(aa_samples_v, aa_samples + 1) );
02021 }
02022 RTERR( rtVariableSet1f(accum_norm_v, 1.0f / float(1 + aa_samples)) );
02023
02024 if (verbose == RT_VERB_DEBUG) {
02025 if (ext_aa_loops > 1)
02026 printf("OptiXRenderer) Running OptiX multi-pass: %d loops\n", ext_aa_loops);
02027 else
02028 printf("OptiXRenderer) Running OptiX single-pass: %d total samples\n", 1+aa_samples);
02029 }
02030
02031
02032 RTERR( rtContextSetEntryPointCount(ctx, RT_RAY_GEN_COUNT) );
02033 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_CLEAR_ACCUMULATION_BUFFER, clear_accumulation_buffer_pgm) );
02034 #if defined(ORT_RAYSTATS)
02035 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_CLEAR_RAYSTATS, clear_raystats_buffers_pgm) );
02036 #endif
02037
02038
02039
02040
02041 set_accum_raygen_pgm(camera_projection, 0, dof_enabled);
02042
02043
02044
02045
02046 #if defined(VMDOPTIX_PROGRESSIVEAPI)
02047 if (interactive) {
02048 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_COPY_FINISH, draw_accumulation_buffer_stub_pgm) );
02049 } else
02050 #endif
02051 {
02052 RTERR( rtContextSetRayGenerationProgram(ctx, RT_RAY_GEN_COPY_FINISH, draw_accumulation_buffer_pgm) );
02053 }
02054
02055
02056 switch (scene_background_mode) {
02057 case RT_BACKGROUND_TEXTURE_SKY_SPHERE:
02058 RTERR( rtContextSetMissProgram(ctx, RT_RAY_TYPE_RADIANCE, miss_pgm_sky_sphere) );
02059 break;
02060
02061 case RT_BACKGROUND_TEXTURE_SKY_ORTHO_PLANE:
02062 RTERR( rtContextSetMissProgram(ctx, RT_RAY_TYPE_RADIANCE, miss_pgm_sky_ortho_plane) );
02063 break;
02064
02065 case RT_BACKGROUND_TEXTURE_SOLID:
02066 default:
02067 RTERR( rtContextSetMissProgram(ctx, RT_RAY_TYPE_RADIANCE, miss_pgm_solid) );
02068 break;
02069 }
02070
02071
02072 unsigned int epcnt=0;
02073 RTERR( rtContextGetEntryPointCount(ctx, &epcnt) );
02074 unsigned int epidx;
02075 for (epidx=0; epidx<epcnt; epidx++) {
02076 RTERR( rtContextSetExceptionProgram(ctx, epidx, exception_pgm) );
02077 }
02078
02079
02080 if (getenv("VMDOPTIXDEBUG")) {
02081 printf("OptiXRenderer) Enabling all OptiX exceptions\n");
02082 RTERR( rtContextSetExceptionEnabled(ctx, RT_EXCEPTION_ALL, 1) );
02083 }
02084
02085
02086
02087
02088 int stacksizeadjusted=0;
02089
02090 #if (OPTIX_VERSION >= 60000)
02091
02092
02093
02094 if (rtx_enabled) {
02095
02096
02097
02098
02099
02100 int newmaxdepth = scene_max_depth + 1;
02101
02102
02103
02104
02105
02106 if (getenv("VMDOPTIXMAXSTACKSIZE")) {
02107 printf("OptiXRenderer) Setting RTX runtime to max depth / stack size\n");
02108
02109
02110 newmaxdepth = 31;
02111 }
02112
02113
02114
02115 if (newmaxdepth > 31)
02116 newmaxdepth = 31;
02117
02118 RTERR( rtContextSetMaxTraceDepth(ctx, newmaxdepth) );
02119 RTERR( rtContextSetMaxCallableProgramDepth(ctx, newmaxdepth) );
02120
02121 stacksizeadjusted = 1;
02122 }
02123 #endif
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133 if (!stacksizeadjusted) {
02134
02135 RTsize ssz;
02136 rtContextGetStackSize(ctx, &ssz);
02137 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) original stack size: %ld\n", ssz);
02138
02139
02140 long newstacksize = 7 * 1024;
02141
02142
02143
02144 if (getenv("VMDOPTIXSTACKSIZE")) {
02145 newstacksize = atoi(getenv("VMDOPTIXSTACKSIZE"));
02146 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) user stack size override: %ld\n", newstacksize);
02147 }
02148 rtContextSetStackSize(ctx, newstacksize);
02149 rtContextGetStackSize(ctx, &ssz);
02150 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) new stack size: %ld\n", ssz);
02151 }
02152
02153 #if !defined(VMDOPTIX_PROGRESSIVEAPI)
02154
02155 rtContextSetPrintEnabled(ctx, 1);
02156 rtContextSetPrintBufferSize(ctx, 1*1024*1024);
02157 #endif
02158
02159 #if defined(VMD_ENABLE_OPTIX_TIMEOUTS)
02160
02161
02162 double timeoutlimit = 0.5;
02163 const char *tmstr = getenv("VMDOPTIXTIMEOUTLIMIT");
02164 if (tmstr) {
02165 timeoutlimit = float(atof(tmstr));
02166 printf("Setting OptiX timeout: %f sec\n", timeoutlimit);
02167 }
02168
02169 if (verbose == RT_VERB_DEBUG)
02170 printf("Setting OptiX timeout: %f sec\n", timeoutlimit);
02171
02172 RTERR( rtContextSetTimeoutCallback(ctx, vmd_timeout_cb, timeoutlimit) );
02173 #endif
02174 }
02175
02176
02177 void OptiXRenderer::framebuffer_config(int fbwidth, int fbheight,
02178 int interactive) {
02179 if (!context_created)
02180 return;
02181
02182 width = fbwidth;
02183 height = fbheight;
02184
02185 #ifdef VMDOPTIX_PROGRESSIVEAPI
02186
02187
02188
02189
02190
02191 if (buffers_progressive != (interactive != 0)) {
02192 if (verbose == RT_VERB_DEBUG) {
02193 printf("OptiXRenderer) switching between progressive/non-progressive mode\n");
02194 printf("OptiXRenderer) remaking framebuffer\n");
02195 }
02196 framebuffer_destroy();
02197 }
02198 #endif
02199
02200
02201 if (buffers_allocated) {
02202
02203
02204 if (verbose == RT_VERB_DEBUG) {
02205 printf("OptiXRenderer) resizing framebuffer\n");
02206 }
02207 framebuffer_resize(width, height);
02208 } else {
02209
02210
02211
02212 if (verbose == RT_VERB_DEBUG) {
02213 printf("OptiXRenderer) creating framebuffer and accum. buffer\n");
02214 }
02215
02216
02217 RTERR( rtContextDeclareVariable(ctx, "accumulation_buffer", &accumulation_buffer_v) );
02218
02219 #ifdef VMDOPTIX_PROGRESSIVEAPI
02220 if (interactive) {
02221 RTERR( rtBufferCreate(ctx, RT_BUFFER_OUTPUT, &accumulation_buffer) );
02222 buffers_progressive = 1;
02223 } else
02224 #endif
02225 {
02226 RTERR( rtBufferCreate(ctx, RT_BUFFER_INPUT_OUTPUT | RT_BUFFER_GPU_LOCAL, &accumulation_buffer) );
02227 buffers_progressive = 0;
02228 }
02229
02230 RTERR( rtBufferSetFormat(accumulation_buffer, RT_FORMAT_FLOAT4) );
02231 RTERR( rtBufferSetSize2D(accumulation_buffer, width, height) );
02232 RTERR( rtVariableSetObject(accumulation_buffer_v, accumulation_buffer) );
02233
02234 #if defined(ORT_RAYSTATS)
02235
02236
02237 RTERR( rtContextDeclareVariable(ctx, "raystats1_buffer", &raystats1_buffer_v) );
02238 RTERR( rtBufferCreate(ctx, RT_BUFFER_OUTPUT, &raystats1_buffer) );
02239 RTERR( rtBufferSetFormat(raystats1_buffer, RT_FORMAT_UNSIGNED_INT4) );
02240 RTERR( rtBufferSetSize2D(raystats1_buffer, width, height) );
02241 RTERR( rtVariableSetObject(raystats1_buffer_v, raystats1_buffer) );
02242
02243 RTERR( rtContextDeclareVariable(ctx, "raystats2_buffer", &raystats2_buffer_v) );
02244 RTERR( rtBufferCreate(ctx, RT_BUFFER_OUTPUT, &raystats2_buffer) );
02245 RTERR( rtBufferSetFormat(raystats2_buffer, RT_FORMAT_UNSIGNED_INT4) );
02246 RTERR( rtBufferSetSize2D(raystats2_buffer, width, height) );
02247 RTERR( rtVariableSetObject(raystats2_buffer_v, raystats2_buffer) );
02248 #endif
02249
02250
02251 #ifdef VMDOPTIX_PROGRESSIVEAPI
02252 if (interactive) {
02253 RTERR( rtBufferCreate(ctx, RT_BUFFER_PROGRESSIVE_STREAM, &framebuffer) );
02254
02255
02256 int stream_bitrate = 5000000;
02257 if (getenv("VMDOPTIXBITRATE"))
02258 stream_bitrate = atoi(getenv("VMDOPTIXBITRATE"));
02259 RTERR( rtBufferSetAttribute(framebuffer, RT_BUFFER_ATTRIBUTE_STREAM_BITRATE, sizeof(int), &stream_bitrate) );
02260
02261
02262 int stream_fps = 30;
02263 if (getenv("VMDOPTIXFPS"))
02264 stream_fps = atoi(getenv("VMDOPTIXFPS"));
02265 RTERR( rtBufferSetAttribute(framebuffer, RT_BUFFER_ATTRIBUTE_STREAM_FPS, sizeof(int), &stream_fps) );
02266
02267
02268 float stream_gamma = 1.0f;
02269 if (getenv("VMDOPTIXGAMMS"))
02270 stream_gamma = atoi(getenv("VMDOPTIXGAMMA"));
02271 RTERR( rtBufferSetAttribute(framebuffer, RT_BUFFER_ATTRIBUTE_STREAM_GAMMA, sizeof(float), &stream_gamma) );
02272 } else
02273 #endif
02274 {
02275 RTERR( rtBufferCreate(ctx, RT_BUFFER_OUTPUT, &framebuffer) );
02276 }
02277
02278 RTERR( rtBufferSetFormat(framebuffer, RT_FORMAT_UNSIGNED_BYTE4) );
02279 RTERR( rtBufferSetSize2D(framebuffer, width, height) );
02280
02281 #ifdef VMDOPTIX_PROGRESSIVEAPI
02282 if (interactive) {
02283 RTERR( rtBufferBindProgressiveStream( framebuffer, accumulation_buffer) );
02284 } else
02285 #endif
02286 {
02287 RTERR( rtContextDeclareVariable(ctx, "framebuffer", &framebuffer_v) );
02288 RTERR( rtVariableSetObject(framebuffer_v, framebuffer) );
02289 }
02290
02291 buffers_allocated = 1;
02292 }
02293 }
02294
02295
02296 void OptiXRenderer::framebuffer_resize(int fbwidth, int fbheight) {
02297 if (!context_created)
02298 return;
02299
02300 width = fbwidth;
02301 height = fbheight;
02302
02303 if (buffers_allocated) {
02304 if (verbose == RT_VERB_DEBUG)
02305 printf("OptiXRenderer) framebuffer_resize(%d x %d)\n", width, height);
02306
02307 RTERR( rtBufferSetSize2D(framebuffer, width, height) );
02308 RTERR( rtBufferSetSize2D(accumulation_buffer, width, height) );
02309 #if defined(ORT_RAYSTATS)
02310 RTERR( rtBufferSetSize2D(raystats1_buffer, width, height) );
02311 RTERR( rtBufferSetSize2D(raystats2_buffer, width, height) );
02312 #endif
02313 }
02314 }
02315
02316
02317 void OptiXRenderer::framebuffer_map_rgb4u(unsigned char **imgrgb4u) {
02318 rtBufferMap(framebuffer, (void **) imgrgb4u);
02319 }
02320
02321
02322 void OptiXRenderer::framebuffer_unmap() {
02323 rtBufferUnmap(framebuffer);
02324 }
02325
02326
02327 void OptiXRenderer::framebuffer_destroy() {
02328 if (!context_created)
02329 return;
02330
02331 if (buffers_allocated) {
02332 #if defined(ORT_RAYSTATS)
02333 RTERR( rtContextRemoveVariable(ctx, raystats1_buffer_v) );
02334 RTERR( rtBufferDestroy(raystats1_buffer) );
02335 RTERR( rtContextRemoveVariable(ctx, raystats2_buffer_v) );
02336 RTERR( rtBufferDestroy(raystats2_buffer) );
02337 #endif
02338 RTERR( rtContextRemoveVariable(ctx, accumulation_buffer_v) );
02339 RTERR( rtBufferDestroy(accumulation_buffer) );
02340 #ifndef VMDOPTIX_PROGRESSIVEAPI
02341 RTERR( rtContextRemoveVariable(ctx, framebuffer_v) );
02342 #endif
02343 RTERR( rtBufferDestroy(framebuffer) );
02344 }
02345 buffers_allocated = 0;
02346 buffers_progressive = 0;
02347 }
02348
02349
02350 void OptiXRenderer::render_compile_and_validate(void) {
02351 if (!context_created)
02352 return;
02353
02354
02355
02356
02357 double startctxtime = wkf_timer_timenow(ort_timer);
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372 #define ORT_AS_BUILD_MEM_HEURISTIC 1
02373 #if defined(ORT_AS_BUILD_MEM_HEURISTIC)
02374 if (getenv("VMDOPTIXNOMEMHEURISTIC") == NULL) {
02375 const char *curbuilderstr = NULL;
02376 RTERR( rtAccelerationGetBuilder(acceleration, &curbuilderstr) );
02377 if (!strcmp(curbuilderstr, "Trbvh")) {
02378 long totaltris = tricolor_cnt + trimesh_c4u_n3b_v3f_cnt +
02379 trimesh_n3b_v3f_cnt + trimesh_n3f_v3f_cnt +
02380 trimesh_v3f_cnt;
02381
02382 long totalobjs = cylinder_array_cnt + cylinder_array_color_cnt +
02383 ring_array_color_cnt +
02384 sphere_array_cnt + sphere_array_color_cnt +
02385 totaltris;
02386
02387 long totaluserbufsz =
02388 cylinder_array_cnt * sizeof(vmd_cylinder) +
02389 cylinder_array_color_cnt * sizeof(vmd_cylinder_color) +
02390 ring_array_color_cnt * sizeof(vmd_ring_color) +
02391 sphere_array_cnt * sizeof(vmd_sphere) +
02392 sphere_array_color_cnt * sizeof(vmd_sphere_color) +
02393 tricolor_cnt * sizeof(vmd_tricolor) +
02394 trimesh_c4u_n3b_v3f_cnt * sizeof(vmd_trimesh_c4u_n3b_v3f) +
02395 trimesh_n3b_v3f_cnt * sizeof(vmd_trimesh_n3b_v3f) +
02396 trimesh_n3f_v3f_cnt * sizeof(vmd_trimesh_n3f_v3f) +
02397 trimesh_v3f_cnt * sizeof(vmd_trimesh_v3f);
02398
02399
02400
02401
02402 unsigned long mingpufreemem, mingpuphysmem;
02403 if (query_meminfo_ctx_devices(ctx, mingpufreemem, mingpuphysmem)) {
02404
02405
02406 mingpufreemem = 4L * 1024L * 1024L * 1024L;
02407 mingpuphysmem = 6L * 1024L * 1024L * 1024L;
02408 }
02409 unsigned long tenpctgpumem = mingpuphysmem / 10;
02410
02411
02412 unsigned long trbvhmemsz = totalobjs * 90L + tenpctgpumem;
02413 unsigned long totaltrbvhmemsz = trbvhmemsz + totaluserbufsz;
02414 unsigned long totaltrbvhmemszmb = totaltrbvhmemsz / (1024L * 1024L);
02415
02416 if (totaltrbvhmemsz > mingpufreemem) {
02417
02418 msgWarn << "OptiXRenderer) Predicted Trbvh AS peak GPU memory requirement exceeds capacity" << sendmsg;
02419 msgWarn << "OptiXRenderer) Min free GPU mem: " << (mingpufreemem / (1024L * 1024L)) << "MB" << sendmsg;
02420 msgWarn << "OptiXRenderer) Predicted Trbvh AS peak mem during build: " << totaltrbvhmemszmb << "MB" << sendmsg;
02421
02422 #if 1
02423
02424
02425
02426
02427 msgWarn << "OptiXRenderer) Switching to MedianBvh AS builder..." << sendmsg;
02428 RTERR( rtAccelerationSetBuilder(acceleration, "MedianBvh") );
02429 RTERR( rtAccelerationSetTraverser(acceleration, "Bvh") );
02430 #else
02431
02432 if (trbvhmemsz + totaluserbufsz > maxgpufreemem) {
02433 msgWarn << "OptiXRenderer) Switching to MedianBvh AS builder..." << sendmsg;
02434 RTERR( rtAccelerationSetBuilder(acceleration, "MedianBvh") );
02435 RTERR( rtAccelerationSetTraverser(acceleration, "Bvh") );
02436 } else {
02437 msgWarn << "OptiXRenderer) Switching to Trbvh CPU-based AS builder..." << sendmsg;
02438 RTERR( rtAccelerationSetBuilder(acceleration, "Trbvh") );
02439 RTERR( rtAccelerationSetProperty(acceleration, "build_type", "CPU") );
02440 RTERR( rtAccelerationSetTraverser(acceleration, "Bvh") );
02441 }
02442 #endif
02443
02444 }
02445 }
02446 }
02447 #endif
02448
02449 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) Finalizing OptiX rendering kernels...\n");
02450 RTERR( rtContextValidate(ctx) );
02451 if (lasterror != RT_SUCCESS) {
02452 printf("OptiXRenderer) An error occured validating the context. Rendering is aborted.\n");
02453 return;
02454 }
02455
02456 RTERR( rtContextCompile(ctx) );
02457 if (lasterror != RT_SUCCESS) {
02458 printf("OptiXRenderer) An error occured compiling the context. Rendering is aborted.\n");
02459 return;
02460 }
02461
02462 double contextinittime = wkf_timer_timenow(ort_timer);
02463 time_ctx_validate = contextinittime - startctxtime;
02464
02465
02466
02467
02468
02469
02470 #if defined(ORT_RETRY_FAILED_AS_BUILD)
02471 RTresult rc;
02472 rc = rtContextLaunch2D(ctx, RT_RAY_GEN_ACCUMULATE, 0, 0);
02473 RTERR( rc );
02474 #else
02475 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_ACCUMULATE, 0, 0) );
02476 #endif
02477
02478 #if defined(ORT_RETRY_FAILED_AS_BUILD)
02479
02480
02481 if (rc == RT_ERROR_MEMORY_ALLOCATION_FAILED) {
02482 const char *curbuilderstr = NULL;
02483 RTERR( rtAccelerationGetBuilder(acceleration, &curbuilderstr) );
02484 printf("Current OptiX builder str: '%s'\n", curbuilderstr);
02485 if (!strcmp(curbuilderstr, "Trbvh")) {
02486
02487 lasterror = RT_SUCCESS;
02488
02489
02490 printf("OptiXRenderer) Trbvh AS ran out of GPU memory, retrying with MedianBvh...\n");
02491 RTERR( rtAccelerationSetBuilder(acceleration, "MedianBvh") );
02492 RTERR( rtAccelerationSetTraverser(acceleration, "Bvh") );
02493
02494
02495
02496 render_compile_and_validate();
02497 }
02498 }
02499 #endif
02500
02501 time_ctx_AS_build = wkf_timer_timenow(ort_timer) - contextinittime;
02502 if (verbose == RT_VERB_DEBUG) {
02503 printf("OptiXRenderer) launching render: %d x %d\n", width, height);
02504 }
02505 }
02506
02507
02508 #if defined(VMDOPTIX_INTERACTIVE_OPENGL)
02509
02510 static void *createoptixwindow(const char *wintitle, int width, int height) {
02511 printf("OptiXRenderer) Creating OptiX window: %d x %d...\n", width, height);
02512
02513 void *win = glwin_create(wintitle, width, height);
02514 while (glwin_handle_events(win, GLWIN_EV_POLL_NONBLOCK) != 0);
02515
02516 glDrawBuffer(GL_BACK);
02517 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
02518 glClearColor(0.0, 0.0, 0.0, 1.0);
02519 glViewport(0, 0, width, height);
02520 glClear(GL_COLOR_BUFFER_BIT);
02521
02522 glShadeModel(GL_FLAT);
02523 glMatrixMode(GL_PROJECTION);
02524 glLoadIdentity();
02525 glOrtho(0.0, width, height, 0.0, -1.0, 1.0);
02526 glMatrixMode(GL_MODELVIEW);
02527 glLoadIdentity();
02528
02529 glDrawBuffer(GL_BACK);
02530 glClear(GL_COLOR_BUFFER_BIT);
02531
02532 glwin_swap_buffers(win);
02533
02534 return win;
02535 }
02536
02537
02538 static void interactive_viewer_usage(RTcontext ctx, void *win) {
02539 printf("OptiXRenderer) VMD TachyonL-OptiX Interactive Ray Tracer help:\n");
02540 printf("OptiXRenderer) ===============================================\n");
02541
02542 print_ctx_devices(ctx);
02543
02544
02545 int havespaceball = ((glwin_spaceball_available(win)) && (getenv("VMDDISABLESPACEBALLXDRV") == NULL));
02546 printf("OptiXRenderer) Spaceball/SpaceNavigator/Magellan: %s\n",
02547 (havespaceball) ? "Available" : "Not available");
02548
02549
02550 int havestereo, havestencil;
02551 glwin_get_wininfo(win, &havestereo, &havestencil);
02552 printf("OptiXRenderer) Stereoscopic display: %s\n",
02553 (havestereo) ? "Available" : "Not available");
02554
02555
02556 int vsync=0, rc=0;
02557 if ((rc = glwin_query_vsync(win, &vsync)) == GLWIN_SUCCESS) {
02558 printf("OptiXRenderer) Vert retrace sync: %s\n", (vsync) ? "On" : "Off");
02559 } else {
02560 printf("OptiXRenderer) Vert retrace sync: indeterminate\n");
02561 }
02562
02563 printf("OptiXRenderer)\n");
02564 printf("OptiXRenderer) General controls:\n");
02565 printf("OptiXRenderer) space: save numbered snapshot image\n");
02566 printf("OptiXRenderer) =: reset to initial view\n");
02567 printf("OptiXRenderer) h: print this help info\n");
02568 printf("OptiXRenderer) p: print current rendering parameters\n");
02569 printf("OptiXRenderer) ESC,q: quit viewer\n");
02570 printf("OptiXRenderer)\n");
02571 printf("OptiXRenderer) Display controls\n");
02572 printf("OptiXRenderer) F1: override shadows on/off (off=AO off too)\n");
02573 printf("OptiXRenderer) F2: override AO on/off\n");
02574 printf("OptiXRenderer) F3: override DoF on/off\n");
02575 printf("OptiXRenderer) F4: override Depth cueing on/off\n");
02576 #if defined(VMDOPTIX_USE_HMD)
02577 printf("OptiXRenderer) F5: override HMD/camera clipping plane/sphere\n");
02578 printf("OptiXRenderer) F6: override HMD/camera headlight\n");
02579 printf("OPtiXRenderer) F7: toggle HMD interleaved drawing\n");
02580 printf("OPtiXRenderer) F8: toggle HMD tex caching/update mode\n");
02581 printf("OPtiXRenderer) F9: switch HMD lens distortion mode\n");
02582 #endif
02583 #ifdef USE_REVERSE_SHADOW_RAYS
02584 printf("OptiXRenderer) F10: enable/disable shadow ray optimizations\n");
02585 #endif
02586 printf("OptiXRenderer) F12: toggle full-screen display on/off\n");
02587 printf("OptiXRenderer) 1-9,0: override samples per update auto-FPS off\n");
02588 printf("OptiXRenderer) Up: increase DoF focal distance\n");
02589 printf("OptiXRenderer) Down: decrease DoF focal distance\n");
02590 printf("OptiXRenderer) Left: decrease DoF f/stop\n");
02591 printf("OptiXRenderer) Right: increase DoF f/stop\n");
02592 printf("OptiXRenderer) S: toggle stereoscopic display on/off (if avail)\n");
02593 printf("OptiXRenderer) a: toggle AA/AO auto-FPS tuning on/off (on)\n");
02594 printf("OptiXRenderer) g: toggle gradient sky xforms on/off (on)\n");
02595 printf("OptiXRenderer) l: toggle light xforms on/off (on)\n");
02596 printf("OptiXRenderer)\n");
02597 printf("OptiXRenderer) Mouse controls:\n");
02598 printf("OptiXRenderer) f: mouse depth-of-field mode\n");
02599 printf("OptiXRenderer) r: mouse rotation mode\n");
02600 printf("OptiXRenderer) s: mouse scaling mode\n");
02601 printf("OptiXRenderer) t: mouse translation mode\n");
02602
02603 int movie_recording_enabled = (getenv("VMDOPTIXLIVEMOVIECAPTURE") != NULL);
02604 if (movie_recording_enabled) {
02605 printf("OptiXRenderer)\n");
02606 printf("OptiXRenderer) Movie recording controls:\n");
02607 printf("OptiXRenderer) R: start/stop movie recording\n");
02608 printf("OptiXRenderer) F: toggle movie FPS (24, 30, 60)\n");
02609 }
02610 }
02611
02612
02613
02614 void OptiXRenderer::render_to_glwin(const char *filename, int writealpha) {
02615 int i;
02616
02617 if (!context_created)
02618 return;
02619
02620 enum RtMouseMode { RTMM_ROT=0, RTMM_TRANS=1, RTMM_SCALE=2, RTMM_DOF=3 };
02621 enum RtMouseDown { RTMD_NONE=0, RTMD_LEFT=1, RTMD_MIDDLE=2, RTMD_RIGHT=3 };
02622 RtMouseMode mm = RTMM_ROT;
02623 RtMouseDown mousedown = RTMD_NONE;
02624
02625
02626
02627 int hmd_freerun = 0;
02628 #if defined(VMDOPTIX_USE_HMD)
02629 void *hmd_warp = NULL;
02630 #endif
02631 int hmd_warp_drawmode=1;
02632
02633
02634 int hmd_warp_coeff_update=0;
02635 int hmd_warp_coeff_edit=1;
02636 int hmd_warp_coeff_set=0;
02637 const float dk2_warp_coeff[5] = { 1.000f, 0.000f, 0.600f, 0.000f, 0.000f };
02638
02639 const float msr_warp_coeff[5] = { 0.950f, 0.330f, 0.195f, 0.045f, 0.360f };
02640 float user_warp_coeff[5] = { 1.000f, 0.000f, 0.600f, 0.000f, 0.000f };
02641 float hmd_warp_coeff[5] = { 1.000f, 0.000f, 0.600f, 0.000f, 0.000f };
02642
02643
02644 if (getenv("VMDOPTIXHMDUSERWARPCOEFFS")) {
02645 printf("OptiXRenderer) user-override of default user-defined HMD warp coefficients\n");
02646 memset(user_warp_coeff, 0, sizeof(user_warp_coeff));
02647 int cnt=sscanf(getenv("VMDOPTIXHMDUSERWARPCOEFFS"), "%f %f %f %f %f",
02648 &user_warp_coeff[0], &user_warp_coeff[1],
02649 &user_warp_coeff[2], &user_warp_coeff[3],
02650 &user_warp_coeff[4]);
02651 if (cnt != 5) {
02652 printf("OptiXRenderer) Warning: only parsed %d coefficients!\n", cnt);
02653 } else {
02654 printf("OptiXRenderer) user-defined warp coefficients: %d\n", cnt);
02655 printf("OptiXRenderer) %.3f %.3f %.3f %.3f %.3f\n",
02656 user_warp_coeff[0], user_warp_coeff[1],
02657 user_warp_coeff[2], user_warp_coeff[3], user_warp_coeff[4]);
02658 }
02659 }
02660
02661
02662
02663
02664 int hmd_interleave_draws = 0;
02665 if (getenv("VMDOPTIXHMDINTERLEAVEDRAWS")) {
02666 hmd_interleave_draws = 1;
02667 printf("OptiXRenderer) HMD GL draw call interleaving enabled\n");
02668 }
02669
02670 int hmd_tex_caching = 0;
02671 if (getenv("VMDOPTIXHMDTEXCACHING")) {
02672 hmd_tex_caching = 1;
02673 printf("OptiXRenderer) HMD texture caching enabled\n");
02674 }
02675
02676
02677 int hmd_no_draw = 0;
02678 if (getenv("VMDOPTIXHMDNODRAW")) {
02679 hmd_no_draw = 1;
02680 printf("OptiXRenderer) HMD GL draw calls disabled\n");
02681 }
02682
02683
02684 float hmd_fov = 95;
02685 if (getenv("VMDOPTIXHMDFOV")) {
02686 hmd_fov = float(atof(getenv("VMDOPTIXHMDFOV")));
02687 printf("OptiXRenderer) User-override of HMD FoV: %.2f\n", hmd_fov);
02688 }
02689
02690
02691 int hmd_spres = 72;
02692 if (getenv("VMDOPTIXHMDSPRES")) {
02693 hmd_spres = atoi(getenv("VMDOPTIXHMDSPRES"));
02694 printf("OptiXRenderer) User-override of HMD sph res: %d\n", hmd_spres);
02695 }
02696
02697
02698 #if defined(USE_REVERSE_SHADOW_RAYS) && defined(USE_REVERSE_SHADOW_RAYS_DEFAULT)
02699 int gl_shadows_on=(shadows_enabled) ? RT_SHADOWS_ON_REVERSE : RT_SHADOWS_OFF;
02700 #else
02701 int gl_shadows_on=(shadows_enabled) ? RT_SHADOWS_ON : RT_SHADOWS_OFF;
02702 #endif
02703
02704 int gl_fs_on=0;
02705 int fsowsx=0, fsowsy=0;
02706 int owsx=0, owsy=0;
02707 int gl_ao_on=(ao_samples > 0);
02708 int gl_dof_on, gl_dof_on_old;
02709 gl_dof_on=gl_dof_on_old=dof_enabled;
02710 int gl_fog_on=(fog_mode != RT_FOG_NONE);
02711 int gl_clip_on=(clipview_mode != RT_CLIP_NONE);
02712 int gl_headlight_on=(headlight_mode != RT_HEADLIGHT_OFF);
02713
02714
02715
02716
02717
02718
02719
02720 int movie_recording_enabled = (getenv("VMDOPTIXLIVEMOVIECAPTURE") != NULL);
02721 int movie_recording_on = 0;
02722 double movie_recording_start_time = 0.0;
02723 int movie_recording_fps = 30;
02724 int movie_framecount = 0;
02725 int movie_lastframeindex = 0;
02726 const char *movie_recording_filebase = "vmdlivemovie.%05d.tga";
02727 if (getenv("VMDOPTIXLIVEMOVIECAPTUREFILEBASE"))
02728 movie_recording_filebase = getenv("VMDOPTIXLIVEMOVIECAPTUREFILEBASE");
02729
02730
02731 int spaceballenabled=(getenv("VMDDISABLESPACEBALLXDRV") == NULL) ? 1 : 0;
02732 int spaceballmode=0;
02733 int spaceballflightmode=0;
02734 if (getenv("VMDOPTIXSPACEBALLFLIGHT"))
02735 spaceballflightmode=1;
02736
02737
02738 int totalsamplecount=0;
02739
02740
02741 int snapshotcount=0;
02742
02743
02744 #if defined(VMDOPTIX_PROGRESSIVEAPI)
02745 #if 1
02746 int autosamplecount=0;
02747 #else
02748 int autosamplecount=1;
02749 #endif
02750 #else
02751 int autosamplecount=1;
02752 #endif
02753
02754
02755
02756 int xformlights=1, xformgradientsphere=1;
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768 int wsx=width, wsy=height;
02769 const char *imageszstr = getenv("VMDOPTIXIMAGESIZE");
02770 if (imageszstr) {
02771 if (sscanf(imageszstr, "%d %d", &width, &height) != 2) {
02772 width=wsx;
02773 height=wsy;
02774 }
02775 }
02776
02777 framebuffer_config(width, height, 1);
02778
02779
02780
02781 update_rendering_state(1);
02782 render_compile_and_validate();
02783
02784
02785
02786 int samples_per_pass = 1;
02787 int force_ao_1 = 0;
02788 int cur_aa_samples = aa_samples;
02789 int cur_ao_samples = ao_samples;
02790 float cam_zoom_orig = cam_zoom;
02791 float scene_gradient_orig[3] = {0.0f, 1.0f, 0.0f};
02792 vec_copy(scene_gradient_orig, scene_gradient);
02793
02794 float cam_pos_orig[3] = {0.0f, 0.0f, 2.0f};
02795 float cam_U_orig[3] = {1.0f, 0.0f, 0.0f};
02796 float cam_V_orig[3] = {0.0f, 1.0f, 0.0f};
02797 float cam_W_orig[3] = {0.0f, 0.0f, -1.0f};
02798 float cam_pos[3], cam_U[3], cam_V[3], cam_W[3];
02799 float hmd_U[3], hmd_V[3], hmd_W[3];
02800
02801 vec_copy(cam_pos, cam_pos_orig);
02802 vec_copy(cam_U, cam_U_orig);
02803 vec_copy(cam_V, cam_V_orig);
02804 vec_copy(cam_W, cam_W_orig);
02805
02806
02807 DirectionalLight *cur_dlights = (DirectionalLight *) calloc(1, directional_lights.num() * sizeof(DirectionalLight));
02808 for (i=0; i<directional_lights.num(); i++) {
02809 vec_copy((float*)&cur_dlights[i].dir, directional_lights[i].dir);
02810 vec_normalize((float*)&cur_dlights[i].dir);
02811 }
02812
02813 #if defined(VMDOPTIX_USE_HMD)
02814 HMDMgr *hmd = NULL;
02815
02816 if (getenv("VMDOPTIXUSEHMD") != NULL) {
02817 hmd = new HMDMgr();
02818 if (hmd->device_count() < 1) {
02819 delete hmd;
02820 hmd = NULL;
02821 }
02822 }
02823 if (hmd) {
02824 autosamplecount=0;
02825 msgInfo << "OptiXRenderer) HMD in use, disabling auto sample count adjustement," << sendmsg;
02826 msgInfo << "OptiXRenderer) optimizing for lowest rendering latency." << sendmsg;
02827 }
02828
02829 #if defined(VMDOPTIX_PROGRESSIVEAPI)
02830 hmd_freerun = (hmd != NULL && camera_projection == RT_EQUIRECTANGULAR);
02831 #endif
02832
02833 #if defined(VMDUSEEVENTIO)
02834 evio_handle eviodev = NULL;
02835 const char *eviodevname = getenv("VMDOPTIXEVIODEV");
02836 if (hmd && eviodevname) {
02837 msgInfo << "OptiXRenderer) Attempting to open '"
02838 << eviodevname << "' for Linux event I/O input..." << sendmsg;
02839 eviodev = evio_open(eviodevname);
02840 if (eviodev) {
02841 msgInfo << "OptiXRenderer) Using Linux event I/O input:" << sendmsg;
02842 evio_print_devinfo(eviodev);
02843 }
02844 }
02845 #endif
02846 #endif
02847
02848
02849 const char *windowtitle;
02850 #if 1
02851 windowtitle = "VMD TachyonL-OptiX Interactive Ray Tracer";
02852 #else
02853
02854 if (getenv("VMDOPTIXNORTX") != NULL || rtx_enabled==0) {
02855 windowtitle = "VMD TachyonL-OptiX Interactive Ray Tracer -- Turing RTX DISABLED";
02856 } else {
02857 windowtitle = "VMD TachyonL-OptiX Interactive Ray Tracer -- Turing RTX ENABLED";
02858 }
02859 #endif
02860
02861 void *win = createoptixwindow(windowtitle, width, height);
02862 interactive_viewer_usage(ctx, win);
02863
02864
02865 int havestereo=0, havestencil=0;
02866 int stereoon=0, stereoon_old=0;
02867 glwin_get_wininfo(win, &havestereo, &havestencil);
02868
02869 #if defined(VMDOPTIX_USE_HMD) && defined(VMDOPTIX_PROGRESSIVEAPI)
02870 if (hmd_freerun && hmd != NULL && camera_projection == RT_EQUIRECTANGULAR) {
02871 glwin_spheremap_draw_prepare(win);
02872
02873
02874 if (hmd != NULL && !getenv("VMDOPTIXHMDNOWARP"))
02875 hmd_warp = glwin_spheremap_create_hmd_warp(win, wsx, wsy, 21, 0,
02876 width, height, hmd_warp_coeff);
02877
02878
02879 if (hmd) {
02880 if (glwin_fullscreen(win, 1, 0) == 0) {
02881 gl_fs_on = 1;
02882 fsowsx = wsx;
02883 fsowsy = wsy;
02884 glwin_get_winsize(win, &wsx, &wsy);
02885 } else {
02886 printf("OptiXRenderer) Fullscreen mode not available\n");
02887 }
02888 }
02889 }
02890 #endif
02891
02892
02893
02894
02895
02896
02897
02898 cur_aa_samples = samples_per_pass;
02899 if (cur_ao_samples > 0) {
02900 cur_aa_samples = 1;
02901 cur_ao_samples = samples_per_pass;
02902 }
02903
02904 const char *statestr = "|/-\\.";
02905 int done=0, winredraw=1;
02906 int state=0, mousedownx=0, mousedowny=0;
02907 float cur_cam_zoom = cam_zoom_orig;
02908
02909 double fpsexpave=0.0;
02910 double hmdfpsexpave=0.0;
02911 double hmdgldrawtime=0.0;
02912 double mapbuftotaltime=0.0;
02913 double accumbufstarttime=wkf_timer_timenow(ort_timer);
02914 double oldtime = wkf_timer_timenow(ort_timer);
02915 #if defined(VMDOPTIX_USE_HMD)
02916 double hmdoldtime = oldtime;
02917 #endif
02918 while (!done) {
02919 int winevent=0;
02920
02921 #if 1
02922 if (app->uivs && app->uivs->srv_connected()) {
02923 if (app->uivs->srv_check_ui_event()) {
02924 int eventtype;
02925 app->uivs->srv_get_last_event_type(eventtype);
02926 switch (eventtype) {
02927 case VideoStream::VS_EV_ROTATE_BY:
02928 { int axis;
02929 float angle;
02930 app->uivs->srv_get_last_rotate_by(angle, axis);
02931 Matrix4 rm;
02932
02933 switch (axis) {
02934 case 'x':
02935 rm.rotate_axis(cam_U, -angle * VMD_PI/180.0f);
02936 break;
02937
02938 case 'y':
02939 rm.rotate_axis(cam_V, -angle * VMD_PI/180.0f);
02940 break;
02941
02942 case 'z':
02943 rm.rotate_axis(cam_W, -angle * VMD_PI/180.0f);
02944 break;
02945 }
02946 rm.multpoint3d(cam_pos, cam_pos);
02947 rm.multnorm3d(cam_U, cam_U);
02948 rm.multnorm3d(cam_V, cam_V);
02949 rm.multnorm3d(cam_W, cam_W);
02950
02951 if (xformgradientsphere) {
02952 rm.multnorm3d(scene_gradient, scene_gradient);
02953 }
02954
02955 if (xformlights) {
02956
02957 for (i=0; i<directional_lights.num(); i++) {
02958 rm.multnorm3d((float*)&cur_dlights[i].dir, (float*)&cur_dlights[i].dir);
02959 }
02960 }
02961 winredraw = 1;
02962 }
02963 break;
02964
02965 case VideoStream::VS_EV_TRANSLATE_BY:
02966 {
02967 float dU[3], dV[3], dW[3];
02968 float tx, ty, tz;
02969 app->uivs->srv_get_last_translate_by(tx, ty, tz);
02970 vec_scale(dU, -tx, cam_U);
02971 vec_scale(dV, -ty, cam_V);
02972 vec_scale(dW, -tz, cam_W);
02973 vec_add(cam_pos, cam_pos, dU);
02974 vec_add(cam_pos, cam_pos, dV);
02975 vec_add(cam_pos, cam_pos, dW);
02976 winredraw = 1;
02977 }
02978 break;
02979
02980 case VideoStream::VS_EV_SCALE_BY:
02981 { float zoominc;
02982 app->uivs->srv_get_last_scale_by(zoominc);
02983 cam_zoom *= 1.0f / zoominc;
02984 winredraw = 1;
02985 }
02986 break;
02987
02988 #if 0
02989 } else if (mm == RTMM_DOF) {
02990 cam_dof_fnumber += txdx * 20.0f;
02991 if (cam_dof_fnumber < 1.0f) cam_dof_fnumber = 1.0f;
02992 cam_dof_focal_dist += -txdy;
02993 if (cam_dof_focal_dist < 0.01f) cam_dof_focal_dist = 0.01f;
02994 winredraw = 1;
02995 }
02996 }
02997 #endif
02998
02999 case VideoStream::VS_EV_NONE:
03000 default:
03001
03002 break;
03003 }
03004 }
03005 }
03006 #endif
03007
03008
03009 while ((winevent = glwin_handle_events(win, GLWIN_EV_POLL_NONBLOCK)) != 0) {
03010 int evdev, evval;
03011 char evkey;
03012
03013 glwin_get_lastevent(win, &evdev, &evval, &evkey);
03014 glwin_get_winsize(win, &wsx, &wsy);
03015
03016 if (evdev == GLWIN_EV_WINDOW_CLOSE) {
03017 printf("OptiXRenderer) display window closed, exiting...\n");
03018 done = 1;
03019 winredraw = 0;
03020 } else if (evdev == GLWIN_EV_KBD) {
03021 switch (evkey) {
03022 case '`': autosamplecount=0; samples_per_pass=1;
03023 force_ao_1 = (!force_ao_1); winredraw=1;
03024 printf("OptiXRenderer) Toggling forced single AO sample per pass: %s\n",
03025 force_ao_1 ? "on" : "off");
03026 break;
03027
03028
03029 case '|': hmd_warp_coeff_set = (hmd_warp_coeff_set + 1) % 3;
03030 switch (hmd_warp_coeff_set) {
03031 case 0:
03032 printf("\nDistortion correction: DK2 stock lens\n");
03033 memcpy(hmd_warp_coeff, dk2_warp_coeff, 5*sizeof(float));
03034 break;
03035
03036 case 1:
03037 printf("\nDistortion correction: DK2 w/ MSR lens\n");
03038 memcpy(hmd_warp_coeff, msr_warp_coeff, 5*sizeof(float));
03039 break;
03040
03041 case 2:
03042 printf("\nDistortion correction: User defined lens\n");
03043 memcpy(hmd_warp_coeff, user_warp_coeff, 5*sizeof(float));
03044 break;
03045 }
03046 printf("\nHMD warp coeff: %.3f, %.3f, %.3f, %.3f, %.3f\n",
03047 hmd_warp_coeff[0], hmd_warp_coeff[1],
03048 hmd_warp_coeff[2], hmd_warp_coeff[3],
03049 hmd_warp_coeff[4]);
03050 hmd_warp_coeff_update=1; winredraw=1; break;
03051 break;
03052
03053 case '\\': hmd_warp_coeff_edit = (hmd_warp_coeff_edit + 1) % 5;
03054 printf("\nHMD edit warp coeff: r^%d\n",hmd_warp_coeff_edit);
03055 break;
03056
03057 case '[': hmd_warp_coeff[hmd_warp_coeff_edit]-=0.005;
03058 printf("\nHMD warp coeff: %.3f, %.3f, %.3f, %.3f, %.3f\n",
03059 hmd_warp_coeff[0], hmd_warp_coeff[1],
03060 hmd_warp_coeff[2], hmd_warp_coeff[3],
03061 hmd_warp_coeff[4]);
03062 memcpy(user_warp_coeff, hmd_warp_coeff, 5*sizeof(float));
03063 hmd_warp_coeff_update=1; winredraw=1; break;
03064
03065 case ']': hmd_warp_coeff[hmd_warp_coeff_edit]+=0.005;
03066 printf("\nHMD warp coeff: %.3f, %.3f, %.3f, %.3f, %.3f\n",
03067 hmd_warp_coeff[0], hmd_warp_coeff[1],
03068 hmd_warp_coeff[2], hmd_warp_coeff[3],
03069 hmd_warp_coeff[4]);
03070 memcpy(user_warp_coeff, hmd_warp_coeff, 5*sizeof(float));
03071 hmd_warp_coeff_update=1; winredraw=1; break;
03072
03073
03074 case '1': autosamplecount=0; samples_per_pass=1; winredraw=1; break;
03075 case '2': autosamplecount=0; samples_per_pass=2; winredraw=1; break;
03076 case '3': autosamplecount=0; samples_per_pass=3; winredraw=1; break;
03077 case '4': autosamplecount=0; samples_per_pass=4; winredraw=1; break;
03078 case '5': autosamplecount=0; samples_per_pass=5; winredraw=1; break;
03079 case '6': autosamplecount=0; samples_per_pass=6; winredraw=1; break;
03080 case '7': autosamplecount=0; samples_per_pass=7; winredraw=1; break;
03081 case '8': autosamplecount=0; samples_per_pass=8; winredraw=1; break;
03082 case '9': autosamplecount=0; samples_per_pass=9; winredraw=1; break;
03083 case '0': autosamplecount=0; samples_per_pass=10; winredraw=1; break;
03084
03085 case '=':
03086 vec_copy(scene_gradient, scene_gradient_orig);
03087 cam_zoom = cam_zoom_orig;
03088 vec_copy(cam_pos, cam_pos_orig);
03089 vec_copy(cam_U, cam_U_orig);
03090 vec_copy(cam_V, cam_V_orig);
03091 vec_copy(cam_W, cam_W_orig);
03092
03093
03094 for (i=0; i<directional_lights.num(); i++) {
03095 vec_copy((float*)&cur_dlights[i].dir, directional_lights[i].dir);
03096 vec_normalize((float*)&cur_dlights[i].dir);
03097 }
03098 winredraw = 1;
03099 #if defined(VMDOPTIX_USE_HMD)
03100
03101 if (hmd) {
03102 hmd->reset_orientation();
03103 printf("\nOptiXRenderer) Resetting HMD orientation\n");
03104 }
03105 #endif
03106 break;
03107
03108 case ' ':
03109 {
03110 char snapfilename[256];
03111 sprintf(snapfilename, "vmdsnapshot.%04d.tga", snapshotcount);
03112 if (OptiXWriteImage(snapfilename, writealpha, framebuffer) != -1) {
03113 printf("OptiXRenderer) Saved snapshot to '%s' \n",
03114 snapfilename);
03115 }
03116 snapshotcount++;
03117 }
03118 break;
03119
03120 case 'a':
03121 autosamplecount = !(autosamplecount);
03122 printf("\nOptiXRenderer) Automatic AO sample count FPS tuning %s\n",
03123 (autosamplecount) ? "enabled" : "disabled");
03124 break;
03125
03126 case 'f':
03127 mm = RTMM_DOF;
03128 printf("\nOptiXRenderer) Mouse DoF aperture and focal dist. mode\n");
03129 break;
03130
03131 case 'g':
03132 xformgradientsphere = !(xformgradientsphere);
03133 printf("\nOptiXRenderer) Gradient sky sphere transformations %s\n",
03134 (xformgradientsphere) ? "enabled" : "disabled");
03135 break;
03136
03137 case 'h':
03138 printf("\n");
03139 interactive_viewer_usage(ctx, win);
03140
03141
03142
03143
03144 winredraw = 1;
03145 break;
03146
03147 case 'l':
03148 xformlights = !(xformlights);
03149 printf("\nOptiXRenderer) Light transformations %s\n",
03150 (xformlights) ? "enabled" : "disabled");
03151 break;
03152
03153 case 'p':
03154 printf("\nOptiXRenderer) Current Ray Tracing Parameters:\n");
03155 printf("OptiXRenderer) -------------------------------\n");
03156 printf("OptiXRenderer) Camera zoom: %f\n", cur_cam_zoom);
03157 printf("OptiXRenderer) Shadows: %s Ambient occlusion: %s\n",
03158 (gl_shadows_on) ? "on" : "off",
03159 (gl_ao_on) ? "on" : "off");
03160 printf("OptiXRenderer) Antialiasing samples per-pass: %d\n",
03161 cur_aa_samples);
03162 printf("OptiXRenderer) Ambient occlusion samples per-pass: %d\n",
03163 cur_ao_samples);
03164 printf("OptiXRenderer) Depth-of-Field: %s f/num: %.1f Foc. Dist: %.2f\n",
03165 (gl_dof_on) ? "on" : "off",
03166 cam_dof_fnumber, cam_dof_focal_dist);
03167 printf("OptiXRenderer) Win size: %d x %d\n", wsx, wsy);
03168 printf("OptiXRenderer) Image size: %d x %d\n", width, height);
03169 break;
03170
03171 case 'r':
03172 mm = RTMM_ROT;
03173 printf("\nOptiXRenderer) Mouse rotation mode\n");
03174 break;
03175
03176 case 's':
03177 mm = RTMM_SCALE;
03178 printf("\nOptiXRenderer) Mouse scaling mode\n");
03179 break;
03180
03181 case 'F':
03182 if (movie_recording_enabled) {
03183 switch (movie_recording_fps) {
03184 case 24: movie_recording_fps = 30; break;
03185 case 30: movie_recording_fps = 60; break;
03186 case 60:
03187 default: movie_recording_fps = 24; break;
03188 }
03189 printf("\nOptiXRenderer) Movie recording FPS rate: %d\n",
03190 movie_recording_fps);
03191 } else {
03192 printf("\nOptiXRenderer) Movie recording not available.\n");
03193 }
03194 break;
03195
03196 case 'R':
03197 if (movie_recording_enabled) {
03198 movie_recording_on = !(movie_recording_on);
03199 printf("\nOptiXRenderer) Movie recording %s\n",
03200 (movie_recording_on) ? "STARTED" : "STOPPED");
03201 if (movie_recording_on) {
03202 movie_recording_start_time = wkf_timer_timenow(ort_timer);
03203 movie_framecount = 0;
03204 movie_lastframeindex = 0;
03205 } else {
03206 printf("OptiXRenderer) Encode movie with:\n");
03207 printf("OptiXRenderer) 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");
03208 }
03209 } else {
03210 printf("\nOptiXRenderer) Movie recording not available.\n");
03211 }
03212 break;
03213
03214 case 'S':
03215 if (havestereo) {
03216 stereoon = (!stereoon);
03217 printf("\nOptiXRenderer) Stereoscopic display %s\n",
03218 (stereoon) ? "enabled" : "disabled");
03219 winredraw = 1;
03220 } else {
03221 printf("\nOptiXRenderer) Stereoscopic display unavailable\n");
03222 }
03223 break;
03224
03225 case 't':
03226 mm = RTMM_TRANS;
03227 printf("\nOptiXRenderer) Mouse translation mode\n");
03228 break;
03229
03230 case 'q':
03231 case 'Q':
03232 case 0x1b:
03233 printf("\nOptiXRenderer) Exiting on user input. \n");
03234 done=1;
03235 break;
03236 }
03237 } else if (evdev != GLWIN_EV_NONE) {
03238 switch (evdev) {
03239 case GLWIN_EV_KBD_F1:
03240 #if defined(USE_REVERSE_SHADOW_RAYS) && defined(USE_REVERSE_SHADOW_RAYS_DEFAULT)
03241 gl_shadows_on=(!gl_shadows_on) ? RT_SHADOWS_ON_REVERSE : RT_SHADOWS_OFF;
03242 #else
03243 gl_shadows_on=(!gl_shadows_on) ? RT_SHADOWS_ON : RT_SHADOWS_OFF;
03244
03245 #endif
03246
03247 printf("\n");
03248 #if defined(USE_REVERSE_SHADOW_RAYS) && defined(USE_REVERSE_SHADOW_RAYS_DEFAULT)
03249 printf("OptiXRenderer) Shadows %s\n",
03250 (gl_shadows_on) ? "enabled (reversal opt.)" : "disabled");
03251 #else
03252 printf("OptiXRenderer) Shadows %s\n",
03253 (gl_shadows_on) ? "enabled" : "disabled");
03254 #endif
03255 winredraw = 1;
03256 break;
03257
03258 case GLWIN_EV_KBD_F2:
03259 gl_ao_on = (!gl_ao_on);
03260 printf("\n");
03261 printf("OptiXRenderer) Ambient occlusion %s\n",
03262 (gl_ao_on) ? "enabled" : "disabled");
03263 winredraw = 1;
03264 break;
03265
03266 case GLWIN_EV_KBD_F3:
03267 gl_dof_on = (!gl_dof_on);
03268 printf("\n");
03269 printf("OptiXRenderer) Depth-of-field %s\n",
03270 (gl_dof_on) ? "enabled" : "disabled");
03271 winredraw = 1;
03272 break;
03273
03274 case GLWIN_EV_KBD_F4:
03275 gl_fog_on = (!gl_fog_on);
03276 printf("\n");
03277 printf("OptiXRenderer) Depth cueing %s\n",
03278 (gl_fog_on) ? "enabled" : "disabled");
03279 winredraw = 1;
03280 break;
03281
03282 case GLWIN_EV_KBD_F5:
03283 gl_clip_on = (!gl_clip_on);
03284 printf("\n");
03285 printf("OptiXRenderer) HMD/camera clipping plane/sphere %s\n",
03286 (gl_clip_on) ? "enabled" : "disabled");
03287 winredraw = 1;
03288 break;
03289
03290 case GLWIN_EV_KBD_F6:
03291 gl_headlight_on = (!gl_headlight_on);
03292 printf("\n");
03293 printf("OptiXRenderer) HMD/camera headlight %s\n",
03294 (gl_headlight_on) ? "enabled" : "disabled");
03295 winredraw = 1;
03296 break;
03297
03298 case GLWIN_EV_KBD_F7:
03299 hmd_interleave_draws = (!hmd_interleave_draws);
03300 printf("\n");
03301 printf("OptiXRenderer) HMD interleaved draws %s\n",
03302 (hmd_interleave_draws) ? "enabled" : "disabled");
03303 break;
03304
03305 case GLWIN_EV_KBD_F8:
03306 hmd_tex_caching = (!hmd_tex_caching);
03307 printf("\n");
03308 printf("OptiXRenderer) HMD tex caching %s\n",
03309 (hmd_tex_caching) ? "enabled" : "disabled");
03310 break;
03311
03312 case GLWIN_EV_KBD_F9:
03313 hmd_warp_drawmode = (hmd_warp_drawmode+1) % 5;
03314 printf("\n");
03315 { const char *warpmodestr="Off";
03316 switch (hmd_warp_drawmode) {
03317 case 0: warpmodestr="Lens: Off Chroma: Off Grid: Off"; break;
03318 case 1: warpmodestr="Lens: On Chroma: On Grid: Off"; break;
03319 case 2: warpmodestr="Lens: On Chroma: On Grid: On "; break;
03320 case 3: warpmodestr="Lens: On Chroma: Off Grid: Off"; break;
03321 case 4: warpmodestr="Lens: On Chroma: Off Grid: On "; break;
03322 }
03323 printf("OptiXRenderer) HMD Corr. %s\n", warpmodestr);
03324 }
03325 break;
03326
03327 #ifdef USE_REVERSE_SHADOW_RAYS
03328 case GLWIN_EV_KBD_F10:
03329 if (gl_shadows_on == RT_SHADOWS_ON)
03330 gl_shadows_on = RT_SHADOWS_ON_REVERSE;
03331 else if (gl_shadows_on == RT_SHADOWS_ON_REVERSE)
03332 gl_shadows_on = RT_SHADOWS_ON;
03333 printf("\n");
03334 printf("OptiXRenderer) Shadow ray reversal %s\n",
03335 (gl_shadows_on==RT_SHADOWS_ON_REVERSE) ? "enabled" : "disabled");
03336 winredraw = 1;
03337 break;
03338 #endif
03339
03340 case GLWIN_EV_KBD_F12:
03341 gl_fs_on = (!gl_fs_on);
03342 printf("\nOptiXRenderer) Toggling fullscreen window %s\n",
03343 (gl_fs_on) ? "on" : "off");
03344 if (gl_fs_on) {
03345 if (glwin_fullscreen(win, gl_fs_on, 0) == 0) {
03346 fsowsx = wsx;
03347 fsowsy = wsy;
03348 glwin_get_winsize(win, &wsx, &wsy);
03349 } else {
03350 printf("OptiXRenderer) Fullscreen mode note available\n");
03351 }
03352 } else {
03353 glwin_fullscreen(win, gl_fs_on, 0);
03354 glwin_resize(win, fsowsx, fsowsy);
03355 }
03356 winredraw = 1;
03357 break;
03358
03359 case GLWIN_EV_KBD_UP:
03360 cam_dof_focal_dist *= 1.02f;
03361 printf("\nOptiXRenderer) DoF focal dist: %f\n", cam_dof_focal_dist);
03362 winredraw = 1;
03363 break;
03364
03365 case GLWIN_EV_KBD_DOWN:
03366 cam_dof_focal_dist *= 0.96f;
03367 if (cam_dof_focal_dist < 0.02f) cam_dof_focal_dist = 0.02f;
03368 printf("\nOptiXRenderer) DoF focal dist: %f\n", cam_dof_focal_dist);
03369 winredraw = 1;
03370 break;
03371
03372 case GLWIN_EV_KBD_RIGHT:
03373 cam_dof_fnumber += 1.0f;
03374 printf("\nOptiXRenderer) DoF f/stop: %f\n", cam_dof_fnumber);
03375 winredraw = 1;
03376 break;
03377
03378 case GLWIN_EV_KBD_LEFT:
03379 cam_dof_fnumber -= 1.0f;
03380 if (cam_dof_fnumber < 1.0f) cam_dof_fnumber = 1.0f;
03381 printf("\nOptiXRenderer) DoF f/stop: %f\n", cam_dof_fnumber);
03382 winredraw = 1;
03383 break;
03384
03385 case GLWIN_EV_MOUSE_MOVE:
03386 if (mousedown != RTMD_NONE) {
03387 int x, y;
03388 glwin_get_mousepointer(win, &x, &y);
03389
03390 float zoommod = 2.0f*cur_cam_zoom/cam_zoom_orig;
03391 float txdx = (x - mousedownx) * zoommod / wsx;
03392 float txdy = (y - mousedowny) * zoommod / wsy;
03393 if (mm != RTMM_SCALE) {
03394 mousedownx = x;
03395 mousedowny = y;
03396 }
03397
03398 if (mm == RTMM_ROT) {
03399 Matrix4 rm;
03400 if (mousedown == RTMD_LEFT) {
03401
03402
03403 rm.rotate_axis(cam_V, -txdx);
03404 rm.rotate_axis(cam_U, -txdy);
03405 } else if (mousedown == RTMD_MIDDLE ||
03406 mousedown == RTMD_RIGHT) {
03407 rm.rotate_axis(cam_W, txdx);
03408 }
03409 rm.multpoint3d(cam_pos, cam_pos);
03410 rm.multnorm3d(cam_U, cam_U);
03411 rm.multnorm3d(cam_V, cam_V);
03412 rm.multnorm3d(cam_W, cam_W);
03413
03414 if (xformgradientsphere) {
03415 rm.multnorm3d(scene_gradient, scene_gradient);
03416 }
03417
03418 if (xformlights) {
03419
03420 for (i=0; i<directional_lights.num(); i++) {
03421 rm.multnorm3d((float*)&cur_dlights[i].dir, (float*)&cur_dlights[i].dir);
03422 }
03423 }
03424
03425 winredraw = 1;
03426 } else if (mm == RTMM_TRANS) {
03427 if (mousedown == RTMD_LEFT) {
03428 float dU[3], dV[3];
03429 vec_scale(dU, -txdx, cam_U);
03430 vec_scale(dV, txdy, cam_V);
03431 vec_add(cam_pos, cam_pos, dU);
03432 vec_add(cam_pos, cam_pos, dV);
03433 } else if (mousedown == RTMD_MIDDLE ||
03434 mousedown == RTMD_RIGHT) {
03435 float dW[3];
03436 vec_scale(dW, txdx, cam_W);
03437 vec_add(cam_pos, cam_pos, dW);
03438 }
03439 winredraw = 1;
03440 } else if (mm == RTMM_SCALE) {
03441 float txdx = (x - mousedownx) * 2.0 / wsx;
03442 float zoominc = 1.0f - txdx;
03443 if (zoominc < 0.01f) zoominc = 0.01f;
03444 cam_zoom = cur_cam_zoom * zoominc;
03445 winredraw = 1;
03446 } else if (mm == RTMM_DOF) {
03447 cam_dof_fnumber += txdx * 20.0f;
03448 if (cam_dof_fnumber < 1.0f) cam_dof_fnumber = 1.0f;
03449 cam_dof_focal_dist += -txdy;
03450 if (cam_dof_focal_dist < 0.01f) cam_dof_focal_dist = 0.01f;
03451 winredraw = 1;
03452 }
03453 }
03454 break;
03455
03456 case GLWIN_EV_MOUSE_LEFT:
03457 case GLWIN_EV_MOUSE_MIDDLE:
03458 case GLWIN_EV_MOUSE_RIGHT:
03459 if (evval) {
03460 glwin_get_mousepointer(win, &mousedownx, &mousedowny);
03461 cur_cam_zoom = cam_zoom;
03462
03463 if (evdev == GLWIN_EV_MOUSE_LEFT) mousedown = RTMD_LEFT;
03464 else if (evdev == GLWIN_EV_MOUSE_MIDDLE) mousedown = RTMD_MIDDLE;
03465 else if (evdev == GLWIN_EV_MOUSE_RIGHT) mousedown = RTMD_RIGHT;
03466 } else {
03467 mousedown = RTMD_NONE;
03468 }
03469 break;
03470
03471 case GLWIN_EV_MOUSE_WHEELUP:
03472 cam_zoom /= 1.1f; winredraw = 1; break;
03473
03474 case GLWIN_EV_MOUSE_WHEELDOWN:
03475 cam_zoom *= 1.1f; winredraw = 1; break;
03476 }
03477 }
03478 }
03479
03480
03481
03482
03483
03484
03485 if (spaceballenabled) {
03486
03487 int tx=0, ty=0, tz=0, rx=0, ry=0, rz=0, buttons=0;
03488 if (glwin_get_spaceball(win, &rx, &ry, &rz, &tx, &ty, &tz, &buttons)) {
03489
03490 if (spaceballflightmode) {
03491 rx= -rx;
03492 ry= -ry;
03493 rz= -rz;
03494
03495 tx= -tx;
03496 ty= -ty;
03497 tz= -tz;
03498 }
03499
03500
03501 if (buttons & 1) {
03502 printf("OptiXRenderer) spaceball button 1 pressed: reset view\n");
03503 vec_copy(scene_gradient, scene_gradient_orig);
03504 cam_zoom = cam_zoom_orig;
03505 vec_copy(cam_pos, cam_pos_orig);
03506 vec_copy(cam_U, cam_U_orig);
03507 vec_copy(cam_V, cam_V_orig);
03508 vec_copy(cam_W, cam_W_orig);
03509
03510
03511 for (i=0; i<directional_lights.num(); i++) {
03512 vec_copy((float*)&cur_dlights[i].dir, directional_lights[i].dir);
03513 vec_normalize((float*)&cur_dlights[i].dir);
03514 }
03515 winredraw = 1;
03516 }
03517
03518
03519 if (buttons & 2) {
03520 spaceballmode = !(spaceballmode);
03521 printf("OptiXRenderer) spaceball mode: %s \n",
03522 (spaceballmode) ? "scaling" : "rotation/translation");
03523 }
03524
03525
03526 if (spaceballmode == 0) {
03527 float zoommod = 2.0f*cam_zoom/cam_zoom_orig;
03528 float divlen = sqrtf(wsx*wsx + wsy*wsy) * 50.0f;
03529
03530
03531 if (rx != 0 || ry !=0 || rz !=0) {
03532 Matrix4 rm;
03533 rm.rotate_axis(cam_U, -rx * zoommod / divlen);
03534 rm.rotate_axis(cam_V, -ry * zoommod / divlen);
03535 rm.rotate_axis(cam_W, -rz * zoommod / divlen);
03536
03537 rm.multpoint3d(cam_pos, cam_pos);
03538 rm.multnorm3d(cam_U, cam_U);
03539 rm.multnorm3d(cam_V, cam_V);
03540 rm.multnorm3d(cam_W, cam_W);
03541
03542 if (xformgradientsphere) {
03543 rm.multnorm3d(scene_gradient, scene_gradient);
03544 }
03545
03546 if (xformlights) {
03547
03548 for (i=0; i<directional_lights.num(); i++) {
03549 rm.multnorm3d((float*)&cur_dlights[i].dir, (float*)&cur_dlights[i].dir);
03550 }
03551 }
03552 winredraw = 1;
03553 }
03554
03555
03556 if (tx != 0 || ty !=0 || tz !=0) {
03557 float dU[3], dV[3], dW[3];
03558 vec_scale(dU, -tx * zoommod / divlen, cam_U);
03559 vec_scale(dV, -ty * zoommod / divlen, cam_V);
03560 vec_scale(dW, -tz * zoommod / divlen, cam_W);
03561 vec_add(cam_pos, cam_pos, dU);
03562 vec_add(cam_pos, cam_pos, dV);
03563 vec_add(cam_pos, cam_pos, dW);
03564 winredraw = 1;
03565 }
03566 }
03567
03568
03569 if (spaceballmode == 1) {
03570 const float sbscale = 1.0f / (1024.0f * 8.0f);
03571 float zoominc = 1.0f - (rz * sbscale);
03572 if (zoominc < 0.01) zoominc = 0.01;
03573 cam_zoom *= zoominc;
03574 winredraw = 1;
03575 }
03576
03577 }
03578 }
03579
03580
03581
03582 vec_copy(hmd_U, cam_U);
03583 vec_copy(hmd_V, cam_V);
03584 vec_copy(hmd_W, cam_W);
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596 #if defined(VMDOPTIX_USE_HMD)
03597 float hmd_U_new[3] = {1.0f, 0.0f, 0.0f};
03598 float hmd_V_new[3] = {0.0f, 1.0f, 0.0f};
03599 float hmd_W_new[3] = {0.0f, 0.0f, 1.0f};
03600 #if defined(VMDUSEEVENTIO)
03601 if ((hmd && eviodev) || (hmd && camera_projection == RT_OCULUS_RIFT)) {
03602 #else
03603 if (hmd && camera_projection == RT_OCULUS_RIFT) {
03604 #endif
03605 float hmd_U_orig[3] = {1.0f, 0.0f, 0.0f};
03606 float hmd_V_orig[3] = {0.0f, 1.0f, 0.0f};
03607 float hmd_W_orig[3] = {0.0f, 0.0f, 1.0f};
03608
03609
03610
03611 hmd->update();
03612 hmd->rot_basis_quat(hmd_U_new, hmd_V_new, hmd_W_new,
03613 hmd_U_orig, hmd_V_orig, hmd_W_orig);
03614
03615
03616
03617
03618
03619 float hmdtmp[3];
03620 memset(hmdtmp, 0, sizeof(hmdtmp));
03621 vec_scaled_add(hmdtmp, hmd_U_new[0], cam_U);
03622 vec_scaled_add(hmdtmp, hmd_U_new[1], cam_V);
03623 vec_scaled_add(hmdtmp, hmd_U_new[2], cam_W);
03624 vec_copy(hmd_U_new, hmdtmp);
03625
03626 memset(hmdtmp, 0, sizeof(hmdtmp));
03627 vec_scaled_add(hmdtmp, hmd_V_new[0], cam_U);
03628 vec_scaled_add(hmdtmp, hmd_V_new[1], cam_V);
03629 vec_scaled_add(hmdtmp, hmd_V_new[2], cam_W);
03630 vec_copy(hmd_V_new, hmdtmp);
03631
03632 memset(hmdtmp, 0, sizeof(hmdtmp));
03633 vec_scaled_add(hmdtmp, hmd_W_new[0], cam_U);
03634 vec_scaled_add(hmdtmp, hmd_W_new[1], cam_V);
03635 vec_scaled_add(hmdtmp, hmd_W_new[2], cam_W);
03636 vec_copy(hmd_W_new, hmdtmp);
03637
03638 #if 0
03639 float q[4];
03640 hmd->get_rot_quat(q);
03641 printf("\nQ: %f %f %f %f\n", q[0], q[1], q[2], q[3]);
03642 printf("hmd_U: %.1f %.1f %.1f\n", hmd_U[0], hmd_U[1], hmd_U[2]);
03643 printf("hmd_V: %.1f %.1f %.1f\n", hmd_V[0], hmd_V[1], hmd_V[2]);
03644 printf("hmd_W: %.1f %.1f %.1f\n", hmd_W[0], hmd_W[1], hmd_W[2]);
03645 #endif
03646
03647 if (hmd && camera_projection == RT_OCULUS_RIFT) {
03648 vec_copy(hmd_U, hmd_U_new);
03649 vec_copy(hmd_V, hmd_V_new);
03650 vec_copy(hmd_W, hmd_W_new);
03651
03652
03653
03654 winredraw = 1;
03655 }
03656 }
03657 #endif
03658
03659
03660 #if defined(VMDUSEEVENTIO)
03661
03662
03663
03664 if (eviodev) {
03665 float ax1, ay1, ax2, ay2;
03666 int buttons;
03667 int rc=0;
03668 rc = evio_get_joystick_status(eviodev, &ax1, &ay1, &ax2, &ay2, &buttons);
03669
03670 if (buttons) {
03671 printf("Joystick: %5.2f %5.2f %5.2f %5.2f 0x%08x \n",
03672 ax1, ay1, ax2, ay2, buttons);
03673 }
03674
03675 float tx = ax1 + ax2;
03676 float ty = ay1;
03677 float tz = ay2;
03678
03679
03680 if (fabsf(tx) > 0.03 || fabsf(ty) > 0.03 || fabsf(tz) > 0.03) {
03681 tx *= -500;
03682 ty *= 500;
03683 tz *= 500;
03684
03685
03686
03687 float zoommod = 2.0f*cam_zoom/cam_zoom_orig;
03688 float divlen = sqrtf(wsx*wsx + wsy*wsy) * 50;
03689 float dU[3], dV[3], dW[3];
03690 vec_scale(dU, -tx * zoommod / divlen, hmd_U_new);
03691 vec_scale(dV, -ty * zoommod / divlen, hmd_V_new);
03692 vec_scale(dW, -tz * zoommod / divlen, hmd_W_new);
03693 vec_add(cam_pos, cam_pos, dU);
03694 vec_add(cam_pos, cam_pos, dV);
03695 vec_add(cam_pos, cam_pos, dW);
03696 winredraw = 1;
03697 }
03698
03699 }
03700 #endif
03701
03702
03703
03704
03705
03706
03707 int resize_buffers=0;
03708
03709 #if defined(VMDOPTIX_USE_HMD)
03710
03711
03712 if (hmd_freerun) {
03713 if (wsx != owsx || wsy != owsy)
03714 winredraw=1;
03715 }
03716 else
03717 #endif
03718 {
03719
03720 if (wsx != width) {
03721 width = wsx;
03722 resize_buffers=1;
03723 }
03724
03725 if (wsy != height || (stereoon != stereoon_old)) {
03726 if (stereoon) {
03727 if (height != wsy * 2) {
03728 height = wsy * 2;
03729 resize_buffers=1;
03730 }
03731 } else {
03732 height = wsy;
03733 resize_buffers=1;
03734 }
03735 }
03736 }
03737
03738
03739
03740
03741 #if defined(VMDOPTIX_PROGRESSIVEAPI) && OPTIX_VERSION < 3080
03742
03743
03744
03745
03746
03747 if (done || winredraw || resize_buffers ||
03748 (stereoon != stereoon_old) || (gl_dof_on != gl_dof_on_old)) {
03749
03750 if (vcarunning) {
03751 rtContextStopProgressive(ctx);
03752 vcarunning=0;
03753 }
03754 }
03755 #endif
03756
03757
03758
03759 if ((stereoon != stereoon_old) || (gl_dof_on != gl_dof_on_old)) {
03760
03761
03762 if (stereoon != stereoon_old) {
03763 resize_buffers=1;
03764 }
03765
03766
03767 stereoon_old = stereoon;
03768 gl_dof_on_old = gl_dof_on;
03769
03770
03771
03772
03773 set_accum_raygen_pgm(camera_projection, stereoon, gl_dof_on);
03774 }
03775
03776 if (resize_buffers) {
03777 framebuffer_resize(width, height);
03778
03779
03780
03781
03782 if (movie_recording_enabled) {
03783 printf("\rOptiXRenderer) Window resize: %d x %d \n", width, height);
03784 }
03785
03786 winredraw=1;
03787 }
03788
03789 int frame_ready = 1;
03790 unsigned int subframe_count = 1;
03791 if (!done) {
03792 #if defined(VMDOPTIX_USE_HMD)
03793
03794 if (hmd_warp && (winredraw || hmd_warp_coeff_update)) {
03795 glwin_spheremap_update_hmd_warp(win, hmd_warp, wsx, wsy, 21,
03796 width, height, hmd_warp_coeff,
03797 hmd_warp_coeff_update);
03798 hmd_warp_coeff_update=0;
03799 }
03800 #endif
03801
03802
03803
03804
03805
03806
03807 if (winredraw) {
03808
03809 RTERR( rtVariableSet1f( cam_zoom_v, cam_zoom) );
03810 RTERR( rtVariableSet3fv( cam_pos_v, cam_pos) );
03811 RTERR( rtVariableSet3fv( cam_U_v, hmd_U) );
03812 RTERR( rtVariableSet3fv( cam_V_v, hmd_V) );
03813 RTERR( rtVariableSet3fv( cam_W_v, hmd_W) );
03814 RTERR( rtVariableSet3fv(scene_gradient_v, scene_gradient) );
03815
03816
03817 RTERR( rtVariableSet1i(shadows_enabled_v, gl_shadows_on) );
03818
03819
03820 RTERR( rtVariableSet1i(fog_mode_v,
03821 (int) (gl_fog_on) ? fog_mode : RT_FOG_NONE) );
03822
03823
03824 RTERR( rtVariableSet1i(clipview_mode_v,
03825 (int) (gl_clip_on) ? clipview_mode : RT_CLIP_NONE) );
03826
03827
03828 RTERR( rtVariableSet1i(headlight_mode_v,
03829 (int) (gl_headlight_on) ? RT_HEADLIGHT_ON : RT_HEADLIGHT_OFF) );
03830
03831
03832 RTERR( rtVariableSet1f(cam_dof_focal_dist_v, cam_dof_focal_dist) );
03833 RTERR( rtVariableSet1f(cam_dof_aperture_rad_v, cam_dof_focal_dist / (2.0f * cam_zoom * cam_dof_fnumber)) );
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844 if (xformlights) {
03845 #if defined(VMDOPTIX_LIGHTUSEROBJS)
03846 DirectionalLightList dlights;
03847 memset(&dlights, 0, sizeof(DirectionalLightList) );
03848 dlights.num_lights = directional_lights.num();
03849 int dlcount = directional_lights.num();
03850 dlcount = (dlcount > DISP_LIGHTS) ? DISP_LIGHTS : dlcount;
03851 for (i=0; i<dlcount; i++) {
03852
03853 dlights.dirs[i] = cur_dlights[i].dir;
03854 }
03855 RTERR( rtVariableSetUserData(dir_light_list_v, sizeof(DirectionalLightList), &dlights) );
03856 #else
03857 DirectionalLight *dlbuf;
03858 RTERR( rtBufferMap(dir_lightbuffer, (void **) &dlbuf) );
03859 for (i=0; i<directional_lights.num(); i++) {
03860 vec_copy((float*)&dlbuf[i].dir, (float*)&cur_dlights[i].dir);
03861 }
03862 RTERR( rtBufferUnmap(dir_lightbuffer) );
03863 #endif
03864 }
03865
03866
03867 totalsamplecount=0;
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878 if (autosamplecount) {
03879 if (fpsexpave > 37)
03880 samples_per_pass++;
03881 else if (fpsexpave < 30)
03882 samples_per_pass--;
03883
03884
03885 if (samples_per_pass > 14)
03886 samples_per_pass=14;
03887 if (samples_per_pass < 1)
03888 samples_per_pass=1;
03889 }
03890
03891
03892
03893 if (force_ao_1) {
03894 cur_aa_samples = samples_per_pass;
03895 cur_ao_samples = 1;
03896 } else if (gl_shadows_on && gl_ao_on) {
03897 if (gl_dof_on) {
03898 if (samples_per_pass < 4) {
03899 cur_aa_samples=samples_per_pass;
03900 cur_ao_samples=1;
03901 } else {
03902 int s = (int) sqrtf(samples_per_pass);
03903 cur_aa_samples=s;
03904 cur_ao_samples=s;
03905 }
03906 } else {
03907 cur_aa_samples=1;
03908 cur_ao_samples=samples_per_pass;
03909 }
03910 } else {
03911 cur_aa_samples=samples_per_pass;
03912 cur_ao_samples=0;
03913 }
03914
03915
03916
03917 RTERR( rtVariableSet1i(aa_samples_v, cur_aa_samples) );
03918
03919
03920 if (gl_shadows_on && gl_ao_on) {
03921 RTERR( rtVariableSet1i(ao_samples_v, cur_ao_samples) );
03922 } else {
03923 cur_ao_samples = 0;
03924 RTERR( rtVariableSet1i(ao_samples_v, 0) );
03925 }
03926
03927 #ifdef VMDOPTIX_PROGRESSIVEAPI
03928 RTERR( rtVariableSet1f(accum_norm_v, 1.0f / float(cur_aa_samples)) );
03929 #endif
03930
03931
03932
03933 owsx = wsx;
03934 owsy = wsy;
03935 }
03936
03937
03938
03939
03940
03941
03942
03943
03944
03945 #ifndef VMDOPTIX_PROGRESSIVEAPI
03946
03947
03948
03949 RTERR( rtVariableSet1f(accum_norm_v, 1.0f / float(cur_aa_samples + accum_count)) );
03950
03951
03952
03953 RTERR( rtVariableSet1ui(accum_count_v, accum_count) );
03954
03955
03956
03957
03958
03959
03960 #endif
03961
03962
03963
03964
03965
03966 frame_ready = 1;
03967 subframe_count = 1;
03968 if (lasterror == RT_SUCCESS) {
03969 if (winredraw) {
03970 #if defined(ORT_RAYSTATS)
03971 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_CLEAR_RAYSTATS, width, height) );
03972 accumbufstarttime=wkf_timer_timenow(ort_timer);
03973 #endif
03974 #ifdef VMDOPTIX_PROGRESSIVEAPI
03975
03976 RTERR( rtContextLaunchProgressive2D(ctx, RT_RAY_GEN_ACCUMULATE, width, height, 0) );
03977 #else
03978 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_CLEAR_ACCUMULATION_BUFFER, width, height) );
03979 #endif
03980 winredraw=0;
03981 }
03982
03983 #ifdef VMDOPTIX_PROGRESSIVEAPI
03984
03985 RTERR( rtBufferGetProgressiveUpdateReady(framebuffer, &frame_ready, &subframe_count, 0) );
03986 if (frame_ready)
03987 totalsamplecount = subframe_count * samples_per_pass;
03988 #else
03989
03990 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_ACCUMULATE, width, height) );
03991 subframe_count++;
03992 totalsamplecount += samples_per_pass;
03993 accum_count += cur_aa_samples;
03994
03995
03996
03997 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_COPY_FINISH, width, height) );
03998 #endif
03999
04000 if (lasterror == RT_SUCCESS) {
04001 if (frame_ready || hmd_freerun) {
04002 double bufnewtime = wkf_timer_timenow(ort_timer);
04003
04004
04005
04006
04007
04008 #if defined(VMDOPTIX_USE_HMD)
04009 if (hmd_freerun) {
04010 double hmdnewtime = wkf_timer_timenow(ort_timer);
04011 double hmdframetime = (hmdnewtime-hmdoldtime) + 0.00001f;
04012 hmdoldtime=hmdnewtime;
04013
04014
04015 double hmdframefps = 1.0f/hmdframetime;
04016 hmdfpsexpave = (hmdfpsexpave * 0.90) + (hmdframefps * 0.10);
04017
04018 float hmdquat[4];
04019 if (hmd_no_draw == 0) {
04020 int hmd_warp_on = (hmd_warp_drawmode!=0);
04021 int hmd_warp_lines = (hmd_warp_drawmode==2 || hmd_warp_drawmode==4);
04022 int hmd_chroma_on = (hmd_warp_drawmode==1 || hmd_warp_drawmode==2);
04023
04024
04025 if (frame_ready || (!hmd_tex_caching)) {
04026
04027 const unsigned char * img;
04028 rtBufferMap(framebuffer, (void **) &img);
04029
04030
04031 if (hmd_interleave_draws) {
04032
04033 hmd->get_rot_quat(hmdquat, 1);
04034 if (hmd_warp && hmd_warp_drawmode != 0) {
04035 glwin_spheremap_draw_hmd_warp(win, hmd_warp,
04036 hmd_warp_on, hmd_warp_lines, hmd_chroma_on,
04037 wsx, wsy, width, height, hmdquat, hmd_fov, 15.0f, hmd_spres);
04038 } else {
04039 glwin_spheremap_draw_tex(win, GLWIN_STEREO_OVERUNDER, width, height, hmdquat, hmd_fov, 15.0f, hmd_spres);
04040 }
04041 glwin_swap_buffers(win);
04042 }
04043
04044 glwin_spheremap_upload_tex_rgb3u(win, width, height, img);
04045
04046
04047 if (hmd_interleave_draws) {
04048
04049 hmd->get_rot_quat(hmdquat, 1);
04050 if (hmd_warp && hmd_warp_drawmode != 0) {
04051 glwin_spheremap_draw_hmd_warp(win, hmd_warp,
04052 hmd_warp_on, hmd_warp_lines, hmd_chroma_on,
04053 wsx, wsy, width, height, hmdquat, hmd_fov, 15.0f, hmd_spres);
04054 } else {
04055 glwin_spheremap_draw_tex(win, GLWIN_STEREO_OVERUNDER, width, height, hmdquat, hmd_fov, 15.0f, hmd_spres);
04056 }
04057 glwin_swap_buffers(win);
04058 }
04059
04060 rtBufferUnmap(framebuffer);
04061 mapbuftotaltime = wkf_timer_timenow(ort_timer) - bufnewtime;
04062 }
04063
04064
04065 hmd->get_rot_quat(hmdquat, 1);
04066 if (hmd_warp && hmd_warp_drawmode != 0) {
04067 glwin_spheremap_draw_hmd_warp(win, hmd_warp,
04068 hmd_warp_on, hmd_warp_lines, hmd_chroma_on,
04069 wsx, wsy, width, height, hmdquat, hmd_fov, 15.0f, hmd_spres);
04070 } else {
04071 glwin_spheremap_draw_tex(win, GLWIN_STEREO_OVERUNDER, width, height, hmdquat, hmd_fov, 15.0f, hmd_spres);
04072 }
04073 glwin_swap_buffers(win);
04074 }
04075
04076 hmdgldrawtime = wkf_timer_timenow(ort_timer) - hmdnewtime;
04077 } else {
04078 #endif
04079
04080 const unsigned char * img;
04081 rtBufferMap(framebuffer, (void **) &img);
04082
04083 #if 0
04084 glwin_draw_image_tex_rgb3u(win, (stereoon!=0)*GLWIN_STEREO_OVERUNDER, width, height, img);
04085 #else
04086 glwin_draw_image_rgb3u(win, (stereoon!=0)*GLWIN_STEREO_OVERUNDER, width, height, img);
04087 #endif
04088
04089 #if 1
04090
04091
04092 if (app->uivs && app->uivs->srv_connected()) {
04093 app->uivs->video_frame_pending(img, width, height);
04094 app->uivs->check_event();
04095 }
04096 #endif
04097
04098 rtBufferUnmap(framebuffer);
04099 mapbuftotaltime = wkf_timer_timenow(ort_timer) - bufnewtime;
04100
04101 #if defined(VMDOPTIX_USE_HMD)
04102 }
04103 #endif
04104
04105
04106
04107
04108
04109
04110 if (movie_recording_enabled && movie_recording_on) {
04111 char moviefilename[2048];
04112
04113
04114
04115 double now = wkf_timer_timenow(ort_timer);
04116 double frametime = now - movie_recording_start_time;
04117 int fidx = frametime * movie_recording_fps;
04118
04119
04120 if (movie_framecount==0)
04121 fidx=0;
04122 movie_framecount++;
04123
04124 #if defined(__linux)
04125
04126
04127
04128
04129 sprintf(moviefilename, movie_recording_filebase,
04130 movie_lastframeindex);
04131 int symidx;
04132 for (symidx=movie_lastframeindex; symidx<fidx; symidx++) {
04133 char symlinkfilename[2048];
04134 sprintf(symlinkfilename, movie_recording_filebase, symidx);
04135 if (symlink(moviefilename, symlinkfilename) < 0)
04136 perror("symlink: ");
04137 }
04138 #endif
04139
04140
04141 sprintf(moviefilename, movie_recording_filebase, fidx);
04142 if (OptiXWriteImage(moviefilename, writealpha, framebuffer,
04143 RT_FORMAT_UNSIGNED_BYTE4, width, height) == -1) {
04144 movie_recording_on = 0;
04145 printf("\n");
04146 printf("OptiXRenderer) ERROR during writing image during movie recording!\n");
04147 printf("OptiXRenderer) Movie recording STOPPED\n");
04148 }
04149
04150 movie_lastframeindex = fidx;
04151 }
04152 }
04153 } else {
04154 printf("OptiXRenderer) An error occured during rendering. Rendering is aborted.\n");
04155 done=1;
04156 break;
04157 }
04158 } else {
04159 printf("OptiXRenderer) An error occured in AS generation. Rendering is aborted.\n");
04160 done=1;
04161 break;
04162 }
04163 }
04164
04165 if (!done && frame_ready) {
04166 double newtime = wkf_timer_timenow(ort_timer);
04167 double frametime = (newtime-oldtime) + 0.00001f;
04168 oldtime=newtime;
04169
04170
04171 double framefps = 1.0f/frametime;
04172 fpsexpave = (fpsexpave * 0.90) + (framefps * 0.10);
04173
04174 if (hmd_freerun) {
04175 printf("OptiXRenderer) %c AA%2d AO%2d %5d tot RT FPS %.1f HMD FPS %.0f GL%.4f MB%.4f \r",
04176 statestr[state], cur_aa_samples, cur_ao_samples,
04177 totalsamplecount, fpsexpave,
04178 hmdfpsexpave, hmdgldrawtime, mapbuftotaltime);
04179 } else {
04180 printf("OptiXRenderer) %c AA:%2d AO:%2d, %4d tot RT FPS: %.1f %.4f s/frame sf: %d \r",
04181 statestr[state], cur_aa_samples, cur_ao_samples,
04182 totalsamplecount, fpsexpave, frametime, subframe_count);
04183 }
04184
04185 fflush(stdout);
04186 state = (state+1) & 3;
04187 }
04188
04189 }
04190
04191 printf("\n");
04192
04193
04194 if (lasterror == RT_SUCCESS) {
04195 #if defined(ORT_RAYSTATS)
04196 double frametime = wkf_timer_timenow(ort_timer) - accumbufstarttime;
04197 OptiXPrintRayStats(raystats1_buffer, raystats2_buffer, frametime);
04198 #endif
04199
04200 wkf_timer_start(ort_timer);
04201 OptiXWriteImage(filename, writealpha, framebuffer);
04202 wkf_timer_stop(ort_timer);
04203
04204 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
04205 printf("OptiXRenderer) image file I/O time: %f secs\n", wkf_timer_time(ort_timer));
04206 }
04207 }
04208
04209 #if defined(VMDOPTIX_USE_HMD)
04210
04211 if (hmd) {
04212 delete hmd;
04213 hmd = NULL;
04214 }
04215
04216 if (hmd_warp != NULL) {
04217 glwin_spheremap_destroy_hmd_warp(win, hmd_warp);
04218 }
04219 #endif
04220
04221 #if defined(VMDUSEEVENTIO)
04222 if (eviodev) {
04223 evio_close(eviodev);
04224 }
04225 #endif
04226
04227 glwin_destroy(win);
04228 }
04229
04230 #endif
04231
04232
04233
04234 void OptiXRenderer::render_to_videostream(const char *filename, int writealpha) {
04235 int i;
04236
04237 if (!context_created)
04238 return;
04239
04240
04241 #if defined(USE_REVERSE_SHADOW_RAYS) && defined(USE_REVERSE_SHADOW_RAYS_DEFAULT)
04242 int gl_shadows_on=(shadows_enabled) ? RT_SHADOWS_ON_REVERSE : RT_SHADOWS_OFF;
04243 #else
04244 int gl_shadows_on=(shadows_enabled) ? RT_SHADOWS_ON : RT_SHADOWS_OFF;
04245 #endif
04246
04247
04248 int gl_ao_on=(ao_samples > 0);
04249 int gl_dof_on, gl_dof_on_old;
04250 gl_dof_on=gl_dof_on_old=dof_enabled;
04251 int gl_fog_on=(fog_mode != RT_FOG_NONE);
04252 int gl_clip_on=(clipview_mode != RT_CLIP_NONE);
04253 int gl_headlight_on=(headlight_mode != RT_HEADLIGHT_OFF);
04254
04255
04256
04257
04258
04259
04260
04261 int movie_recording_enabled = (getenv("VMDOPTIXLIVEMOVIECAPTURE") != NULL);
04262 int movie_recording_on = 0;
04263 double movie_recording_start_time = 0.0;
04264 int movie_recording_fps = 30;
04265 int movie_framecount = 0;
04266 int movie_lastframeindex = 0;
04267 const char *movie_recording_filebase = "vmdlivemovie.%05d.tga";
04268 if (getenv("VMDOPTIXLIVEMOVIECAPTUREFILEBASE"))
04269 movie_recording_filebase = getenv("VMDOPTIXLIVEMOVIECAPTUREFILEBASE");
04270
04271
04272 int totalsamplecount=0;
04273
04274
04275
04276
04277
04278 #if defined(VMDOPTIX_PROGRESSIVEAPI)
04279 #if 1
04280 int autosamplecount=0;
04281 #else
04282 int autosamplecount=1;
04283 #endif
04284 #else
04285 int autosamplecount=1;
04286 #endif
04287
04288
04289
04290 int xformlights=1, xformgradientsphere=1;
04291
04292
04293
04294
04295
04296
04297
04298
04299
04300
04301
04302 int wsx=width, wsy=height;
04303 const char *imageszstr = getenv("VMDOPTIXIMAGESIZE");
04304 if (imageszstr) {
04305 if (sscanf(imageszstr, "%d %d", &width, &height) != 2) {
04306 width=wsx;
04307 height=wsy;
04308 }
04309 }
04310
04311 framebuffer_config(width, height, 1);
04312
04313
04314
04315 update_rendering_state(1);
04316 render_compile_and_validate();
04317
04318
04319
04320 int samples_per_pass = 1;
04321 int force_ao_1 = 0;
04322 int cur_aa_samples = aa_samples;
04323 int cur_ao_samples = ao_samples;
04324 float cam_zoom_orig = cam_zoom;
04325 float scene_gradient_orig[3] = {0.0f, 1.0f, 0.0f};
04326 vec_copy(scene_gradient_orig, scene_gradient);
04327
04328 float cam_pos_orig[3] = {0.0f, 0.0f, 2.0f};
04329 float cam_U_orig[3] = {1.0f, 0.0f, 0.0f};
04330 float cam_V_orig[3] = {0.0f, 1.0f, 0.0f};
04331 float cam_W_orig[3] = {0.0f, 0.0f, -1.0f};
04332 float cam_pos[3], cam_U[3], cam_V[3], cam_W[3];
04333 float hmd_U[3], hmd_V[3], hmd_W[3];
04334
04335 vec_copy(cam_pos, cam_pos_orig);
04336 vec_copy(cam_U, cam_U_orig);
04337 vec_copy(cam_V, cam_V_orig);
04338 vec_copy(cam_W, cam_W_orig);
04339
04340
04341 DirectionalLight *cur_dlights = (DirectionalLight *) calloc(1, directional_lights.num() * sizeof(DirectionalLight));
04342 for (i=0; i<directional_lights.num(); i++) {
04343 vec_copy((float*)&cur_dlights[i].dir, directional_lights[i].dir);
04344 vec_normalize((float*)&cur_dlights[i].dir);
04345 }
04346
04347
04348
04349 int stereoon=0, stereoon_old=0;
04350
04351
04352
04353
04354
04355
04356
04357
04358 cur_aa_samples = samples_per_pass;
04359 if (cur_ao_samples > 0) {
04360 cur_aa_samples = 1;
04361 cur_ao_samples = samples_per_pass;
04362 }
04363
04364 const char *statestr = "|/-\\.";
04365 int done=0, winredraw=1;
04366 int state=0;
04367
04368
04369 double fpsexpave=0.0;
04370 double accumbufstarttime=wkf_timer_timenow(ort_timer);
04371 double oldtime = wkf_timer_timenow(ort_timer);
04372
04373
04374 while (!done &&
04375 app->uivs && app->uivs->srv_connected()) {
04376
04377 #if 1
04378 if (app->uivs && app->uivs->srv_connected()) {
04379 if (app->uivs->srv_check_ui_event()) {
04380 int eventtype;
04381 app->uivs->srv_get_last_event_type(eventtype);
04382 switch (eventtype) {
04383 case VideoStream::VS_EV_ROTATE_BY:
04384 { int axis;
04385 float angle;
04386 app->uivs->srv_get_last_rotate_by(angle, axis);
04387 Matrix4 rm;
04388
04389 switch (axis) {
04390 case 'x':
04391 rm.rotate_axis(cam_U, -angle * VMD_PI/180.0f);
04392 break;
04393
04394 case 'y':
04395 rm.rotate_axis(cam_V, -angle * VMD_PI/180.0f);
04396 break;
04397
04398 case 'z':
04399 rm.rotate_axis(cam_W, -angle * VMD_PI/180.0f);
04400 break;
04401 }
04402 rm.multpoint3d(cam_pos, cam_pos);
04403 rm.multnorm3d(cam_U, cam_U);
04404 rm.multnorm3d(cam_V, cam_V);
04405 rm.multnorm3d(cam_W, cam_W);
04406
04407 if (xformgradientsphere) {
04408 rm.multnorm3d(scene_gradient, scene_gradient);
04409 }
04410
04411 if (xformlights) {
04412
04413 for (i=0; i<directional_lights.num(); i++) {
04414 rm.multnorm3d((float*)&cur_dlights[i].dir, (float*)&cur_dlights[i].dir);
04415 }
04416 }
04417 winredraw = 1;
04418 }
04419 break;
04420
04421 case VideoStream::VS_EV_TRANSLATE_BY:
04422 {
04423 float dU[3], dV[3], dW[3];
04424 float tx, ty, tz;
04425 app->uivs->srv_get_last_translate_by(tx, ty, tz);
04426 vec_scale(dU, -tx, cam_U);
04427 vec_scale(dV, -ty, cam_V);
04428 vec_scale(dW, -tz, cam_W);
04429 vec_add(cam_pos, cam_pos, dU);
04430 vec_add(cam_pos, cam_pos, dV);
04431 vec_add(cam_pos, cam_pos, dW);
04432 winredraw = 1;
04433 }
04434 break;
04435
04436 case VideoStream::VS_EV_SCALE_BY:
04437 { float zoominc;
04438 app->uivs->srv_get_last_scale_by(zoominc);
04439 cam_zoom *= 1.0f / zoominc;
04440 winredraw = 1;
04441 }
04442 break;
04443
04444 #if 0
04445 } else if (mm == RTMM_DOF) {
04446 cam_dof_fnumber += txdx * 20.0f;
04447 if (cam_dof_fnumber < 1.0f) cam_dof_fnumber = 1.0f;
04448 cam_dof_focal_dist += -txdy;
04449 if (cam_dof_focal_dist < 0.01f) cam_dof_focal_dist = 0.01f;
04450 winredraw = 1;
04451 }
04452 }
04453 #endif
04454 case VideoStream::VS_EV_KEYBOARD:
04455 { int keydev, keyval, shift_state;
04456 app->uivs->srv_get_last_keyboard(keydev, keyval, shift_state);
04457 switch (keydev) {
04458 case DisplayDevice::WIN_KBD:
04459 {
04460 switch (keyval) {
04461
04462 case '1': autosamplecount=0; samples_per_pass=1; winredraw=1; break;
04463 case '2': autosamplecount=0; samples_per_pass=2; winredraw=1; break;
04464 case '3': autosamplecount=0; samples_per_pass=3; winredraw=1; break;
04465 case '4': autosamplecount=0; samples_per_pass=4; winredraw=1; break;
04466 case '5': autosamplecount=0; samples_per_pass=5; winredraw=1; break;
04467 case '6': autosamplecount=0; samples_per_pass=6; winredraw=1; break;
04468 case '7': autosamplecount=0; samples_per_pass=7; winredraw=1; break;
04469 case '8': autosamplecount=0; samples_per_pass=8; winredraw=1; break;
04470 case '9': autosamplecount=0; samples_per_pass=9; winredraw=1; break;
04471 case '0': autosamplecount=0; samples_per_pass=10; winredraw=1; break;
04472
04473 case '=':
04474 vec_copy(scene_gradient, scene_gradient_orig);
04475 cam_zoom = cam_zoom_orig;
04476 vec_copy(cam_pos, cam_pos_orig);
04477 vec_copy(cam_U, cam_U_orig);
04478 vec_copy(cam_V, cam_V_orig);
04479 vec_copy(cam_W, cam_W_orig);
04480
04481
04482 for (i=0; i<directional_lights.num(); i++) {
04483 vec_copy((float*)&cur_dlights[i].dir, directional_lights[i].dir);
04484 vec_normalize((float*)&cur_dlights[i].dir);
04485 }
04486 winredraw = 1;
04487 break;
04488
04489 case 'q':
04490 case 'Q':
04491 printf("\nOptiXRenderer) Exiting on user input. \n");
04492 done=1;
04493 break;
04494 }
04495 }
04496 break;
04497
04498 case DisplayDevice::WIN_KBD_ESCAPE:
04499 printf("\nOptiXRenderer) Exiting on user input. \n");
04500 done=1;
04501 break;
04502
04503 case DisplayDevice::WIN_KBD_F1:
04504 #if defined(USE_REVERSE_SHADOW_RAYS) && defined(USE_REVERSE_SHADOW_RAYS_DEFAULT)
04505 gl_shadows_on=(!gl_shadows_on) ? RT_SHADOWS_ON_REVERSE : RT_SHADOWS_OFF;
04506 #else
04507 gl_shadows_on=(!gl_shadows_on) ? RT_SHADOWS_ON : RT_SHADOWS_OFF;
04508
04509 #endif
04510
04511 printf("\n");
04512 #if defined(USE_REVERSE_SHADOW_RAYS) && defined(USE_REVERSE_SHADOW_RAYS_DEFAULT)
04513 printf("OptiXRenderer) Shadows %s\n",
04514 (gl_shadows_on) ? "enabled (reversal opt.)" : "disabled");
04515 #else
04516 printf("OptiXRenderer) Shadows %s\n",
04517 (gl_shadows_on) ? "enabled" : "disabled");
04518 #endif
04519 winredraw = 1;
04520 break;
04521
04522 case DisplayDevice::WIN_KBD_F2:
04523 gl_ao_on = (!gl_ao_on);
04524 printf("\n");
04525 printf("OptiXRenderer) Ambient occlusion %s\n",
04526 (gl_ao_on) ? "enabled" : "disabled");
04527 winredraw = 1;
04528 break;
04529
04530 case DisplayDevice::WIN_KBD_F3:
04531 gl_dof_on = (!gl_dof_on);
04532 printf("\n");
04533 printf("OptiXRenderer) Depth-of-field %s\n",
04534 (gl_dof_on) ? "enabled" : "disabled");
04535 winredraw = 1;
04536 break;
04537 }
04538 }
04539 break;
04540
04541 case VideoStream::VS_EV_NONE:
04542 default:
04543
04544 break;
04545 }
04546 }
04547 }
04548 #endif
04549
04550
04551 vec_copy(hmd_U, cam_U);
04552 vec_copy(hmd_V, cam_V);
04553 vec_copy(hmd_W, cam_W);
04554
04555
04556
04557
04558
04559 int resize_buffers=0;
04560
04561 {
04562
04563 if (wsx != width) {
04564 width = wsx;
04565 resize_buffers=1;
04566 }
04567
04568 if (wsy != height || (stereoon != stereoon_old)) {
04569 if (stereoon) {
04570 if (height != wsy * 2) {
04571 height = wsy * 2;
04572 resize_buffers=1;
04573 }
04574 } else {
04575 height = wsy;
04576 resize_buffers=1;
04577 }
04578 }
04579 }
04580
04581
04582
04583
04584 #if defined(VMDOPTIX_PROGRESSIVEAPI) && OPTIX_VERSION < 3080
04585
04586
04587
04588
04589
04590 if (done || winredraw || resize_buffers ||
04591 (stereoon != stereoon_old) || (gl_dof_on != gl_dof_on_old)) {
04592
04593 if (vcarunning) {
04594 rtContextStopProgressive(ctx);
04595 vcarunning=0;
04596 }
04597 }
04598 #endif
04599
04600
04601
04602 if ((stereoon != stereoon_old) || (gl_dof_on != gl_dof_on_old)) {
04603
04604
04605 if (stereoon != stereoon_old) {
04606 resize_buffers=1;
04607 }
04608
04609
04610 stereoon_old = stereoon;
04611 gl_dof_on_old = gl_dof_on;
04612
04613
04614
04615
04616 set_accum_raygen_pgm(camera_projection, stereoon, gl_dof_on);
04617 }
04618
04619 if (resize_buffers) {
04620 framebuffer_resize(width, height);
04621
04622
04623
04624
04625 if (movie_recording_enabled) {
04626 printf("\rOptiXRenderer) Window resize: %d x %d \n", width, height);
04627 }
04628
04629 winredraw=1;
04630 }
04631
04632 int frame_ready = 1;
04633 unsigned int subframe_count = 1;
04634 if (!done) {
04635
04636
04637
04638
04639
04640 if (winredraw) {
04641
04642 RTERR( rtVariableSet1f( cam_zoom_v, cam_zoom) );
04643 RTERR( rtVariableSet3fv( cam_pos_v, cam_pos) );
04644 RTERR( rtVariableSet3fv( cam_U_v, hmd_U) );
04645 RTERR( rtVariableSet3fv( cam_V_v, hmd_V) );
04646 RTERR( rtVariableSet3fv( cam_W_v, hmd_W) );
04647 RTERR( rtVariableSet3fv(scene_gradient_v, scene_gradient) );
04648
04649
04650 RTERR( rtVariableSet1i(shadows_enabled_v, gl_shadows_on) );
04651
04652
04653 RTERR( rtVariableSet1i(fog_mode_v,
04654 (int) (gl_fog_on) ? fog_mode : RT_FOG_NONE) );
04655
04656
04657 RTERR( rtVariableSet1i(clipview_mode_v,
04658 (int) (gl_clip_on) ? clipview_mode : RT_CLIP_NONE) );
04659
04660
04661 RTERR( rtVariableSet1i(headlight_mode_v,
04662 (int) (gl_headlight_on) ? RT_HEADLIGHT_ON : RT_HEADLIGHT_OFF) );
04663
04664
04665 RTERR( rtVariableSet1f(cam_dof_focal_dist_v, cam_dof_focal_dist) );
04666 RTERR( rtVariableSet1f(cam_dof_aperture_rad_v, cam_dof_focal_dist / (2.0f * cam_zoom * cam_dof_fnumber)) );
04667
04668
04669
04670
04671
04672
04673
04674
04675
04676
04677 if (xformlights) {
04678 #if defined(VMDOPTIX_LIGHTUSEROBJS)
04679 DirectionalLightList dlights;
04680 memset(&dlights, 0, sizeof(DirectionalLightList) );
04681 dlights.num_lights = directional_lights.num();
04682 int dlcount = directional_lights.num();
04683 dlcount = (dlcount > DISP_LIGHTS) ? DISP_LIGHTS : dlcount;
04684 for (i=0; i<dlcount; i++) {
04685
04686 dlights.dirs[i] = cur_dlights[i].dir;
04687 }
04688 RTERR( rtVariableSetUserData(dir_light_list_v, sizeof(DirectionalLightList), &dlights) );
04689 #else
04690 DirectionalLight *dlbuf;
04691 RTERR( rtBufferMap(dir_lightbuffer, (void **) &dlbuf) );
04692 for (i=0; i<directional_lights.num(); i++) {
04693 vec_copy((float*)&dlbuf[i].dir, (float*)&cur_dlights[i].dir);
04694 }
04695 RTERR( rtBufferUnmap(dir_lightbuffer) );
04696 #endif
04697 }
04698
04699
04700 totalsamplecount=0;
04701
04702
04703
04704
04705
04706
04707
04708
04709
04710
04711 if (autosamplecount) {
04712 if (fpsexpave > 37)
04713 samples_per_pass++;
04714 else if (fpsexpave < 30)
04715 samples_per_pass--;
04716
04717
04718 if (samples_per_pass > 14)
04719 samples_per_pass=14;
04720 if (samples_per_pass < 1)
04721 samples_per_pass=1;
04722 }
04723
04724
04725
04726 if (force_ao_1) {
04727 cur_aa_samples = samples_per_pass;
04728 cur_ao_samples = 1;
04729 } else if (gl_shadows_on && gl_ao_on) {
04730 if (gl_dof_on) {
04731 if (samples_per_pass < 4) {
04732 cur_aa_samples=samples_per_pass;
04733 cur_ao_samples=1;
04734 } else {
04735 int s = (int) sqrtf(samples_per_pass);
04736 cur_aa_samples=s;
04737 cur_ao_samples=s;
04738 }
04739 } else {
04740 cur_aa_samples=1;
04741 cur_ao_samples=samples_per_pass;
04742 }
04743 } else {
04744 cur_aa_samples=samples_per_pass;
04745 cur_ao_samples=0;
04746 }
04747
04748
04749
04750 RTERR( rtVariableSet1i(aa_samples_v, cur_aa_samples) );
04751
04752
04753 if (gl_shadows_on && gl_ao_on) {
04754 RTERR( rtVariableSet1i(ao_samples_v, cur_ao_samples) );
04755 } else {
04756 cur_ao_samples = 0;
04757 RTERR( rtVariableSet1i(ao_samples_v, 0) );
04758 }
04759
04760 #ifdef VMDOPTIX_PROGRESSIVEAPI
04761 RTERR( rtVariableSet1f(accum_norm_v, 1.0f / float(cur_aa_samples)) );
04762 #endif
04763
04764
04765
04766
04767
04768 }
04769
04770
04771
04772
04773
04774
04775
04776
04777
04778 #ifndef VMDOPTIX_PROGRESSIVEAPI
04779
04780
04781
04782 RTERR( rtVariableSet1f(accum_norm_v, 1.0f / float(cur_aa_samples + accum_count)) );
04783
04784
04785
04786 RTERR( rtVariableSet1ui(accum_count_v, accum_count) );
04787
04788
04789
04790
04791
04792
04793 #endif
04794
04795
04796
04797
04798
04799 frame_ready = 1;
04800 subframe_count = 1;
04801 if (lasterror == RT_SUCCESS) {
04802 if (winredraw) {
04803 #if defined(ORT_RAYSTATS)
04804 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_CLEAR_RAYSTATS, width, height) );
04805 accumbufstarttime=wkf_timer_timenow(ort_timer);
04806 #endif
04807 #ifdef VMDOPTIX_PROGRESSIVEAPI
04808
04809 RTERR( rtContextLaunchProgressive2D(ctx, RT_RAY_GEN_ACCUMULATE, width, height, 0) );
04810 #else
04811 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_CLEAR_ACCUMULATION_BUFFER, width, height) );
04812 #endif
04813 winredraw=0;
04814 }
04815
04816 #ifdef VMDOPTIX_PROGRESSIVEAPI
04817
04818 RTERR( rtBufferGetProgressiveUpdateReady(framebuffer, &frame_ready, &subframe_count, 0) );
04819 if (frame_ready)
04820 totalsamplecount = subframe_count * samples_per_pass;
04821 #else
04822
04823 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_ACCUMULATE, width, height) );
04824 subframe_count++;
04825 totalsamplecount += samples_per_pass;
04826 accum_count += cur_aa_samples;
04827
04828
04829
04830 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_COPY_FINISH, width, height) );
04831 #endif
04832
04833 if (lasterror == RT_SUCCESS) {
04834 if (frame_ready) {
04835
04836 const unsigned char * img;
04837 rtBufferMap(framebuffer, (void **) &img);
04838
04839 #if 1
04840
04841
04842 if (app->uivs && app->uivs->srv_connected()) {
04843 app->uivs->video_frame_pending(img, width, height);
04844 app->uivs->check_event();
04845 }
04846 #endif
04847
04848 rtBufferUnmap(framebuffer);
04849
04850
04851
04852
04853
04854 if (movie_recording_enabled && movie_recording_on) {
04855 char moviefilename[2048];
04856
04857
04858
04859 double now = wkf_timer_timenow(ort_timer);
04860 double frametime = now - movie_recording_start_time;
04861 int fidx = frametime * movie_recording_fps;
04862
04863
04864 if (movie_framecount==0)
04865 fidx=0;
04866 movie_framecount++;
04867
04868 #if defined(__linux)
04869
04870
04871
04872
04873 sprintf(moviefilename, movie_recording_filebase,
04874 movie_lastframeindex);
04875 int symidx;
04876 for (symidx=movie_lastframeindex; symidx<fidx; symidx++) {
04877 char symlinkfilename[2048];
04878 sprintf(symlinkfilename, movie_recording_filebase, symidx);
04879 if (symlink(moviefilename, symlinkfilename) < 0)
04880 perror("symlink: ");
04881 }
04882 #endif
04883
04884
04885 sprintf(moviefilename, movie_recording_filebase, fidx);
04886 if (OptiXWriteImage(moviefilename, writealpha, framebuffer,
04887 RT_FORMAT_UNSIGNED_BYTE4, width, height) == -1) {
04888 movie_recording_on = 0;
04889 printf("\n");
04890 printf("OptiXRenderer) ERROR during writing image during movie recording!\n");
04891 printf("OptiXRenderer) Movie recording STOPPED\n");
04892 }
04893
04894 movie_lastframeindex = fidx;
04895 }
04896 }
04897 } else {
04898 printf("OptiXRenderer) An error occured during rendering. Rendering is aborted.\n");
04899 done=1;
04900 break;
04901 }
04902 } else {
04903 printf("OptiXRenderer) An error occured in AS generation. Rendering is aborted.\n");
04904 done=1;
04905 break;
04906 }
04907 }
04908
04909 if (!done && frame_ready) {
04910 double newtime = wkf_timer_timenow(ort_timer);
04911 double frametime = (newtime-oldtime) + 0.00001f;
04912 oldtime=newtime;
04913
04914
04915 double framefps = 1.0f/frametime;
04916 fpsexpave = (fpsexpave * 0.90) + (framefps * 0.10);
04917
04918 printf("OptiXRenderer) %c AA:%2d AO:%2d, %4d tot RT FPS: %.1f %.4f s/frame sf: %d \r",
04919 statestr[state], cur_aa_samples, cur_ao_samples,
04920 totalsamplecount, fpsexpave, frametime, subframe_count);
04921
04922 fflush(stdout);
04923 state = (state+1) & 3;
04924 }
04925
04926 }
04927
04928 printf("\n");
04929
04930
04931 if (lasterror == RT_SUCCESS) {
04932 #if defined(ORT_RAYSTATS)
04933 double frametime = wkf_timer_timenow(ort_timer) - accumbufstarttime;
04934 OptiXPrintRayStats(raystats1_buffer, raystats2_buffer, frametime);
04935 #endif
04936
04937 wkf_timer_start(ort_timer);
04938 OptiXWriteImage(filename, writealpha, framebuffer);
04939 wkf_timer_stop(ort_timer);
04940
04941 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
04942 printf("OptiXRenderer) image file I/O time: %f secs\n", wkf_timer_time(ort_timer));
04943 }
04944 }
04945 }
04946
04947
04948 void OptiXRenderer::render_to_file(const char *filename, int writealpha) {
04949 if (!context_created)
04950 return;
04951
04952
04953
04954 int wsx=width, wsy=height;
04955 const char *imageszstr = getenv("VMDOPTIXIMAGESIZE");
04956 if (imageszstr) {
04957 if (sscanf(imageszstr, "%d %d", &width, &height) != 2) {
04958 width=wsx;
04959 height=wsy;
04960 }
04961 }
04962
04963
04964 framebuffer_config(width, height, 0);
04965
04966 update_rendering_state(0);
04967 render_compile_and_validate();
04968 double starttime = wkf_timer_timenow(ort_timer);
04969
04970
04971
04972
04973 if (lasterror == RT_SUCCESS) {
04974 #if defined(ORT_RAYSTATS)
04975 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_CLEAR_RAYSTATS, width, height) );
04976 #endif
04977
04978 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_CLEAR_ACCUMULATION_BUFFER, width, height) );
04979
04980
04981 if (getenv("VMDOPTIXNORENDER") == NULL) {
04982 int accum_sample;
04983 for (accum_sample=0; accum_sample<ext_aa_loops; accum_sample++) {
04984
04985
04986 RTERR( rtVariableSet1ui(accum_count_v, accum_sample) );
04987
04988 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_ACCUMULATE, width, height) );
04989 }
04990 }
04991
04992
04993
04994 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_COPY_FINISH, width, height) );
04995 double rtendtime = wkf_timer_timenow(ort_timer);
04996 time_ray_tracing = rtendtime - starttime;
04997
04998 if (lasterror == RT_SUCCESS) {
04999
05000 if (getenv("VMDOPTIXNOSAVE") == NULL) {
05001 OptiXWriteImage(filename, writealpha, framebuffer);
05002 }
05003 #if defined(ORT_RAYSTATS)
05004 OptiXPrintRayStats(raystats1_buffer, raystats2_buffer, time_ray_tracing);
05005 #endif
05006 time_image_io = wkf_timer_timenow(ort_timer) - rtendtime;
05007 } else {
05008 printf("OptiXRenderer) Error during rendering. Rendering aborted.\n");
05009 }
05010
05011 if (verbose == RT_VERB_TIMING || verbose == RT_VERB_DEBUG) {
05012 printf("OptiXRenderer) 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);
05013 }
05014 } else {
05015 printf("OptiXRenderer) Error during AS generation. Rendering aborted.\n");
05016 }
05017 }
05018
05019
05020 #if defined(VMDOPTIXRTRT)
05021
05022 void OptiXRenderer::add_material_cmdlist(const VMDDisplayList *cmdList) {
05023 add_material(cmdList->materialtag,
05024 cmdList->ambient,
05025 cmdList->diffuse,
05026 cmdList->specular,
05027 cmdList->shininess,
05028 cmdList->mirror,
05029 cmdList->opacity,
05030 cmdList->outline,
05031 cmdList->outlinewidth,
05032 cmdList->transmode);
05033 }
05034
05035
05036 void OptiXRenderer::scene_aggregate_cmdlist(const VMDDisplayList *cmdList,
05037 const float *colorData) {
05038
05039
05040 char *cmdptr = NULL;
05041 int tok;
05042
05043
05044 if (!cmdList)
05045 return;
05046
05047 Stack<Matrix4> transMat(10);
05048 Matrix4 m;
05049 transMat.push(m);
05050 (transMat.top()).multmatrix(cmdList->mat);
05051
05052
05053
05054
05055
05056 #if 0
05057
05058 for (int cp=0; cp<VMD_MAX_CLIP_PLANE; cp++) {
05059
05060
05061 if (cmdList->clipplanes[cp].mode) {
05062 }
05063 }
05064 #endif
05065
05066 #if 0
05067
05068 ResizeArray<Matrix4> pbcImages;
05069 find_pbc_images(cmdList, pbcImages);
05070 int npbcimages = pbcImages.num();
05071
05072
05073 ResizeArray<Matrix4> instanceImages;
05074 find_instance_images(cmdList, instanceImages);
05075 int ninstances = instanceImages.num();
05076
05077 for (int pbcimage = 0; pbcimage < npbcimages; pbcimage++) {
05078 transMat.dup();
05079 (transMat.top()).multmatrix(pbcImages[pbcimage]);
05080 for (int instanceimage = 0; instanceimage < ninstances; instanceimage++) {
05081 transMat.dup();
05082 (transMat.top()).multmatrix(instanceImages[instanceimage]);
05083 }
05084 }
05085 #endif
05086
05087 #if 0
05088
05089 if (ogl_cacheenabled && !ogl_cacheskip) {
05090 ogl_cachedid = displaylistcache.markUsed(cmdList->serial);
05091
05092
05093 if (ogl_cachedid == GLCACHE_FAIL) {
05094 ogl_cachedid = glGenLists(1);
05095 displaylistcache.encache(cmdList->serial, ogl_cachedid);
05096
05097
05098 glNewList(ogl_cachedid, GL_COMPILE_AND_EXECUTE);
05099 ogl_cachecreated = 1;
05100 }
05101 }
05102
05103
05104
05105 if ((!ogl_cacheenabled) || ogl_cacheskip || (ogl_cacheenabled && ogl_cachecreated)) {
05106 #endif
05107
05108
05109
05110
05111 int colorIndex = 0;
05112 VMDDisplayList::VMDLinkIter cmditer;
05113 cmdList->first(&cmditer);
05114 while((tok = cmdList->next(&cmditer, cmdptr)) != DLASTCOMMAND) {
05115 switch (tok) {
05116 case DCOLORINDEX:
05117 colorIndex = (((DispCmdColorIndex *)cmdptr)->color);
05118 break;
05119
05120 case DCYLINDER:
05121 {
05122 add_material_cmdlist(cmdList);
05123
05124
05125
05126 float points[6], radii[1], colors[3];
05127 memcpy(points, (float *)cmdptr, 3L*sizeof(float));
05128 memcpy(&points[3], ((float *)cmdptr) + 3, 3L*sizeof(float));
05129 radii[0] = ((float *)cmdptr)[6];
05130 int filled = ((int) ((float *) cmdptr)[8]);
05131 memcpy(colors, &colorData[colorIndex*3L], 3L*sizeof(float));
05132
05133 float *mat = &transMat.top().mat[0];
05134 float scaleFactor =
05135 (sqrtf(mat[0]*mat[0] + mat[4]*mat[4] + mat[ 8]*mat[ 8]) +
05136 sqrtf(mat[1]*mat[1] + mat[5]*mat[5] + mat[ 9]*mat[ 9]) +
05137 sqrtf(mat[2]*mat[2] + mat[6]*mat[6] + mat[10]*mat[10])) / 3.0f;
05138
05139
05140 cylinder_array_color(&transMat.top(), scaleFactor,
05141 1, points, radii, colors,
05142 cmdList->materialtag);
05143
05144
05145
05146 }
05147 break;
05148
05149 case DCYLINDERARRAY:
05150 {
05151 add_material_cmdlist(cmdList);
05152
05153 DispCmdCylinderArray *ca = (DispCmdCylinderArray *)cmdptr;
05154 float *points, *radii, *colors;
05155 ca->getpointers(points, radii, colors);
05156
05157 float *mat = &transMat.top().mat[0];
05158 float scaleFactor =
05159 (sqrtf(mat[0]*mat[0] + mat[4]*mat[4] + mat[ 8]*mat[ 8]) +
05160 sqrtf(mat[1]*mat[1] + mat[5]*mat[5] + mat[ 9]*mat[ 9]) +
05161 sqrtf(mat[2]*mat[2] + mat[6]*mat[6] + mat[10]*mat[10])) / 3.0f;
05162
05163
05164 cylinder_array_color(&transMat.top(), scaleFactor,
05165 ca->numcylinders, points, radii, colors,
05166 cmdList->materialtag);
05167 }
05168 break;
05169
05170 case DSPHERE:
05171 {
05172 add_material_cmdlist(cmdList);
05173
05174
05175
05176 float centers[3], radii[1], color[3];
05177 memcpy(centers, (float *)cmdptr, 3L*sizeof(float));
05178 radii[0] = ((float *)cmdptr)[3];
05179
05180 float *mat = &transMat.top().mat[0];
05181 float scaleFactor =
05182 (sqrtf(mat[0]*mat[0] + mat[4]*mat[4] + mat[ 8]*mat[ 8]) +
05183 sqrtf(mat[1]*mat[1] + mat[5]*mat[5] + mat[ 9]*mat[ 9]) +
05184 sqrtf(mat[2]*mat[2] + mat[6]*mat[6] + mat[10]*mat[10])) / 3.0f;
05185
05186
05187 sphere_array_color(transMat.top(), scaleFactor,
05188 1, centers, radii, &colorData[colorIndex*3L],
05189 cmdList->materialtag);
05190 }
05191 break;
05192
05193 case DSPHEREARRAY:
05194 {
05195 add_material_cmdlist(cmdList);
05196
05197 DispCmdSphereArray *sa = (DispCmdSphereArray *)cmdptr;
05198 float *centers, *radii, *colors;
05199 sa->getpointers(centers, radii, colors);
05200
05201 float *mat = &transMat.top().mat[0];
05202 float scaleFactor =
05203 (sqrtf(mat[0]*mat[0] + mat[4]*mat[4] + mat[ 8]*mat[ 8]) +
05204 sqrtf(mat[1]*mat[1] + mat[5]*mat[5] + mat[ 9]*mat[ 9]) +
05205 sqrtf(mat[2]*mat[2] + mat[6]*mat[6] + mat[10]*mat[10])) / 3.0f;
05206
05207
05208 sphere_array_color(transMat.top(), scaleFactor,
05209 sa->numspheres, centers, radii, colors,
05210 cmdList->materialtag);
05211 }
05212 break;
05213
05214 case DTRIMESH_C3F_N3F_V3F:
05215 {
05216 add_material_cmdlist(cmdList);
05217
05218 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
05219 float *c=NULL, *n=NULL, *v=NULL;
05220
05221 if (cmd->pervertexcolors) {
05222 cmd->getpointers(c, n, v);
05223 #if 1
05224 printf("Dropped trimesh_c3f_n3f_v3f()\n");
05225 #else
05226
05227 trimesh_c3f_n3f_v3f(transMat.top(), c, n, v, cmd->numfacets,
05228 cmdList->materialtag);
05229 #endif
05230 } else if (cmd->pervertexnormals) {
05231 cmd->getpointers(n, v);
05232 trimesh_n3f_v3f(transMat.top(), &colorData[colorIndex * 3],
05233 n, v, cmd->numfacets, cmdList->materialtag);
05234 } else {
05235 cmd->getpointers(n, v);
05236 trimesh_v3f(transMat.top(), &colorData[colorIndex * 3],
05237 v, cmd->numfacets, cmdList->materialtag);
05238 }
05239 }
05240 break;
05241
05242 case DTRIMESH_C4F_N3F_V3F:
05243 {
05244 add_material_cmdlist(cmdList);
05245
05246
05247 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
05248 int ind = cmd->numfacets * 3;
05249 float *cnv;
05250 int *f;
05251 cmd->getpointers(cnv, f);
05252 trimesh_c4n3v3(transMat.top(), cmd->numverts, cnv, cmd->numfacets, f,
05253 cmdList->materialtag);
05254 }
05255 break;
05256
05257 case DTRIMESH_C4U_N3B_V3F:
05258 {
05259 add_material_cmdlist(cmdList);
05260
05261 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
05262 unsigned char *c=NULL;
05263 signed char *n=NULL;
05264 float *v=NULL;
05265
05266 if (cmd->pervertexcolors) {
05267 cmd->getpointers(c, n, v);
05268 trimesh_c4u_n3b_v3f(transMat.top(), c, n, v, cmd->numfacets,
05269 cmdList->materialtag);
05270 } else {
05271 cmd->getpointers(n, v);
05272 trimesh_n3b_v3f(transMat.top(), &colorData[colorIndex * 3],
05273 n, v, cmd->numfacets, cmdList->materialtag);
05274 }
05275 }
05276 break;
05277
05278 case DTRISTRIP:
05279 {
05280 add_material_cmdlist(cmdList);
05281
05282 DispCmdTriStrips *cmd = (DispCmdTriStrips *) cmdptr;
05283 float *cnv=NULL;
05284 int *f=NULL;
05285 int *vertsperstrip;
05286 cmd->getpointers(cnv, f, vertsperstrip);
05287 tristrip(transMat.top(), cmd->numverts, cnv, cmd->numstrips,
05288 vertsperstrip, f, cmdList->materialtag);
05289 }
05290 break;
05291
05292
05293 #if 0
05294 default:
05295
05296
05297 break;
05298 #endif
05299 }
05300 }
05301 }
05302
05303
05305 void OptiXRenderer::scene_aggregation_complete() {
05306 update_rendering_state(0);
05307 render_compile_and_validate();
05308 }
05309
05310
05311
05312 void OptiXRenderer::render_current_scene() {
05313 if (lasterror == RT_SUCCESS) {
05314
05315 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_CLEAR_ACCUMULATION_BUFFER, width, height) );
05316
05317
05318 if (getenv("VMDOPTIXNORENDER") == NULL) {
05319 int accum_sample;
05320 for (accum_sample=0; accum_sample<ext_aa_loops; accum_sample++) {
05321
05322
05323 RTERR( rtVariableSet1ui(accum_count_v, accum_sample) );
05324 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_ACCUMULATE, width, height) );
05325 }
05326 }
05327
05328
05329
05330 RTERR( rtContextLaunch2D(ctx, RT_RAY_GEN_COPY_FINISH, width, height) );
05331 }
05332 }
05333
05334 #endif
05335
05336
05337 void OptiXRenderer::destroy_context() {
05338 if (!context_created)
05339 return;
05340
05341 #ifdef VMDOPTIX_PROGRESSIVEAPI
05342
05343 rtContextStopProgressive(ctx);
05344 #endif
05345
05346 framebuffer_destroy();
05347
05348 if ((lasterror = rtContextDestroy(ctx)) != RT_SUCCESS) {
05349 msgErr << "OptiXRenderer) An error occured while destroying the OptiX context" << sendmsg;
05350 }
05351 }
05352
05353
05354 void OptiXRenderer::add_material(int matindex,
05355 float ambient, float diffuse, float specular,
05356 float shininess, float reflectivity,
05357 float opacity,
05358 float outline, float outlinewidth,
05359 int transmode) {
05360 int oldmatcount = materialcache.num();
05361 if (oldmatcount <= matindex) {
05362 ort_material m;
05363 memset(&m, 0, sizeof(m));
05364
05365
05366 m.ambient = 0.5f;
05367 m.diffuse = 0.7f;
05368 m.specular = 0.0f;
05369 m.shininess = 10.0f;
05370 m.reflectivity = 0.0f;
05371 m.opacity = 1.0f;
05372 m.transmode = 0;
05373
05374 materialcache.appendN(m, matindex - oldmatcount + 1);
05375 }
05376
05377 if (materialcache[matindex].isvalid) {
05378 return;
05379 } else {
05380 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) Adding material[%d]\n", matindex);
05381
05382 materialcache[matindex].ambient = ambient;
05383 materialcache[matindex].diffuse = diffuse;
05384 materialcache[matindex].specular = specular;
05385 materialcache[matindex].shininess = shininess;
05386 materialcache[matindex].reflectivity = reflectivity;
05387 materialcache[matindex].opacity = opacity;
05388 materialcache[matindex].outline = outline;
05389 materialcache[matindex].outlinewidth = outlinewidth;
05390 materialcache[matindex].transmode = transmode;
05391 materialcache[matindex].isvalid = 1;
05392 }
05393 }
05394
05395
05396 void OptiXRenderer::init_materials() {
05397 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) init_materials()\n");
05398
05399
05400 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "closest_hit_radiance_general", &closest_hit_pgm_general) );
05401 #if defined(ORT_USERTXAPIS)
05402
05403 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "closest_hit_radiance_general_hwtri", &closest_hit_pgm_general_hwtri) );
05404 #endif
05405
05406 #if defined(ORT_USE_TEMPLATE_SHADERS)
05407
05408
05409 int i;
05410 for (i=0; i<ORTMTABSZ; i++) {
05411 char ch_program_name[256];
05412 snprintf(ch_program_name, sizeof(ch_program_name),
05413 "closest_hit_radiance_"
05414 "CLIP_VIEW_%s_"
05415 "HEADLIGHT_%s_"
05416 "FOG_%s_"
05417 "SHADOWS_%s_"
05418 "AO_%s_"
05419 "OUTLINE_%s_"
05420 "REFL_%s_"
05421 "TRANS_%s",
05422 #if defined(VMDOPTIX_VCA_TABSZHACK)
05423 onoffstr(1),
05424 onoffstr(1),
05425 #else
05426 onoffstr(i & 128),
05427 onoffstr(i & 64),
05428 #endif
05429 onoffstr(i & 32),
05430 onoffstr(i & 16),
05431 onoffstr(i & 8),
05432 onoffstr(i & 4),
05433 onoffstr(i & 2),
05434 onoffstr(i & 1));
05435
05436 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, ch_program_name, &closest_hit_pgm_special[i] ) );
05437
05438 #if defined(ORT_USERTXAPIS)
05439 #error OptiX RTX triangle API not implemented for template shader expansion
05440 #endif
05441
05442 }
05443 #endif
05444
05445 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "any_hit_opaque", &any_hit_pgm_opaque) );
05446 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "any_hit_transmission", &any_hit_pgm_transmission) );
05447 RTERR( rtProgramCreateFromPTXFile(ctx, shaderpath, "any_hit_clip_sphere", &any_hit_pgm_clip_sphere) );
05448
05449 RTERR( rtMaterialCreate(ctx, &material_general) );
05450 RTERR( rtMaterialSetClosestHitProgram(material_general, RT_RAY_TYPE_RADIANCE, closest_hit_pgm_general) );
05451 RTERR( rtMaterialSetAnyHitProgram(material_general, RT_RAY_TYPE_SHADOW, any_hit_pgm_clip_sphere) );
05452
05453
05454 #if defined(ORT_USERTXAPIS)
05455 RTERR( rtMaterialCreate(ctx, &material_general_hwtri) );
05456 RTERR( rtMaterialSetClosestHitProgram(material_general_hwtri, RT_RAY_TYPE_RADIANCE, closest_hit_pgm_general_hwtri) );
05457 RTERR( rtMaterialSetAnyHitProgram(material_general_hwtri, RT_RAY_TYPE_SHADOW, any_hit_pgm_clip_sphere) );
05458 #endif
05459
05460
05461 #if defined(ORT_USE_TEMPLATE_SHADERS)
05462
05463 for (i=0; i<ORTMTABSZ; i++) {
05464 RTERR( rtMaterialCreate(ctx, &material_special[i]) );
05465 RTERR( rtMaterialSetClosestHitProgram(material_special[i], RT_RAY_TYPE_RADIANCE, closest_hit_pgm_special[i]) );
05466
05467
05468 if (clipview_mode == RT_CLIP_SPHERE) {
05469 RTERR( rtMaterialSetAnyHitProgram(material_special[i], RT_RAY_TYPE_SHADOW, any_hit_pgm_clip_sphere) );
05470 } else {
05471 if (i & 1) {
05472 RTERR( rtMaterialSetAnyHitProgram(material_special[i], RT_RAY_TYPE_SHADOW, any_hit_pgm_transmission) );
05473 } else {
05474 RTERR( rtMaterialSetAnyHitProgram(material_special[i], RT_RAY_TYPE_SHADOW, any_hit_pgm_opaque) );
05475 }
05476 }
05477
05478 #if defined(ORT_USERTXAPIS)
05479 #error OptiX RTX triangle API not implemented for template shader expansion
05480 #endif
05481
05482
05483 material_special_counts[i] = 0;
05484 }
05485 #endif
05486 }
05487
05488
05489 void OptiXRenderer::set_material(RTgeometryinstance instance, int matindex,
05490 const float *uniform_color, int hwtri) {
05491 if (!context_created)
05492 return;
05493
05494
05495 RTvariable ka, kd, ks, phongexp, krefl;
05496 RTvariable opacity, outline, outlinewidth, transmode, uniform_col;
05497 RTmaterial material = material_general;
05498
05499 #if defined(ORT_USERTXAPIS)
05500
05501 if (hwtri) {
05502 material = material_general_hwtri;
05503 }
05504 #endif
05505
05506 #if defined(ORT_USE_TEMPLATE_SHADERS)
05507 if (getenv("VMDOPTIXFORCEGENERALSHADER") == NULL) {
05508 unsigned int specialized_material_index =
05509 ((clipview_mode != RT_CLIP_NONE) << 7) |
05510 ((headlight_mode != RT_HEADLIGHT_OFF) << 6) |
05511 ((fog_mode != RT_FOG_NONE) << 5) |
05512 ((shadows_enabled != RT_SHADOWS_OFF) << 4) |
05513 ((ao_samples != 0) << 3) |
05514 ((materialcache[matindex].outline != 0) << 2) |
05515 ((materialcache[matindex].reflectivity != 0) << 1) |
05516 ((materialcache[matindex].opacity != 1) );
05517
05518 #if defined(VMDOPTIX_VCA_TABSZHACK)
05519
05520
05521 if (specialized_material_index >= ORTMTABSZ) {
05522 specialized_material_index &= (ORTMTABSZ - 1);
05523 }
05524 #endif
05525
05526 material = material_special[specialized_material_index];
05527
05528
05529 material_special_counts[specialized_material_index]++;
05530 }
05531 #endif
05532
05533 RTERR( rtGeometryInstanceSetMaterialCount(instance, 1) );
05534 RTERR( rtGeometryInstanceSetMaterial(instance, 0, material) );
05535
05536 if (uniform_color != NULL) {
05537 RTERR( rtGeometryInstanceDeclareVariable(instance, "uniform_color", &uniform_col) );
05538 RTERR( rtVariableSet3fv(uniform_col, uniform_color) );
05539 }
05540
05541 RTERR( rtGeometryInstanceDeclareVariable(instance, "Ka", &ka) );
05542 RTERR( rtGeometryInstanceDeclareVariable(instance, "Kd", &kd) );
05543 RTERR( rtGeometryInstanceDeclareVariable(instance, "Ks", &ks) );
05544 RTERR( rtGeometryInstanceDeclareVariable(instance, "phong_exp", &phongexp) );
05545 RTERR( rtGeometryInstanceDeclareVariable(instance, "Krefl", &krefl) );
05546 RTERR( rtGeometryInstanceDeclareVariable(instance, "opacity", &opacity) );
05547 RTERR( rtGeometryInstanceDeclareVariable(instance, "outline", &outline) );
05548 RTERR( rtGeometryInstanceDeclareVariable(instance, "outlinewidth", &outlinewidth) );
05549 RTERR( rtGeometryInstanceDeclareVariable(instance, "transmode", &transmode) );
05550
05551 RTERR( rtVariableSet1f(ka, materialcache[matindex].ambient) );
05552 RTERR( rtVariableSet1f(kd, materialcache[matindex].diffuse) );
05553 RTERR( rtVariableSet1f(ks, materialcache[matindex].specular) );
05554 RTERR( rtVariableSet1f(phongexp, materialcache[matindex].shininess) );
05555 RTERR( rtVariableSet1f(krefl, materialcache[matindex].reflectivity) );
05556 RTERR( rtVariableSet1f(opacity, materialcache[matindex].opacity) );
05557 RTERR( rtVariableSet1f(outline, materialcache[matindex].outline) );
05558 RTERR( rtVariableSet1f(outlinewidth, materialcache[matindex].outlinewidth) );
05559 RTERR( rtVariableSet1i(transmode, materialcache[matindex].transmode) );
05560 }
05561
05562
05563 void OptiXRenderer::add_directional_light(const float *dir, const float *color) {
05564 ort_directional_light l;
05565 vec_copy(l.dir, dir);
05566 vec_copy(l.color, color);
05567
05568 directional_lights.append(l);
05569 }
05570
05571
05572 void OptiXRenderer::add_positional_light(const float *pos, const float *color) {
05573 ort_positional_light l;
05574 vec_copy(l.pos, pos);
05575 vec_copy(l.color, color);
05576
05577 positional_lights.append(l);
05578 }
05579
05580
05583 float OptiXRenderer::calc_matrix_scale_factor(const float *mat) {
05584 float scaleFactor =
05585 (sqrtf(mat[0]*mat[0] + mat[4]*mat[4] + mat[ 8]*mat[ 8]) +
05586 sqrtf(mat[1]*mat[1] + mat[5]*mat[5] + mat[ 9]*mat[ 9]) +
05587 sqrtf(mat[2]*mat[2] + mat[6]*mat[6] + mat[10]*mat[10])) / 3.0f;
05588
05589 return scaleFactor;
05590 }
05591
05592
05593 void OptiXRenderer::cylinder_array(Matrix4 *wtrans, float radius,
05594 const float *uniform_color,
05595 int cylnum, const float *points,
05596 int matindex) {
05597 if (!context_created) return;
05598 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating cylinder array: %d...\n", cylnum);
05599 cylinder_array_cnt += cylnum;
05600
05601 int i, ind;
05602 RTbuffer buf;
05603 RTgeometry geom;
05604 RTgeometryinstance instance;
05605 vmd_cylinder *cyldata;
05606
05607
05608 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
05609 rtBufferSetFormat(buf, RT_FORMAT_USER);
05610 rtBufferSetElementSize(buf, sizeof(vmd_cylinder));
05611 rtBufferSetSize1D(buf, cylnum);
05612
05613 rtBufferMap(buf, (void **) &cyldata);
05614
05615 if (wtrans == NULL) {
05616 for (i=0,ind=0; i<cylnum; i++,ind+=6) {
05617
05618 vec_copy((float*) &cyldata[i].start, &points[ind]);
05619 cyldata[i].radius = radius;
05620 vec_sub((float*) &cyldata[i].axis, &points[ind+3], &points[ind]);
05621 }
05622 } else {
05623 for (i=0,ind=0; i<cylnum; i++,ind+=6) {
05624
05625 wtrans->multpoint3d(&points[ind], (float*) &cyldata[i].start);
05626 cyldata[i].radius = radius;
05627 float ctmp[3];
05628 wtrans->multpoint3d(&points[ind+3], ctmp);
05629 vec_sub((float*) &cyldata[i].axis, ctmp, &points[ind]);
05630 }
05631 }
05632 rtBufferUnmap(buf);
05633
05634 RTERR( rtGeometryCreate(ctx, &geom) );
05635 RTERR( rtGeometrySetPrimitiveCount(geom, cylnum) );
05636 RTERR( rtGeometrySetBoundingBoxProgram(geom, cylinder_array_bbox_pgm) );
05637 RTERR( rtGeometrySetIntersectionProgram(geom, cylinder_array_isct_pgm) );
05638
05639
05640 RTvariable buf_v;
05641 RTERR( rtGeometryDeclareVariable(geom, "cylinder_buffer", &buf_v) );
05642 RTERR( rtVariableSetObject(buf_v, buf) );
05643
05644
05645 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
05646 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
05647
05648 set_material(instance, matindex, uniform_color);
05649
05650 append_objects(buf, geom, instance);
05651 }
05652
05653
05654 void OptiXRenderer::cylinder_array_color(Matrix4 *wtrans, float rscale,
05655 int cylnum, const float *points,
05656 const float *radii,
05657 const float *colors, int matindex) {
05658 if (!context_created) return;
05659 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating cylinder color array: %d...\n", cylnum);
05660 cylinder_array_color_cnt += cylnum;
05661
05662 int i, ind;
05663 RTbuffer buf;
05664 RTgeometry geom;
05665 RTgeometryinstance instance;
05666 vmd_cylinder_color *cyldata;
05667
05668
05669 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
05670 rtBufferSetFormat(buf, RT_FORMAT_USER);
05671 rtBufferSetElementSize(buf, sizeof(vmd_cylinder_color));
05672 rtBufferSetSize1D(buf, cylnum);
05673
05674 rtBufferMap(buf, (void **) &cyldata);
05675
05676 if (wtrans == NULL) {
05677
05678 if (radii == NULL) {
05679 for (i=0,ind=0; i<cylnum; i++,ind+=6) {
05680 vec_copy((float*) &cyldata[i].start, &points[ind]);
05681 cyldata[i].radius = rscale;
05682 vec_sub((float*) &cyldata[i].axis, &points[ind+3], &points[ind]);
05683 vec_copy((float*) &cyldata[i].color, &colors[i*3]);
05684 }
05685 } else {
05686 for (i=0,ind=0; i<cylnum; i++,ind+=6) {
05687 vec_copy((float*) &cyldata[i].start, &points[ind]);
05688 cyldata[i].radius = rscale * radii[i];
05689 vec_sub((float*) &cyldata[i].axis, &points[ind+3], &points[ind]);
05690 vec_copy((float*) &cyldata[i].color, &colors[i*3]);
05691 }
05692 }
05693 } else {
05694
05695 if (radii == NULL) {
05696 for (i=0,ind=0; i<cylnum; i++,ind+=6) {
05697 wtrans->multpoint3d(&points[ind], (float*) &cyldata[i].start);
05698 cyldata[i].radius = rscale;
05699 float ctmp[3];
05700 wtrans->multpoint3d(&points[ind+3], ctmp);
05701 vec_sub((float*) &cyldata[i].axis, ctmp, (float*) &cyldata[i].start);
05702 vec_copy((float*) &cyldata[i].color, &colors[i*3]);
05703 }
05704 } else {
05705 for (i=0,ind=0; i<cylnum; i++,ind+=6) {
05706 wtrans->multpoint3d(&points[ind], (float*) &cyldata[i].start);
05707 cyldata[i].radius = rscale * radii[i];
05708 float ctmp[3];
05709 wtrans->multpoint3d(&points[ind+3], ctmp);
05710 vec_sub((float*) &cyldata[i].axis, ctmp, (float*) &cyldata[i].start);
05711 vec_copy((float*) &cyldata[i].color, &colors[i*3]);
05712 }
05713 }
05714 }
05715 rtBufferUnmap(buf);
05716
05717 RTERR( rtGeometryCreate(ctx, &geom) );
05718 RTERR( rtGeometrySetPrimitiveCount(geom, cylnum) );
05719 RTERR( rtGeometrySetBoundingBoxProgram(geom, cylinder_array_color_bbox_pgm) );
05720 RTERR( rtGeometrySetIntersectionProgram(geom, cylinder_array_color_isct_pgm) );
05721
05722
05723 RTvariable buf_v;
05724 RTERR( rtGeometryDeclareVariable(geom, "cylinder_color_buffer", &buf_v) );
05725 RTERR( rtVariableSetObject(buf_v, buf) );
05726
05727
05728 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
05729 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
05730
05731 set_material(instance, matindex, NULL);
05732
05733 append_objects(buf, geom, instance);
05734 }
05735
05736
05737 void OptiXRenderer::ring_array_color(Matrix4 & wtrans, float rscale,
05738 int rnum, const float *centers,
05739 const float *norms, const float *radii,
05740 const float *colors, int matindex) {
05741 if (!context_created) return;
05742 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating ring array color: %d...\n", rnum);
05743 ring_array_color_cnt += rnum;
05744
05745 int i, ind;
05746 RTbuffer buf;
05747 RTgeometry geom;
05748 RTgeometryinstance instance;
05749 vmd_ring_color *rdata;
05750
05751
05752 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
05753 rtBufferSetFormat(buf, RT_FORMAT_USER);
05754 rtBufferSetElementSize(buf, sizeof(vmd_ring_color));
05755 rtBufferSetSize1D(buf, rnum);
05756
05757 rtBufferMap(buf, (void **) &rdata);
05758
05759 for (i=0,ind=0; i<rnum; i++,ind+=3) {
05760
05761 wtrans.multpoint3d(¢ers[ind], (float*) &rdata[i].center);
05762 wtrans.multnorm3d(&norms[ind], (float*) &rdata[i].norm);
05763 vec_normalize((float*) &rdata[i].norm);
05764 rdata[i].inrad = rscale * radii[i*2];
05765 rdata[i].outrad = rscale * radii[i*2+1];
05766 vec_copy((float*) &rdata[i].color, &colors[ind]);
05767 rdata[i].pad = 0.0f;
05768 }
05769 rtBufferUnmap(buf);
05770
05771 RTERR( rtGeometryCreate(ctx, &geom) );
05772 RTERR( rtGeometrySetPrimitiveCount(geom, rnum) );
05773 RTERR( rtGeometrySetBoundingBoxProgram(geom, ring_array_color_bbox_pgm) );
05774 RTERR( rtGeometrySetIntersectionProgram(geom, ring_array_color_isct_pgm) );
05775
05776
05777 RTvariable buf_v;
05778 RTERR( rtGeometryDeclareVariable(geom, "ring_color_buffer", &buf_v) );
05779 RTERR( rtVariableSetObject(buf_v, buf) );
05780
05781
05782 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
05783 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
05784
05785 set_material(instance, matindex, NULL);
05786
05787 append_objects(buf, geom, instance);
05788 }
05789
05790
05791 void OptiXRenderer::sphere_array(Matrix4 *wtrans, float rscale,
05792 const float *uniform_color,
05793 int spnum, const float *centers,
05794 const float *radii,
05795 int matindex) {
05796 if (!context_created) return;
05797 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating sphere array: %d...\n", spnum);
05798 sphere_array_cnt += spnum;
05799
05800 int i, ind;
05801 RTbuffer buf;
05802 RTgeometry geom;
05803 RTgeometryinstance instance;
05804 vmd_sphere *spdata;
05805
05806
05807 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
05808 rtBufferSetFormat(buf, RT_FORMAT_USER);
05809 rtBufferSetElementSize(buf, sizeof(vmd_sphere));
05810 rtBufferSetSize1D(buf, spnum);
05811
05812 rtBufferMap(buf, (void **) &spdata);
05813
05814 if (wtrans == NULL) {
05815 if (radii == NULL) {
05816 for (i=0,ind=0; i<spnum; i++,ind+=3) {
05817
05818 vec_copy((float*) &spdata[i].center, ¢ers[ind]);
05819 spdata[i].radius = rscale;
05820 }
05821 } else {
05822 for (i=0,ind=0; i<spnum; i++,ind+=3) {
05823
05824 vec_copy((float*) &spdata[i].center, ¢ers[ind]);
05825 spdata[i].radius = rscale * radii[i];
05826 }
05827 }
05828 } else {
05829 if (radii == NULL) {
05830 for (i=0,ind=0; i<spnum; i++,ind+=3) {
05831
05832 wtrans->multpoint3d(¢ers[ind], (float*) &spdata[i].center);
05833 spdata[i].radius = rscale;
05834 }
05835 } else {
05836 for (i=0,ind=0; i<spnum; i++,ind+=3) {
05837
05838 wtrans->multpoint3d(¢ers[ind], (float*) &spdata[i].center);
05839 spdata[i].radius = rscale * radii[i];
05840 }
05841 }
05842 }
05843 rtBufferUnmap(buf);
05844
05845 RTERR( rtGeometryCreate(ctx, &geom) );
05846 RTERR( rtGeometrySetPrimitiveCount(geom, spnum) );
05847 RTERR( rtGeometrySetBoundingBoxProgram(geom, sphere_array_bbox_pgm) );
05848 RTERR( rtGeometrySetIntersectionProgram(geom, sphere_array_isct_pgm) );
05849
05850
05851 RTvariable buf_v;
05852 RTERR( rtGeometryDeclareVariable(geom, "sphere_buffer", &buf_v) );
05853 RTERR( rtVariableSetObject(buf_v, buf) );
05854
05855
05856 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
05857 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
05858
05859 set_material(instance, matindex, uniform_color);
05860
05861 append_objects(buf, geom, instance);
05862 }
05863
05864
05865 void OptiXRenderer::sphere_array_color(Matrix4 & wtrans, float rscale,
05866 int spnum, const float *centers,
05867 const float *radii, const float *colors,
05868 int matindex) {
05869 if (!context_created) return;
05870 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating sphere array color: %d...\n", spnum);
05871 sphere_array_color_cnt += spnum;
05872
05873 int i, ind;
05874 RTbuffer buf;
05875 RTgeometry geom;
05876 RTgeometryinstance instance;
05877 vmd_sphere_color *spdata;
05878
05879
05880 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
05881 rtBufferSetFormat(buf, RT_FORMAT_USER);
05882 rtBufferSetElementSize(buf, sizeof(vmd_sphere_color));
05883 rtBufferSetSize1D(buf, spnum);
05884
05885 rtBufferMap(buf, (void **) &spdata);
05886
05887 for (i=0,ind=0; i<spnum; i++,ind+=3) {
05888
05889 wtrans.multpoint3d(¢ers[ind], (float*) &spdata[i].center);
05890 spdata[i].radius = rscale * radii[i];
05891 vec_copy((float*) &spdata[i].color, &colors[ind]);
05892 spdata[i].pad = 0.0f;
05893 }
05894 rtBufferUnmap(buf);
05895
05896 RTERR( rtGeometryCreate(ctx, &geom) );
05897 RTERR( rtGeometrySetPrimitiveCount(geom, spnum) );
05898 RTERR( rtGeometrySetBoundingBoxProgram(geom, sphere_array_color_bbox_pgm) );
05899 RTERR( rtGeometrySetIntersectionProgram(geom, sphere_array_color_isct_pgm) );
05900
05901
05902 RTvariable buf_v;
05903 RTERR( rtGeometryDeclareVariable(geom, "sphere_color_buffer", &buf_v) );
05904 RTERR( rtVariableSetObject(buf_v, buf) );
05905
05906
05907 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
05908 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
05909
05910 set_material(instance, matindex, NULL);
05911
05912 append_objects(buf, geom, instance);
05913 }
05914
05915
05916 #if defined(ORT_USERTXAPIS)
05917 void OptiXRenderer::tricolor_list_hwtri(Matrix4 & wtrans, int numtris,
05918 const float *vnc, int matindex) {
05919 if (!context_created) return;
05920
05921 tricolor_cnt += numtris;
05922
05923 RTbuffer vbuf, nbuf, cbuf;
05924 RTgeometryinstance instance_hwtri;
05925 RTgeometrytriangles geom_hwtri;
05926
05927
05928 float3 *vertices;
05929 uint4 *normals;
05930 uchar4 *colors;
05931 hwtri_alloc_bufs_v3f_n4u4_c4u(ctx, numtris, vbuf, vertices, nbuf, normals,
05932 cbuf, 1, colors, NULL);
05933
05934 int i, ind, tcnt;
05935 for (i=0,ind=0,tcnt=0; i<numtris; i++,ind+=27) {
05936 int taddr = 3 * tcnt;
05937
05938
05939 wtrans.multpoint3d(&vnc[ind ], (float*) &vertices[taddr + 0]);
05940 wtrans.multpoint3d(&vnc[ind + 3], (float*) &vertices[taddr + 1]);
05941 wtrans.multpoint3d(&vnc[ind + 6], (float*) &vertices[taddr + 2]);
05942
05943
05944 float3 Ng;
05945 if (hwtri_test_calc_Ngeom(&vertices[taddr], Ng)) {
05946 continue;
05947 }
05948
05949 float3 n0, n1, n2;
05950 wtrans.multnorm3d(&vnc[ind + 9], (float*) &n0);
05951 wtrans.multnorm3d(&vnc[ind + 12], (float*) &n1);
05952 wtrans.multnorm3d(&vnc[ind + 15], (float*) &n2);
05953
05954
05955 normals[tcnt].x = packNormal(Ng);
05956 normals[tcnt].y = packNormal(n0);
05957 normals[tcnt].z = packNormal(n1);
05958 normals[tcnt].w = packNormal(n2);
05959
05960
05961 colors[taddr + 0].x = vnc[ind + 18] * 255.0f;
05962 colors[taddr + 0].y = vnc[ind + 19] * 255.0f;
05963 colors[taddr + 0].z = vnc[ind + 20] * 255.0f;
05964
05965 colors[taddr + 1].x = vnc[ind + 21] * 255.0f;
05966 colors[taddr + 1].y = vnc[ind + 22] * 255.0f;
05967 colors[taddr + 1].z = vnc[ind + 23] * 255.0f;
05968
05969 colors[taddr + 2].x = vnc[ind + 24] * 255.0f;
05970 colors[taddr + 2].y = vnc[ind + 25] * 255.0f;
05971 colors[taddr + 2].z = vnc[ind + 26] * 255.0f;
05972
05973 tcnt++;
05974 }
05975
05976 rtBufferUnmap(vbuf);
05977 rtBufferUnmap(nbuf);
05978 rtBufferUnmap(cbuf);
05979
05980 RTERR( rtGeometryTrianglesCreate(ctx, &geom_hwtri) );
05981 RTERR( rtGeometryTrianglesSetPrimitiveCount(geom_hwtri, tcnt) );
05982 RTERR( rtGeometryTrianglesSetVertices(geom_hwtri, tcnt * 3, vbuf,
05983 0, sizeof(float3), RT_FORMAT_FLOAT3) );
05984 #if defined(VMDOPTIXRTXRELEASEBUFS)
05985 RTERR( rtGeometryTrianglesSetBuildFlags(geom_hwtri, RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS) );
05986 #else
05987 append_buffer(vbuf);
05988 #endif
05989
05990
05991 RTERR( rtGeometryInstanceCreate(ctx, &instance_hwtri) );
05992 RTERR( rtGeometryInstanceSetGeometryTriangles(instance_hwtri, geom_hwtri) );
05993
05994
05995 hwtri_set_vertex_flags(ctx, instance_hwtri, nbuf, cbuf, 1, 1);
05996
05997
05998 set_material(instance_hwtri, matindex, NULL, 1);
05999
06000
06001
06002 append_objects(nbuf, cbuf, geom_hwtri, instance_hwtri);
06003 }
06004 #endif
06005
06006
06007 void OptiXRenderer::tricolor_list(Matrix4 & wtrans, int numtris,
06008 const float *vnc, int matindex) {
06009 if (!context_created) return;
06010
06011 tricolor_cnt += numtris;
06012
06013 int i, ind;
06014 RTbuffer buf;
06015 RTgeometry geom;
06016 RTgeometryinstance instance;
06017 vmd_tricolor *trimesh;
06018
06019
06020 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
06021 rtBufferSetFormat(buf, RT_FORMAT_USER);
06022 rtBufferSetElementSize(buf, sizeof(vmd_tricolor));
06023 rtBufferSetSize1D(buf, numtris);
06024
06025 rtBufferMap(buf, (void **) &trimesh);
06026
06027 for (i=0,ind=0; i<numtris; i++,ind+=27) {
06028
06029 wtrans.multpoint3d(&vnc[ind ], (float*) &trimesh[i].v0);
06030 wtrans.multpoint3d(&vnc[ind + 3], (float*) &trimesh[i].v1);
06031 wtrans.multpoint3d(&vnc[ind + 6], (float*) &trimesh[i].v2);
06032
06033 wtrans.multnorm3d(&vnc[ind + 9], (float*) &trimesh[i].n0);
06034 wtrans.multnorm3d(&vnc[ind + 12], (float*) &trimesh[i].n1);
06035 wtrans.multnorm3d(&vnc[ind + 15], (float*) &trimesh[i].n2);
06036
06037 vec_copy((float*) &trimesh[i].c0, &vnc[ind + 18]);
06038 vec_copy((float*) &trimesh[i].c1, &vnc[ind + 21]);
06039 vec_copy((float*) &trimesh[i].c2, &vnc[ind + 24]);
06040 }
06041 rtBufferUnmap(buf);
06042
06043 RTERR( rtGeometryCreate(ctx, &geom) );
06044 RTERR( rtGeometrySetPrimitiveCount(geom, numtris) );
06045 RTERR( rtGeometrySetBoundingBoxProgram(geom, tricolor_bbox_pgm) );
06046 RTERR( rtGeometrySetIntersectionProgram(geom, tricolor_isct_pgm) );
06047
06048
06049 RTvariable buf_v;
06050 RTERR( rtGeometryDeclareVariable(geom, "tricolor_buffer", &buf_v) );
06051 RTERR( rtVariableSetObject(buf_v, buf) );
06052
06053
06054 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
06055 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
06056
06057
06058 set_material(instance, matindex, NULL);
06059
06060 append_objects(buf, geom, instance);
06061 }
06062
06063
06064 #if defined(ORT_USERTXAPIS)
06065 void OptiXRenderer::trimesh_c4n3v3_hwtri(Matrix4 & wtrans,
06066 int numverts, const float *cnv,
06067 int numfacets, const int * facets,
06068 int matindex) {
06069 if (!context_created) return;
06070 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_c4n3v3_hwtri: %d...\n", numfacets);
06071 trimesh_c4u_n3b_v3f_cnt += numfacets;
06072
06073 RTbuffer vbuf, nbuf, cbuf;
06074 RTgeometryinstance instance_hwtri;
06075 RTgeometrytriangles geom_hwtri;
06076
06077
06078 float3 *vertices;
06079 uint4 *normals;
06080 uchar4 *colors;
06081 hwtri_alloc_bufs_v3f_n4u4_c4u(ctx, numfacets, vbuf, vertices, nbuf, normals,
06082 cbuf, numfacets * 3, colors, NULL);
06083
06084 int i, ind, tcnt;
06085 for (i=0,ind=0,tcnt=0; i<numfacets; i++,ind+=3) {
06086 int taddr = 3 * tcnt;
06087
06088 int v0 = facets[ind ] * 10;
06089 int v1 = facets[ind + 1] * 10;
06090 int v2 = facets[ind + 2] * 10;
06091
06092
06093 wtrans.multpoint3d(cnv + v0 + 7, (float*) &vertices[taddr + 0]);
06094 wtrans.multpoint3d(cnv + v1 + 7, (float*) &vertices[taddr + 1]);
06095 wtrans.multpoint3d(cnv + v2 + 7, (float*) &vertices[taddr + 2]);
06096
06097
06098 float3 Ng;
06099 if (hwtri_test_calc_Ngeom(&vertices[taddr], Ng)) {
06100 continue;
06101 }
06102
06103 float3 n0, n1, n2;
06104 wtrans.multnorm3d(cnv + v0 + 4, (float*) &n0);
06105 wtrans.multnorm3d(cnv + v1 + 4, (float*) &n1);
06106 wtrans.multnorm3d(cnv + v2 + 4, (float*) &n2);
06107
06108
06109 normals[tcnt].x = packNormal(Ng);
06110 normals[tcnt].y = packNormal(n0);
06111 normals[tcnt].z = packNormal(n1);
06112 normals[tcnt].w = packNormal(n2);
06113
06114
06115 colors[taddr + 0].x = cnv[v0 + 0] * 255.0f;
06116 colors[taddr + 0].y = cnv[v0 + 1] * 255.0f;
06117 colors[taddr + 0].z = cnv[v0 + 2] * 255.0f;
06118
06119 colors[taddr + 1].x = cnv[v1 + 0] * 255.0f;
06120 colors[taddr + 1].y = cnv[v1 + 1] * 255.0f;
06121 colors[taddr + 1].z = cnv[v1 + 2] * 255.0f;
06122
06123 colors[taddr + 2].x = cnv[v2 + 0] * 255.0f;
06124 colors[taddr + 2].y = cnv[v2 + 1] * 255.0f;
06125 colors[taddr + 2].z = cnv[v2 + 2] * 255.0f;
06126
06127 tcnt++;
06128 }
06129
06130 rtBufferUnmap(vbuf);
06131 rtBufferUnmap(nbuf);
06132 rtBufferUnmap(cbuf);
06133
06134 RTERR( rtGeometryTrianglesCreate(ctx, &geom_hwtri) );
06135 RTERR( rtGeometryTrianglesSetPrimitiveCount(geom_hwtri, tcnt) );
06136 RTERR( rtGeometryTrianglesSetVertices(geom_hwtri, tcnt * 3, vbuf,
06137 0, sizeof(float3), RT_FORMAT_FLOAT3) );
06138 #if defined(VMDOPTIXRTXRELEASEBUFS)
06139 RTERR( rtGeometryTrianglesSetBuildFlags(geom_hwtri, RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS) );
06140 #else
06141 append_buffer(vbuf);
06142 #endif
06143
06144
06145 RTERR( rtGeometryInstanceCreate(ctx, &instance_hwtri) );
06146 RTERR( rtGeometryInstanceSetGeometryTriangles(instance_hwtri, geom_hwtri) );
06147
06148
06149 hwtri_set_vertex_flags(ctx, instance_hwtri, nbuf, cbuf, 1, 1);
06150
06151
06152 set_material(instance_hwtri, matindex, NULL, 1);
06153
06154
06155
06156 append_objects(nbuf, cbuf, geom_hwtri, instance_hwtri);
06157 }
06158 #endif
06159
06160
06161 void OptiXRenderer::trimesh_c4n3v3(Matrix4 & wtrans,
06162 int numverts, const float *cnv,
06163 int numfacets, const int * facets,
06164 int matindex) {
06165 if (!context_created) return;
06166
06167 #if defined(ORT_USERTXAPIS)
06168
06169 if (hwtri_enabled) {
06170 trimesh_c4n3v3_hwtri(wtrans, numverts, cnv, numfacets, facets, matindex);
06171 return;
06172 }
06173 #endif
06174
06175 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_c4n3v3: %d...\n", numfacets);
06176 trimesh_c4u_n3b_v3f_cnt += numfacets;
06177
06178 int i, ind;
06179 RTbuffer buf;
06180 RTgeometry geom;
06181 RTgeometryinstance instance;
06182 vmd_tricolor *trimesh;
06183
06184
06185 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
06186 rtBufferSetFormat(buf, RT_FORMAT_USER);
06187 rtBufferSetElementSize(buf, sizeof(vmd_tricolor));
06188 rtBufferSetSize1D(buf, numfacets);
06189
06190 rtBufferMap(buf, (void **) &trimesh);
06191
06192 for (i=0,ind=0; i<numfacets; i++,ind+=3) {
06193 int v0 = facets[ind ] * 10;
06194 int v1 = facets[ind + 1] * 10;
06195 int v2 = facets[ind + 2] * 10;
06196
06197
06198 wtrans.multpoint3d(cnv + v0 + 7, (float*) &trimesh[i].v0);
06199 wtrans.multpoint3d(cnv + v1 + 7, (float*) &trimesh[i].v1);
06200 wtrans.multpoint3d(cnv + v2 + 7, (float*) &trimesh[i].v2);
06201
06202 wtrans.multnorm3d(cnv + v0 + 4, (float*) &trimesh[i].n0);
06203 wtrans.multnorm3d(cnv + v1 + 4, (float*) &trimesh[i].n1);
06204 wtrans.multnorm3d(cnv + v2 + 4, (float*) &trimesh[i].n2);
06205
06206 vec_copy((float*) &trimesh[i].c0, cnv + v0);
06207 vec_copy((float*) &trimesh[i].c1, cnv + v1);
06208 vec_copy((float*) &trimesh[i].c2, cnv + v2);
06209 }
06210 rtBufferUnmap(buf);
06211
06212 RTERR( rtGeometryCreate(ctx, &geom) );
06213 RTERR( rtGeometrySetPrimitiveCount(geom, numfacets) );
06214 RTERR( rtGeometrySetBoundingBoxProgram(geom, tricolor_bbox_pgm) );
06215 RTERR( rtGeometrySetIntersectionProgram(geom, tricolor_isct_pgm) );
06216
06217
06218 RTvariable buf_v;
06219 RTERR( rtGeometryDeclareVariable(geom, "tricolor_buffer", &buf_v) );
06220 RTERR( rtVariableSetObject(buf_v, buf) );
06221
06222
06223 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
06224 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
06225
06226 set_material(instance, matindex, NULL);
06227
06228 append_objects(buf, geom, instance);
06229 }
06230
06231
06232 #if defined(ORT_USERTXAPIS)
06233
06234
06235
06236
06237
06238 void OptiXRenderer::trimesh_c4u_n3b_v3f_hwtri(Matrix4 & wtrans,
06239 const unsigned char *c,
06240 const signed char *n,
06241 const float *v, int numfacets,
06242 int matindex) {
06243 if (!context_created) return;
06244 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_c4u_n3b_v3f_hwtri: %d...\n", numfacets);
06245 trimesh_c4u_n3b_v3f_cnt += numfacets;
06246
06247 RTbuffer vbuf, nbuf, cbuf;
06248 RTgeometryinstance instance_hwtri;
06249 RTgeometrytriangles geom_hwtri;
06250
06251
06252 float3 *vertices;
06253 uint4 *normals;
06254 uchar4 *colors;
06255 hwtri_alloc_bufs_v3f_n4u4_c4u(ctx, numfacets, vbuf, vertices, nbuf, normals,
06256 cbuf, numfacets * 3, colors, NULL);
06257
06258 const float ci2f = 1.0f / 255.0f;
06259 const float cn2f = 1.0f / 127.5f;
06260 int i, j, ind, tcnt;
06261 for (ind=0,i=0,j=0,tcnt=0; ind<numfacets; ind++,i+=9,j+=12) {
06262 float norm[9];
06263 int taddr = 3 * tcnt;
06264
06265
06266 wtrans.multpoint3d(v + i , (float*) &vertices[taddr + 0]);
06267 wtrans.multpoint3d(v + i + 3, (float*) &vertices[taddr + 1]);
06268 wtrans.multpoint3d(v + i + 6, (float*) &vertices[taddr + 2]);
06269
06270
06271 float3 Ng;
06272 if (hwtri_test_calc_Ngeom(&vertices[taddr], Ng)) {
06273 continue;
06274 }
06275
06276
06277
06278 norm[0] = n[i ] * cn2f + ci2f;
06279 norm[1] = n[i + 1] * cn2f + ci2f;
06280 norm[2] = n[i + 2] * cn2f + ci2f;
06281 norm[3] = n[i + 3] * cn2f + ci2f;
06282 norm[4] = n[i + 4] * cn2f + ci2f;
06283 norm[5] = n[i + 5] * cn2f + ci2f;
06284 norm[6] = n[i + 6] * cn2f + ci2f;
06285 norm[7] = n[i + 7] * cn2f + ci2f;
06286 norm[8] = n[i + 8] * cn2f + ci2f;
06287
06288
06289 float3 n0, n1, n2;
06290 wtrans.multnorm3d(&norm[0], (float*) &n0);
06291 wtrans.multnorm3d(&norm[3], (float*) &n1);
06292 wtrans.multnorm3d(&norm[6], (float*) &n2);
06293
06294
06295 normals[tcnt].x = packNormal(Ng);
06296 normals[tcnt].y = packNormal(n0);
06297 normals[tcnt].z = packNormal(n1);
06298 normals[tcnt].w = packNormal(n2);
06299
06300 memcpy(&colors[tcnt * 3], &c[j], 12);
06301
06302 tcnt++;
06303 }
06304
06305 rtBufferUnmap(vbuf);
06306 rtBufferUnmap(nbuf);
06307 rtBufferUnmap(cbuf);
06308
06309 RTERR( rtGeometryTrianglesCreate(ctx, &geom_hwtri) );
06310 RTERR( rtGeometryTrianglesSetPrimitiveCount(geom_hwtri, tcnt) );
06311 RTERR( rtGeometryTrianglesSetVertices(geom_hwtri, tcnt * 3, vbuf,
06312 0, sizeof(float3), RT_FORMAT_FLOAT3) );
06313 #if defined(VMDOPTIXRTXRELEASEBUFS)
06314 RTERR( rtGeometryTrianglesSetBuildFlags(geom_hwtri, RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS) );
06315 #else
06316 append_buffer(vbuf);
06317 #endif
06318
06319
06320 RTERR( rtGeometryInstanceCreate(ctx, &instance_hwtri) );
06321 RTERR( rtGeometryInstanceSetGeometryTriangles(instance_hwtri, geom_hwtri) );
06322
06323
06324 hwtri_set_vertex_flags(ctx, instance_hwtri, nbuf, cbuf, 1, 1);
06325
06326
06327 set_material(instance_hwtri, matindex, NULL, 1);
06328
06329
06330
06331 append_objects(nbuf, cbuf, geom_hwtri, instance_hwtri);
06332 }
06333 #endif
06334
06335
06336
06337
06338
06339
06340
06341 void OptiXRenderer::trimesh_c4u_n3b_v3f(Matrix4 & wtrans,
06342 const unsigned char *c,
06343 const signed char *n, const float *v,
06344 int numfacets, int matindex) {
06345 if (!context_created) return;
06346
06347 #if defined(ORT_USERTXAPIS)
06348
06349 if (hwtri_enabled) {
06350 trimesh_c4u_n3b_v3f_hwtri(wtrans, c, n, v, numfacets, matindex);
06351 return;
06352 }
06353 #endif
06354
06355 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_c4u_n3b_v3f: %d...\n", numfacets);
06356 trimesh_n3b_v3f_cnt += numfacets;
06357
06358 int i, j, ind;
06359 RTbuffer buf;
06360 RTgeometry geom;
06361 RTgeometryinstance instance;
06362 vmd_trimesh_c4u_n3b_v3f *trimesh;
06363
06364
06365 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
06366 rtBufferSetFormat(buf, RT_FORMAT_USER);
06367 rtBufferSetElementSize(buf, sizeof(vmd_trimesh_c4u_n3b_v3f));
06368 rtBufferSetSize1D(buf, numfacets);
06369
06370 rtBufferMap(buf, (void **) &trimesh);
06371
06372 const float ci2f = 1.0f / 255.0f;
06373 const float cn2f = 1.0f / 127.5f;
06374 for (ind=0,i=0,j=0; ind<numfacets; ind++,i+=9,j+=12) {
06375 float norm[9];
06376
06377
06378 wtrans.multpoint3d(v + i , (float*) &trimesh[ind].v0);
06379 wtrans.multpoint3d(v + i + 3, (float*) &trimesh[ind].v1);
06380 wtrans.multpoint3d(v + i + 6, (float*) &trimesh[ind].v2);
06381
06382
06383
06384 norm[0] = n[i ] * cn2f + ci2f;
06385 norm[1] = n[i + 1] * cn2f + ci2f;
06386 norm[2] = n[i + 2] * cn2f + ci2f;
06387 norm[3] = n[i + 3] * cn2f + ci2f;
06388 norm[4] = n[i + 4] * cn2f + ci2f;
06389 norm[5] = n[i + 5] * cn2f + ci2f;
06390 norm[6] = n[i + 6] * cn2f + ci2f;
06391 norm[7] = n[i + 7] * cn2f + ci2f;
06392 norm[8] = n[i + 8] * cn2f + ci2f;
06393
06394
06395 float3 tmpn;
06396 wtrans.multnorm3d(&norm[0], (float*) &tmpn);
06397 tmpn = tmpn * 127.5f - 0.5f;
06398 trimesh[ind].n0 = make_char4(tmpn.x, tmpn.y, tmpn.z, 0);
06399 wtrans.multnorm3d(&norm[3], (float*) &tmpn);
06400 tmpn = tmpn * 127.5f - 0.5f;
06401 trimesh[ind].n1 = make_char4(tmpn.x, tmpn.y, tmpn.z, 0);
06402 wtrans.multnorm3d(&norm[6], (float*) &tmpn);
06403 tmpn = tmpn * 127.5f - 0.5f;
06404 trimesh[ind].n2 = make_char4(tmpn.x, tmpn.y, tmpn.z, 0);
06405
06406 memcpy(&trimesh[ind].c0, &c[j ], 4);
06407 memcpy(&trimesh[ind].c1, &c[j+4], 4);
06408 memcpy(&trimesh[ind].c2, &c[j+8], 4);
06409 }
06410 rtBufferUnmap(buf);
06411
06412 RTERR( rtGeometryCreate(ctx, &geom) );
06413 RTERR( rtGeometrySetPrimitiveCount(geom, numfacets) );
06414 RTERR( rtGeometrySetBoundingBoxProgram(geom, trimesh_c4u_n3b_v3f_bbox_pgm) );
06415 RTERR( rtGeometrySetIntersectionProgram(geom, trimesh_c4u_n3b_v3f_isct_pgm) );
06416
06417
06418 RTvariable buf_v;
06419 RTERR( rtGeometryDeclareVariable(geom, "trimesh_c4u_n3b_v3f_buffer", &buf_v) );
06420 RTERR( rtVariableSetObject(buf_v, buf) );
06421
06422
06423 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
06424 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
06425
06426 set_material(instance, matindex, NULL);
06427
06428 append_objects(buf, geom, instance);
06429 }
06430
06431
06432 #if defined(ORT_USERTXAPIS)
06433 void OptiXRenderer::trimesh_c4u_n3f_v3f_hwtri(Matrix4 & wtrans,
06434 const unsigned char *c,
06435 const float *n, const float *v,
06436 int numfacets, int matindex) {
06437 if (!context_created) return;
06438 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_c4u_n3f_v3f: %d...\n", numfacets);
06439 tricolor_cnt += numfacets;
06440
06441 RTbuffer vbuf, nbuf, cbuf;
06442 RTgeometryinstance instance_hwtri;
06443 RTgeometrytriangles geom_hwtri;
06444
06445
06446 float3 *vertices;
06447 uint4 *normals;
06448 uchar4 *colors;
06449 hwtri_alloc_bufs_v3f_n4u4_c4u(ctx, numfacets, vbuf, vertices, nbuf, normals,
06450 cbuf, 1, colors, NULL);
06451
06452 int i, j, ind, tcnt;
06453 for (ind=0,i=0,j=0,tcnt=0; ind<numfacets; ind++,i+=9,j+=12) {
06454 int taddr = 3 * tcnt;
06455
06456
06457 wtrans.multpoint3d(v + i , (float*) &vertices[taddr + 0]);
06458 wtrans.multpoint3d(v + i + 3, (float*) &vertices[taddr + 1]);
06459 wtrans.multpoint3d(v + i + 6, (float*) &vertices[taddr + 2]);
06460
06461
06462 float3 Ng;
06463 if (hwtri_test_calc_Ngeom(&vertices[taddr], Ng)) {
06464 continue;
06465 }
06466
06467 float3 n0, n1, n2;
06468 wtrans.multnorm3d(n + i , (float*) &n0);
06469 wtrans.multnorm3d(n + i + 3, (float*) &n1);
06470 wtrans.multnorm3d(n + i + 6, (float*) &n2);
06471
06472
06473 normals[tcnt].x = packNormal(Ng);
06474 normals[tcnt].y = packNormal(n0);
06475 normals[tcnt].z = packNormal(n1);
06476 normals[tcnt].w = packNormal(n2);
06477
06478 memcpy(&colors[taddr + 0], &c[j ], sizeof(uchar4));
06479 memcpy(&colors[taddr + 1], &c[j+4], sizeof(uchar4));
06480 memcpy(&colors[taddr + 2], &c[j+8], sizeof(uchar4));
06481
06482 tcnt++;
06483 }
06484
06485 rtBufferUnmap(vbuf);
06486 rtBufferUnmap(nbuf);
06487 rtBufferUnmap(cbuf);
06488
06489 RTERR( rtGeometryTrianglesCreate(ctx, &geom_hwtri) );
06490 RTERR( rtGeometryTrianglesSetPrimitiveCount(geom_hwtri, tcnt) );
06491 RTERR( rtGeometryTrianglesSetVertices(geom_hwtri, tcnt * 3, vbuf,
06492 0, sizeof(float3), RT_FORMAT_FLOAT3) );
06493 #if defined(VMDOPTIXRTXRELEASEBUFS)
06494 RTERR( rtGeometryTrianglesSetBuildFlags(geom_hwtri, RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS) );
06495 #else
06496 append_buffer(vbuf);
06497 #endif
06498
06499
06500 RTERR( rtGeometryInstanceCreate(ctx, &instance_hwtri) );
06501 RTERR( rtGeometryInstanceSetGeometryTriangles(instance_hwtri, geom_hwtri) );
06502
06503
06504 hwtri_set_vertex_flags(ctx, instance_hwtri, nbuf, cbuf, 1, 1);
06505
06506
06507 set_material(instance_hwtri, matindex, NULL, 1);
06508
06509
06510
06511 append_objects(nbuf, cbuf, geom_hwtri, instance_hwtri);
06512 }
06513 #endif
06514
06515
06516 void OptiXRenderer::trimesh_c4u_n3f_v3f(Matrix4 & wtrans,
06517 const unsigned char *c,
06518 const float *n, const float *v,
06519 int numfacets, int matindex) {
06520 if (!context_created) return;
06521
06522 #if defined(ORT_USERTXAPIS)
06523
06524 if (hwtri_enabled) {
06525 trimesh_c4u_n3f_v3f_hwtri(wtrans, c, n, v, numfacets, matindex);
06526 return;
06527 }
06528 #endif
06529
06530 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_c4u_n3f_v3f: %d...\n", numfacets);
06531 tricolor_cnt += numfacets;
06532
06533 int i, j, ind;
06534 RTbuffer buf;
06535 RTgeometry geom;
06536 RTgeometryinstance instance;
06537 vmd_tricolor *trimesh;
06538
06539
06540 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
06541 rtBufferSetFormat(buf, RT_FORMAT_USER);
06542 rtBufferSetElementSize(buf, sizeof(vmd_tricolor));
06543 rtBufferSetSize1D(buf, numfacets);
06544
06545 rtBufferMap(buf, (void **) &trimesh);
06546
06547 const float ci2f = 1.0f / 255.0f;
06548 for (ind=0,i=0,j=0; ind<numfacets; ind++,i+=9,j+=12) {
06549
06550 wtrans.multpoint3d(v + i , (float*) &trimesh[ind].v0);
06551 wtrans.multpoint3d(v + i + 3, (float*) &trimesh[ind].v1);
06552 wtrans.multpoint3d(v + i + 6, (float*) &trimesh[ind].v2);
06553
06554 wtrans.multnorm3d(n + i , (float*) &trimesh[ind].n0);
06555 wtrans.multnorm3d(n + i + 3, (float*) &trimesh[ind].n1);
06556 wtrans.multnorm3d(n + i + 6, (float*) &trimesh[ind].n2);
06557
06558
06559
06560 float col[9];
06561 col[0] = c[j ] * ci2f;
06562 col[1] = c[j + 1] * ci2f;
06563 col[2] = c[j + 2] * ci2f;
06564 col[3] = c[j + 4] * ci2f;
06565 col[4] = c[j + 5] * ci2f;
06566 col[5] = c[j + 6] * ci2f;
06567 col[6] = c[j + 8] * ci2f;
06568 col[7] = c[j + 9] * ci2f;
06569 col[8] = c[j + 10] * ci2f;
06570
06571 vec_copy((float*) &trimesh[ind].c0, &col[0]);
06572 vec_copy((float*) &trimesh[ind].c1, &col[3]);
06573 vec_copy((float*) &trimesh[ind].c2, &col[6]);
06574 }
06575 rtBufferUnmap(buf);
06576
06577 RTERR( rtGeometryCreate(ctx, &geom) );
06578 RTERR( rtGeometrySetPrimitiveCount(geom, numfacets) );
06579 RTERR( rtGeometrySetBoundingBoxProgram(geom, tricolor_bbox_pgm) );
06580 RTERR( rtGeometrySetIntersectionProgram(geom, tricolor_isct_pgm) );
06581
06582
06583 RTvariable buf_v;
06584 RTERR( rtGeometryDeclareVariable(geom, "tricolor_buffer", &buf_v) );
06585 RTERR( rtVariableSetObject(buf_v, buf) );
06586
06587
06588 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
06589 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
06590
06591 set_material(instance, matindex, NULL);
06592
06593 append_objects(buf, geom, instance);
06594 }
06595
06596
06597 #if defined(ORT_USERTXAPIS)
06598 void OptiXRenderer::trimesh_n3b_v3f_hwtri(Matrix4 & wtrans,
06599 const float *uniform_color,
06600 const signed char *n, const float *v,
06601 int numfacets, int matindex) {
06602 if (!context_created) return;
06603 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_n3b_v3f_hwtri: %d...\n", numfacets);
06604 trimesh_n3b_v3f_cnt += numfacets;
06605
06606 RTbuffer vbuf, nbuf, cbuf;
06607 RTgeometryinstance instance_hwtri;
06608 RTgeometrytriangles geom_hwtri;
06609
06610
06611 float3 *vertices;
06612 uint4 *normals;
06613 uchar4 *colors;
06614 hwtri_alloc_bufs_v3f_n4u4_c4u(ctx, numfacets, vbuf, vertices, nbuf, normals,
06615 cbuf, 1, colors, uniform_color);
06616
06617 const float ci2f = 1.0f / 255.0f;
06618 const float cn2f = 1.0f / 127.5f;
06619 int i, ind, tcnt;
06620 for (ind=0,i=0,tcnt=0; ind<numfacets; ind++,i+=9) {
06621 float norm[9];
06622 int taddr = 3 * tcnt;
06623
06624
06625 wtrans.multpoint3d(v + i , (float*) &vertices[taddr + 0]);
06626 wtrans.multpoint3d(v + i + 3, (float*) &vertices[taddr + 1]);
06627 wtrans.multpoint3d(v + i + 6, (float*) &vertices[taddr + 2]);
06628
06629
06630 float3 Ng;
06631 if (hwtri_test_calc_Ngeom(&vertices[taddr], Ng)) {
06632 continue;
06633 }
06634
06635
06636
06637 norm[0] = n[i ] * cn2f + ci2f;
06638 norm[1] = n[i + 1] * cn2f + ci2f;
06639 norm[2] = n[i + 2] * cn2f + ci2f;
06640 norm[3] = n[i + 3] * cn2f + ci2f;
06641 norm[4] = n[i + 4] * cn2f + ci2f;
06642 norm[5] = n[i + 5] * cn2f + ci2f;
06643 norm[6] = n[i + 6] * cn2f + ci2f;
06644 norm[7] = n[i + 7] * cn2f + ci2f;
06645 norm[8] = n[i + 8] * cn2f + ci2f;
06646
06647
06648 float3 n0, n1, n2;
06649 wtrans.multnorm3d(&norm[0], (float*) &n0);
06650 wtrans.multnorm3d(&norm[3], (float*) &n1);
06651 wtrans.multnorm3d(&norm[6], (float*) &n2);
06652
06653
06654 normals[tcnt].x = packNormal(Ng);
06655 normals[tcnt].y = packNormal(n0);
06656 normals[tcnt].z = packNormal(n1);
06657 normals[tcnt].w = packNormal(n2);
06658
06659 tcnt++;
06660 }
06661
06662 rtBufferUnmap(vbuf);
06663 rtBufferUnmap(nbuf);
06664 rtBufferUnmap(cbuf);
06665
06666 RTERR( rtGeometryTrianglesCreate(ctx, &geom_hwtri) );
06667 RTERR( rtGeometryTrianglesSetPrimitiveCount(geom_hwtri, tcnt) );
06668 RTERR( rtGeometryTrianglesSetVertices(geom_hwtri, tcnt * 3, vbuf,
06669 0, sizeof(float3), RT_FORMAT_FLOAT3) );
06670 #if defined(VMDOPTIXRTXRELEASEBUFS)
06671 RTERR( rtGeometryTrianglesSetBuildFlags(geom_hwtri, RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS) );
06672 #else
06673 append_buffer(vbuf);
06674 #endif
06675
06676
06677 RTERR( rtGeometryInstanceCreate(ctx, &instance_hwtri) );
06678 RTERR( rtGeometryInstanceSetGeometryTriangles(instance_hwtri, geom_hwtri) );
06679
06680
06681 hwtri_set_vertex_flags(ctx, instance_hwtri, nbuf, cbuf, 1, 0);
06682
06683
06684 set_material(instance_hwtri, matindex, uniform_color, 1);
06685
06686
06687
06688 append_objects(nbuf, cbuf, geom_hwtri, instance_hwtri);
06689 }
06690 #endif
06691
06692
06693 void OptiXRenderer::trimesh_n3b_v3f(Matrix4 & wtrans,
06694 const float *uniform_color,
06695 const signed char *n, const float *v,
06696 int numfacets, int matindex) {
06697 if (!context_created) return;
06698
06699 #if defined(ORT_USERTXAPIS)
06700
06701 if (hwtri_enabled) {
06702 trimesh_n3b_v3f_hwtri(wtrans, uniform_color, n, v, numfacets, matindex);
06703 return;
06704 }
06705 #endif
06706
06707 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_n3b_v3f: %d...\n", numfacets);
06708 trimesh_n3b_v3f_cnt += numfacets;
06709
06710 int i, ind;
06711 RTbuffer buf;
06712 RTgeometry geom;
06713 RTgeometryinstance instance;
06714 vmd_trimesh_n3b_v3f *trimesh;
06715
06716
06717 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
06718 rtBufferSetFormat(buf, RT_FORMAT_USER);
06719 rtBufferSetElementSize(buf, sizeof(vmd_trimesh_n3b_v3f));
06720 rtBufferSetSize1D(buf, numfacets);
06721
06722 rtBufferMap(buf, (void **) &trimesh);
06723
06724 const float ci2f = 1.0f / 255.0f;
06725 const float cn2f = 1.0f / 127.5f;
06726 for (ind=0,i=0; ind<numfacets; ind++,i+=9) {
06727 float norm[9];
06728
06729
06730 wtrans.multpoint3d(v + i , (float*) &trimesh[ind].v0);
06731 wtrans.multpoint3d(v + i + 3, (float*) &trimesh[ind].v1);
06732 wtrans.multpoint3d(v + i + 6, (float*) &trimesh[ind].v2);
06733
06734
06735
06736 norm[0] = n[i ] * cn2f + ci2f;
06737 norm[1] = n[i + 1] * cn2f + ci2f;
06738 norm[2] = n[i + 2] * cn2f + ci2f;
06739 norm[3] = n[i + 3] * cn2f + ci2f;
06740 norm[4] = n[i + 4] * cn2f + ci2f;
06741 norm[5] = n[i + 5] * cn2f + ci2f;
06742 norm[6] = n[i + 6] * cn2f + ci2f;
06743 norm[7] = n[i + 7] * cn2f + ci2f;
06744 norm[8] = n[i + 8] * cn2f + ci2f;
06745
06746
06747 float3 tmpn;
06748 wtrans.multnorm3d(&norm[0], (float*) &tmpn);
06749 tmpn = tmpn * 127.5f - 0.5f;
06750 trimesh[ind].n0 = make_char4(tmpn.x, tmpn.y, tmpn.z, 0);
06751 wtrans.multnorm3d(&norm[3], (float*) &tmpn);
06752 tmpn = tmpn * 127.5f - 0.5f;
06753 trimesh[ind].n1 = make_char4(tmpn.x, tmpn.y, tmpn.z, 0);
06754 wtrans.multnorm3d(&norm[6], (float*) &tmpn);
06755 tmpn = tmpn * 127.5f - 0.5f;
06756 trimesh[ind].n2 = make_char4(tmpn.x, tmpn.y, tmpn.z, 0);
06757 }
06758 rtBufferUnmap(buf);
06759
06760 RTERR( rtGeometryCreate(ctx, &geom) );
06761 RTERR( rtGeometrySetPrimitiveCount(geom, numfacets) );
06762 RTERR( rtGeometrySetBoundingBoxProgram(geom, trimesh_n3b_v3f_bbox_pgm) );
06763 RTERR( rtGeometrySetIntersectionProgram(geom, trimesh_n3b_v3f_isct_pgm) );
06764
06765
06766 RTvariable buf_v;
06767 RTERR( rtGeometryDeclareVariable(geom, "trimesh_n3b_v3f_buffer", &buf_v) );
06768 RTERR( rtVariableSetObject(buf_v, buf) );
06769
06770
06771 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
06772 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
06773
06774 set_material(instance, matindex, uniform_color);
06775
06776 append_objects(buf, geom, instance);
06777 }
06778
06779
06780 #if defined(ORT_USERTXAPIS)
06781 void OptiXRenderer::trimesh_n3f_v3f_hwtri(Matrix4 & wtrans,
06782 const float *uniform_color,
06783 const float *n, const float *v,
06784 int numfacets, int matindex) {
06785 if (!context_created) return;
06786 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_n3f_v3f_hwtri: %d...\n", numfacets);
06787 trimesh_n3f_v3f_cnt += numfacets;
06788
06789 RTbuffer vbuf, nbuf, cbuf;
06790 RTgeometryinstance instance_hwtri;
06791 RTgeometrytriangles geom_hwtri;
06792
06793
06794 float3 *vertices;
06795 uint4 *normals;
06796 uchar4 *colors;
06797 hwtri_alloc_bufs_v3f_n4u4_c4u(ctx, numfacets, vbuf, vertices, nbuf, normals,
06798 cbuf, 1, colors, uniform_color);
06799
06800 float3 n0, n1, n2;
06801 int i, tcnt;
06802 for (i=0, tcnt=0; i < numfacets; i++) {
06803 int taddr = 3 * tcnt;
06804
06805
06806 wtrans.multpoint3d(v + 9 * i + 0, (float*) &vertices[taddr + 0]);
06807 wtrans.multpoint3d(v + 9 * i + 3, (float*) &vertices[taddr + 1]);
06808 wtrans.multpoint3d(v + 9 * i + 6, (float*) &vertices[taddr + 2]);
06809
06810
06811 float3 Ng;
06812 if (hwtri_test_calc_Ngeom(&vertices[taddr], Ng)) {
06813 continue;
06814 }
06815
06816 wtrans.multnorm3d(n + 9 * i + 0, (float*) &n0.x);
06817 wtrans.multnorm3d(n + 9 * i + 3, (float*) &n1.x);
06818 wtrans.multnorm3d(n + 9 * i + 6, (float*) &n2.x);
06819
06820
06821 normals[i].x = packNormal(Ng);
06822 normals[i].y = packNormal(n0);
06823 normals[i].z = packNormal(n1);
06824 normals[i].w = packNormal(n2);
06825
06826 tcnt++;
06827 }
06828
06829 rtBufferUnmap(vbuf);
06830 rtBufferUnmap(nbuf);
06831 rtBufferUnmap(cbuf);
06832
06833 RTERR( rtGeometryTrianglesCreate(ctx, &geom_hwtri) );
06834 RTERR( rtGeometryTrianglesSetPrimitiveCount(geom_hwtri, tcnt) );
06835 RTERR( rtGeometryTrianglesSetVertices(geom_hwtri, tcnt * 3, vbuf,
06836 0, sizeof(float3), RT_FORMAT_FLOAT3) );
06837 #if defined(VMDOPTIXRTXRELEASEBUFS)
06838 RTERR( rtGeometryTrianglesSetBuildFlags(geom_hwtri, RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS) );
06839 #else
06840 append_buffer(vbuf);
06841 #endif
06842
06843
06844 RTERR( rtGeometryInstanceCreate(ctx, &instance_hwtri) );
06845 RTERR( rtGeometryInstanceSetGeometryTriangles(instance_hwtri, geom_hwtri) );
06846
06847
06848 hwtri_set_vertex_flags(ctx, instance_hwtri, nbuf, cbuf, 1, 0);
06849
06850
06851 set_material(instance_hwtri, matindex, uniform_color, 1);
06852
06853
06854
06855 append_objects(nbuf, cbuf, geom_hwtri, instance_hwtri);
06856 }
06857 #endif
06858
06859
06860 void OptiXRenderer::trimesh_n3f_v3f(Matrix4 & wtrans,
06861 const float *uniform_color,
06862 const float *n, const float *v,
06863 int numfacets, int matindex) {
06864 if (!context_created) return;
06865
06866 #if defined(ORT_USERTXAPIS)
06867
06868 if (hwtri_enabled) {
06869 trimesh_n3f_v3f_hwtri(wtrans, uniform_color, n, v, numfacets, matindex);
06870 return;
06871 }
06872 #endif
06873
06874 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_n3f_v3f: %d...\n", numfacets);
06875 trimesh_n3f_v3f_cnt += numfacets;
06876
06877 int i, ind;
06878 RTbuffer buf;
06879 RTgeometry geom;
06880 RTgeometryinstance instance;
06881 vmd_trimesh_n3f_v3f *trimesh;
06882
06883
06884 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
06885 rtBufferSetFormat(buf, RT_FORMAT_USER);
06886 rtBufferSetElementSize(buf, sizeof(vmd_trimesh_n3f_v3f));
06887 rtBufferSetSize1D(buf, numfacets);
06888
06889 rtBufferMap(buf, (void **) &trimesh);
06890
06891 for (ind=0,i=0; ind<numfacets; ind++,i+=9) {
06892
06893 wtrans.multpoint3d(v + i , (float*) &trimesh[ind].v0);
06894 wtrans.multpoint3d(v + i + 3, (float*) &trimesh[ind].v1);
06895 wtrans.multpoint3d(v + i + 6, (float*) &trimesh[ind].v2);
06896
06897 wtrans.multnorm3d(n + i , (float*) &trimesh[ind].n0);
06898 wtrans.multnorm3d(n + i + 3, (float*) &trimesh[ind].n1);
06899 wtrans.multnorm3d(n + i + 6, (float*) &trimesh[ind].n2);
06900 }
06901 rtBufferUnmap(buf);
06902
06903 RTERR( rtGeometryCreate(ctx, &geom) );
06904 RTERR( rtGeometrySetPrimitiveCount(geom, numfacets) );
06905 RTERR( rtGeometrySetBoundingBoxProgram(geom, trimesh_n3f_v3f_bbox_pgm) );
06906 RTERR( rtGeometrySetIntersectionProgram(geom, trimesh_n3f_v3f_isct_pgm) );
06907
06908
06909 RTvariable buf_v;
06910 RTERR( rtGeometryDeclareVariable(geom, "trimesh_n3f_v3f_buffer", &buf_v) );
06911 RTERR( rtVariableSetObject(buf_v, buf) );
06912
06913
06914 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
06915 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
06916
06917 set_material(instance, matindex, uniform_color);
06918
06919 append_objects(buf, geom, instance);
06920 }
06921
06922
06923 #if defined(ORT_USERTXAPIS)
06924 void OptiXRenderer::trimesh_v3f_hwtri(Matrix4 & wtrans,
06925 const float *uniform_color,
06926 const float *v,
06927 int numfacets, int matindex) {
06928 if (!context_created) return;
06929 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_v3f_hwtri: %d...\n", numfacets);
06930 trimesh_v3f_cnt += numfacets;
06931
06932 RTbuffer vbuf, nbuf, cbuf;
06933 RTgeometryinstance instance_hwtri;
06934 RTgeometrytriangles geom_hwtri;
06935
06936
06937 float3 *vertices;
06938 uint4 *normals;
06939 uchar4 *colors;
06940 hwtri_alloc_bufs_v3f_n4u4_c4u(ctx, numfacets, vbuf, vertices, nbuf, normals,
06941 cbuf, 1, colors, uniform_color);
06942
06943 int i, tcnt;
06944 for (i=0, tcnt=0; i < numfacets; i++) {
06945 int taddr = 3 * tcnt;
06946
06947
06948 wtrans.multpoint3d(v + 9 * i + 0, (float*) &vertices[taddr + 0]);
06949 wtrans.multpoint3d(v + 9 * i + 3, (float*) &vertices[taddr + 1]);
06950 wtrans.multpoint3d(v + 9 * i + 6, (float*) &vertices[taddr + 2]);
06951
06952
06953 float3 Ng;
06954 if (hwtri_test_calc_Ngeom(&vertices[taddr], Ng)) {
06955 continue;
06956 }
06957
06958
06959 normals[i].x = packNormal(Ng);
06960
06961
06962
06963 tcnt++;
06964 }
06965
06966 rtBufferUnmap(vbuf);
06967 rtBufferUnmap(nbuf);
06968 rtBufferUnmap(cbuf);
06969
06970 RTERR( rtGeometryTrianglesCreate(ctx, &geom_hwtri) );
06971 RTERR( rtGeometryTrianglesSetPrimitiveCount(geom_hwtri, tcnt) );
06972 RTERR( rtGeometryTrianglesSetVertices(geom_hwtri, tcnt * 3, vbuf,
06973 0, sizeof(float3), RT_FORMAT_FLOAT3) );
06974 #if defined(VMDOPTIXRTXRELEASEBUFS)
06975 RTERR( rtGeometryTrianglesSetBuildFlags(geom_hwtri, RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS) );
06976 #else
06977 append_buffer(vbuf);
06978 #endif
06979
06980
06981 RTERR( rtGeometryInstanceCreate(ctx, &instance_hwtri) );
06982 RTERR( rtGeometryInstanceSetGeometryTriangles(instance_hwtri, geom_hwtri) );
06983
06984
06985 hwtri_set_vertex_flags(ctx, instance_hwtri, nbuf, cbuf, 0, 0);
06986
06987
06988 set_material(instance_hwtri, matindex, uniform_color, 1);
06989
06990
06991
06992 append_objects(nbuf, cbuf, geom_hwtri, instance_hwtri);
06993 }
06994 #endif
06995
06996
06997 void OptiXRenderer::trimesh_v3f(Matrix4 & wtrans, const float *uniform_color,
06998 const float *v, int numfacets, int matindex) {
06999 if (!context_created) return;
07000
07001 #if defined(ORT_USERTXAPIS)
07002
07003 if (hwtri_enabled) {
07004 trimesh_v3f_hwtri(wtrans, uniform_color, v, numfacets, matindex);
07005 return;
07006 }
07007 #endif
07008
07009 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating trimesh_v3f: %d...\n", numfacets);
07010 trimesh_v3f_cnt += numfacets;
07011
07012 long i, ind;
07013 RTbuffer buf;
07014 RTgeometry geom;
07015 RTgeometryinstance instance;
07016 vmd_trimesh_v3f *trimesh;
07017
07018
07019 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
07020 rtBufferSetFormat(buf, RT_FORMAT_USER);
07021 rtBufferSetElementSize(buf, sizeof(vmd_trimesh_v3f));
07022 rtBufferSetSize1D(buf, numfacets);
07023
07024 rtBufferMap(buf, (void **) &trimesh);
07025
07026 for (ind=0,i=0; ind<numfacets; ind++,i+=9) {
07027
07028 wtrans.multpoint3d(v + i , (float*) &trimesh[ind].v0);
07029 wtrans.multpoint3d(v + i + 3, (float*) &trimesh[ind].v1);
07030 wtrans.multpoint3d(v + i + 6, (float*) &trimesh[ind].v2);
07031 }
07032 rtBufferUnmap(buf);
07033
07034 RTERR( rtGeometryCreate(ctx, &geom) );
07035 RTERR( rtGeometrySetPrimitiveCount(geom, numfacets) );
07036 RTERR( rtGeometrySetBoundingBoxProgram(geom, trimesh_v3f_bbox_pgm) );
07037 RTERR( rtGeometrySetIntersectionProgram(geom, trimesh_v3f_isct_pgm) );
07038
07039
07040 RTvariable buf_v;
07041 RTERR( rtGeometryDeclareVariable(geom, "trimesh_v3f_buffer", &buf_v) );
07042 RTERR( rtVariableSetObject(buf_v, buf) );
07043
07044
07045 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
07046 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
07047
07048 set_material(instance, matindex, uniform_color);
07049
07050 append_objects(buf, geom, instance);
07051 }
07052
07053
07054 #if defined(ORT_USERTXAPIS)
07055 void OptiXRenderer::tristrip_hwtri(Matrix4 & wtrans, int numverts,
07056 const float * cnv,
07057 int numstrips, const int *vertsperstrip,
07058 const int *facets, int matindex) {
07059 if (!context_created) return;
07060 int i;
07061 int numfacets = 0;
07062 for (i=0; i<numstrips; i++)
07063 numfacets += (vertsperstrip[i] - 2);
07064
07065 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating tristrip_hwtri: %d...\n", numfacets);
07066 tricolor_cnt += numfacets;
07067
07068 RTbuffer vbuf, nbuf, cbuf;
07069 RTgeometryinstance instance_hwtri;
07070 RTgeometrytriangles geom_hwtri;
07071
07072
07073 float3 *vertices;
07074 uint4 *normals;
07075 uchar4 *colors;
07076 hwtri_alloc_bufs_v3f_n4u4_c4u(ctx, numfacets, vbuf, vertices, nbuf, normals,
07077 cbuf, numfacets * 3, colors, NULL);
07078
07079
07080
07081
07082 int strip, t, v = 0;
07083 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
07084
07085
07086 int tcnt=0;
07087 for (strip=0; strip < numstrips; strip++) {
07088
07089 for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
07090 int taddr = 3 * tcnt;
07091
07092
07093 int v0 = facets[v + (stripaddr[t & 0x01][0])] * 10;
07094 int v1 = facets[v + (stripaddr[t & 0x01][1])] * 10;
07095 int v2 = facets[v + (stripaddr[t & 0x01][2])] * 10;
07096
07097
07098 wtrans.multpoint3d(cnv + v0 + 7, (float*) &vertices[taddr + 0]);
07099 wtrans.multpoint3d(cnv + v1 + 7, (float*) &vertices[taddr + 1]);
07100 wtrans.multpoint3d(cnv + v2 + 7, (float*) &vertices[taddr + 2]);
07101
07102
07103 float3 Ng;
07104 if (hwtri_test_calc_Ngeom(&vertices[taddr], Ng)) {
07105 v++;
07106 continue;
07107 }
07108
07109 float3 n0, n1, n2;
07110 wtrans.multnorm3d(cnv + v0 + 4, (float*) &n0);
07111 wtrans.multnorm3d(cnv + v1 + 4, (float*) &n1);
07112 wtrans.multnorm3d(cnv + v2 + 4, (float*) &n2);
07113
07114
07115 normals[tcnt].x = packNormal(Ng);
07116 normals[tcnt].y = packNormal(n0);
07117 normals[tcnt].z = packNormal(n1);
07118 normals[tcnt].w = packNormal(n2);
07119
07120
07121 colors[taddr + 0].x = cnv[v0 + 0] * 255.0f;
07122 colors[taddr + 0].y = cnv[v0 + 1] * 255.0f;
07123 colors[taddr + 0].z = cnv[v0 + 2] * 255.0f;
07124
07125 colors[taddr + 1].x = cnv[v1 + 0] * 255.0f;
07126 colors[taddr + 1].y = cnv[v1 + 1] * 255.0f;
07127 colors[taddr + 1].z = cnv[v1 + 2] * 255.0f;
07128
07129 colors[taddr + 2].x = cnv[v2 + 0] * 255.0f;
07130 colors[taddr + 2].y = cnv[v2 + 1] * 255.0f;
07131 colors[taddr + 2].z = cnv[v2 + 2] * 255.0f;
07132
07133 v++;
07134 tcnt++;
07135 }
07136 v+=2;
07137 }
07138
07139 rtBufferUnmap(vbuf);
07140 rtBufferUnmap(nbuf);
07141 rtBufferUnmap(cbuf);
07142
07143 RTERR( rtGeometryTrianglesCreate(ctx, &geom_hwtri) );
07144 RTERR( rtGeometryTrianglesSetPrimitiveCount(geom_hwtri, tcnt) );
07145 RTERR( rtGeometryTrianglesSetVertices(geom_hwtri, tcnt * 3, vbuf,
07146 0, sizeof(float3), RT_FORMAT_FLOAT3) );
07147 #if defined(VMDOPTIXRTXRELEASEBUFS)
07148 RTERR( rtGeometryTrianglesSetBuildFlags(geom_hwtri, RT_GEOMETRY_BUILD_FLAG_RELEASE_BUFFERS) );
07149 #else
07150 append_buffer(vbuf);
07151 #endif
07152
07153
07154 RTERR( rtGeometryInstanceCreate(ctx, &instance_hwtri) );
07155 RTERR( rtGeometryInstanceSetGeometryTriangles(instance_hwtri, geom_hwtri) );
07156
07157
07158 hwtri_set_vertex_flags(ctx, instance_hwtri, nbuf, cbuf, 1, 1);
07159
07160
07161 set_material(instance_hwtri, matindex, NULL, 1);
07162
07163
07164
07165 append_objects(nbuf, cbuf, geom_hwtri, instance_hwtri);
07166 }
07167 #endif
07168
07169
07170 void OptiXRenderer::tristrip(Matrix4 & wtrans, int numverts, const float * cnv,
07171 int numstrips, const int *vertsperstrip,
07172 const int *facets, int matindex) {
07173 if (!context_created) return;
07174 int i;
07175 int numfacets = 0;
07176 for (i=0; i<numstrips; i++)
07177 numfacets += (vertsperstrip[i] - 2);
07178
07179 #if defined(ORT_USERTXAPIS)
07180
07181 if (hwtri_enabled) {
07182 tristrip_hwtri(wtrans, numverts, cnv, numstrips,
07183 vertsperstrip, facets, matindex);
07184 return;
07185 }
07186 #endif
07187
07188 if (verbose == RT_VERB_DEBUG) printf("OptiXRenderer) creating tristrip: %d...\n", numfacets);
07189 tricolor_cnt += numfacets;
07190
07191 RTbuffer buf;
07192 RTgeometry geom;
07193 RTgeometryinstance instance;
07194 vmd_tricolor *trimesh;
07195
07196
07197 rtBufferCreate(ctx, RT_BUFFER_INPUT, &buf);
07198 rtBufferSetFormat(buf, RT_FORMAT_USER);
07199 rtBufferSetElementSize(buf, sizeof(vmd_tricolor));
07200 rtBufferSetSize1D(buf, numfacets);
07201
07202 rtBufferMap(buf, (void **) &trimesh);
07203
07204
07205
07206
07207 int strip, t, v = 0;
07208 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
07209
07210
07211 i=0;
07212 for (strip=0; strip < numstrips; strip++) {
07213
07214 for (t = 0; t < (vertsperstrip[strip] - 2); t++) {
07215
07216 int v0 = facets[v + (stripaddr[t & 0x01][0])] * 10;
07217 int v1 = facets[v + (stripaddr[t & 0x01][1])] * 10;
07218 int v2 = facets[v + (stripaddr[t & 0x01][2])] * 10;
07219
07220
07221 wtrans.multpoint3d(cnv + v0 + 7, (float*) &trimesh[i].v0);
07222 wtrans.multpoint3d(cnv + v1 + 7, (float*) &trimesh[i].v1);
07223 wtrans.multpoint3d(cnv + v2 + 7, (float*) &trimesh[i].v2);
07224
07225 wtrans.multnorm3d(cnv + v0 + 4, (float*) &trimesh[i].n0);
07226 wtrans.multnorm3d(cnv + v1 + 4, (float*) &trimesh[i].n1);
07227 wtrans.multnorm3d(cnv + v2 + 4, (float*) &trimesh[i].n2);
07228
07229 vec_copy((float*) &trimesh[i].c0, cnv + v0);
07230 vec_copy((float*) &trimesh[i].c1, cnv + v1);
07231 vec_copy((float*) &trimesh[i].c2, cnv + v2);
07232
07233 v++;
07234 i++;
07235 }
07236 v+=2;
07237 }
07238 rtBufferUnmap(buf);
07239
07240 RTERR( rtGeometryCreate(ctx, &geom) );
07241 RTERR( rtGeometrySetPrimitiveCount(geom, numfacets) );
07242 RTERR( rtGeometrySetBoundingBoxProgram(geom, tricolor_bbox_pgm) );
07243 RTERR( rtGeometrySetIntersectionProgram(geom, tricolor_isct_pgm) );
07244
07245
07246 RTvariable buf_v;
07247 RTERR( rtGeometryDeclareVariable(geom, "tricolor_buffer", &buf_v) );
07248 RTERR( rtVariableSetObject(buf_v, buf) );
07249
07250
07251 RTERR( rtGeometryInstanceCreate(ctx, &instance) );
07252 RTERR( rtGeometryInstanceSetGeometry(instance, geom) );
07253
07254 set_material(instance, matindex, NULL);
07255
07256 append_objects(buf, geom, instance);
07257 }
07258
07259
07260 #if !defined(VMDOPENGL)
07261
07262
07263
07264
07265
07266
07267
07268
07269
07270
07271
07272
07273 extern "C" {
07274 typedef struct {
07275 unsigned int sequence;
07276 } xcb_void_cookie_t;
07277 static xcb_void_cookie_t fake_cookie = { 0 };
07278 xcb_void_cookie_t xcb_glx_set_client_info_arb(void) {
07279 return fake_cookie;
07280 }
07281 xcb_void_cookie_t xcb_glx_create_context_attribs_arb_checked(void) {
07282 return fake_cookie;
07283 }
07284 xcb_void_cookie_t xcb_glx_set_client_info_2arb(void) {
07285 return fake_cookie;
07286 }
07287 }
07288 #endif
07289
07290
07291