OpenGL/OpenCL互操作,OpenCL渲染到纹理问题

OpenGL/OpenCL互操作,OpenCL渲染到纹理问题,c,opengl,opencl,textures,C,Opengl,Opencl,Textures,我正在尝试将OpenCL渲染为OpenGL 256x256纹理。 完全正确,但仅渲染黑屏: 如果禁用纹理,它通常渲染白色矩形 // Setting up OpenCL const char *source = "__kernel void Main(__write_only image2d_t image)\n" "{\n" " int x = get_global_id(0);\n" " int y = get_glo

我正在尝试将OpenCL渲染为OpenGL 256x256纹理。
完全正确,但仅渲染黑屏:

如果禁用纹理,它通常渲染白色矩形

// Setting up OpenCL

    const char *source =
        "__kernel void Main(__write_only image2d_t image)\n"
        "{\n"
        " int x = get_global_id(0);\n"
        " int y = get_global_id(1);\n"
        " write_imagef(image, (int2)(x, y), (float4)(x / 256.0f, y / 256.0f, 1.0f, 1.0f));\n"
        "}\n";

    cl_platform_id platform;
    clGetPlatformIDs(1, &platform, NULL);

    cl_device_id cdDeviceID;
    clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &cdDeviceID, NULL);

    cl_context_properties props[] = {
        CL_CONTEXT_PLATFORM,
        (cl_context_properties)platform,
        CL_GL_CONTEXT_KHR,
        (cl_context_properties)wglGetCurrentContext,
        CL_WGL_HDC_KHR,
        (cl_context_properties)wglGetCurrentDC,
    };

    *context = clCreateContextFromType(props, CL_DEVICE_TYPE_GPU ,NULL, NULL, NULL);
    *queue = clCreateCommandQueue(*context, cdDeviceID, 0, NULL);
    *program = clCreateProgramWithSource(*context, 1, &source, NULL, NULL);
    clBuildProgram(*program, 1, &cdDeviceID, NULL, NULL, NULL);
    *kernel = clCreateKernel(*program, "Main", NULL);
...
// Setting up texture

    glEnable(GL_TEXTURE_2D);

    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    cl_mem cl_screen;
    cl_screen = clCreateFromGLTexture2D(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texture, 0);
...
// Rendering
    clEnqueueAcquireGLObjects(queue, 1, &cl_screen, 0, NULL, NULL);
    clSetKernelArg(kernel, 0, sizeof(cl_screen), cl_screen);
    size_t work_size[] = { 256, 256 };
    clEnqueueNDRangeKernel(queue, kernel, 2, 0, work_size, 0, 0, NULL, NULL);
    clEnqueueReleaseGLObjects(queue, 1, &cl_screen, 0, NULL, NULL);
    clFinish(queue);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindTexture(GL_TEXTURE_2D, texture);

    glBegin(GL_QUADS);
    glTexCoord2i(0, 1);
    glVertex3f(-1.0f, 1.0f, 0.0f);
    glTexCoord2i(1, 1);
    glVertex3f( 1.0f, 1.0f, 0.0f);
    glTexCoord2i(1, 0);
    glVertex3f( 1.0f,-1.0f, 0.0f);
    glTexCoord2i(0, 0);
    glVertex3f(-1.0f,-1.0f, 0.0f);
    glEnd();
    glFinish();

    SwapBuffers(hDC);
...
完整代码:

#include <windows.h>
#include <gl/gl.h>
#include <CL/cl.h>
#include <CL/cl_gl.h>

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC);
void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC);
void EnableOpenCL(cl_kernel * kernel, cl_program * program, cl_context * context, cl_command_queue * queue);
void DisableOpenCL(cl_kernel * kernel, cl_program * program, cl_context * context, cl_command_queue * queue);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow)
{
    WNDCLASS wc;
    HWND     hWnd;
    HDC      hDC;
    HGLRC    hRC;
    MSG      msg;
    BOOL     quit = FALSE;

    wc.style         = CS_OWNDC;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon( NULL, IDI_APPLICATION );
    wc.hCursor       = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = "GLCLInterop";

    RegisterClass(&wc);

    hWnd = CreateWindow("GLCLInterop", "GLCLInterop", WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE, 0, 0, 640, 480, NULL, NULL, hInstance, NULL);

    cl_kernel        kernel;
    cl_program       program;
    cl_context       context;
    cl_command_queue queue;

    EnableOpenGL(hWnd, &hDC, &hRC);
    EnableOpenCL(&kernel, &program, &context, &queue);

    glEnable(GL_TEXTURE_2D);

    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    cl_mem cl_screen;
    cl_screen = clCreateFromGLTexture2D(context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texture, 0);

    while (!quit)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT) 
                quit = TRUE;
            else 
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        } 
        else 
        {
            clEnqueueAcquireGLObjects(queue, 1, &cl_screen, 0, NULL, NULL);
            clSetKernelArg(kernel, 0, sizeof(cl_screen), cl_screen);
            size_t work_size[] = { 256, 256 };
            clEnqueueNDRangeKernel(queue, kernel, 2, 0, work_size, 0, 0, NULL, NULL);
            clEnqueueReleaseGLObjects(queue, 1, &cl_screen, 0, NULL, NULL);
            clFinish(queue);

            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            glClear(GL_COLOR_BUFFER_BIT);

            glBindTexture(GL_TEXTURE_2D, texture);

            glBegin(GL_QUADS);
            glTexCoord2i(0, 1);
            glVertex3f(-1.0f, 1.0f, 0.0f);
            glTexCoord2i(1, 1);
            glVertex3f( 1.0f, 1.0f, 0.0f);
            glTexCoord2i(1, 0);
            glVertex3f( 1.0f,-1.0f, 0.0f);
            glTexCoord2i(0, 0);
            glVertex3f(-1.0f,-1.0f, 0.0f);
            glEnd();
            glFinish();

            SwapBuffers(hDC);
        }
    }

    DisableOpenGL(hWnd, hDC, hRC);
    DisableOpenCL(&kernel, &program, &context, &queue);
    DestroyWindow(hWnd);

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_CREATE:
        return 0;

    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;

    case WM_DESTROY:
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {

        case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;

        }
        return 0;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
}

