opengl 保留上一帧_OpenGL渲染线程与逻辑线程分离的错误架构示例

本文介绍了尝试实现OpenGL游戏引擎时遇到的渲染线程与逻辑线程分离的问题。在第一版程序结构中,由于OpenGL上下文不能跨线程访问导致崩溃。第二版尝试将上下文初始化移至渲染线程,但仍因逻辑线程内调用GL函数而失败。最终提出使用Command Buffer方法,通过生产者-消费者模型实现线程间通信,以解决跨线程操作渲染上下文的问题。
摘要由CSDN通过智能技术生成

最近在自己尝试实现一个基于opengl的游戏引擎,基础功能实现之后打算应用一些优化算法。首先想试一试渲染线程与逻辑线程分离,于是先闷头自己搞搞,亲身踩一踩坑(虽然前人已经踩过了)。

阅读此文前的知识背景

  • OpenGL

阅读此文后你会知道

  • 为什么朴素的opengl多线程渲染是行不通的

第一版程序结构

29d2a5e9e6106654cc06397a21534980.png

主线程也充当逻辑线程。一开始先进行渲染context的初始化,然后再进行逻辑的初始化。这样做之后出现了崩溃的问题,因为opengl的context无法被多个线程同时操作。在主线程(兼逻辑线程)里初始化的opengl context,在渲染线程里一访问就会崩溃。

另外我没有对逻辑线程和渲染线程进行加锁或同步操作,因为渲染线程并不会改变物体的逻辑数据状态,对逻辑数据是只读的;但问题是渲染线程可能会拿到上一帧的数据,但一个帧里渲染出来的图像是上一帧的状态还是下一帧的状态其实问题不大,因为一来一帧很短,二来数据的变换是连续的。

第二版程序结构

4205ee0896bbeb7fc3477a8117c7aff5.png

既然不能跨线程访问渲染context,那我把context初始化搬进渲染线程就行了呗。但还是不行。之所以不行是因为逻辑线程里有一些方法调用了gl函数。之所以在逻辑线程里调用gl方法是因为有两类需要逻辑和渲染进行强耦合的情况:

  • 必须耦合,比如实现后处理效果的类,当用户在逻辑线程里指定一个新的后处理shader时,逻辑不得不干涉渲染context的行为。
  • 为优化而耦合,比如只在物体transform属性有改变时(比如调用了rotate、translate方法之类)才去重新设置shader的uniform属性;而不是让渲染线程每次对每个物体都重新设置shader的属性。

可以看到,只要跨线程操作渲染context,运行时就会崩溃,返回一个奇怪的退出值。

正确的路径 Command Buffer

因此解决的办法应该是使用类似command buffer的方法,逻辑线程是生产者,渲染线程是消费者,把要干涉渲染context的行为构造一个协议在两个线程间传递。下一版正确的架构出来之后再写文章记录一下吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值