2012-12-15 2 views
2

OpenCL 렌더링을 OpenGL 256x256 텍스처로 렌더링하려고합니다.
모든 권리 컴파일 만 검은 화면 렌더링 : 텍스처링을 해제OpenGL/OpenCL interop, 텍스처 문제에 대한 OpenCL 렌더링

경우, 일반적으로 흰색 사각형을 렌더링합니다.

// 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); 
} 

그 문제점은 무엇입니까?

+2

이 사이트는 200 개 이상의 코드 라인을 검토하지 않습니다. 1) 코드를 최소로 줄이십시오. 2) 무엇이 잘못되었는지 명확하게 설명하십시오. – Pubby

+1

드문 경우이지만 실제로 형식이 올바르지 않으므로이 질문을지지해야합니다. SSCCE를 만들고 여기에 게시하면 Google에서 도와 드리겠습니다. –

+1

glBegin (GL_QUADS) 앞에 glColor4ub (255,255,255,255)를 삽입하고 CL 호출에 의해 반환 된 상태를 확인하십시오. –

답변

2

이미지가 GL_UNSIGNED_BYTE이지만 write_imagef를 사용 중입니다. GL_FLOAT 또는 write_imageui로 전환하십시오.

+0

문제가 해결되었다고해도 정답이 될 수 없습니다. GL 텍스처가 RGBA8과 부호없는 바이트를 사용하여 생성되면, read_imagef와 write_imagef를 사용하여 매우 잘 접근 할 수 있습니다! 이 부분에 대해 자세히 설명하는 OpenCL 사양을 살펴보십시오. – St0fF