Skip to content

Commit

Permalink
add AppendShaderBuffers method to glbuild.Shader
Browse files Browse the repository at this point in the history
  • Loading branch information
soypat committed Oct 6, 2024
1 parent 5cba178 commit 903fd88
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 0 deletions.
4 changes: 4 additions & 0 deletions forge/threads/threads.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ func Screw(length float32, thread Threader) (glbuild.Shader3D, error) {
return &s, nil
}

func (s *screw) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

func (s *screw) ForEachChild(any, func(any, *glbuild.Shader3D) error) error {
return nil
}
Expand Down
38 changes: 38 additions & 0 deletions glbuild/glbuild.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"errors"
"fmt"
"io"
"reflect"
"strconv"
"unsafe"

"github.com/soypat/glgl/math/ms2"
"github.com/soypat/glgl/math/ms3"
Expand All @@ -26,6 +28,22 @@ type Shader interface {
// AppendShaderBody appends the body of the shader function to the
// buffer and returns the result.
AppendShaderBody(b []byte) []byte
AppendShaderBuffers(ssbos []ShaderBuffer) []ShaderBuffer
}

type ShaderBuffer struct {
// NamePtr is a pointer to the name of the buffer inside of the [Shader].
// This lets the programmer edit the name if a naming conflict is found before generating the shader bodies.
NamePtr []byte

// Element is the element of the buffer.
Element reflect.Type
// Ptr points to the start of buffer data.
Ptr unsafe.Pointer
// Size of buffer in bytes.
Size int
Read bool
// Write bool
}

