2017-05-29 40 views
0

发展teris的游戏,我来,使用通常的MVC模式可能会弄乱我的代码,以及,因为OpenGL是如何GLEW下工作进行了总结,使其实质上难以建立在。相反,我想出了这个整齐的修改,也依赖于观察者模式,这将使有点更有意义,至少在短期内(图像不完全反映分类):
makeshift architecture如何解决这个设计缺陷?

为了解释:
-Every框是一类,Engine保存Entities的实例,Game保存Figure的实例。
- Figure继承Entity
- Engine观察Game,和Game由观察员用Figures耦合。

如何它应该工作:
理想情况下,我应该实例Engine将设置GLEW和GLFW与其他一切将弥补窗口,然后创建一个Game对象,其中,在新的线程,将创建一个沿图中,并通知引擎启动绘图循环,并且当设置该图形时,通过Observer将对象指针传递给Engine
这做工精美,我将能够通过继承Entity添加各种各样的人物,人物不会从屏幕上掉下,因为每个坐标更新将经历Game,我可以,也许,让每个人物的唯一着色器,如果这是必要的。

如何它的实际工作:
引擎被初始化,游戏被初始化,数字是在另一个线程呼吁,并抛出

atioglxx.dll: 0xC0000005: Access violation reading location 0x00000728. 

当被问及访问任何的OpenGL函数。
我怀疑这种情况是因为Figure不知道,所有的配套功能,在Engine启动。我不能再在Figure中再做一次。我可以将与View相关的所有内容移动到Engine,但是我无法设置单独的着色器,并且我必须为Engine内的每个数字构建VAO(顶点数组对象)。
那么如何让错误消失,同时尽可能少地引入变化?

+0

这可能是一个有趣的问题,但也可能是题外话这里。 – Walter

+0

@Walter,我考虑将它放在gamedev.stack上,但它似乎并没有像建筑问题那么多地处理 –

回答

0

简短的回答是,所有OpenGL调用给定环境下需要在同一个线程。较长的答案是在路上...


首先,Entities需要能够与GL调用汲取自己。您不能将绘图代码从一个线程与另一个线程混合使用,OpenGL客户端状态将不正确。 (将OpenGL视为'C'状态机)。

其次,你需要通过帧缓冲实体状态。当您在Game线程中开始下一帧时,Engine可能会或可能不会完成提交绘制调用。所以你需要一些同步的方式来提交一个帧的所有Entity状态。这有点棘手,因为你想避免同步原语(例如互斥体),这可能会拖延你的管道或导致阻塞。

您可以阅读Doom III source code,它使用双缓冲管道将提取调用请求提交给Engine后端。诀窍是Doom在主线程中执行了大部分任务,然后拆分为在后端执行Draw Calls(Engine)线程并提交Game主线程下一帧的绘制状态(Entities)。然后它等待Engine线程完成并交换缓冲区。

阅读Metal和Vulkan多线程。这些非常相似。

资源需要在Engine被加载,并为您的实体引用返回的句柄(着色,纹理,静态Geomety,等..)