love-demo/minecraft.lua

107 lines
3.1 KiB
Lua

local ffi = require "ffi"
local _math = require '_math'
local mat4 = _math.mat4
local vec3 = _math.vec3
local vec4 = _math.vec4
local cube_indices = {
0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10, 11,
12, 13, 14,
15, 16, 17,
0, 18, 1,
3, 19, 4,
6, 20, 7,
9, 21, 10,
12, 22, 13,
15, 23, 16
}
local cube_indices_count = #cube_indices
local cube_index_buffer
local blocks
local shader_minecraft
local region_buffers = {}
local load_blocks_buffer = function(name)
local data = love.filesystem.newFileData(name)
local format = {
{ format = "uint8vec4" },
}
local buffer = love.graphics.newBuffer(format, data, { shaderstorage = true, usage = "static" })
return buffer
end
local load_region_buffer = function(path)
local data = love.filesystem.newFileData(path)
local format = {
{ format = "uint8vec4" },
{ format = "uint32" },
}
local buffer = love.graphics.newBuffer(format, data, { shaderstorage = true, usage = "static" })
return buffer
end
local load_cube_index_buffer = function()
local data = love.data.newByteData(cube_indices_count * 4)
local ptr = ffi.cast("uint32_t*", data:getFFIPointer())
for i, index in ipairs(cube_indices) do
ptr[i - 1] = index
end
local buffer = love.graphics.newBuffer("uint32", data, { index = true, usage = "static" })
return buffer
end
local load_minecraft_shader = function()
local pixel_data = love.filesystem.newFileData("pixel_minecraft.glsl")
local vertex_data = love.filesystem.newFileData("vertex_minecraft.glsl")
local shader = love.graphics.newShader(pixel_data, vertex_data)
return shader
end
local init = function()
table.insert(region_buffers, load_region_buffer("minecraft/region.0.0.data"))
table.insert(region_buffers, load_region_buffer("minecraft/region.-1.0.data"))
table.insert(region_buffers, load_region_buffer("minecraft/region.0.-1.data"))
table.insert(region_buffers, load_region_buffer("minecraft/region.-1.-1.data"))
cube_index_buffer = load_cube_index_buffer()
shader_minecraft = load_minecraft_shader()
end
local viewpos = {
x = -4 * 31,
y = 0,
z = -4 * 31,
}
local draw = function(projection)
local view = mat4.look_at_rh(vec3(-50 + viewpos.x, -50 + viewpos.z, 100 + 50 + viewpos.y),
vec3(50 + viewpos.x, 50 + viewpos.z, 50 + viewpos.y),
vec3(0, 0, 1))
love.graphics.setCanvas()
love.graphics.setDepthMode("always", true)
love.graphics.setShader(shader_clear)
love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1)
love.graphics.setDepthMode("greater", true)
love.graphics.setShader(shader_minecraft)
local view_projection = view * projection
for _, region_buffer in ipairs(region_buffers) do
local instance_count = math.floor(region_buffer:getSize() / (4 * 2))
shader_minecraft:send("transform", "column", view_projection:data())
shader_minecraft:send("BlocksLayout", region_buffer)
love.graphics.drawFromShader(cube_index_buffer, cube_indices_count, instance_count, 1)
end
end
return {
viewpos = viewpos,
init = init,
draw = draw,
}