refactoring progress
This commit is contained in:
@@ -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
37
env.go
Normal 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
|
||||
}
|
||||
|
||||
|
||||
8
field.go
8
field.go
@@ -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)
|
||||
|
||||
@@ -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
67
main.go
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
121
sketch.go
121
sketch.go
@@ -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,46 +92,51 @@ 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),
|
||||
Height: -float32(ctx.SourceHeight),
|
||||
}
|
||||
dst := g.Rect {
|
||||
dst := g.Rect{
|
||||
X: 0, Y: 0,
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user