所以我的目标是创建一个自包含文件,其中包含要加载到3D场景中的所有资源。例如,会有一个文本文件详细说明模型的所有位置,旋转,比例等,然后是里面有模型和纹理的文件夹。这在文件夹中并不难做到,但为了简单起见,我希望将它全部放在一个文件中,避免压缩它并解压缩它。我不想压缩和解压缩它的原因是为了加快加载时间,因为这是为了游戏。
有没有办法做到这一点?或者我将不得不咬紧牙关把它变成拉链。
感谢。
答案 0 :(得分:3)
您可以使用ZIP而不压缩或TAR。但这是一个更好的主意:压缩它。 CPU时间便宜。磁盘传输需要永远。大多数情况下,加载压缩数据并对其进行解压缩比加载未压缩数据更快。
答案 1 :(得分:1)
您可以创建没有压缩的ZIP文件。 ("存储"模式。)还有类似的包装存档程序,可用于从多个文件创建单个存档。 * nix系统上的TAR文件很受欢迎,还有很多其他文件。
此外,平衡将要解压缩的时间量与从磁盘加载(未压缩)文件所花费的时间量。很多时候,未压缩文件的磁盘读取时间比加载压缩文件并在内存中解压缩所花费的时间长。
答案 2 :(得分:1)
如果这是针对Windows应用程序的,则可以在.RC文件中使用用户定义的资源语句作为EXE或包含的DLL,这些DLL将从外部文件插入数据作为二进制资源。如果您只想分发依赖于其他文件中包含的数据的单个EXE文件,或者不希望将您可能存档和分发的文件与您的应用程序进行访问/可修改(没有一些工作),这将非常方便)由最终用户。
这非常简单 - 语法只是
nameID typeID filename
表示资源文件。您可以使用::FindResource()
和::LoadResource().
MS文档访问数据,用户定义的资源位于http://msdn.microsoft.com/en-us/library/windows/desktop/aa381054(v=vs.85).aspx。
答案 3 :(得分:0)
原始问题的时机可能是偶然的。事实证明,在未来,我建议的查找/加载资源方法对我们来说也不是一个选项(之前我使用它的代码是跨平台的),所以我想出了一个也可能的解决方案为你工作。完整代码有点太多要发布作为SO答案(但请参阅我的后续评论),尽管您可以立即制作自己的快速版本。
基本上,我编写了一个实用程序,它只输出输出文件的基名argv[1]
(“ output-base-name ”),argv[2...(argc-1)]
是输入文件。我打开output-base-name.cpp
和output-base-name.h
进行写入(如果存在则会覆盖)。
对于每个输入文件,生成器实用程序执行此操作:
1:根据文件名(“ generated_name ”)生成可变名称标识符
2:读取输入文件
3:将以下内容转储到output-base-name.cpp
:
static uint8_t generated_name[] = {
// Initialize with contents of input file as a bunch of 0xNN, 0xNN... values.
};
并进入output-base-name.h
,相应的
static const unsigned IDR_generated_name = N; // start at 0, see below re:range check
4:在最后一个输入文件之后,用
之类的内容完成output-base-name.cpp
static struct {
unsigned ID;
unsigned size; // I assume you aren't trying to embed files >4GB!
const uint8_t* data;
}
fileData[] = {
// one array element for each input file
{ IDR_generated_name, sizeof(generated_name), generated_name },
...
};
const uint8_t* getResourceData(unsigned ID){
// a real version would do a safer lookup/range check of some sort based on ID
return fileData[ID].data;
}
unsigned getResourceSize(unsigned ID){
// a real version would do a safer lookup/range check of some sort based on ID
return fileData[ID].size;
}
5:完成 output-base-name.h
的原型,无论你的“获取”功能是什么样的,例如。
extern const uint8_t* getResourceData(unsigned ID);
extern unsigned getResourceSize(unsigned ID);
只需在需要访问数据的地方使用output-base-name.h
并将output-base-name.cpp
添加到makefile或项目中(使其依赖于二进制输入文件,使用构建规则中的生成器实用程序并{{ 1}}会在必要时自动为您重新生成它。如果你想要它们在某种动态库中,只需在你的“获取”函数中添加适当的导出属性。
让生成器将输出包装在命名空间中,如果你愿意,可以将基于类的接口放在一起(或者生成一个而不是示例“get”函数),并且你应该很好。
与使用未压缩的zip文件(甚至是我为Windows目标建议的嵌入式资源方法)相比,这种方法有几个优点:
这只是我使用的方法的一个示例,但它涵盖了所有基础知识,因此如果解决方案提前而不是更晚(再次,请参阅注释)对您更好,这可能就足够了(您可能想要范围检查“get”函数中的值 - 至少在调试版本中,可能使用某种容器而不是使用c样式的struct数组等。)