automated snapshot

This commit is contained in:
sumi
2025-12-23 00:30:13 -06:00
parent c29e08bb98
commit f37bdf0604
5 changed files with 117 additions and 107 deletions

View File

@@ -12,7 +12,7 @@ type ContourLayer struct {
rng *rand.Rand 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) actors := make([]*Actor, 0)
@@ -24,7 +24,7 @@ func NewContourLayer(sketch *Sketch, rng *rand.Rand, field Field) ContourLayer {
layer.AddActors(1, sketch.sourceWidth, sketch.sourceHeight) layer.AddActors(1, sketch.sourceWidth, sketch.sourceHeight)
return layer return &layer
} }
func (s *ContourLayer) AddActors(n, sourceWidth, sourceHeight int32) { func (s *ContourLayer) AddActors(n, sourceWidth, sourceHeight int32) {

View File

@@ -28,7 +28,7 @@ type TranslateField struct {
x, y float32 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) 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] return p.colors[x+y*p.w]
} }
func NewImageField(path string) ImageField { func NewImageField(path string) *ImageField {
image := rl.LoadImage(path) image := rl.LoadImage(path)
fmt.Printf("loaded image from %s\n", path) fmt.Printf("loaded image from %s\n", path)
colors := rl.LoadImageColors(image) colors := rl.LoadImageColors(image)
@@ -76,7 +76,7 @@ func NewImageField(path string) ImageField {
} }
offsetX := int(image.Width)/2 offsetX := int(image.Width)/2
offsetY := int(image.Height)/2 offsetY := int(image.Height)/2
return ImageField{ return &ImageField {
image: image, image: image,
pixels: pixels, pixels: pixels,
offsetX: offsetX, offsetX: offsetX,

67
main.go
View File

@@ -42,51 +42,31 @@ func main() {
BlendModeToggleGroupActive := int32(0) 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) rl.SetTargetFPS(60)
t0 := time.Now() t0 := time.Now()
/* /*
*/ */
rng := rand.New(rand.NewSource(0))
imageField := NewImageField("/home/d/Dropbox/art/passage/data/david.png") imageField := NewImageField("/home/d/Dropbox/art/passage/data/david.png")
field := field :=
TranslateField{ &TranslateField {
x: -float32(sourceWidth / 2.0), x: -float32(sourceWidth / 2.0),
y: -float32(sourceHeight / 2.0), y: -float32(sourceHeight / 2.0),
field: &ScaleField{ field: &ScaleField{
scale: 4.0, scale: 4.0,
field: &imageField, field: imageField,
}, },
} }
rng := rand.New(rand.NewSource(0))
sketch := NewSketch(sourceWidth, sourceHeight) sketch := NewSketch(sourceWidth, sourceHeight)
contourLayer := NewContourLayer(&sketch, rng, &field) contourLayer := NewContourLayer(&sketch, rng, field)
//sketch.CreateLayer("testPattern", &TestPattern{}, int32(sourceWidth), int32(sourceHeight)) //sketch.CreateLayer("testPattern", &TestPattern{}, int32(sourceWidth), int32(sourceHeight))
//sketch.CreateLayer("actors", &contourLayer, 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("field", &FieldLayer{field: &field, dirty: true}, int32(sourceWidth), int32(sourceHeight))
sketch.CreateLayer("contours", &contourLayer) sketch.CreateLayer("contours", contourLayer)
ports := MakePorts() ports := MakePorts()
ports["sierpinskiArrowAngle"] = Sine { ports["sierpinskiArrowAngle"] = Sine {
@@ -156,34 +136,31 @@ func main() {
gui.GroupBox(rl.Rectangle{X: 20, Y: 20, Width: controlPanelWidth - 50, Height: 60 }, "Blending") 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) 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") config := layerTools.config
Slider003Value = gui.Slider(rl.Rectangle{X: 64, Y: 136, Width: 264, Height: 16}, "", "", Slider003Value, 0, 255)
RTogglePressed = gui.LabelButton(rl.Rectangle{X: 40, Y: 160, Width: 16, Height: 16}, "R") gui.Label(rl.Rectangle{X: 20, Y: 90, Width: 120, Height: 24}, layerTools.name)
Slider008Value = gui.Slider(rl.Rectangle{X: 64, Y: 160, Width: 264, Height: 16}, "", "", Slider008Value, 0, 100)
GTogglePressed = gui.LabelButton(rl.Rectangle{X: 40, Y: 184, Width: 16, Height: 16}, "G") config.visible = gui.Toggle(rl.Rectangle{X: 40, Y: 136, Width: 16, Height: 16}, "A", config.visible)
Slider009Value = gui.Slider(rl.Rectangle{X: 64, Y: 184, Width: 264, Height: 16}, "", "", Slider009Value, 0, 100) 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") config.rVisible = gui.Toggle(rl.Rectangle{X: 40, Y: 160, Width: 16, Height: 16}, "R", config.rVisible)
Slider010Value = gui.Slider(rl.Rectangle{X: 64, Y: 208, Width: 264, Height: 16}, "", "", Slider010Value, 0, 100) 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) config.bVisible = gui.Toggle(rl.Rectangle{X: 40, Y: 208, Width: 16, Height: 16}, "B", config.bVisible)
gui.Slider(rl.Rectangle{X: 64, Y: 256, Width: 264, Height: 16}, "", "", KSliderValue, 0, 100) 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. gui.Label(rl.Rectangle{X: 40, Y: 256, Width: 16, Height: 16}, "S")
_ = RTogglePressed config.kValue = gui.Slider(rl.Rectangle{X: 64, Y: 256, Width: 264, Height: 16}, "", "", config.kValue, 0, 2)
_ = GTogglePressed
_ = BTogglePressed }
_ = ATogglePressed
_ = SaturationTogglePressed
_ = KTogglePressed
rl.EndDrawing() rl.EndDrawing()

21
shaders/saturation.fs Normal file
View File

@@ -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
}

112
sketch.go
View File

@@ -9,9 +9,9 @@ type Sketch struct {
sourceWidth int32 sourceWidth int32
sourceHeight int32 sourceHeight int32
cam *TextureCam cam *TextureCam
layerTools map[string]LayerTools
layerToolsOrdered []LayerTools
composite rl.RenderTexture2D composite rl.RenderTexture2D
layerTools map[string]*LayerTools
layerToolsOrdered []*LayerTools
} }
type TextureCam struct { type TextureCam struct {
@@ -19,6 +19,35 @@ type TextureCam struct {
Zoom float32 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 { func NewSketch(sourceWidth, sourceHeight int32) Sketch {
@@ -32,8 +61,8 @@ func NewSketch(sourceWidth, sourceHeight int32) Sketch {
return Sketch { return Sketch {
sourceWidth: sourceWidth, sourceWidth: sourceWidth,
sourceHeight: sourceHeight, sourceHeight: sourceHeight,
layerTools: make(map[string]LayerTools), layerTools: make(map[string]*LayerTools),
layerToolsOrdered: []LayerTools {}, layerToolsOrdered: []*LayerTools {},
composite: rl.LoadRenderTexture(sourceWidth, sourceHeight), composite: rl.LoadRenderTexture(sourceWidth, sourceHeight),
cam: &camera, cam: &camera,
} }
@@ -41,25 +70,30 @@ func NewSketch(sourceWidth, sourceHeight int32) Sketch {
func (s *Sketch) CreateLayer(name string, layer Layer) { func (s *Sketch) CreateLayer(name string, layer Layer) {
texture := rl.LoadRenderTexture(s.sourceWidth, s.sourceHeight) texture := rl.LoadRenderTexture(s.sourceWidth, s.sourceHeight)
layerTools := LayerTools { rl.GenTextureMipmaps(&texture.Texture)
rl.SetTextureFilter(texture.Texture, rl.FilterTrilinear)
config := NewLayerConfig()
layerTools :=
LayerTools {
name: name, name: name,
texture: &texture, texture: texture,
layer: layer, layer: layer,
config: NewLayerConfig(), config: &config,
} }
s.layerToolsOrdered = append(s.layerToolsOrdered, layerTools) s.layerToolsOrdered = append(s.layerToolsOrdered, &layerTools)
s.layerTools[name] = layerTools s.layerTools[name] = &layerTools
} }
func (s *Sketch) Draw(ctx *RenderCtx) { func (s *Sketch) Draw(ctx *RenderCtx) {
// render onto all layer textures // render onto all layer textures
for _, instance := range s.layerToolsOrdered { for _, instance := range s.layerToolsOrdered {
instance.layer.Update(ctx)
layer := instance.layer layer := instance.layer
layer.Update(ctx)
if instance.layer.IsDirty() { if instance.layer.IsDirty() {
rl.BeginTextureMode(*instance.texture) rl.BeginTextureMode(instance.texture)
layer.Draw(ctx) layer.Draw(ctx)
rl.EndTextureMode() rl.EndTextureMode()
rl.GenTextureMipmaps(&instance.texture.Texture)
} }
} }
@@ -84,7 +118,23 @@ func (s *Sketch) Draw(ctx *RenderCtx) {
rl.BeginTextureMode(s.composite) rl.BeginTextureMode(s.composite)
rl.ClearBackground(rl.Black) rl.ClearBackground(rl.Black)
for _, instance := range s.layerToolsOrdered { 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() 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 { func NewLayerConfig() LayerConfig {
return 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 **/ /** Layer **/
type Layer interface { type Layer interface {
@@ -297,13 +319,3 @@ func (p Ports) Eval(t float64) map[string]float64 {
} }
return out return out
} }
/** RenderCtx **/
type RenderCtx struct {
TargetBounds rl.Rectangle
SourceWidth int32
SourceHeight int32
Time float64
Ports map[string]float64
}