144 lines
3.5 KiB
Go
144 lines
3.5 KiB
Go
|
package render
|
||
|
|
||
|
import (
|
||
|
"image"
|
||
|
|
||
|
"github.com/go-gl/gl/all-core/gl"
|
||
|
)
|
||
|
|
||
|
func curTextureBinding() uint32 {
|
||
|
var id int32
|
||
|
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &id)
|
||
|
return uint32(id)
|
||
|
}
|
||
|
|
||
|
// Texture holds handle to OpenGL Texture on the graphics card memory.
|
||
|
type Texture struct {
|
||
|
tex uint32
|
||
|
|
||
|
hasMipmap bool
|
||
|
}
|
||
|
|
||
|
// NewTexture creates a new, empty Texture.
|
||
|
func NewTexture() *Texture {
|
||
|
// Restore current texture binding
|
||
|
defer gl.BindTexture(gl.TEXTURE_2D, curTextureBinding())
|
||
|
|
||
|
var tex uint32
|
||
|
|
||
|
gl.GenTextures(1, &tex)
|
||
|
gl.BindTexture(gl.TEXTURE_2D, tex)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
||
|
|
||
|
return &Texture{tex: tex}
|
||
|
}
|
||
|
|
||
|
// NewTextureRGBA creates a new Texture with image.
|
||
|
func NewTextureRGBA(image *image.RGBA) *Texture {
|
||
|
// Restore current texture binding
|
||
|
defer gl.BindTexture(gl.TEXTURE_2D, curTextureBinding())
|
||
|
|
||
|
var tex uint32
|
||
|
|
||
|
gl.GenTextures(1, &tex)
|
||
|
gl.BindTexture(gl.TEXTURE_2D, tex)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
|
||
|
|
||
|
gl.TexImage2D(
|
||
|
gl.TEXTURE_2D,
|
||
|
0,
|
||
|
gl.RGBA,
|
||
|
int32(image.Rect.Size().X),
|
||
|
int32(image.Rect.Size().Y),
|
||
|
0,
|
||
|
gl.RGBA,
|
||
|
gl.UNSIGNED_BYTE,
|
||
|
gl.Ptr(image.Pix),
|
||
|
)
|
||
|
|
||
|
return &Texture{tex: tex}
|
||
|
}
|
||
|
|
||
|
// SetSmooth sets the min/mag filters to LINEAR(smooth) or NEAREST(not smooth)
|
||
|
// TODO: Not working
|
||
|
func (t *Texture) SetSmooth(smooth bool) {
|
||
|
defer gl.BindTexture(gl.TEXTURE_2D, curTextureBinding())
|
||
|
gl.BindTexture(gl.TEXTURE_2D, t.tex)
|
||
|
if smooth {
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||
|
} else {
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// UpdateRGBA updates the content of the texture with image.
|
||
|
// It deletes existing mipmap, you need to generate it again.
|
||
|
func (t *Texture) UpdateRGBA(image *image.RGBA) {
|
||
|
|
||
|
// Restore current texture binding
|
||
|
defer gl.BindTexture(gl.TEXTURE_2D, curTextureBinding())
|
||
|
|
||
|
gl.BindTexture(gl.TEXTURE_2D, t.tex)
|
||
|
gl.TexImage2D(
|
||
|
gl.TEXTURE_2D,
|
||
|
0,
|
||
|
gl.RGBA,
|
||
|
int32(image.Rect.Size().X),
|
||
|
int32(image.Rect.Size().Y),
|
||
|
0,
|
||
|
gl.RGBA,
|
||
|
gl.UNSIGNED_BYTE,
|
||
|
gl.Ptr(image.Pix),
|
||
|
)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||
|
|
||
|
t.hasMipmap = false
|
||
|
|
||
|
}
|
||
|
|
||
|
// GenerateMipMap generates mipmap for the texture.
|
||
|
func (t *Texture) GenerateMipMap() {
|
||
|
|
||
|
// Restore current texture binding
|
||
|
defer gl.BindTexture(gl.TEXTURE_2D, curTextureBinding())
|
||
|
|
||
|
gl.BindTexture(gl.TEXTURE_2D, t.tex)
|
||
|
gl.GenerateMipmap(gl.TEXTURE_2D)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR)
|
||
|
|
||
|
t.hasMipmap = true
|
||
|
|
||
|
}
|
||
|
|
||
|
// InvalidateMipMap invalidates mipmap for the texture.
|
||
|
func (t *Texture) InvalidateMipMap() {
|
||
|
|
||
|
// Restore current texture binding
|
||
|
defer gl.BindTexture(gl.TEXTURE_2D, curTextureBinding())
|
||
|
|
||
|
gl.BindTexture(gl.TEXTURE_2D, t.tex)
|
||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
|
||
|
|
||
|
t.hasMipmap = false
|
||
|
}
|
||
|
|
||
|
// Handle returns the OpenGL handle of the texture.
|
||
|
func (t *Texture) Handle() uint32 {
|
||
|
return t.tex
|
||
|
}
|
||
|
|
||
|
// Free deletes the texture.
|
||
|
func (t *Texture) Free() {
|
||
|
if t.tex != 0 {
|
||
|
gl.DeleteTextures(1, &t.tex)
|
||
|
}
|
||
|
}
|