面向对象架构,用于简单的基于着色器的GL程序
OO architecture for simple shader-based GL program
我正在设计一个OO程序(用C++),它处理用OpenGL实现的中等简单的图形。我已经为我的Drawable
对象编写了几个顶点着色器程序。此外,我还在Shader
类中封装了着色器管理(编译、链接和使用)。
我的问题是,由于我的所有类都将使用这一小组着色器渲染视觉对象,并且它们都有一个指向Shader
对象的指针,因此为所有类提供公共引用是否有意义,这样可以避免多次编译"同一"着色器代码?
如果是,为什么?防止着色器代码的重复真的很重要吗?(我的程序可能会有数千个独立的视觉元素,需要一起渲染)。我是OpenGL的新手,性能/效率问题对我来说仍然很模糊…
编辑:此外,我想知道我的着色器制服会发生什么;它们也会被分享吗?这应该如何允许我,例如以不同的速率旋转我的元素?每次我想绘制每个元素时,编写元素统一(即模型矩阵)是否比复制着色器代码更好?
我敢打赌,在大多数(如果不是所有的话)OpenGL实现中,多次编译和链接同一着色器会导致着色器二进制文件的多个副本和统一空间等。调用glUseProgram在重复副本之间切换仍然会导致状态更改,尽管在调用前后GPU内核上运行相同的代码。有了足够复杂的场景,你可能也会切换纹理,所以无论如何都会有状态变化。
这可能不是你的瓶颈,但肯定是浪费。对于着色器和纹理等静态内容,一个好的模式是拥有一个或多个Manager
类(AssetManager
、TextureManager
等),这些类将延迟加载(或预加载)所有资产,并在您请求时为您提供共享指针(或其他内存管理策略),通常是通过一些字符串ID。
关于编辑:
是的,您的制服将被共享,并且在您解除绑定后仍将被装载。这是首选的方法,因为更新统一比绑定新着色器快一个数量级以上。您只需为每个新对象设置模型矩阵统一,但保持相同的着色器。
统一格式存储在着色器中,因此切换着色器意味着加载所有统一格式。
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- c++r值引用应用于函数指针
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 如果编译的源代码是特定于它编译的硬件的,我们如何分发它
- 如何仅使用对象名称打印特定于对象的成员
- 相当于LocaleMatcher的ICU4C
- 等<thing>效于char32_t
- 类似于strcat()的函数出现问题
- 尝试链接我的着色器时,我收到错误代码"error c5145 must write to gl_position"
- OpenGL - 在 NDC 中计算位置适用于着色器,但不适用于'regular'程序
- 计算着色器Open GL ES的多个输入
- Open GL ES 3.1 的计算着色器的最小工作示例
- GCC 相当于 MSVC 中的 /GS、/GL、/Gy、/Oi、/MD
- 尝试创建波形着色器,我似乎无法计算法线以将镜面照明应用于我的波形
- 面向对象架构,用于简单的基于着色器的GL程序
- 打开"GL着色器存储缓冲区对象"以替换"顶点属性"
- 打开GL彩色拾取器不是着色对象
- 如何将应用于所有顶点的动态数据传递给顶点着色器
- 如何从文件中的类调用,以使用着色器显示在另一个包含gl代码的文件中(其中两个文件都在jni文件夹中)
- 如何使用DirectX11着色器将纹理应用于正交平面