progress using my own graphics interface

This commit is contained in:
2026-01-06 00:35:24 -06:00
parent 59a2f08349
commit bbad63c60a
7 changed files with 230 additions and 195 deletions

177
sketch.go
View File

@@ -1,27 +1,29 @@
package main
import (
"math"
"fmt"
g "github.com/d2fn/sumi/internal/graphics"
"github.com/gen2brain/raylib-go/raylib"
"math"
)
type Sketch struct {
sourceWidth int32
sourceHeight int32
cam *TextureCam
composite rl.RenderTexture2D
layerTools map[string]*LayerTools
sourceWidth int32
sourceHeight int32
cam *TextureCam
composite rl.RenderTexture2D
layerTools map[string]*LayerTools
layerToolsOrdered []*LayerTools
}
type TextureCam struct {
LookAt rl.Vector2
Zoom float32
LookAt rl.Vector2
Zoom float32
}
/** RenderCtx **/
type RenderCtx struct {
TargetBounds rl.RectangleInt32
TargetBounds g.Rect
SourceWidth int32
SourceHeight int32
Time float64
@@ -37,35 +39,35 @@ type LayerTools struct {
}
type LayerConfig struct {
visible bool
a uint8
rVisible bool
r uint8
gVisible bool
g uint8
bVisible bool
b uint8
visible bool
a uint8
rVisible bool
r uint8
gVisible bool
g uint8
bVisible bool
b uint8
desaturate bool
saturation float32
kValue float32
kValue float32
}
func NewSketch(sourceWidth, sourceHeight int32) 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},
Zoom: 1.0,
var camera = TextureCam{
LookAt: rl.Vector2{X: float32(sourceWidth) / 2.0, Y: float32(sourceHeight) / 2.0},
Zoom: 1.0,
}
return Sketch {
sourceWidth: sourceWidth,
sourceHeight: sourceHeight,
layerTools: make(map[string]*LayerTools),
layerToolsOrdered: []*LayerTools {},
composite: rl.LoadRenderTexture(sourceWidth, sourceHeight),
cam: &camera,
return Sketch{
sourceWidth: sourceWidth,
sourceHeight: sourceHeight,
layerTools: make(map[string]*LayerTools),
layerToolsOrdered: []*LayerTools{},
composite: rl.LoadRenderTexture(sourceWidth, sourceHeight),
cam: &camera,
}
}
@@ -73,7 +75,7 @@ func (s *Sketch) AddLayer(name string, layer Layer) {
texture := rl.LoadRenderTexture(s.sourceWidth, s.sourceHeight)
config := NewLayerConfig()
layerTools :=
LayerTools {
LayerTools{
name: name,
texture: texture,
layer: layer,
@@ -84,7 +86,7 @@ func (s *Sketch) AddLayer(name string, layer Layer) {
}
func (s *Sketch) AddColorLayer(name string, c rl.Color) {
colorLayer := &ColorLayer {
colorLayer := &ColorLayer{
color: c,
dirty: true,
}
@@ -115,19 +117,23 @@ func (s *Sketch) Draw(ctx *RenderCtx) {
s.Redraw(ctx)
// copy from full texture for compositing, with vertical flipping
src := rl.Rectangle {
src := g.Rect {
X: 0, Y: 0,
Width: float32(ctx.SourceWidth),
Width: float32(ctx.SourceWidth),
Height: -float32(ctx.SourceHeight),
}
dst := rl.Rectangle {
dst := g.Rect {
X: 0, Y: 0,
Width: float32(ctx.SourceWidth),
Width: float32(ctx.SourceWidth),
Height: float32(ctx.SourceHeight),
}
viewport := s.CalcViewport(ctx)
outputRect := s.calcOutputRectKeepingAspectRatio(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)
fmt.Printf("outputRect = %v\n", outputRect)
x := float32(0)
y := float32(0)
@@ -158,7 +164,6 @@ func (s *Sketch) Draw(ctx *RenderCtx) {
rl.EndScissorMode()
rl.PopMatrix()
rl.BeginBlendMode(rl.BlendAlphaPremultiply)
//rl.BeginBlendMode(rl.BlendAlpha)
rl.BeginTextureMode(s.composite)
@@ -192,48 +197,18 @@ 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, rl.Vector2{}, 0, rl.White)
rl.DrawTexturePro(s.composite.Texture, viewport, *outputRect.ToRL(), rl.Vector2{}, 0, rl.White)
outlineRect := outputRect.ToInt32()
outlineRect := outputRect.ToRL().ToInt32()
rl.DrawRectangleLines(outlineRect.X, outlineRect.Y, outlineRect.Width, outlineRect.Height, rl.Gray)
}
func (s *Sketch) calcOutputRectKeepingAspectRatio(ctx *RenderCtx) rl.Rectangle {
sourceAspect := float32(ctx.SourceWidth) / float32(ctx.SourceHeight)
targetAspect := float32(ctx.TargetBounds.Width) / float32(ctx.TargetBounds.Height)
outputWidth := ctx.TargetBounds.Width
outputHeight := ctx.TargetBounds.Height
if sourceAspect < targetAspect {
// source is relatively taller than the target
// so we set the output height to the target height
// and calculate the width based on source aspect and center
outputWidth = int32(float32(outputHeight) * sourceAspect)
} else {
// source is relatively wider than the target
// so we set the output width to the target width
// and calculate the height based on source aspect and center
outputHeight = int32(float32(outputWidth) / sourceAspect)
}
// output width and height are correct -- center within TargetBounds
x := ctx.TargetBounds.X + ctx.TargetBounds.Width / 2.0 - outputWidth / 2.0
y := ctx.TargetBounds.Y + ctx.TargetBounds.Height / 2.0 - outputHeight / 2.0
return rl.Rectangle{
X: float32(x), Y: float32(y),
Width: float32(outputWidth),
Height: float32(outputHeight),
}
}
func (s *Sketch) CalcViewport(ctx *RenderCtx) rl.Rectangle {
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 rl.Rectangle{
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 *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),
Width: float32(viewportWidth),
Height: -float32(viewportHeight),
}
@@ -260,9 +235,9 @@ func (s *Sketch) Update(ctx *RenderCtx) {
if wheel != 0 {
const zoomIncrement float32 = 0.20
if wheel > 0 {
s.cam.Zoom *= 1+zoomIncrement
s.cam.Zoom *= 1 + zoomIncrement
} else {
s.cam.Zoom *= 1-zoomIncrement
s.cam.Zoom *= 1 - zoomIncrement
}
}
@@ -276,9 +251,9 @@ func (s *Sketch) ResetCamera() {
}
type SketchCapture struct {
width, height uint32
compositeImage *rl.Image
layerTools map[string]*LayerTools
width, height uint32
compositeImage *rl.Image
layerTools map[string]*LayerTools
layerToolsOrdered []*LayerTools
}
@@ -289,26 +264,26 @@ func (s *Sketch) Capture() *SketchCapture {
layerTool.capture = rl.LoadImageFromTexture(layerTool.texture.Texture)
rl.ImageFlipVertical(layerTool.capture)
}
return &SketchCapture {
return &SketchCapture{
width: uint32(s.sourceWidth), height: uint32(s.sourceHeight),
compositeImage: composite,
layerTools: s.layerTools,
compositeImage: composite,
layerTools: s.layerTools,
layerToolsOrdered: s.layerToolsOrdered,
}
}
func NewLayerConfig() LayerConfig {
return LayerConfig {
visible: true,
a: 255,
rVisible: true,
r: 255,
gVisible: true,
g: 255,
bVisible: true,
b: 255,
return LayerConfig{
visible: true,
a: 255,
rVisible: true,
r: 255,
gVisible: true,
g: 255,
bVisible: true,
b: 255,
desaturate: false,
kValue: 1.0,
kValue: 1.0,
}
}
@@ -326,7 +301,7 @@ type ColorLayer struct {
}
func (cl *ColorLayer) Update(ctx *RenderCtx) {
;
}
func (cl *ColorLayer) Draw(ctx *RenderCtx) {
@@ -340,24 +315,24 @@ func (cl *ColorLayer) IsDirty() bool {
type ImageLayer struct {
texture rl.Texture2D
dirty bool
dirty bool
}
func NewImageLayer(path string) *ImageLayer {
image := rl.LoadImage(path)
tex := rl.LoadTextureFromImage(image)
return &ImageLayer {
return &ImageLayer{
texture: tex,
dirty: true,
dirty: true,
}
}
func (il *ImageLayer) Update(ctx *RenderCtx) {
;
}
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)
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)
rl.DrawTexture(il.texture, 0, 0, rl.White)
}
@@ -365,12 +340,12 @@ func (il *ImageLayer) IsDirty() bool {
return il.dirty
}
type TestPattern struct{
type TestPattern struct {
dirty bool
}
func (tp *TestPattern) Update(ctx *RenderCtx) {
;
}
func (tp *TestPattern) Draw(ctx *RenderCtx) {
@@ -379,7 +354,7 @@ func (tp *TestPattern) Draw(ctx *RenderCtx) {
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(*g.Rect{X: 0, Y: 0, Width: centerX, Height: centerY}.ToRL(), 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)