diff --git a/examples/image-text/text.go b/examples/image-text/text.go new file mode 100644 index 0000000..61c1d87 --- /dev/null +++ b/examples/image-text/text.go @@ -0,0 +1,97 @@ +package main + +import ( + "flag" + "fmt" + "image/color" + "log" + "runtime" + "time" + + "github.com/chewxy/math32" + "github.com/soypat/glgl/math/ms1" + "github.com/soypat/gsdf" + "github.com/soypat/gsdf/forge/textsdf" + "github.com/soypat/gsdf/glbuild" + "github.com/soypat/gsdf/gleval" + "github.com/soypat/gsdf/gsdfaux" +) + +const filename = "text.png" + +func init() { + runtime.LockOSThread() +} + +func scene(bld *gsdf.Builder) (glbuild.Shader2D, error) { + var f textsdf.Font + f.Configure(textsdf.FontConfig{ + RelativeGlyphTolerance: 0.001, + }) + err := f.LoadTTFBytes(textsdf.ISO3098TTF()) + if err != nil { + return nil, err + } + return f.TextLine("Abc123~") +} + +func main() { + useGPU := false + flag.BoolVar(&useGPU, "gpu", useGPU, "Enable GPU usage") + flag.Parse() + if useGPU { + term, err := gleval.Init1x1GLFW() + if err != nil { + log.Fatal(err) + } + defer term() + } + var bld gsdf.Builder + s, err := scene(&bld) + if err != nil { + log.Fatal(err) + } + var sdf2 gleval.SDF2 + if useGPU { + sdf2, err = gsdfaux.MakeGPUSDF2(s) + } else { + sdf2, err = gleval.NewCPUSDF2(s) + } + if err != nil { + log.Fatal(err) + } + if !useGPU { + fmt.Println("GPU usage not enabled (-gpu flag). Enable for faster rendering") + } + + charHeight := sdf2.Bounds().Size().Y + edgeAliasing := charHeight / 1000 + start := time.Now() + err = gsdfaux.RenderPNGFile(filename, sdf2, 300, blackAndWhite(edgeAliasing)) + if err != nil { + log.Fatal(err) + } + fmt.Println("PNG file rendered to", filename, "in", time.Since(start)) +} + +func blackAndWhite(edgeSmooth float32) func(d float32) color.Color { + if edgeSmooth <= 0 { + return blackAndWhiteNoSmoothing + } + return func(d float32) color.Color { + // Smoothstep anti-aliasing near the edge + blend := 0.5 + 0.5*math32.Tanh(d/edgeSmooth) + // Clamp blend to [0, 1] for valid grayscale values + blend = ms1.Clamp(blend, 0, 1) + // Convert blend to grayscale + grayValue := uint8(blend * 255) + return color.Gray{Y: grayValue} + } +} + +func blackAndWhiteNoSmoothing(d float32) color.Color { + if d < 0 { + return color.Black + } + return color.White +} diff --git a/examples/text/text.go b/examples/text/text.go deleted file mode 100644 index 16293cf..0000000 --- a/examples/text/text.go +++ /dev/null @@ -1,67 +0,0 @@ -package main - -import ( - "fmt" - "log" - "runtime" - - "github.com/soypat/glgl/math/ms2" - "github.com/soypat/gsdf" - "github.com/soypat/gsdf/forge/textsdf" - "github.com/soypat/gsdf/glbuild" - "github.com/soypat/gsdf/gleval" - "github.com/soypat/gsdf/gsdfaux" -) - -const dim = 20 -const filename = "text.png" - -func init() { - runtime.LockOSThread() -} - -func scene(bld *gsdf.Builder) (glbuild.Shader2D, error) { - var f textsdf.Font - f.Configure(textsdf.FontConfig{ - RelativeGlyphTolerance: 0.001, - }) - err := f.LoadTTFBytes(textsdf.ISO3098TTF()) - if err != nil { - return nil, err - } - var poly ms2.PolygonBuilder - poly.Nagon(7, 1) - vecs, _ := poly.AppendVecs(nil) - return bld.NewPolygon(vecs), bld.Err() - return f.TextLine("Abc") -} - -func main() { - useGPU := true - if useGPU { - term, err := gleval.Init1x1GLFW() - if err != nil { - log.Fatal(err) - } - defer term() - } - var bld gsdf.Builder - s, err := scene(&bld) - if err != nil { - log.Fatal(err) - } - var sdf2 gleval.SDF2 - if useGPU { - sdf2, err = gsdfaux.MakeGPUSDF2(s) - } else { - sdf2, err = gleval.NewCPUSDF2(s) - } - if err != nil { - log.Fatal(err) - } - err = gsdfaux.RenderPNGFile(filename, sdf2, 300, nil) - if err != nil { - log.Fatal(err) - } - fmt.Println("PNG file rendered to", filename) -} diff --git a/examples/ui-geb/uigeb.go b/examples/ui-geb/uigeb.go index cb82adb..41fda69 100644 --- a/examples/ui-geb/uigeb.go +++ b/examples/ui-geb/uigeb.go @@ -65,9 +65,10 @@ func scene(bld *gsdf.Builder) (glbuild.Shader3D, error) { B3 := bld.Extrude(B, L) // Non-uniform scaling to fill letter intersections. - G3 = bld.Transform(G3, ms3.ScaleMat4(ms3.Vec{X: sclG.X, Y: sclG.Y, Z: 1})) - E3 = bld.Transform(E3, ms3.ScaleMat4(ms3.Vec{X: sclE.X, Y: sclE.Y, Z: 1})) - B3 = bld.Transform(B3, ms3.ScaleMat4(ms3.Vec{X: sclB.X, Y: sclB.Y, Z: 1})) + G3 = bld.Transform(G3, ms3.ScalingMat4(ms3.Vec{X: sclG.X, Y: sclG.Y, Z: 1})) + E3 = bld.Transform(E3, ms3.ScalingMat4(ms3.Vec{X: sclE.X, Y: sclE.Y, Z: 1})) + B3 = bld.Transform(B3, ms3.ScalingMat4(ms3.Vec{X: sclB.X, Y: sclB.Y, Z: 1})) + const round2 = 0.025 G3 = bld.Offset(G3, -round2) E3 = bld.Offset(E3, -round2) diff --git a/go.mod b/go.mod index 2d31fb4..5cb6beb 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/go-gl/glfw v0.0.0-20221017161538-93cebf72946b github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 - github.com/soypat/glgl v0.0.0-20241121001014-cc8498d2a83d + github.com/soypat/glgl v0.0.0-20241124175250-a2463fe190a5 golang.org/x/image v0.22.0 ) diff --git a/go.sum b/go.sum index 147c78f..684c6dd 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/soypat/glgl v0.0.0-20241121001014-cc8498d2a83d h1:kDdWM661L/RAxg0j4gV+18hky7/3Tvbhd8O6p8CLB7w= github.com/soypat/glgl v0.0.0-20241121001014-cc8498d2a83d/go.mod h1:1LcEp6XHSMCI91WlJHzl/aW4Bp5v6yQOiYFyjrlk350= +github.com/soypat/glgl v0.0.0-20241124175250-a2463fe190a5 h1:PyD0ceAopD2FDv3ddx99Q+h7QxIzDPPuOQiaZrRA7yU= +github.com/soypat/glgl v0.0.0-20241124175250-a2463fe190a5/go.mod h1:1LcEp6XHSMCI91WlJHzl/aW4Bp5v6yQOiYFyjrlk350= golang.org/x/exp v0.0.0-20221230185412-738e83a70c30 h1:m9O6OTJ627iFnN2JIWfdqlZCzneRO6EEBsHXI25P8ws= golang.org/x/exp v0.0.0-20221230185412-738e83a70c30/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g= diff --git a/gsdf_test.go b/gsdf_test.go index 67d8ce4..8a02f97 100644 --- a/gsdf_test.go +++ b/gsdf_test.go @@ -22,9 +22,9 @@ func TestTransformDuplicateBug(t *testing.T) { B3 := bld.Extrude(B, L) // Non-uniform scaling to fill letter intersections. - G3 = bld.Transform(G3, ms3.ScaleMat4(ms3.Vec{X: 1.2, Y: 1.3, Z: 1})) - E3 = bld.Transform(E3, ms3.ScaleMat4(ms3.Vec{X: 1.2, Y: 1.3, Z: 1})) - B3 = bld.Transform(B3, ms3.ScaleMat4(ms3.Vec{X: 1.2, Y: 1.3, Z: 1})) + G3 = bld.Transform(G3, ms3.ScalingMat4(ms3.Vec{X: 1.2, Y: 1.3, Z: 1})) + E3 = bld.Transform(E3, ms3.ScalingMat4(ms3.Vec{X: 1.2, Y: 1.3, Z: 1})) + B3 = bld.Transform(B3, ms3.ScalingMat4(ms3.Vec{X: 1.2, Y: 1.3, Z: 1})) const round2 = 0.025 G3 = bld.Offset(G3, -round2) E3 = bld.Offset(E3, -round2) diff --git a/operations.go b/operations.go index 6897993..15df397 100644 --- a/operations.go +++ b/operations.go @@ -394,7 +394,7 @@ func (bld *Builder) Rotate(s glbuild.Shader3D, radians float32, axis ms3.Vec) gl if axis == (ms3.Vec{}) { bld.shapeErrorf("null vector") } - T := ms3.RotationMat4(radians, axis) + T := ms3.RotatingMat4(radians, axis) return bld.Transform(s, T) }