Add variable offset per layer
This commit is contained in:
parent
ace6a3cea9
commit
0ac6791e75
@ -115,7 +115,7 @@ function zchunk:draw(...)
|
|||||||
for _, chunk in pairs(self._chunks) do
|
for _, chunk in pairs(self._chunks) do
|
||||||
chunk.z:_upload()
|
chunk.z:_upload()
|
||||||
if chunk.z._instances[i] then
|
if chunk.z._instances[i] then
|
||||||
love.graphics.drawInstanced(chunk.z._meshes[i], #chunk.z._instances[i] / 3, ...)
|
love.graphics.drawInstanced(chunk.z._meshes[i], #chunk.z._instances[i] / 4, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
80
zprite.lua
80
zprite.lua
@ -16,7 +16,7 @@ local ZPRITE_SHADER = love.graphics.newShader([[
|
|||||||
varying vec4 VsColorOut;
|
varying vec4 VsColorOut;
|
||||||
|
|
||||||
#ifdef VERTEX
|
#ifdef VERTEX
|
||||||
layout (location = 3) attribute uvec3 InstanceData;
|
layout (location = 3) attribute uvec4 InstanceData;
|
||||||
|
|
||||||
uniform float HeightScale;
|
uniform float HeightScale;
|
||||||
|
|
||||||
@ -34,19 +34,25 @@ vec4 position(mat4 transform_projection, vec4 vertex_position)
|
|||||||
uint scale_y = bitfieldExtract(InstanceData.y, 26, 6);
|
uint scale_y = bitfieldExtract(InstanceData.y, 26, 6);
|
||||||
vec2 scale = vec2(scale_x, scale_y);
|
vec2 scale = vec2(scale_x, scale_y);
|
||||||
|
|
||||||
uint layer = bitfieldExtract(InstanceData.z, 0, 8);
|
uint r = bitfieldExtract(InstanceData.z, 0, 8);
|
||||||
|
uint g = bitfieldExtract(InstanceData.z, 8, 8);
|
||||||
|
uint b = bitfieldExtract(InstanceData.z, 16, 8);
|
||||||
|
uint a = bitfieldExtract(InstanceData.z, 24, 8);
|
||||||
|
vec4 color = vec4(r, g, b, a) / vec4(256, 256, 256, 256);
|
||||||
|
|
||||||
uint r = bitfieldExtract(InstanceData.z, 8, 8);
|
uint layer = bitfieldExtract(InstanceData.w, 0, 8);
|
||||||
uint g = bitfieldExtract(InstanceData.z, 16, 8);
|
uint offset_x = bitfieldExtract(InstanceData.w, 8, 4);
|
||||||
uint b = bitfieldExtract(InstanceData.z, 24, 8);
|
uint offset_y = bitfieldExtract(InstanceData.w, 12, 4);
|
||||||
vec3 color = vec3(r, g, b) / vec3(256, 256, 256);
|
vec2 offset = vec2(offset_x, offset_y) - vec2(8, 8);
|
||||||
|
|
||||||
|
vec2 pixel_offset = offset * vec2(layer * HeightScale, layer * HeightScale) / love_ScreenSize.xy;
|
||||||
|
|
||||||
vertex_position.xy *= scale;
|
vertex_position.xy *= scale;
|
||||||
vertex_position.xy += position;
|
vertex_position.xy += position;
|
||||||
VaryingTexCoord.xy *= scale;
|
VaryingTexCoord.xy *= scale;
|
||||||
VaryingTexCoord.xy += uv;
|
VaryingTexCoord.xy += uv;
|
||||||
VsColorOut = vec4(color, 1);
|
VsColorOut = color;
|
||||||
return (transform_projection * vertex_position) + vec4(0, (layer * HeightScale) / love_ScreenSize.y, 0, 0);
|
return (transform_projection * vertex_position) + vec4(pixel_offset, 0, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -60,7 +66,11 @@ vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords)
|
|||||||
]])
|
]])
|
||||||
|
|
||||||
local function ZPRITE_DEFAULT_COLORMAP(_)
|
local function ZPRITE_DEFAULT_COLORMAP(_)
|
||||||
return 1, 1, 1
|
return 1, 1, 1, 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ZPRITE_DEFAULT_OFFSETMAP(_)
|
||||||
|
return 0, 2
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param texture love.Image
|
---@param texture love.Image
|
||||||
@ -100,15 +110,15 @@ end
|
|||||||
---@param y number
|
---@param y number
|
||||||
---@param quad love.Quad|fun(layer: integer): love.Quad
|
---@param quad love.Quad|fun(layer: integer): love.Quad
|
||||||
---@param layer_count integer
|
---@param layer_count integer
|
||||||
---@param color_map (fun(layer: integer): integer, integer, integer)?
|
---@param color_map (fun(layer: integer): number, number, number, number)?
|
||||||
---@param base_layer integer?
|
---@param offset_map (fun(layer: integer): integer, integer)?
|
||||||
function zprite:put(x, y, quad, layer_count, color_map, base_layer)
|
function zprite:put(x, y, quad, layer_count, color_map, offset_map)
|
||||||
if #self._instances + layer_count > self._instance_vertex_count then
|
if #self._instances + layer_count > self._instance_vertex_count then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
base_layer = base_layer or 0
|
color_map = color_map and color_map or ZPRITE_DEFAULT_COLORMAP
|
||||||
color_map = color_map or ZPRITE_DEFAULT_COLORMAP
|
offset_map = offset_map and offset_map or ZPRITE_DEFAULT_OFFSETMAP
|
||||||
|
|
||||||
self._changed = true
|
self._changed = true
|
||||||
|
|
||||||
@ -117,15 +127,13 @@ function zprite:put(x, y, quad, layer_count, color_map, base_layer)
|
|||||||
local pos = bit.bor(pos_x, pos_y)
|
local pos = bit.bor(pos_x, pos_y)
|
||||||
|
|
||||||
for i = 1, layer_count do
|
for i = 1, layer_count do
|
||||||
if not self._instances[i + base_layer] then
|
if not self._instances[i] then
|
||||||
self._instances[i + base_layer] = {}
|
self._instances[i] = {}
|
||||||
if i > self._top_layer then
|
if i > self._top_layer then
|
||||||
self._top_layer = i
|
self._top_layer = i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local layer = bit.band(i + base_layer, 0xFF)
|
local r, g, b, a = color_map(i)
|
||||||
|
|
||||||
local r, g, b = color_map(i)
|
|
||||||
if r > 1 then
|
if r > 1 then
|
||||||
r = 1
|
r = 1
|
||||||
end
|
end
|
||||||
@ -144,13 +152,20 @@ function zprite:put(x, y, quad, layer_count, color_map, base_layer)
|
|||||||
if b < 0 then
|
if b < 0 then
|
||||||
b = 0
|
b = 0
|
||||||
end
|
end
|
||||||
local rb = bit.lshift(bit.band(r * 0xFF, 0xFF), 8)
|
if a > 1 then
|
||||||
local gb = bit.lshift(bit.band(g * 0xFF, 0xFF), 16)
|
a = 1
|
||||||
local bb = bit.lshift(bit.band(b * 0xFF, 0xFF), 24)
|
end
|
||||||
|
if a < 0 then
|
||||||
|
a = 0
|
||||||
|
end
|
||||||
|
local rb = bit.lshift(bit.band(r * 0xFF, 0xFF), 0)
|
||||||
|
local gb = bit.lshift(bit.band(g * 0xFF, 0xFF), 8)
|
||||||
|
local bb = bit.lshift(bit.band(b * 0xFF, 0xFF), 16)
|
||||||
|
local ab = bit.lshift(bit.band(a * 0xFF, 0xFF), 24)
|
||||||
|
|
||||||
local layer_rgb = bit.bor(bit.bor(layer, rb), bit.bor(gb, bb))
|
local rgba = bit.bor(rb, gb, bb, ab)
|
||||||
|
|
||||||
local q = type(quad) == "function" and quad(layer) or quad
|
local q = type(quad) == "function" and quad(i) or quad
|
||||||
local qx, qy, qw, qh = q:getViewport()
|
local qx, qy, qw, qh = q:getViewport()
|
||||||
local tw, th = self._texture:getPixelDimensions()
|
local tw, th = self._texture:getPixelDimensions()
|
||||||
|
|
||||||
@ -164,9 +179,18 @@ function zprite:put(x, y, quad, layer_count, color_map, base_layer)
|
|||||||
|
|
||||||
local uv_scale = bit.bor(uv, scale)
|
local uv_scale = bit.bor(uv, scale)
|
||||||
|
|
||||||
|
local offset_x, offset_y = offset_map(i)
|
||||||
|
local offset_x_b = bit.lshift(bit.band(offset_x - 8, 0xF), 8)
|
||||||
|
local offset_y_b = bit.lshift(bit.band(offset_y - 8, 0xF), 12)
|
||||||
|
|
||||||
|
local layer = bit.band(i, 0xFF)
|
||||||
|
|
||||||
|
local layer_offset = bit.bor(layer, offset_x_b, offset_y_b)
|
||||||
|
|
||||||
table.insert(self._instances[i], pos)
|
table.insert(self._instances[i], pos)
|
||||||
table.insert(self._instances[i], uv_scale)
|
table.insert(self._instances[i], uv_scale)
|
||||||
table.insert(self._instances[i], layer_rgb)
|
table.insert(self._instances[i], rgba)
|
||||||
|
table.insert(self._instances[i], layer_offset)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -180,7 +204,7 @@ function zprite:draw(...)
|
|||||||
|
|
||||||
for i = 1, self._top_layer do
|
for i = 1, self._top_layer do
|
||||||
if self._instances[i] then
|
if self._instances[i] then
|
||||||
love.graphics.drawInstanced(self._meshes[i], #self._instances[i] / 3, ...)
|
love.graphics.drawInstanced(self._meshes[i], #self._instances[i] / 4, ...)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -208,11 +232,11 @@ function zprite:_upload()
|
|||||||
}, vertices, "strip", "static")
|
}, vertices, "strip", "static")
|
||||||
self._meshes[i]:setTexture(self._texture)
|
self._meshes[i]:setTexture(self._texture)
|
||||||
self._instance_buffers[i] = love.graphics.newBuffer({
|
self._instance_buffers[i] = love.graphics.newBuffer({
|
||||||
{ name = "InstanceData", format = "uint32vec3", location = 3 },
|
{ name = "InstanceData", format = "uint32vec4", location = 3 },
|
||||||
}, self._instance_vertex_count, { vertex = true })
|
}, self._instance_vertex_count, { vertex = true })
|
||||||
self._meshes[i]:attachAttribute(3, self._instance_buffers[i], "perinstance")
|
self._meshes[i]:attachAttribute(3, self._instance_buffers[i], "perinstance")
|
||||||
end
|
end
|
||||||
self._instance_buffers[i]:setArrayData(self._instances[i], 1, 1, #self._instances[i] / 3)
|
self._instance_buffers[i]:setArrayData(self._instances[i], 1, 1, #self._instances[i] / 4)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self._changed = false
|
self._changed = false
|
||||||
|
Loading…
x
Reference in New Issue
Block a user