我正在开发一个相当复杂的数学库,当客户端代码使用 auto 时,我发现了一个令人讨厌的错误。在创建一个最小的复制案例来提出一个问题的过程中,我意识到我可以单独使用标准库来复制类似的东西。查看这个简单的测试用例:
#include <vector>
#include <assert.h>
int main()
{
std::vector<bool> allTheData = {true, false, true};
auto boolValue = allTheData[1]; // This should be false - we just declared it.
assert(boolValue == false);
boolValue = !boolValue;
assert(boolValue == true);
assert(allTheData[1] == false); // Huh? But we never changed the source data! Only our local copy.
}
Run Code Online (Sandbox Code Playgroud)
住在 Godbolt 上。(有趣的事实:Clang 实际上将其优化为写入“7” - 3 个真位 - 以及对 __assert_fail 的调用。)
(是的,我知道 std::vector<bool> 很烂- 但在这种情况下,创建一个只有几行长的最小可重现示例很方便)这是一个较长的示例,它不使用 std::vector<bool>,并且使用自定义容器类型,删除了分配和复制/移动,仍然显示问题。
我了解幕后发生的事情,operator[] 返回的代理类旨在实现allTheData[1] …
为了提高非常大的对象(并填充GPU ram)的显示性能,在一些相当轻的数学之后,我发现我有一个机会来将我的顶点数据从16字节顶点压缩到4字节顶点(因为数据在概念上可以被认为是一个变换的高度图 - 从顶点id中提取x和y位置),我可以将Z坐标紧密地打包到30位,留下2位用于a彩色托盘指数.无论如何,这是个主意.我的问题不在于坐标包装,而在于颜色包装.
颜色托盘将由加载模型的c ++代码选择.因为它还加载着色器,我现在正在尝试将颜色查找代码编写为switch语句,即:
int colourIndex = (compressedVertex & Mask) >> bitOffset;
switch (colourIndex)
{
case 0: return vec4(....);
case 1: return vec4(....);
case 2: return vec4(....);
case 3: return vec4(....);
}
Run Code Online (Sandbox Code Playgroud)
如果模型有更多的颜色然后4,我很舒服牺牲高度精度,以适应更多的颜色托盘(无论如何).我的测量表明,使用switch语句绑定4色托盘并不慢,然后绑定4像素1D纹理并使用采样器从中读取.
到目前为止,我已将其扩展到32种颜色,并且它似乎至少与使用纹理一样快.
什么是沙子中的好线,以停止使用开关并开始使用纹理查找表?如果它有助于我正在开发的应用程序已经实施了OpenGl 3.3的最低要求.一旦数据在卡上,它就永远不会被改变.我可以将其调整为256个案例陈述吗?1024?32768?限制在哪里?
(先发制人的回应:是的我可以继续尝试并使用试错法和一些内插法在我的单张现代卡片上挑选一个对我有用的价值;但我对更好地了解什么是最佳做法以及是否还有其他人尝试过类似的东西并知道它可以在野外锻炼吗?)