今天我尝试整理一个简单的 OpenGL 着色器类,它从文件中加载文本,根据一些(非常甜美的)自定义语法(例如,编写“ .variing [type] [name];" 将允许您在两个着色器中定义一个可变变量,同时只编写一次,与 ".version" 相同,) 然后使用两者编译 OpenGL 着色器程序,然后标记着色器类当且仅当着色器代码正确编译时为“就绪”。
现在,我做了这一切,但后来遇到了最奇怪(坦率地说有点可怕)的问题。我设置了所有东西,用一些包含有效着色器代码的文件声明了一个新的 'tt::Shader',只是让它告诉我着色器无效,但是当我询问错误是什么时给了我一个空字符串(这意味着OpenGL 给了我一个空字符串,因为它是从那里得到的。)
我再次尝试,这次使用了明显无效的着色器代码,虽然它识别出着色器无效,但它仍然没有给我任何关于错误是什么的信息,只是一个空字符串(我认为显然错误识别部分它也和以前一样。)
感到困惑的是,我手动将两个着色器(有效和无效的着色器)作为字符串重新编写,直接用字符串再次编译类,没有文件访问权限。这样做,错误消失了,第一个编译正确,第二个失败但正确识别了错误是什么。
更困惑的是,我开始将文件中的字符串与我自己编写的字符串进行比较。原来前者比梯子长一点,尽管打印相同。数了数之后,我意识到这些字符一定是在导入过程中被截断的 Windows CR LF 行尾回车字符。
为了测试这一点,我拿起手写的字符串,在它们将被切断的地方插入马车,然后再次运行我的字符串比较测试。这一次,它评价theres长度相同,但还告诉我,两者仍然不相等,这很令人费解。
因此,我编写了一个简单的 for 循环来遍历两个字符串的字符,然后将每个字符串彼此相邻打印,然后转换为整数,这样我就可以看到它们的索引值。我运行程序,浏览了(相当长的)列表,并得出了一个不同的有见地但更不明确的答案:隐藏的字符在正确的位置,但它们不是马车......它们是空终止符!
这是我正在使用的文件读取功能的代码。这没什么花哨的,只是标准库的东西。
// Attempts to read the file with the given path, returning a string of its contents.
// If the file could not be found and read, an empty string will be returned.
// File strings are build by reading the file line-by-line and assembling a single with new lines placed between them.
// Given this line-by-line method, take note that it will copy no more than 4096 bytes from a single line before moving on.
inline std::string fileRead(const std::string& path) {
if (!tt::fileExists(path))
return "";
std::ifstream a;
a.open(path);
std::string r;
const tt::uint32 _LIMIT = 4096;
char r0[_LIMIT];
tt::uint32 i = 0;
while (a.good()) {
a.getline(r0, _LIMIT);
if (i > 0)
r += "\n";
i++;
r += std::string(r0, static_cast<tt::uint32>(a.gcount()));
}
// TODO: Ask StackOverflow why on earth our file reading function is placing null characters where excess carriages should go.
for (tt::uint32 i = 0; i < r.length(); i++)
if (r[i] == '\0')
r[i] = '\r';
a.close();
tt::printL("Reading file '" + path + "' ...");
return r;
}
如果你们都可以阅读并告诉我到底发生了什么,那就太棒了,因为我完全不知道它对我的琴弦做了什么导致这种情况。
最后,我确实明白为什么空终止符没有出现在我面前,但对于 OpenGL 却出现了,梯子使用 C 字符串,而我只是用 std::string 对象做所有事情,其中根据给定的长度存储东西他们几乎只是花哨的 std::vector 对象。