Search code examples
openglcudaglsltextures

is there any way to bin an 3d surface created in CUDA to an OpenGL texture?


here is the scenario: I pass an 3D OpenGL Texture to CUDA by cudaBindTextureToArray transforming it with a non rigid transformation and writed it to a 3d surface and then I want to pass it by a texture to GLSL shader for volume rendering. and GLSL only knows texture id?how I use this 3d surface as an ordinary OpenGL texture?

pseudo code

craete a texture with opengl like this

glTexImage3D(GL_TEXTURE_3D, 0,............);

pass it to cuda

create and fill a surface with

cutilSafeCall(cudaBindSurfaceToArray(volumeTexOut, outTexture->content));
......
..
  cutilSafeCall( cudaMalloc3DArray(&vol->content, &vol->channelDesc, dataSize,  cudaArraySurfaceLoadStore ) );

after transformation,..

  surf3Dwrite(short(voxel), volumeTexOut, sizeof(short)*x1,y1, z1);

and now i want to use this surface as an opengl Texture and pass it to GLSL


Solution

  • Update: The APIs suggested below are quite old and have been deprecated. Please see the current Graphics Interop APIs for CUDA

    CUDA OpenGL interop is (unfortunately) a one-way API: to interoperate between CUDA and OpenGL you must allocate all memory needed in your GL code using OpenGL, and then bind it to CUDA arrays or device pointers in order to access it in CUDA. You cannot do the opposite (allocate memory with CUDA and access it from OpenGL). This goes for data that is either read or written by CUDA.

    So for your output, you want to allocate the 3D texture in OpenGL, not with cudaMalloc3DArray(). Then you want to call cudaGraphicsGLRegisterImage with the cudaGraphicsRegisterFlagsSurfaceLoadStore, and then bind a surface to the resulting array using cudaBindSurfaceToArray. This is discussed in section 3.2.11.1 of the CUDA 4.2 CUDA C Programming Guide. The CUDA reference guide provides full documentation on the functions I mentioned.

    Note that surface writes require a compute capability 2.0 or higher GPU.