zworld/engine/renderapi/texture/texture.go

141 lines
3.0 KiB
Go
Raw Permalink Normal View History

2024-01-14 22:56:06 +08:00
package texture
import (
"zworld/engine/renderapi/device"
"zworld/engine/renderapi/image"
"zworld/engine/renderapi/vkerror"
"zworld/plugins/math/vec3"
"github.com/vkngwrapper/core/v2/core1_0"
"github.com/vkngwrapper/core/v2/driver"
)
type T interface {
device.Resource[core1_0.Sampler]
Key() string
Image() image.T
View() image.View
Size() vec3.T
}
type Args struct {
Filter Filter
Wrap Wrap
Aspect core1_0.ImageAspectFlags
Usage core1_0.ImageUsageFlags
Border core1_0.BorderColor
}
type vktexture struct {
Args
ptr core1_0.Sampler
key string
device device.T
image image.T
view image.View
}
func New(device device.T, key string, width, height int, format core1_0.Format, args Args) (T, error) {
if key == "" {
panic("texture must have a key")
}
args.Usage |= core1_0.ImageUsageFlags(core1_0.ImageUsageSampled | core1_0.ImageUsageTransferDst)
img, err := image.New2D(device, key, width, height, format, args.Usage)
if err != nil {
return nil, err
}
device.SetDebugObjectName(driver.VulkanHandle(img.Ptr().Handle()),
core1_0.ObjectTypeImage, key)
tex, err := FromImage(device, key, img, args)
if err != nil {
img.Destroy()
return nil, err
}
return tex, nil
}
func FromImage(device device.T, key string, img image.T, args Args) (T, error) {
if key == "" {
key = img.Key()
}
if args.Aspect == 0 {
args.Aspect = core1_0.ImageAspectFlags(core1_0.ImageAspectColor)
}
view, err := img.View(img.Format(), args.Aspect)
if err != nil {
return nil, err
}
tex, err := FromView(device, key, view, args)
if err != nil {
// clean up
view.Destroy()
return nil, err
}
return tex, nil
}
func FromView(device device.T, key string, view image.View, args Args) (T, error) {
if key == "" {
panic("texture must have a key")
}
info := core1_0.SamplerCreateInfo{
MinFilter: core1_0.Filter(args.Filter),
MagFilter: core1_0.Filter(args.Filter),
AddressModeU: core1_0.SamplerAddressMode(args.Wrap),
AddressModeV: core1_0.SamplerAddressMode(args.Wrap),
AddressModeW: core1_0.SamplerAddressMode(args.Wrap),
BorderColor: args.Border,
MipmapMode: core1_0.SamplerMipmapModeLinear,
}
ptr, result, err := device.Ptr().CreateSampler(nil, info)
if err != nil {
return nil, err
}
if result != core1_0.VKSuccess {
return nil, vkerror.FromResult(result)
}
device.SetDebugObjectName(driver.VulkanHandle(ptr.Handle()),
core1_0.ObjectTypeSampler, key)
return &vktexture{
Args: args,
key: key,
ptr: ptr,
device: device,
image: view.Image(),
view: view,
}, nil
}
func (t *vktexture) Ptr() core1_0.Sampler {
return t.ptr
}
func (t *vktexture) Key() string { return t.key }
func (t *vktexture) Image() image.T { return t.image }
func (t *vktexture) View() image.View { return t.view }
func (t *vktexture) Size() vec3.T { return t.image.Size() }
func (t *vktexture) Destroy() {
t.ptr.Destroy(nil)
t.ptr = nil
t.view.Destroy()
t.view = nil
t.image.Destroy()
t.image = nil
t.device = nil
}