【问题标题】:Is it safe/acceptable to call SDL_SetTextureColorMod every frame multiple times?每帧多次调用 SDL_SetTextureColorMod 是否安全/可接受?
【发布时间】:2014-07-27 02:39:19
【问题描述】:

作为一种简单的方法来渲染除颜色之外的多个相同纹理,我将一个纯白色圆圈加载到 SDL_Texture 中,然后调用 SDL_SetTextureColorMod() 给它我想要制作圆圈的颜色。

如果纹理是单独的(示例 1),这一切都可以正常工作,但如果我共享 SDL_Texture 以便多个对象都引用它,这意味着必须在对象渲染之前的每个渲染帧调用 SDL_SetTextureColorMod()纹理,因为它上次提供的颜色可能已被另一个对象更改(示例 2)。

是否在每个渲染帧都调用SDL_SetTextureColorMod(),因为可能有相当多的对象共享一个纹理,会导致严重的性能问题?

需要它的原因是系统是使用具有基本引用计数的共享纹理功能设计的(我知道使用智能指针可能有更好的方法来做到这一点,但这不是这里讨论的主题)。让每个对象拥有自己的SDL_Texture 副本会更好吗?这样它只需设置一次颜色(或在需要更改时)而不是每个渲染帧?

示例 1:

SDL_Texture* tex1;
SDL_Texture* tex2;
SDL_Texture* tex3;
...
// All 3 instances have their own SDL_Texture
MyObject A(tex1);
MyObject B(tex2);
MyObject C(tex3);
...
// A call to set the color of the texture is only required once for each class

示例 2:

SDL_Texture* tex;
...
// All 3 instances share the SDL_Texture
MyObject A(tex);
MyObject B(tex);
MyObject C(tex);
...
// A call to set the color of the texture must be made before rendering 
// each object to ensure that any other object has not set a different color.
// E.g if the draw order was A, B, C and the color was set to be different
// for each object then before rendering B, each frame it would need to set 
// the color again otherwise it would have the color of A and the same 
// for the others    

编辑:这也将扩展到 SDL_SetTextureAlphaMod()SDL_SetTextureBlendMode() 或其他类似功能

作为参考,我使用的是 SDL2。

更新:最初认为对函数的调用只是更新颜色混合标志。我做了更多的调查,这是部分正确的,可以在 -http://pastebin.com/pMjgVkmM

中的函数中看到

但是,如果渲染器有一个分配给SetTextureColorMod() 的函数(大多数情况下似乎都是这种情况),那么它会映射到一个函数 'SW_SetTextureColorMod()' - http://pastebin.com/qYtxD0TH

这反过来又调用SDL_SetSurfaceColorMod() - http://pastebin.com/GrsVibAz

我担心此时可能会调用 SDL_InvalidateMap,尽管我不确定 - http://pastebin.com/r0HGJYHT

【问题讨论】:

  • 我建议在这篇文章中添加 C 或 C++ 标签以启用语法高亮

标签: sdl sdl-2


【解决方案1】:

SDL_SetTextureColorMod 不更新纹理纹素 - 它保存乘数颜色并引发 SDL_MODTEXTURE_COLOR 标志。该纹理上的后续 RenderCopy 将增加具有固定颜色的纹素。

由于它不修改纹理,只是在纹理标题中保持一点不变,因此在渲染帧中为同一纹理设置多次是完全可以的。克隆纹理会适得其反(更多的内存使用,并且由于更高的内存带宽压力可能会降低帧速率)。

【讨论】:

  • 这似乎是这种情况,但我一直在做更多的研究,发现它改变了 SDL_COPY_MODULATE_COLOR 标志的状态,如你所说,但反过来可能会导致纹理重新分配(如果我理解SDL_InvalidateMap() 的含义 对)这是因为它只是将调用转发到某个渲染器定义的函数。我认为大多数(如果不是所有)渲染器似乎都使用来自 SW_SetTextureColorMod 的实现,该实现重定向到 SDL_SetSurfaceColorMod
  • 通过软件实现,它会使 blitting 缓存失效,这可能会导致缓存重新创建。任何硬件加速实现都不会发生这种情况,因为它们没有任何缓存(也不需要缓存)。
  • 我已经接受了这个作为答案,但我认为在我所做的 SDL 论坛帖子中讨论的背景工作还有很多 - forums.libsdl.org/…
  • 如果您不相信我,您可以随时使用调试符号编译 SDL,在感兴趣的函数中设置断点并单步执行。对于大多数硬件实现(directfb 除外),此函数未定义 - 因此它无法执行您编写的操作,仅设置颜色标记和标志。
  • 是的,我继续执行了一些代码,只是为了让我自己清楚地知道发生了什么,我对所有发生的事情确实是颜色发生了变化和设置标志来告诉渲染器使用它。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
相关资源
最近更新 更多