如何使用CUDA内核更新OpenGL VBO

3

我有一个名为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);

GL-CUDA互操作您想要做的事情的干净简单的方法。 您到底不明白什么? - talonmies
你不必使用任何命令。当你映射资源时,设备指针就是GL资源。 - talonmies
1
CUDA互操作的整个重点在于您不需要“将数据从位置指针传输到VBO”。相反,您可以将要写入的缓冲区对象提供给CUDA,而不是分配CUDA内存。 - Nicol Bolas
我确实查看了示例,但是我没有理解它们,所以我发布了这个问题。我想知道的是,我需要做什么才能使用设备指针更新VBOs数据。 - Dynamitos
1
你的方法不对。如果你想要有效地使用cuda/opengl互操作,你需要从OpenGL提供的指针开始。你将其注册到CUDA中,然后映射它,在其上执行CUDA操作。然后,当你想要将其返回给OpenGL进行进一步处理时,可以“取消映射”它。这个演示文稿(从第35页开始,但你可能需要学习全部内容)提供了一个完整的教程,用于使用OpenGL顶点缓冲区与CUDA。 - Robert Crovella
显示剩余9条评论
1个回答

5
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示例代码提供了一个完整的工作示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接