minecraft: non-global world data model
This commit is contained in:
parent
2b379aa27c
commit
527d4f5472
12
Makefile
12
Makefile
@ -17,6 +17,12 @@ CFLAGS += -fno-strict-aliasing
|
|||||||
LDFLAGS += -lm
|
LDFLAGS += -lm
|
||||||
LDFLAGS += $(shell pkg-config --libs glfw3)
|
LDFLAGS += $(shell pkg-config --libs glfw3)
|
||||||
|
|
||||||
|
MINECRAFT_OBJS = \
|
||||||
|
minecraft/love2dworld/inthash.o \
|
||||||
|
src/minecraft.o \
|
||||||
|
src/world/world.o \
|
||||||
|
src/world/entry_table.o
|
||||||
|
|
||||||
OBJS = \
|
OBJS = \
|
||||||
src/gl.o \
|
src/gl.o \
|
||||||
src/opengl.o \
|
src/opengl.o \
|
||||||
@ -25,11 +31,8 @@ OBJS = \
|
|||||||
src/window.o \
|
src/window.o \
|
||||||
src/bresenham.o \
|
src/bresenham.o \
|
||||||
src/file.o \
|
src/file.o \
|
||||||
src/world.o \
|
|
||||||
src/inthash.o \
|
|
||||||
src/non_block.o \
|
src/non_block.o \
|
||||||
src/view.o \
|
src/view.o \
|
||||||
src/minecraft.o \
|
|
||||||
src/hud.o \
|
src/hud.o \
|
||||||
src/lighting.o \
|
src/lighting.o \
|
||||||
src/collision_scene.o \
|
src/collision_scene.o \
|
||||||
@ -44,7 +47,8 @@ OBJS = \
|
|||||||
data/scenes/ship20/ship20.o \
|
data/scenes/ship20/ship20.o \
|
||||||
data/scenes/noodle/noodle.o \
|
data/scenes/noodle/noodle.o \
|
||||||
data/scenes/shadow_test/shadow_test.o \
|
data/scenes/shadow_test/shadow_test.o \
|
||||||
data/scenes/book/book.o
|
data/scenes/book/book.o \
|
||||||
|
$(MINECRAFT_OBJS)
|
||||||
|
|
||||||
all: test.so
|
all: test.so
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "world/world.h"
|
||||||
|
|
||||||
namespace minecraft {
|
namespace minecraft {
|
||||||
|
extern world::state * current_world;
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
void draw();
|
void draw();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct global_entry {
|
|
||||||
int global_index;
|
|
||||||
uint8_t block_id;
|
|
||||||
uint8_t block_data;
|
|
||||||
uint16_t _padding;
|
|
||||||
} global_entry_t;
|
|
||||||
static_assert((sizeof (global_entry_t)) == 8);
|
|
||||||
|
|
||||||
void load_world();
|
|
||||||
global_entry_t * const world_lookup(int x, int y, int z);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
27
include/world/entry_table.h
Normal file
27
include/world/entry_table.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
namespace world::entry_table {
|
||||||
|
|
||||||
|
typedef struct global_entry {
|
||||||
|
int global_index;
|
||||||
|
uint8_t block_id;
|
||||||
|
uint8_t block_data;
|
||||||
|
uint16_t _padding;
|
||||||
|
} global_entry_t;
|
||||||
|
static_assert((sizeof (global_entry_t)) == 8);
|
||||||
|
|
||||||
|
typedef uint32_t (hash_func_t)(const int32_t key);
|
||||||
|
|
||||||
|
void load_entry_table(char const * const path,
|
||||||
|
global_entry_t ** out_entry_table,
|
||||||
|
int * out_entry_table_length,
|
||||||
|
hash_func_t * hash_func);
|
||||||
|
|
||||||
|
global_entry_t * const world_lookup(hash_func_t * hash_func,
|
||||||
|
global_entry_t * entry_table,
|
||||||
|
int entry_table_length,
|
||||||
|
int x, int y, int z);
|
||||||
|
}
|
||||||
@ -6,8 +6,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t
|
uint32_t love2dworld_hash(const int32_t key);
|
||||||
inthash(const int32_t key);
|
uint32_t grandlecturn_hash(const int32_t key);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
51
include/world/world.h
Normal file
51
include/world/world.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "world/entry_table.h"
|
||||||
|
|
||||||
|
namespace world {
|
||||||
|
struct vtx_cfg {
|
||||||
|
const char * vtx;
|
||||||
|
const char * cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct descriptor {
|
||||||
|
int const region_count;
|
||||||
|
vtx_cfg const * const vertex_paths;
|
||||||
|
char const * const entry_table_path;
|
||||||
|
char const * const lights_path;
|
||||||
|
entry_table::hash_func_t * hash_func;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct world_id {
|
||||||
|
enum {
|
||||||
|
LOVE2DWORLD = 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// also update index_buffer_custom_offsets in data.inc
|
||||||
|
const int custom_block_types = 5;
|
||||||
|
const int instance_cfg_length = 64 + custom_block_types;
|
||||||
|
|
||||||
|
struct instance_cfg_entry {
|
||||||
|
int count;
|
||||||
|
int offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct region {
|
||||||
|
unsigned int per_instance_vertex_buffer;
|
||||||
|
instance_cfg_entry instance_cfg[instance_cfg_length];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct state {
|
||||||
|
world::descriptor const * descriptor;
|
||||||
|
world::region * region; // malloc region_count
|
||||||
|
unsigned int light_uniform_buffer;
|
||||||
|
entry_table::global_entry_t * entry_table;
|
||||||
|
int entry_table_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern descriptor const descriptors[];
|
||||||
|
extern int const descriptors_length;
|
||||||
|
}
|
||||||
20
minecraft/gen/grandlecturn.sh
Normal file
20
minecraft/gen/grandlecturn.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
set -eux
|
||||||
|
#cd ./minecraft/gen
|
||||||
|
PYTHON=pypy3.11
|
||||||
|
cat <<EOF > ../grandlecturn/all_regions.txt
|
||||||
|
$HOME/GrandLecturn/region/r.0.0.mcr
|
||||||
|
$HOME/GrandLecturn/region/r.-1.-1.mcr
|
||||||
|
$HOME/GrandLecturn/region/r.0.-1.mcr
|
||||||
|
$HOME/GrandLecturn/region/r.-1.0.mcr
|
||||||
|
EOF
|
||||||
|
$PYTHON mc.py $HOME/GrandLecturn/region/r.0.0.mcr ../grandlecturn/region.0.0 ../grandlecturn/all_regions.txt &
|
||||||
|
$PYTHON mc.py $HOME/GrandLecturn/region/r.-1.-1.mcr ../grandlecturn/region.-1.-1 ../grandlecturn/all_regions.txt &
|
||||||
|
$PYTHON mc.py $HOME/GrandLecturn/region/r.0.-1.mcr ../grandlecturn/region.0.-1 ../grandlecturn/all_regions.txt &
|
||||||
|
$PYTHON mc.py $HOME/GrandLecturn/region/r.-1.0.mcr ../grandlecturn/region.-1.0 ../grandlecturn/all_regions.txt &
|
||||||
|
|
||||||
|
wait
|
||||||
|
|
||||||
|
cat ../grandlecturn/region*.lights.vtx > ../grandlecturn/global.lights.vtx
|
||||||
|
|
||||||
|
cat ../grandlecturn/region*.dump > ../grandlecturn/global.dump
|
||||||
|
$PYTHON intkeys.py ../grandlecturn/global.dump | $HOME/nbperf/nbperf -n grandlecturn_hash -I -a bpz -c 1.26 -m ../love2dworld/map.txt > ../grandlecturn/inthash.c
|
||||||
20
minecraft/gen/love2dworld.sh
Normal file
20
minecraft/gen/love2dworld.sh
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
set -eux
|
||||||
|
#cd ./minecraft/gen
|
||||||
|
PYTHON=pypy3.11
|
||||||
|
cat <<EOF > ../love2dworld/all_regions.txt
|
||||||
|
$HOME/Love2DWorld/region/r.0.0.mcr
|
||||||
|
$HOME/Love2DWorld/region/r.-1.-1.mcr
|
||||||
|
$HOME/Love2DWorld/region/r.0.-1.mcr
|
||||||
|
$HOME/Love2DWorld/region/r.-1.0.mcr
|
||||||
|
EOF
|
||||||
|
$PYTHON mc.py $HOME/Love2DWorld/region/r.0.0.mcr ../love2dworld/region.0.0 ../love2dworld/all_regions.txt &
|
||||||
|
$PYTHON mc.py $HOME/Love2DWorld/region/r.-1.-1.mcr ../love2dworld/region.-1.-1 ../love2dworld/all_regions.txt &
|
||||||
|
$PYTHON mc.py $HOME/Love2DWorld/region/r.0.-1.mcr ../love2dworld/region.0.-1 ../love2dworld/all_regions.txt &
|
||||||
|
$PYTHON mc.py $HOME/Love2DWorld/region/r.-1.0.mcr ../love2dworld/region.-1.0 ../love2dworld/all_regions.txt &
|
||||||
|
|
||||||
|
wait
|
||||||
|
|
||||||
|
cat ../love2dworld/region*.lights.vtx > ../love2dworld/global.lights.vtx
|
||||||
|
|
||||||
|
cat ../love2dworld/region*.dump > ../love2dworld/global.dump
|
||||||
|
$PYTHON intkeys.py ../love2dworld/global.dump | $HOME/nbperf/nbperf -n love2dworld_hash -I -a bpz -c 1.24 -m ../love2dworld/map.txt > ../love2dworld/inthash.c
|
||||||
@ -101,7 +101,7 @@ def build_level_table(level_table, mem, locations):
|
|||||||
for location in locations:
|
for location in locations:
|
||||||
try:
|
try:
|
||||||
level = mcregion.parse_location(mem, location)
|
level = mcregion.parse_location(mem, location)
|
||||||
except CountZeroException:
|
except mcregion.CountZeroException:
|
||||||
continue
|
continue
|
||||||
x, z = level.x_pos, level.z_pos
|
x, z = level.x_pos, level.z_pos
|
||||||
level_table[(x, z)] = level
|
level_table[(x, z)] = level
|
||||||
@ -209,13 +209,6 @@ def level_table_from_path(level_table, path):
|
|||||||
|
|
||||||
build_level_table(level_table, mem, locations)
|
build_level_table(level_table, mem, locations)
|
||||||
|
|
||||||
all_paths = [
|
|
||||||
"/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",
|
|
||||||
]
|
|
||||||
|
|
||||||
g_stride = 512 * 2
|
g_stride = 512 * 2
|
||||||
def from_global_index(i):
|
def from_global_index(i):
|
||||||
x, y, z = i % g_stride, i // (g_stride * g_stride), (i // g_stride) % g_stride
|
x, y, z = i % g_stride, i // (g_stride * g_stride), (i // g_stride) % g_stride
|
||||||
@ -256,7 +249,13 @@ def main2(level_table, level_table_keys):
|
|||||||
build_block_instances(blocks)
|
build_block_instances(blocks)
|
||||||
print("blocks_length:", len(blocks))
|
print("blocks_length:", len(blocks))
|
||||||
|
|
||||||
def main(mcr_path, data_path):
|
def parse_all_paths(path):
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
buf = f.read()
|
||||||
|
return set(l.strip() for l in buf.split('\n') if l.strip())
|
||||||
|
|
||||||
|
def main(mcr_path, data_path, all_paths_path):
|
||||||
|
all_paths = parse_all_paths(all_paths_path)
|
||||||
assert mcr_path in all_paths
|
assert mcr_path in all_paths
|
||||||
level_table = {}
|
level_table = {}
|
||||||
level_table_from_path(level_table, mcr_path)
|
level_table_from_path(level_table, mcr_path)
|
||||||
@ -273,4 +272,5 @@ def main(mcr_path, data_path):
|
|||||||
|
|
||||||
mcr_path = sys.argv[1]
|
mcr_path = sys.argv[1]
|
||||||
data_path = sys.argv[2]
|
data_path = sys.argv[2]
|
||||||
main(mcr_path, data_path)
|
all_paths_path = sys.argv[3]
|
||||||
|
main(mcr_path, data_path, all_paths_path)
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
set -eux
|
|
||||||
cd ./minecraft/gen
|
|
||||||
PYTHON=pypy3.11
|
|
||||||
$PYTHON mc.py ~/Love2DWorld/region/r.0.0.mcr ../region.0.0 &
|
|
||||||
$PYTHON mc.py ~/Love2DWorld/region/r.-1.-1.mcr ../region.-1.-1 &
|
|
||||||
$PYTHON mc.py ~/Love2DWorld/region/r.0.-1.mcr ../region.0.-1 &
|
|
||||||
$PYTHON mc.py ~/Love2DWorld/region/r.-1.0.mcr ../region.-1.0 &
|
|
||||||
|
|
||||||
wait
|
|
||||||
|
|
||||||
cat ../region*.lights.vtx > ../global.lights.vtx
|
|
||||||
|
|
||||||
cat ../region*.dump > ../global.dump
|
|
||||||
$PYTHON intkeys.py ../global.dump | ~/nbperf/nbperf -I -a bpz -c 1.24 -m map.txt > ../../src/inthash.c
|
|
||||||
4
minecraft/grandlecturn/all_regions.txt
Normal file
4
minecraft/grandlecturn/all_regions.txt
Normal file
@ -0,0 +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
|
||||||
BIN
minecraft/grandlecturn/global.dump
Normal file
BIN
minecraft/grandlecturn/global.dump
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/global.lights.vtx
Normal file
BIN
minecraft/grandlecturn/global.lights.vtx
Normal file
Binary file not shown.
42545
minecraft/grandlecturn/inthash.c
Normal file
42545
minecraft/grandlecturn/inthash.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
minecraft/grandlecturn/region.-1.-1.dump
Normal file
BIN
minecraft/grandlecturn/region.-1.-1.dump
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.-1.-1.instance.cfg
Normal file
BIN
minecraft/grandlecturn/region.-1.-1.instance.cfg
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.-1.-1.instance.vtx
Normal file
BIN
minecraft/grandlecturn/region.-1.-1.instance.vtx
Normal file
Binary file not shown.
0
minecraft/grandlecturn/region.-1.-1.lights.vtx
Normal file
0
minecraft/grandlecturn/region.-1.-1.lights.vtx
Normal file
BIN
minecraft/grandlecturn/region.-1.0.dump
Normal file
BIN
minecraft/grandlecturn/region.-1.0.dump
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.-1.0.instance.cfg
Normal file
BIN
minecraft/grandlecturn/region.-1.0.instance.cfg
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.-1.0.instance.vtx
Normal file
BIN
minecraft/grandlecturn/region.-1.0.instance.vtx
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.-1.0.lights.vtx
Normal file
BIN
minecraft/grandlecturn/region.-1.0.lights.vtx
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.0.-1.dump
Normal file
BIN
minecraft/grandlecturn/region.0.-1.dump
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.0.-1.instance.cfg
Normal file
BIN
minecraft/grandlecturn/region.0.-1.instance.cfg
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.0.-1.instance.vtx
Normal file
BIN
minecraft/grandlecturn/region.0.-1.instance.vtx
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.0.-1.lights.vtx
Normal file
BIN
minecraft/grandlecturn/region.0.-1.lights.vtx
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.0.0.dump
Normal file
BIN
minecraft/grandlecturn/region.0.0.dump
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.0.0.instance.cfg
Normal file
BIN
minecraft/grandlecturn/region.0.0.instance.cfg
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.0.0.instance.vtx
Normal file
BIN
minecraft/grandlecturn/region.0.0.instance.vtx
Normal file
Binary file not shown.
BIN
minecraft/grandlecturn/region.0.0.lights.vtx
Normal file
BIN
minecraft/grandlecturn/region.0.0.lights.vtx
Normal file
Binary file not shown.
4
minecraft/love2dworld/all_regions.txt
Normal file
4
minecraft/love2dworld/all_regions.txt
Normal file
@ -0,0 +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
|
||||||
@ -11,7 +11,7 @@
|
|||||||
#define HAVE_POPCOUNT64
|
#define HAVE_POPCOUNT64
|
||||||
#define popcount64 __builtin_popcountll
|
#define popcount64 __builtin_popcountll
|
||||||
#else
|
#else
|
||||||
static const uint8_t inthash_bits_per_byte[256] = {
|
static const uint8_t love2dworld_hash_bits_per_byte[256] = {
|
||||||
4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
|
4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
|
||||||
4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
|
4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
|
||||||
4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
|
4, 4, 4, 3, 4, 4, 4, 3, 4, 4, 4, 3, 3, 3, 3, 2,
|
||||||
@ -41,7 +41,7 @@ static inline void _inthash4(const int32_t key, uint64_t *h)
|
|||||||
#define GETI2(g, i) ((uint8_t)((g[i >> 2] >> ((i & 3) << 1U)) & 3))
|
#define GETI2(g, i) ((uint8_t)((g[i >> 2] >> ((i & 3) << 1U)) & 3))
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
inthash(const int32_t key)
|
love2dworld_hash(const int32_t key)
|
||||||
{
|
{
|
||||||
static const uint8_t g[560736] = {
|
static const uint8_t g[560736] = {
|
||||||
0x81, 0x43, 0xa9, 0xba, 0xf7, 0x18, 0xa3, 0xbf, 0x45, 0x80,
|
0x81, 0x43, 0xa9, 0xba, 0xf7, 0x18, 0xa3, 0xbf, 0x45, 0x80,
|
||||||
@ -59645,7 +59645,7 @@ inthash(const int32_t key)
|
|||||||
idx_b = idx_v >> 2;
|
idx_b = idx_v >> 2;
|
||||||
end_idx_b = vertex >> 2;
|
end_idx_b = vertex >> 2;
|
||||||
while (idx_b < end_idx_b)
|
while (idx_b < end_idx_b)
|
||||||
base_rank += inthash_bits_per_byte[*(g + idx_b++)];
|
base_rank += love2dworld_hash_bits_per_byte[*(g + idx_b++)];
|
||||||
idx_v = idx_b << 2;
|
idx_v = idx_b << 2;
|
||||||
while (idx_v < vertex)
|
while (idx_v < vertex)
|
||||||
{
|
{
|
||||||
1268856
minecraft/love2dworld/map.txt
Normal file
1268856
minecraft/love2dworld/map.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
minecraft/love2dworld/region.-1.-1.dump
Normal file
BIN
minecraft/love2dworld/region.-1.-1.dump
Normal file
Binary file not shown.
BIN
minecraft/love2dworld/region.-1.-1.lights.vtx
Normal file
BIN
minecraft/love2dworld/region.-1.-1.lights.vtx
Normal file
Binary file not shown.
BIN
minecraft/love2dworld/region.-1.0.dump
Normal file
BIN
minecraft/love2dworld/region.-1.0.dump
Normal file
Binary file not shown.
BIN
minecraft/love2dworld/region.-1.0.lights.vtx
Normal file
BIN
minecraft/love2dworld/region.-1.0.lights.vtx
Normal file
Binary file not shown.
BIN
minecraft/love2dworld/region.0.-1.dump
Normal file
BIN
minecraft/love2dworld/region.0.-1.dump
Normal file
Binary file not shown.
0
minecraft/love2dworld/region.0.-1.lights.vtx
Normal file
0
minecraft/love2dworld/region.0.-1.lights.vtx
Normal file
BIN
minecraft/love2dworld/region.0.0.dump
Normal file
BIN
minecraft/love2dworld/region.0.0.dump
Normal file
Binary file not shown.
BIN
minecraft/love2dworld/region.0.0.lights.vtx
Normal file
BIN
minecraft/love2dworld/region.0.0.lights.vtx
Normal file
Binary file not shown.
@ -38,8 +38,6 @@ namespace lighting {
|
|||||||
static unsigned int program;
|
static unsigned int program;
|
||||||
static location location;
|
static location location;
|
||||||
|
|
||||||
static unsigned int light_uniform_buffer;
|
|
||||||
|
|
||||||
void load_program()
|
void load_program()
|
||||||
{
|
{
|
||||||
program = compile_from_files("shader/quad.vert",
|
program = compile_from_files("shader/quad.vert",
|
||||||
@ -65,11 +63,6 @@ namespace lighting {
|
|||||||
glUniformBlockBinding(program, location.uniform.lights, location.binding.lights);
|
glUniformBlockBinding(program, location.uniform.lights, location.binding.lights);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_light_uniform_buffer()
|
|
||||||
{
|
|
||||||
light_uniform_buffer = load_uniform_buffer("minecraft/global.lights.vtx");
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool near_zero(float a)
|
static inline bool near_zero(float a)
|
||||||
{
|
{
|
||||||
return (fabsf(a) < 0.00001f);
|
return (fabsf(a) < 0.00001f);
|
||||||
@ -101,7 +94,7 @@ namespace lighting {
|
|||||||
XMStoreFloat3(&eye, view::state.eye);
|
XMStoreFloat3(&eye, view::state.eye);
|
||||||
glUniform3fv(location.uniform.eye, 1, (float*)&eye);
|
glUniform3fv(location.uniform.eye, 1, (float*)&eye);
|
||||||
|
|
||||||
glBindBufferBase(GL_UNIFORM_BUFFER, location.binding.lights, light_uniform_buffer);
|
//glBindBufferBase(GL_UNIFORM_BUFFER, location.binding.lights, light_uniform_buffer);
|
||||||
|
|
||||||
glBindVertexArray(empty_vertex_array_object);
|
glBindVertexArray(empty_vertex_array_object);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "minecraft.h"
|
#include "minecraft.h"
|
||||||
#include "minecraft_data.inc"
|
#include "minecraft_data.inc"
|
||||||
|
#include "new.h"
|
||||||
|
#include "world/world.h"
|
||||||
|
|
||||||
namespace minecraft {
|
namespace minecraft {
|
||||||
struct location {
|
struct location {
|
||||||
@ -35,21 +37,7 @@ namespace minecraft {
|
|||||||
static unsigned int program;
|
static unsigned int program;
|
||||||
static location location;
|
static location location;
|
||||||
|
|
||||||
struct char_tpl {
|
|
||||||
const char * vtx;
|
|
||||||
const char * cfg;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int region_count = 4;
|
|
||||||
static const char_tpl vertex_paths[] = {
|
|
||||||
{ "minecraft/region.0.0.instance.vtx", "minecraft/region.0.0.instance.cfg" },
|
|
||||||
{ "minecraft/region.-1.0.instance.vtx", "minecraft/region.-1.0.instance.cfg" },
|
|
||||||
{ "minecraft/region.0.-1.instance.vtx", "minecraft/region.0.-1.instance.cfg" },
|
|
||||||
{ "minecraft/region.-1.-1.instance.vtx", "minecraft/region.-1.-1.instance.cfg" },
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned int vertex_array_object;
|
static unsigned int vertex_array_object;
|
||||||
static unsigned int per_instance_vertex_buffers[region_count];
|
|
||||||
static unsigned int per_vertex_buffer;
|
static unsigned int per_vertex_buffer;
|
||||||
|
|
||||||
static const int per_instance_size = 4 + (1 * 4);
|
static const int per_instance_size = 4 + (1 * 4);
|
||||||
@ -57,23 +45,14 @@ namespace minecraft {
|
|||||||
|
|
||||||
static unsigned int index_buffer;
|
static unsigned int index_buffer;
|
||||||
|
|
||||||
// also update index_buffer_custom_offsets in data.inc
|
|
||||||
static const int custom_block_types = 5;
|
|
||||||
static const int instance_cfg_length = 64 + custom_block_types;
|
|
||||||
|
|
||||||
struct instance_cfg {
|
|
||||||
struct region_instance {
|
|
||||||
int instance_count;
|
|
||||||
int offset;
|
|
||||||
} cfg[instance_cfg_length];
|
|
||||||
};
|
|
||||||
|
|
||||||
static instance_cfg instance_cfg[region_count];
|
|
||||||
|
|
||||||
static unsigned int texture;
|
static unsigned int texture;
|
||||||
|
|
||||||
static unsigned int texture_id_uniform_buffer;
|
static unsigned int texture_id_uniform_buffer;
|
||||||
|
|
||||||
|
static const int world_count = 1;
|
||||||
|
static world::state world_state[world_count];
|
||||||
|
world::state * current_world;
|
||||||
|
|
||||||
void load_program()
|
void load_program()
|
||||||
{
|
{
|
||||||
program = compile_from_files("shader/minecraft.vert",
|
program = compile_from_files("shader/minecraft.vert",
|
||||||
@ -143,19 +122,6 @@ namespace minecraft {
|
|||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_per_instance_vertex_buffer(int i)
|
|
||||||
{
|
|
||||||
int vertex_buffer_data_size;
|
|
||||||
void * vertex_buffer_data = read_file(vertex_paths[i].vtx, &vertex_buffer_data_size);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, per_instance_vertex_buffers[i]);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_data_size, vertex_buffer_data, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
free(vertex_buffer_data);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_per_vertex_buffer()
|
void load_per_vertex_buffer()
|
||||||
{
|
{
|
||||||
glGenBuffers(1, &per_vertex_buffer);
|
glGenBuffers(1, &per_vertex_buffer);
|
||||||
@ -186,15 +152,6 @@ namespace minecraft {
|
|||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_instance_cfg(int i)
|
|
||||||
{
|
|
||||||
int data_size;
|
|
||||||
void * data = read_file(vertex_paths[i].cfg, &data_size);
|
|
||||||
assert(data_size == (sizeof (struct instance_cfg)));
|
|
||||||
|
|
||||||
memcpy(&instance_cfg[i], data, data_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_texture()
|
void load_texture()
|
||||||
{
|
{
|
||||||
glGenTextures(1, &texture);
|
glGenTextures(1, &texture);
|
||||||
@ -223,6 +180,61 @@ namespace minecraft {
|
|||||||
texture_id_uniform_buffer = load_uniform_buffer("minecraft/block_id_to_texture_id.data");
|
texture_id_uniform_buffer = load_uniform_buffer("minecraft/block_id_to_texture_id.data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// per-world load
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
namespace per_world {
|
||||||
|
static void load_instance_cfg(char const * path, world::instance_cfg_entry * entries)
|
||||||
|
{
|
||||||
|
int data_size;
|
||||||
|
void * data = read_file(path, &data_size);
|
||||||
|
assert(data_size == (sizeof (struct world::instance_cfg_entry)) * world::instance_cfg_length);
|
||||||
|
memcpy(entries, data, data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_per_instance_vertex_buffer(char const * path, unsigned int vertex_buffer)
|
||||||
|
{
|
||||||
|
int vertex_buffer_data_size;
|
||||||
|
void * vertex_buffer_data = read_file(path, &vertex_buffer_data_size); // vertex_paths[i].vtx
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer); //per_instance_vertex_buffers[i]
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_data_size, vertex_buffer_data, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
free(vertex_buffer_data);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_regions(world::descriptor const * const descriptor, world::region * region)
|
||||||
|
{
|
||||||
|
unsigned int per_instance_vertex_buffers[descriptor->region_count];
|
||||||
|
glGenBuffers(descriptor->region_count, per_instance_vertex_buffers);
|
||||||
|
for (int i = 0; i < descriptor->region_count; i++) {
|
||||||
|
// vtx
|
||||||
|
load_per_instance_vertex_buffer(descriptor->vertex_paths[i].vtx, per_instance_vertex_buffers[i]);
|
||||||
|
region[i].per_instance_vertex_buffer = per_instance_vertex_buffers[i];
|
||||||
|
|
||||||
|
// cfg
|
||||||
|
load_instance_cfg(descriptor->vertex_paths[i].cfg, region[i].instance_cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_world(world::descriptor const * const descriptor, world::state & state)
|
||||||
|
{
|
||||||
|
state.descriptor = descriptor;
|
||||||
|
state.region = New<world::region>(descriptor->region_count);
|
||||||
|
load_regions(descriptor, state.region);
|
||||||
|
|
||||||
|
state.light_uniform_buffer = load_uniform_buffer(descriptor->lights_path);
|
||||||
|
|
||||||
|
// collision data
|
||||||
|
world::entry_table::load_entry_table(descriptor->entry_table_path,
|
||||||
|
&state.entry_table,
|
||||||
|
&state.entry_table_length,
|
||||||
|
descriptor->hash_func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void load()
|
void load()
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -239,13 +251,6 @@ namespace minecraft {
|
|||||||
// per-vertex buffer
|
// per-vertex buffer
|
||||||
load_per_vertex_buffer();
|
load_per_vertex_buffer();
|
||||||
|
|
||||||
// per-instance buffer
|
|
||||||
glGenBuffers(region_count, per_instance_vertex_buffers);
|
|
||||||
for (int i = 0; i < region_count; i++) {
|
|
||||||
load_per_instance_vertex_buffer(i);
|
|
||||||
load_instance_cfg(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// index buffer
|
// index buffer
|
||||||
load_index_buffer();
|
load_index_buffer();
|
||||||
|
|
||||||
@ -260,6 +265,15 @@ namespace minecraft {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
load_texture_id_uniform_buffer();
|
load_texture_id_uniform_buffer();
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// worlds
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
for (int i = 0; i < world_count; i++) {
|
||||||
|
per_world::load_world(&world::descriptors[i], world_state[i]);
|
||||||
|
}
|
||||||
|
current_world = &world_state[world::world_id::LOVE2DWORLD];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int popcount(int x)
|
static inline int popcount(int x)
|
||||||
@ -291,8 +305,8 @@ namespace minecraft {
|
|||||||
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
|
glBindVertexBuffer(0, per_vertex_buffer, 0, per_vertex_size);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
|
||||||
|
|
||||||
for (int region_index = 0; region_index < region_count; region_index++) {
|
for (int region_index = 0; region_index < current_world->descriptor->region_count; region_index++) {
|
||||||
glBindVertexBuffer(1, per_instance_vertex_buffers[region_index], 0, per_instance_size);
|
glBindVertexBuffer(1, current_world->region[region_index].per_instance_vertex_buffer, 0, per_instance_size);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// cube blocks
|
// cube blocks
|
||||||
@ -301,8 +315,8 @@ namespace minecraft {
|
|||||||
int element_count = 6 * popcount(configuration);
|
int element_count = 6 * popcount(configuration);
|
||||||
const void * indices = (void *)(2 * (ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx
|
const void * indices = (void *)(2 * (ptrdiff_t)index_buffer_configuration_offsets[configuration]); // index into configuration.idx
|
||||||
|
|
||||||
int instance_count = instance_cfg[region_index].cfg[configuration].instance_count;
|
int instance_count = current_world->region[region_index].instance_cfg[configuration].count;
|
||||||
int base_instance = instance_cfg[region_index].cfg[configuration].offset / per_instance_size; // index into region.0.0.instance.vtx
|
int base_instance = current_world->region[region_index].instance_cfg[configuration].offset / per_instance_size; // index into region.0.0.instance.vtx
|
||||||
|
|
||||||
if (instance_count == 0)
|
if (instance_count == 0)
|
||||||
continue;
|
continue;
|
||||||
@ -313,11 +327,11 @@ namespace minecraft {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// custom blocks
|
// custom blocks
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
for (int i = 0; i < custom_block_types; i++) {
|
for (int i = 0; i < world::custom_block_types; i++) {
|
||||||
int element_count = index_buffer_custom_offsets[i].count;
|
int element_count = index_buffer_custom_offsets[i].count;
|
||||||
const void * indices = (void *)(2 * (ptrdiff_t)index_buffer_custom_offsets[i].offset);
|
const void * indices = (void *)(2 * (ptrdiff_t)index_buffer_custom_offsets[i].offset);
|
||||||
int instance_count = instance_cfg[region_index].cfg[64 + i].instance_count;
|
int instance_count = current_world->region[region_index].instance_cfg[64 + i].count;
|
||||||
int base_instance = instance_cfg[region_index].cfg[64 + i].offset / per_instance_size; // index into region.0.0.instance.vtx
|
int base_instance = current_world->region[region_index].instance_cfg[64 + i].offset / per_instance_size; // index into region.0.0.instance.vtx
|
||||||
if (instance_count == 0)
|
if (instance_count == 0)
|
||||||
continue;
|
continue;
|
||||||
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_SHORT, indices, instance_count, base_instance);
|
glDrawElementsInstancedBaseInstance(GL_TRIANGLES, element_count, GL_UNSIGNED_SHORT, indices, instance_count, base_instance);
|
||||||
|
|||||||
230
src/test.cpp
230
src/test.cpp
@ -11,7 +11,6 @@
|
|||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "bresenham.h"
|
#include "bresenham.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "world.h"
|
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "non_block.h"
|
#include "non_block.h"
|
||||||
#include "minecraft.h"
|
#include "minecraft.h"
|
||||||
@ -26,6 +25,9 @@
|
|||||||
#include "collada/types.h"
|
#include "collada/types.h"
|
||||||
#include "collada/instance_types.h"
|
#include "collada/instance_types.h"
|
||||||
|
|
||||||
|
#include "world/entry_table.h"
|
||||||
|
#include "world/world.h"
|
||||||
|
|
||||||
#include "data/scenes/ship20.h"
|
#include "data/scenes/ship20.h"
|
||||||
#include "data/scenes/noodle.h"
|
#include "data/scenes/noodle.h"
|
||||||
#include "data/scenes/shadow_test.h"
|
#include "data/scenes/shadow_test.h"
|
||||||
@ -111,123 +113,6 @@ extern "C" {
|
|||||||
void * SDL_GL_GetProcAddress(const char *proc);
|
void * SDL_GL_GetProcAddress(const char *proc);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct short_point {
|
|
||||||
short x;
|
|
||||||
short y;
|
|
||||||
short z;
|
|
||||||
};
|
|
||||||
static_assert((sizeof (short_point)) == 6);
|
|
||||||
|
|
||||||
short_point line_points[128];
|
|
||||||
static int line_point_ix = 0;
|
|
||||||
|
|
||||||
void append_line_point(int x, int y, int z)
|
|
||||||
{
|
|
||||||
if (line_point_ix == 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
global_entry * const entry = world_lookup(x, y, z);
|
|
||||||
if (entry != NULL) {
|
|
||||||
line_points[line_point_ix].x = x;
|
|
||||||
line_points[line_point_ix].y = y;
|
|
||||||
line_points[line_point_ix].z = z;
|
|
||||||
line_point_ix += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_line_program()
|
|
||||||
{
|
|
||||||
unsigned int program = compile_from_files("shader/line.vert",
|
|
||||||
NULL,
|
|
||||||
"shader/line.frag");
|
|
||||||
|
|
||||||
line_location.attrib.position = glGetAttribLocation(program, "Position");
|
|
||||||
line_location.attrib.normal = glGetAttribLocation(program, "Normal");
|
|
||||||
line_location.attrib.texture = glGetAttribLocation(program, "Texture");
|
|
||||||
|
|
||||||
line_location.attrib.block_position = glGetAttribLocation(program, "BlockPosition");
|
|
||||||
|
|
||||||
printf("line program:\n");
|
|
||||||
printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n",
|
|
||||||
line_location.attrib.position,
|
|
||||||
line_location.attrib.normal,
|
|
||||||
line_location.attrib.texture,
|
|
||||||
line_location.attrib.block_position);
|
|
||||||
|
|
||||||
line_location.uniform.transform = glGetUniformLocation(program, "Transform");
|
|
||||||
printf(" uniforms:\n transform %u\n\n",
|
|
||||||
line_location.uniform.transform);
|
|
||||||
|
|
||||||
line_program = program;
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_line_vertex_attributes()
|
|
||||||
{
|
|
||||||
glGenVertexArrays(1, &line_vertex_array_object);
|
|
||||||
glBindVertexArray(line_vertex_array_object);
|
|
||||||
|
|
||||||
glVertexBindingDivisor(0, 0);
|
|
||||||
glVertexBindingDivisor(1, 1);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(line_location.attrib.position);
|
|
||||||
glVertexAttribFormat(line_location.attrib.position, 3, GL_HALF_FLOAT, GL_FALSE, 0);
|
|
||||||
glVertexAttribBinding(line_location.attrib.position, 0);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(line_location.attrib.normal);
|
|
||||||
glVertexAttribFormat(line_location.attrib.normal, 3, GL_HALF_FLOAT, GL_FALSE, 6);
|
|
||||||
glVertexAttribBinding(line_location.attrib.normal, 0);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(line_location.attrib.texture);
|
|
||||||
glVertexAttribFormat(line_location.attrib.texture, 2, GL_HALF_FLOAT, GL_FALSE, 12);
|
|
||||||
glVertexAttribBinding(line_location.attrib.texture, 0);
|
|
||||||
|
|
||||||
glEnableVertexAttribArray(line_location.attrib.block_position);
|
|
||||||
glVertexAttribFormat(line_location.attrib.block_position, 3, GL_SHORT, GL_FALSE, 0);
|
|
||||||
glVertexAttribBinding(line_location.attrib.block_position, 1);
|
|
||||||
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_line_instance_buffer()
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, line_instance_buffer);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, (sizeof (short_point)) * line_point_ix, line_points, GL_STATIC_DRAW);
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct line_state {
|
|
||||||
struct {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int z;
|
|
||||||
} point[2];
|
|
||||||
};
|
|
||||||
static line_state line_state = {};
|
|
||||||
|
|
||||||
void load_line()
|
|
||||||
{
|
|
||||||
line_point_ix = 0;
|
|
||||||
bresenham(line_state.point[0].x, line_state.point[0].y, line_state.point[0].z,
|
|
||||||
line_state.point[1].x, line_state.point[1].y, line_state.point[1].z,
|
|
||||||
append_line_point);
|
|
||||||
|
|
||||||
load_line_instance_buffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void load_line_point_from_eye(int point_ix)
|
|
||||||
{
|
|
||||||
int x = XMVectorGetX(view::state.eye);
|
|
||||||
int y = XMVectorGetY(view::state.eye);
|
|
||||||
int z = XMVectorGetZ(view::state.eye);
|
|
||||||
|
|
||||||
line_state.point[point_ix].x = x;
|
|
||||||
line_state.point[point_ix].y = z;
|
|
||||||
line_state.point[point_ix].z = y;
|
|
||||||
|
|
||||||
load_line();
|
|
||||||
}
|
|
||||||
|
|
||||||
void load(const char * source_path)
|
void load(const char * source_path)
|
||||||
{
|
{
|
||||||
g_source_path_length = strlen(source_path);
|
g_source_path_length = strlen(source_path);
|
||||||
@ -243,12 +128,6 @@ void load(const char * source_path)
|
|||||||
|
|
||||||
minecraft::load();
|
minecraft::load();
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// world (collision data)
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
load_world();
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// view
|
// view
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -277,16 +156,6 @@ void load(const char * source_path)
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
lighting::load_program();
|
lighting::load_program();
|
||||||
lighting::load_light_uniform_buffer();
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// line
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
load_line_program();
|
|
||||||
load_line_vertex_attributes();
|
|
||||||
|
|
||||||
glGenBuffers(1, &line_instance_buffer);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// non_block
|
// non_block
|
||||||
@ -360,7 +229,10 @@ void check_collisions(collision::Sphere const & sphere, XMVECTOR const & directi
|
|||||||
for (int x = min_x; x <= max_x; x++) {
|
for (int x = min_x; x <= max_x; x++) {
|
||||||
for (int y = min_y; y <= max_y; y++) {
|
for (int y = min_y; y <= max_y; y++) {
|
||||||
for (int z = min_z; z <= max_z; z++) {
|
for (int z = min_z; z <= max_z; z++) {
|
||||||
global_entry * const entry = world_lookup(x, y, z);
|
world::entry_table::global_entry * const entry = world_lookup(minecraft::current_world->descriptor->hash_func,
|
||||||
|
minecraft::current_world->entry_table,
|
||||||
|
minecraft::current_world->entry_table_length,
|
||||||
|
x, y, z);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -377,24 +249,8 @@ void check_collisions(collision::Sphere const & sphere, XMVECTOR const & directi
|
|||||||
|
|
||||||
const int max_joysticks = 8;
|
const int max_joysticks = 8;
|
||||||
|
|
||||||
void update_joystick(int joystick_index,
|
void minecraft_view_update(XMVECTOR direction)
|
||||||
float lx, float ly, float rx, float ry, float tl, float tr,
|
|
||||||
int up, int down, int left, int right,
|
|
||||||
int a, int b, int x, int y,
|
|
||||||
int leftshoulder, int rightshoulder,
|
|
||||||
int start)
|
|
||||||
{
|
{
|
||||||
float forward = -ly * 0.5;
|
|
||||||
float strafe = lx * 0.5;
|
|
||||||
float elevation = (tl - tr) * 0.5;
|
|
||||||
float delta_yaw = rx * -0.035;
|
|
||||||
float delta_pitch = ry * -0.035;
|
|
||||||
|
|
||||||
XMVECTOR direction = view::third_person::apply_transform(forward, strafe, elevation,
|
|
||||||
delta_yaw, delta_pitch);
|
|
||||||
view::apply_fov(0.01 * up + -0.01 * down);
|
|
||||||
|
|
||||||
/*
|
|
||||||
XMVECTOR sphere_position = view::state.at;
|
XMVECTOR sphere_position = view::state.at;
|
||||||
|
|
||||||
float sphere_radius = 0.48;
|
float sphere_radius = 0.48;
|
||||||
@ -426,9 +282,31 @@ void update_joystick(int joystick_index,
|
|||||||
// apply the last direction impulse
|
// apply the last direction impulse
|
||||||
view::state.at = sphere.center + direction;
|
view::state.at = sphere.center + direction;
|
||||||
}
|
}
|
||||||
*/
|
view::state.eye = view::state.at - view::state.direction * view::at_distance;
|
||||||
|
}
|
||||||
|
|
||||||
view::state.eye = view::state.eye + direction;
|
void update_joystick(int joystick_index,
|
||||||
|
float lx, float ly, float rx, float ry, float tl, float tr,
|
||||||
|
int up, int down, int left, int right,
|
||||||
|
int a, int b, int x, int y,
|
||||||
|
int leftshoulder, int rightshoulder,
|
||||||
|
int start)
|
||||||
|
{
|
||||||
|
float forward = -ly * 0.5;
|
||||||
|
float strafe = lx * 0.5;
|
||||||
|
float elevation = (tl - tr) * 0.5;
|
||||||
|
float delta_yaw = rx * -0.035;
|
||||||
|
float delta_pitch = ry * -0.035;
|
||||||
|
|
||||||
|
XMVECTOR direction = view::third_person::apply_transform(forward, strafe, elevation,
|
||||||
|
delta_yaw, delta_pitch);
|
||||||
|
view::apply_fov(0.01 * up + -0.01 * down);
|
||||||
|
|
||||||
|
if (true) {
|
||||||
|
minecraft_view_update(direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
//view::state.eye = view::state.eye + direction;
|
||||||
//view::state.at = view::state.at - view::state.direction * view::at_distance;
|
//view::state.at = view::state.at - view::state.direction * view::at_distance;
|
||||||
|
|
||||||
//view::state.at = view::state.at + direction;
|
//view::state.at = view::state.at + direction;
|
||||||
@ -442,13 +320,6 @@ void update_joystick(int joystick_index,
|
|||||||
if (lighting.linear < 0.0f)
|
if (lighting.linear < 0.0f)
|
||||||
lighting.linear = 0.0f;
|
lighting.linear = 0.0f;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (leftshoulder) {
|
|
||||||
load_line_point_from_eye(0);
|
|
||||||
}
|
|
||||||
if (rightshoulder) {
|
|
||||||
load_line_point_from_eye(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(float time)
|
void update(float time)
|
||||||
@ -548,48 +419,13 @@ void update_mouse(int x, int y)
|
|||||||
GL_FLOAT,
|
GL_FLOAT,
|
||||||
(void*)&mouse_position);
|
(void*)&mouse_position);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{
|
|
||||||
float mx = (2.0f * (float)x) / geometry_buffer_pnc.width - 1.0f;
|
|
||||||
float my = 1.0f - (2.0f * (float)y) / geometry_buffer_pnc.height;
|
|
||||||
/*
|
|
||||||
XMVECTOR mouse_world = XMVector3Transform(mouse_clip, inverse);
|
|
||||||
XMVECTOR ray = XMVector3Normalize(mouse_world - view::state.eye);
|
|
||||||
mouse_ray_position = ray;
|
|
||||||
|
|
||||||
XMVECTOR ray_start = view::state.eye;
|
|
||||||
XMVECTOR ray_end = ray_start + ray * 20.0f;
|
|
||||||
*/
|
|
||||||
|
|
||||||
XMVECTOR mouse_clip = XMVectorSet(mx, my, -1, 0);
|
|
||||||
|
|
||||||
XMMATRIX projection_inverse = XMMatrixInverse(NULL, view::state.projection_transform);
|
|
||||||
XMMATRIX view_inverse = XMMatrixInverse(NULL, view::state.view_transform);
|
|
||||||
|
|
||||||
XMVECTOR mouse_view = XMVector3Transform(mouse_clip, projection_inverse);
|
|
||||||
|
|
||||||
mouse_view = XMVectorSetZ(mouse_view, -1);
|
|
||||||
XMVECTOR ray = XMVector3Normalize(XMVector3TransformNormal(mouse_view, view_inverse));
|
|
||||||
|
|
||||||
XMVECTOR ray_start = view::state.eye;
|
|
||||||
XMVECTOR ray_end = ray_start + ray * 20.0f;
|
|
||||||
|
|
||||||
line_state.point[0].x = roundf(XMVectorGetX(ray_start));
|
|
||||||
line_state.point[0].z = roundf(XMVectorGetY(ray_start));
|
|
||||||
line_state.point[0].y = roundf(XMVectorGetZ(ray_start));
|
|
||||||
|
|
||||||
line_state.point[1].x = roundf(XMVectorGetX(ray_end));
|
|
||||||
line_state.point[1].z = roundf(XMVectorGetY(ray_end));
|
|
||||||
line_state.point[1].y = roundf(XMVectorGetZ(ray_end));
|
|
||||||
load_line();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw()
|
void draw()
|
||||||
{
|
{
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
glClearDepth(-1.0f);
|
glClearDepth(-1.0f);
|
||||||
if (false) {
|
if (true) {
|
||||||
// possibly re-initialize geometry buffer if window width/height changes
|
// possibly re-initialize geometry buffer if window width/height changes
|
||||||
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
|
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
|
||||||
|
|
||||||
|
|||||||
@ -104,9 +104,9 @@ namespace view {
|
|||||||
state.direction = get_direction(); // on forward/normal/pitch change
|
state.direction = get_direction(); // on forward/normal/pitch change
|
||||||
|
|
||||||
// position
|
// position
|
||||||
//state.eye = XMVectorSet(-45.5f, 43.25f, 63.0f, 1);
|
state.eye = XMVectorSet(-45.5f, 43.25f, 63.0f, 1);
|
||||||
//state.at = state.eye + state.direction * at_distance;
|
state.at = state.eye + state.direction * at_distance;
|
||||||
state.at = XMVectorSet(0, 0, 0, 1);
|
//state.at = XMVectorSet(0, 0, 0, 1);
|
||||||
state.eye = XMVectorSet(0, -100, 0, 1);
|
//state.eye = XMVectorSet(0, -100, 0, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
52
src/world.c
52
src/world.c
@ -1,52 +0,0 @@
|
|||||||
#include <assert.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "inthash.h"
|
|
||||||
#include "file.h"
|
|
||||||
#include "world.h"
|
|
||||||
|
|
||||||
static global_entry_t * global_entry_table = NULL;
|
|
||||||
static int global_entry_table_length = 0;
|
|
||||||
|
|
||||||
void load_world()
|
|
||||||
{
|
|
||||||
int global_size;
|
|
||||||
global_entry_t * entry = (global_entry_t *)read_file("minecraft/global.dump", &global_size);
|
|
||||||
assert(entry != NULL);
|
|
||||||
global_entry_table_length = global_size / (sizeof (global_entry_t));
|
|
||||||
|
|
||||||
global_entry_table = calloc(global_entry_table_length, (sizeof (global_entry_t)));
|
|
||||||
|
|
||||||
for (int i = 0; i < global_entry_table_length; i++) {
|
|
||||||
uint32_t ix = inthash(entry[i].global_index);
|
|
||||||
assert(global_entry_table[ix].global_index == 0);
|
|
||||||
memcpy(&global_entry_table[ix], &entry[i], (sizeof (global_entry_t)));
|
|
||||||
}
|
|
||||||
|
|
||||||
free(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int global_index_from_xyz(int x, int y, int z)
|
|
||||||
{
|
|
||||||
const int g_stride = 512 * 2;
|
|
||||||
if (x < 0)
|
|
||||||
x = -(x - 511);
|
|
||||||
if (z < 0)
|
|
||||||
z = -(z - 511);
|
|
||||||
return x + z * g_stride + y * g_stride * g_stride;
|
|
||||||
}
|
|
||||||
|
|
||||||
global_entry_t * const world_lookup(int x, int y, int z)
|
|
||||||
{
|
|
||||||
int global_index = global_index_from_xyz(x, y, z);
|
|
||||||
int table_index = inthash(global_index);
|
|
||||||
if (table_index < 0 || table_index >= global_entry_table_length)
|
|
||||||
return NULL;
|
|
||||||
global_entry_t * const entry = &global_entry_table[table_index];
|
|
||||||
if (entry->global_index != global_index)
|
|
||||||
return NULL;
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
62
src/world/entry_table.cpp
Normal file
62
src/world/entry_table.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "file.h"
|
||||||
|
#include "new.h"
|
||||||
|
#include "world/entry_table.h"
|
||||||
|
|
||||||
|
namespace world::entry_table {
|
||||||
|
|
||||||
|
void load_entry_table(char const * const path,
|
||||||
|
global_entry_t ** out_entry_table,
|
||||||
|
int * out_entry_table_length,
|
||||||
|
hash_func_t * hash_func)
|
||||||
|
{
|
||||||
|
int global_size;
|
||||||
|
global_entry_t * entry = (global_entry_t *)read_file(path, &global_size);
|
||||||
|
assert(entry != NULL);
|
||||||
|
int entry_table_length = global_size / (sizeof (global_entry_t));
|
||||||
|
|
||||||
|
global_entry_t * entry_table = New<global_entry_t>(entry_table_length);
|
||||||
|
memset(entry_table, 0, global_size);
|
||||||
|
|
||||||
|
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);
|
||||||
|
memcpy(&entry_table[ix], &entry[i], (sizeof (global_entry_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
free(entry);
|
||||||
|
|
||||||
|
*out_entry_table = entry_table;
|
||||||
|
*out_entry_table_length = entry_table_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int global_index_from_xyz(int x, int y, int z)
|
||||||
|
{
|
||||||
|
const int g_stride = 512 * 2;
|
||||||
|
if (x < 0)
|
||||||
|
x = -(x - 511);
|
||||||
|
if (z < 0)
|
||||||
|
z = -(z - 511);
|
||||||
|
return x + z * g_stride + y * g_stride * g_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
global_entry_t * const world_lookup(hash_func_t * hash_func,
|
||||||
|
global_entry_t * entry_table,
|
||||||
|
int entry_table_length,
|
||||||
|
int x, int y, int z)
|
||||||
|
{
|
||||||
|
int global_index = global_index_from_xyz(x, y, z);
|
||||||
|
int table_index = hash_func(global_index);
|
||||||
|
if (table_index < 0 || table_index >= entry_table_length)
|
||||||
|
return NULL;
|
||||||
|
global_entry_t * const entry = &entry_table[table_index];
|
||||||
|
if (entry->global_index != global_index)
|
||||||
|
return NULL;
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/world/world.cpp
Normal file
22
src/world/world.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include "world/world.h"
|
||||||
|
#include "world/inthash.h"
|
||||||
|
|
||||||
|
namespace world {
|
||||||
|
static vtx_cfg const love2dworld_vertex_paths[] = {
|
||||||
|
{ "minecraft/love2dworld/region.0.0.instance.vtx", "minecraft/love2dworld/region.0.0.instance.cfg" },
|
||||||
|
{ "minecraft/love2dworld/region.-1.0.instance.vtx", "minecraft/love2dworld/region.-1.0.instance.cfg" },
|
||||||
|
{ "minecraft/love2dworld/region.0.-1.instance.vtx", "minecraft/love2dworld/region.0.-1.instance.cfg" },
|
||||||
|
{ "minecraft/love2dworld/region.-1.-1.instance.vtx", "minecraft/love2dworld/region.-1.-1.instance.cfg" },
|
||||||
|
};
|
||||||
|
|
||||||
|
descriptor const descriptors[] = {
|
||||||
|
[world_id::LOVE2DWORLD] = {
|
||||||
|
.region_count = 4,
|
||||||
|
.vertex_paths = love2dworld_vertex_paths,
|
||||||
|
.entry_table_path = "minecraft/love2dworld/global.dump",
|
||||||
|
.lights_path = "minecraft/love2dworld/global.lights.vtx",
|
||||||
|
.hash_func = love2dworld_hash,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
int const descriptors_length = (sizeof (descriptors)) / (sizeof (descriptors[0]));
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user