From e9dd43f406116633bf23563017b24fe7e72d5929 Mon Sep 17 00:00:00 2001 From: Christian Williams Date: Thu, 29 Apr 2021 20:21:42 -0700 Subject: [PATCH] =?UTF-8?q?WIP=20=E2=80=94=20fix=20bug=20#366=20etc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/baaahs/gl/glsl/GlslCode.kt | 45 +++++----- .../kotlin/baaahs/gl/glsl/GlslParser.kt | 4 +- .../kotlin/baaahs/gl/patch/Component.kt | 2 + .../kotlin/baaahs/gl/patch/LinkedPatch.kt | 4 + .../kotlin/baaahs/gl/patch/ShaderComponent.kt | 19 ++++- .../kotlin/baaahs/gl/shader/OpenShader.kt | 83 +++++++++++++------ .../gl/shader/dialect/BaseShaderDialect.kt | 4 +- .../gl/shader/dialect/IsfShaderDialect.kt | 7 +- .../kotlin/baaahs/gl/glsl/GlslCodeSpec.kt | 4 +- .../kotlin/baaahs/gl/glsl/GlslParserSpec.kt | 5 +- .../baaahs/gl/patch/GlslGenerationSpec.kt | 49 +++++++++-- .../baaahs/gl/shader/type/PaintShaderSpec.kt | 35 ++++---- .../kotlin/baaahs/show/live/FakeOpenShader.kt | 5 +- 13 files changed, 185 insertions(+), 81 deletions(-) diff --git a/src/commonMain/kotlin/baaahs/gl/glsl/GlslCode.kt b/src/commonMain/kotlin/baaahs/gl/glsl/GlslCode.kt index cb02c698d8..863fb06616 100644 --- a/src/commonMain/kotlin/baaahs/gl/glsl/GlslCode.kt +++ b/src/commonMain/kotlin/baaahs/gl/glsl/GlslCode.kt @@ -85,6 +85,10 @@ class GlslCode( } } + fun interface Substitutions { + fun substitute(word: String): String + } + interface GlslStatement { val name: String val fullText: String @@ -93,20 +97,13 @@ class GlslCode( fun stripSource(): GlslStatement - fun toGlsl( - namespace: Namespace, - symbolsToNamespace: Set, - symbolMap: Map - ): String { + fun toGlsl(substitutions: Substitutions): String { + return substituteGlsl(fullText, substitutions, lineNumber) + } + + fun substituteGlsl(text: String, substitutions: Substitutions, lineNumber: Int?): String { return "${lineNumber?.let { "\n#line $lineNumber\n" }}" + - replaceCodeWords(fullText) { - symbolMap[it]?.s - ?: if (it == name || symbolsToNamespace.contains(it)) { - namespace.qualify(it) - } else { - it - } - } + replaceCodeWords(text) { substitutions.substitute(it) } } } @@ -159,6 +156,7 @@ class GlslCode( val isConst: Boolean = false, val isUniform: Boolean = false, override val isVarying: Boolean = false, + val initExpr: String? = null, override val lineNumber: Int? = null, override val comments: List = emptyList() ) : GlslStatement, GlslArgSite { @@ -166,8 +164,21 @@ class GlslCode( override val isGlobalInput: Boolean get() = isUniform || isVarying override val isAbstractFunction: Boolean get() = false override val hint: Hint? by lazy { Hint.parse(comments.joinToString(" ") { it.trim() }, lineNumber) } + val deferInitialization: Boolean = !isConst && initExpr != null override fun stripSource() = copy(fullText = "", lineNumber = null) + + fun declarationToGlsl(substitutions: Substitutions): String { + val declaration = if (deferInitialization) { + fullText.substring(0, fullText.indexOf(initExpr!!)) + ";" + } else fullText + return substituteGlsl(declaration, substitutions, lineNumber) + } + + fun assignmentToGlsl(substitutions: Substitutions): String { + val assignment = " $name$initExpr;" + return substituteGlsl(assignment, substitutions, lineNumber) + } } class Hint( @@ -252,13 +263,9 @@ class GlslCode( return params.associate { it.name to (it.findContentType(plugins, this) ?: ContentType.Unknown) } } - override fun toGlsl( - namespace: Namespace, - symbolsToNamespace: Set, - symbolMap: Map - ): String { + override fun toGlsl(substitutions: Substitutions): String { // Chomp trailing ';' if it's an abstract method. - return super.toGlsl(namespace, symbolsToNamespace, symbolMap) + return super.toGlsl(substitutions) .let { if (isAbstract) it.trimEnd(';') else it } } diff --git a/src/commonMain/kotlin/baaahs/gl/glsl/GlslParser.kt b/src/commonMain/kotlin/baaahs/gl/glsl/GlslParser.kt index 2a7aaff9cb..adbc6da997 100644 --- a/src/commonMain/kotlin/baaahs/gl/glsl/GlslParser.kt +++ b/src/commonMain/kotlin/baaahs/gl/glsl/GlslParser.kt @@ -267,7 +267,7 @@ class GlslParser { return Regex("(?:(const|uniform|varying)\\s+)?(\\w+)\\s+(\\w+)(\\s*\\[\\s*\\d+\\s*])?(\\s*=.*)?;", RegexOption.MULTILINE) .find(text.trim())?.let { - val (qualifier, type, name, arraySpec, constValue) = it.destructured + val (qualifier, type, name, arraySpec, initExpr) = it.destructured var (isConst, isUniform, isVarying) = arrayOf(false, false, false) when (qualifier) { "const" -> isConst = true @@ -277,7 +277,7 @@ class GlslParser { val (trimmedText, trimmedLineNumber) = chomp(text, lineNumber) GlslCode.GlslVar( name, context.findType(type), trimmedText, isConst, isUniform, isVarying, - trimmedLineNumber, comments + if (initExpr.isEmpty()) null else initExpr, trimmedLineNumber, comments ) } } diff --git a/src/commonMain/kotlin/baaahs/gl/patch/Component.kt b/src/commonMain/kotlin/baaahs/gl/patch/Component.kt index bb1c2d2cb3..fdbf4db235 100644 --- a/src/commonMain/kotlin/baaahs/gl/patch/Component.kt +++ b/src/commonMain/kotlin/baaahs/gl/patch/Component.kt @@ -15,4 +15,6 @@ interface Component { fun appendInvokeAndSet(buf: StringBuilder, injectionParams: Map = emptyMap()) fun getExpression(prefix: String): GlslExpr + + fun getInit(): String? = null } \ No newline at end of file diff --git a/src/commonMain/kotlin/baaahs/gl/patch/LinkedPatch.kt b/src/commonMain/kotlin/baaahs/gl/patch/LinkedPatch.kt index 699520826f..8ddd2c512a 100644 --- a/src/commonMain/kotlin/baaahs/gl/patch/LinkedPatch.kt +++ b/src/commonMain/kotlin/baaahs/gl/patch/LinkedPatch.kt @@ -42,6 +42,10 @@ class LinkedPatch( buf.append("\n#line 10001\n") buf.append("void main() {\n") + components.forEach { component -> + component.getInit()?.let { buf.append(it) } + } + components.filter { it.invokeFromMain }.forEach { component -> component.appendInvokeAndSet(buf) } diff --git a/src/commonMain/kotlin/baaahs/gl/patch/ShaderComponent.kt b/src/commonMain/kotlin/baaahs/gl/patch/ShaderComponent.kt index 695010453a..9b1436b31e 100644 --- a/src/commonMain/kotlin/baaahs/gl/patch/ShaderComponent.kt +++ b/src/commonMain/kotlin/baaahs/gl/patch/ShaderComponent.kt @@ -4,6 +4,7 @@ import baaahs.gl.glsl.GlslCode import baaahs.gl.glsl.GlslExpr import baaahs.gl.glsl.GlslType import baaahs.gl.shader.InputPort +import baaahs.gl.shader.ShaderSubstitutions import baaahs.show.live.LinkedShaderInstance class ShaderComponent( @@ -58,6 +59,8 @@ class ShaderComponent( private val resolvedPortMap get() = portMap + mapOf(shaderInstance.shader.outputPort.id to GlslExpr(outputVar)) + private val substitutions = ShaderSubstitutions(shaderInstance.shader, namespace, resolvedPortMap) + override fun appendStructs(buf: StringBuilder) { val openShader = shaderInstance.shader val portStructs = openShader.portStructs @@ -81,7 +84,7 @@ class ShaderComponent( appendInjectionCode(buf) - buf.append(openShader.toGlsl(namespace, resolvedPortMap), "\n") + buf.append(openShader.toGlsl(substitutions), "\n") } private fun appendInjectionCode(buf: StringBuilder) { @@ -114,7 +117,9 @@ class ShaderComponent( link: ProgramNode ) { val fn = inputPort.glslArgSite as GlslCode.GlslFunction - buf.append(fn.toGlsl(namespace, emptySet(), emptyMap())) + buf.append(fn.toGlsl { + if (it == fn.name) namespace.qualify(it) else it + }) buf.append(" {\n") val destComponent = findUpstreamComponent(link) @@ -148,6 +153,16 @@ class ShaderComponent( }.let { GlslExpr(it) } } + override fun getInit(): String? { + return if (shaderInstance.shader.requiresInit) { + StringBuilder().apply { + append(" // Init ${title}.\n") + append(" ${ShaderSubstitutions.namespacedInitFnName(namespace)}();\n") + append("\n") + }.toString() + } else null + } + override fun toString(): String = "ShaderComponent(${prefix}_$id)" } \ No newline at end of file diff --git a/src/commonMain/kotlin/baaahs/gl/shader/OpenShader.kt b/src/commonMain/kotlin/baaahs/gl/shader/OpenShader.kt index 3a035bbb1a..4d5e6dbfa7 100644 --- a/src/commonMain/kotlin/baaahs/gl/shader/OpenShader.kt +++ b/src/commonMain/kotlin/baaahs/gl/shader/OpenShader.kt @@ -10,13 +10,13 @@ import baaahs.gl.shader.type.ShaderType import baaahs.only import baaahs.show.Shader import baaahs.unknown -import kotlin.collections.set interface OpenShader : RefCounted { val shader: Shader val src: String get() = glslCode.src val glslCode: GlslCode val title: String + val requiresInit: Boolean get() = false val entryPoint: GlslFunction val inputPorts: List @@ -38,10 +38,7 @@ interface OpenShader : RefCounted { (inputPorts.map { it.contentType.glslType } + outputPort.contentType.glslType) .filterIsInstance() - /** The list of global variables that aren't also backing input ports. */ - val globalVars: List - - fun toGlsl(namespace: Namespace, portMap: Map = emptyMap()): String + fun toGlsl(substitutions: GlslCode.Substitutions): String fun invoker( namespace: Namespace, @@ -67,34 +64,29 @@ interface OpenShader : RefCounted { override val title: String get() = shader.title - override val globalVars: List get() = - glslCode.globalVars.filter { !it.isUniform && !it.isVarying } + override val requiresInit = globalVars.any { it.deferInitialization } - override fun toGlsl( - namespace: Namespace, - portMap: Map - ): String { + override fun toGlsl(substitutions: GlslCode.Substitutions): String { val buf = StringBuilder() - - val nonUniformGlobalsMap = hashMapOf() globalVars.forEach { glslVar -> - nonUniformGlobalsMap[glslVar.name] = GlslExpr(namespace.qualify(glslVar.name)) - buf.append(glslVar.toGlsl(namespace, glslCode.symbolNames, emptyMap())) + buf.append(glslVar.declarationToGlsl(substitutions)) buf.append("\n") } - val uniformGlobalsMap = portMap.filter { (id, _) -> - val inputPort = findInputPortOrNull(id) - - inputPort?.isGlobal == true || - (outputPort.id == id && !outputPort.isParam) + glslCode.functions.filterNot { it.isAbstract }.forEach { glslFunction -> + buf.append(glslFunction.toGlsl(substitutions)) + buf.append("\n") } - val symbolsToNamespace = glslCode.symbolNames.toSet() - portStructs.map { it.name} - val symbolMap = uniformGlobalsMap + nonUniformGlobalsMap - glslCode.functions.filterNot { it.isAbstract }.forEach { glslFunction -> - buf.append(glslFunction.toGlsl(namespace, symbolsToNamespace, symbolMap)) + if (requiresInit) { buf.append("\n") + buf.append("void ${substitutions.substitute(ShaderSubstitutions.initFnName)}() {") + globalVars.forEach { + if (it.deferInitialization) { + buf.append(" ${it.assignmentToGlsl(substitutions)};\n") + } + } + buf.append("}\n") } return buf.toString() @@ -113,4 +105,45 @@ interface OpenShader : RefCounted { override fun hashCode(): Int = src.hashCode() } -} \ No newline at end of file +} + +class ShaderSubstitutions( + val openShader: OpenShader, + val namespace: Namespace, + portMap: Map +) : GlslCode.Substitutions { + private val uniformGlobalsMap = portMap.filter { (id, _) -> + val inputPort = openShader.findInputPortOrNull(id) + inputPort?.isGlobal == true || + (openShader.outputPort.id == id && !openShader.outputPort.isParam) + } + + private val nonUniformGlobalsMap = openShader.globalVars.associate { glslVar -> + glslVar.name to GlslExpr(namespace.qualify(glslVar.name)) + } + + private val symbolsToNamespace = + openShader.glslCode.symbolNames.toSet() - openShader.portStructs.map { it.name } + + private val specialSymbols = + mapOf(initFnName to GlslExpr(namespacedInitFnName(namespace))) + + private val symbolMap = uniformGlobalsMap + nonUniformGlobalsMap + specialSymbols + + override fun substitute(word: String): String = + symbolMap[word]?.s + ?: if (symbolsToNamespace.contains(word)) { + namespace.qualify(word) + } else { + word + } + + companion object { + val initFnName = "_init_" + fun namespacedInitFnName(namespace: Namespace) = namespace.internalQualify("init") + } +} + +/** The list of global variables that aren't also backing input ports. */ +private val OpenShader.globalVars: List get() = + glslCode.globalVars.filter { !it.isUniform && !it.isVarying } diff --git a/src/commonMain/kotlin/baaahs/gl/shader/dialect/BaseShaderDialect.kt b/src/commonMain/kotlin/baaahs/gl/shader/dialect/BaseShaderDialect.kt index 03d1c65b14..c5599eb798 100644 --- a/src/commonMain/kotlin/baaahs/gl/shader/dialect/BaseShaderDialect.kt +++ b/src/commonMain/kotlin/baaahs/gl/shader/dialect/BaseShaderDialect.kt @@ -152,14 +152,14 @@ abstract class BaseShaderDialect(id: String) : ShaderDialect(id) { open fun findWellKnownInputPorts(glslCode: GlslCode, declaredInputPorts: Set): List { if (wellKnownInputPorts.isEmpty()) return emptyList() - val iVars = glslCode.statements.flatMap { glslFunction -> + val symbolsMentionedInShader = glslCode.statements.flatMap { glslFunction -> Regex("\\w+").findAll(glslFunction.fullText).map { it.value }.filter { word -> wellKnownInputPortsById.containsKey(word) }.toList() }.toSet() return wellKnownInputPorts.filter { inputPort -> - iVars.contains(inputPort.id) && !declaredInputPorts.contains(inputPort.id) + symbolsMentionedInShader.contains(inputPort.id) && !declaredInputPorts.contains(inputPort.id) } } } \ No newline at end of file diff --git a/src/commonMain/kotlin/baaahs/gl/shader/dialect/IsfShaderDialect.kt b/src/commonMain/kotlin/baaahs/gl/shader/dialect/IsfShaderDialect.kt index f57b54da76..16e51c59dc 100644 --- a/src/commonMain/kotlin/baaahs/gl/shader/dialect/IsfShaderDialect.kt +++ b/src/commonMain/kotlin/baaahs/gl/shader/dialect/IsfShaderDialect.kt @@ -117,10 +117,9 @@ object IsfShaderDialect : BaseShaderDialect("baaahs.Core:ISF") { } private fun findIsfShaderDeclaration(glslCode: GlslCode): IsfShader? { - val match = Regex("^/\\*(\\{[\\s\\S]*})\\*/").find(glslCode.src) - ?: return null - - val (jsonDecl) = match.destructured + if (!glslCode.src.startsWith("/*{")) return null + val endOfJson = glslCode.src.indexOf("*/") + val jsonDecl = glslCode.src.substring(2, endOfJson) try { return json.decodeFromString(IsfShader.serializer(), jsonDecl) } catch (e: SerializationException) { diff --git a/src/commonTest/kotlin/baaahs/gl/glsl/GlslCodeSpec.kt b/src/commonTest/kotlin/baaahs/gl/glsl/GlslCodeSpec.kt index fe68c4385c..8d66100484 100644 --- a/src/commonTest/kotlin/baaahs/gl/glsl/GlslCodeSpec.kt +++ b/src/commonTest/kotlin/baaahs/gl/glsl/GlslCodeSpec.kt @@ -35,7 +35,9 @@ object GlslCodeSpec : Spek({ context("const") { override(text) { "const int i = 3;" } - expectValue(GlslCode.GlslVar("i", GlslType.Int, "const int i = 3;", isConst = true)) { variable } + expectValue( + GlslCode.GlslVar("i", GlslType.Int, "const int i = 3;", isConst = true, initExpr = " = 3") + ) { variable } } context("uniform") { diff --git a/src/commonTest/kotlin/baaahs/gl/glsl/GlslParserSpec.kt b/src/commonTest/kotlin/baaahs/gl/glsl/GlslParserSpec.kt index fc943b42ad..c5419c9945 100644 --- a/src/commonTest/kotlin/baaahs/gl/glsl/GlslParserSpec.kt +++ b/src/commonTest/kotlin/baaahs/gl/glsl/GlslParserSpec.kt @@ -233,7 +233,9 @@ object GlslParserSpec : Spek({ it("handles nested macro expansions") { val glslFunction = glslCode.functions.only() - val glsl = glslFunction.toGlsl(Namespace("ns"), emptySet(), emptyMap()) + val glsl = glslFunction.toGlsl { text -> + if (text == "main") Namespace("ns").qualify(text) else text + } expect(glsl.trim()) .toBe( @@ -423,6 +425,7 @@ object GlslParserSpec : Spek({ GlslVar( "baseColor", GlslType.Vec3, "const vec3 baseColor = vec3(0.0,0.09,0.18);", isConst = true, + initExpr = " = vec3(0.0,0.09,0.18)", lineNumber = 1 ) ) diff --git a/src/commonTest/kotlin/baaahs/gl/patch/GlslGenerationSpec.kt b/src/commonTest/kotlin/baaahs/gl/patch/GlslGenerationSpec.kt index 213921337e..b83746fecd 100644 --- a/src/commonTest/kotlin/baaahs/gl/patch/GlslGenerationSpec.kt +++ b/src/commonTest/kotlin/baaahs/gl/patch/GlslGenerationSpec.kt @@ -29,7 +29,8 @@ object GlslGenerationSpec : Spek({ uniform float blueness; uniform vec2 resolution; uniform float time; - int someGlobalVar; + int someGlobalVar = int(blueness * 100.); + int anotherGlobalVar = someGlobalVar + 1; const int someConstVar = 123; int anotherFunc(int i) { return i; } @@ -94,21 +95,35 @@ object GlslGenerationSpec : Spek({ int p0_thisShaderSName_someGlobalVar; #line 8 + int p0_thisShaderSName_anotherGlobalVar; + + #line 9 const int p0_thisShaderSName_someConstVar = 123; - #line 10 + #line 11 int p0_thisShaderSName_anotherFunc(int i) { return i; } - #line 12 + #line 13 void p0_thisShaderSName_main( void ) { vec2 uv = gl_FragCoord.xy / in_resolution.xy; p0_thisShaderSName_someGlobalVar = p0_thisShaderSName_anotherFunc(p0_thisShaderSName_someConstVar); p0_thisShaderSName_gl_FragColor = vec4(uv.xy, in_bluenessSlider, 1.); } + void p0_thisShaderSNamei_init() { + #line 7 + p0_thisShaderSName_someGlobalVar = int(in_bluenessSlider * 100.);; + + #line 8 + p0_thisShaderSName_anotherGlobalVar = p0_thisShaderSName_someGlobalVar + 1;; + } + #line 10001 void main() { + // Init This Shader's Name. + p0_thisShaderSNamei_init(); + // Invoke This Shader's Name p0_thisShaderSName_main(); @@ -192,7 +207,7 @@ object GlslGenerationSpec : Spek({ // Other stuff. uniform float blueness; - int someGlobalVar; + int someGlobalVar = int(blueness * 100.); const int someConstVar = 123; int anotherFunc(int i) { return i; } @@ -260,9 +275,17 @@ object GlslGenerationSpec : Spek({ fragColor = vec4(uv.xy, in_bluenessSlider, 1.); } + void p0_thisShaderSNamei_init() { + #line 5 + p0_thisShaderSName_someGlobalVar = int(in_bluenessSlider * 100.);; + } + #line 10001 void main() { + // Init This Shader's Name. + p0_thisShaderSNamei_init(); + // Invoke This Shader's Name p0_thisShaderSName_mainImage(p0_thisShaderSName_fragColor, gl_FragCoord.xy); @@ -356,21 +379,35 @@ object GlslGenerationSpec : Spek({ int p1_thisShaderSName_someGlobalVar; #line 8 + int p1_thisShaderSName_anotherGlobalVar; + + #line 9 const int p1_thisShaderSName_someConstVar = 123; - #line 10 + #line 11 int p1_thisShaderSName_anotherFunc(int i) { return i; } - #line 12 + #line 13 void p1_thisShaderSName_main( void ) { vec2 uv = p0_cylindricalProjectioni_result.xy / in_resolution.xy; p1_thisShaderSName_someGlobalVar = p1_thisShaderSName_anotherFunc(p1_thisShaderSName_someConstVar); p1_thisShaderSName_gl_FragColor = vec4(uv.xy, in_bluenessSlider, 1.); } + void p1_thisShaderSNamei_init() { + #line 7 + p1_thisShaderSName_someGlobalVar = int(in_bluenessSlider * 100.);; + + #line 8 + p1_thisShaderSName_anotherGlobalVar = p1_thisShaderSName_someGlobalVar + 1;; + } + #line 10001 void main() { + // Init This Shader's Name. + p1_thisShaderSNamei_init(); + // Invoke Pixel Location in_pixelLocation = ds_pixelLocation_getPixelCoords(gl_FragCoord.xy); diff --git a/src/commonTest/kotlin/baaahs/gl/shader/type/PaintShaderSpec.kt b/src/commonTest/kotlin/baaahs/gl/shader/type/PaintShaderSpec.kt index d7730162b3..ccd6b87fe8 100644 --- a/src/commonTest/kotlin/baaahs/gl/shader/type/PaintShaderSpec.kt +++ b/src/commonTest/kotlin/baaahs/gl/shader/type/PaintShaderSpec.kt @@ -9,6 +9,7 @@ import baaahs.gl.openShader import baaahs.gl.override import baaahs.gl.patch.ContentType import baaahs.gl.shader.InputPort +import baaahs.gl.shader.ShaderSubstitutions import baaahs.gl.testToolchain import baaahs.show.Shader import baaahs.toBeSpecified @@ -128,12 +129,13 @@ object PaintShaderSpec : Spek({ it("generates function declarations") { expect( openShader.toGlsl( - namespace, - mapOf( - "resolution" to GlslExpr("in_resolution"), - "blueness" to GlslExpr("aquamarinity"), - "identity" to GlslExpr("p0_identity"), - "gl_FragColor" to GlslExpr("sm_result") + ShaderSubstitutions(openShader, namespace, + mapOf( + "resolution" to GlslExpr("in_resolution"), + "blueness" to GlslExpr("aquamarinity"), + "identity" to GlslExpr("p0_identity"), + "gl_FragColor" to GlslExpr("sm_result") + ) ) ).trim() ) @@ -279,15 +281,18 @@ object PaintShaderSpec : Spek({ it("generates function declarations") { expect( openShader.toGlsl( - namespace, - mapOf( - "iResolution" to GlslExpr("in_resolution"), - "iMouse" to GlslExpr("in_mouse"), - "iTime" to GlslExpr("in_time"), - "blueness" to GlslExpr("aquamarinity"), - "identity" to GlslExpr("p0_identity"), - "fragCoord" to GlslExpr("gl_FragCoord.xy") - ), + ShaderSubstitutions( + openShader, + namespace, + mapOf( + "iResolution" to GlslExpr("in_resolution"), + "iMouse" to GlslExpr("in_mouse"), + "iTime" to GlslExpr("in_time"), + "blueness" to GlslExpr("aquamarinity"), + "identity" to GlslExpr("p0_identity"), + "fragCoord" to GlslExpr("gl_FragCoord.xy") + ), + ) ).trim() ) .toBe( diff --git a/src/commonTest/kotlin/baaahs/show/live/FakeOpenShader.kt b/src/commonTest/kotlin/baaahs/show/live/FakeOpenShader.kt index 239e15d5f7..fa789cccc0 100644 --- a/src/commonTest/kotlin/baaahs/show/live/FakeOpenShader.kt +++ b/src/commonTest/kotlin/baaahs/show/live/FakeOpenShader.kt @@ -26,10 +26,7 @@ class FakeOpenShader( override val entryPoint: GlslCode.GlslFunction get() = TODO("not implemented") - override val globalVars: List - get() = TODO("not implemented") - - override fun toGlsl(namespace: GlslCode.Namespace, portMap: Map): String = + override fun toGlsl(substitutions: GlslCode.Substitutions): String = "// GLSL for $title" override fun invoker(