gl01/internal/render/texture.go
2022-01-20 21:58:50 +08:00

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)
}
}