Skip to content

Commit 3b84c52

Browse files
authored
Merge pull request #279 from baaahs/more-patch-editor
More work on patch editor
2 parents e254d43 + 678737c commit 3b84c52

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1419
-816
lines changed

build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ kotlin {
210210
implementation(npm("resize-observer-polyfill", "^1.5.1"))
211211
implementation(npm("react-ace", "^9.0.0"))
212212
implementation(npm("ace-builds", "^1.4.11"))
213+
implementation(npm("markdown-it", "~11.0.0"))
213214
implementation(npm("normalize.css", "^7.0.0"))
214215
implementation(npm("@blueprintjs/core", "^3.24.0"))
215216
implementation(npm("@blueprintjs/icons", "^3.14.0"))

src/commonMain/kotlin/baaahs/glshaders/AutoWirer.kt

+13-7
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,26 @@ class AutoWirer(
1414
) {
1515
fun autoWire(
1616
vararg shaders: Shader,
17-
focus: Shader? = null
17+
focus: Shader? = null,
18+
overrides: Map<ContentType, MutableLink.Port> = emptyMap()
1819
): UnresolvedPatch {
1920
val openShaders = shaders.associate { it to glslAnalyzer.openShader(it) }
20-
return autoWire(openShaders.values, focus?.let { openShaders[it] })
21+
return autoWire(openShaders.values, focus?.let { openShaders[it] }, overrides = overrides)
2122
}
2223

2324
fun autoWire(
2425
vararg shaders: OpenShader,
25-
focus: OpenShader? = null
26+
focus: OpenShader? = null,
27+
overrides: Map<ContentType, MutableLink.Port> = emptyMap()
2628
): UnresolvedPatch {
27-
return autoWire(shaders.toList(), focus)
29+
return autoWire(shaders.toList(), focus, overrides = overrides)
2830
}
2931

3032
fun autoWire(
3133
shaders: Collection<OpenShader>,
3234
focus: OpenShader? = null,
33-
shaderChannel: ShaderChannel = ShaderChannel.Main
35+
shaderChannel: ShaderChannel = ShaderChannel.Main,
36+
overrides: Map<ContentType, MutableLink.Port> = emptyMap()
3437
): UnresolvedPatch {
3538
val locallyAvailable: MutableMap<ContentType, MutableSet<MutableLink.Port>> = mutableMapOf()
3639

@@ -54,6 +57,10 @@ class AutoWirer(
5457
openShader to unresolvedShaderInstance
5558
}
5659

60+
overrides.forEach { (contentType, port) ->
61+
locallyAvailable[contentType] = hashSetOf(port)
62+
}
63+
5764
// Second pass: link datasources/output ports to input ports.
5865
val shaderInstancesOfInterest = if (focus == null) {
5966
shaderInstances
@@ -270,8 +277,7 @@ class AutoWirer(
270277
?: error(unknown("shader instance editor", fromShader, shaderInstances.keys))
271278
shaderInstance.incomingLinks[toPortId] =
272279
MutableShaderOutPort(
273-
fromShaderInstance,
274-
fromPort.portId
280+
fromShaderInstance
275281
)
276282
}
277283
}

src/commonMain/kotlin/baaahs/glshaders/FilterShader.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package baaahs.glshaders
22

3+
import baaahs.glsl.LinkException
34
import baaahs.show.Shader
45
import baaahs.show.ShaderOutPortRef
56
import baaahs.show.ShaderType
@@ -38,6 +39,7 @@ class FilterShader(shader: Shader, glslCode: GlslCode) : OpenShader.Base(shader,
3839
resultVar: String,
3940
portMap: Map<String, String>
4041
): String {
41-
return resultVar + " = " + namespace.qualify(entryPoint.name) + "(${portMap["gl_FragColor"]})"
42+
val inVar = portMap["gl_FragColor"] ?: throw LinkException("No input for shader \"$title\"")
43+
return resultVar + " = " + namespace.qualify(entryPoint.name) + "($inVar)"
4244
}
4345
}

src/commonMain/kotlin/baaahs/glshaders/GlslAnalyzer.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class GlslAnalyzer {
1010
fun import(src: String, defaultTitle: String? = null): Shader {
1111
val glslCode = analyze(src)
1212
val type = ShaderType.values().firstOrNull { it.matches(glslCode) }
13-
?: ShaderType.Color // Reasonable guess?
13+
?: ShaderType.Paint // Reasonable guess?
1414

1515
val title = Regex("^// (.*)").find(src)?.groupValues?.get(1)
1616

@@ -41,7 +41,7 @@ class GlslAnalyzer {
4141
return when (shader.type) {
4242
ShaderType.Projection -> OpenShader.tryUvTranslatorShader(shader, glslObj)
4343
ShaderType.Distortion -> TODO()
44-
ShaderType.Color -> OpenShader.tryColorShader(shader, glslObj)
44+
ShaderType.Paint -> OpenShader.tryPaintShader(shader, glslObj)
4545
ShaderType.Filter -> OpenShader.tryFilterShader(shader, glslObj)
4646
} ?: throw AnalysisException("Can't open purported ${shader.type} shader \"${shader.title}\"")
4747
}

src/commonMain/kotlin/baaahs/glshaders/GlslProgram.kt

+1-3
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@ class GlslProgram(
4040
)
4141

4242
internal val fragShader =
43-
gl.createFragmentShader(
44-
"#version ${gl.glslVersion}\n\n${linkedPatch.toGlsl()}\n"
45-
)
43+
gl.createFragmentShader(linkedPatch.toFullGlsl(gl.glslVersion))
4644

4745
private val bindings: List<Binding>
4846

src/commonMain/kotlin/baaahs/glshaders/LinkedPatch.kt

+14-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import baaahs.glsl.GlslContext
77
import baaahs.show.ShaderChannel
88
import baaahs.show.Surfaces
99
import baaahs.show.live.LiveShaderInstance
10-
import baaahs.show.live.LiveShaderInstance.DataSourceLink
11-
import baaahs.show.live.LiveShaderInstance.ShaderOutLink
10+
import baaahs.show.live.LiveShaderInstance.*
1211
import kotlin.collections.component1
1312
import kotlin.collections.component2
1413
import kotlin.collections.set
@@ -98,7 +97,15 @@ class LinkedPatch(
9897
fromLink.dataSource.getVarName(fromLink.varName)
9998
}
10099
}
101-
else -> logger.warn { "Unexpected incoming link $fromLink for $toPortId" }
100+
is ShaderChannelLink -> {
101+
logger.warn { "Unexpected unresolved $fromLink for $toPortId" }
102+
}
103+
is ConstLink -> {
104+
tmpPortMap[toPortId] = lazy {
105+
"(" + fromLink.glsl + ")"
106+
}
107+
}
108+
is NoOpLink -> {}
102109
}
103110
}
104111

@@ -195,6 +202,10 @@ class LinkedPatch(
195202
return buf.toString()
196203
}
197204

205+
fun toFullGlsl(glslVersion: String): String {
206+
return "#version ${glslVersion}\n\n${toGlsl()}\n"
207+
}
208+
198209
fun compile(glslContext: GlslContext, resolver: Resolver): GlslProgram =
199210
GlslProgram(glslContext, this, resolver)
200211

src/commonMain/kotlin/baaahs/glshaders/OpenShader.kt

+4-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ interface OpenShader : RefCounted {
1414
val src: String get() = glslCode.src
1515
val glslCode: GlslCode
1616
val title: String
17-
val description: String?
1817
val shaderType: ShaderType
1918
val entryPoint: GlslFunction
2019
val inputPorts: List<InputPort>
@@ -33,8 +32,7 @@ interface OpenShader : RefCounted {
3332
final override val shader: Shader,
3433
final override val glslCode: GlslCode
3534
) : OpenShader, RefCounted by RefCounter() {
36-
override val title: String = shader.title
37-
override val description: String? = null
35+
override val title: String get() = shader.title
3836

3937
protected fun toInputPort(it: GlslCode.GlslVar): InputPort {
4038
return InputPort(
@@ -83,13 +81,13 @@ interface OpenShader : RefCounted {
8381
}
8482

8583
companion object {
86-
fun tryColorShader(shader: Shader, glslCode: GlslCode): ColorShader? {
84+
fun tryPaintShader(shader: Shader, glslCode: GlslCode): PaintShader? {
8785
return when {
8886
glslCode.functionNames.contains("main") ->
89-
GenericColorShader(shader, glslCode)
87+
GenericPaintShader(shader, glslCode)
9088

9189
glslCode.functionNames.contains("mainImage") ->
92-
ShaderToyColorShader(shader, glslCode)
90+
ShaderToyPaintShader(shader, glslCode)
9391

9492
else -> null
9593
}

src/commonMain/kotlin/baaahs/glshaders/ColorShader.kt src/commonMain/kotlin/baaahs/glshaders/PaintShader.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import baaahs.show.Shader
44
import baaahs.show.ShaderOutPortRef
55
import baaahs.show.ShaderType
66

7-
abstract class ColorShader(shader: Shader, glslCode: GlslCode) : OpenShader.Base(shader, glslCode) {
8-
override val shaderType: ShaderType = ShaderType.Color
7+
abstract class PaintShader(shader: Shader, glslCode: GlslCode) : OpenShader.Base(shader, glslCode) {
8+
override val shaderType: ShaderType = ShaderType.Paint
99
}
1010

11-
class ShaderToyColorShader(shader: Shader, glslCode: GlslCode) : ColorShader(shader, glslCode) {
11+
class ShaderToyPaintShader(shader: Shader, glslCode: GlslCode) : PaintShader(shader, glslCode) {
1212
companion object {
1313
val magicUniforms = listOf(
1414
// uniform vec3 iResolution; // viewport resolution (in pixels)
@@ -89,7 +89,7 @@ class ShaderToyColorShader(shader: Shader, glslCode: GlslCode) : ColorShader(sha
8989
}
9090
}
9191

92-
class GenericColorShader(shader: Shader, glslCode: GlslCode) : ColorShader(shader, glslCode) {
92+
class GenericPaintShader(shader: Shader, glslCode: GlslCode) : PaintShader(shader, glslCode) {
9393
companion object {
9494
val wellKnownInputPorts = listOf(
9595
InputPort("gl_FragCoord", "vec4", "Coordinates", ContentType.UvCoordinate),

src/commonMain/kotlin/baaahs/glsl/CompiledShader.kt

-9
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ class CompiledShader(
1919
}
2020

2121
private fun compile() {
22-
// logger.warn { "CompiledShader src: ${source}" }
23-
2422
gl.runInContext {
2523
gl.check { shaderSource(shaderId, source) }
2624
gl.check { compileShader(shaderId) }
@@ -31,13 +29,6 @@ class CompiledShader(
3129
gl.runInContext {
3230
if (gl.check { getShaderParameter(shaderId, GL_COMPILE_STATUS) } != GL_TRUE) {
3331
val infoLog = gl.check { getShaderInfoLog(shaderId) }
34-
logger.warn {
35-
"Failed to compile shader: $infoLog\n" +
36-
"Version: \${gl.getParameter(GL_VERSION)}\n" +
37-
"GLSL Version: \${gl.getParameter(GL_SHADING_LANGUAGE_VERSION)}\n" +
38-
"\n" +
39-
source
40-
}
4132
throw CompilationException(infoLog ?: "huh?")
4233
}
4334
}

src/commonMain/kotlin/baaahs/glsl/Shaders.kt

+63
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,71 @@
11
package baaahs.glsl
22

33
import baaahs.glshaders.GlslAnalyzer
4+
import baaahs.show.Shader
5+
import baaahs.show.ShaderType
46

57
object Shaders {
8+
val smpteColorBars = Shader("SMTPE Color Bars", ShaderType.Paint, """
9+
// Robby Kraft
10+
// from https://www.shadertoy.com/view/XlGXRz
11+
12+
void mainImage( out vec4 fragColor, in vec2 fragCoord )
13+
{
14+
float br = 0.75; // a less popular SMPTE version uses 1.0
15+
16+
vec2 st = fragCoord.xy/iResolution.xy;
17+
18+
bool sev1 = bool( step(st.x, 1.0/7.0) );
19+
bool sev2 = bool( step(st.x, 2.0/7.0) );
20+
bool sev3 = bool( step(st.x, 3.0/7.0) );
21+
bool sev4 = bool( step(st.x, 4.0/7.0) );
22+
bool sev5 = bool( step(st.x, 5.0/7.0) );
23+
bool sev6 = bool( step(st.x, 6.0/7.0) );
24+
25+
bool row1 = !bool( step(st.y, 0.3333) );
26+
bool row2 = !bool( step(st.y, 0.25) );
27+
28+
/////////////////////////////////////////
29+
// R : 0.75 1.0 1.0 1.0
30+
// G : 0.75 1.0 1.0 1.0
31+
// B : 0.75 1.0 1.0 1.0
32+
/////////////////////////////////////////
33+
float top_red = br * float((sev6 && !sev4) || sev2 );
34+
float top_green = br * float(sev4);
35+
float top_blue = br * float(!sev6 || (sev5 && !sev4) || (sev3 && !sev2) || sev1 );
36+
37+
/////////////////////////////////////////
38+
// R : 1.0 0.75
39+
// G : 1.0 0.75
40+
// B : 1.0 1.0 1.0 0.75
41+
/////////////////////////////////////////
42+
float mid_red = 0.075*float( (sev6 && !sev5)||(sev4 && !sev3)||(sev2 && !sev1) ) + br * float(!sev6 || (sev3 && !sev2) );
43+
float mid_green = 0.075*float( (sev6 && !sev5)||(sev4 && !sev3)||(sev2 && !sev1) ) + br * float(!sev6 || (sev5 && !sev4) );
44+
float mid_blue = 0.075*float( (sev6 && !sev5)||(sev4 && !sev3)||(sev2 && !sev1) ) + br * float(!sev6 || (sev5 && !sev4) || (sev3 && !sev2) || sev1);
45+
46+
///////////////////////
47+
// R: 0.00 1.0 0.22
48+
// G: 0.24 1.0 0.00
49+
// B: 0.35 1.0 0.5
50+
///////////////////////
51+
bool fourth1 = bool( step(st.x, 1.0*(5.0/7.0)/4.0 ));
52+
bool fourth2 = bool( step(st.x, 2.0*(5.0/7.0)/4.0 ));
53+
bool fourth3 = bool( step(st.x, 3.0*(5.0/7.0)/4.0 ));
54+
bool fourth4 = bool( step(st.x, (5.0/7.0) ));
55+
56+
bool littleThird1 = bool( step(st.x, 5.0/7.0 + 1.0/7.0/3.0) );
57+
bool littleThird2 = bool( step(st.x, 5.0/7.0 + 1.0/7.0/3.0*2.0) );
58+
bool littleThird3 = bool( step(st.x, 5.0/7.0 + 1.0/7.0/3.0*3.0) );
59+
60+
float bottom_red = float(fourth2 && !fourth1) + 0.22*float(fourth3 && !fourth2) + 0.075*float(fourth4 && !fourth3) + 0.075*float(littleThird2 && !littleThird1) + 0.15*float(littleThird3 && !littleThird2) + 0.075*float(!sev6);
61+
float bottom_green = 0.24*float(fourth1) + float(fourth2 && !fourth1) + 0.075*float(fourth4 && !fourth3) + 0.075*float(littleThird2 && !littleThird1) + 0.15*float(littleThird3 && !littleThird2) + 0.075*float(!sev6);
62+
float bottom_blue = 0.35*float(fourth1) + float(fourth2 && !fourth1) + 0.5*float(fourth3 && !fourth2) + 0.075*float(fourth4 && !fourth3) + 0.075*float(littleThird2 && !littleThird1) + 0.15*float(littleThird3 && !littleThird2) + 0.075*float(!sev6);
63+
64+
fragColor = vec4(top_red*float(row1) + mid_red*float(row2 && !row1) + bottom_red*float(!row2),
65+
top_green*float(row1) + mid_green*float(row2 && !row1) + bottom_green*float(!row2),
66+
top_blue*float(row1) + mid_blue*float(row2 && !row1) + bottom_blue*float(!row2),1.);
67+
}
68+
""".trimIndent())
669

770
val cylindricalUvMapper = GlslAnalyzer().openShader(
871
/**language=glsl*/

src/commonMain/kotlin/baaahs/glsl/errors.kt

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ abstract class GlslException(message: String) : Exception(message) {
44
abstract val errors: List<GlslError>
55
}
66

7+
class LinkException(
8+
message: String, row: Int = -1
9+
) : GlslException("Shader link error: $message") {
10+
override val errors = listOf(GlslError(message, row))
11+
}
12+
713
class AnalysisException(
814
message: String, row: Int = -1
915
) : GlslException("Shader analysis error: $message") {

src/commonMain/kotlin/baaahs/show/FixtureShaders.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package baaahs.show
33
object FixtureShaders {
44
val fireBallGlsl = Shader(
55
"Fire Ball",
6-
ShaderType.Color,
6+
ShaderType.Paint,
77
"""
88
// Fire Ball
99
// From http://glslsandbox.com/e#61108.0

src/commonMain/kotlin/baaahs/show/PortRef.kt

+8-7
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,11 @@ interface ShaderPortRef {
2121
}
2222

2323
@Serializable @SerialName("shader-out")
24-
data class ShaderOutPortRef(val shaderInstanceId: String, val portId: String = ReturnValue) : PortRef() {
25-
fun isReturnValue() = portId == ReturnValue
24+
data class ShaderOutPortRef(val shaderInstanceId: String) : PortRef() {
2625

2726
override fun dereference(mutableShow: MutableShow): MutableLink.Port =
2827
MutableShaderOutPort(
29-
mutableShow.shaderInstances.getBang(
30-
shaderInstanceId,
31-
"shader instance"
32-
), portId
33-
)
28+
mutableShow.shaderInstances.getBang(shaderInstanceId, "shader instance"))
3429

3530
companion object {
3631
const val ReturnValue = "_"
@@ -48,3 +43,9 @@ data class OutputPortRef(val portId: String) : PortRef() {
4843
override fun dereference(mutableShow: MutableShow): MutableLink.Port =
4944
MutableOutputPort(portId)
5045
}
46+
47+
@Serializable @SerialName("const")
48+
data class ConstPortRef(val glsl: String) : PortRef() {
49+
override fun dereference(mutableShow: MutableShow): MutableLink.Port =
50+
MutableConstPort(glsl)
51+
}

src/commonMain/kotlin/baaahs/show/SampleData.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ object SampleData {
4545

4646
private val showDefaultPaint = autoWirer.autoWire(Shader(
4747
"Darkness",
48-
ShaderType.Color,
48+
ShaderType.Paint,
4949
/**language=glsl*/
5050
"""
5151
void main(void) {
@@ -64,7 +64,7 @@ object SampleData {
6464
6565
vec4 filterImage(vec4 inColor) {
6666
vec4 clampedColor = clamp(inColor, 0., 1.);
67-
return clampedColor * brightness;
67+
return vec4(clampedColor.rgb * brightness, clampedColor.a);
6868
}
6969
""".trimIndent()
7070
))
@@ -112,7 +112,7 @@ object SampleData {
112112

113113
private val redYellowGreenPatch = autoWirer.autoWire(Shader(
114114
"GLSL Hue Test Pattern",
115-
ShaderType.Color,
115+
ShaderType.Paint,
116116
/**language=glsl*/
117117
"""
118118
uniform vec2 resolution;
@@ -124,7 +124,7 @@ object SampleData {
124124

125125
private val blueAquaGreenPatch = autoWirer.autoWire(Shader(
126126
"Another GLSL Hue Test Pattern",
127-
ShaderType.Color,
127+
ShaderType.Paint,
128128
/**language=glsl*/
129129
"""
130130
uniform vec2 resolution;

src/commonMain/kotlin/baaahs/show/ShaderType.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ enum class ShaderType(
4747
}
4848
},
4949

50-
Color(0, mapOf(ContentType.UvCoordinate to ShaderChannel.Main), ContentType.Color, """
50+
Paint(0, mapOf(ContentType.UvCoordinate to ShaderChannel.Main), ContentType.Color, """
5151
uniform vec2 resolution;
5252
uniform float time;
5353

0 commit comments

Comments
 (0)