이것은 하나의 코드입니다. 적절한 설명을 위해서 제가하고 싶은 일을 설명하겠습니다. 코드 목록을 작성한 다음 코드를 자세히 설명합니다.GLSL 쉐이더 문자열을 파싱하여 Android NDK에서 변수 이름을 찾습니다.
나는 내가 가진 모든 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;
}
레드 필
촬영 그래서, 아이디어는 가장 일반적으로 사용되는 변수 유형를 포함하는 키 룩업 테이블이있을 것입니다. 우선,받은 Shader는 핸들, 타입 (Fragment, Vertex, Texture 등) 및 소스와 같은 데이터에 대한 정보를 보유하는 클래스입니다. 나는 셰이더 파일에서 문자열을 제외한 모든 것을 구문 분석하고 있습니다.
쉐이더 파일에서 구문 분석되는 각 행을 반복하는 그랜드 아빠 루프가 발생합니다. 각각의 라인에서 키 룩업 테이블에 일치가있는 경우 keyLookupTable[]
을 반복하는 두 번째 루프는 iKey
값을 취하는 인덱스 값으로 중단됩니다 (즉, 일치하는 항목이있는 배열의 인덱스) . 그런 다음 루프가 중단됩니다.
일치하는 것이 발견되면 일치 항목이있는 행의 위치 (예 : vec4
또는 mat3
)가 사용됩니다. 여기서부터 pos
에 저장된 위치를 사용하여 pos
을 사용하여 문자 배열에 필요한 문자 양을 지정하여 수행되는 변수 이름 길이의 기초로 사용됩니다. 필요한 양은 행의 길이에서 위치를 뺀 값입니다.
거기에서 세 번째이자 마지막 루프는 char*
을 사용하여 행을 반복하고 값을 line
으로 가져와 할당 된 var
문자 배열로 복사합니다.
마지막으로 std::vector
키는 var
을 삽입하고 반복 과정을 반복합니다. 자신이 자바를 통해 분석 한 다음 C에 JNI ++를 통해 전송되는 셰이더로
주목할만한 우려
- 내가 쉐이더 문자열을 얻기 위해 JNI를 사용하고 있습니다.나는 이와 같은 출력을 받았는데으로
- 유니 코드가 우려 될 수 쉐이더 SRC는
env->GetStringUTFChars()
결론 통해 JNI에서 const를 숯불 *에 전달 Shader Variable Found is: |uԯ|uԯ/
std::stringstream
또는 뭔가를 사용하여이를 수행하는 더 좋은 방법이있을 것이라고 확신하지만이 알고리즘에 익숙하지 않아서이 알고리즘을 어떻게 든 또는 어딘지로 작동시키고 싶습니다. 그러나 이것이 이것이 "순진한"방법이라면, 나는 제안에 개방적이다.
[질문
구문 분석이 작동하도록하려면이 옵션을 달성하기 위해 가장 좋은 방법은 무엇입니까?
미안 해요, 난 여기에 조금 혼란 느낌 : 당신이 활성 attribs/링크 된 쉐이더의 유니폼의 수를 조회 말할 때, 않습니다 당신은 당신이 제시 한 두 가지 기능 중 하나를 사용하여 의미 , 또는 다른 기능을 사용합니까? 당신이 "설명"아래의 첫 번째 단락에서 설명한 것 설명서를 읽어 보면 – zeboidlund
는 "glGetActiveAttrib 프로그램에 의해 지정된 프로그램 객체 \t에 적극적으로 속성 변수에 대한 정보 \t를 반환 \t 활성 속성의 수는 호출하는 것으로 취득 할 수 있습니다. \t glGetProgram \t 값이 GL_ACTIVE_ATTRIBUTES입니다. " – Tim
좋습니다. 고맙습니다. – zeboidlund