void EnableOpenGL(HWND hWnd, HDC * hDC, HGLRC * hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    int format;

    *hDC = GetDC(hWnd);

    ZeroMemory(&pfd, sizeof(pfd));

    pfd.nSize      = sizeof(pfd);
    pfd.nVersion   = 1;
    pfd.dwFlags    = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    format         = ChoosePixelFormat(*hDC, &pfd);

    SetPixelFormat(*hDC, format, &pfd);

    *hRC = wglCreateContext(*hDC);
    wglMakeCurrent(*hDC, *hRC);
}

void DisableOpenGL(HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent(NULL, NULL);
    wglDeleteContext(hRC);
    ReleaseDC(hWnd, hDC);
}

void EnableOpenCL(cl_kernel * kernel, cl_program * program, cl_context * context, cl_command_queue * queue)
{
    const char *source =
        "__kernel void Main(__write_only image2d_t image)\n"
        "{\n"
        " int x = get_global_id(0);\n"
        " int y = get_global_id(1);\n"
        " write_imagef(image, (int2)(x, y), (float4)(x / 256.0f, y / 256.0f, 1.0f, 1.0f));\n"
        "}\n";

    cl_platform_id platform;
    clGetPlatformIDs(1, &platform, NULL);

    cl_device_id cdDeviceID;
    clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &cdDeviceID, NULL);

    cl_context_properties props[] = {
        CL_CONTEXT_PLATFORM,
        (cl_context_properties)platform,
        CL_GL_CONTEXT_KHR,
        (cl_context_properties)wglGetCurrentContext,
        CL_WGL_HDC_KHR,
        (cl_context_properties)wglGetCurrentDC,
    };

    *context = clCreateContextFromType(props, CL_DEVICE_TYPE_GPU ,NULL, NULL, NULL);

    *queue = clCreateCommandQueue(*context, cdDeviceID, 0, NULL);

    *program = clCreateProgramWithSource(*context, 1, &source, NULL, NULL);
    clBuildProgram(*program, 1, &cdDeviceID, NULL, NULL, NULL);

    *kernel = clCreateKernel(*program, "Main", NULL);
}

