diff --git a/main.go b/main.go index 698d88d..e0fd15e 100644 --- a/main.go +++ b/main.go @@ -15,10 +15,17 @@ import ( const ( targetWidth = 800 targetHeight = 600 - sourceScale = 1 + sourceScale = 10 snapshotsDir = "snapshots" ) +type TextureCam struct { + SourceWidth int + SourceHeight int + LookAt rl.Vector2 + Zoom float32 +} + func main() { sourceWidth := sourceScale * targetWidth @@ -32,7 +39,7 @@ func main() { os.Exit(1) } - rl.SetConfigFlags(rl.FlagWindowHighdpi & rl.FlagMsaa4xHint) + rl.SetConfigFlags(rl.FlagMsaa4xHint) rl.InitWindow(targetWidth, targetHeight, "sumi sierpinski arrow") log.Printf("screen=%dx%d render=%dx%d", @@ -42,11 +49,11 @@ func main() { // point at source center // put source center at center of screen - var camera = rl.Camera2D { - Target: rl.Vector2{X: float32(targetWidth) / 2, Y: float32(targetHeight) / 2}, - Offset: rl.Vector2{}, - Zoom: 1.0, - Rotation: 0, + var camera = TextureCam { + LookAt: rl.Vector2 { X: float32(sourceWidth) / 2.0, Y: float32(sourceHeight) / 2.0 }, + Zoom: 1.0, + SourceWidth: sourceWidth, + SourceHeight: sourceHeight, } /* @@ -85,7 +92,6 @@ func main() { } for !rl.WindowShouldClose() { - updateCamera(&camera) // begin drawing t := time.Since(t0).Seconds() @@ -98,9 +104,11 @@ func main() { SourceHeight: int32(sourceHeight), Time: t, Ports: ports.Eval(t), - Cam: camera, + Cam: &camera, } + sketch.Update(renderCtx) + /** MAIN DRAWING **/ @@ -131,6 +139,7 @@ type FieldSketch struct { Field Field } +/* func (s *FieldSketch) Draw(ctx *RenderCtx) { fmt.Printf("drawing field") for x := range ctx.TargetWidth { @@ -143,6 +152,7 @@ func (s *FieldSketch) Draw(ctx *RenderCtx) { } } } +*/ type ContourLayer struct { field Field @@ -196,40 +206,6 @@ func RandRadialVec(rng *rand.Rand, minRadius float32, maxRadius float32, loAngle return rl.Vector2{X: float32(r * math.Cos(rad)), Y: float32(r * math.Sin(rad))} } -func updateCamera(camera *rl.Camera2D) { - // Get the world point that is under the mouse - mouseVec2 := rl.GetMousePosition() - - if rl.IsMouseButtonDown(rl.MouseRightButton) { - // get mouse delta from last frame - delta := rl.GetMouseDelta() - // compute the amount to move scaled by the camera zoom - delta = rl.Vector2Scale(delta, -1.0/camera.Zoom) - delta.Y = -delta.Y - camera.Target = rl.Vector2Add(camera.Target, delta) - } - // Zoom based on mouse wheel - wheel := rl.GetMouseWheelMove() - if wheel != 0 { - mouseWorldPos := rl.GetScreenToWorld2D(mouseVec2, *camera) - - // Set the offset to where the mouse is - camera.Offset = mouseVec2 - - // Set the target to match, so that the camera maps the world space point - // under the cursor to the screen space point under the cursor at any zoom - camera.Target = mouseWorldPos - - // Zoom increment - const zoomIncrement float32 = 0.125 - - camera.Zoom += (wheel * zoomIncrement) - if camera.Zoom < zoomIncrement { - camera.Zoom = zoomIncrement - } - } -} - type Worm struct { position rl.Vector2 angles []float32 diff --git a/sketch.go b/sketch.go index 906361f..f9d7420 100644 --- a/sketch.go +++ b/sketch.go @@ -1,7 +1,7 @@ package main import ( - "fmt" + "math" "github.com/gen2brain/raylib-go/raylib" ) @@ -10,36 +10,17 @@ type Sketch struct { } func NewSketch() Sketch { - return Sketch { + return Sketch{ layerTools: make(map[string]LayerTools), } } func (s *Sketch) CreateLayer(name string, layer Layer, sourceWidth int32, sourceHeight int32) { texture := rl.LoadRenderTexture(sourceWidth, sourceHeight) - s.layerTools[name] = LayerTools { - name: name, + s.layerTools[name] = LayerTools{ + name: name, texture: &texture, - layer: layer, - } -} - -func LayerViewRect(ctx *RenderCtx) rl.Rectangle { - - z := ctx.Cam.Zoom - - // get the viewport width in texture space - viewportWidth := float32(ctx.TargetWidth) / z - viewportHeight := float32(ctx.TargetHeight) / z - - x := rl.Clamp(ctx.Cam.Target.X - viewportWidth/2, 0, float32(ctx.SourceWidth) - viewportWidth/2.0) - y := rl.Clamp(ctx.Cam.Target.Y - viewportHeight/2, 0, float32(ctx.SourceHeight) - viewportHeight/2.0) - - return rl.Rectangle{ - X: x, - Y: y, - Width: viewportWidth, - Height: viewportHeight, + layer: layer, } } @@ -52,36 +33,68 @@ func (s *Sketch) Draw(ctx *RenderCtx) { layer.Draw(ctx) rl.EndTextureMode() } + // composite all layers to screen - //ClampCameraToLayer(ctx) - - //view := LayerViewRect(ctx) - src := rl.Rectangle { - X: 0, - Y: 0, - Width: float32(ctx.SourceWidth), - Height: -float32(ctx.SourceHeight), - } - - dst := rl.Rectangle { - X: 0, - Y: 0, - Width: float32(ctx.TargetWidth), + screen := rl.Rectangle { + X: 0, + Y: 0, + Width: float32(ctx.TargetWidth), Height: float32(ctx.TargetHeight), } - fmt.Printf("src = %v, dst %v\n", src, dst) + viewport := s.CalcViewport(ctx) for _, instance := range s.layerTools { - rl.DrawTexturePro(instance.texture.Texture, src, dst, rl.Vector2{}, 0, rl.White) + rl.DrawTexturePro(instance.texture.Texture, viewport, screen, rl.Vector2{}, 0, rl.White) } - + +} + +func (s *Sketch) CalcViewport(ctx *RenderCtx) rl.Rectangle { + viewportWidth := rl.Clamp(float32(ctx.SourceWidth) / ctx.Cam.Zoom, 0, float32(ctx.SourceWidth)) + viewportHeight := rl.Clamp(float32(ctx.SourceHeight) / ctx.Cam.Zoom, 0, float32(ctx.SourceHeight)) + return rl.Rectangle{ + X: rl.Clamp(ctx.Cam.LookAt.X - viewportWidth/2.0, 0, float32(ctx.SourceWidth)-viewportWidth), + Y: rl.Clamp(ctx.Cam.LookAt.Y - viewportHeight/2.0, 0, float32(ctx.SourceHeight)-viewportHeight), + Width: float32(viewportWidth), + Height: -float32(viewportHeight), + } +} + +func (s *Sketch) Update(ctx *RenderCtx) { + if rl.IsMouseButtonDown(rl.MouseRightButton) { + // get mouse delta from last frame + delta := rl.GetMouseDelta() + // compute the amount to move scaled by the camera zoom + delta = rl.Vector2Scale(delta, -sourceScale/ctx.Cam.Zoom) + delta.Y = -delta.Y + ctx.Cam.LookAt = rl.Vector2Add(ctx.Cam.LookAt, delta) + } + + // clamp LookAt to be somewhere on the texture + ctx.Cam.LookAt.X = rl.Clamp(ctx.Cam.LookAt.X, 0, float32(ctx.SourceWidth-1)) + ctx.Cam.LookAt.Y = rl.Clamp(ctx.Cam.LookAt.Y, 0, float32(ctx.SourceHeight-1)) + + // Zoom based on mouse wheel + wheel := rl.GetMouseWheelMove() + if wheel != 0 { + const zoomIncrement float32 = 0.05 + if wheel > 0 { + ctx.Cam.Zoom *= 1+zoomIncrement + } else { + ctx.Cam.Zoom *= 1-zoomIncrement + } + } + + // clamp zoom to > 1 so we don't ever zoom out more than necessary + ctx.Cam.Zoom = rl.Clamp(ctx.Cam.Zoom, 1, math.MaxInt64) + } type LayerTools struct { - name string - layer Layer + name string + layer Layer texture *rl.RenderTexture2D } @@ -91,7 +104,7 @@ type Layer interface { Draw(ctx *RenderCtx) } -type TestPattern struct { } +type TestPattern struct{} func DrawGrid(spacing int32, halfExtent int32) { col := rl.Color{R: 220, G: 220, B: 220, A: 255} @@ -107,13 +120,13 @@ func DrawGrid(spacing int32, halfExtent int32) { func (tp *TestPattern) Draw(ctx *RenderCtx) { rl.ClearBackground(rl.Black) - centerX := float32(ctx.SourceWidth)/2 - centerY := float32(ctx.SourceHeight)/2 + 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(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) + rl.DrawRectangleRec(rl.Rectangle{X: 0, Y: 0, Width: centerX, Height: centerY}, 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) rl.DrawLine(0, 0, ctx.SourceWidth, ctx.SourceHeight, rl.Black) @@ -126,7 +139,6 @@ func (tp *TestPattern) Draw(ctx *RenderCtx) { rl.PopMatrix() } - /** Ports **/ type Ports map[string]Signal @@ -151,9 +163,9 @@ func (p Ports) Eval(t float64) map[string]float64 { type RenderCtx struct { TargetWidth int32 TargetHeight int32 - SourceWidth int32 + SourceWidth int32 SourceHeight int32 - Time float64 - Ports map[string]float64 - Cam rl.Camera2D + Time float64 + Ports map[string]float64 + Cam *TextureCam }