2014-04-08 93 views
1

该设置有点复杂,所以我会尽我所能详细说明。opencl/opengl interop使用clCreateFromGLTexture无法绘制到纹理(纹理黑色)

首先,我试图使用openCL/openGL interop。代码在interop cl :: ImageGL未使用时起作用,因此基础知识就在那里。该项目使用3个主要的openGL上下文(花了很多时间才能打开openCL上下文)。我正在使用QGLWidgets的上下文。首先创建一个隐藏的QGLWidget,另外两个共享隐藏的上下文。 2个QGLWidget中的每一个都在自己的线程中运行。隐藏的QGLWidget被转移到创建openCL上下文的线程中。

QGLFormat qglFormat; 
qglFormat.setVersion(3, 3); 
qglFormat.setProfile(QGLFormat::CoreProfile); 

m_hiddenGl=new GLHiddenWidget(qglFormat); 
m_hiddenGl->setVisible(false); 

m_view1=new GLWidget(qglFormat, m_hiddenGl); 
m_view2=new GLWidget(qglFormat, m_hiddenGl); 
... 
QThread *processThread=m_process.qThread(); 

m_hiddenGl->doneCurrent(); 
m_hiddenGl->context()->moveToThread(processThread); 

GLWidget是启动自己的线程和移动环境中,GLHiddenWidget再次自定义类,但基本上只是覆盖,以保持makeCurrent从主线程调用所需的所有功能的自定义类。

在启动进程线程里面是以下

m_hiddenGl->makeCurrent(); 
hdc=wglGetCurrentDC(); 
glHandle=wglGetCurrentContext(); 

cl_context_properties clContextProps[]={ 
    CL_CONTEXT_PLATFORM, (cl_context_properties)m_openCLPlatform(), 
    CL_WGL_HDC_KHR, (intptr_t) hdc, 
    CL_GL_CONTEXT_KHR, (intptr_t) glHandle, 0 
}; 

m_openCLContext=cl::Context(m_openCLDevice, clContextProps, NULL, NULL, &error); 

这一切是一展身手。从这一点开始,几个内核在传入的图像上依次执行。所有的内核都成功了(没有错误),但是使用openGL纹理写出数据的内核却无法写入任何内容。当使用openCL cl :: Image2d时,即使openCL上下文创建为互操作,它也能正常工作(产生正确的输出)。

openGL纹理是在所有openGL上下文创建完成之后以及openCL上下文创建之后(也与openCL上下文位于同一线程中)创建的。在processThread开始时,纹理由带有glGenTextures的隐藏QGLWidget生成。然后,所有内核都与其他openCL缓冲区和图像一起创建。在内核执行之前,完成以下操作。

if(initBuffer) //runs only if buffer size is changed, allways runs first time 
{ 
    m_hiddenGl->makeCurrent(); 

    glBindTexture(GL_TEXTURE_2D, m_texture); 

    //I have attempted to put data in, result is always black from kernel 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glBindTexture(GL_TEXTURE_2D, 0); 

    glFinish(); 

    //m_flags is CL_MEM_READ_WRITE 
    m_imageGL=cl::ImageGL(m_openCLContext, m_flags, GL_TEXTURE_2D, 0, m_texture, &error); 
} 

和一个简化的内核。

__kernel void kernel1(__read_only image2d_t src1, __read_only image2d_t src2, __write_only image2d_t dst) 
{ 
    int2 coord=(int2)(get_global_id(0), get_global_id(1)); 
    uint4 value=255; 

    write_imageui(dst, coord, convert_uint4(value)); 
} 

即使我不显示纹理图像仍然是黑色的。使用cl :: Image2d或cl :: ImageGL时,图像从openCL读回并保存到硬盘。对于cl :: Image2d,cl :: ImageGL是黑色的。

+0

好的,发现问题似乎需要创建如下纹理。 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8UI,width,height,0,GL_RGBA_INTEGER,GL_UNSIGNED_BYTE,NULL);现在,如果我只能渲染的东西。 – Krazer

回答

0

正如上面在我的评论中指出的,我发现我的问题与openGL纹理的定义有关。由于我在OpenCL的内核所使用的write_imageui openGL的纹理不得不被定义如下:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, width, height, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); 

我已经取得了一些时间,因为然后和创建的使用既openGL的/ OpenCL的互操作和螺纹QGLWidgets一个示例程序。你可以在上面看我的意见在这里http://www.krazer.com/?p=109和/或可以从github.com

1

我有同样的问题,使用write_imagef()(不要忘记255.0划分RGBA值获取的源泉!),而不是在OpenCL内核中的write_imageui()解决它,而不改变OpenGL纹理的像素格式(您可能没有机会这样做,特别是如果它是在大型应用程序中的其他位置创建的现有纹理)。