Blue Brain BioExplorer
OptiXContext.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2024, EPFL/Blue Brain Project
3  *
4  * The Blue Brain BioExplorer is a tool for scientists to extract and analyse
5  * scientific data from visualization
6  *
7  * This file is part of Blue Brain BioExplorer <https://github.com/BlueBrain/BioExplorer>
8  *
9  * This library is free software; you can redistribute it and/or modify it under
10  * the terms of the GNU Lesser General Public License version 3.0 as published
11  * by the Free Software Foundation.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #include "OptiXContext.h"
24 #include "Logs.h"
25 #include "OptiXCameraProgram.h"
26 #include "OptiXCommonStructs.h"
27 #include "OptiXTypes.h"
28 #include "OptiXUtils.h"
29 
30 #include <platform/engines/optix6/OptiX6Engine_generated_Cones.cu.ptx.h>
31 #include <platform/engines/optix6/OptiX6Engine_generated_Cylinders.cu.ptx.h>
32 #include <platform/engines/optix6/OptiX6Engine_generated_Fields.cu.ptx.h>
33 #include <platform/engines/optix6/OptiX6Engine_generated_SDFGeometries.cu.ptx.h>
34 #include <platform/engines/optix6/OptiX6Engine_generated_Spheres.cu.ptx.h>
35 #include <platform/engines/optix6/OptiX6Engine_generated_Streamlines.cu.ptx.h>
36 #include <platform/engines/optix6/OptiX6Engine_generated_TriangleMesh.cu.ptx.h>
37 #include <platform/engines/optix6/OptiX6Engine_generated_Volumes.cu.ptx.h>
38 
40 
41 namespace
42 {
43 static const char* CUDA_SPHERES = OptiX6Engine_generated_Spheres_cu_ptx;
44 static const char* CUDA_CYLINDERS = OptiX6Engine_generated_Cylinders_cu_ptx;
45 static const char* CUDA_CONES = OptiX6Engine_generated_Cones_cu_ptx;
46 static const char* CUDA_SDF_GEOMETRIES = OptiX6Engine_generated_SDFGeometries_cu_ptx;
47 static const char* CUDA_TRIANGLES_MESH = OptiX6Engine_generated_TriangleMesh_cu_ptx;
48 static const char* CUDA_VOLUMES = OptiX6Engine_generated_Volumes_cu_ptx;
49 static const char* CUDA_STREAMLINES = OptiX6Engine_generated_Streamlines_cu_ptx;
50 static const char* CUDA_FIELDS = OptiX6Engine_generated_Fields_cu_ptx;
51 
52 template <typename T>
53 T white();
54 
55 template <>
56 uint8 white()
57 {
58  return 255;
59 }
60 
61 template <>
62 float white()
63 {
64  return 1.f;
65 }
66 
67 template <typename T>
68 void textureToOptix(T* ptr_dst, const core::Texture2D& texture, const uint8_t face, const uint8_t mipLevel,
69  const bool hasAlpha)
70 {
71  uint16_t width = texture.width;
72  uint16_t height = texture.height;
73  for (uint8_t i = 0; i < mipLevel; ++i)
74  {
75  width /= 2;
76  height /= 2;
77  }
78  size_t idx_src = 0;
79  size_t idx_dst = 0;
80  const auto rawData = texture.getRawData<T>(face, mipLevel);
81  for (uint16_t y = 0; y < height; ++y)
82  {
83  for (uint16_t x = 0; x < width; ++x)
84  {
85  ptr_dst[idx_dst] = rawData[idx_src];
86  ptr_dst[idx_dst + 1u] = rawData[idx_src + 1u];
87  ptr_dst[idx_dst + 2u] = rawData[idx_src + 2u];
88  ptr_dst[idx_dst + 3u] = hasAlpha ? rawData[idx_src + 3u] : white<T>();
89  idx_dst += 4u;
90  idx_src += hasAlpha ? 4u : 3u;
91  }
92  }
93 }
94 
95 RTwrapmode wrapModeToOptix(const core::TextureWrapMode mode)
96 {
97  switch (mode)
98  {
100  return RT_WRAP_CLAMP_TO_BORDER;
102  return RT_WRAP_CLAMP_TO_EDGE;
104  return RT_WRAP_MIRROR;
106  default:
107  return RT_WRAP_REPEAT;
108  }
109 }
110 
111 } // namespace
112 
113 #define RT_CHECK_ERROR_NO_CONTEXT(func) \
114  do \
115  { \
116  RTresult code = func; \
117  if (code != RT_SUCCESS) \
118  throw std::runtime_error("Optix error in function '" + std::string(#func) + "'"); \
119  } while (0)
120 
121 namespace core
122 {
123 namespace engine
124 {
125 namespace optix
126 {
127 std::unique_ptr<OptiXContext> OptiXContext::_context;
128 
129 OptiXContext::OptiXContext()
130 {
131  _printSystemInformation();
132  _initialize();
133 }
134 
136 {
137  _rendererPrograms.clear();
138  _cameraPrograms.clear();
139  RT_DESTROY_MAP(_optixBoundsPrograms);
140  RT_DESTROY_MAP(_optixIntersectionPrograms);
141  RT_DESTROY_MAP(_optixTextureSamplers);
142  RT_DESTROY(_optixContext);
143 }
144 
146 {
147  if (!_context)
148  _context.reset(new OptiXContext);
149 
150  return *_context;
151 }
152 
153 ::optix::Material OptiXContext::createMaterial()
154 {
155  return _optixContext->createMaterial();
156 }
157 
158 void OptiXContext::addRenderer(const std::string& name, OptiXShaderProgramPtr program)
159 {
160  _rendererPrograms[name] = program;
161 }
162 
164 {
165  auto it = _rendererPrograms.find(name);
166  if (it == _rendererPrograms.end())
167  throw std::runtime_error("Shader program not found for renderer '" + name + "'");
168  return it->second;
169 }
170 
171 void OptiXContext::addCamera(const std::string& name, OptiXCameraProgramPtr program)
172 {
173  _cameraPrograms[name] = program;
174 }
175 
177 {
178  auto it = _cameraPrograms.find(name);
179  if (it == _cameraPrograms.end())
180  throw std::runtime_error("Camera program not found for camera '" + name + "'");
181  return it->second;
182 }
183 
184 void OptiXContext::setCamera(const std::string& name)
185 {
186  auto camera = getCamera(name);
187  _optixContext->setRayGenerationProgram(0, camera->getRayGenerationProgram());
188  _optixContext->setMissProgram(0, camera->getMissProgram());
189  _optixContext->setExceptionProgram(0, camera->getExceptionProgram());
190 }
191 
192 ::optix::TextureSampler OptiXContext::createTextureSampler(Texture2DPtr texture)
193 {
194  uint16_t nx = texture->width;
195  uint16_t ny = texture->height;
196  const uint16_t channels = texture->channels;
197  const uint16_t optixChannels = 4;
198  const bool hasAlpha = optixChannels == channels;
199 
200  const bool useFloat = texture->depth == 4;
201  const bool useByte = texture->depth == 1;
202 
203  if (!useFloat && !useByte)
204  throw std::runtime_error("Only byte or float textures are supported");
205 
206  const bool createMipmaps = texture->getMipLevels() == 1 && useByte && !texture->isCubeMap();
207  uint16_t mipMapLevels = texture->getMipLevels();
208  if (createMipmaps)
209  mipMapLevels = texture->getPossibleMipMapsLevels();
210 
211  if (createMipmaps && !useByte)
212  throw std::runtime_error(
213  "Non 8-bits textures are not supported for automatic mipmaps "
214  "generation");
215 
216  RTformat optixFormat = useByte ? RT_FORMAT_UNSIGNED_BYTE4 : RT_FORMAT_FLOAT4;
217 
218  // Create texture sampler
219  ::optix::TextureSampler sampler = _optixContext->createTextureSampler();
220  const auto wrapMode = wrapModeToOptix(texture->getWrapMode());
221  sampler->setWrapMode(0, wrapMode);
222  sampler->setWrapMode(1, wrapMode);
223  sampler->setWrapMode(2, wrapMode);
224  sampler->setIndexingMode(RT_TEXTURE_INDEX_NORMALIZED_COORDINATES);
225  sampler->setReadMode(RT_TEXTURE_READ_NORMALIZED_FLOAT);
226  sampler->setMaxAnisotropy(8.0f);
227 
228  // Create buffer and populate with texture data
229  ::optix::Buffer buffer;
230  if (texture->isCubeMap())
231  buffer = _optixContext->createCubeBuffer(RT_BUFFER_INPUT, optixFormat, nx, ny, mipMapLevels);
232  else
233  buffer = _optixContext->createMipmappedBuffer(RT_BUFFER_INPUT, optixFormat, nx, ny, mipMapLevels);
234 
235  std::vector<void*> mipMapBuffers(mipMapLevels);
236  for (uint8_t currentLevel = 0u; currentLevel < mipMapLevels; ++currentLevel)
237  mipMapBuffers[currentLevel] = buffer->map(currentLevel);
238 
239  if (createMipmaps)
240  {
241  uint8_t* ptr_dst = (uint8_t*)mipMapBuffers[0];
242  size_t idx_src = 0;
243  size_t idx_dst = 0;
244  const auto rawData = texture->getRawData<unsigned char>();
245  for (uint16_t y = 0; y < ny; ++y)
246  {
247  for (uint16_t x = 0; x < nx; ++x)
248  {
249  ptr_dst[idx_dst] = rawData[idx_src];
250  ptr_dst[idx_dst + 1u] = rawData[idx_src + 1u];
251  ptr_dst[idx_dst + 2u] = rawData[idx_src + 2u];
252  ptr_dst[idx_dst + 3u] = hasAlpha ? rawData[idx_src + 3u] : 255u;
253  idx_dst += 4u;
254  idx_src += hasAlpha ? 4u : 3u;
255  }
256  }
257  ny /= 2u;
258  nx /= 2u;
259 
260  for (uint8_t currentLevel = 1u; currentLevel < mipMapLevels; ++currentLevel)
261  {
262  ptr_dst = (uint8_t*)mipMapBuffers[currentLevel];
263  uint8_t* ptr_src = (uint8_t*)mipMapBuffers[currentLevel - 1u];
264  for (uint16_t y = 0u; y < ny; ++y)
265  {
266  for (uint16_t x = 0u; x < nx; ++x)
267  {
268  ptr_dst[(y * nx + x) * 4u] =
269  (ptr_src[(y * 2u * nx + x) * 8u] + ptr_src[((y * 2u * nx + x) * 2u + 1u) * 4u] +
270  ptr_src[((y * 2u + 1u) * nx + x) * 8u] + ptr_src[(((y * 2u + 1u) * nx + x) * 2u + 1u) * 4u]) /
271  4.0f;
272  ptr_dst[(y * nx + x) * 4u + 1u] =
273  (ptr_src[(y * 2u * nx + x) * 8u + 1u] + ptr_src[((y * 2u * nx + x) * 2u + 1u) * 4u + 1u] +
274  ptr_src[((y * 2u + 1u) * nx + x) * 8u + 1u] +
275  ptr_src[(((y * 2u + 1u) * nx + x) * 2u + 1u) * 4u + 1u]) /
276  4.0f;
277  ptr_dst[(y * nx + x) * 4u + 2u] =
278  (ptr_src[(y * 2u * nx + x) * 8u + 2u] + ptr_src[((y * 2u * nx + x) * 2u + 1u) * 4u + 2u] +
279  ptr_src[((y * 2u + 1u) * nx + x) * 8u + 2u] +
280  ptr_src[(((y * 2u + 1u) * nx + x) * 2u + 1u) * 4u + 2u]) /
281  4.0f;
282  ptr_dst[(y * nx + x) * 4u + 3u] =
283  (ptr_src[(y * 2u * nx + x) * 8u + 3u] + ptr_src[((y * 2u * nx + x) * 2u + 1u) * 4u + 3u] +
284  ptr_src[((y * 2u + 1u) * nx + x) * 8u + 3u] +
285  ptr_src[(((y * 2u + 1u) * nx + x) * 2u + 1u) * 4u + 3u]) /
286  4.0f;
287 
288  if (texture->isNormalMap())
289  {
290  glm::vec3 normalized =
291  glm::normalize(glm::vec3(2.0f * (float)ptr_dst[(y * nx + x) * 4u] / 255.0f - 1.0f,
292  2.0f * (float)ptr_dst[(y * nx + x) * 4u + 1u] / 255.0f - 1.0f,
293  2.0f * (float)ptr_dst[(y * nx + x) * 4u + 2u] / 255.0f - 1.0f));
294  ptr_dst[(y * nx + x) * 4u] = 255.0f * (0.5f * normalized.x + 0.5f);
295  ptr_dst[(y * nx + x) * 4u + 1u] = 255.0f * (0.5f * normalized.y + 0.5f);
296  ptr_dst[(y * nx + x) * 4u + 2u] = 255.0f * (0.5f * normalized.z + 0.5f);
297  }
298  }
299  }
300  ny /= 2u;
301  nx /= 2u;
302  }
303  }
304  else
305  {
306  for (uint8_t face = 0; face < texture->getNumFaces(); ++face)
307  {
308  auto mipWidth = nx;
309  auto mipHeight = ny;
310  for (uint16_t mip = 0; mip < mipMapLevels; ++mip)
311  {
312  if (useByte)
313  {
314  auto dst = (uint8_t*)mipMapBuffers[mip];
315  dst += face * mipWidth * mipHeight * 4;
316  textureToOptix<uint8_t>(dst, *texture, face, mip, hasAlpha);
317  }
318  else if (useFloat)
319  {
320  auto dst = (float*)mipMapBuffers[mip];
321  dst += face * mipWidth * mipHeight * 4;
322  textureToOptix<float>(dst, *texture, face, mip, hasAlpha);
323  }
324  mipWidth /= 2;
325  mipHeight /= 2;
326  }
327  }
328  }
329 
330  for (uint8_t currentLevel = 0u; currentLevel < mipMapLevels; ++currentLevel)
331  buffer->unmap(currentLevel);
332 
333  // Assign buffer to sampler
334  sampler->setBuffer(buffer);
335  sampler->setFilteringModes(RT_FILTER_LINEAR, RT_FILTER_LINEAR,
336  mipMapLevels > 1 ? RT_FILTER_LINEAR : RT_FILTER_NONE);
337  sampler->validate();
338  return sampler;
339 }
340 
341 void OptiXContext::_initialize()
342 {
343  PLUGIN_DEBUG("Creating context...");
344  _optixContext = ::optix::Context::create();
345 
346  if (!_optixContext)
347  throw(std::runtime_error("Failed to initialize OptiX"));
348 
349 #ifdef NDEBUG
350  _optixContext->setPrintEnabled(false);
351 #else
352  _optixContext->setPrintEnabled(true);
353  _optixContext->setPrintBufferSize(1024);
354 #endif
355 
356  _optixContext->setRayTypeCount(OPTIX_RAY_TYPE_COUNT);
357  _optixContext->setEntryPointCount(OPTIX_ENTRY_POINT_COUNT);
358  _optixContext->setStackSize(OPTIX_STACK_SIZE);
359  _optixContext->setMaxTraceDepth(DEFAULT_RENDERER_MAX_RAY_DEPTH);
360 
361  _optixBoundsPrograms[OptixGeometryType::cone] =
362  _optixContext->createProgramFromPTXString(CUDA_CONES, OPTIX_CUDA_FUNCTION_BOUNDS);
363  _optixIntersectionPrograms[OptixGeometryType::cone] =
364  _optixContext->createProgramFromPTXString(CUDA_CONES, OPTIX_CUDA_FUNCTION_INTERSECTION);
365 
366  _optixBoundsPrograms[OptixGeometryType::cylinder] =
367  _optixContext->createProgramFromPTXString(CUDA_CYLINDERS, OPTIX_CUDA_FUNCTION_BOUNDS);
368  _optixIntersectionPrograms[OptixGeometryType::cylinder] =
369  _optixContext->createProgramFromPTXString(CUDA_CYLINDERS, OPTIX_CUDA_FUNCTION_INTERSECTION);
370 
371  _optixBoundsPrograms[OptixGeometryType::sphere] =
372  _optixContext->createProgramFromPTXString(CUDA_SPHERES, OPTIX_CUDA_FUNCTION_BOUNDS);
373  _optixIntersectionPrograms[OptixGeometryType::sphere] =
374  _optixContext->createProgramFromPTXString(CUDA_SPHERES, OPTIX_CUDA_FUNCTION_INTERSECTION);
375 
376  _optixBoundsPrograms[OptixGeometryType::triangleMesh] =
377  _optixContext->createProgramFromPTXString(CUDA_TRIANGLES_MESH, OPTIX_CUDA_FUNCTION_BOUNDS);
378  _optixIntersectionPrograms[OptixGeometryType::triangleMesh] =
379  _optixContext->createProgramFromPTXString(CUDA_TRIANGLES_MESH, OPTIX_CUDA_FUNCTION_INTERSECTION);
380 
381  _optixBoundsPrograms[OptixGeometryType::volume] =
382  _optixContext->createProgramFromPTXString(CUDA_VOLUMES, OPTIX_CUDA_FUNCTION_BOUNDS);
383  _optixIntersectionPrograms[OptixGeometryType::volume] =
384  _optixContext->createProgramFromPTXString(CUDA_VOLUMES, OPTIX_CUDA_FUNCTION_INTERSECTION);
385  _optixContext[CONTEXT_VOLUME_SIZE]->setUint(sizeof(VolumeGeometry) / sizeof(float));
386 
387  _optixBoundsPrograms[OptixGeometryType::streamline] =
388  _optixContext->createProgramFromPTXString(CUDA_STREAMLINES, OPTIX_CUDA_FUNCTION_BOUNDS);
389  _optixIntersectionPrograms[OptixGeometryType::streamline] =
390  _optixContext->createProgramFromPTXString(CUDA_STREAMLINES, OPTIX_CUDA_FUNCTION_INTERSECTION);
391 
392  _optixBoundsPrograms[OptixGeometryType::sdfGeometry] =
393  _optixContext->createProgramFromPTXString(CUDA_SDF_GEOMETRIES, OPTIX_CUDA_FUNCTION_BOUNDS);
394  _optixIntersectionPrograms[OptixGeometryType::sdfGeometry] =
395  _optixContext->createProgramFromPTXString(CUDA_SDF_GEOMETRIES, OPTIX_CUDA_FUNCTION_INTERSECTION);
396 
397  _optixBoundsPrograms[OptixGeometryType::field] =
398  _optixContext->createProgramFromPTXString(CUDA_FIELDS, OPTIX_CUDA_FUNCTION_BOUNDS);
399  _optixIntersectionPrograms[OptixGeometryType::field] =
400  _optixContext->createProgramFromPTXString(CUDA_FIELDS, OPTIX_CUDA_FUNCTION_INTERSECTION);
401  _optixContext[CONTEXT_FIELD_SIZE]->setUint(sizeof(FieldGeometry) / sizeof(float));
402 
403  // Exceptions
404  _optixContext[CONTEXT_EXCEPTION_BAD_COLOR]->setFloat(1.0f, 0.0f, 0.0f, 1.f);
405  PLUGIN_DEBUG("Context created");
406 }
407 
408 void OptiXContext::_printSystemInformation() const
409 {
410  unsigned int optixVersion;
411  RT_CHECK_ERROR_NO_CONTEXT(rtGetVersion(&optixVersion));
412 
413  unsigned int major = optixVersion / 1000; // Check major with old formula.
414  unsigned int minor;
415  unsigned int micro;
416  if (3 < major) // New encoding since OptiX 4.0.0 to get two digits micro
417  // numbers?
418  {
419  major = optixVersion / 10000;
420  minor = (optixVersion % 10000) / 100;
421  micro = optixVersion % 100;
422  }
423  else // Old encoding with only one digit for the micro number.
424  {
425  minor = (optixVersion % 1000) / 10;
426  micro = optixVersion % 10;
427  }
428  PLUGIN_INFO("OptiX " << major << "." << minor << "." << micro);
429 
430  unsigned int numberOfDevices = 0;
431  RT_CHECK_ERROR_NO_CONTEXT(rtDeviceGetDeviceCount(&numberOfDevices));
432  PLUGIN_INFO("Number of Devices = " << numberOfDevices);
433 
434  for (unsigned int i = 0; i < numberOfDevices; ++i)
435  {
436  char name[256];
437  RT_CHECK_ERROR_NO_CONTEXT(rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_NAME, sizeof(name), name));
438  PLUGIN_INFO("Device " << i << ": " << name);
439 
440  int computeCapability[2] = {0, 0};
441  RT_CHECK_ERROR_NO_CONTEXT(rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY,
442  sizeof(computeCapability), &computeCapability));
443  PLUGIN_INFO(" Compute Support: " << computeCapability[0] << "." << computeCapability[1]);
444 
445  RTsize totalMemory = 0;
447  rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_TOTAL_MEMORY, sizeof(totalMemory), &totalMemory));
448  PLUGIN_INFO(" Total Memory: " << (unsigned long long)(totalMemory / 1024 / 1024) << " MB");
449 
450  int clockRate = 0;
452  rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_CLOCK_RATE, sizeof(clockRate), &clockRate));
453  PLUGIN_INFO(" Clock Rate: " << (clockRate / 1000) << " MHz");
454 
455  int maxThreadsPerBlock = 0;
456  RT_CHECK_ERROR_NO_CONTEXT(rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK,
457  sizeof(maxThreadsPerBlock), &maxThreadsPerBlock));
458  PLUGIN_INFO(" Max. Threads per Block: " << maxThreadsPerBlock);
459 
460  int smCount = 0;
462  rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, sizeof(smCount), &smCount));
463  PLUGIN_INFO(" Streaming Multiprocessor Count: " << smCount);
464 
465  int executionTimeoutEnabled = 0;
466  RT_CHECK_ERROR_NO_CONTEXT(rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_EXECUTION_TIMEOUT_ENABLED,
467  sizeof(executionTimeoutEnabled), &executionTimeoutEnabled));
468  PLUGIN_INFO(" Execution Timeout Enabled: " << executionTimeoutEnabled);
469 
470  int maxHardwareTextureCount = 0;
471  RT_CHECK_ERROR_NO_CONTEXT(rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_MAX_HARDWARE_TEXTURE_COUNT,
472  sizeof(maxHardwareTextureCount), &maxHardwareTextureCount));
473  PLUGIN_INFO(" Max. Hardware Texture Count: " << maxHardwareTextureCount);
474 
475  int tccDriver = 0;
477  rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_TCC_DRIVER, sizeof(tccDriver), &tccDriver));
478  PLUGIN_INFO(" TCC Driver enabled: " << tccDriver);
479 
480  int cudaDeviceOrdinal = 0;
481  RT_CHECK_ERROR_NO_CONTEXT(rtDeviceGetAttribute(i, RT_DEVICE_ATTRIBUTE_CUDA_DEVICE_ORDINAL,
482  sizeof(cudaDeviceOrdinal), &cudaDeviceOrdinal));
483  PLUGIN_INFO(" CUDA Device Ordinal: " << cudaDeviceOrdinal);
484  }
485 }
486 
487 ::optix::Geometry OptiXContext::createGeometry(const OptixGeometryType type)
488 {
489  ::optix::Geometry geometry = _optixContext->createGeometry();
490  geometry->setBoundingBoxProgram(_optixBoundsPrograms[type]);
491  geometry->setIntersectionProgram(_optixIntersectionPrograms[type]);
492  return geometry;
493 }
494 
495 ::optix::GeometryGroup OptiXContext::createGeometryGroup(const bool compact)
496 {
497  auto group = _optixContext->createGeometryGroup();
498  auto accel =
499  _optixContext->createAcceleration(compact ? OPTIX_ACCELERATION_TYPE_SBVH : DEFAULT_ACCELERATION_STRUCTURE);
500  accel->setProperty(OPTIX_ACCELERATION_VERTEX_BUFFER_NAME, "vertices_buffer");
501  accel->setProperty(OPTIX_ACCELERATION_VERTEX_BUFFER_STRIDE, "12");
502  accel->setProperty(OPTIX_ACCELERATION_INDEX_BUFFER_NAME, "indices_buffer");
503  accel->setProperty(OPTIX_ACCELERATION_INDEX_BUFFER_STRIDE, "12");
504  group->setAcceleration(accel);
505  return group;
506 }
507 
509 {
510  auto group = _optixContext->createGroup();
511  group->setAcceleration(_optixContext->createAcceleration(DEFAULT_ACCELERATION_STRUCTURE));
512  return group;
513 }
514 } // namespace optix
515 } // namespace engine
516 } // namespace core
const size_t OPTIX_STACK_SIZE
const size_t OPTIX_ENTRY_POINT_COUNT
const size_t OPTIX_RAY_TYPE_COUNT
#define RT_CHECK_ERROR_NO_CONTEXT(func)
#define RT_DESTROY_MAP(__map)
Definition: OptiXUtils.h:51
#define RT_DESTROY(__object)
Definition: OptiXUtils.h:38
const T * getRawData(const uint8_t face=0, const uint8_t mip=0) const
Definition: Texture2D.h:89
const uint32_t width
Definition: Texture2D.h:158
const uint32_t height
Definition: Texture2D.h:161
OptiXCameraProgramPtr getCamera(const std::string &name)
void addCamera(const std::string &name, OptiXCameraProgramPtr program)
OptiXShaderProgramPtr getRenderer(const std::string &name)
::optix::GeometryGroup createGeometryGroup(const bool compact)
static OptiXContext & get()
::optix::Material createMaterial()
::optix::Geometry createGeometry(const OptixGeometryType type)
void addRenderer(const std::string &name, OptiXShaderProgramPtr program)
::optix::TextureSampler createTextureSampler(Texture2DPtr texture)
void setCamera(const std::string &name)
std::shared_ptr< OptiXCameraProgram > OptiXCameraProgramPtr
Definition: OptiXTypes.h:38
std::shared_ptr< OptixShaderProgram > OptiXShaderProgramPtr
Definition: OptiXContext.h:195
std::shared_ptr< Texture2D > Texture2DPtr
Definition: Types.h:159
TextureWrapMode
Definition: Texture2D.h:30
::uint8_t uint8
Definition: Types.h:42
#define PLUGIN_INFO(message)
Definition: Logs.h:34
#define PLUGIN_DEBUG(message)
Definition: Logs.h:39