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
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;"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|