2016-09-17 85 views
0

我已经找到了如何让OpenCL的发挥好与OpenGL和QT5,各有不同复杂程度的几个非官方消息来源:让OpenCL在Qt5中与OpenGL一起玩的好方法是什么?

有这些例子很好,但是他们没有回答以下问题:需要具有最低什么确切的步骤有一个QT5程序窗口小部件显示在OpenCL的内核进行的计算的结果,然后直接转移到由QT5发起附OpenGL上下文

子问题包括:

  • 什么是暴露在QT5到OpenCL的OpenGL上下文正确的方法是什么?
  • 如何首先启动我的Qt5应用程序以确保OpenGL上下文正确设置与OpenCL一起使用?
  • OpenCL应该如何启动才能与Qt5中的OpenGL环境兼容?
  • 我希望在Qt5支持的平台上工作吗?
  • 有没有这样的事情做“官方”的方式来做到这一点,或者是Digia工作?

请注意,我主要使用OpenGL作为窗口部件而不是窗口/全屏幕。

回答

1

我已经使用QT5和OpenCL一起在Mac,Linux和Windows有以下策略:

  1. 创建QGLWidget来绘图和GL上下文(本例中创建了两个GL背景下,一个在QGLWidget来绘图QT /可视化和一个针对OpenCL做多线程时称为mainGLContext,是有用的。这两个上下文将能够共享数据。)
QGLWidget* widget = new QGLWidget; 
QGLContext* mainGLContext = new QGLContext(QGLFormat::defaultFormat(), widget); 
mainGLContext->create(); 
  • 用OpenGL创建OpenCL上下文上下文。这是平台特定的。对于linux,你可以使用glx,windows wgl和mac cgl sharegroups。下面是我用来创建互操作性的上下文属性的函数。显示变量用在linux和windows上,你可以用glXGetCurrentDisplay()和wglGetCurrentDC()来获得它。
  • cl_context_properties* createInteropContextProperties(
         const cl::Platform &platform, 
         cl_context_properties OpenGLContext, 
         cl_context_properties display) { 
    #if defined(__APPLE__) || defined(__MACOSX) 
    CGLSetCurrentContext((CGLContextObj)OpenGLContext); 
    CGLShareGroupObj shareGroup = CGLGetShareGroup((CGLContextObj)OpenGLContext); 
    if(shareGroup == NULL) 
    throw Exception("Not able to get sharegroup"); 
        cl_context_properties * cps = new cl_context_properties[3]; 
        cps[0] = CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE; 
        cps[1] = (cl_context_properties)shareGroup; 
        cps[2] = 0; 
    
    #else 
    #ifdef _WIN32 
        // Windows 
        cl_context_properties * cps = new cl_context_properties[7]; 
        cps[0] = CL_GL_CONTEXT_KHR; 
        cps[1] = OpenGLContext; 
        cps[2] = CL_WGL_HDC_KHR; 
        cps[3] = display; 
        cps[4] = CL_CONTEXT_PLATFORM; 
        cps[5] = (cl_context_properties) (platform)(); 
        cps[6] = 0; 
    #else 
        cl_context_properties * cps = new cl_context_properties[7]; 
        cps[0] = CL_GL_CONTEXT_KHR; 
        cps[1] = OpenGLContext; 
        cps[2] = CL_GLX_DISPLAY_KHR; 
        cps[3] = display; 
        cps[4] = CL_CONTEXT_PLATFORM; 
        cps[5] = (cl_context_properties) (platform)(); 
        cps[6] = 0; 
    #endif 
    #endif 
        return cps; 
    }
  • 通常你想要做的多线程,有一个线程做Qt的事件处理,而在另一个线程做一些OpenCL的处理。请记住在每个线程中将GL上下文设置为“当前”。为此,在QGLContext对象上使用makeCurrent和moveToThread函数。您可以在这里找到有关我如何完成此操作的详细信息:https://github.com/smistad/FAST/blob/master/source/FAST/Visualization/Window.cpp

  • 我不知道用于创建OpenCL上下文的Qt OpenCL包装。

  • +0

    Takk!快速问:你提到QGLWidget,但它已被弃用,在Qt5.x中被QOpenGLWidget所青睐。我想方法是相似/相同的,但你可以请评论一下吗? –

    +0

    我不知道它已被弃用。快速查看后,他们似乎以相同的方式运作,所以不知道为什么它弃用。我将不得不测试一天。这里有关于新课程的一些信息:https://blog.qt.io/blog/2014/09/10/qt-weekly-19-qopenglwidget/。看起来你不得不在上面的例子中使用QOpenGLContext而不是QGLContext。 –

    1

    经过这一些工作后,我觉得不得不增加一些更多的信息。 Erik Smistad的回答是正确的,并且会继续接受,但它只是其中几种方法之一。

    基于this文章至少有3种方式就可以拥有的OpenGL与OpenCL的互操作:

    1. 直接与OpenCL的共享一个OpenGL纹理。优点:最快的路线,因为一切都是零拷贝。缺点:严重限制了可用的支持数据格式。
    2. 与OpenCL共享OpenGL PBO并将其复制到纹理中。其次最快,但会强制需要内存拷贝。
    3. 将OpenCL中的输出缓冲区映射到主机内存并从那里上传纹理。在GPU上使用OpenCL时速度最慢。在CPU上使用OpenCL时速度最快。强制数据被复制到主机内存并返回。就可用数据格式而言最灵活。
    相关问题