OO架构,用于简单的基于着色器的GL程序

时间:2017-01-17 17:55:04

标签: c++ opengl opengl-es shader

我正在设计一个OO程序(用C ++编写),它处理用OpenGL实现的中等简单图形。我为我的ListView个对象编写了几个顶点着色器程序。另外,我在foreach (ColumnHeader columnHeader in ListView.Columns) { columnHeader.Width = -2; } 类中封装了着色器管理(编译,链接和使用)。

我的问题是,因为我的所有类都将使用这一小组着色器渲染可视对象,并且它们都有一个指向Drawable对象的指针,提供公共引用是否有意义< / strong>让他们所有人都使用,这样就可以避免同样的&#34;相同的&#34; shader代码编译不止一次?

如果是这样,为什么?防止重复着色器代码真的很重要吗? (我的程序可能会有数千个需要一起渲染的独立视觉元素)。我是OpenGL的新手,性能/效率问题对我来说仍然很模糊......

编辑:此外,我想知道我的着色器制服会发生什么事情;他们也会被分享吗?应该如何允许我这样做,例如以不同的速度旋转我的元素?每次我想绘制每个元素时,编写元素制服(即模型矩阵)比使用复制着色器代码更好吗?

1 个答案:

答案 0 :(得分:1)

我敢打赌,在大多数(如果不是全部)OpenGL实现中,多次编译和链接相同的着色器将导致着色器二进制文件的多个副本和制服的空间等。调用glUseProgram在您的重复副本之间切换仍将导致尽管在调用之前和之后在GPU核心上运行了相同的代码,但状态发生了变化。有足够复杂的场景,你可能也会切换纹理,所以无论如何都会有状态改变。

这可能不是你的瓶颈,但肯定是浪费。静态内容(如着色器和纹理)的良好模式是具有一个或多个Manager类(AssetManagerTextureManager等),这些类将延迟加载(或预加载)所有你的资产,并在你提出要求时给你一个共享指针(或其他一些内存管理策略),通常用一些字符串ID。

关于修改:

是的,你的制服将被分享,也将remain loaded after you unbind。这是执行此操作的首选方法,因为updating a uniform is more than an order of magnitude faster than binding a new shader。您只需为每个新对象设置模型矩阵制服,但保留相同的着色器。

制服与着色器一起存储,因此切换着色器意味着无论如何都要加载所有制服。