added a way to replace an image after it has been loaded

This commit is contained in:
Thomas Friedel 2018-10-20 12:43:25 +02:00
parent 091db17ac0
commit 32bbbdd7c8

View file

@ -30,21 +30,47 @@ func LoadImage(src interface{}) (*Image, error) {
if gli == nil { if gli == nil {
panic("LoadGL must be called before images can be loaded") panic("LoadGL must be called before images can be loaded")
} }
var tex uint32
gli.GenTextures(1, &tex)
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_2D, tex)
if src == nil {
return &Image{tex: tex}, nil
}
img, err := loadImage(src, tex)
if err != nil {
return nil, err
}
runtime.SetFinalizer(img, func(img *Image) {
if !img.deleted {
glChan <- func() {
gli.DeleteTextures(1, &img.tex)
}
}
})
return img, nil
}
func loadImage(src interface{}, tex uint32) (*Image, error) {
var img *Image var img *Image
var err error var err error
switch v := src.(type) { switch v := src.(type) {
case *image.RGBA: case *image.RGBA:
img, err = loadImageRGBA(v) img, err = loadImageRGBA(v, tex)
if err != nil { if err != nil {
return nil, err return nil, err
} }
case *image.Gray: case *image.Gray:
img, err = loadImageGray(v) img, err = loadImageGray(v, tex)
if err != nil { if err != nil {
return nil, err return nil, err
} }
case image.Image: case image.Image:
img, err = loadImageConverted(v) img, err = loadImageConverted(v, tex)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -57,23 +83,16 @@ func LoadImage(src interface{}) (*Image, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return LoadImage(srcImg) return loadImage(srcImg, tex)
case []byte: case []byte:
srcImg, _, err := image.Decode(bytes.NewReader(v)) srcImg, _, err := image.Decode(bytes.NewReader(v))
if err != nil { if err != nil {
return nil, err return nil, err
} }
return LoadImage(srcImg) return loadImage(srcImg, tex)
default: default:
return nil, errors.New("Unsupported source type") return nil, errors.New("Unsupported source type")
} }
runtime.SetFinalizer(img, func(img *Image) {
if !img.deleted {
glChan <- func() {
gli.DeleteTextures(1, &img.tex)
}
}
})
return img, nil return img, nil
} }
@ -112,8 +131,8 @@ func getImage(src interface{}) *Image {
return nil return nil
} }
func loadImageRGBA(src *image.RGBA) (*Image, error) { func loadImageRGBA(src *image.RGBA, tex uint32) (*Image, error) {
img := &Image{w: src.Bounds().Dx(), h: src.Bounds().Dy(), opaque: true} img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy(), opaque: true}
checkOpaque: checkOpaque:
for y := 0; y < img.h; y++ { for y := 0; y < img.h; y++ {
@ -127,9 +146,6 @@ checkOpaque:
} }
} }
gli.GenTextures(1, &img.tex)
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_2D, img.tex)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR_MIPMAP_LINEAR) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR_MIPMAP_LINEAR)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE)
@ -158,11 +174,8 @@ checkOpaque:
return img, nil return img, nil
} }
func loadImageGray(src *image.Gray) (*Image, error) { func loadImageGray(src *image.Gray, tex uint32) (*Image, error) {
img := &Image{w: src.Bounds().Dx(), h: src.Bounds().Dy()} img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy()}
gli.GenTextures(1, &img.tex)
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_2D, img.tex)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR_MIPMAP_LINEAR) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR_MIPMAP_LINEAR)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE)
@ -191,11 +204,8 @@ func loadImageGray(src *image.Gray) (*Image, error) {
return img, nil return img, nil
} }
func loadImageConverted(src image.Image) (*Image, error) { func loadImageConverted(src image.Image, tex uint32) (*Image, error) {
img := &Image{w: src.Bounds().Dx(), h: src.Bounds().Dy(), opaque: true} img := &Image{tex: tex, w: src.Bounds().Dx(), h: src.Bounds().Dy(), opaque: true}
gli.GenTextures(1, &img.tex)
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_2D, img.tex)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR_MIPMAP_LINEAR) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR_MIPMAP_LINEAR)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR)
gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE) gli.TexParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE)
@ -241,6 +251,18 @@ func (img *Image) Delete() {
img.deleted = true img.deleted = true
} }
// Replace replaces the image with the new one
func (img *Image) Replace(src interface{}) {
gli.ActiveTexture(gl_TEXTURE0)
gli.BindTexture(gl_TEXTURE_2D, img.tex)
newImg, err := loadImage(src, img.tex)
if err != nil {
fmt.Fprintf(os.Stderr, "Error replacing image: %v\n", err)
return
}
*img = *newImg
}
// DrawImage draws the given image to the given coordinates. The image // DrawImage draws the given image to the given coordinates. The image
// parameter can be an Image loaded by LoadImage, a file name string that will // parameter can be an Image loaded by LoadImage, a file name string that will
// be loaded and cached, or a name string that corresponds to a previously // be loaded and cached, or a name string that corresponds to a previously