Texture: Add existing_resource to newTexture to pass an existing handle.

Meant for e.g. using OpenXR swapchains which give a number of texture images.
For OpenGL, cast the `GLuint` to `pointer` (only tested in little-endian).
This commit is contained in:
Alberto Torres 2025-01-21 18:42:12 +01:00
parent 548f8f88c1
commit 2c8c1407ab

View file

@ -41,7 +41,7 @@ import ../platform/gl
func mipmapHigh*(self: Texture): int
proc needsMipmap*(self: Texture): bool
proc setMaxTextures*(count: int32)
proc newTextureStorage*(ttype: TextureType, width, height, depth: int, format: TextureFormat): TextureStorage
proc newTextureStorage*(ttype: TextureType, width, height, depth: int, format: TextureFormat, existing_resource: pointer = nil): TextureStorage
proc preallocate(self: Texture)
proc freeTextureStorage(self: Texture)
proc bind_it*(texture: Texture, reserve_slot: static[int32] = -1, needs_active_texture: static[bool] = false)
@ -56,7 +56,8 @@ proc newTexture*(engine: MyouEngine, name: string, width, height: int, depth: in
format: TextureFormat,
tex_type: TextureType = Tex2D,
filter: TextureFilter = Trilinear,
pixels: ArrRef[float32] = nil): Texture
pixels: ArrRef[float32] = nil,
existing_resource: pointer = nil): Texture
proc generateMipmap*(self: Texture)
func to_sRGB*(format: TextureFormat): TextureFormat
proc newTexture*(engine: MyouEngine, name: string, data: SliceMem[byte],
@ -169,7 +170,7 @@ proc setTextureReservedSlots*(reserved_slots_bitfield: int32) =
proc resetNextTextureSlot*() =
next_texture = 0
proc newTextureStorage*(ttype: TextureType, width, height, depth: int, format: TextureFormat): TextureStorage =
proc newTextureStorage*(ttype: TextureType, width, height, depth: int, format: TextureFormat, existing_resource: pointer = nil): TextureStorage =
var ts = new TextureStorage
ts.unit = -1
ts.target = case ttype:
@ -197,9 +198,13 @@ proc newTextureStorage*(ttype: TextureType, width, height, depth: int, format: T
# of Depth_u24_s8: GL_UNSIGNED_INT
ts.layer = 0
ts.tile_size = vec2(1,1)
var tex: GLuint
glGenTextures(1, addr tex)
ts.tex = tex.GPUTexture
if existing_resource == nil:
var tex: GLuint
glGenTextures(1, addr tex)
ts.tex = tex.GPUTexture
else:
# TODO: Do we need a way to remove it without calling the destructor?
ts.tex = cast[uint32](existing_resource).GPUTexture
return ts
proc preallocate(self: Texture) =
@ -394,9 +399,9 @@ proc setFilter*(self: Texture, filter: TextureFilter) =
glTexParameteri(self.storage.target, GL_TEXTURE_MAG_FILTER, mag_filter.GLint)
glTexParameteri(self.storage.target, GL_TEXTURE_MIN_FILTER, min_filter.GLint)
proc ensure_storage*(self: Texture) =
proc ensure_storage*(self: Texture, existing_resource: pointer = nil) =
if self.storage == nil:
self.storage = newTextureStorage(self.tex_type, self.width, self.height, self.depth, self.format)
self.storage = newTextureStorage(self.tex_type, self.width, self.height, self.depth, self.format, existing_resource)
self.setFilter self.filter
self.mipmap_range = (0, self.mipmapHigh)
@ -405,7 +410,8 @@ proc newTexture*(engine: MyouEngine, name: string,
format: TextureFormat,
tex_type: TextureType = Tex2D,
filter: TextureFilter = Trilinear,
pixels: ArrRef[float32] = nil): Texture =
pixels: ArrRef[float32] = nil,
existing_resource: pointer = nil): Texture =
result = new Texture
result.engine = engine
result.name = name
@ -421,7 +427,7 @@ proc newTexture*(engine: MyouEngine, name: string,
if width != 0 and height != 0:
let self = result
self.engine.renderer.enqueue proc()=
self.ensure_storage()
self.ensure_storage(existing_resource)
if pixels != nil:
self.loadFromPixelsPointer(pixels.toPointer)
else: