From b7d6c5b664ff3701e6842e61c40b9ed31f74732a Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Thu, 30 Jan 2025 19:53:55 +0800 Subject: [PATCH] [Feat] (shader.c): Process uniform variables declarations. Signed-off-by: BZLZHH --- src/main/cpp/gl/shader.c | 144 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) diff --git a/src/main/cpp/gl/shader.c b/src/main/cpp/gl/shader.c index 54b4e92..bcc2427 100644 --- a/src/main/cpp/gl/shader.c +++ b/src/main/cpp/gl/shader.c @@ -16,6 +16,149 @@ #define DEBUG 0 +void trim(char* str) { + char* end; + while (isspace((unsigned char)*str)) str++; + if (*str == 0) return; + end = str + strlen(str) - 1; + while (end > str && isspace((unsigned char)*end)) end--; + *(end + 1) = 0; +} + +int startsWith(const char *str, const char *prefix) { + if (!str || !prefix) return 0; + while (*prefix) { + if (*str++ != *prefix++) return 0; + } + return 1; +} + +char* process_uniform_declarations(char* glslCode) { + char* cursor = glslCode; + char name[256], type[256], initial_value[1024]; + int modifiedCodeIndex = 0; + size_t maxLength = 1024 * 10; + char* modifiedGlslCode = (char*)malloc(maxLength * sizeof(char)); + if (!modifiedGlslCode) return NULL; + + while (*cursor) { + if (strncmp(cursor, "uniform", 7) == 0) { + char* cursor_start = cursor; + + cursor += 7; + + while (isspace((unsigned char)*cursor)) cursor++; + + // may be precision qualifier + char* precision = NULL; + if (startsWith(cursor, "highp")) { + precision = " highp"; + cursor += 5; + while (isspace((unsigned char)*cursor)) cursor++; + } else if (startsWith(cursor, "lowp")) { + precision = " lowp"; + cursor += 4; + while (isspace((unsigned char)*cursor)) cursor++; + } else if (startsWith(cursor, "mediump")) { + precision = " mediump"; + cursor += 7; + while (isspace((unsigned char)*cursor)) cursor++; + } + + int i = 0; + while (isalnum((unsigned char)*cursor) || *cursor == '_') { + type[i++] = *cursor++; + } + type[i] = '\0'; + + while (isspace((unsigned char)*cursor)) cursor++; + + // may be precision qualifier + if(!precision) + { + if (startsWith(cursor, "highp")) { + precision = " highp"; + cursor += 5; + while (isspace((unsigned char)*cursor)) cursor++; + } else if (startsWith(cursor, "lowp")) { + precision = " lowp"; + cursor += 4; + while (isspace((unsigned char)*cursor)) cursor++; + } else if (startsWith(cursor, "mediump")) { + precision = " mediump"; + cursor += 7; + while (isspace((unsigned char)*cursor)) cursor++; + } else { + precision = ""; + } + } + + while (isspace((unsigned char)*cursor)) cursor++; + + i = 0; + while (isalnum((unsigned char)*cursor) || *cursor == '_') { + name[i++] = *cursor++; + } + name[i] = '\0'; + while (isspace((unsigned char)*cursor)) cursor++; + + initial_value[0] = '\0'; + if (*cursor == '=') { + cursor++; + i = 0; + while (*cursor && *cursor != ';') { + initial_value[i++] = *cursor++; + } + initial_value[i] = '\0'; + trim(initial_value); + } + + while (*cursor != ';' && *cursor) { + cursor++; + } + + char* cursor_end = cursor; + + int spaceLeft = maxLength - modifiedCodeIndex; + int len = 0; + + if (*initial_value) { + len = snprintf(modifiedGlslCode + modifiedCodeIndex, spaceLeft, "uniform%s %s %s;", precision, type, name); + } else { + // use original declaration + size_t length = cursor_end - cursor_start + 1; + if (length < spaceLeft) { + memcpy(modifiedGlslCode + modifiedCodeIndex, cursor_start, length); + len = (int)length; + } else { + fprintf(stderr, "Error: Not enough space in buffer\n"); + } + // len = snprintf(modifiedGlslCode + modifiedCodeIndex, spaceLeft, "uniform%s %s %s;", precision, type, name); + } + + if (len < 0 || len >= spaceLeft) { + free(modifiedGlslCode); + return NULL; + } + modifiedCodeIndex += len; + + while (*cursor == ';') cursor++; + + } else { + modifiedGlslCode[modifiedCodeIndex++] = *cursor++; + } + + if (modifiedCodeIndex >= maxLength - 1) { + maxLength *= 2; + modifiedGlslCode = (char*)realloc(modifiedGlslCode, maxLength); + if (!modifiedGlslCode) return NULL; + } + } + + modifiedGlslCode[modifiedCodeIndex] = '\0'; + return modifiedGlslCode; +} + bool can_run_essl3(int esversion, const char *glsl) { int glsl_version; @@ -76,6 +219,7 @@ void glShaderSource(GLuint shader, GLsizei count, const GLchar *const* string, c GLint shaderType; glGetShaderiv(shader, GL_SHADER_TYPE, &shaderType); converted = glsl_version<140?GLSLtoGLSLES_1(source, shaderType):GLSLtoGLSLES_2(source,shaderType,320); + converted = process_uniform_declarations(converted); LOG_D("\n[INFO] [Shader] Converted Shader source: \n%s", converted); } if (converted)