显示从其他PC捕获的屏幕缓冲区的最快方式

时间:2015-01-09 02:15:07

标签: c opengl opengl-es screen screenshot

我的问题如下:

我有一个存储 framebuffer 的指针,它经常被某个线程更改。

我想通过OpenGL API显示这个 framebuffer 。我的琐碎选择是使用glTexImage2D并每次一次又一次地加载 framebuffer 。这种在帧缓冲区上的加载是必要的,因为帧缓冲区在OpenGL API之外被更改。我认为可能有一些方法或技巧可以加速,例如:

  • 找出帧缓冲区内的变化(甚至可能吗?)

  • 快速重新加载图像的一些方法

  • OpenGL可以直接使用framebuffer的指针吗? (减少帧缓冲复制)

我不确定上述方法是否有效。我希望你能给出一些建议。

1 个答案:

答案 0 :(得分:2)

  
      
  • 通过找出帧缓冲区内的变化(甚至可能吗?)
  •   

这会减少所需的带宽,因为它实际上是视频压缩。但是,CPU负载明显更高,而且比仅仅DMA复制数据要慢得多。

  

快速重新加载图像的一些方法

使用 glTexSubImage2D 代替 glTexImage2D (注意...... Sub ...)。每次调用时, glTexImage2D 都会经历一次完整的纹理初始化,这相当昂贵。

如果您的程序使用OpenGL 进行其他操作而不是仅显示图像,则可以通过使用像素缓冲区对象减少程序等待完成任务的时间来进一步加快速度。基本要点是

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID);
void *pbuf = glMapBuffer();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
thread image_load_thread = start_thread_copy_image_to_pbo(image, pbuf);

do_other_things_with_opengl();

join_thread(image_load_thread();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID);
glUnmapBuffer();
glBindTexture(…);
glTexSubImage2D(…, NULL); /* will read from PBO */
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

draw_textured_quad();

您可以使用线程池和条件变量进行线程间同步,而不是创建和连接线程。

  
      
  • OpenGL可以直接使用framebuffer的指针吗? (所以减少帧缓冲复制)
  •   

几乎总是要复制东西。如果有必要,请不要担心副本。我在上面概述的像素缓冲区对象可能与系统RAM中的着色器副本一起使用也可能不兼容。基本上你可以将glBufferMap加入你的进程的地址空间,并直接解码到你给出的缓冲区。但这并不能保证避免进一步复制。