Abstract shader parameters (to make them modifiable later)

This commit is contained in:
mid 2025-06-28 13:18:58 +03:00
parent 446ff24fcf
commit e81750300d

View File

@ -3285,26 +3285,99 @@ static const char *k3glslloader(const char *fn) {
return data;
}
#define KV_STORE_SIZE 128
struct KVPair {
char *key;
char *value;
};
typedef struct KVPair KVStore[KV_STORE_SIZE];
static intmax_t kvpair_compare(const void *a_, const void *b_) {
const struct KVPair *a = a_;
const struct KVPair *b = b_;
if(!a->key) {
return 1;
} else if(!b->key) {
return -1;
}
return strcmp(a->key, b->key);
}
static char *kvstore_tostring(KVStore store) {
ssort(store, KV_STORE_SIZE, sizeof(struct KVPair), kvpair_compare);
const size_t sz = 2048;
char *ret = calloc(1, sz);
for(size_t i = 0; i < KV_STORE_SIZE; i++) {
if(store[i].key == NULL) {
break;
}
char def[256];
snprintf(def, sizeof(def), "%s\x1F%s\x1E", store[i].key, store[i].value);
strncat(ret, def, sz - strlen(ret) - 1);
}
return ret;
}
static bool kvstore_add(KVStore store, char *key, char *value) {
for(size_t i = 0; i < KV_STORE_SIZE; i++) {
if(store[i].key == NULL) {
store[i].key = key;
store[i].value = value;
return true;
}
}
return false;
}
static bool kvstore_add_fmt(KVStore store, char *key, const char *format, ...) {
va_list vl;
va_start(vl, format);
va_list vl2;
va_copy(vl2, vl);
size_t len = vsnprintf(NULL, 0, format, vl2);
char *def = malloc(len);
vsnprintf(def, len, format, vl);
va_end(vl);
va_end(vl2);
return kvstore_add(store, key, def);
}
static void kvstore_free(KVStore store) {
for(size_t i = 0; i < KV_STORE_SIZE; i++) {
free(store[i].key);
free(store[i].value);
}
}
// The glsl field of a material table is cached and stored
// in the resource manager. This function generates its name.
static char *glsl_table_fullname() {
KVStore store = {};
lua_getfield(L, -1, "vs");
lua_geti(L, -1, 1); // Version
size_t vsVer = lua_tointeger(L, -1);
lua_geti(L, -2, 2); // Filename
char *vsFile = strdup(lua_tostring(L, -1));
kvstore_add(store, strdup("vs"), strdup(lua_tostring(L, -1)));
kvstore_add_fmt(store, strdup("vsv"), "%lu", vsVer);
lua_pop(L, 3);
lua_getfield(L, -1, "fs");
lua_geti(L, -1, 1); // Version
size_t fsVer = lua_tointeger(L, -1);
lua_geti(L, -2, 2); // Filename
char *fsFile = strdup(lua_tostring(L, -1));
kvstore_add(store, strdup("fs"), strdup(lua_tostring(L, -1)));
kvstore_add_fmt(store, strdup("fsv"), "%lu", fsVer);
lua_pop(L, 3);
char ret[1024];
snprintf(ret, sizeof(ret), "\x1E%u\x1E%s\x1E%u\x1E%s\x1E", vsVer, vsFile, fsVer, fsFile);
lua_getfield(L, -1, "defs");
lua_pushnil(L);
while(lua_next(L, -2)) {
@ -3314,19 +3387,17 @@ static char *glsl_table_fullname() {
continue;
}
char def[128];
snprintf(def, sizeof(def), "%s\x1F%s\x1E", lua_tostring(L, -2), lua_tostring(L, -1));
strncat(ret, def, sizeof(ret) - strlen(ret) - 1);
kvstore_add(store, strdup(lua_tostring(L, -2)), strdup(lua_tostring(L, -1)));
lua_pop(L, 1);
}
lua_pop(L, 1);
free(vsFile);
free(fsFile);
char *fullname = kvstore_tostring(store);
return strdup(ret);
kvstore_free(store);
return fullname;
}
static int parse_glsl_table(struct k3Mat *mat) {