#include #include #include #include #include #ifndef STRINGIFY #define STRINGIFY(x) #x #endif class OpenCLMeshKit { public: //RAII is violated but it is really triky to do differently cl_int initCL(intptr_t gl_display, intptr_t gl_context, intptr_t gl_vbo, size_t meshWidth, size_t meshHeight, size_t groupSize); cl_int compileKernels(std::list names, const char source[], size_t sourceLen); cl_int execKernel(std::string kernelName, float time); void releaseKernels(); size_t getMeshWidth(); size_t getMeshHeight(); size_t getMeshItemCount(); size_t getGroupSize(); intptr_t getGLVBO(); void setGroupSize(size_t groupSize); // Quick and dirty function to initialize a test mesh cl_int resetVBO(); virtual ~OpenCLMeshKit(); protected: size_t meshWidth; size_t meshHeight; size_t groupSize; cl_context cl_ctx; cl_device_id cl_dev; cl_command_queue cl_cq; cl_mem cl_vbo; intptr_t gl_vbo; // Save this pointer for convinence (for data display code) std::map kernels; }; /* Kernel for resetVBO() To write your own kernels, take this one a make the calculus you want for z variable staying in [-0.5;0.5] if you want everything a 1*1*1 cube */ const char kernel_src_zero_z[]=STRINGIFY( __kernel void zero_z(__global float4 *pos, unsigned int width, unsigned int height, float time) { unsigned int nx = get_global_id(0); unsigned int ny = get_global_id(1); /* calculate uv coordinates of the mesh point [0.0;1.0] */ float u = nx / (float) width; float v = ny / (float) height; /* calculate centered coordinates [-0.5;0.5] */ float x = (u*2-1)/2; float y = (v*2-1)/2; /* We only use normalized quaterinons here */ float w = 1.0f; /* Calculate the desirated value of the mesh point */ float z = 0.0f; /* Write output vertex (centered) */ pos[ny*width+nx] = (float4)(x, y, z, w); } );