CUDA <-> OpenGL довольно прост.
Вы создаете буфер вершин OpenGL следующим образом:
unsigned int _vbo;
cudaGraphicsResource *_vb_resource;
glGenBuffers(1, &_vbo);
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
зарегистрируйте его в CUDA:
cudaGraphicsGLRegisterBuffer(_vb_resource, _vbo, FLAGS);
отобразите его перед вызовом ядра визуализации:
vertex_t *ptr = NULL;
size_t size;
cudaGraphicsMapResources(1, &_vb_resource, 0);
cudaGraphicsResourceGetMappedPointer(ptr, &size, _vb_resource);
вызовите ваше ядро с буфером вершин в качестве аргумента:
visData<<<BLOCKS, THREADS>>>(data, ptr);
unmap ваш буфер вершин
cudaGraphicsUnmapResources(1, &_vb_resource, 0);
и все готово. OpenGL теперь может отображать ваши данные.
Также CUDA может взаимодействовать с DirectX 10 и 11 (даже 9, но это устарело и удручает)
Посмотрите образцы, опубликованные Мартином Беккетом. Это не так сложно.
РЕДАКТИРОВАТЬ: Небольшой намек:
Отключение vsync может привести к лучшей производительности вычислений. vsync по умолчанию включен. Если у вас есть только в потоке для рендеринга и вычислений, vsync снизит частоту вычислений fps до частоты vsync используемого дисплея (60 Гц)
Чтобы отключить vSync в Windows и Linux, используйте:
// turn off vsync
#ifndef _WIN32
// or just try it for non Windows
if (glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA") != NULL)
((void (*)(int))glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA"))(0);
else if (glXGetProcAddress((const GLubyte*) "glXSwapIntervalSGI") != NULL)
((void (*)(int))glXGetProcAddress((const GLubyte*) "glXSwapIntervalSGI"))(0);
#else
wglSwapIntervalEXT(0);
#endif