diff --git a/contour_layer.go b/contour_layer.go index dec9f16..e4ae411 100644 --- a/contour_layer.go +++ b/contour_layer.go @@ -1,18 +1,18 @@ package main import ( + "github.com/gen2brain/raylib-go/raylib" "math" "math/rand" - "github.com/gen2brain/raylib-go/raylib" ) type ContourLayer struct { - field Field - rng *rand.Rand - maxActors uint32 - actors []*Actor - actorIndex uint32 - actorColor rl.Color + field Field + rng *rand.Rand + maxActors uint32 + actors []*Actor + actorIndex uint32 + actorColor rl.Color loActorAngle float32 hiActorAngle float32 } @@ -23,13 +23,13 @@ func NewContourLayer(sketch *Sketch, rng *rand.Rand, field Field, color rl.Color actors := make([]*Actor, maxActors) - layer := ContourLayer { - rng: rng, - field: field, - actors: actors, - maxActors: uint32(maxActors), - actorColor: color, - actorIndex: 0, + layer := ContourLayer{ + rng: rng, + field: field, + actors: actors, + maxActors: uint32(maxActors), + actorColor: color, + actorIndex: 0, loActorAngle: loActorAngle, hiActorAngle: hiActorAngle, } @@ -42,13 +42,13 @@ func (s *ContourLayer) AddActors(color rl.Color, n, sourceWidth, sourceHeight in x := s.rng.Int31() % sourceWidth y := s.rng.Int31() % sourceHeight newActor := - &Actor { + &Actor{ position: rl.Vector2{X: float32(x), Y: float32(y)}, field: s.field, stepSize: 1, color: s.actorColor, - loAngle: s.loActorAngle, - hiAngle: s.hiActorAngle, + loAngle: s.loActorAngle, + hiAngle: s.hiActorAngle, } s.actors[s.actorIndex] = newActor s.actorIndex = (s.actorIndex + 1) % s.maxActors @@ -133,4 +133,3 @@ func (w *Worm) Draw(ctx *RenderCtx) { rl.PopMatrix() w.angleIndex = (w.angleIndex + 1) % len(w.angles) } - diff --git a/field.go b/field.go index 74a142e..e1117db 100644 --- a/field.go +++ b/field.go @@ -2,9 +2,9 @@ package main import ( "fmt" - "math" rl "github.com/gen2brain/raylib-go/raylib" "github.com/ojrac/opensimplex-go" + "math" ) type Field interface { @@ -75,9 +75,9 @@ func NewImageField(path string) *ImageField { h: int(image.Height), colors: colors, } - offsetX := int(image.Width)/2 - offsetY := int(image.Height)/2 - return &ImageField { + offsetX := int(image.Width) / 2 + offsetY := int(image.Height) / 2 + return &ImageField{ image: image, pixels: pixels, offsetX: offsetX, @@ -92,18 +92,17 @@ func (f *ImageField) Get(x, y float32) float32 { return Brightness(c) } - /** LAYER HELPERS **/ type FieldLayer struct { - field Field + field Field loColor rl.Color hiColor rl.Color - dirty bool + dirty bool } func (fl *FieldLayer) Update(ctx *RenderCtx) { - ; + } func (fl *FieldLayer) Draw(ctx *RenderCtx) { @@ -136,7 +135,7 @@ func (f *AdderField) Get(x, y float32) float32 { return z } -type SinXYField struct {} +type SinXYField struct{} func (f *SinXYField) Get(x, y float32) float32 { return float32(0.5 + 0.5*math.Sin(float64(x))*math.Sin(float64(y))) diff --git a/internal/graphics/graphics.go b/internal/graphics/graphics.go index 1518fa5..d2a12d9 100644 --- a/internal/graphics/graphics.go +++ b/internal/graphics/graphics.go @@ -3,9 +3,83 @@ package graphics import ( "fmt" "math/rand" + "image/color" rl "github.com/gen2brain/raylib-go/raylib" ) +type Graphics struct { + layout Layout + style Style +} + +type Layout struct { + // total monitor bounds + Monitor Rect + // bounds of the application window + Window Rect + // bounds of the ui controls area + Controls Rect + // bounds of the region of the app window reserved for rendering the graphics buffer + Viewport Rect + // bounds of the off screen graphics buffer where rendering happens + Graphics Rect +} + +type Color color.RGBA + +type HSBA struct { + H uint + S, B float32 + A uint8 +} + +type Style struct { + StrokeColor Color + StrokeWeight float32 + FillColor Color +} + +type Rect rl.Rectangle + +/** + * scale the given rect down to the target rect + * maintaining the aspect ratio of the original rect + */ +func (r Rect) ToRL() *rl.Rectangle { + return &rl.Rectangle { X: r.X, Y: r.Y, Width: r.Width, Height: r.Height } +} + +func (r Rect) ScaleTo(tgt Rect) Rect { + + outputWidth := tgt.Width + outputHeight := tgt.Height + + aspect := r.Width / r.Height + tgtAspect := outputWidth / outputHeight + + if aspect < tgtAspect { + // source is relatively taller than the target + // so we set the output height to the target height + // and calculate the width based on source aspect and center + outputWidth = float32(outputHeight) * aspect + } else { + // source is relatively wider than the target + // so we set the output width to the target width + // and calculate the height based on source aspect and center + outputHeight = float32(outputWidth) / aspect + } + + // output width and height are correct -- center within TargetBounds + x := tgt.X + tgt.Width / 2.0 - outputWidth / 2.0 + y := tgt.Y + tgt.Height / 2.0 - outputHeight / 2.0 + + return Rect { + X: x, Y: y, + Width: outputWidth, + Height: outputHeight, + } +} + var ( FlourescentHues = []float32{ 0, // hot magenta-red diff --git a/main.go b/main.go index c0a0fe9..c26d6ad 100644 --- a/main.go +++ b/main.go @@ -19,18 +19,10 @@ import ( var ( snapshotsPath string - storage *Storage + storage *Storage ) -type Layout struct { - monitor rl.RectangleInt32 - window rl.RectangleInt32 - controls rl.RectangleInt32 - viewport rl.RectangleInt32 - graphics rl.RectangleInt32 -} - -func bootstrap() Layout { +func Bootstrap() g.Layout { rl.InitWindow(800, 600, "bootstrap") @@ -49,16 +41,16 @@ func bootstrap() Layout { // set controls to use 1/6th of the width controlsRelWidth := 1.0 / 12.0 - - defaultGraphicsWidth := 5*int((float64(defaultWindowWidth)*(1.0-controlsRelWidth))) - defaultGraphicsHeight := 5*defaultWindowHeight + + defaultGraphicsWidth := 5 * int((float64(defaultWindowWidth) * (1.0 - controlsRelWidth))) + defaultGraphicsHeight := 5 * defaultWindowHeight graphicsWidth := defaultGraphicsWidth graphicsHeight := defaultGraphicsHeight fmt.Printf("monitor : %d x %d / window : %d x %d / buffer : %d x %d", - monitorWidth, monitorHeight, - defaultWindowWidth, defaultWindowHeight, - defaultGraphicsWidth, defaultWindowHeight) + monitorWidth, monitorHeight, + defaultWindowWidth, defaultWindowHeight, + defaultGraphicsWidth, defaultWindowHeight) flag.StringVar(&snapshotsPath, "path", "snapshots", "Path to snapshots and db") flag.IntVar(&graphicsWidth, "gw", defaultGraphicsWidth, "Width of the internal graphics buffer. Can be much larger than the screen.") @@ -82,12 +74,12 @@ func bootstrap() Layout { os.Exit(1) } - return Layout { - monitor: rl.RectangleInt32{ X: 0, Y: 0, Width: int32(monitorWidth), Height: int32(monitorHeight) }, - window: rl.RectangleInt32{ X: 0, Y: 0, Width: int32(windowWidth), Height: int32(windowHeight) }, - controls: rl.RectangleInt32{ X: 0, Y: 0, Width: int32(controlsWidth), Height: int32(windowHeight) }, - viewport: rl.RectangleInt32{ X: int32(controlsWidth), Y: 0, Width: int32(viewportWidth), Height: int32(windowHeight) }, - graphics: rl.RectangleInt32{ X: 0, Y: 0, Width: int32(graphicsWidth), Height: int32(graphicsHeight) }, + return g.Layout { + Monitor: g.Rect{X: 0, Y: 0, Width: float32(monitorWidth), Height: float32(monitorHeight)}, + Window: g.Rect{X: 0, Y: 0, Width: float32(windowWidth), Height: float32(windowHeight)}, + Controls: g.Rect{X: 0, Y: 0, Width: float32(controlsWidth), Height: float32(windowHeight)}, + Viewport: g.Rect{X: float32(controlsWidth), Y: 0, Width: float32(viewportWidth), Height: float32(windowHeight)}, + Graphics: g.Rect{X: 0, Y: 0, Width: float32(graphicsWidth), Height: float32(graphicsHeight)}, } } @@ -95,10 +87,10 @@ func main() { log := log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile) - layout := bootstrap() + layout := Bootstrap() //rl.SetConfigFlags(rl.FlagMsaa4xHint) - rl.InitWindow(layout.window.Width, layout.window.Height, "sumi sierpinski arrow") + rl.InitWindow(int32(layout.Window.Width), int32(layout.Window.Height), "sumi sierpinski arrow") // reproducable flourescent color cycle colorCycle := g.NewFixedColorCycle(g.FlourescentColors).Shuffle(0) @@ -108,21 +100,21 @@ func main() { rng := rand.New(rand.NewSource(0)) //imageField := NewImageField("/home/d/Dropbox/art/data/david.png") - noiseField := &SimplexNoiseField { Noise: opensimplex.New32(0) } - sinXYField := &SinXYField { } + noiseField := &SimplexNoiseField{Noise: opensimplex.New32(0)} + sinXYField := &SinXYField{} //imageField := NewImageField("/home/d/Dropbox/art/data/ramstatue.png") //imageField := NewImageField("/home/d/Dropbox/art/data/bassrockastro/Photo Dec 24 2025, 5 58 23 PM.jpg") //imageField := NewImageField("/home/d/Dropbox/art/data/bassrockastro/andromeda.jpg") //imageField := NewImageField("/home/d/Dropbox/art/data/moses_statue.jpg") field := - &TranslateField { - x: -float32(layout.graphics.Width / 2.0), - y: -float32(layout.graphics.Height / 2.0), + &TranslateField{ + x: -float32(layout.Graphics.Width / 2.0), + y: -float32(layout.Graphics.Height / 2.0), field: &ScaleField{ scale: 100.0, - field: &AdderField { - fields: []Field { - &ScaleField { scale: 10,field: noiseField }, + field: &AdderField{ + fields: []Field{ + &ScaleField{scale: 10, field: noiseField}, sinXYField, }, }, @@ -131,12 +123,11 @@ func main() { //sierpinskiLayer := &SierpinskiArrow { dirty: true } - sketch := NewSketch(layout.graphics.Width, layout.graphics.Height) + sketch := NewSketch(int32(layout.Graphics.Width), int32(layout.Graphics.Height)) fieldColor := colorCycle.Next() fmt.Printf("field color = %v\n", fieldColor) - sketch.AddColorLayer("background-magenta", rl.Magenta) sketch.AddColorLayer("background-black", rl.Black) //sketch.AddLayer("field", &FieldLayer{field: field, loColor: rl.NewColor(0, 0, 0, 0), hiColor: fieldColor, dirty: true}) @@ -144,7 +135,7 @@ func main() { fmt.Printf("actor color = %v\n", actorColor) - hsv := rl.ColorToHSV(actorColor); + hsv := rl.ColorToHSV(actorColor) hsv.Z *= 0.7 actorColor = rl.ColorFromHSV(hsv.X, hsv.Y, hsv.Z) actorColor = g.Clamp(actorColor, 10, 255) @@ -155,40 +146,39 @@ func main() { contourLayer := NewContourLayer(&sketch, rng, field, actorColor, -25*math.Pi, 25*math.Pi) sketch.AddLayer("contours", contourLayer) //sketch.AddLayer("sierpinski-arrowhead", sierpinskiLayer) -// aurora := NewImageLayer("/home/d/Dropbox/photos/Events/2025/Aurora/Photo Nov 11 2025, 9 52 03 PM.jpg") -// sketch.AddLayer("aurora", aurora) -// cave := NewImageLayer("/home/d/Dropbox/photos/Events/2025/ Chelsea and James visit Lindell/Photo Nov 29 2025, 5 26 40 PM (29).jpg") -// sketch.AddLayer("cave", cave) + // aurora := NewImageLayer("/home/d/Dropbox/photos/Events/2025/Aurora/Photo Nov 11 2025, 9 52 03 PM.jpg") + // sketch.AddLayer("aurora", aurora) + // cave := NewImageLayer("/home/d/Dropbox/photos/Events/2025/ Chelsea and James visit Lindell/Photo Nov 29 2025, 5 26 40 PM (29).jpg") + // sketch.AddLayer("cave", cave) ports := MakePorts() ports["sierpinskiArrowAngle"] = - Sine { - Amp: 5, + Sine{ + Amp: 5, Freq: 0.1, Bias: 60, } ports["sierpinskiArrowDepth"] = - Const { + Const{ V: 6, } ports["sierpinskiArrowLength"] = - Const { + Const{ V: 8000, } - for !rl.WindowShouldClose() { // begin drawing t := time.Since(t0).Seconds() // set up RenderCtx - renderCtx := &RenderCtx{ - TargetBounds: layout.viewport, - SourceWidth: layout.graphics.Width, - SourceHeight: layout.graphics.Height, + renderCtx := &RenderCtx { + TargetBounds: layout.Viewport, + SourceWidth: int32(layout.Graphics.Width), + SourceHeight: int32(layout.Graphics.Height), Time: t, Ports: ports.Eval(t), } @@ -214,13 +204,15 @@ func main() { y := float32(10) minX := float32(60) - maxX := float32(layout.controls.X + layout.controls.Width - 20) + maxX := float32(layout.Controls.X + layout.Controls.Width - 20) sliderWidth := maxX - minX - 20 controlRowHeight := 20 for _, layerTools := range sketch.layerToolsOrdered { config := layerTools.config + //layerTools.texture.Texture + gui.Label(rl.Rectangle{X: minX, Y: y, Width: 120, Height: 24}, layerTools.name) y += float32(controlRowHeight + 10) @@ -243,15 +235,14 @@ func main() { config.bVisible = gui.Toggle(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "B", config.bVisible) config.b = uint8(gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", float32(config.b), 0, 255)) - /* - // don't do anything with saturation / k values yet - y += float32(controlRowHeight) - config.desaturate = !gui.Toggle(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "S", !config.desaturate) - config.saturation = gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", config.saturation, 0, 100) - y += float32(controlRowHeight) - gui.Label(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "K") - config.kValue = gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", config.kValue, 0, 2) + // don't do anything with saturation / k values yet + y += float32(controlRowHeight) + config.desaturate = !gui.Toggle(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "S", !config.desaturate) + config.saturation = gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", config.saturation, 0, 100) + y += float32(controlRowHeight) + gui.Label(rl.Rectangle{X: minX, Y: y, Width: 16, Height: 16}, "K") + config.kValue = gui.Slider(rl.Rectangle{X: minX + 20, Y: y, Width: sliderWidth, Height: 16}, "", "", config.kValue, 0, 2) */ y += float32(controlRowHeight + 10) @@ -284,4 +275,3 @@ func main() { rl.CloseWindow() } - diff --git a/sierpinski.go b/sierpinski.go index d0c2a29..8568425 100644 --- a/sierpinski.go +++ b/sierpinski.go @@ -4,12 +4,12 @@ import ( rl "github.com/gen2brain/raylib-go/raylib" ) -type SierpinskiArrow struct{ +type SierpinskiArrow struct { dirty bool } func (s *SierpinskiArrow) Draw(ctx *RenderCtx) { - rl.Translatef(float32(ctx.SourceWidth) / 2.0, float32(ctx.SourceHeight) / 2.0, 0) + rl.Translatef(float32(ctx.SourceWidth)/2.0, float32(ctx.SourceHeight)/2.0, 0) rl.ClearBackground(rl.NewColor(0, 0, 0, 0)) sierpinskiArrow(ctx, int(ctx.Ports["sierpinskiArrowDepth"]), ctx.Ports["sierpinskiArrowLength"]) } @@ -45,5 +45,3 @@ func curve(ctx *RenderCtx, order int, length float64, angle float64) { curve(ctx, order-1, length/2, -angle) } } - - diff --git a/sketch.go b/sketch.go index 40a8273..e86b9a0 100644 --- a/sketch.go +++ b/sketch.go @@ -1,27 +1,29 @@ package main import ( - "math" + "fmt" + g "github.com/d2fn/sumi/internal/graphics" "github.com/gen2brain/raylib-go/raylib" + "math" ) type Sketch struct { - sourceWidth int32 - sourceHeight int32 - cam *TextureCam - composite rl.RenderTexture2D - layerTools map[string]*LayerTools + sourceWidth int32 + sourceHeight int32 + cam *TextureCam + composite rl.RenderTexture2D + layerTools map[string]*LayerTools layerToolsOrdered []*LayerTools } type TextureCam struct { - LookAt rl.Vector2 - Zoom float32 + LookAt rl.Vector2 + Zoom float32 } /** RenderCtx **/ type RenderCtx struct { - TargetBounds rl.RectangleInt32 + TargetBounds g.Rect SourceWidth int32 SourceHeight int32 Time float64 @@ -37,35 +39,35 @@ type LayerTools struct { } type LayerConfig struct { - visible bool - a uint8 - rVisible bool - r uint8 - gVisible bool - g uint8 - bVisible bool - b uint8 + visible bool + a uint8 + rVisible bool + r uint8 + gVisible bool + g uint8 + bVisible bool + b uint8 desaturate bool saturation float32 - kValue float32 + kValue float32 } func NewSketch(sourceWidth, sourceHeight int32) Sketch { // point at source center // put source center at center of screen - var camera = TextureCam { - LookAt: rl.Vector2{X: float32(sourceWidth) / 2.0, Y: float32(sourceHeight) / 2.0}, - Zoom: 1.0, + var camera = TextureCam{ + LookAt: rl.Vector2{X: float32(sourceWidth) / 2.0, Y: float32(sourceHeight) / 2.0}, + Zoom: 1.0, } - return Sketch { - sourceWidth: sourceWidth, - sourceHeight: sourceHeight, - layerTools: make(map[string]*LayerTools), - layerToolsOrdered: []*LayerTools {}, - composite: rl.LoadRenderTexture(sourceWidth, sourceHeight), - cam: &camera, + return Sketch{ + sourceWidth: sourceWidth, + sourceHeight: sourceHeight, + layerTools: make(map[string]*LayerTools), + layerToolsOrdered: []*LayerTools{}, + composite: rl.LoadRenderTexture(sourceWidth, sourceHeight), + cam: &camera, } } @@ -73,7 +75,7 @@ func (s *Sketch) AddLayer(name string, layer Layer) { texture := rl.LoadRenderTexture(s.sourceWidth, s.sourceHeight) config := NewLayerConfig() layerTools := - LayerTools { + LayerTools{ name: name, texture: texture, layer: layer, @@ -84,7 +86,7 @@ func (s *Sketch) AddLayer(name string, layer Layer) { } func (s *Sketch) AddColorLayer(name string, c rl.Color) { - colorLayer := &ColorLayer { + colorLayer := &ColorLayer{ color: c, dirty: true, } @@ -115,19 +117,23 @@ func (s *Sketch) Draw(ctx *RenderCtx) { s.Redraw(ctx) // copy from full texture for compositing, with vertical flipping - src := rl.Rectangle { + src := g.Rect { X: 0, Y: 0, - Width: float32(ctx.SourceWidth), + Width: float32(ctx.SourceWidth), Height: -float32(ctx.SourceHeight), } - dst := rl.Rectangle { + dst := g.Rect { X: 0, Y: 0, - Width: float32(ctx.SourceWidth), + Width: float32(ctx.SourceWidth), Height: float32(ctx.SourceHeight), } viewport := s.CalcViewport(ctx) - outputRect := s.calcOutputRectKeepingAspectRatio(ctx) + + sourceRect := g.Rect{X: 0, Y: 0, Width: float32(ctx.SourceWidth), Height: float32(ctx.SourceHeight)} + targetRect := g.Rect{X: float32(ctx.TargetBounds.X), Y: float32(ctx.TargetBounds.Y), Width: float32(ctx.TargetBounds.Width), Height: float32(ctx.TargetBounds.Height)} + outputRect := sourceRect.ScaleTo(targetRect) + fmt.Printf("outputRect = %v\n", outputRect) x := float32(0) y := float32(0) @@ -158,7 +164,6 @@ func (s *Sketch) Draw(ctx *RenderCtx) { rl.EndScissorMode() rl.PopMatrix() - rl.BeginBlendMode(rl.BlendAlphaPremultiply) //rl.BeginBlendMode(rl.BlendAlpha) rl.BeginTextureMode(s.composite) @@ -192,48 +197,18 @@ func (s *Sketch) Draw(ctx *RenderCtx) { rl.GenTextureMipmaps(&s.composite.Texture) rl.SetTextureFilter(s.composite.Texture, rl.FilterTrilinear) - rl.DrawTexturePro(s.composite.Texture, viewport, outputRect, rl.Vector2{}, 0, rl.White) + rl.DrawTexturePro(s.composite.Texture, viewport, *outputRect.ToRL(), rl.Vector2{}, 0, rl.White) - outlineRect := outputRect.ToInt32() + outlineRect := outputRect.ToRL().ToInt32() rl.DrawRectangleLines(outlineRect.X, outlineRect.Y, outlineRect.Width, outlineRect.Height, rl.Gray) } -func (s *Sketch) calcOutputRectKeepingAspectRatio(ctx *RenderCtx) rl.Rectangle { - sourceAspect := float32(ctx.SourceWidth) / float32(ctx.SourceHeight) - targetAspect := float32(ctx.TargetBounds.Width) / float32(ctx.TargetBounds.Height) - - outputWidth := ctx.TargetBounds.Width - outputHeight := ctx.TargetBounds.Height - - if sourceAspect < targetAspect { - // source is relatively taller than the target - // so we set the output height to the target height - // and calculate the width based on source aspect and center - outputWidth = int32(float32(outputHeight) * sourceAspect) - } else { - // source is relatively wider than the target - // so we set the output width to the target width - // and calculate the height based on source aspect and center - outputHeight = int32(float32(outputWidth) / sourceAspect) - } - - // output width and height are correct -- center within TargetBounds - x := ctx.TargetBounds.X + ctx.TargetBounds.Width / 2.0 - outputWidth / 2.0 - y := ctx.TargetBounds.Y + ctx.TargetBounds.Height / 2.0 - outputHeight / 2.0 - - return rl.Rectangle{ - X: float32(x), Y: float32(y), - Width: float32(outputWidth), - Height: float32(outputHeight), - } -} - -func (s *Sketch) CalcViewport(ctx *RenderCtx) rl.Rectangle { - viewportWidth := rl.Clamp(float32(ctx.SourceWidth) / s.cam.Zoom, 0, float32(ctx.SourceWidth)) - viewportHeight := rl.Clamp(float32(ctx.SourceHeight) / s.cam.Zoom, 0, float32(ctx.SourceHeight)) - return rl.Rectangle{ - X: rl.Clamp(s.cam.LookAt.X - viewportWidth/2.0, 0, float32(ctx.SourceWidth)-viewportWidth), - Y: rl.Clamp(s.cam.LookAt.Y - viewportHeight/2.0, 0, float32(ctx.SourceHeight)-viewportHeight), +func (s *Sketch) CalcViewport(ctx *RenderCtx) g.Rect { + viewportWidth := rl.Clamp(float32(ctx.SourceWidth)/s.cam.Zoom, 0, float32(ctx.SourceWidth)) + viewportHeight := rl.Clamp(float32(ctx.SourceHeight)/s.cam.Zoom, 0, float32(ctx.SourceHeight)) + return g.Rect { + X: rl.Clamp(s.cam.LookAt.X-viewportWidth/2.0, 0, float32(ctx.SourceWidth)-viewportWidth), + Y: rl.Clamp(s.cam.LookAt.Y-viewportHeight/2.0, 0, float32(ctx.SourceHeight)-viewportHeight), Width: float32(viewportWidth), Height: -float32(viewportHeight), } @@ -260,9 +235,9 @@ func (s *Sketch) Update(ctx *RenderCtx) { if wheel != 0 { const zoomIncrement float32 = 0.20 if wheel > 0 { - s.cam.Zoom *= 1+zoomIncrement + s.cam.Zoom *= 1 + zoomIncrement } else { - s.cam.Zoom *= 1-zoomIncrement + s.cam.Zoom *= 1 - zoomIncrement } } @@ -276,9 +251,9 @@ func (s *Sketch) ResetCamera() { } type SketchCapture struct { - width, height uint32 - compositeImage *rl.Image - layerTools map[string]*LayerTools + width, height uint32 + compositeImage *rl.Image + layerTools map[string]*LayerTools layerToolsOrdered []*LayerTools } @@ -289,26 +264,26 @@ func (s *Sketch) Capture() *SketchCapture { layerTool.capture = rl.LoadImageFromTexture(layerTool.texture.Texture) rl.ImageFlipVertical(layerTool.capture) } - return &SketchCapture { + return &SketchCapture{ width: uint32(s.sourceWidth), height: uint32(s.sourceHeight), - compositeImage: composite, - layerTools: s.layerTools, + compositeImage: composite, + layerTools: s.layerTools, layerToolsOrdered: s.layerToolsOrdered, } } func NewLayerConfig() LayerConfig { - return LayerConfig { - visible: true, - a: 255, - rVisible: true, - r: 255, - gVisible: true, - g: 255, - bVisible: true, - b: 255, + return LayerConfig{ + visible: true, + a: 255, + rVisible: true, + r: 255, + gVisible: true, + g: 255, + bVisible: true, + b: 255, desaturate: false, - kValue: 1.0, + kValue: 1.0, } } @@ -326,7 +301,7 @@ type ColorLayer struct { } func (cl *ColorLayer) Update(ctx *RenderCtx) { - ; + } func (cl *ColorLayer) Draw(ctx *RenderCtx) { @@ -340,24 +315,24 @@ func (cl *ColorLayer) IsDirty() bool { type ImageLayer struct { texture rl.Texture2D - dirty bool + dirty bool } func NewImageLayer(path string) *ImageLayer { image := rl.LoadImage(path) tex := rl.LoadTextureFromImage(image) - return &ImageLayer { + return &ImageLayer{ texture: tex, - dirty: true, + dirty: true, } } func (il *ImageLayer) Update(ctx *RenderCtx) { - ; + } func (il *ImageLayer) Draw(ctx *RenderCtx) { - rl.Translatef(float32(ctx.SourceWidth) / 2.0 - float32(il.texture.Width) / 2.0, float32(ctx.SourceHeight) / 2.0 - float32(il.texture.Height) / 2.0, 0) + rl.Translatef(float32(ctx.SourceWidth)/2.0-float32(il.texture.Width)/2.0, float32(ctx.SourceHeight)/2.0-float32(il.texture.Height)/2.0, 0) rl.DrawTexture(il.texture, 0, 0, rl.White) } @@ -365,12 +340,12 @@ func (il *ImageLayer) IsDirty() bool { return il.dirty } -type TestPattern struct{ +type TestPattern struct { dirty bool } func (tp *TestPattern) Update(ctx *RenderCtx) { - ; + } func (tp *TestPattern) Draw(ctx *RenderCtx) { @@ -379,7 +354,7 @@ func (tp *TestPattern) Draw(ctx *RenderCtx) { centerX := float32(ctx.SourceWidth) / 2 centerY := float32(ctx.SourceHeight) / 2 - rl.DrawRectangleRec(rl.Rectangle{X: 0, Y: 0, Width: centerX, Height: centerY}, rl.Red) + rl.DrawRectangleRec(*g.Rect{X: 0, Y: 0, Width: centerX, Height: centerY}.ToRL(), rl.Red) rl.DrawRectangleRec(rl.Rectangle{X: centerX, Y: 0, Width: centerX, Height: centerY}, rl.Green) rl.DrawRectangleRec(rl.Rectangle{X: 0, Y: centerY, Width: centerX, Height: centerY}, rl.Blue) rl.DrawRectangleRec(rl.Rectangle{X: centerX, Y: centerY, Width: centerX, Height: centerY}, rl.White) diff --git a/storage.go b/storage.go index 711f81a..11f5274 100644 --- a/storage.go +++ b/storage.go @@ -132,14 +132,14 @@ func (s *Storage) Save(capture *SketchCapture) (string, error) { ii := len(capture.layerTools) - 1 - i oraLayers[ii] = ora.ORALayer{ - Name: layerTools.name, + Name: layerTools.name, Filename: filename, - Visible: layerTools.config.visible, - Opacity: opacity, - Blend: "svg:src-over", + Visible: layerTools.config.visible, + Opacity: opacity, + Blend: "svg:src-over", } } - + oraPath := filepath.Join(path, fmt.Sprintf("%s-layers.ora", flakeId)) ora.WriteORA(oraPath, int(capture.width), int(capture.height), oraLayers,