You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

47 lines
1.6 KiB
Kotlin

package me.eater.threedom.gl
class ShaderPreProcessor {
private val regex = Regex("(?<module>[^:]+)::(?<call>[^:(]+)\\((?<args>.+)\\)")
private val calls: MutableMap<Pair<String, String>, (List<String>) -> String> = mutableMapOf()
fun process(input: String): String =
input.split("\n").joinToString("\n") {
if (it.startsWith("#[") && it.endsWith("]")) {
val macro = it.substring(2 until it.length - 1)
val match = regex.find(macro) ?: return@joinToString it
val module = match.groups["module"]!!.value
val call = match.groups["call"]!!.value
val args = match.groups["args"]!!.value.split(",").map { arg -> arg.trim() }.toList()
calls[module to call]?.invoke(args) ?: throw RuntimeException("Can't find macro $module::$call")
} else {
it
}
}
fun register(module: String, call: String, block: (List<String>) -> String) {
calls[module to call] = block
}
fun compile(source: String, type: Shader.ShaderType): Shader {
return Shader.create(process(source), type)
}
companion object {
fun createDefault() = ShaderPreProcessor().apply {
register("3dom", "import") { it ->
val knownUniforms = mapOf(
"model" to "mat4",
"view" to "mat4",
"projection" to "mat4",
"normalModel" to "mat3"
)
it.joinToString("\n") { uni ->
"uniform ${knownUniforms[uni]} $uni;"
}
}
}
}
}