这是一个笨蛋。为了正确解释,让我解释一下我正在尝试做的事情。我将跟进代码清单,然后解释代码。
目标
我正在尝试获取我拥有的每个 GLSL 着色器文件中的变量名称。现在,我只有一个顶点着色器,以及一个片段着色器来补充它。这样做的目的是让我可以动态地将值绑定到着色器,而无需输入每个变量名称。
代码
std::vector< const char* > GetShaderVariableNames( const Shader& shader )
{
Config::Log::info( "Getting shader variable names." );
static const char* keyLookupTable[] =
{
"vec2", "vec3", "vec4",
"mat2", "mat3", "mat4",
"float", "int", "double"
};
std::vector< const char* > keys;
std::vector< std::string > lines;
SplitIntoLines( &lines, std::string( shader.shaderSrc ) );
for( int32_t iLines = 0; iLines < lines.size(); ++iLines )
{
const char* line = lines[ iLines ].c_str();
int32_t index = 0;
bool foundMatch = false;
for( int32_t iKey = 0; iKey < sizeof( keyLookupTable ) / sizeof( char ); ++iKey )
{
if( strContains( lines[ iLines ], keyLookupTable[ iKey ] ) )
{
index = iKey;
foundMatch = true;
break;
}
}
if( foundMatch )
{
const int32_t pos = lines[ iLines ].find( keyLookupTable[ index ] );
Config::Log::info( "Position found is %i", pos );
const int32_t lineLen = strlen( line );
char* var = new char[ lineLen - pos ];
int32_t iLine = pos + strlen( keyLookupTable[ index ] );
for( ; iLine < lineLen; ++iLine )
{
var[ iLine ] = line[ iLine ];
}
Config::Log::info( "Shader Variable Found is: %s", var );
keys.push_back( var );
}
}
return keys;
}
服用红色药丸
因此,想法是有一个包含最常用变量类型的键查找表。首先,接收到的着色器是一个类,它包含有关数据的信息,例如它的句柄、它的类型(片段、顶点、纹理等),当然还有它的来源。我从着色器文件中解析这些,而不是字符串。
发生的情况是有一个老爹循环,它遍历着色器文件中解析的每一行。在每一行中,如果在键查找表中存在匹配项,则迭代的第二个循环keyLookupTable[]
将中断,索引值取值为iKey
(即,数组中的索引,在其中找到匹配项)。然后循环中断。
如果找到匹配项,则采用找到匹配项的行中的位置(例如vec4
或mat3
)。从那里,使用存储在 中的位置pos
,我们用作pos
变量名称长度的基础,这是通过在 char 数组中指定所需的字符数量来完成的。所需数量是线的长度减去位置。
然后从那里第三个也是最后一个循环遍历该行,使用 achar*
来引用它,将值放入line
并将它们复制到分配的var
字符数组中。
最后,std::vector
键插入var
并继续循环,重复该过程。
值得注意的问题
- 我使用 JNI 来获取着色器字符串,因为着色器本身是通过 Java 解析的,然后通过 JNI 发送到 C++。
- Unicode 可能是一个问题,因为我得到了这样的输出:
Shader Variable Found is: |uԯ|uԯ/
- 着色器 src 从 JNI 通过
env->GetStringUTFChars()
结论
我确信有更好的方法可以做到这一点,可能是使用std::stringstream
或其他方法,但我对它不是很熟悉,希望这个算法能以某种方式或某种方式工作。但是,如果这是这样做的“天真”方式,我愿意接受建议。
问题
实现这一目标以使解析工作的最佳方法是什么?