Hello. I am trying to put some values in an 3D Image shared with OpenGL by running a kernel which writes into a buffer and then I call clEnqueueCopyBufferToImage. But here happens a strange thing: There is reproducible data in the image but its only in the blue and alpha channel. No matter what i do. Here follows the example code. Can anyone test this or tell me what is wrong?
P.S.: Writing directly into the 3DImage works but is no option since this has to run on nvidia gpus either.
//////////////main
GLuint texid = 0;
GLuint bufferid = 0;
ocl oclObject;
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
oclObject.run();
glBindTexture(GL_TEXTURE_3D, texid);
glBegin(GL_QUADS);
glVertex3f(-0.5,-0.5,0);
glTexCoord2f(0,0);
glVertex3f(-0.5,0.5,0);
glTexCoord2f(0,1);
glVertex3f(0.5,0.5,0);
glTexCoord2f(1,1);
glVertex3f(0.5,-0.5,0);
glTexCoord2f(1,0);
glEnd();
glBindTexture(GL_TEXTURE_3D,0);
glFinish();
glutSwapBuffers();
}
void idle(){
glutPostRedisplay();
}
void glInit(){
glEnable(GL_TEXTURE_3D);
glGenTextures(1, &texid);
glBindTexture(GL_TEXTURE_3D, texid);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexImage3D(GL_TEXTURE_3D,0,GL_RGBA,16,16,16,0,GL_RGBA, GL_FLOAT,0);
glBindTexture(GL_TEXTURE_3D, 0);
}
void main(int argc, char ** argv ){
glutInit(&argc, argv );
glutInitDisplayMode ( GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowPosition ( 0, 0 );
glutInitWindowSize ( 600, 400 );
glClearColor(0.2,0.2,0.2,1);
glutCreateWindow("");
glutDisplayFunc(display);
glutIdleFunc(idle);
glewInit();
oclObject.init(CL_DEVICE_TYPE_GPU);
glInit();
oclObject.allocateMemory(texid);
glutMainLoop();
}
//opencl stuff
void ocl::allocateMemory(GLuint texid){
std::cout<<"Alocating OCL Memory..."<<std::endl;
outputTexture = clCreateFromGLTexture3D (context, CL_MEM_READ_WRITE, GL_TEXTURE_3D,0,texid, &status);
if(status != CL_SUCCESS)
std::cout<<"Error: clCreateFromGLTexture3D (_texture)"<< "("<< status <<")" << std::endl;
output = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(cl_float4)*16*16*16,0,&status);
if(status != CL_SUCCESS)
std::cout<<"Error: clCreateFromGLBuffer (_texture)"<< "("<< status <<")" << std::endl;
status = clSetKernelArg(outputDensity_kernel,0, sizeof(cl_mem), &output);
if(status != CL_SUCCESS)
std::cout<<"Error: clSetKernelArg (3D Image)"<< "("<< status <<")" << std::endl;
std::cout<<"done!"<<std::endl;
}
void ocl::run(){
status = clEnqueueAcquireGLObjects(commandQueue, 1, &outputTexture, 0, NULL, NULL);
if(status != CL_SUCCESS)
std::cout<<"Error: clEnqueueAquireGLObjects ( outputDensity"<< "("<< status <<")" << std::endl;
size_t global[3] = {4096,1,1};
cl_event w;
status = clEnqueueNDRangeKernel(commandQueue, outputDensity_kernel, 1, 0, global,0,0,NULL,&w);
if(status != CL_SUCCESS)
std::cout<<"Error: clEnqueueNDRangeKernel"<< "("<< status <<")" << std::endl;
clWaitForEvents(1,&w);
clReleaseEvent(w);
size_t origin[3] = {0,0,0};
size_t globalImage[3] = {16,16,16};
cl_event w2;
status = clEnqueueCopyBufferToImage(commandQueue,output,outputTexture,0,origin,globalImage,0,NULL,&w2);
if(status != CL_SUCCESS)
std::cout<<"Error: clEnqueueNDRangeKernel"<< "("<< status <<")" << std::endl;
clWaitForEvents(1,&w2);
clReleaseEvent(w2);
status = clEnqueueReleaseGLObjects(commandQueue, 1, &outputTexture, 0, NULL, NULL);
if(status != CL_SUCCESS)
std::cout<<"Error: clEnqueueAquireGLObjects ( outputDensity"<< "("<< status <<")" << std::endl;
clFinish(commandQueue);
}