Texture.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package giu
  2. import (
  3. "fmt"
  4. "image"
  5. "runtime"
  6. "github.com/AllenDang/imgui-go"
  7. "github.com/faiface/mainthread"
  8. )
  9. // Texture represents imgui.TextureID.
  10. // It is base unit of images in imgui.
  11. type Texture struct {
  12. id imgui.TextureID
  13. }
  14. type textureLoadRequest struct {
  15. img image.Image
  16. cb func(*Texture)
  17. }
  18. type loadImageResult struct {
  19. id imgui.TextureID
  20. err error
  21. }
  22. // EnqueueNewTextureFromRgba adds loading texture request to loading queue
  23. // it allows us to run this method in main loop
  24. // NOTE: remember to call it after NewMasterWindow!
  25. func EnqueueNewTextureFromRgba(rgba image.Image, loadCb func(t *Texture)) {
  26. Assert((Context.textureLoadingQueue != nil), "", "EnqueueNewTextureFromRgba", "you need to call EnqueueNewTextureFromRgba after giu.NewMasterWindow call!")
  27. Context.textureLoadingQueue.Add(textureLoadRequest{rgba, loadCb})
  28. }
  29. // NewTextureFromRgba creates a new texture from image.Image and, when it is done, calls loadCallback(loadedTexture).
  30. func NewTextureFromRgba(rgba image.Image, loadCallback func(*Texture)) {
  31. Assert(Context.isRunning, "", "NewTextureFromRgba", "cannot load texture befor (*MasterWindow).Run call!")
  32. loadTexture(rgba, loadCallback)
  33. }
  34. func loadTexture(rgba image.Image, loadCallback func(*Texture)) {
  35. go func() {
  36. Update()
  37. result := mainthread.CallVal(func() any {
  38. texID, err := Context.renderer.LoadImage(ImageToRgba(rgba))
  39. return &loadImageResult{id: texID, err: err}
  40. })
  41. tid, ok := result.(*loadImageResult)
  42. switch {
  43. case !ok:
  44. panic("giu: NewTextureFromRgba: unexpected error occurred")
  45. case tid.err != nil:
  46. panic(fmt.Sprintf("giu: NewTextureFromRgba: error loading texture: %v", tid.err))
  47. }
  48. texture := Texture{id: tid.id}
  49. // Set finalizer
  50. runtime.SetFinalizer(&texture, (*Texture).release)
  51. // execute callback
  52. loadCallback(&texture)
  53. }()
  54. }
  55. // ToTexture converts imgui.TextureID to Texture.
  56. func ToTexture(textureID imgui.TextureID) *Texture {
  57. return &Texture{id: textureID}
  58. }
  59. func (t *Texture) release() {
  60. Update()
  61. mainthread.Call(func() {
  62. Context.renderer.ReleaseImage(t.id)
  63. })
  64. }