mirror of
https://github.com/MobileGL-Dev/MobileGlues.git
synced 2025-09-22 10:42:11 -04:00
[Improvement] (Shader/GLSL): Better function injections.
This commit is contained in:
parent
98d4d51427
commit
75ddfe4100
@ -345,7 +345,6 @@ std::string getCachedESSL(const char* glsl_code, uint essl_version) {
|
||||
} else return "";
|
||||
}
|
||||
|
||||
|
||||
std::string GLSLtoGLSLES(const char* glsl_code, GLenum glsl_type, uint essl_version, uint glsl_version) {
|
||||
std::string sha256_string(glsl_code);
|
||||
sha256_string += "\n//" + std::to_string(MAJOR) + "." + std::to_string(MINOR) + "." + std::to_string(REVISION) + "|" + std::to_string(essl_version);
|
||||
@ -435,28 +434,73 @@ static inline void replace_all(std::string& str, const std::string& from, const
|
||||
}
|
||||
}
|
||||
|
||||
static inline void inject_textureQueryLod(std::string& glsl) {
|
||||
const std::string textureQueryLodCall = "textureQueryLod(";
|
||||
const std::string textureQueryLodDef = "vec2 mg_textureQueryLod(sampler2D tex, vec2 uv)";
|
||||
const std::string mainStart = "void main()";
|
||||
static size_t find_insertion_point(const std::string& glsl) {
|
||||
size_t pos = 0;
|
||||
size_t insertion_point = 0;
|
||||
|
||||
// Already defined function
|
||||
const auto def_loc = glsl.find(textureQueryLodDef);
|
||||
if (def_loc != std::string::npos)
|
||||
size_t version_pos = glsl.find("#version");
|
||||
if (version_pos != std::string::npos) {
|
||||
size_t version_end = glsl.find('\n', version_pos);
|
||||
if (version_end == std::string::npos) {
|
||||
version_end = glsl.length();
|
||||
}
|
||||
else {
|
||||
version_end++;
|
||||
}
|
||||
insertion_point = version_end;
|
||||
pos = version_end;
|
||||
}
|
||||
else {
|
||||
insertion_point = 0;
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
while (pos < glsl.length()) {
|
||||
size_t line_begin = pos;
|
||||
while (pos < glsl.length() && std::isspace(glsl[pos])) {
|
||||
pos++;
|
||||
}
|
||||
if (pos >= glsl.length()) break;
|
||||
|
||||
if (glsl[pos] == '#') {
|
||||
pos++;
|
||||
while (pos < glsl.length() && std::isspace(glsl[pos])) {
|
||||
pos++;
|
||||
}
|
||||
if (glsl.compare(pos, 9, "extension") == 0) {
|
||||
size_t ext_end = glsl.find('\n', pos);
|
||||
if (ext_end == std::string::npos) {
|
||||
ext_end = glsl.length();
|
||||
} else {
|
||||
ext_end++;
|
||||
}
|
||||
insertion_point = ext_end;
|
||||
pos = ext_end;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return insertion_point;
|
||||
}
|
||||
|
||||
|
||||
static void inject_textureQueryLod(std::string& glsl) {
|
||||
const std::regex defRegex(R"(vec2\s+mg_textureQueryLod\s*\()", std::regex::ECMAScript);
|
||||
|
||||
if (glsl.find("textureQueryLod") == std::string::npos) {
|
||||
return;
|
||||
|
||||
// Never called function
|
||||
const auto call_loc = glsl.find(textureQueryLodCall);
|
||||
if (call_loc == std::string::npos)
|
||||
return;
|
||||
|
||||
|
||||
const auto main_loc = glsl.find(mainStart);
|
||||
// No main(), no inject
|
||||
if (main_loc == std::string::npos)
|
||||
}
|
||||
if (std::regex_search(glsl, defRegex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string textureQueryLodImpl = R"(
|
||||
#define textureQueryLod mg_textureQueryLod
|
||||
|
||||
vec2 mg_textureQueryLod(sampler2D tex, vec2 uv) {
|
||||
vec2 texSizeF = vec2(textureSize(tex, 0));
|
||||
vec2 dFdx_uv = dFdx(uv * texSizeF);
|
||||
@ -466,35 +510,30 @@ vec2 mg_textureQueryLod(sampler2D tex, vec2 uv) {
|
||||
return vec2(lod);
|
||||
}
|
||||
)";
|
||||
// Replace all calls to textureQueryLod()
|
||||
replace_all(glsl, "textureQueryLod(", "mg_textureQueryLod(");
|
||||
|
||||
// Do injection here
|
||||
glsl.insert(main_loc, "\n" + textureQueryLodImpl + "\n");
|
||||
size_t insertPos = find_insertion_point(glsl);
|
||||
glsl.insert(insertPos, "\n" + textureQueryLodImpl + "\n");
|
||||
}
|
||||
|
||||
static inline void inject_temporal_filter(std::string& glsl) {
|
||||
const std::string temporalFilterCall = "deferredOutput2 = GI_TemporalFilter()";
|
||||
const std::string temporalFilterDef = "vec4 GI_TemporalFilter()";
|
||||
const std::string mainStart = "void main()";
|
||||
const std::regex defRegex(R"(vec4\s+GI_TemporalFilter\s*\()", std::regex::ECMAScript);
|
||||
|
||||
// Already defined function
|
||||
const auto def_loc = glsl.find(temporalFilterDef);
|
||||
if (def_loc != std::string::npos)
|
||||
if (glsl.find("GI_TemporalFilter") == std::string::npos) {
|
||||
return;
|
||||
|
||||
// Never called function
|
||||
const auto call_loc = glsl.find(temporalFilterCall);
|
||||
if (call_loc == std::string::npos)
|
||||
}
|
||||
if (std::regex_search(glsl, defRegex)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::regex uniformRegex(R"(^\s*(?:layout\s*\([^)]*\)\s*)?uniform\s+\w+(?:\s*\[\s*\d+\s*\])?\s+\w+(?:\s*\[\s*\d+\s*\])?\s*;.*$)", std::regex::ECMAScript | std::regex::multiline);
|
||||
std::sregex_iterator it(glsl.begin(), glsl.end(), uniformRegex);
|
||||
std::sregex_iterator end;
|
||||
size_t insertPos = 0;
|
||||
for (; it != end; ++it) {
|
||||
insertPos = it->position() + it->length();
|
||||
}
|
||||
|
||||
const auto main_loc = glsl.find(mainStart);
|
||||
// No main(), no inject
|
||||
if (main_loc == std::string::npos)
|
||||
return;
|
||||
|
||||
const std::string GI_TemporalFilter = R"(
|
||||
const std::string GI_TemporalFilterImpl = R"(
|
||||
vec4 GI_TemporalFilter() {
|
||||
vec2 uv = gl_FragCoord.xy / screenSize;
|
||||
uv += taaJitter * pixelSize;
|
||||
@ -518,10 +557,8 @@ vec4 GI_TemporalFilter() {
|
||||
return filteredGI;
|
||||
}
|
||||
)";
|
||||
// Do injection here
|
||||
glsl.insert(main_loc, "\n" + GI_TemporalFilter + "\n");
|
||||
glsl.insert(insertPos, "\n" + GI_TemporalFilterImpl + "\n");
|
||||
}
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user