grandlecturn

This commit is contained in:
Zack Buhman 2026-03-19 00:35:00 -05:00
parent 527d4f5472
commit a5a304bcae
34 changed files with 1311592 additions and 1311524 deletions

View File

@ -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

View File

@ -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);

View File

@ -21,6 +21,7 @@ namespace world {
struct world_id {
enum {
LOVE2DWORLD = 0,
GRANDLECTURN = 1,
};
};

View File

@ -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)

View 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,,,,
1 name block id data linear texture index custom mesh properties notes
2 Grass 2 0,1 1 "data" is "0 (zero)" if unspecified
3 Dirt 3 1 "custom mesh" is "cube" if unspecified
4 Wooden Planks 5 4 "linear texture index" is invalid if unspecified
5 Trunk 17 5 "properties" is (empty) if unspecified
6 Trunk 17 1 5
7 Birch Block 17 2 6
8 Leaves 18 12
9 Leaves 18 1 12
10 Leaves 18 2 12
11 Leaves 18 3 12
12 Unused 20 11
13 Door Bottom 21 18
14 Door Top 22 17
15 Tall Grass 31 0,1 22 tall_grass
16 Tan Block 1 35 1 2
17 White Block 2 35 5 6 if you say so
18 Arch Bottom 35 6 10
19 Tan Block 2 35 8 3
20 White Block 1 35 9 21
21 Grey Bricks 35 10 8
22 Unused 35 10
23 Arch Top 35 14 9
24 Grey Bricks 1 35 15 8
25 White Block 3 35 7
26 Lilac Grass 37 15 tall_grass
27 Spider Plant 38 13 tall_grass
28 Spider Plant 39 13 tall_grass
29 Red Mushroom 40 14 custom_mushroom
30 Start/Finish Line 45 16
31 Shadow Block 49 20
32 Wall Torch 50 1,2,3,4 wall_torch emits_light
33 Candle 50 5 candle emits_light
34 Fence 85 0 4 fence
35 Lamp Block 89 19

View 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)

View File

@ -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
View 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

View File

@ -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

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

File diff suppressed because one or more lines are too long

BIN
minecraft/terrain2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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));
}
}

View File

@ -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);
}
*/
}
}
}

View File

@ -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()

View File

@ -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)));
}

View File

@ -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]));
}