diff --git a/graphics.go b/graphics.go index db5074b7b4d0c572b4e4b4755f884191b4d14274..d6948be1fe7860fde1259cd8828fd93e44678833 100644 --- a/graphics.go +++ b/graphics.go @@ -24,19 +24,6 @@ type Drawer interface { Draw(t ...Transform) } -// Deleter is anything that can be deleted. All graphics objects that have some associated video memory -// are deleters. It is necessary to call Delete when you're done with an object, otherwise you're going -// to have video memory leaks. -type Deleter interface { - Delete() -} - -// DrawDeleter combines Drawer and Deleter interfaces. -type DrawDeleter interface { - Drawer - Deleter -} - // Group is used to effeciently handle a collection of objects with a common parent. Usually many objects share a parent, // using a group can significantly increase performance in these cases. // @@ -110,11 +97,6 @@ func NewShape(parent pixelgl.Doer, picture Picture, c color.Color, transform Tra } } -// Delete deletes the underlying -func (s *Shape) Delete() { - s.va.Delete() -} - // SetPicture changes the picture of a shape. func (s *Shape) SetPicture(picture Picture) { s.picture = picture @@ -183,7 +165,7 @@ type MultiShape struct { *Shape } -// NewMultiShape creates a new multishape from several other shapes. These shapes are automatically deleted after creating a multishape. +// NewMultiShape creates a new multishape from several other shapes. // // If two of the supplied shapes have different pictures, this function panics. func NewMultiShape(parent pixelgl.Doer, shapes ...*Shape) *MultiShape { @@ -259,10 +241,6 @@ func NewMultiShape(parent pixelgl.Doer, shapes ...*Shape) *MultiShape { offset += shape.VertexArray().VertexNum() } - for _, shape := range shapes { - shape.Delete() - } - return &MultiShape{NewShape(parent, picture, color.White, Position(0), va)} } diff --git a/picture.go b/picture.go index 8915eaa4cff6c99f7cd3915701155e196ededa10..fd5287b2df95aac5f1b707c58067a24f6695516e 100644 --- a/picture.go +++ b/picture.go @@ -12,9 +12,6 @@ import ( // // A picture is created from an image.Image, that can be either loaded from a file, or generated. After the creation // a picture can be sliced (slicing creates a "sub-picture" from a picture) into smaller pictures. -// -// However note, that all of the sliced pictures share the same underlying texture. Deleting one picture also deletes -// all pictures that share the same underlying texture. type Picture struct { texture *pixelgl.Texture bounds Rect @@ -42,12 +39,6 @@ func NewPicture(img image.Image) Picture { } } -// Delete deletes this picture and all pictures that share the same underlying texuture (all that have been -// created from the same parent using slicing). -func (p Picture) Delete() { - p.texture.Delete() -} - // IsNil returns true if a picture is no picture. func (p Picture) IsNil() bool { return p.texture == nil @@ -61,7 +52,7 @@ func (p Picture) Texture() *pixelgl.Texture { } // Slice returns a picture within the supplied rectangle of the original picture. The original and the sliced picture -// share the same texture. Thus deleting one also deletes the other one. +// share the same texture. // // For example, suppose we have a 100x200 pixels picture. If we slice it with rectangle (50, 100, 50, 100), we get // the upper-right quadrant of the original picture. diff --git a/pixelgl/shader.go b/pixelgl/shader.go index 666eed6e46cb4e823b0b8d218b3f3df6a6d6fba3..da68dbc561ca396140cc66b245eb21e64c096dc5 100644 --- a/pixelgl/shader.go +++ b/pixelgl/shader.go @@ -2,6 +2,7 @@ package pixelgl import ( "fmt" + "runtime" "github.com/go-gl/gl/v3.3-core/gl" "github.com/go-gl/mathgl/mgl32" @@ -113,11 +114,12 @@ func NewShader(parent Doer, vertexFmt, uniformFmt AttrFormat, vertexShader, frag return nil, err } + runtime.SetFinalizer(shader, (*Shader).delete) + return shader, nil } -// Delete deletes a shader program. Don't use a shader after deletion. -func (s *Shader) Delete() { +func (s *Shader) delete() { s.parent.Do(func(ctx Context) { DoNoBlock(func() { gl.DeleteProgram(s.program.obj) diff --git a/pixelgl/texture.go b/pixelgl/texture.go index f443081da16abd04e5ed9262019706a034a20837..843ed82e111b51eb8997ec5a7a4d2da02d263995 100644 --- a/pixelgl/texture.go +++ b/pixelgl/texture.go @@ -1,6 +1,7 @@ package pixelgl import "github.com/go-gl/gl/v3.3-core/gl" +import "runtime" // Texture is an OpenGL texture. type Texture struct { @@ -45,11 +46,12 @@ func NewTexture(parent Doer, width, height int, pixels []uint8) (*Texture, error }) }) + runtime.SetFinalizer(texture, (*Texture).delete) + return texture, nil } -// Delete deletes a texture. Don't use a texture after deletion. -func (t *Texture) Delete() { +func (t *Texture) delete() { t.parent.Do(func(ctx Context) { DoNoBlock(func() { gl.DeleteTextures(1, &t.tex.obj) diff --git a/pixelgl/vertex.go b/pixelgl/vertex.go index e8c9ca20ee934b147b18eec89209f84ef3998ca8..f9c67ffbc4755f1d6cf72a28cd7be3cfdbd003dc 100644 --- a/pixelgl/vertex.go +++ b/pixelgl/vertex.go @@ -3,6 +3,8 @@ package pixelgl import ( "unsafe" + "runtime" + "github.com/go-gl/gl/v3.3-core/gl" "github.com/go-gl/mathgl/mgl32" "github.com/pkg/errors" @@ -107,11 +109,12 @@ func NewVertexArray(parent Doer, format AttrFormat, vertexNum int, indices []int va.SetIndices(indices) + runtime.SetFinalizer(va, (*VertexArray).delete) + return va, nil } -// Delete deletes a vertex array and it's associated vertex buffer. Don't use a vertex array after deletion. -func (va *VertexArray) Delete() { +func (va *VertexArray) delete() { va.parent.Do(func(ctx Context) { DoNoBlock(func() { gl.DeleteVertexArrays(1, &va.vao.obj) diff --git a/window.go b/window.go index 7867ea378cb3526a27eec463b5af18c64f152d50..90b90f74d7174120840863d354d9ffb9845d4a7e 100644 --- a/window.go +++ b/window.go @@ -4,6 +4,8 @@ import ( "image/color" "sync" + "runtime" + "github.com/faiface/pixel/pixelgl" "github.com/go-gl/gl/v3.3-core/gl" "github.com/go-gl/glfw/v3.2/glfw" @@ -121,15 +123,17 @@ func NewWindow(config WindowConfig) (*Window, error) { w.defaultShader.SetUniformAttr(transformMat3, mgl32.Ident3()) }) if err != nil { - w.Delete() + w.Destroy() return nil, errors.Wrap(err, "creating window failed") } + runtime.SetFinalizer(w, (*Window).Destroy) + return w, nil } -// Delete destroys a window. The window can't be used any further. -func (w *Window) Delete() { +// Destroy destroys a window. The window can't be used any further. +func (w *Window) Destroy() { pixelgl.Do(func() { w.window.Destroy() })