c++ - 了解 OpenGL 中的绑定(bind)/激活纹理性能损失

标签 c++ opengl

我不确定我正在做的事情是否最佳。

我有三个纹理(其中两个是堆叠有大量信息的数组纹理)并且我进行了三个渲染过程:

  • 具有纹理 1 的关卡几何体

  • 具有纹理 2 的世界实体

  • 具有纹理 3 的 HUD 内容

因此我的代码通常会做类似这样的伪代码:

bindTexture(tex1);
drawLevel();
unbindTexture(tex1);  // Is this necessary if I just bind after anyways?

bindTexture(tex2);
drawEntities();
unbindTexture(tex2);

bindTexture(tex3);
drawHUD();
unbindTexture(tex3);

因为我记得在 GL_TEXTURE0、GL_TEXTURE1 等上允许最多 16 个(或更多)独立纹理,这是否意味着我可以将我的世界纹理写入 GL_TEXTURE0,将实体写入 GL_TEXTURE1,将 HUD 写入 GL_TEXTURE2 和有没有性能损失,还是很少?或者即使改变事件纹理也会带来明显的损失?

我问是因为我记得看到纹理交换是一项繁重的操作。这是否意味着即使我改变我的事件纹理,它仍然很费力?还是仅当您有超过 16 个左右的纹理并不断将它们推送到 GPU 时才会增加负担?

这是错误还是缓慢?

我只需要 3 个纹理,所以如果有最优化的方法,我很乐意学习。

假设我使用的是核心 3.3 而不是 4.5(但如果在 4.2 或更高版本中有更好的方法,我也很乐意听到这些)。它也应该适用于 nvidia 和 AMD 或过去 4-5 年内发布的任何 GPU。

编辑:如果您发现我所说的任何奇怪概念是错误的,请纠正我,因为我是新手。出于这个原因,我宁愿有人在他们的回答中冗长。

最佳答案

我认为 OpenGL 中的事件纹理存在一些混淆。 OpenGL 让您可以同时 拥有多达 16 个事件纹理(编辑:每个着色器阶段)。因此,您可以让一个绘图调用一次最多引用 16 个纹理(有些实现将允许超过 16 个)。

您可以创建并在程序中激活的纹理数量没有限制(物理 VRAM 限制除外)。更重要的是,大多数 OpenGL 驱动程序都围绕以下假设进行了优化:您将为每个绘制调用 绑定(bind)一个新纹理(或可能多个纹理)。

更改事件纹理是一个相对昂贵的过程,但不是在您使用它的上下文中。例如,如果每个实体都有多个纹理可供引用,并且每个实体都是一个很小的对象,否则不会花费太多精力来渲染,这将很重要。当您将所有纹理真正捆绑成 3 个“巨型纹理”并且仅在从一组对象移动到下一组对象时才进行切换时,它就不那么重要了。在这种情况下,切换纹理的成本微不足道且不值得关注。

我会说这看起来有点像过早优化的情况,因为将所有东西捆绑在一起的努力可能代表工作量足迹可能超过您从最终结果中获得的好处,但这是一个决心你必须自己做。

但是,TL;DR:您的代码在功能或性能方面没有任何错误。

关于c++ - 了解 OpenGL 中的绑定(bind)/激活纹理性能损失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42425281/

相关文章:

c# - "On-the-run"调试/监控

c++ - Vectors of vectors 字符串问题

c - OpenGL MVP 矩阵计算错误

java - Lwjgl MouseDwheel 没有得到 0

c++ - std::auto_ptr、delete[] 和泄漏

c++ - 我可以声明一个模板只接受具有同质签名的函数吗?

c++ - 无法在 macOS 上的 SDL 游戏中加载图像

delphi - 对于小数组来说,glDrawArrays 永远不会比 glBegin/glEnd 更快吗?

c++ - OpenGL-QT : Mouse move event effects is not showing up

opengl - 简单 OpenGL 图像库 (SOIL) 使用已弃用的功能?