Advertisement
Guest User

OpenCL/GL Interop is all white :(

a guest
Oct 5th, 2013
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.66 KB | None | 0 0
  1. static int screenWidth = 800;
  2. static int screenHeight = 600;
  3. static int imageWidth = 512;
  4. static int imageHeight = 512;
  5.  
  6. int main( int argc, char* argv[] )
  7. {
  8.    
  9.     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  10.     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  11.     glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  12.     glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE );   
  13.  
  14.     // Setup OpenGL context
  15.     glfwInit();
  16.     glfwSwapInterval(0);
  17.     GLFWwindow* window = 0;
  18.     window = glfwCreateWindow( screenWidth, screenHeight, "OpenCL Ray Tracer", nullptr, nullptr );
  19.  
  20.     if(!window)
  21.     {
  22.         glfwTerminate();
  23.         return -1;
  24.     }
  25.    
  26.     glfwSetErrorCallback( error_callback );
  27.     glfwSetKeyCallback( window, key_callback );
  28.     glfwMakeContextCurrent(window);
  29.  
  30.     glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
  31.     glViewport(0, 0, screenWidth, screenHeight);
  32.     glfwSetFramebufferSizeCallback( window, framebuffer_size_callback );
  33.    
  34.     glewExperimental = GL_TRUE; //This makes it work on newer graphics cards
  35.     if( glewInit() != GLEW_OK ){
  36.             printf( "Failed to init GLEW\n" );
  37.             return -3;
  38.     }
  39.  
  40.     // Setup OpenCL context to work with OpenGL
  41.     // Load source file
  42.     std::ifstream file("vector_add_kernel.cl");
  43.     if(!file.is_open())
  44.     {
  45.         return -1;
  46.     }
  47.  
  48.     std::string source( (std::istreambuf_iterator<char>(file)),
  49.                         std::istreambuf_iterator<char>() );
  50.     unsigned int sourceLength = source.length();
  51.     file.close();
  52.  
  53.     cl_platform_id platformId = 0;
  54.     cl_device_id deviceId = 0;
  55.     cl_uint numDevices;
  56.     cl_uint numPlatforms;
  57.     cl_int ret;
  58.  
  59.     // Get platform info
  60.     ret = clGetPlatformIDs( 1, &platformId, &numPlatforms );
  61.  
  62.     // Get device info
  63.     ret = clGetDeviceIDs( platformId, CL_DEVICE_TYPE_GPU, 1, &deviceId, &numDevices );
  64.  
  65.     // Create an OpenCL context shared with OpenGL
  66.     cl_context_properties properties[] = {
  67.         CL_CONTEXT_PLATFORM, (cl_context_properties)platformId,
  68.         CL_GL_CONTEXT_KHR, (cl_context_properties)wglGetCurrentContext(),  
  69.         CL_WGL_HDC_KHR, (cl_context_properties)wglGetCurrentDC(),
  70.         0  
  71.     };
  72.     cl_context context = clCreateContext( properties, 1, &deviceId, cl_callback, 0, &ret );
  73.  
  74.     // Create a command queue
  75.     cl_command_queue commandQueue = clCreateCommandQueue( context, deviceId, CL_QUEUE_PROFILING_ENABLE, &ret);
  76.    
  77.     // Create the kernel program
  78.     const char* source_cst = source.c_str();
  79.     cl_program program = clCreateProgramWithSource( context, 1,
  80.         &source_cst, &sourceLength, &ret);
  81.    
  82.     // Build the program
  83.     ret = clBuildProgram( program, 1, &deviceId, "-cl-single-precision-constant -cl-mad-enable -cl-fast-relaxed-math -I kernels/ -cl-std=CL1.1", NULL, NULL );
  84.  
  85.     // Check build for errors
  86.     if( ret == CL_BUILD_PROGRAM_FAILURE )
  87.     {
  88.         // Determine the size of the log
  89.         size_t log_size;
  90.         clGetProgramBuildInfo( program, deviceId, CL_PROGRAM_BUILD_LOG,
  91.             0, 0, &log_size );
  92.  
  93.         char* log = new char[log_size];
  94.  
  95.          // Get the log
  96.         clGetProgramBuildInfo(program, deviceId, CL_PROGRAM_BUILD_LOG,
  97.             log_size, log, NULL);
  98.        
  99.         // Print log
  100.         std::cout << log;
  101.         std::cin.get();
  102.         return -1;
  103.  
  104.     }
  105.     else
  106.     {
  107.         CLERR(ret);
  108.     }
  109.  
  110.     // Create the OpenCL Kernel
  111.     cl_kernel kernel = clCreateKernel( program, "Draw", &ret );
  112.  
  113.     // Create vertex buffer
  114.     float qs = 1.0f;
  115.    
  116.     // posx, posy, u, v
  117.     static const float vertexBufferData[] =
  118.     {
  119.         -qs, -qs, 0.0f, 0.0f,
  120.         -qs, qs, 0.0f, 1.0f,
  121.         qs, -qs, 1.0f, 0.0f,
  122.         qs, qs, 1.0f, 1.0f,
  123.     };
  124.    
  125.     GLuint vertexArrayID;
  126.     glGenVertexArrays( 1, &vertexArrayID );
  127.     glBindVertexArray( vertexArrayID );
  128.  
  129.     GLuint vertexBuffer;
  130.     glGenBuffers( 1, &vertexBuffer );
  131.     glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer );
  132.     glBufferData( GL_ARRAY_BUFFER, sizeof(float) * 16, vertexBufferData, GL_STATIC_DRAW );
  133.    
  134.     // Create the openGL fullscreen quad program
  135.     GLuint quadProgramID = LoadShaders( "draw_quad.vertex", "draw_quad.fragment" );
  136.  
  137.     // Create a gl texture for use as the
  138.     GLuint textureID;
  139.     glGenTextures( 1, &textureID );
  140.     glBindTexture( GL_TEXTURE_2D, textureID );
  141.  
  142.     // Fill texture with green
  143.     std::vector<float> texdata(imageWidth * imageHeight * 4, 0);
  144.     for( unsigned int i = 0; i < texdata.size(); i+=4 )
  145.     {
  146.         texdata[i]  = 0;
  147.         texdata[i+1]    = 1.0f;
  148.         texdata[i+2]    = 0;
  149.         texdata[i+3]    = 1.0f;
  150.     }
  151.     glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, 0, GL_RGBA, GL_FLOAT, &texdata[0] );
  152.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  153.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  154.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  155.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  156.     glBindTexture( GL_TEXTURE_2D, 0 );
  157.     glActiveTexture(GL_TEXTURE0);
  158.     glBindTexture( GL_TEXTURE_2D, textureID );
  159.     glUseProgram( quadProgramID );
  160.  
  161.     // Get texture shader location
  162.     GLuint uniformTextureID = glGetUniformLocation( quadProgramID, "image" );
  163.  
  164.     // Set the texture uniform in shader
  165.     glUniform1i( uniformTextureID, 0 );    
  166.     glBindTexture( GL_TEXTURE_2D, 0 );
  167.    
  168.     // Create OpenCL memobject from gl texture
  169.     cl_mem textureMem = clCreateFromGLTexture2D( context, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, textureID, &ret );
  170.    
  171.     while (!glfwWindowShouldClose(window))
  172.     {
  173.        
  174.         float ratio;
  175.  
  176.         glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
  177.         ratio = screenWidth / (float) screenHeight;
  178.  
  179.         // Do OpenCL
  180.         // Force OpenGL to finish
  181.         glFinish();
  182.  
  183.         // Set kernel args
  184.         ret = clSetKernelArg( kernel, 0, sizeof(cl_mem), (void *)&textureMem );
  185.         ret = clSetKernelArg( kernel, 1, sizeof(int), (void *)&imageWidth );
  186.         ret = clSetKernelArg( kernel, 2, sizeof(int), (void *)&imageHeight );
  187.  
  188.         cl_event event[3];
  189.         // Aquire the texture memory
  190.         ret = clEnqueueAcquireGLObjects( commandQueue, 1, &textureMem, 0, NULL, &event[0] );
  191.        
  192.         // Execute kernel
  193.         size_t globalWorkSize[] = {imageWidth, imageHeight};
  194.         size_t localWorkSize[] = {32,32};
  195.         ret = clEnqueueNDRangeKernel( commandQueue, kernel, 2, NULL, globalWorkSize, localWorkSize, 1, &event[0], &event[1] );
  196.        
  197.         // Make OpenCL release the texture memory
  198.         ret = clEnqueueReleaseGLObjects( commandQueue, 1, &textureMem, 1, &event[1], &event[2] );
  199.        
  200.         clWaitForEvents( 1, &event[2] );
  201.  
  202.         // Render a textured quad
  203.         glClear( GL_COLOR_BUFFER_BIT );
  204.         glUseProgram( quadProgramID );
  205.         glBindBuffer( GL_ARRAY_BUFFER, vertexBuffer );
  206.    
  207.         glActiveTexture(GL_TEXTURE0);
  208.         glBindTexture( GL_TEXTURE_2D, textureID );
  209.  
  210.         glEnableVertexAttribArray( 0 );
  211.         glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, 0, (void*)0 );
  212.  
  213.         glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
  214.  
  215.         glDisableVertexAttribArray( 0 );
  216.  
  217.         glUseProgram(0);
  218.  
  219.         glfwSwapBuffers( window );
  220.  
  221.         glFinish();
  222.  
  223.         glfwPollEvents();  
  224.  
  225.  
  226.     }
  227.  
  228.     glfwDestroyWindow(window);
  229.     glfwTerminate();
  230.     return 0;
  231. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement