Improve orx-shader-phrases
This commit is contained in:
@@ -1,33 +1,58 @@
|
||||
package org.openrndr.extra.shaderphrases
|
||||
|
||||
import org.openrndr.draw.codeFromURL
|
||||
import org.openrndr.extra.shaderphrases.annotations.ShaderPhrases
|
||||
|
||||
fun preprocessShader(shader: String): String {
|
||||
val lines = shader.split("\n")
|
||||
val processed = lines.map {
|
||||
if (it.startsWith("import ")) {
|
||||
/**
|
||||
* Preprocess shader source.
|
||||
* Looks for "#pragma import" statements and injects found phrases.
|
||||
* @param source GLSL source code encoded as string
|
||||
* @return GLSL source code with injected shader phrases
|
||||
*/
|
||||
fun preprocessShader(source: String): String {
|
||||
val lines = source.split("\n")
|
||||
val processed = lines.mapIndexed { index, it ->
|
||||
if (it.startsWith("#pragma import")) {
|
||||
val tokens = it.split(" ")
|
||||
val full = tokens[1]
|
||||
val full = tokens[2]
|
||||
val fullTokens = full.split(".")
|
||||
val fieldName = fullTokens.last().replace(";","").trim()
|
||||
val fieldName = fullTokens.last().replace(";", "").trim()
|
||||
val packageClassTokens = fullTokens.dropLast(1)
|
||||
val packageClass = packageClassTokens.joinToString(".")
|
||||
|
||||
val c = Class.forName(packageClass)
|
||||
if (c.annotations.any { it.annotationClass == ShaderPhrases::class }) {
|
||||
if (fieldName == "*") {
|
||||
c.declaredFields.filter { it.type.name =="java.lang.String" }.map {
|
||||
it.get(null)
|
||||
}.joinToString("\n")
|
||||
try {
|
||||
val c = Class.forName(packageClass)
|
||||
if (c.annotations.any { it.annotationClass == ShaderPhrases::class }) {
|
||||
if (fieldName == "*") {
|
||||
c.declaredFields.filter { it.type.name == "java.lang.String" }.map {
|
||||
"/* imported from $packageClass.$it */\n ${it.get(null)}"
|
||||
}.joinToString("\n")
|
||||
} else {
|
||||
try {
|
||||
c.getDeclaredField(fieldName).get(null)
|
||||
} catch (e: NoSuchFieldException) {
|
||||
error("field \"$fieldName\" not found in \"#pragma import $packageClass.$fieldName\" on line ${index + 1}")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
c.getDeclaredField(fieldName).get(null)
|
||||
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}")
|
||||
}
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
return processed.joinToString("\n")
|
||||
}
|
||||
|
||||
/**
|
||||
* Preprocess shader source from url
|
||||
* Looks for "#pragma import" statements and injects found phrases.
|
||||
* @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))
|
||||
}
|
||||
@@ -1,15 +1,8 @@
|
||||
package org.openrndr.extra.shaderphrases.annotations
|
||||
|
||||
enum class ShaderPhraseLanguage {
|
||||
GLSL
|
||||
GLSL_330
|
||||
}
|
||||
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@Target(AnnotationTarget.FILE, AnnotationTarget.CLASS, AnnotationTarget.FIELD)
|
||||
annotation class ShaderPhrase(val exports: Array<String>,
|
||||
val imports: Array<String> = emptyArray(),
|
||||
val language: ShaderPhraseLanguage = ShaderPhraseLanguage.GLSL)
|
||||
|
||||
|
||||
@Target(AnnotationTarget.FILE)
|
||||
annotation class ShaderPhrases(val exports: Array<String>)
|
||||
annotation class ShaderPhrases(val exports: Array<String> = emptyArray())
|
||||
33
orx-shader-phrases/src/main/kotlin/phrases/Depth.kt
Normal file
33
orx-shader-phrases/src/main/kotlin/phrases/Depth.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
@file:JvmName("Depth")
|
||||
@file:ShaderPhrases([])
|
||||
package org.openrndr.extra.shaderphrases.phrases
|
||||
|
||||
import org.openrndr.extra.shaderphrases.annotations.ShaderPhrases
|
||||
|
||||
/**
|
||||
* phrase for conversion from view to projection depth
|
||||
* @param viewDepth depth in view space ([0.0 .. -far])
|
||||
* @param projection projection matrix
|
||||
* @return depth in projection space ([0.0 .. 1.0]]
|
||||
*/
|
||||
const val viewToProjectionDepth = """
|
||||
float viewToProjectionDepth(float viewDepth, mat4 projection) {
|
||||
float z = viewDepth * projection[2].z + projection[3].z;
|
||||
float w = viewDepth * projection[2].w + projection[3].w;
|
||||
return z / w;
|
||||
}
|
||||
"""
|
||||
|
||||
/**
|
||||
* phrase for conversion from view to projection depth
|
||||
* @param projectionDepth depth in projection space ([0.0 .. 1.0])
|
||||
* @param projectionInversed inverse of the projection matrix
|
||||
* @return depth in view space ([0.0 .. -far]]
|
||||
*/
|
||||
const val projectionToViewDepth = """
|
||||
float projectionToViewDepth(float projectionDepth, mat4 projectionInverse) {
|
||||
float z = projectionDepth * projectionInverse[2].z + projectionInverse[3].z;
|
||||
float w = projectionDepth * projectionInverse[2].w + projectionInverse[3].w;
|
||||
return z / w;
|
||||
}
|
||||
"""
|
||||
@@ -1,19 +1,16 @@
|
||||
@file:JvmName("Dummy")
|
||||
@file:ShaderPhrases(["dummy"])
|
||||
@file:ShaderPhrases
|
||||
|
||||
package org.openrndr.extra.shaderphrases.phrases
|
||||
import org.openrndr.extra.shaderphrases.annotations.ShaderPhrase
|
||||
import org.openrndr.extra.shaderphrases.annotations.ShaderPhrases
|
||||
import org.openrndr.extra.shaderphrases.preprocessShader
|
||||
|
||||
@ShaderPhrase(["dummy"])
|
||||
const val phraseDummy = """
|
||||
float dummy() {
|
||||
return 0.0;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
fun main() {
|
||||
val c = Class.forName("org.openrndr.extra.shaderphrases.phrases.Dummy")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user