diff --git a/drawsdf.go b/drawsdf.go index ec63b37..82bccbe 100644 --- a/drawsdf.go +++ b/drawsdf.go @@ -82,34 +82,7 @@ func (r *Renderer) rerenderOpt(forceCancel bool, callbacks ...func(err error)) { renderSize := sdf.V2i{X: int(float64(r.screenSize.X) / float64(r.implState.ResInv)), Y: int(float64(r.screenSize.Y) / float64(r.implState.ResInv))} r.implStateLock.Unlock() partialRenders := make(chan *image.RGBA) - go func(renderSize sdf.V2i) { - partialRenderCopy := image.NewRGBA(image.Rect(0, 0, renderSize.X, renderSize.Y)) - lastPartialRender := time.Now() - for partialRender := range partialRenders { - if time.Since(lastPartialRender) < r.partialRenderEvery { - continue // Skip this partial render (throttled) as it slows down significantly the full render - } - lastPartialRender = time.Now() - r.cachedRenderLock.RLock() - copy(partialRenderCopy.Pix, partialRender.Pix) - r.cachedRenderLock.RUnlock() - // WARNING: This blocks the main rendering thread: call sparingly - gpuImg, err := ebiten.NewImageFromImage(partialRenderCopy, ebiten.FilterDefault) - if err != nil { - log.Println("Error sending image to GPU:", err) - continue - } - r.cachedRenderLock.Lock() - r.cachedPartialRender = gpuImg - r.cachedRenderLock.Unlock() - } - r.cachedRenderLock.Lock() // Use the cached render as the partial one (to make sure it is complete) - err := r.cachedPartialRender.Fill(color.Transparent) - if err != nil { - log.Println("cachedPartialRender.Fill(color.Transparent) error:", err) - } - r.cachedRenderLock.Unlock() - }(renderSize) + r.goPartialRendersHandler(partialRenders, renderSize) renderStartTime := time.Now() r.implStateLock.RLock() sameSize := r.cachedRenderCPU != nil && (sdf.V2i{r.cachedRenderCPU.Rect.Max.X, r.cachedRenderCPU.Rect.Max.Y} == renderSize) @@ -169,3 +142,34 @@ func (r *Renderer) rerenderOpt(forceCancel bool, callbacks ...func(err error)) { r.cachedRenderLock.Unlock() }(callbacks...) } + +func (r *Renderer) goPartialRendersHandler(partialRenders chan *image.RGBA, renderSize sdf.V2i) { + go func(renderSize sdf.V2i) { + partialRenderCopy := image.NewRGBA(image.Rect(0, 0, renderSize.X, renderSize.Y)) + lastPartialRender := time.Now() + for partialRender := range partialRenders { + if time.Since(lastPartialRender) < r.partialRenderEvery { + continue // Skip this partial render (throttled) as it slows down significantly the full render + } + lastPartialRender = time.Now() + r.cachedRenderLock.RLock() + copy(partialRenderCopy.Pix, partialRender.Pix) + r.cachedRenderLock.RUnlock() + // WARNING: This blocks the main rendering thread: call sparingly + gpuImg, err := ebiten.NewImageFromImage(partialRenderCopy, ebiten.FilterDefault) + if err != nil { + log.Println("Error sending image to GPU:", err) + continue + } + r.cachedRenderLock.Lock() + r.cachedPartialRender = gpuImg + r.cachedRenderLock.Unlock() + } + r.cachedRenderLock.Lock() // Use the cached render as the partial one (to make sure it is complete) + err := r.cachedPartialRender.Fill(color.Transparent) + if err != nil { + log.Println("cachedPartialRender.Fill(color.Transparent) error:", err) + } + r.cachedRenderLock.Unlock() + }(renderSize) +} diff --git a/examples/cylinder_head/main.go b/examples/cylinder_head/main.go index 2fe6ec0..d140606 100644 --- a/examples/cylinder_head/main.go +++ b/examples/cylinder_head/main.go @@ -14,6 +14,7 @@ package main import ( ui "github.com/Yeicor/sdfx-ui" + "github.com/deadsy/sdfx/render" "github.com/deadsy/sdfx/sdf" "github.com/hajimehoshi/ebiten" "math" @@ -390,7 +391,7 @@ func main() { // Actual rendering loop err := ui.NewRenderer(s, ui.OptMWatchFiles([]string{"main.go"}), // Default of "." also works, but it triggers too often if generating a profile - //ui.Opt3Mesh(&render.MarchingCubesUniform{}, 100, math.Pi/3), + ui.Opt3Mesh(&render.MarchingCubesUniform{}, 100, math.Pi/3), ui.OptMSmoothCamera(true), ).Run() if err != nil {