【问题标题】:How to update an OpenGL VBO using a CUDA kernel如何使用 CUDA 内核更新 OpenGL VBO
【发布时间】:2016-07-06 18:55:09
【问题描述】:

我有一个名为 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 互操作做你想做的事的干净和简单的方法。您完全了解什么?
  • 我唯一不明白的是我必须使用哪些命令来将数据从设备指针存储到 VBO。我不明白 map- 和 unmap-command 在做什么以及如何使用它们
  • 您不必使用任何命令。当您映射资源时,设备指针 GL 资源
  • CUDA 互操作的全部意义在于您不要“将数据从位置指针传输到 VBO”。相反,您将要写入的缓冲区对象提供给 CUDA,而不是分配 CUDA 内存。
  • 你做错了。如果你想有效地使用 cuda/opengl 互操作,你想start with a pointer that is provided by OpenGL。您将其注册到 CUDA,然后对其进行映射,然后对其进行 CUDA 操作。然后,当您想将其返回给 OpenGL 进行进一步处理时,您可以“取消映射”它。 This presentation(从幻灯片 35 开始,但您可能想学习所有内容)提供了一个完整的教程,用于将 OpenGL 顶点缓冲区与 CUDA 结合使用。

标签: c++ opengl cuda


【解决方案1】:

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();

This presentation(例如,从幻灯片 36 开始)概述了一般顺序。

simpleGL cuda 示例代码提供了一个完整的示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    • 2016-04-06
    • 1970-01-01
    相关资源
    最近更新 更多