代码之家  ›  专栏  ›  技术社区  ›  Flamefire

(纹理)资源系统设计

  •  0
  • Flamefire  · 技术社区  · 6 年前

    对于一个开源游戏,我想重新设计资源管理系统,但进入了死胡同,需要一些指向一些阅读材料或现在该去哪里的指针。

    Loader Header Src

    资源格式:

    • 资源(通常)在档案中,由编号的文件(无名称)组成,这些文件可以是任何类型的,并且可能包含相关的元数据(大小、绘制偏移量等)
      • 二维偏移(模型矩阵转换)
      • 播放器色板(额外灰度bmp)

    我想解决的问题是混乱的代码(没有SRP…),资源的不统一处理和大多数访问的动态转换(基本上: dynamic_cast<type*>(Get("foo", 42)) ). 只有一种纹理类型也可以简化渲染(可能是2种:一种有播放器遮罩,另一种没有)

    我的方法(基于ENTT):

    • ResourceLocator :给定一个名称,返回要加载的存档文件列表(句柄扩展/覆盖)
    • ResourceCache<Type>
    • ResourceLoader<Type> :加载资源
    • ResourceRegistry :包含多个缓存、1个定位器和(可能)加载程序。通过先检查缓存并在未命中时加载缓存(将其添加到缓存)来提供对所有资源的访问

    这对于音效和音乐效果很好:

    SoundEffect& get(ResId id){
       if(id in soundcache) return it;
       archive& = get(id.name);
       SoundEffect* effect = load(archive)
       add to cache and return effect;
    }
    

    这是好的和一般的。但我正在为如何对不同类型的纹理执行此操作而苦苦挣扎:

    • “简单背景”,“普通”按钮
    • 特定于贴图的纹理(例如,根据贴图类型,有雪或无雪的树。以前是 装载机 存储了对地图存档的引用,消费者只需调用 GetMapTexture(idx)
    • 特定于国家的纹理(每个国家都有存档和/或存档中的偏移)->使用 ("archive", number)

    fixed size multi-D-arrays 有许多不同的索引,其含义包含在 班级。

    很容易将它们加载到OGL纹理中。其他的需要(通常)多个图像组合成一个纹理。所以我不想把这些部分放到纹理缓存中,而只想把它们组合起来。但拥有这些多D阵列也让人觉得是设计缺陷。我该如何引用/使用它们?其他人是怎么做到的?

    注:构成纹理/bld的图像的索引。。。可以(有点)容易地从国家指数,建筑指数,动画帧指数。。。

    示例用法(来自当前/旧)代码:

    drawAnimal(int type, int dir, int animationFrame){animal_cache[type][dir][animationFrame].draw(pos...);} drawCarrier(...){carrier_cache[carriedWare][dir][animationFrame][isFat].draw(pos, playerColor,...);} drawBuilding(...){building_cache[nationIdx][bldIdx].draw(pos, playerColor,...);}

    0 回复  |  直到 6 年前