[orx-dnk3] Add feature architecture and post processing effects

This commit is contained in:
Edwin Jakobs
2020-07-06 13:00:58 +02:00
parent 0b0691e9ae
commit 419c38cc25
63 changed files with 2164 additions and 187 deletions

View File

@@ -9,50 +9,56 @@ import org.openrndr.extra.shaderphrases.annotations.ShaderPhrases
* @param source GLSL source code encoded as string
* @return GLSL source code with injected shader phrases
*/
fun preprocessShader(source: String): String {
fun preprocessShader(source: String, symbols: Set<String> = emptySet()): String {
val newSymbols = mutableSetOf<String>()
newSymbols.addAll(symbols)
val lines = source.split("\n")
val processed = lines.mapIndexed { index, it ->
if (it.startsWith("#pragma import")) {
val tokens = it.split(" ")
val full = tokens[2]
val fullTokens = full.split(".")
val symbol = tokens[2].trim().replace(";", "")
val fullTokens = symbol.split(".")
val fieldName = fullTokens.last().replace(";", "").trim()
val packageClassTokens = fullTokens.dropLast(1)
val packageClass = packageClassTokens.joinToString(".")
try {
/* Note that JVM-style reflection is used here because of short-comings in the Kotlin reflection
if (symbol !in newSymbols) {
newSymbols.add(symbol)
try {
/* Note that JVM-style reflection is used here because of short-comings in the Kotlin reflection
library (as of 1.3.61), most notably reflection support for file facades is missing. */
val c = Class.forName(packageClass)
if (c.annotations.any { it.annotationClass == ShaderPhrases::class }) {
if (fieldName == "*") {
c.declaredMethods.filter { it.returnType.name == "java.lang.String" }.map {
"/* imported from $packageClass.$it */\n${it.invoke(null)}\n"
}.joinToString("\n") +
c.declaredFields.filter { it.type.name == "java.lang.String" }.map {
"/* imported from $packageClass.$it */\n${it.get(null)}\n"
}.joinToString("\n")
} else {
var result:String?
try {
val methodName = "get${fieldName.take(1).toUpperCase() + fieldName.drop(1)}"
result = c.getMethod(methodName).invoke(null) as String
result
} catch (e: NoSuchMethodException) {
val c = Class.forName(packageClass)
if (c.annotations.any { it.annotationClass == ShaderPhrases::class }) {
if (fieldName == "*") {
c.declaredMethods.filter { it.returnType.name == "java.lang.String" }.map {
"/* imported from $packageClass.$it */\n${it.invoke(null)}\n"
}.joinToString("\n") +
c.declaredFields.filter { it.type.name == "java.lang.String" }.map {
"/* imported from $packageClass.$it */\n${it.get(null)}\n"
}.joinToString("\n")
} else {
var result: String?
try {
result = c.getDeclaredField(fieldName).get(null) as String
result
} catch (e: NoSuchFieldException) {
error("field \"$fieldName\" not found in \"#pragma import $packageClass.$fieldName\" on line ${index + 1}")
val methodName = "get${fieldName.take(1).toUpperCase() + fieldName.drop(1)}"
result = preprocessShader(c.getMethod(methodName).invoke(null) as String, newSymbols)
} catch (e: NoSuchMethodException) {
try {
result = preprocessShader(c.getDeclaredField(fieldName).get(null) as String, newSymbols)
} catch (e: NoSuchFieldException) {
error("field \"$fieldName\" not found in \"#pragma import $packageClass.$fieldName\" on line ${index + 1}")
}
}
result
}
} else {
throw IllegalArgumentException("class $packageClass has no ShaderPhrases annotation")
}
} else {
throw IllegalArgumentException("class $packageClass has no ShaderPhrases annotation")
} catch (e: ClassNotFoundException) {
error("class \"$packageClass\" not found in \"#pragma import $packageClass\" on line ${index + 1}")
}
} catch (e: ClassNotFoundException) {
error("class \"$packageClass\" not found in \"#pragma import $packageClass\" on line ${index + 1}")
} else {
""
}
} else {
it
@@ -67,6 +73,6 @@ fun preprocessShader(source: String): String {
* @param url url pointing to GLSL shader source
* @return GLSL source code with injected shader phrases
*/
fun preprocessShaderFromUrl(url: String): String {
return preprocessShader(codeFromURL(url))
fun preprocessShaderFromUrl(url: String, symbols: Set<String>): String {
return preprocessShader(codeFromURL(url), symbols)
}