我还没有弄清楚 OpenGL 4.0 是如何使这个功能发挥作用的,因为据我所知,它以前就存在过。我不确定这是否能回答你的问题,但无论如何我会告诉你我对这个主题的了解。
它指的是OpenGL以外的其他库,例如OpenCL或CUDA,将一些数据直接生成到显卡的内存中,然后OpenGL从其他库离开的地方继续,并将该数据用作
- 像素缓冲区对象 (PBO),当他们想要将数据原样绘制到屏幕上时
- 当他们想要将图形数据用作其他场景的一部分时的纹理
- 当他们想要使用生成的数据作为顶点着色器的一些任意属性输入时,顶点缓冲区对象 (VBO)。 (其中一个例子可能是使用 CUDA 模拟并使用 OpenGL 渲染的粒子系统)
在这种情况下,最好将数据一直保存在显卡中而不是到处复制,尤其是不要通过 CPU 复制,因为 PCIe 总线与内存相比非常慢显卡总线。
下面是一些示例代码,可以使用 CUDA 和 OpenGL 来实现 VBO 和 PBO:
// in the beginning
glGenBuffers(&id, 1);
// for every frame
cudaGLRegisterBufferObject(id);
CUdeviceptr ptr;
cudaGLMapBufferObject(&ptr, id);
// <launch kernel here>
cudaGLUnmapBufferObject(id);
// <now use the buffer "id" with OpenGL>
cudaGLUnregisterBufferObject(id);
以下是如何将数据加载到纹理中:
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, id);
glBindTexture(GL_TEXTURE_2D, your_tex_id);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, 0);
另外请注意,如果您使用一些更不寻常的格式而不是 GL_RGBA,它可能会更慢,因为它必须转换所有值。
我不知道 OpenCL,但想法是一样的。只有函数名不同。
做同样事情的另一种方法是所谓的主机固定内存。在这种方法中,您将一些 CPU 内存地址范围映射到显卡内存。