// Shader3D can create SDF shader source code for an arbitrary 3D shape.
Expand Down Expand Up @@ -773,6 +791,11 @@ func (c3 *CachedShader3D) ForEach2DChild(userData any, fn func(userData any, s *
return err
}

// AppendShaderBuffers returns the underlying [Shader]'s buffer declarations.
func (c3 *CachedShader3D) AppendShaderBuffers(ssbos []ShaderBuffer) []ShaderBuffer {
return c3.Shader.AppendShaderBuffers(ssbos)
}

// Evaluate implements the gleval.SDF3 interface.
func (c3 *CachedShader3D) Evaluate(pos []ms3.Vec, dist []float32, userData any) error {
sdf, ok := c3.Shader.(sdf3)
Expand Down Expand Up @@ -827,6 +850,11 @@ func (c2 *CachedShader2D) Evaluate(pos []ms2.Vec, dist []float32, userData any)
return sdf.Evaluate(pos, dist, userData)
}

// AppendShaderBuffers returns the underlying [Shader]'s buffer declarations.
func (c2 *CachedShader2D) AppendShaderBuffers(ssbos []ShaderBuffer) []ShaderBuffer {
return c2.Shader.AppendShaderBuffers(ssbos)
}

type nameOverloadShader3D struct {
Shader Shader3D
name []byte
Expand Down Expand Up @@ -855,6 +883,11 @@ func (nos3 *nameOverloadShader3D) ForEach2DChild(userData any, fn func(userData
return err
}

// AppendShaderBuffers returns the underlying [Shader]'s buffer declarations.
func (nos3 *nameOverloadShader3D) AppendShaderBuffers(ssbos []ShaderBuffer) []ShaderBuffer {
return nos3.Shader.AppendShaderBuffers(ssbos)
}

type (
sdf3 interface {
Evaluate(pos []ms3.Vec, dist []float32, userData any) error
Expand Down Expand Up @@ -903,6 +936,11 @@ func (nos2 *nameOverloadShader2D) Evaluate(pos []ms2.Vec, dist []float32, userDa
return sdf.Evaluate(pos, dist, userData)
}

// AppendShaderBuffers returns the underlying [Shader]'s buffer declarations.
func (nos2 *nameOverloadShader2D) AppendShaderBuffers(ssbos []ShaderBuffer) []ShaderBuffer {
return nos2.Shader.AppendShaderBuffers(ssbos)
}

func hash(b []byte, in uint64) uint64 {
// Leaving md5 here since we may need to revert to
// a more entropic hash to avoid collisions...
Expand Down
78 changes: 78 additions & 0 deletions gsdf2d.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ func (u *OpUnion2D) AppendShaderBody(b []byte) []byte {
return b
}

// AppendShaderBuffers implements [glbuild.Shader]. This method returns the argument buffer with no modifications. See [glbuild.Shader] for more information.
func (u *OpUnion2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
u.mustValidate()
return ssbos
}

func (u *OpUnion2D) mustValidate() {
if len(u.joined) < 2 {
panic("OpUnion2D must have at least 2 elements. Please prefer using gsdf.Union2D over gsdf.OpUnion2D")
Expand Down Expand Up @@ -147,6 +153,10 @@ func (l *line2D) ForEach2DChild(userData any, fn func(userData any, s *glbuild.S
return nil
}

func (u *line2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// NewArc returns a 2D arc centered at the origin (x,y)=(0,0) for a given radius and arc angle and thickness of the arc.
// The arc begins opening at (x,y)=(0,r) in both positive and negative x direction.
func NewArc(radius, arcAngle, thick float32) (glbuild.Shader2D, error) {
Expand Down Expand Up @@ -196,6 +206,10 @@ func (a *arc2D) ForEach2DChild(userData any, fn func(userData any, s *glbuild.Sh
return nil
}

func (u *arc2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

type circle2D struct {
r float32
}
Expand Down Expand Up @@ -229,6 +243,10 @@ func (c *circle2D) ForEach2DChild(userData any, fn func(userData any, s *glbuild
return nil
}

func (u *circle2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

type equilateralTri2d struct {
hTri float32
}
Expand Down Expand Up @@ -273,6 +291,10 @@ func (t *equilateralTri2d) ForEach2DChild(userData any, fn func(userData any, s
return nil
}

func (u *equilateralTri2d) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

type rect2D struct {
d ms2.Vec
}
Expand Down Expand Up @@ -312,6 +334,10 @@ func (c *rect2D) ForEach2DChild(userData any, fn func(userData any, s *glbuild.S
return nil
}

func (u *rect2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

type hex2D struct {
side float32
}
Expand Down Expand Up @@ -349,6 +375,10 @@ func (c *hex2D) ForEach2DChild(userData any, fn func(userData any, s *glbuild.Sh
return nil
}

func (u *hex2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

type ellipse2D struct {
a, b float32
}
Expand Down Expand Up @@ -416,6 +446,10 @@ func (c *ellipse2D) ForEach2DChild(userData any, fn func(userData any, s *glbuil
return nil
}

func (u *ellipse2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

type poly2D struct {
vert []ms2.Vec
}
Expand Down Expand Up @@ -489,6 +523,10 @@ func (c *poly2D) ForEach2DChild(userData any, fn func(userData any, s *glbuild.S
return nil
}

func (u *poly2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos // TODO: implement shader buffer storage here!
}

// Extrude converts a 2D SDF into a 3D extrusion. Extrudes in both positive and negative Z direction, half of h both ways.
func Extrude(s glbuild.Shader2D, h float32) (glbuild.Shader3D, error) {
if s == nil {
Expand Down Expand Up @@ -519,6 +557,9 @@ func (e *extrusion) ForEach2DChild(userData any, fn func(userData any, s *glbuil
func (e *extrusion) ForEachChild(userData any, fn func(userData any, s *glbuild.Shader3D) error) error {
return nil
}
func (u *extrusion) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

func (e *extrusion) AppendShaderName(b []byte) []byte {
b = append(b, "extrusion_"...)
Expand Down Expand Up @@ -564,6 +605,9 @@ func (r *revolution) ForEach2DChild(userData any, fn func(userData any, s *glbui
func (r *revolution) ForEachChild(userData any, fn func(userData any, s *glbuild.Shader3D) error) error {
return nil
}
func (u *revolution) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

func (r *revolution) AppendShaderName(b []byte) []byte {
b = append(b, "revolution_"...)
Expand Down Expand Up @@ -619,6 +663,9 @@ func (s *diff2D) AppendShaderBody(b []byte) []byte {
b = append(b, "(p));"...)
return b
}
func (u *diff2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// Intersection2D is the SDF intersection of a ^ b. Does not produce an exact SDF.
func Intersection2D(a, b glbuild.Shader2D) glbuild.Shader2D {
Expand Down Expand Up @@ -660,6 +707,9 @@ func (s *intersect2D) AppendShaderBody(b []byte) []byte {
b = append(b, "(p));"...)
return b
}
func (u *intersect2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// Xor2D is the mutually exclusive boolean operation and results in an exact SDF.
func Xor2D(s1, s2 glbuild.Shader2D) glbuild.Shader2D {
Expand Down Expand Up @@ -699,6 +749,9 @@ func (s *xor2D) AppendShaderBody(b []byte) []byte {
b = append(b, "return max(min(d1,d2),-max(d1,d2));"...)
return b
}
func (u *xor2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// Array is the domain repetition operation. It repeats domain centered around (x,y)=(0,0).
func Array2D(s glbuild.Shader2D, spacingX, spacingY float32, nx, ny int) (glbuild.Shader2D, error) {
Expand Down Expand Up @@ -775,6 +828,9 @@ return d;`, s.d.X, s.d.Y,
b = append(b, body...)
return b
}
func (u *array2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// Offset2D adds sdfAdd to the entire argument SDF. If sdfAdd is negative this will
// round edges and increase the dimension of flat surfaces of the SDF by the absolute magnitude.
Expand Down Expand Up @@ -821,6 +877,9 @@ func (s *offset2D) AppendShaderBody(b []byte) []byte {
b = append(b, ')', ';')
return b
}
func (u *offset2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// Translate2D moves the SDF s in the given direction.
func Translate2D(s glbuild.Shader2D, dirX, dirY float32) glbuild.Shader2D {
Expand Down Expand Up @@ -856,6 +915,9 @@ func (s *translate2D) AppendShaderBody(b []byte) []byte {
b = append(b, "(p-t);"...)
return b
}
func (u *translate2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// Rotate2D returns the argument shape rotated around the origin by theta (radians).
func Rotate2D(s glbuild.Shader2D, theta float32) (glbuild.Shader2D, error) {
Expand Down Expand Up @@ -913,6 +975,10 @@ func (r *rotation2D) AppendShaderBody(b []byte) []byte {
return b
}

func (u *rotation2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// Symmetry reflects the SDF around x or y (or both) axis.
func Symmetry2D(s glbuild.Shader2D, mirrorX, mirrorY bool) glbuild.Shader2D {
if !mirrorX && !mirrorY {
Expand Down Expand Up @@ -961,6 +1027,10 @@ func (s *symmetry2D) AppendShaderBody(b []byte) []byte {
return b
}

func (u *symmetry2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// Annulus makes a 2D shape annular by emptying it's center. It is the equivalent of the 3D Shell operation but in 2D.
func Annulus(s glbuild.Shader2D, sub float32) (glbuild.Shader2D, error) {
if s == nil {
Expand Down Expand Up @@ -998,6 +1068,10 @@ func (s *annulus2D) AppendShaderBody(b []byte) []byte {
return b
}

func (u *annulus2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}

// CircularArray2D is the circular domain repetition operation around the origin (x,y)=(0,0).
// It repeats the shape numInstances times and the spacing angle is defined by circleDiv such that angle = 2*pi/circleDiv.
// The operation is defined this way so that the argument shape is evaluated only twice per circular array evaluation, regardless of instances.
Expand Down Expand Up @@ -1074,3 +1148,7 @@ func (ca *circarray2D) AppendShaderBody(b []byte) []byte {
b = append(b, "return min(d0, d1);"...)
return b
}

func (u *circarray2D) AppendShaderBuffers(ssbos []glbuild.ShaderBuffer) []glbuild.ShaderBuffer {
return ssbos
}
Loading

0 comments on commit 903fd88

Please sign in to comment.