Getting OpenGL buffers using OpenCL
是否可以使用OpenCL获取OpenGL缓冲区的值?例如,编写一个使用缓冲区创建OpenGL上下文的程序,并编写另一个执行OpenCL代码的程序?我不想更改第一个程序代码。
有一个可选的OpenCL扩展名
中可用。
您可以通过使用
在OpenCL初始化期间,您需要以特定方式创建OpenCL上下文,以便能够与OpenGL共享对象。这是特定于OS的,但在所有情况下都涉及创建一组上下文属性,您将这些属性传递给
OS X
1 2 3 4 5 6 7 8 9 10 11 12 | CGLContextObj CGLGetCurrentContext(void); CGLShareGroupObj CGLGetShareGroup(CGLContextObj); CGLContextObj kCGLContext = CGLGetCurrentContext(); CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext); cl_context_properties properties[] = { CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) kCGLShareGroup, 0 }; |
Linux(带有GLX)
1 2 3 4 5 6 7 | cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, // OpenCL platform object 0 }; |
Windows(WGL)
1 2 3 4 5 6 7 | cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(), CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, // OpenCL platform object 0 }; |
Android(带有EGL)
1 2 3 4 5 6 7 | cl_context_properties properties[] = { CL_GL_CONTEXT_KHR, (cl_context_properties)eglGetCurrentContext(), CL_EGL_DISPLAY_KHR, (cl_context_properties)eglGetCurrentDisplay(), CL_CONTEXT_PLATFORM, (cl_context_properties)platform, // OpenCL platform object 0 }; |
设置好属性后,创建如下上下文:
1 | context = clCreateContext(properties, 1, &device, NULL, NULL, &err); |
下一步是从现有OpenGL对象创建OpenCL对象。 OpenGL方面无需进行任何更改。给定一个名为
1 | bufferCL = clCreateFromGLBuffer(context, CL_MEM_READ_WRITE, bufferGL, &err); |
或者您可以从OpenGL纹理创建OpenCL图像:
1 2 | imageCL = clCreateFromGLTexture2D(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, textureGL, &err); |
剩下的就是让在这些共享的CL / GL对象上运行的OpenCL内核排队。您需要在内核的任一侧加入一些额外的命令,以告知实现要与OpenCL转移对象的所有权。您需要执行的一般操作顺序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Flush GL queue glFlush(); // Acquire shared objects err = clEnqueueAcquireGLObjects(queue, 1, &bufferCL, 0, NULL, NULL); // Enqueue OpenCL commands to operate on objects (kernels, read/write commands, etc) // Release shared objects err = clEnqueueReleaseGLObjects(queue, 1, &bufferCL, 0, NULL, NULL); checkError(err,"releasing GL objects"); // Flush CL queue err = clFinish(queue); |
这里有一些示例代码演示了OpenCL / OpenGL的互操作性,值得一看的是在完整的应用程序中看到所有这些示例:
- 英特尔的OpenCL / OpenGL教程
- Apple的OpenCL程序几何位移示例
- NVIDIA的简单OpenCL / OpenGL示例