refactoring progress

This commit is contained in:
2026-01-08 11:54:35 -06:00
parent bbad63c60a
commit b3d9d0340a
7 changed files with 312 additions and 155 deletions

View File

@@ -4,6 +4,7 @@ import (
"github.com/gen2brain/raylib-go/raylib"
"math"
"math/rand"
sg "github.com/d2fn/sumi/internal/graphics"
)
type ContourLayer struct {
@@ -12,12 +13,12 @@ type ContourLayer struct {
maxActors uint32
actors []*Actor
actorIndex uint32
actorColor rl.Color
actorColor sg.Color
loActorAngle float32
hiActorAngle float32
}
func NewContourLayer(sketch *Sketch, rng *rand.Rand, field Field, color rl.Color, loActorAngle float32, hiActorAngle float32) *ContourLayer {
func NewContourLayer(sketch *Sketch, rng *rand.Rand, field Field, color sg.Color, loActorAngle float32, hiActorAngle float32) *ContourLayer {
maxActors := 200000
@@ -37,13 +38,13 @@ func NewContourLayer(sketch *Sketch, rng *rand.Rand, field Field, color rl.Color
return &layer
}
func (s *ContourLayer) AddActors(color rl.Color, n, sourceWidth, sourceHeight int32) {
func (s *ContourLayer) AddActors(color sg.Color, n, sourceWidth, sourceHeight int32) {
for range n {
x := s.rng.Int31() % sourceWidth
y := s.rng.Int31() % sourceHeight
newActor :=
&Actor{
position: rl.Vector2{X: float32(x), Y: float32(y)},
position: sg.Point { X: float32(x), Y: float32(y) },
field: s.field,
stepSize: 1,
color: s.actorColor,
@@ -55,18 +56,19 @@ func (s *ContourLayer) AddActors(color rl.Color, n, sourceWidth, sourceHeight in
}
}
func (s *ContourLayer) Update(ctx *RenderCtx) {
s.AddActors(s.actorColor, 100, ctx.SourceWidth, ctx.SourceHeight)
func (s *ContourLayer) Update(ctx *Env) {
s.AddActors(s.actorColor, 100, int32(ctx.Graphics.Layout.Graphics.Width), int32(ctx.Graphics.Layout.Graphics.Height))
}
func (s *ContourLayer) Draw(ctx *RenderCtx) {
rl.BeginBlendMode(rl.BlendAdditive)
func (s *ContourLayer) Draw(ctx *Env) {
g := ctx.Graphics
g.BeginAdditiveBlend()
for _, actor := range s.actors {
if actor != nil {
actor.Draw()
actor.Draw(ctx)
}
}
rl.EndBlendMode()
g.EndBlend()
}
func (s *ContourLayer) IsDirty() bool {
@@ -74,40 +76,43 @@ func (s *ContourLayer) IsDirty() bool {
}
type Actor struct {
position rl.Vector2
position sg.Point
field Field
stepSize float32
color rl.Color
color sg.Color
loAngle float32
hiAngle float32
}
func (a *Actor) Draw() {
func (a *Actor) Draw(ctx *Env) {
v := a.field.Get(a.position.X, a.position.Y)
rad := rl.Remap(v, 0, 1, a.loAngle, a.hiAngle)
nextPosition := rl.Vector2{X: a.position.X + a.stepSize*float32(math.Cos(float64(rad))), Y: a.position.Y + a.stepSize*float32(math.Sin(float64(rad)))}
rl.DrawLineV(a.position, nextPosition, a.color)
nextPosition := sg.Point {X: a.position.X + a.stepSize*float32(math.Cos(float64(rad))), Y: a.position.Y + a.stepSize*float32(math.Sin(float64(rad)))}
//nextPosition := rl.Vector2{X: a.position.X + a.stepSize*float32(math.Cos(float64(rad))), Y: a.position.Y + a.stepSize*float32(math.Sin(float64(rad)))}
g := ctx.Graphics
g.SetStrokeWeight(1.0)
g.SetStroke(true)
g.SetStrokeColor(a.color)
g.DrawLine(a.position, nextPosition)
//rl.DrawLineV(a.position, nextPosition, a.color)
a.position = nextPosition
}
func RandRadialVec(rng *rand.Rand, minRadius float32, maxRadius float32, loAngle float32, hiAngle float32) rl.Vector2 {
r := float64(rl.Remap(rng.Float32(), 0, 1, minRadius, maxRadius))
deg := float64(rl.Remap(rng.Float32(), 0, 1, loAngle, hiAngle))
rad := rl.Deg2rad * deg
return rl.Vector2{X: float32(r * math.Cos(rad)), Y: float32(r * math.Sin(rad))}
}
type Worm struct {
position rl.Vector2
position sg.Point
angles []float32
angleIndex int
stepSize int
renderPct float32
}
func (w *Worm) Draw(ctx *RenderCtx) {
rl.PushMatrix()
rl.Translatef(w.position.X, w.position.Y, 0)
func (w *Worm) Draw(ctx *Env) {
g := ctx.Graphics
g.PushMatrix()
g.Translate(w.position)
//rl.PushMatrix()
//rl.Translatef(w.position.X, w.position.Y, 0)
lastAngle := float32(0.0)
stepCount := 0
nudged := false
@@ -117,8 +122,8 @@ func (w *Worm) Draw(ctx *RenderCtx) {
deltaAngle := angle - lastAngle
if !nudged {
rad := float64(deltaAngle * math.Pi / 180.0)
nudge := rl.Vector2{X: float32(w.stepSize) * float32(math.Cos(rad)), Y: float32(w.stepSize) * float32(math.Sin(rad))}
w.position = rl.Vector2Add(w.position, nudge)
nudge := sg.Vec {X: float32(w.stepSize) * float32(math.Cos(rad)), Y: float32(w.stepSize) * float32(math.Sin(rad))}
w.position = w.position.Add(nudge)//rl.Vector2Add(w.position, nudge)
nudged = true
}
rl.Rotatef(deltaAngle, 0, 0, 1)
@@ -130,6 +135,6 @@ func (w *Worm) Draw(ctx *RenderCtx) {
break
}
}
rl.PopMatrix()
g.PopMatrix()
w.angleIndex = (w.angleIndex + 1) % len(w.angles)
}

37
env.go Normal file
View File

@@ -0,0 +1,37 @@
package main
import (
sg "github.com/d2fn/sumi/internal/graphics"
)
/** Env **/
type Env struct {
Layout Layout
Time float64
Ports map[string]float64
Graphics sg.Graphics
}
type Layout struct {
// total monitor bounds
Monitor sg.Rect
// bounds of the application window
Window sg.Rect
// bounds of the ui controls area
Controls sg.Rect
// bounds of the region of the app window reserved for rendering the graphics buffer
Viewport sg.Rect
// bounds of the off screen graphics buffer where rendering happens
Graphics sg.Rect
}
func (ctx *Env) GetGraphicsWidth() float32 {
return ctx.Graphics.Bounds.Width
}
func (ctx *Env) GetGraphicsHeight() float32 {
return ctx.Graphics.Bounds.Height
}

View File

@@ -101,15 +101,15 @@ type FieldLayer struct {
dirty bool
}
func (fl *FieldLayer) Update(ctx *RenderCtx) {
func (fl *FieldLayer) Update(env *Env) {
}
func (fl *FieldLayer) Draw(ctx *RenderCtx) {
func (fl *FieldLayer) Draw(env *Env) {
rl.ClearBackground(rl.Blank)
rl.BeginBlendMode(rl.BlendAlphaPremultiply)
for x := range ctx.SourceWidth {
for y := range ctx.SourceHeight {
for x := range int32(env.GetGraphicsHeight()) {
for y := range int32(env.GetGraphicsHeight()) {
v := fl.field.Get(float32(x), float32(y))
clr := LerpCurve(v, 1.3, fl.loColor, fl.hiColor)
rl.DrawPixel(x, y, clr)

View File

@@ -8,45 +8,152 @@ import (
)
type Graphics struct {
layout Layout
style Style
Style Style
Bounds Rect
}
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 Style struct {
StrokeColor, FillColor color.RGBA
StrokeWeight float32
Stroke, Fill bool
}
func (g *Graphics) GetGraphicsWidth() int32 {
return int32(g.Bounds.Width)
}
func (g *Graphics) GetGraphicsHeight() int32 {
return int32(g.Bounds.Height)
}
func (g *Graphics) PushStyle() {
}
func (g *Graphics) PopStyle() {
}
func (g *Graphics) SetStrokeColor(c Color) {
g.Style.StrokeColor = color.RGBA { R: c.R, G: c.G, B: c.B, A: c.A }
}
func (g *Graphics) SetFillColor(c Color) {
g.Style.FillColor = color.RGBA { R: c.R, G: c.G, B: c.B, A: c.A }
}
func (g *Graphics) SetStrokeWeight(w float32) {
g.Style.StrokeWeight = w
}
func (g *Graphics) SetStroke(b bool) {
g.Style.Stroke = b
}
func (g *Graphics) SetFill(b bool) {
g.Style.Fill = b
}
func (g *Graphics) PushMatrix() {
rl.PushMatrix()
}
func (g *Graphics) Translate(p Point) {
rl.Translatef(p.X, p.Y, 0)
}
func (g *Graphics) PopMatrix() {
rl.PopMatrix()
}
func (g *Graphics) BeginClip(r Rect) {
rlRect := r.ToRL()
rint := (&rlRect).ToInt32()
rl.BeginScissorMode(rint.X, rint.Y, rint.Width, rint.Height)
}
func (g *Graphics) EndClip() {
rl.EndScissorMode()
}
func (g *Graphics) BeginAdditiveBlend() {
rl.BeginBlendMode(rl.BlendAdditive)
}
func (g *Graphics) EndBlend() {
rl.EndBlendMode()
}
func (g *Graphics) BeginTexture(t rl.RenderTexture2D) {
rl.BeginTextureMode(t)
}
func (g *Graphics) EndTexture() {
rl.EndTextureMode()
}
func (g *Graphics) DrawRect(r Rect) {
if g.Style.Fill {
rl.DrawRectangleRec(r.ToRL(), g.Style.FillColor)
}
if g.Style.Stroke {
saveLineWidth := rl.GetLineWidth()
rl.SetLineWidth(g.Style.StrokeWeight)
rl.DrawRectangleLines(
int32(r.X), int32(r.Y),
int32(r.Width), int32(r.Height),
g.Style.StrokeColor,
)
rl.SetLineWidth(saveLineWidth)
}
}
func (g *Graphics) DrawLine(a, b Point) {
saveLineWidth := rl.GetLineWidth()
rl.SetLineWidth(g.Style.StrokeWeight)
rl.DrawLineV(a.ToRL(), b.ToRL(), g.Style.StrokeColor)
rl.SetLineWidth(saveLineWidth)
}
type Color color.RGBA
func RGBA(r, g, b, a uint8) Color {
return Color { R: r, G: g, B: b, A: a }
}
type HSBA struct {
H uint
S, B float32
A uint8
}
type Style struct {
StrokeColor Color
StrokeWeight float32
FillColor Color
type Point rl.Vector3
type Vec rl.Vector3
type Rect rl.Rectangle
func (p *Point) Add(v Vec) Point {
return Point { X: p.X + v.X, Y: p.Y + v.Y, Z: p.Z + v.Z }
}
type Rect rl.Rectangle
func (p Point) ToRL() rl.Vector2 {
return rl.Vector2 { X: p.X, Y: p.Y }
}
func (p Point) ToRL3() rl.Vector3 {
return rl.Vector3 { X: p.X, Y: p.Y, Z: p.Z }
}
/**
* 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) UL() Point {
return Point { X: r.X, Y: r.Y }
}
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 {

67
main.go
View File

@@ -9,7 +9,7 @@ import (
"os"
"time"
g "github.com/d2fn/sumi/internal/graphics"
sg "github.com/d2fn/sumi/internal/graphics"
"github.com/ojrac/opensimplex-go"
gui "github.com/gen2brain/raylib-go/raygui"
@@ -17,13 +17,14 @@ import (
//"github.com/ojrac/opensimplex-go"
)
func Bootstrap() sg.Graphics {
var (
snapshotsPath string
storage *Storage
)
func Bootstrap() g.Layout {
rl.InitWindow(800, 600, "bootstrap")
monitor := rl.GetCurrentMonitor()
@@ -74,12 +75,27 @@ func Bootstrap() g.Layout {
os.Exit(1)
}
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)},
layout := sg.Layout {
Monitor: sg.Rect{X: 0, Y: 0, Width: float32(monitorWidth), Height: float32(monitorHeight)},
Window: sg.Rect{X: 0, Y: 0, Width: float32(windowWidth), Height: float32(windowHeight)},
Controls: sg.Rect{X: 0, Y: 0, Width: float32(controlsWidth), Height: float32(windowHeight)},
Viewport: sg.Rect{X: float32(controlsWidth), Y: 0, Width: float32(viewportWidth), Height: float32(windowHeight)},
Graphics: sg.Rect{X: 0, Y: 0, Width: float32(graphicsWidth), Height: float32(graphicsHeight)},
}
//rl.SetConfigFlags(rl.FlagMsaa4xHint)
rl.InitWindow(int32(layout.Window.Width), int32(layout.Window.Height), "sumi sierpinski arrow")
rl.SetTargetFPS(60)
return sg.Graphics {
Layout: layout,
Style: sg.Style {
Fill: false,
FillColor: rl.RayWhite,
Stroke: true,
StrokeColor: rl.Black,
StrokeWeight: 1.0,
},
}
}
@@ -87,15 +103,11 @@ func main() {
log := log.New(os.Stdout, "", log.Ldate|log.Ltime|log.Lshortfile)
layout := Bootstrap()
//rl.SetConfigFlags(rl.FlagMsaa4xHint)
rl.InitWindow(int32(layout.Window.Width), int32(layout.Window.Height), "sumi sierpinski arrow")
g := Bootstrap()
// reproducable flourescent color cycle
colorCycle := g.NewFixedColorCycle(g.FlourescentColors).Shuffle(0)
colorCycle := sg.NewFixedColorCycle(sg.FlourescentColors).Shuffle(0)
rl.SetTargetFPS(60)
t0 := time.Now()
rng := rand.New(rand.NewSource(0))
@@ -108,8 +120,8 @@ func main() {
//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),
x: -float32(g.Layout.Graphics.Width / 2.0),
y: -float32(g.Layout.Graphics.Height / 2.0),
field: &ScaleField{
scale: 100.0,
field: &AdderField{
@@ -123,7 +135,7 @@ func main() {
//sierpinskiLayer := &SierpinskiArrow { dirty: true }
sketch := NewSketch(int32(layout.Graphics.Width), int32(layout.Graphics.Height))
sketch := NewSketch(&g)
fieldColor := colorCycle.Next()
fmt.Printf("field color = %v\n", fieldColor)
@@ -138,12 +150,14 @@ func main() {
hsv := rl.ColorToHSV(actorColor)
hsv.Z *= 0.7
actorColor = rl.ColorFromHSV(hsv.X, hsv.Y, hsv.Z)
actorColor = g.Clamp(actorColor, 10, 255)
actorColor = sg.Clamp(actorColor, 10, 255)
actorColor.A = 10
actorSGColor := sg.Color { R: actorColor.R, G: actorColor.G, B: actorColor.B, A: actorColor.A }
//NewColor(11, 35, 176, 50),
//r
contourLayer := NewContourLayer(&sketch, rng, field, actorColor, -25*math.Pi, 25*math.Pi)
contourLayer := NewContourLayer(&sketch, rng, field, actorSGColor, -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")
@@ -175,15 +189,13 @@ func main() {
t := time.Since(t0).Seconds()
// set up RenderCtx
renderCtx := &RenderCtx {
TargetBounds: layout.Viewport,
SourceWidth: int32(layout.Graphics.Width),
SourceHeight: int32(layout.Graphics.Height),
env := &Env {
Graphics: g,
Time: t,
Ports: ports.Eval(t),
}
sketch.Update(renderCtx)
sketch.Update(env)
/**
* MAIN DRAWING
@@ -191,7 +203,7 @@ func main() {
rl.BeginDrawing()
rl.ClearBackground(rl.GetColor(uint(gui.GetStyle(gui.DEFAULT, gui.BACKGROUND_COLOR))))
sketch.Draw(renderCtx)
sketch.Draw(env)
gui.SetStyle(gui.DEFAULT, gui.BACKGROUND_COLOR, 0x181818FF)
gui.SetStyle(gui.DEFAULT, gui.BASE_COLOR_NORMAL, 0x2A2A2AFF)
@@ -204,7 +216,7 @@ func main() {
y := float32(10)
minX := float32(60)
maxX := float32(layout.Controls.X + layout.Controls.Width - 20)
maxX := float32(g.Layout.Controls.X + g.Layout.Controls.Width - 20)
sliderWidth := maxX - minX - 20
controlRowHeight := 20
for _, layerTools := range sketch.layerToolsOrdered {
@@ -246,7 +258,6 @@ func main() {
*/
y += float32(controlRowHeight + 10)
}
rl.EndDrawing()

View File

@@ -8,13 +8,13 @@ type SierpinskiArrow struct {
dirty bool
}
func (s *SierpinskiArrow) Draw(ctx *RenderCtx) {
rl.Translatef(float32(ctx.SourceWidth)/2.0, float32(ctx.SourceHeight)/2.0, 0)
func (s *SierpinskiArrow) Draw(env *Env) {
rl.Translatef(float32(env.GetGraphicsWidth())/2.0, float32(env.GetGraphicsHeight())/2.0, 0)
rl.ClearBackground(rl.NewColor(0, 0, 0, 0))
sierpinskiArrow(ctx, int(ctx.Ports["sierpinskiArrowDepth"]), ctx.Ports["sierpinskiArrowLength"])
sierpinskiArrow(env, int(env.Ports["sierpinskiArrowDepth"]), env.Ports["sierpinskiArrowLength"])
}
func (s *SierpinskiArrow) Update(ctx *RenderCtx) {
func (s *SierpinskiArrow) Update(_ *Env) {
s.dirty = true
}
@@ -22,26 +22,26 @@ func (s *SierpinskiArrow) IsDirty() bool {
return s.dirty
}
func sierpinskiArrow(ctx *RenderCtx, order int, length float64) {
func sierpinskiArrow(env *Env, order int, length float64) {
if order == 0 {
curve(ctx, order, length, ctx.Ports["sierpinskiArrowAngle"])
curve(env, order, length, env.Ports["sierpinskiArrowAngle"])
} else {
rl.Rotatef(float32(ctx.Ports["sierpinskiArrowAngle"]), 0, 0, 1)
curve(ctx, order, length, -ctx.Ports["sierpinskiArrowAngle"])
rl.Rotatef(float32(env.Ports["sierpinskiArrowAngle"]), 0, 0, 1)
curve(env, order, length, -env.Ports["sierpinskiArrowAngle"])
}
}
func curve(ctx *RenderCtx, order int, length float64, angle float64) {
func curve(env *Env, order int, length float64, angle float64) {
if order == 0 {
len := int32(length)
rl.SetLineWidth(4)
rl.DrawLine(0, 0, len, 0, rl.RayWhite)
rl.Translatef(float32(length), 0, 0)
} else {
curve(ctx, order-1, length/2, -angle)
curve(env, order-1, length/2, -angle)
rl.Rotatef(float32(angle), 0, 0, 1)
curve(ctx, order-1, length/2, angle)
curve(env, order-1, length/2, angle)
rl.Rotatef(float32(angle), 0, 0, 1)
curve(ctx, order-1, length/2, -angle)
curve(env, order-1, length/2, -angle)
}
}

119
sketch.go
View File

@@ -2,14 +2,13 @@ package main
import (
"fmt"
g "github.com/d2fn/sumi/internal/graphics"
sg "github.com/d2fn/sumi/internal/graphics"
"github.com/gen2brain/raylib-go/raylib"
"math"
)
type Sketch struct {
sourceWidth int32
sourceHeight int32
graphics *sg.Graphics
cam *TextureCam
composite rl.RenderTexture2D
layerTools map[string]*LayerTools
@@ -21,15 +20,6 @@ type TextureCam struct {
Zoom float32
}
/** RenderCtx **/
type RenderCtx struct {
TargetBounds g.Rect
SourceWidth int32
SourceHeight int32
Time float64
Ports map[string]float64
}
type LayerTools struct {
name string
layer Layer
@@ -52,27 +42,26 @@ type LayerConfig struct {
kValue float32
}
func NewSketch(sourceWidth, sourceHeight int32) Sketch {
func NewSketch(g *sg.Graphics) 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},
LookAt: rl.Vector2{X: float32(g.Layout.Graphics.Width) / 2.0, Y: float32(g.Layout.Graphics.Height) / 2.0},
Zoom: 1.0,
}
return Sketch{
sourceWidth: sourceWidth,
sourceHeight: sourceHeight,
graphics: g,
layerTools: make(map[string]*LayerTools),
layerToolsOrdered: []*LayerTools{},
composite: rl.LoadRenderTexture(sourceWidth, sourceHeight),
composite: rl.LoadRenderTexture(int32(g.Layout.Graphics.Width), int32(g.Layout.Graphics.Height)),
cam: &camera,
}
}
func (s *Sketch) AddLayer(name string, layer Layer) {
texture := rl.LoadRenderTexture(s.sourceWidth, s.sourceHeight)
texture := rl.LoadRenderTexture(int32(s.graphics.Layout.Graphics.Width), int32(s.graphics.Layout.Graphics.Height))
config := NewLayerConfig()
layerTools :=
LayerTools{
@@ -93,7 +82,8 @@ func (s *Sketch) AddColorLayer(name string, c rl.Color) {
s.AddLayer(name, colorLayer)
}
func (s *Sketch) Redraw(ctx *RenderCtx) {
func (s *Sketch) Redraw(ctx *Env) {
g := ctx.Graphics
// render onto all layer textures
for _, instance := range s.layerToolsOrdered {
layer := instance.layer
@@ -102,21 +92,27 @@ func (s *Sketch) Redraw(ctx *RenderCtx) {
layer.Update(ctx)
// re-render to texture if dirty
if instance.layer.IsDirty() {
rl.BeginTextureMode(instance.texture)
rl.PushMatrix()
g.PushMatrix()
g.BeginTexture(instance.texture)
layer.Draw(ctx)
rl.PopMatrix()
rl.EndTextureMode()
g.PopMatrix()
g.EndTexture()
}
}
}
}
func (s *Sketch) Draw(ctx *RenderCtx) {
func (s *Sketch) Draw(ctx *Env) {
g := ctx.Graphics
s.Redraw(ctx)
// copy from full texture for compositing, with vertical flipping
src := g.Layout.Graphics
src.Height = -src.Height
dst := g.Layout.Graphics
/*
src := g.Rect {
X: 0, Y: 0,
Width: float32(ctx.SourceWidth),
@@ -127,21 +123,20 @@ func (s *Sketch) Draw(ctx *RenderCtx) {
Width: float32(ctx.SourceWidth),
Height: float32(ctx.SourceHeight),
}
*/
viewport := s.CalcViewport(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)
outputRect := g.Layout.Graphics.ScaleTo(g.Layout.Viewport)
fmt.Printf("outputRect = %v\n", outputRect)
x := float32(0)
y := float32(0)
w := outputRect.Width
h := outputRect.Height
rl.PushMatrix()
rl.Translatef(outputRect.X, outputRect.Y, 0)
rl.BeginScissorMode(int32(outputRect.X), int32(outputRect.Y), int32(outputRect.Width), int32(outputRect.Height))
g.PushMatrix()
g.Translate(outputRect.UL())
g.BeginClip(outputRect)
checkSize := float32(25.0)
grey := rl.NewColor(220, 220, 220, 255)
cellX := 0
@@ -161,8 +156,8 @@ func (s *Sketch) Draw(ctx *RenderCtx) {
y += checkSize
cellY++
}
rl.EndScissorMode()
rl.PopMatrix()
g.EndClip()
g.PopMatrix()
rl.BeginBlendMode(rl.BlendAlphaPremultiply)
//rl.BeginBlendMode(rl.BlendAlpha)
@@ -188,7 +183,7 @@ func (s *Sketch) Draw(ctx *RenderCtx) {
g = uint8(float32(g) * (float32(config.a) / 255.0))
b = uint8(float32(b) * (float32(config.a) / 255.0))
tint := rl.NewColor(r, g, b, config.a)
rl.DrawTexturePro(instance.texture.Texture, src, dst, rl.Vector2{}, 0, tint)
rl.DrawTexturePro(instance.texture.Texture, src.ToRL(), dst.ToRL(), rl.Vector2{}, 0, tint)
}
}
rl.EndTextureMode()
@@ -197,29 +192,30 @@ 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.ToRL(), rl.Vector2{}, 0, rl.White)
rl.DrawTexturePro(s.composite.Texture, viewport.ToRL(), outputRect.ToRL(), rl.Vector2{}, 0, rl.White)
outlineRect := outputRect.ToRL().ToInt32()
outputRectRL := outputRect.ToRL()
outlineRect := (&outputRectRL).ToInt32()
rl.DrawRectangleLines(outlineRect.X, outlineRect.Y, outlineRect.Width, outlineRect.Height, rl.Gray)
}
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),
func (s *Sketch) CalcViewport(ctx *Env) sg.Rect {
viewportWidth := rl.Clamp(float32(ctx.Graphics.Layout.Graphics.Width)/s.cam.Zoom, 0, float32(ctx.Graphics.Layout.Graphics.Width))
viewportHeight := rl.Clamp(float32(ctx.Graphics.Layout.Graphics.Height)/s.cam.Zoom, 0, float32(ctx.Graphics.Layout.Graphics.Height))
return sg.Rect{
X: rl.Clamp(s.cam.LookAt.X-viewportWidth/2.0, 0, float32(ctx.Graphics.Layout.Graphics.Width)-viewportWidth),
Y: rl.Clamp(s.cam.LookAt.Y-viewportHeight/2.0, 0, float32(ctx.Graphics.Layout.Graphics.Height)-viewportHeight),
Width: float32(viewportWidth),
Height: -float32(viewportHeight),
}
}
func (s *Sketch) Update(ctx *RenderCtx) {
func (s *Sketch) Update(ctx *Env) {
if rl.IsMouseButtonDown(rl.MouseRightButton) {
// get mouse delta from last frame
delta := rl.GetMouseDelta()
sourceScale := float32(ctx.SourceWidth) / float32(ctx.TargetBounds.Width)
sourceScale := float32(ctx.Graphics.Layout.Graphics.Width) / float32(ctx.Graphics.Layout.Viewport.Width)
// compute the amount to move scaled by the camera zoom
delta = rl.Vector2Scale(delta, -sourceScale/s.cam.Zoom)
delta.Y = -delta.Y
@@ -227,8 +223,8 @@ func (s *Sketch) Update(ctx *RenderCtx) {
}
// clamp LookAt to be somewhere on the texture
s.cam.LookAt.X = rl.Clamp(s.cam.LookAt.X, 0, float32(ctx.SourceWidth-1))
s.cam.LookAt.Y = rl.Clamp(s.cam.LookAt.Y, 0, float32(ctx.SourceHeight-1))
s.cam.LookAt.X = rl.Clamp(s.cam.LookAt.X, 0, float32(ctx.Graphics.Layout.Graphics.Width))
s.cam.LookAt.Y = rl.Clamp(s.cam.LookAt.Y, 0, float32(ctx.Graphics.Layout.Graphics.Height))
// Zoom based on mouse wheel
wheel := rl.GetMouseWheelMove()
@@ -246,12 +242,12 @@ func (s *Sketch) Update(ctx *RenderCtx) {
}
func (s *Sketch) ResetCamera() {
s.cam.LookAt = rl.Vector2{X: float32(s.sourceWidth) / 2.0, Y: float32(s.sourceHeight) / 2.0}
s.cam.LookAt = rl.Vector2{X: float32(s.graphics.Layout.Graphics.Width) / 2.0, Y: float32(s.graphics.Layout.Graphics.Height) / 2.0}
s.cam.Zoom = 1.0
}
type SketchCapture struct {
width, height uint32
width, height int32
compositeImage *rl.Image
layerTools map[string]*LayerTools
layerToolsOrdered []*LayerTools
@@ -265,7 +261,8 @@ func (s *Sketch) Capture() *SketchCapture {
rl.ImageFlipVertical(layerTool.capture)
}
return &SketchCapture{
width: uint32(s.sourceWidth), height: uint32(s.sourceHeight),
width: s.graphics.GetGraphicsWidth(),
height: s.graphics.GetGraphicsHeight(),
compositeImage: composite,
layerTools: s.layerTools,
layerToolsOrdered: s.layerToolsOrdered,
@@ -290,8 +287,8 @@ func NewLayerConfig() LayerConfig {
/** Layer **/
type Layer interface {
Update(ctx *RenderCtx)
Draw(ctx *RenderCtx)
Update(ctx *Env)
Draw(ctx *Env)
IsDirty() bool
}
@@ -300,11 +297,11 @@ type ColorLayer struct {
dirty bool
}
func (cl *ColorLayer) Update(ctx *RenderCtx) {
func (cl *ColorLayer) Update(ctx *Env) {
}
func (cl *ColorLayer) Draw(ctx *RenderCtx) {
func (cl *ColorLayer) Draw(ctx *Env) {
rl.ClearBackground(cl.color)
cl.dirty = false
}
@@ -327,12 +324,12 @@ func NewImageLayer(path string) *ImageLayer {
}
}
func (il *ImageLayer) Update(ctx *RenderCtx) {
func (il *ImageLayer) Update(ctx *Env) {
}
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)
func (il *ImageLayer) Draw(ctx *Env) {
rl.Translatef(float32(ctx.GetGraphicsWidth())/2.0-float32(il.texture.Width)/2.0, float32(ctx.GetGraphicsHeight())/2.0-float32(il.texture.Height)/2.0, 0)
rl.DrawTexture(il.texture, 0, 0, rl.White)
}
@@ -344,22 +341,22 @@ type TestPattern struct {
dirty bool
}
func (tp *TestPattern) Update(ctx *RenderCtx) {
func (tp *TestPattern) Update(ctx *Env) {
}
func (tp *TestPattern) Draw(ctx *RenderCtx) {
func (tp *TestPattern) Draw(ctx *Env) {
rl.ClearBackground(rl.Black)
centerX := float32(ctx.SourceWidth) / 2
centerY := float32(ctx.SourceHeight) / 2
centerX := float32(ctx.GetGraphicsWidth()) / 2
centerY := float32(ctx.GetGraphicsHeight()) / 2
rl.DrawRectangleRec(*g.Rect{X: 0, Y: 0, Width: centerX, Height: centerY}.ToRL(), rl.Red)
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)
rl.DrawLine(0, 0, ctx.Graphics.GetGraphicsWidth(), ctx.Graphics.GetGraphicsHeight(), rl.Black)
rl.PushMatrix()
rl.Translatef(centerX, centerY, 0)