add minecraft region rendering demo
This commit is contained in:
parent
761a0073ef
commit
8bc64d418a
@ -21,7 +21,7 @@ local pixel_ssao = love.filesystem.newFileData("pixel_ssao.glsl")
|
|||||||
local shader_ssao = love.graphics.newShader(pixel_ssao, vertex_screen)
|
local shader_ssao = love.graphics.newShader(pixel_ssao, vertex_screen)
|
||||||
|
|
||||||
local pixel_clear = love.filesystem.newFileData("pixel_clear.glsl")
|
local pixel_clear = love.filesystem.newFileData("pixel_clear.glsl")
|
||||||
local shader_clear = love.graphics.newShader(pixel_clear, vertex_screen)
|
shader_clear = love.graphics.newShader(pixel_clear, vertex_screen)
|
||||||
|
|
||||||
local pixel_blur = love.filesystem.newFileData("pixel_blur.glsl")
|
local pixel_blur = love.filesystem.newFileData("pixel_blur.glsl")
|
||||||
local shader_blur = love.graphics.newShader(pixel_blur, vertex_screen)
|
local shader_blur = love.graphics.newShader(pixel_blur, vertex_screen)
|
||||||
|
|||||||
45
main.lua
45
main.lua
@ -1,6 +1,3 @@
|
|||||||
local rotation
|
|
||||||
local texture
|
|
||||||
|
|
||||||
local ffi = require 'ffi'
|
local ffi = require 'ffi'
|
||||||
local _math = require '_math'
|
local _math = require '_math'
|
||||||
local mat4 = _math.mat4
|
local mat4 = _math.mat4
|
||||||
@ -21,6 +18,10 @@ local terminus_font
|
|||||||
|
|
||||||
local update_global_parameters = require "update_global_parameters"
|
local update_global_parameters = require "update_global_parameters"
|
||||||
|
|
||||||
|
local minecraft = require "minecraft"
|
||||||
|
|
||||||
|
local joysticks
|
||||||
|
|
||||||
local scenes = {
|
local scenes = {
|
||||||
sci_fi_ship = {
|
sci_fi_ship = {
|
||||||
descriptor = scene_sci_fi_ship.descriptor,
|
descriptor = scene_sci_fi_ship.descriptor,
|
||||||
@ -89,17 +90,23 @@ function init()
|
|||||||
load_screen_shader()
|
load_screen_shader()
|
||||||
|
|
||||||
terminus_font = font.load_font(font.fonts.ter_10x18)
|
terminus_font = font.load_font(font.fonts.ter_10x18)
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
-- minecraft
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
minecraft.init()
|
||||||
|
|
||||||
|
--
|
||||||
|
joysticks = love.joystick.getJoysticks()
|
||||||
end
|
end
|
||||||
|
|
||||||
local rotation = 0.0
|
|
||||||
local t = 0.0
|
local t = 0.0
|
||||||
|
|
||||||
local update = function(dt)
|
local update = function(dt)
|
||||||
|
|
||||||
collada_scene_animate.update(t, node_state)
|
collada_scene_animate.update(t, node_state)
|
||||||
t = t + 0.016 * 0.1
|
t = t + 0.016 * 0.1
|
||||||
|
|
||||||
rotation = rotation + 0.01
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local draw = function()
|
local draw = function()
|
||||||
@ -138,6 +145,14 @@ local keypressed = function(key, scancode, isrepeat)
|
|||||||
update_global_parameters.update_current_ix(function(v) return v - 1 end)
|
update_global_parameters.update_current_ix(function(v) return v - 1 end)
|
||||||
elseif key == "down" then
|
elseif key == "down" then
|
||||||
update_global_parameters.update_current_ix(function(v) return v + 1 end)
|
update_global_parameters.update_current_ix(function(v) return v + 1 end)
|
||||||
|
-- elseif key == "j" then
|
||||||
|
-- minecraft.viewpos.x = minecraft.viewpos.x - 5
|
||||||
|
-- elseif key == "l" then
|
||||||
|
-- minecraft.viewpos.x = minecraft.viewpos.x + 5
|
||||||
|
-- elseif key == "i" then
|
||||||
|
-- minecraft.viewpos.z = minecraft.viewpos.z - 5
|
||||||
|
-- elseif key == "k" then
|
||||||
|
-- minecraft.viewpos.z = minecraft.viewpos.z + 5
|
||||||
else
|
else
|
||||||
print(key)
|
print(key)
|
||||||
end
|
end
|
||||||
@ -165,8 +180,24 @@ function love.run()
|
|||||||
|
|
||||||
local dt = love.timer.step()
|
local dt = love.timer.step()
|
||||||
update(dt)
|
update(dt)
|
||||||
draw()
|
|
||||||
|
|
||||||
|
for _, joystick in ipairs(joysticks) do
|
||||||
|
local lx = joystick:getGamepadAxis("leftx")
|
||||||
|
local ly = joystick:getGamepadAxis("lefty")
|
||||||
|
local ry = joystick:getGamepadAxis("righty")
|
||||||
|
minecraft.viewpos.x = minecraft.viewpos.x + 2.5 * lx
|
||||||
|
minecraft.viewpos.y = minecraft.viewpos.y + -2.5 * ry
|
||||||
|
minecraft.viewpos.z = minecraft.viewpos.z + -2.5 * ly
|
||||||
|
end
|
||||||
|
|
||||||
|
--draw()
|
||||||
|
local width, height = love.graphics.getDimensions()
|
||||||
|
local aspect_ratio = width / height
|
||||||
|
local perspective_projection = mat4.perspective_fov_rh(scalar.convert_to_radians(45 * 0.75),
|
||||||
|
aspect_ratio,
|
||||||
|
1,
|
||||||
|
0.1)
|
||||||
|
minecraft.draw(perspective_projection)
|
||||||
love.graphics.present()
|
love.graphics.present()
|
||||||
love.timer.sleep(0.001)
|
love.timer.sleep(0.001)
|
||||||
end
|
end
|
||||||
|
|||||||
106
minecraft.lua
Normal file
106
minecraft.lua
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
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,
|
||||||
|
}
|
||||||
BIN
minecraft/region.-1.-1.data
Normal file
BIN
minecraft/region.-1.-1.data
Normal file
Binary file not shown.
BIN
minecraft/region.-1.0.data
Normal file
BIN
minecraft/region.-1.0.data
Normal file
Binary file not shown.
BIN
minecraft/region.0.-1.data
Normal file
BIN
minecraft/region.0.-1.data
Normal file
Binary file not shown.
BIN
minecraft/region.0.0.data
Normal file
BIN
minecraft/region.0.0.data
Normal file
Binary file not shown.
22
pixel_minecraft.glsl
Normal file
22
pixel_minecraft.glsl
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#pragma language glsl4
|
||||||
|
|
||||||
|
in vec3 PixelNormal;
|
||||||
|
in vec3 PixelColor;
|
||||||
|
in float PixelBlock;
|
||||||
|
|
||||||
|
out vec4 out_color;
|
||||||
|
|
||||||
|
void pixelmain()
|
||||||
|
{
|
||||||
|
if (PixelBlock == 0) {
|
||||||
|
discard;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 light_direction = normalize(vec3(-1, -0.5, 0.5));
|
||||||
|
float diffuse_intensity = max(dot(PixelNormal, light_direction), 0.0);
|
||||||
|
|
||||||
|
vec3 color = PixelColor * diffuse_intensity;
|
||||||
|
|
||||||
|
out_color = vec4(color, 1.0);
|
||||||
|
}
|
||||||
19
reasons_for_raw_opengl.txt
Normal file
19
reasons_for_raw_opengl.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Reason #1: Can't bind vertex attributes per draw call
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
While this can be mostly worked around with shader storage buffers and
|
||||||
|
the Love2D "drawFromShader" API, the format of shader storage buffers
|
||||||
|
must be defined using GLSL types.
|
||||||
|
|
||||||
|
GLSL has no sized integer or sized float type, which makes it
|
||||||
|
impossible to use, for example, vectors of uint8. uint8 is useful for
|
||||||
|
representing things like Minecraft Block IDs.
|
||||||
|
|
||||||
|
A workaround for the lack of sized scalars in shader storage buffers
|
||||||
|
is to use bit shifts on GLSL's uint(32) type, but this is fragile as
|
||||||
|
it makes the shader dependent on host endianness.
|
||||||
|
|
||||||
|
However, this is extremely awkward if a vector of signed 8-bit
|
||||||
|
integers is desired (as in signed Minecraft chunk x/z coordinates). A
|
||||||
|
workaround for this is to perform sign extension manually via GLSL
|
||||||
|
arithmetic.
|
||||||
81
vertex_minecraft.glsl
Normal file
81
vertex_minecraft.glsl
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#pragma language glsl4
|
||||||
|
|
||||||
|
struct vertex_t {
|
||||||
|
vec3 position;
|
||||||
|
vec3 normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
vertex_t vertices[] = vertex_t[](vertex_t(vec3(-1.0, 1.0, -1.0), vec3(0.0, 1.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, 1.0, 1.0), vec3(0.0, 1.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, 1.0, -1.0), vec3(0.0, 1.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, 1.0, 1.0), vec3(0.0, 0.0, 1.0)),
|
||||||
|
vertex_t(vec3(-1.0, -1.0, 1.0), vec3(0.0, 0.0, 1.0)),
|
||||||
|
vertex_t(vec3(1.0, -1.0, 1.0), vec3(0.0, 0.0, 1.0)),
|
||||||
|
vertex_t(vec3(-1.0, 1.0, 1.0), vec3(-1.0, 0.0, 0.0)),
|
||||||
|
vertex_t(vec3(-1.0, -1.0, -1.0), vec3(-1.0, 0.0, 0.0)),
|
||||||
|
vertex_t(vec3(-1.0, -1.0, 1.0), vec3(-1.0, 0.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, -1.0, -1.0), vec3(0.0, -1.0, 0.0)),
|
||||||
|
vertex_t(vec3(-1.0, -1.0, 1.0), vec3(0.0, -1.0, 0.0)),
|
||||||
|
vertex_t(vec3(-1.0, -1.0, -1.0), vec3(0.0, -1.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, 1.0, -1.0), vec3(1.0, 0.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, -1.0, 1.0), vec3(1.0, 0.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, -1.0, -1.0), vec3(1.0, 0.0, 0.0)),
|
||||||
|
vertex_t(vec3(-1.0, 1.0, -1.0), vec3(0.0, 0.0, -1.0)),
|
||||||
|
vertex_t(vec3(1.0, -1.0, -1.0), vec3(0.0, 0.0, -1.0)),
|
||||||
|
vertex_t(vec3(-1.0, -1.0, -1.0), vec3(0.0, 0.0, -1.0)),
|
||||||
|
vertex_t(vec3(-1.0, 1.0, 1.0), vec3(0.0, 1.0, 0.0)),
|
||||||
|
vertex_t(vec3(-1.0, 1.0, 1.0), vec3(0.0, 0.0, 1.0)),
|
||||||
|
vertex_t(vec3(-1.0, 1.0, -1.0), vec3(-1.0, 0.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, -1.0, 1.0), vec3(0.0, -1.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, 1.0, 1.0), vec3(1.0, 0.0, 0.0)),
|
||||||
|
vertex_t(vec3(1.0, 1.0, -1.0), vec3(0.0, 0.0, -1.0)));
|
||||||
|
|
||||||
|
uniform mat4 transform;
|
||||||
|
|
||||||
|
out vec3 PixelNormal;
|
||||||
|
out vec3 PixelColor;
|
||||||
|
out float PixelBlock;
|
||||||
|
|
||||||
|
struct block_t {
|
||||||
|
uint x_z_blockid;
|
||||||
|
uint block_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std430) readonly buffer BlocksLayout
|
||||||
|
{
|
||||||
|
block_t Blocks[];
|
||||||
|
};
|
||||||
|
|
||||||
|
vec3 palette(float t) {
|
||||||
|
vec3 a = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 b = vec3(0.5, 0.5, 0.5);
|
||||||
|
vec3 c = vec3(1.0, 1.0, 1.0);
|
||||||
|
vec3 d = vec3(0.263, 0.416, 0.557);
|
||||||
|
|
||||||
|
return a + b * cos(6.28318 * (c * t + d));
|
||||||
|
}
|
||||||
|
|
||||||
|
int sign_extend(uint x)
|
||||||
|
{
|
||||||
|
return int(((x + 0x80) & 0xff) - 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vertexmain()
|
||||||
|
{
|
||||||
|
vertex_t vertex = vertices[gl_VertexID];
|
||||||
|
|
||||||
|
block_t block = Blocks[int(gl_InstanceID)];
|
||||||
|
float x = float(block.block_index / (128 * 16));
|
||||||
|
float y = float(block.block_index % 128);
|
||||||
|
float z = float(int(block.block_index / 128) % 16);
|
||||||
|
|
||||||
|
float chunk_x = float(sign_extend((block.x_z_blockid >> 0) & 0xff));
|
||||||
|
float chunk_z = float(sign_extend((block.x_z_blockid >> 8) & 0xff));
|
||||||
|
int block_id = int((block.x_z_blockid >> 16) & 0xff);
|
||||||
|
|
||||||
|
PixelNormal = vertex.normal;
|
||||||
|
PixelColor = palette(float(block_id) * 0.01);
|
||||||
|
PixelBlock = block_id;
|
||||||
|
vec3 position = ((vertex.position * 0.4) + vec3(x, z, y) + vec3(chunk_x * 16.0, chunk_z * 16.0, 0));
|
||||||
|
love_Position = transform * vec4(position, 1.0);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user