多线程内的 OpenGL VBO

2023-12-07

我正在用 C++/OpenGL 开发一个程序,它可以绘制整个世界的地形。我有一个以图块形式存储的海拔高度数据库。每次启动程序时,都会加载一个图块。然后,当人移动时,应该加载另一个图块,这不会每帧都发生,可能每 5 分钟一次。

我将初始图块加载到显卡内存中:

glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBuffer[idx]);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, VBOsz * 3 * sizeof(float), tile_data, GL_STATIC_DRAW_ARB);

...有法线、颜色和索引缓冲区

我画了它们:

glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBuffer[idx]);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, VBOsz * 3 * sizeof(float), tile_data, GL_STATIC_DRAW_ARB);


glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBuffer[idx]);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

...

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, IndexBuffer[idx]);
glDrawElements(GL_TRIANGLES, IndexBuffersz, GL_UNSIGNED_INT, BUFFER_OFFSET(0));

glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

由于我希望程序尽可能流畅,因此我无法计算同一帧的顶点+颜色+法线+其他纹理,因为创建一个图块大约需要20秒。

因此,我决定创建一个加载器线程来检查何时需要加载新图块,然后加载它。当一切完成后,它应该只交换 VBO(因此 [idx].

因此,对于加载器线程,我知道我需要第二个 OpenGL 上下文,我创建了一个上下文并在它们之间共享列表。这个想法是有效的,但是在加载器线程中,当我发送新的VBO数据时,我需要这个函数:wglMakeCurrent

只有当所有数据都已加载后,我才能将上下文设置为渲染线程(主程序的线程)。这会导致在这段时间内没有绘制任何内容,从而使程序毫无用处。

您对解决方案有什么想法吗?我需要改变观念吗?

我正在使用 OpenGL 2.1。升级到 OpenGL 3 可以解决问题吗?


这其实并没有那么复杂。

您只需创建两个缓冲区对象:一个用于当前渲染,另一个用于将来。当未使用的缓冲区充满数据时,渲染线程会从该缓冲区切换到渲染。先前使用的缓冲区将成为未使用的缓冲区。

您可以通过两种方式之一上传数据。一种方法是让数据创建线程创建一个数据数组,渲染线程将使用该数组将其上传到缓冲区对象glBufferData。显然,这需要一些同步,但您需要的是同步代码:最终必须在数据准备好时通知渲染线程,以便它可以使用新数据进行渲染。

另一种方法是告诉您的渲染线程需要开始生成数据。此时,它将映射未使用的缓冲区对象并将映射的指针传递给数据创建线程。该线程将直接将数据生成到该映射指针中。当它完成时,它通知渲染线程,渲染线程将取消映射缓冲区,然后使用数据进行渲染。

这两种方法都不需要多个上下文或通过 OpenGL 代码进行线程化。

请注意,性能最好的服务是not使缓冲区变大或变小。选择尺寸并坚持使用;你不想调整缓冲区大小glBufferData.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多线程内的 OpenGL VBO 的相关文章

  • SDL 鼠标位置调整大小后裁剪

    我在 SDL 中的鼠标位置上遇到了一些奇怪的行为 如果我将窗口大小调整得更大 则任一鼠标事件的 x y 位置似乎都限制为原始窗口的宽度和高度 如果我缺少一些函数调用来告诉 SDL 鼠标区域的大小已增加 应用程序的相关部分 void Resi
  • 什么时候 Thread.sleep(1000) 睡眠时间少于 1000 毫秒?

    在这篇有趣的文章中程序员对时间的看法是错误的 http infiniteundo com post 25509354022 more falsehoods programmers believe about time wisdom 其中之一
  • 如何在 GTX 560 及更高版本上使用 OpenGL 进行立体 3D?

    我正在使用在 Windows 7 上运行的开源触觉和 3D 图形库 Chai3D 我重写了该库以使用 Nvidia nvision 执行立体 3D 我将 OpenGL 与 GLUT 一起使用 并使用 glutInitDisplayMode
  • 使用 C# 截取任何外部应用程序的屏幕截图

    我们有一个 C WPF 应用程序 我们想要在其中截取我们启动的任意应用程序的屏幕截图 即 我们可以引用我们启动的进程 应用程序可能已最小化或位于其他窗口后面 但我们仍然只需要单个应用程序的图像 而不是重叠像素 我知道使用 BitBlt 或的
  • 如何多线程从列表中读取字典并输入数据库

    我正在尝试对以下代码进行多线程处理 但似乎无法使其正常工作 以下代码 其中我删除了大部分代码只是为了说明目的 目前运行顺利 但速度很慢 对于 3600 条推文的列表大约需要 5 分钟 import dataset import dateti
  • Unity3d 中的多线程脚本调用

    我试图在Unity3d中实现多线程脚本执行 但是Unity库似乎没有提供方法 我们必须使用Mono提供的System Threading 但他们提到 Unity Scripting 不是线程安全的 我可以使用 System threadin
  • PyQt5 的 OpenGL 模块和版本控制问题(调用不正确的 _QOpenGLFunctions_(ver))

    我一直在努力得到PyQt5 helloGL 示例代码 https github com baoboa pyqt5 blob master examples opengl hellogl py编译 当我尝试构建解决方案时 我得到 Traceb
  • 插入并发问题-多线程环境

    我有一个问题 即使用完全相同的参数在完全相同的时间调用相同的存储过程 存储过程的目的是获取记录 如果存在 或创建并获取记录 如果不存在 问题是两个线程都在检查记录是否存在并报告错误 然后都插入新记录 在数据库中创建重复记录 我尝试将操作保留
  • 线程安全的get(访问器方法)

    我目前正在使用以下代码对变量进行线程安全访问 int gnVariable void getVariableValue int pnValue acquireLock Acquires the protection mechanism pn
  • c++11 中的 std::thread 问题

    我在尝试从标准模板库编译具有多线程的程序时遇到一些麻烦 当我尝试编译以下程序时 它返回一个晦涩的错误 include
  • Java 执行器和长寿命线程

    我继承了一些使用 Executors newFixedThreadPool 4 的代码运行 4 个长寿命线程来完成应用程序的所有工作 这是推荐的吗 我读过Java 并发实践 https rads stackoverflow com amzn
  • 如果未返回,则在一段时间后终止线程

    我有一个线程从网络或串行端口获取一些数据 如果 5 秒内没有收到数据 则线程必须终止 或返回 false 换句话说 如果线程运行时间超过 5 秒 则必须停止 我用 C 编写 但任何 NET 语言都可以 有两种方法 1 封装超时 从网络或串行
  • 在不支持 CAS 操作的处理器上进行 CompareAndSet

    今天 我在一次采访中被问到下一个问题 如果您在具有不支持 CAS 操作的处理器的机器上调用 AtomicLong 的compareAndSet 方法 会发生什么情况 您能否帮我解决这个问题 并在可能的情况下提供一些全面描述的链接 From
  • 为什么在谈论线程和进程时,“不要同时格式化软盘”的评论很有趣?

    我正在阅读之间的区别线程和进程 https stackoverflow com questions 200469 what is the difference between a process and a thread并在第二个答案中发现
  • 如何通过start-stop-daemon正常关闭Spring Boot应用程序[重复]

    这个问题在这里已经有答案了 我们有一个多线程 Spring Boot 应用程序 它作为守护进程在 Linux 机器上运行 当我尝试像这样通过启动停止守护进程停止应用程序时 start stop daemon stop quiet retry
  • 将数据从一个线程传递到另一个线程的最快可能方法

    我正在使用增强spsc queue将我的东西从一个线程移动到另一个线程 这是我的软件中的关键位置之一 所以我想尽快完成它 我写了这个测试程序 include
  • 通过推送通知唤醒

    Suppose 有一些对象 例如 一个数组a 和依赖于对象的条件 例如 a empty 当前线程以外的某些线程可以操作该对象 a 因此条件评估值的真实性会随着时间的推移而变化 如何让当前线程在代码中的某个时刻休眠 并在条件满足时通过推送通知
  • 如何使用 runOnUiThread 而不出现“无法对非静态方法进行静态引用”编译器错误

    我有一个主课 ClientPlayer extends Activity 和一项服务 LotteryServer extends Service implements Runnable 当尝试在此服务的 run 方法中使用 RunOnUiT
  • GLSL NVidia 方形神器

    当 GLSL 着色器在以下 GPU 上生成不正确的图像时 我遇到了问题 GT 430 GT 770 GTX 570显卡760 但在这些上正常工作 英特尔高清显卡 2500英特尔高清4000英特尔4400显卡740MRadeon HD 631
  • 新任务中使用的依赖注入服务

    我在需要时使用依赖项注入来访问我的服务 但我现在想要创建一个并发任务 但这会由于依赖项注入对象及其生命周期而导致问题 我读过这篇文章 标题 防止多线程 Link http mehdi me ambient dbcontext in ef6

随机推荐

  • 我想在 ping 主机后获取 ping 执行时间和结果字符串

    我想在 ping 主机后获取 ping 执行时间和结果字符串 我该怎么做 long currentTime System currentTimeMillis boolean isPinged InetAddress getByName se
  • Defer 块未执行

    我在操场上执行以下快速代码 func A print Hello guard 1 2 else return defer print World A 我期待看到 Hello World 相反 只有Hello被打印 为什么是这样 我缺少什么
  • Matlab中两点之间的距离

    我有 2 个向量 一个的尺寸为 200 2 另一个的尺寸为 3 2 它们都是笛卡尔坐标系中的点 我想计算前 200 个点和其他 3 个点之间的距离并将它们存储在向量中 我正在使用这样的函数 for i 1 cur for j 1 200 L
  • 带有 SpriteKit 的 iOS 通用设备应用程序,如何缩放所有视图的节点?

    我想做一个景观 app to be 普遍的 以便精灵节点根据运行应用程序的任何视图大小按比例缩放 我想要一个完全程序化解决方案 因为我不喜欢IB 我的游戏非常简单 我不需要任何类型的滚动或缩放 因此整个游戏将始终存在并占据整个视图 我正在寻
  • java将数组刷新到jList中

    好的 我有一个 JList 内容是通过数组提供的 我知道如何向数组添加元素 但我想知道如何刷新 JList 或者甚至可能吗 我试过谷歌 import java applet Applet import java awt import jav
  • 如何满足迭代器特征界限才能在这里使用 Rayon?

    我正在尝试使用 Rayon 的并行化 Ramer Douglas Peucker 线简化算法par iter代替iter extern crate num traits use num traits Float ToPrimitive ex
  • 属性访问器[重复]

    这个问题在这里已经有答案了 之间有什么根本区别吗 public string Name get return name set name value and public string Name get set 您可以访问内部字段 在第二种
  • 使用循环创建菱形图案

    我正在尝试编写一个程序 该程序读取整数并使用星号显示给定边长的实心菱形 例如 如果边长是4 程序应该显示 这就是我正在尝试做的事情 它正在执行 但我似乎无法为程序提供正确的空间来正确显示菱形形状 userInput int input Pl
  • 如果 json 字段具有特殊字符(如点),则访问 json 字段值

    如果我有一个 json 文件 其中的字段具有特殊字符 在我的例子中是点 我如何访问空手道中的字段值 例如有一个名为 example json 的 json 文件 field1 field2 value2 field 3 value3 如果我
  • 根 ViewController 内的 UIViewController 不旋转

    我有一个 UIViewController 我想将其作为独立层添加到整个应用程序的顶部 所以我尝试在应用程序委托中使用 self window addSubview viewController view 将其添加到 UIWindow 中
  • 将 9 位值作为字节写入 C 中的文件

    我有一个整数值从 0 511 最多 9 位 的数组 我正在尝试将其写入文件fwrite 例如 对于数组 257 258 259 Which is 100000001 100000010 100000011 I am trying to wr
  • 设置配置文件的过期时间

    是否可以设置配置文件的到期日期 我正在公司内部进行试用 我想设定expiration审判结束的日期 而不是仅仅一年之后creation日期 是否有可能 或者总是需要一年的时间creation date 另外 如果无法设置expiration
  • 无法从 json 对象访问数据

    我已将 json 数据结构存储在具有单列的数据框中 名为json 数据在R中 所以我的 json 文本以这种格式存储 row 1 results formatted address Sahibzada Ajit Singh Nagar Pu
  • 使用 Dumper 不会触发故障

    当运行这样的代码时 use strict print Dumper something 编译和运行时没有打印任何内容 也没有发生错误 为什么会出现这种情况 为什么不strict阻止此代码运行 尽管 Dumper 未知 但为什么运行时没有错误
  • 在docker容器内运行maven集成测试

    在运行集成测试之前 我使用 dockerfile maven 插件将我的 jar 文件移动到 docker 容器内 但是 mvn verify 命令构建图像并运行集成测试 结果测试失败 有人可以帮我在运行集成测试之前运行 docker 镜像
  • Python 中的节拍器脚本中的计时问题(使用 Pygame)[重复]

    这个问题在这里已经有答案了 我正在尝试编写一个节拍器脚本 它可以为我提供音频反馈并将 MIDI 消息发送到合成器 我用Python 2 7 5 and Pygame 1 9 1 release在 Linux Mint 16 上 我对 MID
  • Pytest 日志记录忽略 pytest.ini 中的选项

    我正在运行一个测试 pytest capture no verbose rootdir testing testing tests docker test py from home user development 该测试检查某些容器是否正
  • 同步 WrapPanel 中的 WPF 控件宽度

    我有这个案例
  • 这个命名变量是如何工作的?

    我是Python的初学者 我发现了一种奇怪的变量命名方式 并且根本无法理解 有人能帮助我吗 x 1 n 1 1 3 for i in n y x x i 我想理解这一行y x x i这是什么意思 这称为元组拆包 右边只是一个元组 表达式中的
  • 多线程内的 OpenGL VBO

    我正在用 C OpenGL 开发一个程序 它可以绘制整个世界的地形 我有一个以图块形式存储的海拔高度数据库 每次启动程序时 都会加载一个图块 然后 当人移动时 应该加载另一个图块 这不会每帧都发生 可能每 5 分钟一次 我将初始图块加载到显