package main import ( "fmt" sg "github.com/d2fn/sumi/internal/graphics" rl "github.com/gen2brain/raylib-go/raylib" "github.com/ojrac/opensimplex-go" "math" ) type Field interface { /** * return a value on the range 0,1 */ Get(x float32, y float32) float32 } // TRANSFORM FIELDS type ScaleField struct { field Field scale float32 } func (f *ScaleField) Get(x, y float32) float32 { return f.field.Get(x/f.scale, y/f.scale) } type TranslateField struct { field Field x, y float32 } func (f TranslateField) Get(x float32, y float32) float32 { return f.field.Get(x+f.x, y+f.y) } // NOISE FIELDS type SimplexNoiseField struct { Noise opensimplex.Noise32 } func (f *SimplexNoiseField) Get(x, y float32) float32 { return f.Noise.Eval2(x, y) } // IMAGE FIELDS type ImageField struct { image *rl.Image pixels ImagePixels offsetX, offsetY int } type ImagePixels struct { w, h int colors []rl.Color } func (p *ImagePixels) Get(x, y int) rl.Color { if x < 0 || x >= p.w { return rl.Black } if y < 0 || y >= p.h { return rl.Black } return p.colors[x+y*p.w] } func NewImageField(path string) *ImageField { image := rl.LoadImage(path) fmt.Printf("loaded image from %s\n", path) colors := rl.LoadImageColors(image) pixels := ImagePixels{ w: int(image.Width), h: int(image.Height), colors: colors, } offsetX := int(image.Width) / 2 offsetY := int(image.Height) / 2 return &ImageField{ image: image, pixels: pixels, offsetX: offsetX, offsetY: offsetY, } } // zero centered func (f *ImageField) Get(x, y float32) float32 { // todo : blend colors c := f.pixels.Get(int(x+float32(f.offsetX)), int(y+float32(f.offsetY))) return Brightness(c) } /** LAYER HELPERS **/ type FieldLayer struct { field Field loColor rl.Color hiColor rl.Color dirty bool } func (fl *FieldLayer) Update(env *Env, g *sg.Graphics) { } func (fl *FieldLayer) Draw(env *Env, g *sg.Graphics) { g.Clear() g.BeginAdditiveBlend() //rl.ClearBackground(rl.Blank) //rl.BeginBlendMode(rl.BlendAlphaPremultiply) for x := range g.WidthInt32() { for y := range g.HeightInt32() { v := fl.field.Get(float32(x), float32(y)) clr := LerpCurve(v, 1.3, fl.loColor, fl.hiColor) rl.DrawPixel(x, y, clr) } } rl.EndBlendMode() fl.dirty = false } func (fl *FieldLayer) IsDirty() bool { return fl.dirty } type AdderField struct { fields []Field } func (f *AdderField) Get(x, y float32) float32 { var z float32 = 0.0 for _, field := range f.fields { z += rl.Clamp(field.Get(x, y), 0.0, 1.0) / float32(len(f.fields)) } return z } 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))) //return float32(math.Sin(float64(x * y))) }