diff --git a/zchunk.lua b/zchunk.lua index 41e7f6f..66ac193 100644 --- a/zchunk.lua +++ b/zchunk.lua @@ -61,7 +61,7 @@ end ---@param x integer? ---@param y integer? function zchunk:remove(x, y) - if not x then + if not x or not y then self._chunks = {} else local index = self:_chunk_index(x, y) @@ -72,7 +72,7 @@ end ---@param x integer? ---@param y integer? function zchunk:clear(x, y) - if not x then + if not x or not y then for _, chunk in pairs(self._chunks) do chunk.z:clear() end @@ -88,11 +88,12 @@ end --- Add an 'entity' to be rendered ---@param x number ---@param y number ----@param quad love.Quad +---@param quad love.Quad|fun(layer: integer): love.Quad ---@param layer_count integer ----@param color_map fun(layer: integer): number, number, number ----@param base_layer integer? -function zchunk:put(x, y, quad, layer_count, color_map, base_layer) +---@param color_map (fun(layer: integer): number, number, number, number)? +---@param offset_map (fun(layer: integer): integer, integer)? +---@param scale_map (fun(layer: integer): number)? +function zchunk:put(x, y, quad, layer_count, color_map, offset_map, scale_map) local index = self:_chunk_index(x, y) if not self._chunks[index] then self._chunks[index] = { @@ -100,7 +101,7 @@ function zchunk:put(x, y, quad, layer_count, color_map, base_layer) } self._chunks[index].z._height_scale = self._height_scale end - self._chunks[index].z:put(x, y, quad, layer_count, color_map, base_layer) + self._chunks[index].z:put(x, y, quad, layer_count, color_map, offset_map, scale_map) self._chunks[index].x = math.floor(x / self._chunk_size) self._chunks[index].y = math.floor(y / self._chunk_size) end diff --git a/zprite.lua b/zprite.lua index a150376..cc6a866 100644 --- a/zprite.lua +++ b/zprite.lua @@ -30,9 +30,9 @@ vec4 position(mat4 transform_projection, vec4 vertex_position) uint uv_y = bitfieldExtract(InstanceData.y, 10, 10); vec2 uv = vec2(uv_x, uv_y) / vec2(1024, 1024); - uint scale_x = bitfieldExtract(InstanceData.y, 20, 6); - uint scale_y = bitfieldExtract(InstanceData.y, 26, 6); - vec2 scale = vec2(scale_x, scale_y); + uint tex_scale_x = bitfieldExtract(InstanceData.y, 20, 6); + uint tex_scale_y = bitfieldExtract(InstanceData.y, 26, 6); + vec2 tex_scale = vec2(tex_scale_x, tex_scale_y); uint r = bitfieldExtract(InstanceData.z, 0, 8); uint g = bitfieldExtract(InstanceData.z, 8, 8); @@ -45,11 +45,15 @@ vec4 position(mat4 transform_projection, vec4 vertex_position) uint offset_y = bitfieldExtract(InstanceData.w, 16, 8); vec2 offset = (vec2(offset_x, offset_y) / vec2(128, 128)) - vec2(1, 1); + uint scale_xy = bitfieldExtract(InstanceData.w, 24, 8); + float scale = 1 + float(scale_xy) / 64.0; + vec2 pixel_offset = offset * vec2(layer * HeightScale, layer * HeightScale) / love_ScreenSize.xy; - vertex_position.xy *= scale; + vertex_position.xy *= tex_scale; + vertex_position.xy *= vec2(scale); vertex_position.xy += position; - VaryingTexCoord.xy *= scale; + VaryingTexCoord.xy *= tex_scale; VaryingTexCoord.xy += uv; VsColorOut = color; return (transform_projection * vertex_position) + vec4(pixel_offset, 0, 0); @@ -73,6 +77,10 @@ local function ZPRITE_DEFAULT_OFFSETMAP(_) return 0, 2 end +local function ZPRITE_DEFAULT_SCALEMAP(_) + return 0 +end + ---@param texture love.Image ---@param max_instances integer? function zprite.new(texture, max_instances) @@ -112,13 +120,15 @@ end ---@param layer_count integer ---@param color_map (fun(layer: integer): number, number, number, number)? ---@param offset_map (fun(layer: integer): integer, integer)? -function zprite:put(x, y, quad, layer_count, color_map, offset_map) +---@param scale_map (fun(layer: integer): number)? +function zprite:put(x, y, quad, layer_count, color_map, offset_map, scale_map) if #self._instances + layer_count > self._instance_vertex_count then return end - color_map = color_map and color_map or ZPRITE_DEFAULT_COLORMAP - offset_map = offset_map and offset_map or ZPRITE_DEFAULT_OFFSETMAP + color_map = color_map or ZPRITE_DEFAULT_COLORMAP + offset_map = offset_map or ZPRITE_DEFAULT_OFFSETMAP + scale_map = scale_map or ZPRITE_DEFAULT_SCALEMAP self._changed = true @@ -173,11 +183,11 @@ function zprite:put(x, y, quad, layer_count, color_map, offset_map) local uv_y = bit.lshift(bit.band(1024 * qy / th, 0x3FF), 10) local uv = bit.bor(uv_x, uv_y) - local scale_x = bit.lshift(bit.band(qw, 0x3F), 20) - local scale_y = bit.lshift(bit.band(qh, 0x3F), 26) - local scale = bit.bor(scale_x, scale_y) + local tex_scale_x = bit.lshift(bit.band(qw, 0x3F), 20) + local tex_scale_y = bit.lshift(bit.band(qh, 0x3F), 26) + local tex_scale = bit.bor(tex_scale_x, tex_scale_y) - local uv_scale = bit.bor(uv, scale) + local uv_scale = bit.bor(uv, tex_scale) local offset_x, offset_y = offset_map(i) local offset_x_b = bit.lshift(bit.band((offset_x + 1) / 2 * 0xFF, 0xFF), 8) @@ -185,12 +195,14 @@ function zprite:put(x, y, quad, layer_count, color_map, offset_map) local layer = bit.band(i, 0xFF) - local layer_offset = bit.bor(layer, offset_x_b, offset_y_b) + local scale = bit.lshift(bit.band(math.floor(scale_map(i) * 127.5), 0xFF), 24) + + local layer_offset_scale = bit.bor(layer, offset_x_b, offset_y_b, scale) table.insert(self._instances[i], pos) table.insert(self._instances[i], uv_scale) table.insert(self._instances[i], rgba) - table.insert(self._instances[i], layer_offset) + table.insert(self._instances[i], layer_offset_scale) end end