2016-11-23 10:29:28 -06:00
|
|
|
package pixelgl
|
|
|
|
|
2016-12-06 09:05:08 -06:00
|
|
|
import "github.com/go-gl/gl/v3.3-core/gl"
|
2016-12-18 13:16:27 -06:00
|
|
|
import "runtime"
|
2016-11-23 10:29:28 -06:00
|
|
|
|
|
|
|
// Texture is an OpenGL texture.
|
|
|
|
type Texture struct {
|
2016-12-06 09:23:55 -06:00
|
|
|
parent Doer
|
2016-12-14 09:24:31 -06:00
|
|
|
tex binder
|
2016-12-06 09:23:55 -06:00
|
|
|
width, height int
|
2016-11-23 10:29:28 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// NewTexture creates a new texture with the specified width and height.
|
|
|
|
// The pixels must be a sequence of RGBA values.
|
2016-11-25 15:49:56 -06:00
|
|
|
func NewTexture(parent Doer, width, height int, pixels []uint8) (*Texture, error) {
|
2016-12-06 09:23:55 -06:00
|
|
|
texture := &Texture{
|
|
|
|
parent: parent,
|
2016-12-14 09:24:31 -06:00
|
|
|
tex: binder{
|
|
|
|
restoreLoc: gl.TEXTURE_BINDING_2D,
|
|
|
|
bindFunc: func(obj uint32) {
|
|
|
|
gl.BindTexture(gl.TEXTURE_2D, obj)
|
|
|
|
},
|
|
|
|
},
|
2016-12-06 09:23:55 -06:00
|
|
|
width: width,
|
|
|
|
height: height,
|
|
|
|
}
|
2016-11-24 07:37:11 -06:00
|
|
|
|
2016-11-28 16:26:56 -06:00
|
|
|
parent.Do(func(ctx Context) {
|
2016-12-06 09:05:08 -06:00
|
|
|
Do(func() {
|
2016-12-14 09:24:31 -06:00
|
|
|
gl.GenTextures(1, &texture.tex.obj)
|
|
|
|
defer texture.tex.bind().restore()
|
2016-11-25 15:49:56 -06:00
|
|
|
|
|
|
|
gl.TexImage2D(
|
|
|
|
gl.TEXTURE_2D,
|
|
|
|
0,
|
|
|
|
gl.RGBA,
|
|
|
|
int32(width),
|
|
|
|
int32(height),
|
|
|
|
0,
|
|
|
|
gl.RGBA,
|
|
|
|
gl.UNSIGNED_BYTE,
|
|
|
|
gl.Ptr(pixels),
|
|
|
|
)
|
2016-11-23 11:06:55 -06:00
|
|
|
|
2016-11-25 15:49:56 -06:00
|
|
|
gl.GenerateMipmap(gl.TEXTURE_2D)
|
|
|
|
})
|
2016-11-23 10:29:28 -06:00
|
|
|
})
|
2016-11-24 07:37:11 -06:00
|
|
|
|
2016-12-18 13:16:27 -06:00
|
|
|
runtime.SetFinalizer(texture, (*Texture).delete)
|
|
|
|
|
2016-11-23 11:06:55 -06:00
|
|
|
return texture, nil
|
2016-11-23 10:29:28 -06:00
|
|
|
}
|
|
|
|
|
2016-12-18 13:16:27 -06:00
|
|
|
func (t *Texture) delete() {
|
2016-12-18 18:11:34 -06:00
|
|
|
DoNoBlock(func() {
|
|
|
|
gl.DeleteTextures(1, &t.tex.obj)
|
2016-11-23 13:06:34 -06:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-12-02 11:03:51 -06:00
|
|
|
// ID returns an OpenGL identifier of a texture.
|
|
|
|
func (t *Texture) ID() uint32 {
|
2016-12-14 09:24:31 -06:00
|
|
|
return t.tex.obj
|
2016-12-02 11:03:51 -06:00
|
|
|
}
|
|
|
|
|
2016-12-06 09:23:55 -06:00
|
|
|
// Width returns the width of a texture in pixels.
|
|
|
|
func (t *Texture) Width() int {
|
|
|
|
return t.width
|
|
|
|
}
|
|
|
|
|
|
|
|
// Height returns the height of a texture in pixels.
|
|
|
|
func (t *Texture) Height() int {
|
|
|
|
return t.height
|
|
|
|
}
|
|
|
|
|
2016-11-25 15:49:56 -06:00
|
|
|
// Do bind a texture, executes sub, and unbinds the texture.
|
2016-11-28 16:26:56 -06:00
|
|
|
func (t *Texture) Do(sub func(Context)) {
|
|
|
|
t.parent.Do(func(ctx Context) {
|
2016-11-25 15:49:56 -06:00
|
|
|
DoNoBlock(func() {
|
2016-12-14 09:24:31 -06:00
|
|
|
t.tex.bind()
|
2016-11-25 15:49:56 -06:00
|
|
|
})
|
2016-11-28 16:26:56 -06:00
|
|
|
sub(ctx)
|
2016-11-25 15:49:56 -06:00
|
|
|
DoNoBlock(func() {
|
2016-12-14 09:24:31 -06:00
|
|
|
t.tex.restore()
|
2016-11-25 15:49:56 -06:00
|
|
|
})
|
2016-11-23 10:29:28 -06:00
|
|
|
})
|
|
|
|
}
|