简体   繁体   English

如何使用CUDA内核更新OpenGL VBO

[英]How to update an OpenGL VBO using a CUDA kernel

I have a CUDA kernel called update which takes two float* as a input and updates the first one. 我有一个称为update的CUDA内核,它将两个float *作为输入并更新第一个。 After the update, I need to update the VBO from OpenGL with the new data from the first pointer. 更新之后,我需要使用第一个指针的新数据更新OpenGL中的VBO。 Now I've been looking for some cuda-GL interop, but for me, all of this was really hard to understand. 现在,我一直在寻找一些cuda-GL互操作性,但是对我来说,所有这些真的很难理解。 I'm looking for a clean and easy way to update a VBO using the data from a device pointer. 我正在寻找一种干净简单的方法来使用设备指针中的数据更新VBO。 I imagined something like this: 我想像这样的事情:

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

The basic idea with CUDA/OpenGL interop is that you will create a resource (eg VBO, PBO, etc.) using OpenGL. CUDA / OpenGL互操作的基本思想是,您将使用OpenGL创建资源(例如VBO,PBO等)。 Using OpenGL you will allocate a buffer for that resource. 使用OpenGL,您将为该资源分配一个缓冲区。 Using CUDA/OpenGL interop you will register that resource with CUDA. 使用CUDA / OpenGL互操作,您将向CUDA 注册该资源。 Before using that resource in CUDA, you map the resource, to obtain a pointer to the underlying allocation that is usable by CUDA. 在CUDA中使用该资源之前,您需要映射资源,以获得指向CUDA可用的基础分配的指针。

You then operate on that allocation using CUDA, and you can "return" that resource to OpenGL (for further processing, display, etc.) by unmapping the resource. 然后,您可以使用CUDA对分配进行操作,并且可以通过取消映射资源将资源“返回”到OpenGL(以进行进一步处理,显示等)。

In the case of an OpenGL VBO, the API sequence might look like this: 对于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 (eg. starting at slide 36) outlines the general sequence. 此演示文稿 (例如,从幻灯片36开始)概述了一般顺序。

The simpleGL cuda sample code gives a fully worked example. simpleGL cuda示例代码提供了一个完整的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM