如何使用 CUDA 内核更新 OpenGL VBO



我有一个名为 update 的 CUDA 内核,它接受两个 float* 作为输入并更新第一个。更新后,我需要使用第一个指针中的新数据更新 OpenGL 中的 VBO。现在我一直在寻找一些 cuda-GL 互操作,但对我来说,所有这些都很难理解。我正在寻找一种干净简单的方法来使用设备指针中的数据更新 VBO。我想象了这样的事情:

//initialize VBO
glGenBuffers(1, &vboID);
glBindBuffers(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*SIZE, (void*)0, GL_STREAM_DRAW);
cudaMalloc((void**)&positions, sizeof(float)*SIZE);

//per frame code
glBindBuffer(GL_ARRAY_BUFFER, vboID);
update<<<SIZE/TPB, TPB>>>(positions, velocities);
//somehow transfer the data from the positions pointer to the VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);

CUDA/OpenGL互操作的基本思想是,您将使用OpenGL创建一个资源(例如VBO,PBO等)。 使用 OpenGL,您将为该资源分配缓冲区。 使用 CUDA/OpenGL 互操作,您将向 CUDA 注册该资源。在 CUDA 中使用该资源之前,您映射资源以获取指向 CUDA 可用的基础分配的指针。

然后,您可以使用 CUDA 对该分配进行操作,并且您可以通过取消映射资源将该资源"返回"到 OpenGL(用于进一步处理、显示等)。

对于 OpenGL VBO,API 序列可能如下所示:

// create allocation/pointer using OpenGL
GLuint vertexArray;
glGenBuffers( 1,&vertexArray);
glBindBuffer( GL_ARRAY_BUFFER, vertexArray);
glBufferData( GL_ARRAY_BUFFER, numVertices * 16, NULL, GL_DYNAMIC_COPY );
cudaGLRegisterBufferObject( vertexArray );
void * vertexPointer;
// Map the buffer to CUDA
cudaGLMapBufferObject(&ptr, vertexBuffer);
// Run a kernel to create/manipulate the data
MakeVerticiesKernel<<<gridSz,blockSz>>>(ptr,numVerticies);
// Unmap the buffer
cudaGLUnmapbufferObject(vertexBuffer);
// Bind the Buffer
glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer );
// Enable Vertex and Color arrays
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
// Set the pointers to the vertices and colors
glVertexPointer(3,GL_FLOAT,16,0);
glColorPointer(4,GL_UNSIGNED_BYTE,16,12);
glDrawArrays(GL_POINTS,0, numVerticies);
SwapBuffer();

本演示文稿(例如,从幻灯片 36 开始)概述了一般顺序。

simpleGL cuda 示例代码给出了一个完整的示例。

最新更新