我有一个静态库Xcode4项目,其中包括一个自制的渲染引擎,我在多个应用程序中重用了这个引擎。此引擎使用OpenGL ES 2.0,并通过扩展使用着色器。随着着色器变得更加复杂,我不再将它们存储为源文件中的NSStrings,而是现在将它们存储为具有.vert和.frag扩展名的独立文本文件。
这对于在自己的源代码中包含渲染引擎的应用程序很有效;着色器只需添加到应用程序的"Copy Bundle Resources“构建阶段,并在运行时加载到NSStrings中并进行编译、链接等。
如果加载这些着色器的渲染引擎位于静态库项目中,则此策略根本不起作用;没有要将资源复制到其中的包。目前,我不得不让静态库渲染引擎的每个客户端项目在自己的"Copy Bundle Resources“构建阶段包含自己的着色器副本。这是一个巨大的痛苦,并在很大程度上击败了将渲染引擎转换为静态库的便利性。
我想这是“静态库中的资源”这个更普遍的问题的具体实例。我能想到的最好的解决方案是将着色器文件的内容复制到头文件中的字符串中,然后将其包含在渲染引擎的源代码中。我甚至可以使用一些“运行脚本”构建阶段的魔术来自动完成从.frag到.h的转换,但不幸的是,这似乎很复杂。
我是不是漏掉了什么?
发布于 2011-08-05 01:59:47
您可以尝试创建一个框架,它似乎符合您的需求。在这个页面上有一个关于如何为iOS创建这样一个框架的例子:
http://db-in.com/blog/2011/07/universal-framework-iphone-ios-2-0/
编写该指南的人实际上使用了这种技术来分发his own iOS 3D engine project。
编辑:链接到较新版本指南的。
发布于 2011-08-18 01:15:33
为了后人的利益,我将分享我最终使用的解决方案。在高层次上,解决方案是将有问题的资源编译成应用程序二进制文件,从而避免将其复制到捆绑资源的需要。
我决定将任何文件数据编译成二进制文件的一种通用且可靠的方法是将文件内容存储在头文件的静态字节数组中。假设已经创建了一个头文件并将其添加到静态lib目标中,我编写了以下bash脚本来读取文件,并使用C语法将其内容写为十六进制文字的字节数组。然后,在编译源代码和复制头文件构建阶段之前,我在“运行脚本”构建阶段运行该脚本:
#!/bin/bash
# Hexify.sh reads an input file, and hexdumps its contents to an output
# file in C-compliant syntax. The final argument is the name of the array.
infile=$1
outfile=$2
arrayName=$3
fileSize=$(stat -f "%z" $infile)
fileHexString=$(hexdump -ve '1/1 "0x%.2x, "' $infile)
prefix=$arrayName
suffix="Size"
variableName=$arrayName$suffix
nullTermination="0x00"
echo "//" > $headerFile
echo "// This file was automatically generated by a build script." >> $headerFile
echo "// Do not modify; the contents of this file will be overwritten on each build." >> $headerFile
echo "//" >> $headerFile
echo "" >> $headerFile;
echo "#ifndef some_arbitrary_include_guard" >> $headerFile
echo "#define some_arbitrary_include_guard" >> $headerFile
echo "" >> $headerFile
echo "static const int $variableName = $((fileSize+1));" >> $outfile
echo "static const char $arrayName[$variableName] = {" >> $outfile
echo -e "\t$fileHexString$nullTermination" >> $outfile
echo "};" >> $outfile
echo "#endif" >> $headerFile例如,如果我有一个资源文件example.txt:
Hello this
is a file如果我运行./Hexify.sh example.txt myHeader.h exampleArray,报头将如下所示:
//
// This file was automatically generated by a build script.
// Do not modify; the contents of this file will be overwritten on each build.
//
#ifndef some_arbitrary_include_guard
#define some_arbitrary_include_guard
static const int exampleArraySize = 21;
static const char exampleArray[exampleArraySize] = {
0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x74, 0x68, 0x69, 0x73, 0x0a,
0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x00
};
#endif现在,在我从主包加载上述资源的任何时间点,我都可以引用该头文件中的字节数组。请注意,我的版本的脚本添加了一个以null结尾的字节,这使得数据适合于创建string对象。这可能并不适用于所有情况。
作为最后一个补充,如果bash脚本让任何真正的bash程序员感到畏缩,我道歉;我几乎不知道我在用bash做什么。
发布于 2011-08-05 01:44:32
我感受到了你的痛苦,伙伴,静态库和资源不能很好地搭配在一起。我认为最简单的方法就是你已经提到的:编写一个脚本来读取你的着色器,正确地转义它们,并将它们包装在符合C语言的代码中。
我不是专家,但也许你可以在链接时将着色器数据添加到Mach-O可执行文件的某些部分?但这最终归结为与上面提到的相同的解决方案,唯一的缺点是留给您的工作丑陋的部分。
我会使用一些shell脚本来获取字符串常量。根据我的经验,PHP非常擅长做这类工作。当然还有bash脚本,但我不太擅长这一点。
https://stackoverflow.com/questions/6945869
复制相似问题