diff --git a/minecraft.lua b/minecraft.lua index 5592360..7b08154 100644 --- a/minecraft.lua +++ b/minecraft.lua @@ -16,13 +16,15 @@ local cube_indices = { 6, 20, 7, 9, 21, 10, 12, 22, 13, - 15, 23, 16 + 15, 23, 16, } local cube_indices_count = #cube_indices local cube_index_buffer local blocks local shader_minecraft -local region_buffers = {} +local region_buffers +local terrain_texture +local block_id_to_texture_id_buffer local load_blocks_buffer = function(name) local data = love.filesystem.newFileData(name) @@ -43,6 +45,15 @@ local load_region_buffer = function(path) return buffer end +local load_block_id_to_texture_id_buffer = function() + local data = love.filesystem.newFileData("minecraft/block_id_to_texture_id.data") + local format = { + { format = "uint8vec4" }, + } + 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()) @@ -60,13 +71,23 @@ local load_minecraft_shader = function() return shader end +local load_terrain_texture = function() + local image_data = love.image.newImageData("minecraft/terrain.png") + local texture = love.graphics.newTexture(image_data) + return texture +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")) + region_buffers = { + load_region_buffer("minecraft/region.0.0.data"), + load_region_buffer("minecraft/region.-1.0.data"), + load_region_buffer("minecraft/region.0.-1.data"), + load_region_buffer("minecraft/region.-1.-1.data"), + } + terrain_texture = load_terrain_texture() cube_index_buffer = load_cube_index_buffer() shader_minecraft = load_minecraft_shader() + block_id_to_texture_id_buffer = load_block_id_to_texture_id_buffer() end local viewpos = { @@ -91,9 +112,12 @@ local draw = function(projection) local view_projection = view * projection + shader_minecraft:send("terrain_sampler", terrain_texture) + shader_minecraft:send("TexturesLayout", block_id_to_texture_id_buffer) + shader_minecraft:send("transform", "column", view_projection:data()) + 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 diff --git a/minecraft/block_id_to_texture_id.data b/minecraft/block_id_to_texture_id.data new file mode 100644 index 0000000..94099df Binary files /dev/null and b/minecraft/block_id_to_texture_id.data differ diff --git a/minecraft/terrain.png b/minecraft/terrain.png new file mode 100644 index 0000000..7a4f29f Binary files /dev/null and b/minecraft/terrain.png differ diff --git a/pixel_minecraft.glsl b/pixel_minecraft.glsl index 6b7d8fa..f70f0c0 100644 --- a/pixel_minecraft.glsl +++ b/pixel_minecraft.glsl @@ -1,22 +1,48 @@ #pragma language glsl4 in vec3 PixelNormal; -in vec3 PixelColor; +//in vec3 PixelColor; +in vec2 PixelTexture; in float PixelBlock; +uniform sampler2D terrain_sampler; + out vec4 out_color; +layout (std430) readonly buffer TexturesLayout +{ + uint Textures[]; +}; + void pixelmain() { - if (PixelBlock == 0) { + 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; + + //int t_ix = int(PixelBlock) / 4; + //int t_shift = (int(PixelBlock) % 4) * 8; + //int terrain_ix = int(Textures[t_ix] >> t_shift); + int terrain_ix = int(Textures[int(PixelBlock)]); + int terrain_x = terrain_ix % 16; + int terrain_y = terrain_ix / 16; + + ivec2 coord = ivec2(terrain_x, terrain_y) * 16; + coord += ivec2(int(PixelTexture.x * 16.0), int(PixelTexture.y * 16.0)); + + vec4 texture_color = texelFetch(terrain_sampler, coord, 0); + if (texture_color.w != 1.0) { discard; return; } - vec3 light_direction = normalize(vec3(-1, -0.5, 0.5)); - float diffuse_intensity = max(dot(PixelNormal, light_direction), 0.0); + if (int(PixelBlock) == 18) // leaves + texture_color.xyz *= vec3(0.125, 0.494, 0.027); - vec3 color = PixelColor * diffuse_intensity; - out_color = vec4(color, 1.0); + + //out_color = vec4(color, 1.0); + out_color = vec4((texture_color * diffuse_intensity).xyz, 1.0); + //out_color = vec4(diffuse_intensity); } diff --git a/vertex_minecraft.glsl b/vertex_minecraft.glsl index 6e4a39e..da41a02 100644 --- a/vertex_minecraft.glsl +++ b/vertex_minecraft.glsl @@ -1,39 +1,43 @@ #pragma language glsl4 struct vertex_t { - vec3 position; - vec3 normal; + vec3 Position; + vec3 Normal; + vec2 Texture; }; -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))); +vertex_t vertices[] = vertex_t[]( +vertex_t(vec3(-1.0, 1.0, -1.0), vec3(0.0, 1.0, 0.0), vec2(1.0, 0.0)), +vertex_t(vec3(1.0, 1.0, 1.0), vec3(0.0, 1.0, 0.0), vec2(0.0, 1.0)), +vertex_t(vec3(1.0, 1.0, -1.0), vec3(0.0, 1.0, 0.0), vec2(0.0, 0.0)), +vertex_t(vec3(1.0, 1.0, 1.0), vec3(0.0, 0.0, 1.0), vec2(1.0, 1.0)), +vertex_t(vec3(-1.0, -1.0, 1.0), vec3(0.0, 0.0, 1.0), vec2(0.0, 0.0)), +vertex_t(vec3(1.0, -1.0, 1.0), vec3(0.0, 0.0, 1.0), vec2(1.0, 0.0)), +vertex_t(vec3(-1.0, 1.0, 1.0), vec3(-1.0, 0.0, 0.0), vec2(1.0, 1.0)), +vertex_t(vec3(-1.0, -1.0, -1.0), vec3(-1.0, 0.0, 0.0), vec2(0.0, 0.0)), +vertex_t(vec3(-1.0, -1.0, 1.0), vec3(-1.0, 0.0, 0.0), vec2(1.0, 0.0)), +vertex_t(vec3(1.0, -1.0, -1.0), vec3(0.0, -1.0, 0.0), vec2(1.0, 0.0)), +vertex_t(vec3(-1.0, -1.0, 1.0), vec3(0.0, -1.0, 0.0), vec2(0.0, 1.0)), +vertex_t(vec3(-1.0, -1.0, -1.0), vec3(0.0, -1.0, 0.0), vec2(0.0, 0.0)), +vertex_t(vec3(1.0, 1.0, -1.0), vec3(1.0, 0.0, 0.0), vec2(1.0, 1.0)), +vertex_t(vec3(1.0, -1.0, 1.0), vec3(1.0, 0.0, 0.0), vec2(0.0, 0.0)), +vertex_t(vec3(1.0, -1.0, -1.0), vec3(1.0, 0.0, 0.0), vec2(1.0, 0.0)), +vertex_t(vec3(-1.0, 1.0, -1.0), vec3(0.0, 0.0, -1.0), vec2(1.0, 1.0)), +vertex_t(vec3(1.0, -1.0, -1.0), vec3(0.0, 0.0, -1.0), vec2(0.0, 0.0)), +vertex_t(vec3(-1.0, -1.0, -1.0), vec3(0.0, 0.0, -1.0), vec2(1.0, 0.0)), +vertex_t(vec3(-1.0, 1.0, 1.0), vec3(0.0, 1.0, 0.0), vec2(1.0, 1.0)), +vertex_t(vec3(-1.0, 1.0, 1.0), vec3(0.0, 0.0, 1.0), vec2(0.0, 1.0)), +vertex_t(vec3(-1.0, 1.0, -1.0), vec3(-1.0, 0.0, 0.0), vec2(0.0, 1.0)), +vertex_t(vec3(1.0, -1.0, 1.0), vec3(0.0, -1.0, 0.0), vec2(1.0, 1.0)), +vertex_t(vec3(1.0, 1.0, 1.0), vec3(1.0, 0.0, 0.0), vec2(0.0, 1.0)), +vertex_t(vec3(1.0, 1.0, -1.0), vec3(0.0, 0.0, -1.0), vec2(0.0, 1.0)) +); uniform mat4 transform; out vec3 PixelNormal; -out vec3 PixelColor; +//out vec3 PixelColor; +out vec2 PixelTexture; out float PixelBlock; struct block_t { @@ -46,6 +50,7 @@ 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); @@ -54,6 +59,7 @@ vec3 palette(float t) { return a + b * cos(6.28318 * (c * t + d)); } +*/ int sign_extend(uint x) { @@ -73,9 +79,10 @@ void vertexmain() 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); + 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)); + PixelTexture = vertex.Texture; + vec3 position = ((vertex.Position * 0.5) + vec3(x, z, y) + vec3(chunk_x * 16.0, chunk_z * 16.0, 0)); love_Position = transform * vec4(position, 1.0); }