使用CUDA OpenGL在单个窗口上显示不同大小的图像

时间:2014-08-05 23:34:46

标签: opengl cuda

我有两个不同尺寸的图像(图像尺寸1:W1 * H1,图像尺寸2:W2 * H2)。通过启动两个Cuda内核正确处理这些图像。现在我想使用CUDA-OpenGL互操作在一个寡妇中显示它们。无论是水平显示还是垂直显示都可以。该应用程序适用于窗口上的一个图像。如果有人能告诉我如何在一个窗口上正确显示多个图像,我将不胜感激?

unsigned int ScreenWidth = W1+W2;
unsigned int ScreenHeight = H1+H2;    
static void display (void)
 {
   unsigned char *ImPtr;
   size_t mapped_size;
   checkCudaErrors(cudaGraphicsMapResources(1, &pbo_r, 0));
   checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void **)&ImPtr, &mapped_size,pbo_r));

   CrossSectionKernel<<<grid1, block1>>>(ImPtr, W1, H1);

   EnFaceKernel<<<grid2, block2>>> &ImPtr[W1*H1], W2, H2);

   checkCudaErrors(cudaGraphicsUnmapResources(1, &pbo_r, 0));

   glClear(GL_COLOR_BUFFER_BIT);

   glBindTexture(GL_TEXTURE_2D, textureID);
   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bufferObj);
   glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ScreenWidth, ScreenHeight,GL_LUMINANCE, GL_UNSIGNED_BYTE, 0);
   glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

   glDisable(GL_DEPTH_TEST);
   glEnable(GL_TEXTURE_2D);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

   glBegin(GL_QUADS);
     glVertex2f(0, 0);
     glTexCoord2f(0, 0);
     glVertex2f(0, 1);
     glTexCoord2f(0, 1);
     glVertex2f(1, 1);
     glTexCoord2f(1, 1);
     glVertex2f(1, 0);
     glTexCoord2f(1, 0);
   glEnd();
  glBindTexture(GL_TEXTURE_2D, 0);
  glutSwapBuffers();
  glutPostRedisplay();
 }

void initGL(int *argc, char **argv)
{
  glutInit(argc, argv);
  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
  glutInitWindowSize(ScreenWidth, ScreenHeight);
  glutCreateWindow("One Frame");

  glewInit();
} 

void createPBO()
{
  glGenBuffers(1, &bufferObj);
  glBindBuffer(GL_PIXEL_UNPACK_BUFFER, bufferObj);
  glBufferData(GL_PIXEL_UNPACK_BUFFER, (W1*H1 + W2*H2)*sizeof(unsigned char), NULL, GL_STREAM_DRAW);
  glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0 );
  checkCudaErrors(cudaGraphicsGLRegisterBuffer(&pbo_r, bufferObj, cudaGraphicsMapFlagsWriteDiscard));
}

void createTexture()
{
 glGenTextures(1,&textureID);
 glBindTexture( GL_TEXTURE_2D, textureID);
 glTexImage2D( GL_TEXTURE_2D, 0, GL_LUMINANCE, ScreenWidth, ScreenHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL);
 glBindTexture( GL_TEXTURE_2D, 0);

 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 glPixelStorei(GL_PACK_ALIGNMENT, 1);
}

int main(int argc, char **argv)
{
  initGL(&argc, argv);

  cudaDeviceProp prop;
  int dev;

  memset(&prop, 0, sizeof(cudaDeviceProp));
  prop.major = 1;
  prop.minor = 0;
  checkCudaErrors(cudaChooseDevice(&dev, &prop));

  cudaGLSetGLDevice(dev);

  glutDisplayFunc(display);

  createPBO();
  createTexture();
  glutMainLoop();  

  return 0;
}  

1 个答案:

答案 0 :(得分:1)

我会给你一个提示:你正在做两个不同的操作,但你只使用一个目标位置ImPtr。在每个CUDA内核执行后立即将内存ImPtr的内容复制到OpenGL纹理,或者使用两个不同的PBO。你应该使用两种纹理。