使 glReadPixel() 运行得更快

2023-12-09

我想要一种非常快速的方法来为我的应用程序捕获 openGL 帧缓冲区的内容。一般来说,glReadPixels()用于将framebuffer的内容读取到缓冲区中。但这很慢。

我试图通过创建 4 个线程使用 glReadPixels() 从 4 个不同区域读取帧缓冲区来并行读取帧缓冲区内容的过程。但由于分段错误,该应用程序正在退出。如果我从线程中删除 glReadPixels() 调用,则应用程序可以正常运行。


线程不起作用,请放弃这种方法。

正如您所注意到的,创建多个线程会失败,因为只有一个线程具有当前的 OpenGL 上下文。原则上,你could在调用之前使上下文在每个工作线程中处于当前状态glReadPixels,但这需要您进行额外的同步(否则,在使上下文成为当前上下文和读回之间,线程可能会被抢占!),并且(wgl|glx)MakeCurrent是一个非常慢的函数,会严重阻碍 OpenGL。最后,你会做更多的工作得到很多东西slower.

There is no way to make glReadPixels any faster1, but you can decouple the time it takes (i.e. the readback runs asynchronously), so it does not block your application and effectively appears to run "faster".
You want to use a Pixel buffer object for that. Be sure to get the buffer flags correct.

请注意,映射缓冲区以访问其内容将still如果完整的内容还没有完成传输,则阻塞,所以它会still不会再快了。为了解决这个问题,您要么必须读取前一帧,要么使用可以查询的栅栏对象以确保它已完成。
或者,更简单但不太可靠,您可以在两者之间插入“一些其他工作”glReadPixels并访问数据。这不能保证在您访问数据时传输已完成,因此它可能仍会阻塞。然而,它may只要工作,它就会likely阻塞时间较短(因此运行“更快”)。


