@@ -5,19 +5,28 @@ local gfx = require("arisu-gfx")
55--- @field framebuffer number
66--- @field id number ? # if nil, it is the backbuffer (default framebuffer)
77--- @field context gfx.gl.Context ? # only present if id is nil
8+ --- @field private descriptor gfx.TextureDescriptor
89local GLTexture = {}
910GLTexture .__index = GLTexture
1011
11- local formatMap = {
12+ local glInternalFormatMap = {
1213 [gfx .TextureFormat .Rgba8UNorm ] = gl .RGBA8 ,
1314}
1415
16+ local glFormatMap = {
17+ [gfx .TextureFormat .Rgba8UNorm ] = gl .RGBA ,
18+ }
19+
20+ local glTypeMap = {
21+ [gfx .TextureFormat .Rgba8UNorm ] = gl .UNSIGNED_BYTE ,
22+ }
23+
1524--- @param device gfx.gl.Device
1625--- @param descriptor gfx.TextureDescriptor
1726function GLTexture .new (device , descriptor )
1827 local levels = descriptor .mipLevelCount or 1
1928 local extents = descriptor .extents
20- local format = assert (formatMap [descriptor .format ], " Unsupported texture format" )
29+ local format = assert (glInternalFormatMap [descriptor .format ], " Unsupported texture format" )
2130
2231 local id --- @type number
2332 if extents .dim == " 1d" then
@@ -45,7 +54,52 @@ function GLTexture.new(device, descriptor)
4554 error (" Unsupported texture extents" )
4655 end
4756
48- return setmetatable ({ framebuffer = 0 , id = id }, GLTexture )
57+ return setmetatable ({ framebuffer = 0 , id = id , descriptor = descriptor }, GLTexture )
58+ end
59+
60+ --- @param desc gfx.TextureDataDescriptor
61+ --- @param data ffi.cdata*
62+ function GLTexture :writeData (desc , data )
63+ local extents = self .descriptor .extents
64+ local mip = desc .mip or 0
65+ local layer = desc .layer or 0
66+
67+ local format = assert (glFormatMap [self .descriptor .format ], " Unsupported texture format" )
68+ local type = assert (glTypeMap [self .descriptor .format ], " Unsupported texture format" )
69+
70+ data = data + (desc .offset or 0 )
71+ local bytesPerRow = desc .bytesPerRow
72+ local rowsPerImage = desc .rowsPerImage
73+
74+ local width = desc .width or extents .width
75+ local height = desc .height or extents .height
76+ local depth = desc .depth or extents .depth
77+
78+ gl .pixelStorei (gl .UNPACK_ALIGNMENT , 1 )
79+ gl .pixelStorei (gl .UNPACK_IMAGE_HEIGHT , rowsPerImage or 0 )
80+ gl .pixelStorei (gl .UNPACK_ROW_LENGTH , bytesPerRow and (bytesPerRow / 4 ) or 0 )
81+
82+ if extents .dim == " 1d" then
83+ if extents .count then
84+ gl .textureSubImage2D (self .id , mip , 0 , layer , width , 1 , format , type , data )
85+ else
86+ gl .textureSubImage1D (self .id , mip , 0 , width , format , type , data )
87+ end
88+ elseif extents .dim == " 2d" then
89+ if extents .count then
90+ gl .textureSubImage3D (self .id , mip , 0 , 0 , layer , width , height , 1 , format , type , data )
91+ else
92+ gl .textureSubImage2D (self .id , mip , 0 , 0 , width , height , format , type , data )
93+ end
94+ elseif extents .dim == " 3d" then
95+ gl .textureSubImage3D (self .id , mip , 0 , 0 , 0 , width , height , depth , format , type , data )
96+ else
97+ error (" Unsupported texture extents" )
98+ end
99+
100+ gl .pixelStorei (gl .UNPACK_ALIGNMENT , 4 )
101+ gl .pixelStorei (gl .UNPACK_IMAGE_HEIGHT , 0 )
102+ gl .pixelStorei (gl .UNPACK_ROW_LENGTH , 0 )
49103end
50104
51105--- @param framebuffer number
@@ -61,6 +115,15 @@ function GLTexture.forContextViewport(context)
61115end
62116
63117function GLTexture :destroy ()
118+ gl .deleteTextures ({ self .id })
119+ end
120+
121+ function GLTexture :__tostring ()
122+ if self .context then
123+ return " GLBackbuffer(" .. tostring (self .context ) .. " )"
124+ end
125+
126+ return " GLTexture(" .. tostring (self .id ) .. " )"
64127end
65128
66129return GLTexture
0 commit comments