我们如何使用 OpenGL 将在 OpenCL 内核中计算的像素数据显示到屏幕上?
How do we display pixel data calculated in an OpenCL kernel to the screen using OpenGL?
我对用 c++ 编写实时光线追踪应用程序很感兴趣,听说使用 OpenCL-OpenGL 互操作性是实现此目的的好方法(充分利用 GPU),所以我开始编写使用此互操作性并使用 GLFW 进行 window 管理的 c++ 项目。我应该提一下,虽然我有一些编码经验,但我在 C++ 方面并没有那么多,并且在尝试这个项目之前没有使用过 OpenCL 或 OpenGL,所以如果考虑到这一点给出答案(即初学者),我将不胜感激- 友好的术语是首选)。
到目前为止,我已经能够通过使用顶点缓冲对象的示例获得 OpenCL-OpenGL 互操作性。我还演示了我可以使用 RGBA 数组创建图像数据(至少在 CPU 上),使用 glTexImage2D() 将其发送到 OpenGL 纹理并使用 glBlitFramebuffer() 显示它。
我的问题是我不知道如何创建一个能够计算像素数据的 OpenCL 内核,以便它可以作为 glTexImage2D() 中的数据参数给出。我知道要使用互操作性,我们必须首先创建 OpenGL 对象,然后从这些对象创建 OpenCL 对象以在这些对象共享内存时写入数据,所以我假设我必须首先创建一个空的 OpenGL 数组对象,然后创建一个 OpenCL 数组从这个对象应用一个适当的内核,在使用 OpenGL 数组对象作为 glTexImage2D() 中的数据参数之前写入像素数据,但我不确定要使用哪种对象,并且没有看到任何示例证明这一点。一个简单的例子展示了 OpenCL 如何为 OpenGL 纹理图像创建像素数据(假设一个有效的 OpenCL-OpenGL 上下文)将不胜感激。请不要漏掉任何一行,因为我可能无法填写空白!
我上面描述的用于实现光线追踪器的方法也很可能是不可能的,或者至少不推荐,所以如果是这种情况,请概述一个建议的替代方法,用于将 OpenCL 内核计算的像素数据发送到 OpenGL然后将其绘制到屏幕上。对此 similar question does not go into enough detail for me and the CL/GL interop link is not working. The answer mentions that this can be achieved using a renderbuffer rather than a texture, but it says at the bottom of the Khronos OpenGL wiki for Renderbuffer Objects 的回答是,向它们发送像素数据的唯一方法是通过像素传输操作,但我找不到任何直接解释如何以这种方式初始化数据的方法。
请注意,我使用的是 OpenCL c(没有 C++ 绑定)。
从你的第二段开始,你正在创建一个 OpenCL 上下文,其中包含 GLX_DISPLAY / WGL_HDC 和 GL_CONTEXT 属性的平台特定组合以与 OpenGL 进行互操作,并且你可以创建一个顶点OpenGL 和 OpenCL 都可以根据需要 read/written 缓冲对象。
这就是大部分工作。在 OpenGL 中,您可以使用
将任何 VBO 复制到纹理中
glBindBuffer(GL_PIXEL_UNPACK_BUFER, myVBO);
glTexSubImage2D(GL_TEXTURE_2D, level, x, y, width, height, format, size, NULL);
最后的 NULL 表示从 GPU 内存(解包缓冲区)而不是 CPU 内存复制。
与从常规 CPU 内存复制一样,如果不是 32 位,您可能还需要更改像素对齐方式。
我对用 c++ 编写实时光线追踪应用程序很感兴趣,听说使用 OpenCL-OpenGL 互操作性是实现此目的的好方法(充分利用 GPU),所以我开始编写使用此互操作性并使用 GLFW 进行 window 管理的 c++ 项目。我应该提一下,虽然我有一些编码经验,但我在 C++ 方面并没有那么多,并且在尝试这个项目之前没有使用过 OpenCL 或 OpenGL,所以如果考虑到这一点给出答案(即初学者),我将不胜感激- 友好的术语是首选)。
到目前为止,我已经能够通过使用顶点缓冲对象的示例获得 OpenCL-OpenGL 互操作性。我还演示了我可以使用 RGBA 数组创建图像数据(至少在 CPU 上),使用 glTexImage2D() 将其发送到 OpenGL 纹理并使用 glBlitFramebuffer() 显示它。
我的问题是我不知道如何创建一个能够计算像素数据的 OpenCL 内核,以便它可以作为 glTexImage2D() 中的数据参数给出。我知道要使用互操作性,我们必须首先创建 OpenGL 对象,然后从这些对象创建 OpenCL 对象以在这些对象共享内存时写入数据,所以我假设我必须首先创建一个空的 OpenGL 数组对象,然后创建一个 OpenCL 数组从这个对象应用一个适当的内核,在使用 OpenGL 数组对象作为 glTexImage2D() 中的数据参数之前写入像素数据,但我不确定要使用哪种对象,并且没有看到任何示例证明这一点。一个简单的例子展示了 OpenCL 如何为 OpenGL 纹理图像创建像素数据(假设一个有效的 OpenCL-OpenGL 上下文)将不胜感激。请不要漏掉任何一行,因为我可能无法填写空白!
我上面描述的用于实现光线追踪器的方法也很可能是不可能的,或者至少不推荐,所以如果是这种情况,请概述一个建议的替代方法,用于将 OpenCL 内核计算的像素数据发送到 OpenGL然后将其绘制到屏幕上。对此 similar question does not go into enough detail for me and the CL/GL interop link is not working. The answer mentions that this can be achieved using a renderbuffer rather than a texture, but it says at the bottom of the Khronos OpenGL wiki for Renderbuffer Objects 的回答是,向它们发送像素数据的唯一方法是通过像素传输操作,但我找不到任何直接解释如何以这种方式初始化数据的方法。
请注意,我使用的是 OpenCL c(没有 C++ 绑定)。
从你的第二段开始,你正在创建一个 OpenCL 上下文,其中包含 GLX_DISPLAY / WGL_HDC 和 GL_CONTEXT 属性的平台特定组合以与 OpenGL 进行互操作,并且你可以创建一个顶点OpenGL 和 OpenCL 都可以根据需要 read/written 缓冲对象。
这就是大部分工作。在 OpenGL 中,您可以使用
将任何 VBO 复制到纹理中glBindBuffer(GL_PIXEL_UNPACK_BUFER, myVBO);
glTexSubImage2D(GL_TEXTURE_2D, level, x, y, width, height, format, size, NULL);
最后的 NULL 表示从 GPU 内存(解包缓冲区)而不是 CPU 内存复制。
与从常规 CPU 内存复制一样,如果不是 32 位,您可能还需要更改像素对齐方式。