cocos2d-x引擎优化的一些建议,望引擎组重视

关于资源加密及回调的事情我想是两个方面的问题。

@halx99 建议的是所有的资源都放在一起打成一个包(类似Android现在的形式),然后都从这个包读取资源。引擎最初从cocos2d-iphone移植过来时没有这样的考虑。要做到这样的话,对引擎的改动比较大,必然带来兼容性的极大破坏。

@wangzhe 的意思是单个文件的读取、写入接口能有回调,这样可以做自己的操作,比如加密、解密等。这个对于开发者自己调用接口读取、写入文件是有效的。而引擎内部也会调用这些接口读取、写入信息,比如通过 Sprite::Create()创建sprite时,内部会调用文件读取接口读取图片数据生成纹理,这时这个回调接口从哪里获取呢?如果说在FileUtils里设置一个统一的回调接口,那么所有的文件读取都会走这个逻辑,显然也不符合需求。

所以文件的读取、写入增加回调的需求就变成了FileUtils可以被继承。开发者继承FileUtils就做自己想要的事情了。

@halx99
关于增加通用文件读取接口,以std::string作为返回值,那么如果是二进制数据呢?最近开发者提交了一个FileUitls::getContents()的接口,不知道这个是否能满足需求:https://github.com/cocos2d/cocos2d-x/pull/15479

ETC1的问题我看一下,是应该要有透明通道支持。
Data数据结构的说明能否给个具体的说明?

其实string处理二进制完全没任何问题(唯一的就是在申请分配内存是会+1个字节), 而且更加通用, 具体可以看我的实现, 很多标准库接口都会以string作为参数, 那么, 文件读取其实一个接口就够了,不需要那么多接口, 相比接口唯一的便利性,我认为+1字节是完全可以接受的

新接口,我看了下,个人拙见,除了增加接口复杂性,感觉意义不大, std::vector 和 std::string, 我更愿意选择std::string

恩,确实。这个和开发者提交的有异曲同工之妙。开发者的那个提交后,可以这样用

std::string bs;
auto serr = fs->getContents(_generatedFile, &bs);

std::vector<int> vbuf;
auto verr = fs->getContents(file, &vbuf);

Data dbuf;
auto derr = fs->getContents(file, &dbuf);

还可以扩展自己的数据类型,也就是你说的一个接口。我会把别的接口慢慢deperecated掉。现在别的接口内部也是用getContents()实现。

@minggo 关于解密hook, 我实现的方案中,默认hook是空的,如果开发者没有指定hook,则完全不影响原引擎Sprite::create读取纹理

嗯,我看到了。但是增加了hook后就意味着所有的资源都要走同一个逻辑。但是如果我只是想部分加密呢?

std::string也是支持的啊。

这样的话,只能有开发者对资源分表管理,加密的一个表,不加密的一个表, 目前我们游戏是全量加密,所以只有一个表

文件读取接口怎么知道这个分表用于区分哪些需要调用回调,哪些不需要?

嗯嗯,getContents这个接口比我说的更通用,只是增加一顶点复杂性,可以接受, 呵呵,我个人比较纠结,对于简易接口,喜欢one input, one output 原则。

这个我想,只能有开发者自己决定了,哪些需要加密,哪些不需要加密,分类的方法应该有很多,例如文件后缀什么的,引擎层面肯定无法控制的。这个表不应该在引擎层,而是由开发者自己管理,是否加密的逻辑也由开发者自行控制, 例如:


这里,hook需要在增加一个文件名参数, 让开发者来决定该文件是否需要解密

嗯,那我就加个接口用于设置这个hook函数吧,类似 FileUtils::setReadCallback(callback);

已经建立了issue

1赞

@halx99 不知道你是怎么支持ETC1 alpha通道的,从该文章 了解到,要支持alpha通道的话主要有两种:

  1. 把alpha数据和图片数据打在一个图片文件里
  2. alpha数据和图片分开位两个图片

对于方法2需要自己写shader,类似这个测试例子:https://github.com/cocos2d/cocos2d-x/blob/v3/tests/cpp-tests/Classes/ShaderTest/ShaderTest.cpp#L665

方法1正如文章所说的,在scale时有性能下降,而且wrap时也只有一个方向是对的。

所以没太明白你说的支持指的是哪种。如果是方法2的话,那么其实是要自己写shader比较好控制。

OK,赞一个

我是用的方法二,直接在引擎层面支持,存储alpha通道的文件名和原文件名一致,仅仅多加一个Alpha后缀字符,引擎以此来判断纹理ETC1是否使用了有Alpha通道

但是这样也有问题:

1、你是在哪个阶段创建alpha后缀的纹理?Sprite初始化还是?那图集呢?
2、引擎应该尽量少对文件名、目录做限制,使用Alpha后缀区分比较过分,如果是完全工具化,那么没问题,工具和引擎配合不需要注意这种规则

在TextureCache 加载贴图时:


这里s_etc1_alpha_endix可以提出一个全局接口cocos2d::setETC1AlphaEndix
可以把我分享的 https://github.com/halx99/cocos2d-x-pc-port down下来, 所以设计etc1 alpha 支持修改的地方,我都加了注释:

目前的问题在于引擎对多纹理的支持不友好,需要自己写shader来达到目的。你的方法相当于在目前的实现上的一个“hack”,引擎里到处需要对ETC进行特殊处理,使得逻辑变得很复杂,所以我觉得维持现状,自己写shader解决吧。

嗯,不过如果引擎能实现,那么开发者应该会更加便利

嗯,如果要实现多纹理工作量不少,而且可能带来兼容性问题。目前兼容性问题被开发者认为是很严重的问题,很多时候也是没办法。