2014-04-08 124 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紋理的像素格式(您可能沒有機會這樣做,特別是如果它是在大型應用程序中的其他位置創建的現有紋理)。