grandlecturn
This commit is contained in:
parent
527d4f5472
commit
a5a304bcae
1
Makefile
1
Makefile
@ -19,6 +19,7 @@ LDFLAGS += $(shell pkg-config --libs glfw3)
|
||||
|
||||
MINECRAFT_OBJS = \
|
||||
minecraft/love2dworld/inthash.o \
|
||||
minecraft/grandlecturn/inthash.o \
|
||||
src/minecraft.o \
|
||||
src/world/world.o \
|
||||
src/world/entry_table.o
|
||||
|
||||
@ -26,6 +26,7 @@ struct target_name {
|
||||
POSITION = 0,
|
||||
NORMAL = 1,
|
||||
COLOR = 2,
|
||||
BLOCK = 3,
|
||||
};
|
||||
};
|
||||
|
||||
@ -57,9 +58,12 @@ void init_geometry_buffer(geometry_buffer<render_target_count>& geometry_buffer,
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, types[i].attachment, GL_TEXTURE_2D, geometry_buffer.target[i], 0);
|
||||
}
|
||||
static_assert(render_target_count == 3);
|
||||
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
|
||||
glDrawBuffers(3, attachments); // bound to GL_DRAW_FRAMEBUFFER
|
||||
static_assert(render_target_count <= 8);
|
||||
static GLenum const attachments[8] = {
|
||||
GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3,
|
||||
GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5, GL_COLOR_ATTACHMENT6, GL_COLOR_ATTACHMENT7,
|
||||
};
|
||||
glDrawBuffers(render_target_count, attachments); // bound to GL_DRAW_FRAMEBUFFER
|
||||
|
||||
glGenRenderbuffers(1, &geometry_buffer.renderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, geometry_buffer.renderbuffer);
|
||||
|
||||
@ -21,6 +21,7 @@ namespace world {
|
||||
struct world_id {
|
||||
enum {
|
||||
LOVE2DWORLD = 0,
|
||||
GRANDLECTURN = 1,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
7
main.lua
7
main.lua
@ -115,8 +115,11 @@ function love.run()
|
||||
|
||||
draw()
|
||||
|
||||
local x, y = love.mouse.getPosition()
|
||||
--test.update_mouse(x, y)
|
||||
local mouse_down = love.mouse.isDown(1)
|
||||
if mouse_down then
|
||||
local x, y = love.mouse.getPosition()
|
||||
test.update_mouse(x, y)
|
||||
end
|
||||
|
||||
love.graphics.present()
|
||||
love.timer.sleep(0.001)
|
||||
|
||||
35
minecraft/gen/block_ids.csv
Normal file
35
minecraft/gen/block_ids.csv
Normal file
@ -0,0 +1,35 @@
|
||||
name,block id,data,linear texture index,custom mesh,properties,,notes
|
||||
Grass,2,"0,1",1,,,,"""data"" is ""0 (zero)"" if unspecified"
|
||||
Dirt,3,,1,,,,"""custom mesh"" is ""cube"" if unspecified"
|
||||
Wooden Planks,5,,4,,,,"""linear texture index"" is invalid if unspecified"
|
||||
Trunk,17,,5,,,,"""properties"" is (empty) if unspecified"
|
||||
Trunk,17,1,5,,,,
|
||||
Birch Block,17,2,6,,,,
|
||||
Leaves,18,,12,,,,
|
||||
Leaves,18,1,12,,,,
|
||||
Leaves,18,2,12,,,,
|
||||
Leaves,18,3,12,,,,
|
||||
Unused,20,,11,,,,
|
||||
Door Bottom,21,,18,,,,
|
||||
Door Top,22,,17,,,,
|
||||
Tall Grass,31,"0,1",22,tall_grass,,,
|
||||
Tan Block 1,35,1,2,,,,
|
||||
White Block 2,35,5,6,,,,if you say so
|
||||
Arch Bottom,35,6,10,,,,
|
||||
Tan Block 2,35,8,3,,,,
|
||||
White Block 1,35,9,21,,,,
|
||||
Grey Bricks,35,10,8,,,,
|
||||
Unused,35,10,,,,,
|
||||
Arch Top,35,14,9,,,,
|
||||
Grey Bricks 1,35,15,8,,,,
|
||||
White Block 3,35,,7,,,,
|
||||
Lilac Grass,37,,15,tall_grass,,,
|
||||
Spider Plant,38,,13,tall_grass,,,
|
||||
Spider Plant,39,,13,tall_grass,,,
|
||||
Red Mushroom,40,,14,custom_mushroom,,,
|
||||
Start/Finish Line,45,,16,,,,
|
||||
Shadow Block,49,,20,,,,
|
||||
Wall Torch,50,"1,2,3,4",,wall_torch,emits_light,,
|
||||
Candle,50,5,,candle,emits_light,,
|
||||
Fence,85,0,4,fence,,,
|
||||
Lamp Block,89,,19,,,,
|
||||
|
81
minecraft/gen/block_ids.py
Normal file
81
minecraft/gen/block_ids.py
Normal file
@ -0,0 +1,81 @@
|
||||
import csv
|
||||
from dataclasses import dataclass
|
||||
import data
|
||||
|
||||
@dataclass
|
||||
class Decl:
|
||||
name: str
|
||||
block_id: int
|
||||
data: int
|
||||
linear_texture_index: str
|
||||
custom_mesh: str
|
||||
properties: set[str]
|
||||
|
||||
def decls():
|
||||
with open("block_ids.csv", "r") as f:
|
||||
reader = csv.reader(f)
|
||||
rows = list(reader)
|
||||
|
||||
header = ('name', 'block id', 'data', 'linear texture index', 'custom mesh', 'properties')
|
||||
assert tuple(rows[0][:len(header)]) == header, rows[0]
|
||||
data_rows = rows[1:]
|
||||
for name, block_id, data, texture_index, custom_mesh, properties, *_ in data_rows:
|
||||
block_id = int(block_id)
|
||||
texture_index = (int(texture_index) - 1) if texture_index.strip() != '' else 62
|
||||
custom_mesh = custom_mesh if custom_mesh.strip() != '' else 'cube'
|
||||
properties = set(properties.split(','))
|
||||
if ',' in data:
|
||||
for d in data.split(","):
|
||||
yield Decl(name, block_id, int(d), texture_index, custom_mesh, properties)
|
||||
else:
|
||||
data = int(data) if data.strip() != '' else 0
|
||||
yield Decl(name, block_id, data, texture_index, custom_mesh, properties)
|
||||
|
||||
def key_block_id_data(decl):
|
||||
return decl.block_id, decl.data
|
||||
|
||||
sorted_decls = list(sorted(decls(), key=key_block_id_data))
|
||||
by_id_data = {
|
||||
(decl.block_id, decl.data): decl
|
||||
for decl in sorted_decls
|
||||
}
|
||||
|
||||
default_decl = Decl(
|
||||
name = "_undefined",
|
||||
block_id = 999,
|
||||
data = 111,
|
||||
linear_texture_index = 62,
|
||||
custom_mesh = "cube",
|
||||
properties = set(),
|
||||
)
|
||||
|
||||
def is_neighbor_block(block_id, block_data):
|
||||
if block_id == data.BlockID.AIR:
|
||||
return False
|
||||
decl = by_id_data.get((block_id, block_data), default_decl)
|
||||
return decl.custom_mesh == 'cube'
|
||||
|
||||
def is_light_source(block_id, block_data):
|
||||
decl = by_id_data.get((block_id, block_data), default_decl)
|
||||
return 'emits_light' in decl.properties
|
||||
|
||||
def is_cube_block(block_id, block_data):
|
||||
decl = by_id_data.get((block_id, block_data), default_decl)
|
||||
return decl.custom_mesh == 'cube'
|
||||
|
||||
sorted_custom_mesh = list(sorted(set(decl.custom_mesh for decl in sorted_decls if decl.custom_mesh != "cube")))
|
||||
custom_mesh_index = {
|
||||
custom_mesh: index
|
||||
for index, custom_mesh in enumerate(sorted_custom_mesh)
|
||||
}
|
||||
|
||||
def get_custom_mesh_index(block_id, block_data):
|
||||
decl = by_id_data.get((block_id, block_data), default_decl)
|
||||
return custom_mesh_index[decl.custom_mesh]
|
||||
|
||||
def get_texture_id(block_id, block_data):
|
||||
decl = by_id_data.get((block_id, block_data), default_decl)
|
||||
return decl.linear_texture_index
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(sorted_custom_mesh)
|
||||
@ -10,8 +10,7 @@ import mcregion
|
||||
import vec3
|
||||
import vertex_buffer
|
||||
import data
|
||||
|
||||
FAST = "FAST" in os.environ
|
||||
import block_ids
|
||||
|
||||
def wrap_n(nc, chunk_c):
|
||||
if nc < 0:
|
||||
@ -22,35 +21,11 @@ def wrap_n(nc, chunk_c):
|
||||
chunk_c = chunk_c + 1
|
||||
return nc, chunk_c
|
||||
|
||||
# check vertex_buffer.py for model order
|
||||
custom_blocks = [
|
||||
{ # "tallgrass" model
|
||||
data.BlockID.TALL_GRASS,
|
||||
data.BlockID.MUSHROOM_1,
|
||||
data.BlockID.FLOWER,
|
||||
data.BlockID.ROSE,
|
||||
data.BlockID.SAPLING,
|
||||
},
|
||||
{ # "fence" model
|
||||
data.BlockID.FENCE,
|
||||
},
|
||||
{ # "torch" model
|
||||
data.BlockID.TORCH,
|
||||
},
|
||||
{ # "wheat" model
|
||||
data.BlockID.WHEAT,
|
||||
},
|
||||
{ # "custom-mushroom" model
|
||||
data.BlockID.MUSHROOM_2,
|
||||
},
|
||||
]
|
||||
|
||||
non_solid_blocks = set(chain.from_iterable(custom_blocks))
|
||||
|
||||
hack_non_solid_blocks = set([
|
||||
data.BlockID.LADDER,
|
||||
data.BlockID.WIRE,
|
||||
])
|
||||
def decode_block_data(level_table, chunk_x, chunk_z, block_index):
|
||||
block_data = level_table[(chunk_x, chunk_z)].data[block_index // 2]
|
||||
#block_data = (block_data >> (1 - (block_index % 2)) * 4) & 0xf
|
||||
block_data = (block_data >> (block_index % 2) * 4) & 0xf
|
||||
return block_data
|
||||
|
||||
def neighbor_exists(level_table, chunk_x, chunk_z, nx, ny, nz):
|
||||
if ny > 127 or ny < 0:
|
||||
@ -64,22 +39,23 @@ def neighbor_exists(level_table, chunk_x, chunk_z, nx, ny, nz):
|
||||
return True
|
||||
n_block_index = mcregion.block_index_from_xyz(nx, ny, nz)
|
||||
n_block_id = level_table[key].blocks[n_block_index]
|
||||
|
||||
has_neighbor = (n_block_id != data.BlockID.AIR) and (n_block_id not in non_solid_blocks) and (n_block_id not in hack_non_solid_blocks)
|
||||
return has_neighbor
|
||||
n_block_data = decode_block_data(level_table, chunk_x, chunk_z, n_block_index)
|
||||
return block_ids.is_neighbor_block(n_block_id, n_block_data)
|
||||
|
||||
def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
||||
block_id = level_table[(chunk_x, chunk_z)].blocks[block_index]
|
||||
if block_id == data.BlockID.AIR or block_id == data.BlockID.BEDROCK:
|
||||
return
|
||||
|
||||
block_data = level_table[(chunk_x, chunk_z)].data[block_index // 2]
|
||||
block_data = (block_data >> (1 - (block_index % 2)) * 4) & 0xf
|
||||
block_data = decode_block_data(level_table, chunk_x, chunk_z, block_index)
|
||||
|
||||
xyz = mcregion.xyz_from_block_index(block_index)
|
||||
|
||||
center_position = vec3.add(xyz, (chunk_x * 16, 0, chunk_z * 16))
|
||||
|
||||
if not block_ids.is_cube_block(block_id, block_data):
|
||||
yield center_position, block_id, block_data, None
|
||||
return
|
||||
|
||||
def find_non_neighbors():
|
||||
for i, normal in enumerate(vertex_buffer.normals):
|
||||
neighbor = vec3.add(normal, xyz)
|
||||
@ -87,15 +63,13 @@ def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
||||
yield i
|
||||
|
||||
normal_indices = list(find_non_neighbors())
|
||||
if block_id in non_solid_blocks or block_id in hack_non_solid_blocks or normal_indices:
|
||||
if normal_indices:
|
||||
yield center_position, block_id, block_data, normal_indices
|
||||
|
||||
def devoxelize_region(level_table, level_table_keys):
|
||||
for chunk_x, chunk_z in level_table_keys:
|
||||
for block_index in range(128 * 16 * 16):
|
||||
yield from block_neighbors(level_table, chunk_x, chunk_z, block_index)
|
||||
if FAST:
|
||||
return
|
||||
|
||||
def build_level_table(level_table, mem, locations):
|
||||
for location in locations:
|
||||
@ -121,11 +95,10 @@ def build_block_configuration_table():
|
||||
indices.extend(vertex_buffer.faces_by_normal[vertex_buffer.normals[j]])
|
||||
yield indices
|
||||
|
||||
def pack_instance_data(position, block_id, block_data):
|
||||
packed = struct.pack("<hhhBB",
|
||||
position[0], position[1], position[2],
|
||||
block_id,
|
||||
block_data)
|
||||
def pack_instance_data(position, block_id, block_data, texture_id):
|
||||
packed = struct.pack("<hhhhhhhh",
|
||||
position[0], position[1], position[2], 0,
|
||||
block_id, block_data, texture_id, 0)
|
||||
return packed
|
||||
|
||||
def pack_light_data(position, block_id):
|
||||
@ -135,22 +108,16 @@ def pack_light_data(position, block_id):
|
||||
def build_block_instances(blocks):
|
||||
by_configuration = defaultdict(list)
|
||||
|
||||
deferred_blocks = defaultdict(list)
|
||||
non_cube_blocks = defaultdict(list)
|
||||
|
||||
light_sources = []
|
||||
|
||||
def is_deferred_block(position, block_id, block_data):
|
||||
for i, custom_block_types in enumerate(custom_blocks):
|
||||
if block_id in custom_block_types:
|
||||
deferred_blocks[i].append((position, block_id, block_data))
|
||||
return True
|
||||
return False
|
||||
|
||||
for position, block_id, block_data, normal_indices in blocks:
|
||||
if block_id == data.BlockID.TORCH:
|
||||
light_sources.append((position, block_id))
|
||||
if is_deferred_block(position, block_id, block_data):
|
||||
assert block_id in non_solid_blocks
|
||||
if block_ids.is_light_source(block_id, block_data):
|
||||
light_sources.append((position, block_id, block_data))
|
||||
if not block_ids.is_cube_block(block_id, block_data):
|
||||
#custom_mesh_index = block_ids.get_custom_mesh_index(block_id, block_data)
|
||||
#non_cube_blocks[custom_mesh_index].append((position, block_id, block_data))
|
||||
continue
|
||||
configuration = normal_indices_as_block_configuration(normal_indices)
|
||||
by_configuration[configuration].append((position, block_id, block_data))
|
||||
@ -168,21 +135,22 @@ def build_block_instances(blocks):
|
||||
_blocks = by_configuration[configuration]
|
||||
configuration_instance_count_offset.append((len(_blocks), offset))
|
||||
for position, block_id, block_data in _blocks:
|
||||
assert block_id not in non_solid_blocks, block_id
|
||||
packed = pack_instance_data(position, block_id, block_data)
|
||||
texture_id = block_ids.get_texture_id(block_id, block_data)
|
||||
packed = pack_instance_data(position, block_id, block_data, texture_id)
|
||||
f.write(packed)
|
||||
offset += len(packed)
|
||||
|
||||
######################################################################
|
||||
# non-cubes
|
||||
######################################################################
|
||||
for custom_block_ix in range(len(custom_blocks)):
|
||||
for custom_block_ix in range(len(block_ids.sorted_custom_mesh)):
|
||||
nc_offset = offset
|
||||
nc_instance_count = 0
|
||||
for position, block_id, block_data in deferred_blocks[custom_block_ix]:
|
||||
assert block_id in non_solid_blocks, block_id
|
||||
packed = pack_instance_data(position, block_id, block_data)
|
||||
for position, block_id, block_data in non_cube_blocks[custom_block_ix]:
|
||||
texture_id = block_ids.get_texture_id(block_id, block_data)
|
||||
packed = pack_instance_data(position, block_id, block_data, texture_id)
|
||||
f.write(packed)
|
||||
assert len(packed) == 16
|
||||
offset += len(packed)
|
||||
nc_instance_count += 1
|
||||
configuration_instance_count_offset.append((nc_instance_count, nc_offset))
|
||||
@ -193,7 +161,7 @@ def build_block_instances(blocks):
|
||||
f.write(struct.pack("<ii", instance_count, offset))
|
||||
|
||||
with open(f"{data_path}.lights.vtx", "wb") as f:
|
||||
for position, block_id in light_sources:
|
||||
for position, block_id, block_data in light_sources:
|
||||
packed = pack_light_data(position, block_id)
|
||||
f.write(packed)
|
||||
|
||||
@ -266,9 +234,6 @@ def main(mcr_path, data_path, all_paths_path):
|
||||
level_table_from_path(level_table, path)
|
||||
|
||||
main2(level_table, level_table_keys)
|
||||
#import cProfile
|
||||
#cProfile.runctx("main2(level_table, level_table_keys)", {},
|
||||
# {"level_table_keys": level_table_keys, "level_table": level_table, "main2": main2})
|
||||
|
||||
mcr_path = sys.argv[1]
|
||||
data_path = sys.argv[2]
|
||||
|
||||
31
minecraft/gen/stairs.obj
Normal file
31
minecraft/gen/stairs.obj
Normal file
@ -0,0 +1,31 @@
|
||||
# Blender 4.5.7 LTS
|
||||
# www.blender.org
|
||||
o Cube
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vn 0.7071 0.7071 -0.0000
|
||||
vn -1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -1.0000 -0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vt 1.000000 1.000000
|
||||
vt 1.000000 0.000000
|
||||
vt 0.000000 0.000000
|
||||
vt -0.000000 0.000000
|
||||
vt 1.000000 -0.000000
|
||||
vt 0.000000 -0.000000
|
||||
vt -0.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
s 0
|
||||
f 5/1/1 6/2/1 2/3/1
|
||||
f 3/1/2 2/4/2 1/5/2
|
||||
f 5/1/3 4/4/3 6/5/3
|
||||
f 1/6/4 6/1/4 4/7/4
|
||||
f 1/3/5 4/2/5 3/1/5
|
||||
f 3/1/2 5/8/2 2/4/2
|
||||
f 5/1/3 3/8/3 4/4/3
|
||||
f 1/6/4 2/2/4 6/1/4
|
||||
@ -1,4 +1,4 @@
|
||||
/home/bilbo/Love2DWorld/region/r.0.0.mcr
|
||||
/home/bilbo/Love2DWorld/region/r.-1.-1.mcr
|
||||
/home/bilbo/Love2DWorld/region/r.0.-1.mcr
|
||||
/home/bilbo/Love2DWorld/region/r.-1.0.mcr
|
||||
/home/bilbo/GrandLecturn/region/r.0.0.mcr
|
||||
/home/bilbo/GrandLecturn/region/r.-1.-1.mcr
|
||||
/home/bilbo/GrandLecturn/region/r.0.-1.mcr
|
||||
/home/bilbo/GrandLecturn/region/r.-1.0.mcr
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2537570
minecraft/love2dworld/map.txt
2537570
minecraft/love2dworld/map.txt
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 12 KiB |
95
minecraft/terrain2.data
Normal file
95
minecraft/terrain2.data
Normal file
File diff suppressed because one or more lines are too long
BIN
minecraft/terrain2.png
Normal file
BIN
minecraft/terrain2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -7,49 +7,34 @@ in VS_OUT {
|
||||
vec2 Texture;
|
||||
flat int BlockID;
|
||||
flat int Data;
|
||||
flat int TextureID;
|
||||
} fs_in;
|
||||
|
||||
layout (location = 0) out vec3 Position;
|
||||
layout (location = 1) out vec3 Normal;
|
||||
layout (location = 2) out vec3 Color;
|
||||
layout (location = 3) out vec3 Block;
|
||||
|
||||
uniform sampler2D TerrainSampler;
|
||||
uniform vec3 MousePosition;
|
||||
uniform vec3 MousePosition2;
|
||||
|
||||
layout (std140) uniform TextureID
|
||||
{
|
||||
ivec4 block_id_to_texture_id[256 / 4];
|
||||
};
|
||||
|
||||
int wool[16] = int[16]( 64, // 0 64
|
||||
210, // 32 208
|
||||
194, // 32 192
|
||||
178, // 32 176
|
||||
162, // 32 160
|
||||
146, // 32 144
|
||||
130, // 32 128
|
||||
114, // 32 112
|
||||
225, // 16 224
|
||||
209, // 16 208
|
||||
193, // 16 192
|
||||
177, // 16 176
|
||||
161, // 16 160
|
||||
145, // 16 144
|
||||
129, // 16 128
|
||||
113 // 16 112
|
||||
);
|
||||
|
||||
void main()
|
||||
{
|
||||
int terrain_ix;
|
||||
if (fs_in.BlockID == 35) // cloth
|
||||
terrain_ix = wool[fs_in.Data];
|
||||
else
|
||||
terrain_ix = block_id_to_texture_id[fs_in.BlockID / 4][fs_in.BlockID % 4];
|
||||
int texture_id = fs_in.TextureID;
|
||||
if (fs_in.BlockID == 2) // grass
|
||||
texture_id = 0;
|
||||
if (fs_in.BlockID == 50 && fs_in.Data == 0) // ?
|
||||
texture_id = 61;
|
||||
if (fs_in.BlockID == 18)
|
||||
texture_id = 11;
|
||||
if (fs_in.BlockID == 21)
|
||||
texture_id = 17;
|
||||
if (fs_in.BlockID == 22)
|
||||
texture_id = 16;
|
||||
|
||||
int terrain_x = terrain_ix % 16;
|
||||
int terrain_y = terrain_ix / 16;
|
||||
int terrain_x = texture_id % 8;
|
||||
int terrain_y = texture_id / 8;
|
||||
ivec2 coord = ivec2(terrain_x, terrain_y) * 16;
|
||||
coord += ivec2(vec2(fs_in.Texture.x, 1.0 - fs_in.Texture.y) * 16.0);
|
||||
|
||||
@ -59,16 +44,8 @@ void main()
|
||||
return;
|
||||
}
|
||||
|
||||
if (fs_in.BlockID == 18 || fs_in.BlockID == 31) // leaves
|
||||
texture_color.xyz *= vec3(0.125, 0.494, 0.027);
|
||||
|
||||
Position = fs_in.Position.xzy;
|
||||
Position = fs_in.BlockPosition.xzy;
|
||||
Normal = normalize(fs_in.Normal.xzy);
|
||||
|
||||
if (length(fs_in.BlockPosition - floor(MousePosition.xzy)) < 1)
|
||||
Color = vec3(0, 1, 0);
|
||||
else if (length(fs_in.BlockPosition - floor(MousePosition.xzy)) <= 1)
|
||||
Color = vec3(0, 0.5, 0);
|
||||
else
|
||||
Color = texture_color.xyz;
|
||||
Color = texture_color.xyz;
|
||||
Block = vec3(fs_in.BlockID, fs_in.Data, fs_in.TextureID);
|
||||
}
|
||||
|
||||
@ -6,8 +6,9 @@ in vec3 Normal;
|
||||
in vec2 Texture;
|
||||
// per-instance:
|
||||
in vec3 BlockPosition;
|
||||
in float BlockID;
|
||||
in float Data;
|
||||
in int BlockID;
|
||||
in int Data;
|
||||
in int TextureID;
|
||||
|
||||
out VS_OUT {
|
||||
vec3 Position;
|
||||
@ -16,6 +17,7 @@ out VS_OUT {
|
||||
vec2 Texture;
|
||||
flat int BlockID;
|
||||
flat int Data;
|
||||
flat int TextureID;
|
||||
} vs_out;
|
||||
|
||||
uniform mat4 Transform;
|
||||
@ -28,8 +30,9 @@ void main()
|
||||
vs_out.BlockPosition = BlockPosition;
|
||||
vs_out.Normal = Normal;
|
||||
vs_out.Texture = Texture;
|
||||
vs_out.BlockID = int(BlockID);
|
||||
vs_out.Data = int(Data);
|
||||
vs_out.BlockID = BlockID;
|
||||
vs_out.Data = Data;
|
||||
vs_out.TextureID = TextureID;
|
||||
|
||||
gl_Position = Transform * vec4(position.xzy, 1.0);
|
||||
}
|
||||
|
||||
10
src/hud.cpp
10
src/hud.cpp
@ -20,6 +20,9 @@ extern float last_frame_time;
|
||||
// - load_quad_index_buffer
|
||||
// - empty_vertex_array_object
|
||||
|
||||
extern float mouse_position[3];
|
||||
extern float mouse_block[3];
|
||||
|
||||
namespace hud {
|
||||
|
||||
template <typename T, typename... Args>
|
||||
@ -100,6 +103,7 @@ namespace hud {
|
||||
*/
|
||||
|
||||
y = draw_vector(ter_best, buf, y, "eye", view::state.eye);
|
||||
y = draw_vector(ter_best, buf, y, "at", view::state.at);
|
||||
y = draw_vector(ter_best, buf, y, "forward", view::state.forward);
|
||||
|
||||
labeled_value<float>(buf, "pitch: ", "%.4f", view::state.pitch);
|
||||
@ -109,6 +113,10 @@ namespace hud {
|
||||
labeled_value<float>(buf, "frame_rate_avg: ", "%.2f", 1.0f / update_average(current_time - last_frame_time));
|
||||
font::draw_string(ter_best, buf, 10, y);
|
||||
y += ter_best.desc->glyph_height;
|
||||
}
|
||||
|
||||
font::draw_string(ter_best, "mouse:", 10, y);
|
||||
y += ter_best.desc->glyph_height;
|
||||
y = draw_vector(ter_best, buf, y, " position", XMLoadFloat3((XMFLOAT3*)mouse_position));
|
||||
y = draw_vector(ter_best, buf, y, " block", XMLoadFloat3((XMFLOAT3*)mouse_block));
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,16 +22,12 @@ namespace minecraft {
|
||||
unsigned int block_position;
|
||||
unsigned int block_id;
|
||||
unsigned int data;
|
||||
unsigned int texture_id;
|
||||
} attrib;
|
||||
struct {
|
||||
unsigned int transform;
|
||||
unsigned int terrain_sampler;
|
||||
|
||||
unsigned int texture_id;
|
||||
} uniform;
|
||||
struct {
|
||||
unsigned int texture_id;
|
||||
} binding;
|
||||
};
|
||||
|
||||
static unsigned int program;
|
||||
@ -40,16 +36,14 @@ namespace minecraft {
|
||||
static unsigned int vertex_array_object;
|
||||
static unsigned int per_vertex_buffer;
|
||||
|
||||
static const int per_instance_size = 4 + (1 * 4);
|
||||
static const int per_instance_size = (3 + 1 + 3 + 1) * 2;
|
||||
static const int per_vertex_size = (3 + 3 + 2) * 2;
|
||||
|
||||
static unsigned int index_buffer;
|
||||
|
||||
static unsigned int texture;
|
||||
|
||||
static unsigned int texture_id_uniform_buffer;
|
||||
|
||||
static const int world_count = 1;
|
||||
static const int world_count = 2;
|
||||
static world::state world_state[world_count];
|
||||
world::state * current_world;
|
||||
|
||||
@ -66,25 +60,22 @@ namespace minecraft {
|
||||
location.attrib.block_position = glGetAttribLocation(program, "BlockPosition");
|
||||
location.attrib.block_id = glGetAttribLocation(program, "BlockID");
|
||||
location.attrib.data = glGetAttribLocation(program, "Data");
|
||||
location.attrib.texture_id = glGetAttribLocation(program, "TextureID");
|
||||
printf("minecraft program:\n");
|
||||
printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n block_id %u\n data %u\n",
|
||||
printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n block_id %u\n data %u\n texture_id %u\n",
|
||||
location.attrib.position,
|
||||
location.attrib.normal,
|
||||
location.attrib.texture,
|
||||
location.attrib.block_position,
|
||||
location.attrib.block_id,
|
||||
location.attrib.data);
|
||||
location.attrib.data,
|
||||
location.attrib.texture_id);
|
||||
|
||||
location.uniform.transform = glGetUniformLocation(program, "Transform");
|
||||
location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler");
|
||||
location.uniform.texture_id = glGetUniformBlockIndex(program, "TextureID");
|
||||
printf(" uniforms:\n transform %u\n terrain_sampler %u\n texture_id %u\n",
|
||||
printf(" uniforms:\n transform %u\n terrain_sampler %u\n",
|
||||
location.uniform.transform,
|
||||
location.uniform.terrain_sampler,
|
||||
location.uniform.texture_id);
|
||||
|
||||
location.binding.texture_id = 0;
|
||||
glUniformBlockBinding(program, location.uniform.texture_id, location.binding.texture_id);
|
||||
location.uniform.terrain_sampler);
|
||||
}
|
||||
|
||||
void load_vertex_attributes()
|
||||
@ -112,13 +103,17 @@ namespace minecraft {
|
||||
glVertexAttribBinding(location.attrib.block_position, 1);
|
||||
|
||||
glEnableVertexAttribArray(location.attrib.block_id);
|
||||
glVertexAttribFormat(location.attrib.block_id, 1, GL_UNSIGNED_BYTE, GL_FALSE, 6);
|
||||
glVertexAttribIFormat(location.attrib.block_id, 1, GL_SHORT, 8);
|
||||
glVertexAttribBinding(location.attrib.block_id, 1);
|
||||
|
||||
glEnableVertexAttribArray(location.attrib.data);
|
||||
glVertexAttribFormat(location.attrib.data, 1, GL_UNSIGNED_BYTE, GL_FALSE, 7);
|
||||
glVertexAttribIFormat(location.attrib.data, 1, GL_SHORT, 10);
|
||||
glVertexAttribBinding(location.attrib.data, 1);
|
||||
|
||||
glEnableVertexAttribArray(location.attrib.texture_id);
|
||||
glVertexAttribIFormat(location.attrib.texture_id, 1, GL_SHORT, 12);
|
||||
glVertexAttribBinding(location.attrib.texture_id, 1);
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
@ -163,11 +158,11 @@ namespace minecraft {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
int texture_data_size;
|
||||
void * texture_data = read_file("minecraft/terrain.data", &texture_data_size);
|
||||
void * texture_data = read_file("minecraft/terrain2.data", &texture_data_size);
|
||||
assert(texture_data != NULL);
|
||||
|
||||
int width = 256;
|
||||
int height = 256;
|
||||
int width = 128;
|
||||
int height = 128;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data);
|
||||
|
||||
free(texture_data);
|
||||
@ -175,11 +170,6 @@ namespace minecraft {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void load_texture_id_uniform_buffer()
|
||||
{
|
||||
texture_id_uniform_buffer = load_uniform_buffer("minecraft/block_id_to_texture_id.data");
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// per-world load
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -188,6 +178,7 @@ namespace minecraft {
|
||||
{
|
||||
int data_size;
|
||||
void * data = read_file(path, &data_size);
|
||||
printf("%s %d %d %ld\n", path, data_size, world::instance_cfg_length, (sizeof (struct world::instance_cfg_entry)));
|
||||
assert(data_size == (sizeof (struct world::instance_cfg_entry)) * world::instance_cfg_length);
|
||||
memcpy(entries, data, data_size);
|
||||
}
|
||||
@ -260,20 +251,16 @@ namespace minecraft {
|
||||
|
||||
load_texture();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// uniform buffers
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
load_texture_id_uniform_buffer();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// worlds
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
for (int i = 0; i < world_count; i++) {
|
||||
if (i == 0)
|
||||
continue;
|
||||
per_world::load_world(&world::descriptors[i], world_state[i]);
|
||||
}
|
||||
current_world = &world_state[world::world_id::LOVE2DWORLD];
|
||||
current_world = &world_state[world::world_id::GRANDLECTURN];
|
||||
}
|
||||
|
||||
static inline int popcount(int x)
|
||||
@ -295,8 +282,6 @@ namespace minecraft {
|
||||
glUniformMatrix4fv(location.uniform.transform, 1, false, (float *)&view::state.float_transform);
|
||||
glUniform1i(location.uniform.terrain_sampler, 0);
|
||||
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, location.binding.texture_id, texture_id_uniform_buffer);
|
||||
|
||||
//glEnable(GL_CULL_FACE);
|
||||
//glCullFace(GL_FRONT);
|
||||
//glFrontFace(GL_CCW);
|
||||
@ -327,6 +312,7 @@ namespace minecraft {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// custom blocks
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
for (int i = 0; i < world::custom_block_types; i++) {
|
||||
int element_count = index_buffer_custom_offsets[i].count;
|
||||
const void * indices = (void *)(2 * (ptrdiff_t)index_buffer_custom_offsets[i].offset);
|
||||
@ -336,6 +322,7 @@ namespace minecraft {
|
||||
continue;
|
||||
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_SHORT, indices, instance_count, base_instance);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
64
src/test.cpp
64
src/test.cpp
@ -44,10 +44,6 @@ struct line_location {
|
||||
unsigned int transform;
|
||||
} uniform;
|
||||
};
|
||||
static unsigned int line_program;
|
||||
static line_location line_location;
|
||||
static unsigned int line_vertex_array_object;
|
||||
static unsigned int line_instance_buffer;
|
||||
|
||||
struct quad_location {
|
||||
struct {
|
||||
@ -71,11 +67,12 @@ float last_frame_time;
|
||||
|
||||
font::font * terminus_fonts;
|
||||
|
||||
geometry_buffer<3> geometry_buffer_pnc = {};
|
||||
static target_type const geometry_buffer_pnc_types[3] = {
|
||||
geometry_buffer<4> geometry_buffer_pnc = {};
|
||||
static target_type const geometry_buffer_pnc_types[4] = {
|
||||
[target_name::POSITION] = { GL_RGBA16F, GL_COLOR_ATTACHMENT0 },
|
||||
[target_name::NORMAL] = { GL_RGBA16F, GL_COLOR_ATTACHMENT1 },
|
||||
[target_name::COLOR] = { GL_RGBA8, GL_COLOR_ATTACHMENT2 },
|
||||
[target_name::BLOCK] = { GL_RGBA16F, GL_COLOR_ATTACHMENT3 },
|
||||
};
|
||||
|
||||
collada::instance_types::node * node_eye;
|
||||
@ -359,41 +356,6 @@ static inline int popcount(int x)
|
||||
return __builtin_popcount(x);
|
||||
}
|
||||
|
||||
/*
|
||||
void draw_line()
|
||||
{
|
||||
if (line_point_ix == 0)
|
||||
return;
|
||||
|
||||
glUseProgram(line_program);
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
|
||||
glUniformMatrix4fv(line_location.uniform.transform, 1, false, (float *)&view::state.float_transform);
|
||||
|
||||
//glEnable(GL_CULL_FACE);
|
||||
//glCullFace(GL_FRONT);
|
||||
//glFrontFace(GL_CCW);
|
||||
|
||||
glBindVertexArray(line_vertex_array_object);
|
||||
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
|
||||
int line_instance_vertex_size = (sizeof (short_point));
|
||||
glBindVertexBuffer(1, line_instance_buffer, 0, line_instance_vertex_size);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
||||
|
||||
int configuration = 63;
|
||||
int element_count = 6 * popcount(configuration);
|
||||
const void * indices = (void *)((ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx
|
||||
int instance_count = line_point_ix;
|
||||
int base_instance = 0;
|
||||
if (instance_count - base_instance <= 0)
|
||||
return;
|
||||
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_BYTE, indices, instance_count - base_instance, base_instance);
|
||||
}
|
||||
*/
|
||||
|
||||
int clamp(int n, int high)
|
||||
{
|
||||
if (n < 0)
|
||||
@ -403,14 +365,18 @@ int clamp(int n, int high)
|
||||
return n;
|
||||
}
|
||||
|
||||
float mouse_position[3] = {};
|
||||
float mouse_block[3] = {};
|
||||
|
||||
void update_mouse(int x, int y)
|
||||
{
|
||||
printf("update mouse %d %d\n", x, y);
|
||||
x = clamp(x, geometry_buffer_pnc.width);
|
||||
y = clamp(y, geometry_buffer_pnc.height);
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, geometry_buffer_pnc.framebuffer);
|
||||
glReadBuffer(geometry_buffer_pnc_types[target_name::POSITION].attachment);
|
||||
|
||||
/*
|
||||
x = clamp(x, geometry_buffer_pnc.width);
|
||||
y = clamp(y, geometry_buffer_pnc.height);
|
||||
glReadPixels(x,
|
||||
geometry_buffer_pnc.height - y,
|
||||
1, // width
|
||||
@ -418,7 +384,15 @@ void update_mouse(int x, int y)
|
||||
GL_RGB,
|
||||
GL_FLOAT,
|
||||
(void*)&mouse_position);
|
||||
*/
|
||||
|
||||
glReadBuffer(geometry_buffer_pnc_types[target_name::BLOCK].attachment);
|
||||
glReadPixels(x,
|
||||
geometry_buffer_pnc.height - y,
|
||||
1, // width
|
||||
1, // height
|
||||
GL_RGB,
|
||||
GL_FLOAT,
|
||||
(void*)&mouse_block);
|
||||
}
|
||||
|
||||
void draw()
|
||||
|
||||
@ -25,7 +25,11 @@ namespace world::entry_table {
|
||||
|
||||
for (int i = 0; i < entry_table_length; i++) {
|
||||
uint32_t ix = hash_func(entry[i].global_index);
|
||||
assert(entry_table[ix].global_index == 0);
|
||||
if (entry_table[ix].global_index != 0) {
|
||||
printf("collision hash(%d) = %d ; %d\n", entry[i].global_index, ix, entry_table[ix].global_index);
|
||||
assert(hash_func(entry_table[ix].global_index) == ix);
|
||||
}
|
||||
//assert(entry_table[ix].global_index == 0);
|
||||
memcpy(&entry_table[ix], &entry[i], (sizeof (global_entry_t)));
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,13 @@ namespace world {
|
||||
{ "minecraft/love2dworld/region.-1.-1.instance.vtx", "minecraft/love2dworld/region.-1.-1.instance.cfg" },
|
||||
};
|
||||
|
||||
static vtx_cfg const grandlecturn_vertex_paths[] = {
|
||||
{ "minecraft/grandlecturn/region.0.0.instance.vtx", "minecraft/grandlecturn/region.0.0.instance.cfg" },
|
||||
{ "minecraft/grandlecturn/region.-1.0.instance.vtx", "minecraft/grandlecturn/region.-1.0.instance.cfg" },
|
||||
{ "minecraft/grandlecturn/region.0.-1.instance.vtx", "minecraft/grandlecturn/region.0.-1.instance.cfg" },
|
||||
{ "minecraft/grandlecturn/region.-1.-1.instance.vtx", "minecraft/grandlecturn/region.-1.-1.instance.cfg" },
|
||||
};
|
||||
|
||||
descriptor const descriptors[] = {
|
||||
[world_id::LOVE2DWORLD] = {
|
||||
.region_count = 4,
|
||||
@ -17,6 +24,13 @@ namespace world {
|
||||
.lights_path = "minecraft/love2dworld/global.lights.vtx",
|
||||
.hash_func = love2dworld_hash,
|
||||
},
|
||||
[world_id::GRANDLECTURN] = {
|
||||
.region_count = 4,
|
||||
.vertex_paths = grandlecturn_vertex_paths,
|
||||
.entry_table_path = "minecraft/grandlecturn/global.dump",
|
||||
.lights_path = "minecraft/grandlecturn/global.lights.vtx",
|
||||
.hash_func = grandlecturn_hash,
|
||||
},
|
||||
};
|
||||
int const descriptors_length = (sizeof (descriptors)) / (sizeof (descriptors[0]));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user