go-opengl-pixel/pixelgl/texture.go

98 lines
2.1 KiB
Go
Raw Normal View History

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"
import "runtime"
2016-11-23 10:29:28 -06:00
// Texture is an OpenGL texture.
type Texture struct {
parent Doer
tex binder
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-12-21 13:51:05 -06:00
func NewTexture(parent Doer, width, height int, smooth bool, pixels []uint8) (*Texture, error) {
texture := &Texture{
parent: parent,
tex: binder{
restoreLoc: gl.TEXTURE_BINDING_2D,
bindFunc: func(obj uint32) {
gl.BindTexture(gl.TEXTURE_2D, obj)
},
},
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() {
gl.GenTextures(1, &texture.tex.obj)
defer texture.tex.bind().restore()
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-12-21 13:51:05 -06:00
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.MIRRORED_REPEAT)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT)
if smooth {
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
} else {
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
}
gl.GenerateMipmap(gl.TEXTURE_2D)
})
2016-11-23 10:29:28 -06:00
})
2016-11-24 07:37:11 -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
}
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
})
}
// ID returns an OpenGL identifier of a texture.
func (t *Texture) ID() uint32 {
return t.tex.obj
}
// 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
}
// 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) {
DoNoBlock(func() {
t.tex.bind()
})
2016-11-28 16:26:56 -06:00
sub(ctx)
DoNoBlock(func() {
t.tex.restore()
})
2016-11-23 10:29:28 -06:00
})
}