void DisableOpenCL(cl_kernel * kernel, cl_program * program, cl_context * context, cl_command_queue * queue)
{
    clReleaseKernel(*kernel);
    clReleaseProgram(*program);
    clReleaseContext(*context);
    clReleaseCommandQueue(*queue);
}
#包括
#包括
#包括
#包括
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM);
void EnableOpenGL(HWND-HWND、HDC*HDC、HGLRC*hRC);
无效禁用OpenGL(HWND HWND、HDC HDC、HGLRC hRC);
void EnableOpenCL(cl_内核*内核,cl_程序*程序,cl_上下文*上下文,cl_命令_队列*队列);
void DisableOpenCL(cl_内核*内核,cl_程序*程序,cl_上下文*上下文,cl_命令_队列*队列);
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE hPrevInstance、LPSTR lpCmdLine、int iCmdShow)
{
WNDCLASS wc;
HWND-HWND;
HDC-HDC;
HGLRC人权委员会;
味精;
BOOL-quit=FALSE;
wc.style=CS_OWNDC;
wc.lpfnWndProc=WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(空,IDI_应用程序);
wc.hCursor=LoadCursor(空,IDC_箭头);
wc.hbrBackground=(HBRUSH)GetStockObject(黑色画笔);
wc.lpszMenuName=NULL;
wc.lpszClassName=“GLCLInterop”;
注册类(&wc);
hWnd=CreateWindow(“GLCLInterop”、“GLCLInterop”、WS|u标题| WS|u弹出窗口| WS|u可见、0、0、640、480、NULL、NULL、hInstance、NULL);
cl_核;
CLU计划;
语境;
cl_命令_队列;
启用OpenGL(hWnd、hDC和hRC);
启用OpenCL(内核、程序、上下文和队列);
glEnable(GL_纹理_2D);
胶合结构;
glGenTextures(1,&纹理);
glBindTexture(GL_TEXTURE_2D,纹理);
glTexParameteri(GL_纹理2D、GL_纹理MAG_过滤器、GL_线性);
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
GLTEXAGE2D(GL_纹理_2D,0,GL_RGBA8,256,256,0,GL_RGBA,GL_无符号_字节,NULL);
cl_mem cl_屏幕;
cl_screen=clCreateFromGLTexture2D(上下文,仅cl_MEM_WRITE_,GL_TEXTURE_2D,0,纹理,0);
而(!退出)
{
if(peek消息(&msg,NULL,0,0,PM_-REMOVE))
{
如果(msg.message==WM\u退出)
退出=真;
其他的
{
翻译信息(&msg);
发送消息(&msg);
}
} 
其他的
{
clEnqueueAcquireGLObjects(队列,1,&cl_屏幕,0,NULL,NULL);
clSetKernelArg(内核,0,sizeof(cl_屏幕),cl_屏幕);
大小工作大小[]={256,256};
clEnqueueNDRangeKernel(队列,内核,2,0,工作大小,0,0,NULL,NULL);
clEnqueueReleaseGLObjects(队列,1,&cl_屏幕,0,NULL,NULL);
clFinish(队列);
glClearColor(0.0f、0.0f、0.0f、0.0f);
glClear(GLU颜色缓冲位);
glBindTexture(GL_TEXTURE_2D,纹理);
glBegin(GL_QUADS);
glTexCoord2i(0,1);
glVertex3f(-1.0f,1.0f,0.0f);
glTexCoord2i(1,1);
glVertex3f(1.0f,1.0f,0.0f);
glTexCoord2i(1,0);
glVertex3f(1.0f,-1.0f,0.0f);
glTexCoord2i(0,0);
glVertex3f(-1.0f,-1.0f,0.0f);
格伦德();
glFinish();
SwapBuffers(hDC);
}
}
禁用OpenGL(hWnd、hDC、hRC);
禁用OpenCL(内核、程序、上下文和队列);
窗口(hWnd);
返回msg.wParam;
}
LRESULT回调WndProc(HWND HWND,UINT消息,WPARAM WPARAM,LPARAM LPARAM)
{
开关(信息)
{
案例WM_创建:
返回0;
案例WM_结束:
PostQuitMessage(0);
返回0;
案例WM_销毁:
返回0;
案例WM_键控:
交换机(wParam)
{
案件VK_逃逸:
PostQuitMessage(0);
返回0;
}
返回0;
违约:
返回DefWindowProc(hWnd、message、wParam、lParam);
}
}
启用void的OpenGL(HWND HWND、HDC*HDC、HGLRC*hRC)
{
像素描述符pfd;
int格式;
*hDC=GetDC(hWnd);
零内存(&pfd,sizeof(pfd));
pfd.nSize=sizeof(pfd);
pfd.inversion=1;
pfd.dwFlags=pfd_DRAW_TO_WINDOW | pfd_SUPPORT | OPENGL | pfd_DOUBLEBUFFER;
pfd.iPixelType=pfd_TYPE_RGBA;
pfd.cColorBits=24;
pfd.cDepthBits=16;
pfd.iLayerType=pfd_主平面;
格式=选择像素格式(*hDC和pfd);
SetPixelFormat(*hDC、格式和pfd);
*hRC=wglCreateContext(*hDC);
wglMakeCurrent(*hDC,*hRC);
}
无效禁用OpenGL(HWND HWND、HDC HDC、HGLRC hRC)
{
wglMakeCurrent(NULL,NULL);
背景(hRC);
释放DC(hWnd、hDC);
}
void EnableOpenCL(cl_内核*内核,cl_程序*程序,cl_上下文*上下文,cl_命令_队列*队列)
{
常量字符*源=
“\uuuu内核void Main(\uuuuu只写图像2d\t图像)\n”
“{\n”
“int x=get_global_id(0);\n”
“int y=get_global_id(1);\n”
写入图像f(图像(int2)(x,y)、(float4)(x/256.0f,y/256.0f,1.0f,1.0f));\n
“}\n”;
cl_平台\u id平台;
clGetPlatformIDs(1,&平台,NULL);
cl_设备id cdDeviceID;
CLGetDeviceID(平台,CL\U设备类型\U GPU,1和cdDeviceID,NULL);
cl_上下文_属性道具[]={
CL_环境_平台,
(cl_上下文_属性)平台,
CL_GL_CONTEXT_KHR,
(cl_context_属性)wglGetCurrentContext,
CL_WGL_HDC_KHR,
(cl_上下文属性)wglGetCurrentDC,
};
*context=clCreateContextFromType(道具,CL_设备_类型_GPU,NULL,NULL);
*queue=clCreateCommandQueue(*上下文,cdDeviceID,0,NULL);
*program=clCreateProgramWithSource(*上下文,1,&source,NULL,NULL);
clBuildProgram(*程序,1,&cdDeviceID,NULL,NULL,NULL);
*kernel=clCreateKernel(*程序,“Main”,NULL);
}
无效禁用