Files
sumi/field.go

144 lines
2.7 KiB
Go

package main
import (
"fmt"
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) {
}
func (fl *FieldLayer) Draw(env *Env) {
rl.ClearBackground(rl.Blank)
rl.BeginBlendMode(rl.BlendAlphaPremultiply)
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)
}
}
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)))
}