multithreading - 带网络代码的OpenGL程序示例?

标签 multithreading networking opengl boost network-programming

我想知道是否有人知道与OpenGL集成的网络代码的任何示例。

基本上,我需要通过网络将某物的位置坐标发送到我的OpenGL显示器...然后将其绘制在正确的位置。

我遇到的问题是将UDP代码与游戏集成在一起。我基本上有一个循环不断更新/绘制。我最初以为我可以将UDP代码放在单独的线程中,而只是更新共享坐标。但是,如果我的绘制函数在完成网络代码写入新位置之前读取位置,那么我就有竞争条件和无效数据...但是我无法使Update或Draw循环块...

我不确定在这里应该使用同步还是异步网络代码。

那么,有关如何解决此问题的任何提示?谢谢

最佳答案

我假设您的游戏是实时的,因为您已经编写了使用UDP的信息,并且没有其他说法。此问题的一般解决方案是:

  • 用于实现网络状态的缓冲,这将延迟与稳定性进行了权衡。
  • 将模拟与渲染循环分离。
  • 在两个或多个状态之间插值,而不是将状态视为绝对状态。
  • 实现客户端预测。

    正在缓冲

    缓冲可以 boost 稳定性,因为模拟将始终滞后于接收到的数据。这样,您将永远不会用完要在接收端进行仿真的数据。这的自然结果是等待时间略有增加。具有良好的启发式(大小合适的缓冲区),模拟将永远不会 catch 缓冲区,即,同步将永远不会阻塞,除非通信 channel 本身在较长的时间段内变得不稳定。这可能是可用带宽的突然变化,数据包丢失,延迟严重增加等。您还可以使用同步原语,该原语会在超时(例如1毫秒)时阻塞。发生超时时,您可以使用外推法而不是内插法(请参见下文),一起放弃更新丢失的状态,而仅更新客户端预测处理的内容(如果有的话),或者拒绝更新任何内容,直到您与偏远的一面。

    仿真回路解耦

    您的仿真应该以恒定的频率采样。通过将模拟与渲染分离,您可以以比模拟采样更高的频率进行渲染。例如,您的模拟可以30 fps的速度运行,但是您仍然可以按照图形卡允许的速度进行渲染,例如300 fps。这意味着您需要通过网络发送较少的数据,但又不牺牲动画质量。

    节省带宽,在样本之间进行插值

    在两个样本之间平滑地插值,而不是将数据视为绝对值。例如游戏中的玩家位置。如果您直接使用矢量简单地移动或捕捉玩家位置,您将需要一些疯狂的高采样频率,这会淹没您的网络。通过分别在两个或三个点之间使用线性或三次插值,您可以获得平滑的运动,但采样点很少。当然这需要一个插值点,因此它将以一个增量时间(即您的时间步长)增加延迟。

    概括

    编辑:好的,那么这些概念如何直接与您的问题相关?您的问题是设计问题;您只需将数据直接发送到仿真和渲染中就可以了。使用其wait()函数具有超时的互斥锁可以解决阻塞问题,但不能解决数据匮乏的问题。某些延迟比频繁超时更好。这就是为什么我建议实现缓冲并将带宽使用降低到合理水平的原因。
    仅发送所需数量的数据,以获得足够好的结果。响应式和美学上。

  • 有关游戏网络理论的出色见解,请访问Glenn Fiedler博客上的文章:
    Gaffer on games : networking for game-programmers
    Gaffer on games : game-physics

    关于multithreading - 带网络代码的OpenGL程序示例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1548619/

    相关文章:

    c++ - 如何计算相机对象的 View 矩阵

    c++ - OpenGL-鼠标坐标到空间坐标

    java - 在线程中读取时的 BufferedReader readline

    c - FreeBSD 以太网操作

    python - 如何在发生错误时重新执行 ThreadPoolExecutor 中的函数?

    language-agnostic - 收听多播如何伤害我?

    linux - SO_TIMESTAMP 和 SO_TIMESTAMPING 软件时间戳的区别

    c++ - 在 GPU 中使用八叉树组织 3D 体数据

    .net - .NET垃圾收集和 native 线程

    c++ - 可以使用 boost::threads 中的 std::this_thread* 函数吗?