From f37bdf0604184419cbf710fa3669f8f23fd8148e Mon Sep 17 00:00:00 2001 From: sumi Date: Tue, 23 Dec 2025 00:30:13 -0600 Subject: [PATCH] automated snapshot --- contour_layer.go | 12 ++--- field.go | 6 +-- main.go | 67 ++++++++---------------- shaders/saturation.fs | 21 ++++++++ sketch.go | 118 +++++++++++++++++++++++------------------- 5 files changed, 117 insertions(+), 107 deletions(-) create mode 100644 shaders/saturation.fs diff --git a/contour_layer.go b/contour_layer.go index 1c6ca83..1bd0ffb 100644 --- a/contour_layer.go +++ b/contour_layer.go @@ -7,24 +7,24 @@ import ( ) type ContourLayer struct { - field Field - actors []*Actor - rng *rand.Rand + field Field + actors []*Actor + rng *rand.Rand } -func NewContourLayer(sketch *Sketch, rng *rand.Rand, field Field) ContourLayer { +func NewContourLayer(sketch *Sketch, rng *rand.Rand, field Field) *ContourLayer { actors := make([]*Actor, 0) layer := ContourLayer { rng: rng, field: field, - actors: actors, + actors: actors, } layer.AddActors(1, sketch.sourceWidth, sketch.sourceHeight) - return layer + return &layer } func (s *ContourLayer) AddActors(n, sourceWidth, sourceHeight int32) { diff --git a/field.go b/field.go index 68f1406..cf921e7 100644 --- a/field.go +++ b/field.go @@ -28,7 +28,7 @@ type TranslateField struct { x, y float32 } -func (f *TranslateField) Get(x, y float32) float32 { +func (f TranslateField) Get(x float32, y float32) float32 { return f.field.Get(x+f.x, y+f.y) } @@ -65,7 +65,7 @@ func (p *ImagePixels) Get(x, y int) rl.Color { return p.colors[x+y*p.w] } -func NewImageField(path string) ImageField { +func NewImageField(path string) *ImageField { image := rl.LoadImage(path) fmt.Printf("loaded image from %s\n", path) colors := rl.LoadImageColors(image) @@ -76,7 +76,7 @@ func NewImageField(path string) ImageField { } offsetX := int(image.Width)/2 offsetY := int(image.Height)/2 - return ImageField{ + return &ImageField { image: image, pixels: pixels, offsetX: offsetX, diff --git a/main.go b/main.go index c65488c..71402c4 100644 --- a/main.go +++ b/main.go @@ -42,51 +42,31 @@ func main() { BlendModeToggleGroupActive := int32(0) - Slider003Value := float32(0.0) - - RTogglePressed := false - GTogglePressed := false - BTogglePressed := false - - Slider008Value := float32(0.0) - Slider009Value := float32(0.0) - Slider010Value := float32(0.0) - - ATogglePressed := false - SaturationTogglePressed := false - - SaturationSliderValue := float32(0.0) - KSliderValue := float32(0.0) - KTogglePressed := false - // end layout vars - rl.SetTargetFPS(60) t0 := time.Now() /* */ + rng := rand.New(rand.NewSource(0)) imageField := NewImageField("/home/d/Dropbox/art/passage/data/david.png") - field := - TranslateField{ + &TranslateField { x: -float32(sourceWidth / 2.0), y: -float32(sourceHeight / 2.0), field: &ScaleField{ scale: 4.0, - field: &imageField, + field: imageField, }, } - rng := rand.New(rand.NewSource(0)) - sketch := NewSketch(sourceWidth, sourceHeight) - contourLayer := NewContourLayer(&sketch, rng, &field) + contourLayer := NewContourLayer(&sketch, rng, field) //sketch.CreateLayer("testPattern", &TestPattern{}, int32(sourceWidth), int32(sourceHeight)) //sketch.CreateLayer("actors", &contourLayer, int32(sourceWidth), int32(sourceHeight)) //sketch.CreateLayer("field", &FieldLayer{field: &field, dirty: true}, int32(sourceWidth), int32(sourceHeight)) - sketch.CreateLayer("contours", &contourLayer) + sketch.CreateLayer("contours", contourLayer) ports := MakePorts() ports["sierpinskiArrowAngle"] = Sine { @@ -156,34 +136,31 @@ func main() { gui.GroupBox(rl.Rectangle{X: 20, Y: 20, Width: controlPanelWidth - 50, Height: 60 }, "Blending") BlendModeToggleGroupActive = gui.ToggleGroup(rl.Rectangle{X: 30, Y: 40, Width: (controlPanelWidth - 70) / 3.0, Height: 24}, "ONE;TWO;THREE", BlendModeToggleGroupActive) - gui.Label(rl.Rectangle{X: 20, Y: 90, Width: 120, Height: 24}, "Contour Layer") + for _, layerTools := range sketch.layerToolsOrdered { - ATogglePressed = gui.LabelButton(rl.Rectangle{X: 40, Y: 136, Width: 16, Height: 16}, "A") - Slider003Value = gui.Slider(rl.Rectangle{X: 64, Y: 136, Width: 264, Height: 16}, "", "", Slider003Value, 0, 255) + config := layerTools.config - RTogglePressed = gui.LabelButton(rl.Rectangle{X: 40, Y: 160, Width: 16, Height: 16}, "R") - Slider008Value = gui.Slider(rl.Rectangle{X: 64, Y: 160, Width: 264, Height: 16}, "", "", Slider008Value, 0, 100) + gui.Label(rl.Rectangle{X: 20, Y: 90, Width: 120, Height: 24}, layerTools.name) - GTogglePressed = gui.LabelButton(rl.Rectangle{X: 40, Y: 184, Width: 16, Height: 16}, "G") - Slider009Value = gui.Slider(rl.Rectangle{X: 64, Y: 184, Width: 264, Height: 16}, "", "", Slider009Value, 0, 100) + config.visible = gui.Toggle(rl.Rectangle{X: 40, Y: 136, Width: 16, Height: 16}, "A", config.visible) + config.a = uint8(gui.Slider(rl.Rectangle{X: 64, Y: 136, Width: 264, Height: 16}, "", "", float32(config.a), 0, 255)) - BTogglePressed = gui.LabelButton(rl.Rectangle{X: 40, Y: 208, Width: 16, Height: 16}, "B") - Slider010Value = gui.Slider(rl.Rectangle{X: 64, Y: 208, Width: 264, Height: 16}, "", "", Slider010Value, 0, 100) + config.rVisible = gui.Toggle(rl.Rectangle{X: 40, Y: 160, Width: 16, Height: 16}, "R", config.rVisible) + config.r = uint8(gui.Slider(rl.Rectangle{X: 64, Y: 160, Width: 264, Height: 16}, "", "", float32(config.r), 0, 255)) - SaturationTogglePressed = gui.LabelButton(rl.Rectangle{X: 40, Y: 232, Width: 16, Height: 16}, "S") + config.gVisible = gui.Toggle(rl.Rectangle{X: 40, Y: 184, Width: 16, Height: 16}, "G", config.gVisible) + config.g = uint8(gui.Slider(rl.Rectangle{X: 64, Y: 184, Width: 264, Height: 16}, "", "", float32(config.g), 0, 255)) - gui.Slider(rl.Rectangle{X: 64, Y: 232, Width: 264, Height: 16}, "", "", SaturationSliderValue, 0, 100) - gui.Slider(rl.Rectangle{X: 64, Y: 256, Width: 264, Height: 16}, "", "", KSliderValue, 0, 100) + config.bVisible = gui.Toggle(rl.Rectangle{X: 40, Y: 208, Width: 16, Height: 16}, "B", config.bVisible) + config.b = uint8(gui.Slider(rl.Rectangle{X: 64, Y: 208, Width: 264, Height: 16}, "", "", float32(config.b), 0, 255)) - KTogglePressed = gui.LabelButton(rl.Rectangle{X: 40, Y: 256, Width: 16, Height: 16}, "K") + config.desaturate = !gui.Toggle(rl.Rectangle{X: 40, Y: 232, Width: 16, Height: 16}, "S", !config.desaturate) + config.saturation = gui.Slider(rl.Rectangle{X: 64, Y: 232, Width: 264, Height: 16}, "", "", config.saturation, 0, 100) - // NOTE: LabelButton returns "pressed this frame" bool, so these are edge-triggered. - _ = RTogglePressed - _ = GTogglePressed - _ = BTogglePressed - _ = ATogglePressed - _ = SaturationTogglePressed - _ = KTogglePressed + gui.Label(rl.Rectangle{X: 40, Y: 256, Width: 16, Height: 16}, "S") + config.kValue = gui.Slider(rl.Rectangle{X: 64, Y: 256, Width: 264, Height: 16}, "", "", config.kValue, 0, 2) + + } rl.EndDrawing() diff --git a/shaders/saturation.fs b/shaders/saturation.fs new file mode 100644 index 0000000..d604311 --- /dev/null +++ b/shaders/saturation.fs @@ -0,0 +1,21 @@ +#version 330 + +in vec2 fragTexCoord; +in vec4 fragColor; + +uniform sampler2D texture0; +uniform float uSat; // 0 = grayscale, 1 = original, >1 = boosted + +out vec4 finalColor; + +void main() { + vec4 c = texture(texture0, fragTexCoord) * fragColor; + + // luminance (perceptual-ish) + float l = dot(c.rgb, vec3(0.2126, 0.7152, 0.0722)); + vec3 gray = vec3(l); + + c.rgb = mix(gray, c.rgb, uSat); + finalColor = c; // preserves alpha +} + diff --git a/sketch.go b/sketch.go index a4c6e93..869bf06 100644 --- a/sketch.go +++ b/sketch.go @@ -9,9 +9,9 @@ type Sketch struct { sourceWidth int32 sourceHeight int32 cam *TextureCam - layerTools map[string]LayerTools - layerToolsOrdered []LayerTools composite rl.RenderTexture2D + layerTools map[string]*LayerTools + layerToolsOrdered []*LayerTools } type TextureCam struct { @@ -19,6 +19,35 @@ type TextureCam struct { Zoom float32 } +/** RenderCtx **/ +type RenderCtx struct { + TargetBounds rl.Rectangle + SourceWidth int32 + SourceHeight int32 + Time float64 + Ports map[string]float64 +} + +type LayerTools struct { + name string + layer Layer + texture rl.RenderTexture2D + config *LayerConfig +} + +type LayerConfig struct { + visible bool + a uint8 + rVisible bool + r uint8 + gVisible bool + g uint8 + bVisible bool + b uint8 + desaturate bool + saturation float32 + kValue float32 +} func NewSketch(sourceWidth, sourceHeight int32) Sketch { @@ -32,8 +61,8 @@ func NewSketch(sourceWidth, sourceHeight int32) Sketch { return Sketch { sourceWidth: sourceWidth, sourceHeight: sourceHeight, - layerTools: make(map[string]LayerTools), - layerToolsOrdered: []LayerTools {}, + layerTools: make(map[string]*LayerTools), + layerToolsOrdered: []*LayerTools {}, composite: rl.LoadRenderTexture(sourceWidth, sourceHeight), cam: &camera, } @@ -41,25 +70,30 @@ func NewSketch(sourceWidth, sourceHeight int32) Sketch { func (s *Sketch) CreateLayer(name string, layer Layer) { texture := rl.LoadRenderTexture(s.sourceWidth, s.sourceHeight) - layerTools := LayerTools { - name: name, - texture: &texture, - layer: layer, - config: NewLayerConfig(), - } - s.layerToolsOrdered = append(s.layerToolsOrdered, layerTools) - s.layerTools[name] = layerTools + rl.GenTextureMipmaps(&texture.Texture) + rl.SetTextureFilter(texture.Texture, rl.FilterTrilinear) + config := NewLayerConfig() + layerTools := + LayerTools { + name: name, + texture: texture, + layer: layer, + config: &config, + } + s.layerToolsOrdered = append(s.layerToolsOrdered, &layerTools) + s.layerTools[name] = &layerTools } func (s *Sketch) Draw(ctx *RenderCtx) { // render onto all layer textures for _, instance := range s.layerToolsOrdered { - instance.layer.Update(ctx) layer := instance.layer + layer.Update(ctx) if instance.layer.IsDirty() { - rl.BeginTextureMode(*instance.texture) + rl.BeginTextureMode(instance.texture) layer.Draw(ctx) rl.EndTextureMode() + rl.GenTextureMipmaps(&instance.texture.Texture) } } @@ -84,7 +118,23 @@ func (s *Sketch) Draw(ctx *RenderCtx) { rl.BeginTextureMode(s.composite) rl.ClearBackground(rl.Black) for _, instance := range s.layerToolsOrdered { - rl.DrawTexturePro(instance.texture.Texture, src, dst, rl.Vector2{}, 0, rl.White) + config := instance.config + if config.visible { + var r uint8 + if config.rVisible { + r = config.r + } + var g uint8 + if config.gVisible { + g = config.g + } + var b uint8 + if config.bVisible { + b = config.b + } + tint := rl.NewColor(r, g, b, config.a) + rl.DrawTexturePro(instance.texture.Texture, src, dst, rl.Vector2{}, 0, tint) + } } rl.EndTextureMode() @@ -191,12 +241,6 @@ func (s *Sketch) Capture() *SketchCapture { } -type LayerTools struct { - name string - layer Layer - texture *rl.RenderTexture2D - config LayerConfig -} func NewLayerConfig() LayerConfig { return LayerConfig { @@ -213,28 +257,6 @@ func NewLayerConfig() LayerConfig { } } -type LayerConfig struct { - - visible bool - a uint8 - - rVisible bool - r uint8 - - gVisible bool - g uint8 - - - bVisible bool - b uint8 - - - desaturate bool - saturation float32 - - kValue float32 -} - /** Layer **/ type Layer interface { @@ -297,13 +319,3 @@ func (p Ports) Eval(t float64) map[string]float64 { } return out } - -/** RenderCtx **/ - -type RenderCtx struct { - TargetBounds rl.Rectangle - SourceWidth int32 - SourceHeight int32 - Time float64 - Ports map[string]float64 -}