1 There are plenty of ways of making it slower, e.g. if you ask OpenGL to do some weird conversions or if you use wrong buffer flags. However, generally, there's no way to make it faster since its speed depends on all previous draw commands having finished before the transfer can even start, and the data being transferred over the PCIe bus (which has a fixed time overhead plus a finite bandwidth).
The only viable way of making readbacks "faster" is hiding this latency. It's of course still not faster, but you don't get to feel it.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使 glReadPixel() 运行得更快 的相关文章

  • 在 OpenGL 中渲染纹理 1 到 1

    所以我想做的是使用 OpenGL 和 C 将纹理渲染到平面上 作为显示图像的一种方式 但是我需要确保在渲染纹理时没有对纹理进行任何处理 抗锯齿 插值 平滑 模糊等 这是 OpenGL 处理渲染纹理的默认方式吗 或者是否需要设置一些标志才能禁
  • GLSL聚光投影体积

    在我的开源项目中 我使用 Qt3D 设置了延迟渲染管道 到目前为止一切顺利 但现在我想通过添加聚光灯投影量来继续前进 例如场景中好像有烟雾 像这样 我正在使用的片段着色器位于问题的末尾 我读过 对于每个片段 我应该从光位置进行光线行进并找到
  • 渲染缓冲区大于窗口大小 - OpenGL

    我正在尝试绘制大于屏幕尺寸 即 320x480 的渲染缓冲区 512x512 执行 glReadPixels 后 图像看起来是正确的 除非图像的尺寸超过了屏幕尺寸 在本例中 超过了水平 320 和垂直 480 是什么原因导致这种异常现象呢
  • 实例着色器矩阵的设置

    我想绘制实例立方体 我可以打电话GL DrawArraysInstanced PrimitiveType Triangles 0 36 2 成功地 我的问题是所有立方体都绘制在相同的位置和相同的旋转 我如何为每个立方体单独更改它 要创建不同
  • 纹理采样:根据LOD值计算BIAS值

    GL ES 2 0 中的功能纹理2DLod在片段着色器中不可用 我需要移植 GLSL 着色器 在 GL ES 2 0 中我只能使用二维纹理 sampler2D 采样器 vec2 坐标 浮点数bias 告诉我如何计算 a 的值bias相当于已
  • 使用 gl_FragColor 与 vec4 颜色?

    似乎有很多不明确的地方gl FragColor被弃用 例如 它缺失在GLSL 4 40 规范 https www khronos org registry OpenGL specs gl GLSLangSpec 4 40 pdf 但它包含在
  • Windows 上的 OpenGL SDK

    我正在尝试编写一个 OpenGL 应用程序 因此我安装了 Windows 7 SDK 然而 它似乎是OpenGL 1 1 define GL VERSION 1 1 1 如何找到我安装的 OpenGL 版本 dll 以及在哪里可以找到较新的
  • 为贝塞尔曲线中的每个点绘制切线

    我设法绘制了一条贝塞尔曲线 如下所示 glColor3f 0 1 0 glBegin GL LINE STRIP for int i 3 i lt nPt i 3 glColor3f 0 0 0 for float k 0 k lt NLI
  • nVidia 和 ATI 之间的 OpenGL 渲染差异

    最近 我将 ATI 驱动程序 我使用的是 HD7970 更新为最新版本 但我的 OpenGL 项目的一些对象停止工作 更重要的是 他们适用于 nVidia 最新驱动程序 在 960m 上测试 ATI 和 nVidia 渲染管道之间有什么我应
  • 新显卡上的 nvoglv32.dll 中的绘制调用崩溃

    几天前 由于一些硬件更改 我设置了计算机并安装了新的 Windows 8 副本 其中 我将显卡从 Radeon HD 7870 更改为 Nvidia GTX 660 再次设置 Visual Studio 11 后 我从 Github 下载了
  • OpenGL 新手: glutMouseFunc

    我试图在单击鼠标后更改球体位置 但在使用 glutMouseFunc 中的 x 和 y 时它不起作用 以下是代码 include stdafx h include
  • GLSL memoryBarrierShared() 有用吗?

    我想知道 memoryBarrierShared 的用处 事实上 当我查找屏障功能的文档时 我读到 对于计算着色器中任何给定的静态屏障实例 单个工作组内的所有调用都必须进入该实例 然后才能允许任何调用继续超出该实例 这确保了在给定的屏障静态
  • 在 OpenGL 中设置 MVP 矩阵

    我正在尝试学习 OpenGL 的基础知识 但我在设置变换矩阵时遇到问题 我制作了模型 视图和投影矩阵 但将它们发送到我的顶点着色器时遇到问题 这是代码 Set up MVP glm mat4 model glm mat4 GLint uni
  • Libgdx SpriteBatch.draw() 指定 4 个顶点

    我正在使用 libGdx 创建一个 2d 游戏 并尝试使用这个特殊的方法来绘制一个简单的 2d 纹理 分别指定 4 个顶点 draw Texture texture float spriteVertices int offset int l
  • OpenGL旋转自定义实现

    我正在尝试编写 Opengl glRotatef angle x y z 函数的自定义实现 我写了旋转矩阵 但是当我尝试使用它时 效果与原始函数不一样 这是我的代码 void mglRotate float angle float x fl
  • OpenGL 中的 VBO 到底是什么?

    我正在尝试了解 OpenGL 背后的理论 目前正在研究 VBO 到目前为止我的理解是 当我们声明一系列顶点时 比如说形成一个三角形基元的 3 个顶点 我们基本上不会将它们存储在任何地方 它们只是在代码中声明 但是 如果我们想将它们存储在某个
  • 如何将 OpenGL 数学 (GLM) 添加到 Xcode 4?

    我不知道如何将框架添加到我的项目中 我尝试像任何其他框架一样添加它 方法是单击 链接二进制文件与库 下的加号按钮 然后单击 其他 然后选择 GLM 文件夹 但是当我去包含它时 自动完成功能可以工作 但无法构建 因为它说找不到该文件 图书馆网
  • 如何获取片段的当前颜色?

    我正在尝试了解 GLSL 中的着色器 并且找到了一些有用的资源和教程 但我一直在寻找一些应该是基本且微不足道的东西 我的片段着色器如何检索当前片段 你通过说设置最终颜色gl FragColor whatever 但显然这是一个仅输出值 如何
  • 纹理映射和光照顶点着色器错误 Java OpenGL

    我正在尝试将纹理映射到 3D 立方体并尝试编写着色器以使其具有照明和纹理 我尝试过只编写纹理着色器并且它有效 我还尝试过仅将 3D 值设置为红色的照明着色器 并且该照明着色器也可以工作 但当我尝试将两者结合起来时 我遇到了问题 我在下面提供
  • OpenGL 中的像素间隙从何而来?

    我遇到的问题是 渲染场景中有一些像素 似乎丢失 看不见 因此与我的透明颜色相同 颜色 有趣的是 只有当 MSAA 关闭时才会发生这种情况 我的第一个想法是 这可能与以下事实有关 所有三角形都是重叠的 并且被投影矩阵以某种方式扭曲 但这些伪像

随机推荐