minecraft: render via geometry shader
This commit is contained in:
parent
d8443b3c8c
commit
86890e2a77
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,3 +6,4 @@
|
|||||||
main
|
main
|
||||||
*.so
|
*.so
|
||||||
*.dylib
|
*.dylib
|
||||||
|
__pycache__
|
||||||
@ -7,6 +7,7 @@ extern "C" {
|
|||||||
void * read_file(const char * filename, int * out_size);
|
void * read_file(const char * filename, int * out_size);
|
||||||
|
|
||||||
unsigned int compile_from_files(const char * vertex_path,
|
unsigned int compile_from_files(const char * vertex_path,
|
||||||
|
const char * geometry_path,
|
||||||
const char * fragment_path);
|
const char * fragment_path);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
5
main.lua
5
main.lua
@ -40,9 +40,6 @@ function love.run()
|
|||||||
return a or 0, b
|
return a or 0, b
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if name == "keypressed" then
|
|
||||||
keypressed(a, b, c)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local dt = love.timer.step()
|
local dt = love.timer.step()
|
||||||
@ -52,5 +49,7 @@ function love.run()
|
|||||||
|
|
||||||
love.graphics.present()
|
love.graphics.present()
|
||||||
love.timer.sleep(0.001)
|
love.timer.sleep(0.001)
|
||||||
|
local fps = love.timer.getFPS( )
|
||||||
|
print(fps)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Binary file not shown.
@ -101,4 +101,6 @@ with open("block_id_to_texture_id.data", "wb") as f:
|
|||||||
for i in range(256):
|
for i in range(256):
|
||||||
value = lookup.get(i, unk)
|
value = lookup.get(i, unk)
|
||||||
f.write(struct.pack("<i", value))
|
f.write(struct.pack("<i", value))
|
||||||
print(str(value)+',')
|
print(str(value).rjust(3), end=', ')
|
||||||
|
if i % 16 == 15:
|
||||||
|
print()
|
||||||
|
|||||||
@ -1,238 +1,11 @@
|
|||||||
# https://minecraft.fandom.com/wiki/Region_file_format
|
|
||||||
# https://minecraft.wiki/w/NBT_format#Binary_format
|
|
||||||
# https://minecraft.wiki/w/Chunk_format/McRegion
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import struct
|
import struct
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
import zlib
|
|
||||||
import enum
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
def _parse_locations(mem, offset):
|
import mcregion
|
||||||
for i in range(1024):
|
import vec3
|
||||||
ix = offset + i * 4
|
import vertex_buffer
|
||||||
chunk_location, = struct.unpack(">I", mem[ix:ix+4])
|
|
||||||
chunk_offset = (chunk_location >> 8) & 0xffffff
|
|
||||||
chunk_sector_count = chunk_location & 0xff
|
|
||||||
yield chunk_offset, chunk_sector_count
|
|
||||||
|
|
||||||
def parse_locations(mem, offset):
|
|
||||||
locations = list(_parse_locations(mem, offset))
|
|
||||||
return offset + 1024 * 4, locations
|
|
||||||
|
|
||||||
def _parse_timestamps(mem, offset):
|
|
||||||
for i in range(1024):
|
|
||||||
ix = offset + i * 4
|
|
||||||
timestamp, = struct.unpack(">I", mem[ix:ix+4])
|
|
||||||
yield timestamp
|
|
||||||
|
|
||||||
def parse_timestamps(mem, offset):
|
|
||||||
timestamps = list(_parse_timestamps(mem, offset))
|
|
||||||
return offset + 1024 * 4, timestamps
|
|
||||||
|
|
||||||
def print_locations(locations):
|
|
||||||
for y in range(32):
|
|
||||||
for x in range(32):
|
|
||||||
offset, count = locations[y * 32 + x]
|
|
||||||
print(str(offset).rjust(4), end=' ')
|
|
||||||
print()
|
|
||||||
|
|
||||||
class CountZeroException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def parse_payload(mem, location):
|
|
||||||
offset, count = location
|
|
||||||
if count == 0:
|
|
||||||
raise CountZeroException()
|
|
||||||
ix = offset * 4096
|
|
||||||
payload = mem[ix:ix + count * 4096]
|
|
||||||
length, = struct.unpack(">I", payload[0:4])
|
|
||||||
assert length <= count * 4096, (length, count)
|
|
||||||
compression_type = payload[4]
|
|
||||||
data = payload[5:5 + (length - 1)]
|
|
||||||
assert compression_type == 2, compression_type
|
|
||||||
uncompressed = zlib.decompress(data)
|
|
||||||
return memoryview(uncompressed)
|
|
||||||
|
|
||||||
class TAG:
|
|
||||||
Byte = 0x01
|
|
||||||
Short = 0x02
|
|
||||||
Int = 0x03
|
|
||||||
Long = 0x04
|
|
||||||
Float = 0x05
|
|
||||||
Double = 0x06
|
|
||||||
ByteArray = 0x07
|
|
||||||
String = 0x08
|
|
||||||
List = 0x09
|
|
||||||
Compound = 0x0a
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Byte:
|
|
||||||
name: str
|
|
||||||
value: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Short:
|
|
||||||
name: str
|
|
||||||
value: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Int:
|
|
||||||
name: str
|
|
||||||
value: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Long:
|
|
||||||
name: str
|
|
||||||
value: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Float:
|
|
||||||
name: str
|
|
||||||
value: float
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Double:
|
|
||||||
name: str
|
|
||||||
value: float
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ByteArray:
|
|
||||||
name: str
|
|
||||||
value: bytes
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class String:
|
|
||||||
name: str
|
|
||||||
value: str
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class List:
|
|
||||||
name: str
|
|
||||||
items: list
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Compound:
|
|
||||||
name: str
|
|
||||||
tags: list
|
|
||||||
|
|
||||||
def indent(level):
|
|
||||||
return " " * level
|
|
||||||
|
|
||||||
def parse_tag_inner(mem, offset, level, tag_type, name):
|
|
||||||
payload = mem[offset:]
|
|
||||||
if tag_type == TAG.Byte:
|
|
||||||
value, = struct.unpack(">b", payload[0:1])
|
|
||||||
return offset + 1, Byte(name, value)
|
|
||||||
if tag_type == TAG.Short:
|
|
||||||
value, = struct.unpack(">h", payload[0:2])
|
|
||||||
return offset + 2, Short(name, value)
|
|
||||||
elif tag_type == TAG.Int:
|
|
||||||
value, = struct.unpack(">i", payload[0:4])
|
|
||||||
return offset + 4, Int(name, value)
|
|
||||||
elif tag_type == TAG.Long:
|
|
||||||
value, = struct.unpack(">q", payload[0:8])
|
|
||||||
return offset + 8, Long(name, value)
|
|
||||||
elif tag_type == TAG.Float:
|
|
||||||
value, = struct.unpack(">f", payload[0:4])
|
|
||||||
return offset + 4, Float(name, value)
|
|
||||||
elif tag_type == TAG.Double:
|
|
||||||
value, = struct.unpack(">d", payload[0:8])
|
|
||||||
return offset + 8, Double(name, value)
|
|
||||||
elif tag_type == TAG.ByteArray:
|
|
||||||
size, = struct.unpack(">i", payload[0:4])
|
|
||||||
value = bytes(payload[4:4+size])
|
|
||||||
return offset + 4 + size, ByteArray(name, value)
|
|
||||||
elif tag_type == TAG.String:
|
|
||||||
size, = struct.unpack(">H", payload[0:2])
|
|
||||||
value = bytes(payload[2:2+size]).decode('utf-8')
|
|
||||||
return offset + 2 + size, String(name, value)
|
|
||||||
elif tag_type == TAG.List:
|
|
||||||
list_content_tag_id, size = struct.unpack(">BI", payload[0:5])
|
|
||||||
items = []
|
|
||||||
offset = offset + 5
|
|
||||||
for i in range(size):
|
|
||||||
payload = mem[offset:]
|
|
||||||
offset, item = parse_tag_inner(mem, offset, level, list_content_tag_id, None)
|
|
||||||
items.append(item)
|
|
||||||
return offset, List(name, items)
|
|
||||||
elif tag_type == TAG.Compound:
|
|
||||||
tags = []
|
|
||||||
while payload[0] != 0:
|
|
||||||
offset, tag = parse_tag(mem, offset, level+1)
|
|
||||||
payload = mem[offset:]
|
|
||||||
tags.append(tag)
|
|
||||||
return offset + 1, Compound(name, tags)
|
|
||||||
else:
|
|
||||||
assert False, tag_type
|
|
||||||
|
|
||||||
def parse_tag(mem, offset, level):
|
|
||||||
data = mem[offset:]
|
|
||||||
tag_type = data[0]
|
|
||||||
name_length, = struct.unpack(">H", data[1:3])
|
|
||||||
name = bytes(data[3:3+name_length])
|
|
||||||
#print(indent(level), tag_type, name_length, name)
|
|
||||||
offset = offset + 3 + name_length
|
|
||||||
return parse_tag_inner(mem, offset, level, tag_type, name)
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class Level:
|
|
||||||
blocks: bytes
|
|
||||||
data: bytes
|
|
||||||
sky_light: bytes
|
|
||||||
block_light: bytes
|
|
||||||
height_map: bytes
|
|
||||||
x_pos: int
|
|
||||||
z_pos: int
|
|
||||||
|
|
||||||
def level_from_tag(tag):
|
|
||||||
assert type(tag) == Compound
|
|
||||||
assert tag.name == b''
|
|
||||||
assert len(tag.tags) == 1
|
|
||||||
level, = tag.tags
|
|
||||||
assert type(level) == Compound
|
|
||||||
assert level.name == b'Level'
|
|
||||||
|
|
||||||
name_mapping = {
|
|
||||||
b'Blocks': 'blocks',
|
|
||||||
b'Data': 'data',
|
|
||||||
b'SkyLight': 'sky_light',
|
|
||||||
b'BlockLight': 'block_light',
|
|
||||||
b'HeightMap': 'height_map',
|
|
||||||
b'xPos': 'x_pos',
|
|
||||||
b'zPos': 'z_pos',
|
|
||||||
}
|
|
||||||
|
|
||||||
args = {}
|
|
||||||
|
|
||||||
for tag in level.tags:
|
|
||||||
if tag.name in name_mapping:
|
|
||||||
arg_name = name_mapping[tag.name]
|
|
||||||
args[arg_name] = tag.value
|
|
||||||
|
|
||||||
return Level(**args)
|
|
||||||
|
|
||||||
def parse_location(mem, location):
|
|
||||||
uncompressed = parse_payload(mem, location)
|
|
||||||
offset, tag = parse_tag(uncompressed, 0, 0)
|
|
||||||
assert offset == len(uncompressed), (offset, len(uncompressed))
|
|
||||||
level = level_from_tag(tag)
|
|
||||||
return level
|
|
||||||
|
|
||||||
def xyz_from_block_index(block_index):
|
|
||||||
assert block_index >= 0 and block_index < (128 * 16 * 16)
|
|
||||||
x = int(block_index / (128 * 16))
|
|
||||||
y = int(block_index % 128)
|
|
||||||
z = int(int(block_index / 128) % 16)
|
|
||||||
return x, y, z
|
|
||||||
|
|
||||||
def block_index_from_xyz(x, y, z):
|
|
||||||
assert x >= 0 and x < 16
|
|
||||||
assert y >= 0 and y < 128
|
|
||||||
assert z >= 0 and z < 16
|
|
||||||
return int(y + z * 128 + x * 128 * 16)
|
|
||||||
|
|
||||||
def wrap_n(nc, chunk_c):
|
def wrap_n(nc, chunk_c):
|
||||||
if nc < 0:
|
if nc < 0:
|
||||||
@ -243,77 +16,15 @@ def wrap_n(nc, chunk_c):
|
|||||||
chunk_c = chunk_c + 1
|
chunk_c = chunk_c + 1
|
||||||
return nc, chunk_c
|
return nc, chunk_c
|
||||||
|
|
||||||
def vec3_add(v1, v2):
|
normals = [
|
||||||
return (
|
(-1.0, 0.0, 0.0),
|
||||||
v1[0] + v2[0],
|
(0.0, -1.0, 0.0),
|
||||||
v1[1] + v2[1],
|
(0.0, 0.0, -1.0),
|
||||||
v1[2] + v2[2],
|
(0.0, 0.0, 1.0),
|
||||||
)
|
(0.0, 1.0, 0.0),
|
||||||
|
(1.0, 0.0, 0.0),
|
||||||
def vec3_mul(v, s):
|
|
||||||
return (
|
|
||||||
v[0] * s,
|
|
||||||
v[1] * s,
|
|
||||||
v[2] * s,
|
|
||||||
)
|
|
||||||
|
|
||||||
vertex_table = [
|
|
||||||
((-1.0, 1.0, -1.0), (0.0, 1.0, 0.0), (1.0, 0.0)),
|
|
||||||
((1.0, 1.0, 1.0), (0.0, 1.0, 0.0), (0.0, 1.0)),
|
|
||||||
((1.0, 1.0, -1.0), (0.0, 1.0, 0.0), (0.0, 0.0)),
|
|
||||||
((1.0, 1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 1.0)),
|
|
||||||
|
|
||||||
((-1.0, -1.0, 1.0), (0.0, 0.0, 1.0), (0.0, 0.0)),
|
|
||||||
((1.0, -1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 0.0)),
|
|
||||||
((-1.0, 1.0, 1.0), (-1.0, 0.0, 0.0), (1.0, 1.0)),
|
|
||||||
((-1.0, -1.0, -1.0), (-1.0, 0.0, 0.0), (0.0, 0.0)),
|
|
||||||
|
|
||||||
((-1.0, -1.0, 1.0), (-1.0, 0.0, 0.0), (1.0, 0.0)),
|
|
||||||
((1.0, -1.0, -1.0), (0.0, -1.0, 0.0), (1.0, 0.0)),
|
|
||||||
((-1.0, -1.0, 1.0), (0.0, -1.0, 0.0), (0.0, 1.0)),
|
|
||||||
((-1.0, -1.0, -1.0), (0.0, -1.0, 0.0), (0.0, 0.0)),
|
|
||||||
|
|
||||||
((1.0, 1.0, -1.0), (1.0, 0.0, 0.0), (1.0, 1.0)),
|
|
||||||
((1.0, -1.0, 1.0), (1.0, 0.0, 0.0), (0.0, 0.0)),
|
|
||||||
((1.0, -1.0, -1.0), (1.0, 0.0, 0.0), (1.0, 0.0)),
|
|
||||||
((-1.0, 1.0, -1.0), (0.0, 0.0, -1.0), (1.0, 1.0)),
|
|
||||||
((1.0, -1.0, -1.0), (0.0, 0.0, -1.0), (0.0, 0.0)),
|
|
||||||
((-1.0, -1.0, -1.0), (0.0, 0.0, -1.0), (1.0, 0.0)),
|
|
||||||
((-1.0, 1.0, 1.0), (0.0, 1.0, 0.0), (1.0, 1.0)),
|
|
||||||
((-1.0, 1.0, 1.0), (0.0, 0.0, 1.0), (0.0, 1.0)),
|
|
||||||
((-1.0, 1.0, -1.0), (-1.0, 0.0, 0.0), (0.0, 1.0)),
|
|
||||||
((1.0, -1.0, 1.0), (0.0, -1.0, 0.0), (1.0, 1.0)),
|
|
||||||
((1.0, 1.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0)),
|
|
||||||
((1.0, 1.0, -1.0), (0.0, 0.0, -1.0), (0.0, 1.0))
|
|
||||||
]
|
]
|
||||||
|
|
||||||
faces_by_normal = {
|
|
||||||
(-1.0, 0.0, 0.0): [6, 7, 8, 6, 20, 7],
|
|
||||||
(0.0, -1.0, 0.0): [9, 10, 11, 9, 21, 10],
|
|
||||||
(0.0, 0.0, -1.0): [15, 16, 17, 15, 23, 16],
|
|
||||||
(0.0, 0.0, 1.0): [3, 4, 5, 3, 19, 4],
|
|
||||||
(0.0, 1.0, 0.0): [0, 1, 2, 0, 18, 1],
|
|
||||||
(1.0, 0.0, 0.0): [12, 13, 14, 12, 22, 13]
|
|
||||||
}
|
|
||||||
|
|
||||||
vertex_buffer = {}
|
|
||||||
|
|
||||||
def add_vertex(vertex):
|
|
||||||
if vertex in vertex_buffer:
|
|
||||||
return vertex_buffer[vertex]
|
|
||||||
else:
|
|
||||||
index = len(vertex_buffer)
|
|
||||||
vertex_buffer[vertex] = index
|
|
||||||
return index
|
|
||||||
|
|
||||||
def emit_face(center_position, block_id, triangles):
|
|
||||||
for index in triangles:
|
|
||||||
position, normal, texture = vertex_table[index]
|
|
||||||
position = vec3_add(vec3_mul(position, 0.5), center_position)
|
|
||||||
vertex = (position, normal, texture, block_id)
|
|
||||||
new_index = add_vertex(vertex)
|
|
||||||
yield new_index
|
|
||||||
|
|
||||||
def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
||||||
block_id = level_table[(chunk_x, chunk_z)].blocks[block_index]
|
block_id = level_table[(chunk_x, chunk_z)].blocks[block_index]
|
||||||
if block_id == 0:
|
if block_id == 0:
|
||||||
@ -328,36 +39,65 @@ def block_neighbors(level_table, chunk_x, chunk_z, block_index):
|
|||||||
return True
|
return True
|
||||||
if nz > 15 or nz < 0:
|
if nz > 15 or nz < 0:
|
||||||
return True
|
return True
|
||||||
n_block_index = block_index_from_xyz(nx, ny, nz)
|
n_block_index = mcregion.block_index_from_xyz(nx, ny, nz)
|
||||||
key = (n_chunk_x, n_chunk_z)
|
key = (n_chunk_x, n_chunk_z)
|
||||||
if key not in level_table:
|
if key not in level_table:
|
||||||
return True
|
return True
|
||||||
n_block_id = level_table[key].blocks[n_block_index]
|
n_block_id = level_table[key].blocks[n_block_index]
|
||||||
return n_block_id != 0
|
return n_block_id != 0
|
||||||
|
|
||||||
x, y, z = xyz_from_block_index(block_index)
|
x, y, z = mcregion.xyz_from_block_index(block_index)
|
||||||
|
|
||||||
center_position = vec3_add((x, y, z), (chunk_x * 16, 0, chunk_z * 16))
|
center_position = vec3.add((x, y, z), (chunk_x * 16, 0, chunk_z * 16))
|
||||||
|
|
||||||
for normal, triangles in faces_by_normal.items():
|
def find_non_neighbors():
|
||||||
neighbor = vec3_add(normal, (x, y, z))
|
for i, normal in enumerate(normals):
|
||||||
if not neighbor_exists(*neighbor):
|
neighbor = vec3.add(normal, (x, y, z))
|
||||||
yield from emit_face(center_position, block_id, triangles)
|
if not neighbor_exists(*neighbor):
|
||||||
|
yield i
|
||||||
|
|
||||||
#yield chunk_x, chunk_z, block_index, block_id
|
normal_indices = list(find_non_neighbors())
|
||||||
#break
|
if normal_indices:
|
||||||
|
yield center_position, block_id, normal_indices
|
||||||
|
|
||||||
def devoxelize_region(level_table):
|
def devoxelize_region(level_table):
|
||||||
for chunk_x, chunk_z in level_table.keys():
|
for chunk_x, chunk_z in level_table.keys():
|
||||||
for block_index in range(128 * 16 * 16):
|
for block_index in range(128 * 16 * 16):
|
||||||
yield from block_neighbors(level_table, chunk_x, chunk_z, block_index)
|
yield from block_neighbors(level_table, chunk_x, chunk_z, block_index)
|
||||||
|
|
||||||
from collections import defaultdict
|
def build_level_table(mem, locations):
|
||||||
counts = defaultdict(int)
|
level_table = {}
|
||||||
|
for location in locations:
|
||||||
|
try:
|
||||||
|
level = mcregion.parse_location(mem, location)
|
||||||
|
except CountZeroException:
|
||||||
|
continue
|
||||||
|
x, z = level.x_pos, level.z_pos
|
||||||
|
level_table[(x, z)] = level
|
||||||
|
return level_table
|
||||||
|
|
||||||
def linearized_vertex_buffer():
|
def normal_indices_as_block_configuration(normal_indices):
|
||||||
for vertex, i in sorted(vertex_buffer.items(), key=lambda kv: kv[1]):
|
acc = 0
|
||||||
yield vertex
|
for i in normal_indices:
|
||||||
|
acc |= (1 << i)
|
||||||
|
return acc
|
||||||
|
|
||||||
|
def build_block_configuration_table():
|
||||||
|
for i in range(64):
|
||||||
|
indices = []
|
||||||
|
for j in range(6):
|
||||||
|
if ((i >> j) & 1) != 0:
|
||||||
|
indices.extend(vertex_buffer.faces_by_normal[normals[j]])
|
||||||
|
yield indices
|
||||||
|
|
||||||
|
def build_block_instances(f, blocks):
|
||||||
|
for position, block_id, normal_indices in blocks:
|
||||||
|
block_configuration = normal_indices_as_block_configuration(normal_indices)
|
||||||
|
#print(position, block_id, block_configuration)
|
||||||
|
f.write(struct.pack("<hhhBB",
|
||||||
|
position[0], position[1], position[2],
|
||||||
|
block_id,
|
||||||
|
block_configuration))
|
||||||
|
|
||||||
def main(mcr_path, data_path):
|
def main(mcr_path, data_path):
|
||||||
with open(mcr_path, "rb") as f:
|
with open(mcr_path, "rb") as f:
|
||||||
@ -365,35 +105,17 @@ def main(mcr_path, data_path):
|
|||||||
mem = memoryview(buf)
|
mem = memoryview(buf)
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
offset, locations = parse_locations(mem, offset)
|
offset, locations = mcregion.parse_locations(mem, offset)
|
||||||
offset, timestamps = parse_timestamps(mem, offset)
|
offset, timestamps = mcregion.parse_timestamps(mem, offset)
|
||||||
assert offset == 0x2000
|
assert offset == 0x2000
|
||||||
|
|
||||||
level_table = {}
|
level_table = build_level_table(mem, locations)
|
||||||
for location in locations:
|
blocks = devoxelize_region(level_table)
|
||||||
try:
|
|
||||||
level = parse_location(mem, location)
|
|
||||||
except CountZeroException:
|
|
||||||
continue
|
|
||||||
x, z = level.x_pos, level.z_pos
|
|
||||||
level_table[(x, z)] = level
|
|
||||||
#with open(f"blocks__{x:02x}_{z:02x}.data", "wb") as f:
|
|
||||||
# f.write(level.blocks)
|
|
||||||
|
|
||||||
with open(data_path + ".idx", "wb") as f:
|
|
||||||
for index in devoxelize_region(level_table):
|
|
||||||
f.write(struct.pack("<I", index))
|
|
||||||
|
|
||||||
with open(data_path + ".vtx", "wb") as f:
|
with open(data_path + ".vtx", "wb") as f:
|
||||||
for vertex in linearized_vertex_buffer():
|
build_block_instances(f, blocks)
|
||||||
vertex = [*vertex[0], *vertex[1], *vertex[2], vertex[3]]#, vertex[3]]
|
|
||||||
f.write(struct.pack("<fffffffff", *vertex))
|
|
||||||
|
|
||||||
#for chunk_x, chunk_z, block_index, block_id in devoxelize_region(level_table):
|
#pprint(list(build_block_configuration_table()))
|
||||||
# #print(chunk_x, chunk_z, block_id)
|
|
||||||
# counts[block_id] += 1
|
|
||||||
# f.write(struct.pack("<bbBb", chunk_x, chunk_z, block_id, 0))
|
|
||||||
# f.write(struct.pack("<i", block_index))
|
|
||||||
|
|
||||||
mcr_path = sys.argv[1]
|
mcr_path = sys.argv[1]
|
||||||
data_path = sys.argv[2]
|
data_path = sys.argv[2]
|
||||||
|
|||||||
231
minecraft/gen/mcregion.py
Normal file
231
minecraft/gen/mcregion.py
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
import struct
|
||||||
|
import zlib
|
||||||
|
|
||||||
|
# https://minecraft.fandom.com/wiki/Region_file_format
|
||||||
|
# https://minecraft.wiki/w/NBT_format#Binary_format
|
||||||
|
# https://minecraft.wiki/w/Chunk_format/McRegion
|
||||||
|
|
||||||
|
def _parse_locations(mem, offset):
|
||||||
|
for i in range(1024):
|
||||||
|
ix = offset + i * 4
|
||||||
|
chunk_location, = struct.unpack(">I", mem[ix:ix+4])
|
||||||
|
chunk_offset = (chunk_location >> 8) & 0xffffff
|
||||||
|
chunk_sector_count = chunk_location & 0xff
|
||||||
|
yield chunk_offset, chunk_sector_count
|
||||||
|
|
||||||
|
def parse_locations(mem, offset):
|
||||||
|
locations = list(_parse_locations(mem, offset))
|
||||||
|
return offset + 1024 * 4, locations
|
||||||
|
|
||||||
|
def _parse_timestamps(mem, offset):
|
||||||
|
for i in range(1024):
|
||||||
|
ix = offset + i * 4
|
||||||
|
timestamp, = struct.unpack(">I", mem[ix:ix+4])
|
||||||
|
yield timestamp
|
||||||
|
|
||||||
|
def parse_timestamps(mem, offset):
|
||||||
|
timestamps = list(_parse_timestamps(mem, offset))
|
||||||
|
return offset + 1024 * 4, timestamps
|
||||||
|
|
||||||
|
def print_locations(locations):
|
||||||
|
for y in range(32):
|
||||||
|
for x in range(32):
|
||||||
|
offset, count = locations[y * 32 + x]
|
||||||
|
print(str(offset).rjust(4), end=' ')
|
||||||
|
print()
|
||||||
|
|
||||||
|
class CountZeroException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def parse_payload(mem, location):
|
||||||
|
offset, count = location
|
||||||
|
if count == 0:
|
||||||
|
raise CountZeroException()
|
||||||
|
ix = offset * 4096
|
||||||
|
payload = mem[ix:ix + count * 4096]
|
||||||
|
length, = struct.unpack(">I", payload[0:4])
|
||||||
|
assert length <= count * 4096, (length, count)
|
||||||
|
compression_type = payload[4]
|
||||||
|
data = payload[5:5 + (length - 1)]
|
||||||
|
assert compression_type == 2, compression_type
|
||||||
|
uncompressed = zlib.decompress(data)
|
||||||
|
return memoryview(uncompressed)
|
||||||
|
|
||||||
|
class TAG:
|
||||||
|
Byte = 0x01
|
||||||
|
Short = 0x02
|
||||||
|
Int = 0x03
|
||||||
|
Long = 0x04
|
||||||
|
Float = 0x05
|
||||||
|
Double = 0x06
|
||||||
|
ByteArray = 0x07
|
||||||
|
String = 0x08
|
||||||
|
List = 0x09
|
||||||
|
Compound = 0x0a
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Byte:
|
||||||
|
name: str
|
||||||
|
value: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Short:
|
||||||
|
name: str
|
||||||
|
value: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Int:
|
||||||
|
name: str
|
||||||
|
value: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Long:
|
||||||
|
name: str
|
||||||
|
value: int
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Float:
|
||||||
|
name: str
|
||||||
|
value: float
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Double:
|
||||||
|
name: str
|
||||||
|
value: float
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ByteArray:
|
||||||
|
name: str
|
||||||
|
value: bytes
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class String:
|
||||||
|
name: str
|
||||||
|
value: str
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class List:
|
||||||
|
name: str
|
||||||
|
items: list
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Compound:
|
||||||
|
name: str
|
||||||
|
tags: list
|
||||||
|
|
||||||
|
def indent(level):
|
||||||
|
return " " * level
|
||||||
|
|
||||||
|
def parse_tag_inner(mem, offset, level, tag_type, name):
|
||||||
|
payload = mem[offset:]
|
||||||
|
if tag_type == TAG.Byte:
|
||||||
|
value, = struct.unpack(">b", payload[0:1])
|
||||||
|
return offset + 1, Byte(name, value)
|
||||||
|
if tag_type == TAG.Short:
|
||||||
|
value, = struct.unpack(">h", payload[0:2])
|
||||||
|
return offset + 2, Short(name, value)
|
||||||
|
elif tag_type == TAG.Int:
|
||||||
|
value, = struct.unpack(">i", payload[0:4])
|
||||||
|
return offset + 4, Int(name, value)
|
||||||
|
elif tag_type == TAG.Long:
|
||||||
|
value, = struct.unpack(">q", payload[0:8])
|
||||||
|
return offset + 8, Long(name, value)
|
||||||
|
elif tag_type == TAG.Float:
|
||||||
|
value, = struct.unpack(">f", payload[0:4])
|
||||||
|
return offset + 4, Float(name, value)
|
||||||
|
elif tag_type == TAG.Double:
|
||||||
|
value, = struct.unpack(">d", payload[0:8])
|
||||||
|
return offset + 8, Double(name, value)
|
||||||
|
elif tag_type == TAG.ByteArray:
|
||||||
|
size, = struct.unpack(">i", payload[0:4])
|
||||||
|
value = bytes(payload[4:4+size])
|
||||||
|
return offset + 4 + size, ByteArray(name, value)
|
||||||
|
elif tag_type == TAG.String:
|
||||||
|
size, = struct.unpack(">H", payload[0:2])
|
||||||
|
value = bytes(payload[2:2+size]).decode('utf-8')
|
||||||
|
return offset + 2 + size, String(name, value)
|
||||||
|
elif tag_type == TAG.List:
|
||||||
|
list_content_tag_id, size = struct.unpack(">BI", payload[0:5])
|
||||||
|
items = []
|
||||||
|
offset = offset + 5
|
||||||
|
for i in range(size):
|
||||||
|
payload = mem[offset:]
|
||||||
|
offset, item = parse_tag_inner(mem, offset, level, list_content_tag_id, None)
|
||||||
|
items.append(item)
|
||||||
|
return offset, List(name, items)
|
||||||
|
elif tag_type == TAG.Compound:
|
||||||
|
tags = []
|
||||||
|
while payload[0] != 0:
|
||||||
|
offset, tag = parse_tag(mem, offset, level+1)
|
||||||
|
payload = mem[offset:]
|
||||||
|
tags.append(tag)
|
||||||
|
return offset + 1, Compound(name, tags)
|
||||||
|
else:
|
||||||
|
assert False, tag_type
|
||||||
|
|
||||||
|
def parse_tag(mem, offset, level):
|
||||||
|
data = mem[offset:]
|
||||||
|
tag_type = data[0]
|
||||||
|
name_length, = struct.unpack(">H", data[1:3])
|
||||||
|
name = bytes(data[3:3+name_length])
|
||||||
|
#print(indent(level), tag_type, name_length, name)
|
||||||
|
offset = offset + 3 + name_length
|
||||||
|
return parse_tag_inner(mem, offset, level, tag_type, name)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Level:
|
||||||
|
blocks: bytes
|
||||||
|
data: bytes
|
||||||
|
sky_light: bytes
|
||||||
|
block_light: bytes
|
||||||
|
height_map: bytes
|
||||||
|
x_pos: int
|
||||||
|
z_pos: int
|
||||||
|
|
||||||
|
def level_from_tag(tag):
|
||||||
|
assert type(tag) == Compound
|
||||||
|
assert tag.name == b''
|
||||||
|
assert len(tag.tags) == 1
|
||||||
|
level, = tag.tags
|
||||||
|
assert type(level) == Compound
|
||||||
|
assert level.name == b'Level'
|
||||||
|
|
||||||
|
name_mapping = {
|
||||||
|
b'Blocks': 'blocks',
|
||||||
|
b'Data': 'data',
|
||||||
|
b'SkyLight': 'sky_light',
|
||||||
|
b'BlockLight': 'block_light',
|
||||||
|
b'HeightMap': 'height_map',
|
||||||
|
b'xPos': 'x_pos',
|
||||||
|
b'zPos': 'z_pos',
|
||||||
|
}
|
||||||
|
|
||||||
|
args = {}
|
||||||
|
|
||||||
|
for tag in level.tags:
|
||||||
|
if tag.name in name_mapping:
|
||||||
|
arg_name = name_mapping[tag.name]
|
||||||
|
args[arg_name] = tag.value
|
||||||
|
|
||||||
|
return Level(**args)
|
||||||
|
|
||||||
|
def parse_location(mem, location):
|
||||||
|
uncompressed = parse_payload(mem, location)
|
||||||
|
offset, tag = parse_tag(uncompressed, 0, 0)
|
||||||
|
assert offset == len(uncompressed), (offset, len(uncompressed))
|
||||||
|
level = level_from_tag(tag)
|
||||||
|
return level
|
||||||
|
|
||||||
|
def xyz_from_block_index(block_index):
|
||||||
|
assert block_index >= 0 and block_index < (128 * 16 * 16)
|
||||||
|
x = int(block_index / (128 * 16))
|
||||||
|
y = int(block_index % 128)
|
||||||
|
z = int(int(block_index / 128) % 16)
|
||||||
|
return x, y, z
|
||||||
|
|
||||||
|
def block_index_from_xyz(x, y, z):
|
||||||
|
assert x >= 0 and x < 16
|
||||||
|
assert y >= 0 and y < 128
|
||||||
|
assert z >= 0 and z < 16
|
||||||
|
return int(y + z * 128 + x * 128 * 16)
|
||||||
BIN
minecraft/gen/region.idx
Normal file
BIN
minecraft/gen/region.idx
Normal file
Binary file not shown.
13
minecraft/gen/vec3.py
Normal file
13
minecraft/gen/vec3.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
def add(v1, v2):
|
||||||
|
return (
|
||||||
|
v1[0] + v2[0],
|
||||||
|
v1[1] + v2[1],
|
||||||
|
v1[2] + v2[2],
|
||||||
|
)
|
||||||
|
|
||||||
|
def mul(v, s):
|
||||||
|
return (
|
||||||
|
v[0] * s,
|
||||||
|
v[1] * s,
|
||||||
|
v[2] * s,
|
||||||
|
)
|
||||||
64
minecraft/gen/vertex_buffer.py
Normal file
64
minecraft/gen/vertex_buffer.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import vec3
|
||||||
|
|
||||||
|
vertex_table = [
|
||||||
|
((-1.0, 1.0, -1.0), (0.0, 1.0, 0.0), (1.0, 0.0)),
|
||||||
|
((1.0, 1.0, 1.0), (0.0, 1.0, 0.0), (0.0, 1.0)),
|
||||||
|
((1.0, 1.0, -1.0), (0.0, 1.0, 0.0), (0.0, 0.0)),
|
||||||
|
((1.0, 1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 1.0)),
|
||||||
|
((-1.0, -1.0, 1.0), (0.0, 0.0, 1.0), (0.0, 0.0)),
|
||||||
|
((1.0, -1.0, 1.0), (0.0, 0.0, 1.0), (1.0, 0.0)),
|
||||||
|
((-1.0, 1.0, 1.0), (-1.0, 0.0, 0.0), (1.0, 1.0)),
|
||||||
|
((-1.0, -1.0, -1.0), (-1.0, 0.0, 0.0), (0.0, 0.0)),
|
||||||
|
((-1.0, -1.0, 1.0), (-1.0, 0.0, 0.0), (1.0, 0.0)),
|
||||||
|
((1.0, -1.0, -1.0), (0.0, -1.0, 0.0), (1.0, 0.0)),
|
||||||
|
((-1.0, -1.0, 1.0), (0.0, -1.0, 0.0), (0.0, 1.0)),
|
||||||
|
((-1.0, -1.0, -1.0), (0.0, -1.0, 0.0), (0.0, 0.0)),
|
||||||
|
((1.0, 1.0, -1.0), (1.0, 0.0, 0.0), (1.0, 1.0)),
|
||||||
|
((1.0, -1.0, 1.0), (1.0, 0.0, 0.0), (0.0, 0.0)),
|
||||||
|
((1.0, -1.0, -1.0), (1.0, 0.0, 0.0), (1.0, 0.0)),
|
||||||
|
((-1.0, 1.0, -1.0), (0.0, 0.0, -1.0), (1.0, 1.0)),
|
||||||
|
((1.0, -1.0, -1.0), (0.0, 0.0, -1.0), (0.0, 0.0)),
|
||||||
|
((-1.0, -1.0, -1.0), (0.0, 0.0, -1.0), (1.0, 0.0)),
|
||||||
|
((-1.0, 1.0, 1.0), (0.0, 1.0, 0.0), (1.0, 1.0)),
|
||||||
|
((-1.0, 1.0, 1.0), (0.0, 0.0, 1.0), (0.0, 1.0)),
|
||||||
|
((-1.0, 1.0, -1.0), (-1.0, 0.0, 0.0), (0.0, 1.0)),
|
||||||
|
((1.0, -1.0, 1.0), (0.0, -1.0, 0.0), (1.0, 1.0)),
|
||||||
|
((1.0, 1.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0)),
|
||||||
|
((1.0, 1.0, -1.0), (0.0, 0.0, -1.0), (0.0, 1.0))
|
||||||
|
]
|
||||||
|
|
||||||
|
faces_by_normal = {
|
||||||
|
(-1.0, 0.0, 0.0): [6, 7, 8, 6, 20, 7],
|
||||||
|
(0.0, -1.0, 0.0): [9, 10, 11, 9, 21, 10],
|
||||||
|
(0.0, 0.0, -1.0): [15, 16, 17, 15, 23, 16],
|
||||||
|
(0.0, 0.0, 1.0): [3, 4, 5, 3, 19, 4],
|
||||||
|
(0.0, 1.0, 0.0): [0, 1, 2, 0, 18, 1],
|
||||||
|
(1.0, 0.0, 0.0): [12, 13, 14, 12, 22, 13]
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex_buffer = {}
|
||||||
|
|
||||||
|
def add_vertex(vertex):
|
||||||
|
if vertex in vertex_buffer:
|
||||||
|
return vertex_buffer[vertex]
|
||||||
|
else:
|
||||||
|
index = len(vertex_buffer)
|
||||||
|
vertex_buffer[vertex] = index
|
||||||
|
return index
|
||||||
|
|
||||||
|
def emit_face(center_position, block_id, triangles):
|
||||||
|
for index in triangles:
|
||||||
|
position, normal, texture = vertex_table[index]
|
||||||
|
position = vec3.add(vec3.mul(position, 0.5), center_position)
|
||||||
|
vertex = (position, normal, texture, block_id)
|
||||||
|
new_index = add_vertex(vertex)
|
||||||
|
yield new_index
|
||||||
|
|
||||||
|
def linearized_vertex_buffer():
|
||||||
|
for vertex, i in sorted(vertex_buffer.items(), key=lambda kv: kv[1]):
|
||||||
|
yield vertex
|
||||||
|
|
||||||
|
#with open(data_path + ".vtx", "wb") as f:
|
||||||
|
# for vertex in linearized_vertex_buffer():
|
||||||
|
# vertex = [*vertex[0], *vertex[1], *vertex[2], vertex[3]]#, vertex[3]]
|
||||||
|
# f.write(struct.pack("<fffffffff", *vertex))
|
||||||
BIN
minecraft/region.-1.-1.inst.vtx
Normal file
BIN
minecraft/region.-1.-1.inst.vtx
Normal file
Binary file not shown.
BIN
minecraft/region.-1.0.inst.vtx
Normal file
BIN
minecraft/region.-1.0.inst.vtx
Normal file
Binary file not shown.
BIN
minecraft/region.0.-1.inst.vtx
Normal file
BIN
minecraft/region.0.-1.inst.vtx
Normal file
Binary file not shown.
BIN
minecraft/region.0.0.inst.vtx
Normal file
BIN
minecraft/region.0.0.inst.vtx
Normal file
Binary file not shown.
294
shader/test.frag
294
shader/test.frag
@ -1,286 +1,44 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
in vec3 PixelNormal;
|
in GS_OUT {
|
||||||
in vec2 PixelTexture;
|
vec3 Normal;
|
||||||
in float PixelBlock;
|
vec2 Texture;
|
||||||
|
flat int BlockID;
|
||||||
|
} gs_out;
|
||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
uniform sampler2D TerrainSampler;
|
uniform sampler2D TerrainSampler;
|
||||||
|
|
||||||
/*layout (std140) uniform TexturesLayout
|
|
||||||
{
|
|
||||||
uint Textures[256];
|
|
||||||
};*/
|
|
||||||
int Textures[256] = int[256](
|
int Textures[256] = int[256](
|
||||||
185,
|
185, 1, 0, 2, 16, 4, 15, 17, 205, 205, 237, 237, 18, 19, 32, 33,
|
||||||
1,
|
34, 20, 52, 48, 49, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 0,
|
||||||
0,
|
185, 185, 185, 64, 185, 13, 12, 29, 28, 39, 38, 5, 5, 7, 8, 35,
|
||||||
2,
|
36, 37, 80, 31, 65, 4, 27, 84, 50, 40, 43, 88, 87, 44, 61, 185,
|
||||||
16,
|
81, 83, 128, 16, 185, 96, 6, 82, 6, 51, 51, 115, 99, 185, 66, 67,
|
||||||
4,
|
66, 70, 72, 73, 74, 4, 102, 103, 104, 105, 14, 102, 185, 185, 185, 185,
|
||||||
15,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
17,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
205,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
205,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
237,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
237,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
18,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
19,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
32,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
|
||||||
33,
|
185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185
|
||||||
34,
|
);
|
||||||
20,
|
|
||||||
52,
|
|
||||||
48,
|
|
||||||
49,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
0,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
64,
|
|
||||||
185,
|
|
||||||
13,
|
|
||||||
12,
|
|
||||||
29,
|
|
||||||
28,
|
|
||||||
39,
|
|
||||||
38,
|
|
||||||
5,
|
|
||||||
5,
|
|
||||||
7,
|
|
||||||
8,
|
|
||||||
35,
|
|
||||||
36,
|
|
||||||
37,
|
|
||||||
80,
|
|
||||||
31,
|
|
||||||
65,
|
|
||||||
4,
|
|
||||||
27,
|
|
||||||
84,
|
|
||||||
50,
|
|
||||||
40,
|
|
||||||
43,
|
|
||||||
88,
|
|
||||||
87,
|
|
||||||
44,
|
|
||||||
61,
|
|
||||||
185,
|
|
||||||
81,
|
|
||||||
83,
|
|
||||||
128,
|
|
||||||
16,
|
|
||||||
185,
|
|
||||||
96,
|
|
||||||
6,
|
|
||||||
82,
|
|
||||||
6,
|
|
||||||
51,
|
|
||||||
51,
|
|
||||||
115,
|
|
||||||
99,
|
|
||||||
185,
|
|
||||||
66,
|
|
||||||
67,
|
|
||||||
66,
|
|
||||||
70,
|
|
||||||
72,
|
|
||||||
73,
|
|
||||||
74,
|
|
||||||
4,
|
|
||||||
102,
|
|
||||||
103,
|
|
||||||
104,
|
|
||||||
105,
|
|
||||||
14,
|
|
||||||
102,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185,
|
|
||||||
185
|
|
||||||
);
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 light_direction = normalize(vec3(-1, -0.5, 0.5));
|
vec3 light_direction = normalize(vec3(-1, -0.5, 0.5));
|
||||||
float diffuse_intensity = max(dot(normalize(PixelNormal), light_direction), 0.0);
|
float diffuse_intensity = max(dot(normalize(gs_out.Normal), light_direction), 0.0);
|
||||||
|
|
||||||
int terrain_ix = int(Textures[int(PixelBlock)]);
|
int terrain_ix = int(Textures[int(gs_out.BlockID)]);
|
||||||
int terrain_x = terrain_ix % 16;
|
int terrain_x = terrain_ix % 16;
|
||||||
int terrain_y = terrain_ix / 16;
|
int terrain_y = terrain_ix / 16;
|
||||||
ivec2 coord = ivec2(terrain_x, terrain_y) * 16;
|
ivec2 coord = ivec2(terrain_x, terrain_y) * 16;
|
||||||
coord += ivec2(PixelTexture.xy * 16.0);
|
coord += ivec2(gs_out.Texture.xy * 16.0);
|
||||||
|
|
||||||
vec4 texture_color = texelFetch(TerrainSampler, coord, 0);
|
vec4 texture_color = texelFetch(TerrainSampler, coord, 0);
|
||||||
if (texture_color.w != 1.0) {
|
if (texture_color.w != 1.0) {
|
||||||
@ -288,7 +46,7 @@ void main()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int(PixelBlock) == 18) // leaves
|
if (int(gs_out.BlockID) == 18) // leaves
|
||||||
texture_color.xyz *= vec3(0.125, 0.494, 0.027);
|
texture_color.xyz *= vec3(0.125, 0.494, 0.027);
|
||||||
|
|
||||||
FragColor = vec4(texture_color.xyz * vec3(diffuse_intensity), 1.0);
|
FragColor = vec4(texture_color.xyz * vec3(diffuse_intensity), 1.0);
|
||||||
|
|||||||
100
shader/test.geom
Normal file
100
shader/test.geom
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
layout (points) in;
|
||||||
|
layout (triangle_strip, max_vertices = 24) out;
|
||||||
|
|
||||||
|
in VS_OUT {
|
||||||
|
int BlockID;
|
||||||
|
int Configuration;
|
||||||
|
} gs_in[1];
|
||||||
|
|
||||||
|
out GS_OUT {
|
||||||
|
vec3 Normal;
|
||||||
|
vec2 Texture;
|
||||||
|
flat int BlockID;
|
||||||
|
} gs_out;
|
||||||
|
|
||||||
|
struct PT {
|
||||||
|
vec3 Position;
|
||||||
|
vec2 Texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform mat4 Transform;
|
||||||
|
|
||||||
|
PT vertices[] = PT[24](
|
||||||
|
PT(vec3(-1.0, 1.0, -1.0), vec2(1.0, 0.0)),
|
||||||
|
PT(vec3(1.0, 1.0, 1.0), vec2(0.0, 1.0)),
|
||||||
|
PT(vec3(1.0, 1.0, -1.0), vec2(0.0, 0.0)),
|
||||||
|
PT(vec3(1.0, 1.0, 1.0), vec2(1.0, 1.0)),
|
||||||
|
PT(vec3(-1.0, -1.0, 1.0), vec2(0.0, 0.0)),
|
||||||
|
PT(vec3(1.0, -1.0, 1.0), vec2(1.0, 0.0)),
|
||||||
|
PT(vec3(-1.0, 1.0, 1.0), vec2(1.0, 1.0)),
|
||||||
|
PT(vec3(-1.0, -1.0, -1.0), vec2(0.0, 0.0)),
|
||||||
|
PT(vec3(-1.0, -1.0, 1.0), vec2(1.0, 0.0)),
|
||||||
|
PT(vec3(1.0, -1.0, -1.0), vec2(1.0, 0.0)),
|
||||||
|
PT(vec3(-1.0, -1.0, 1.0), vec2(0.0, 1.0)),
|
||||||
|
PT(vec3(-1.0, -1.0, -1.0), vec2(0.0, 0.0)),
|
||||||
|
PT(vec3(1.0, 1.0, -1.0), vec2(1.0, 1.0)),
|
||||||
|
PT(vec3(1.0, -1.0, 1.0), vec2(0.0, 0.0)),
|
||||||
|
PT(vec3(1.0, -1.0, -1.0), vec2(1.0, 0.0)),
|
||||||
|
PT(vec3(-1.0, 1.0, -1.0), vec2(1.0, 1.0)),
|
||||||
|
PT(vec3(1.0, -1.0, -1.0), vec2(0.0, 0.0)),
|
||||||
|
PT(vec3(-1.0, -1.0, -1.0), vec2(1.0, 0.0)),
|
||||||
|
PT(vec3(-1.0, 1.0, 1.0), vec2(1.0, 1.0)),
|
||||||
|
PT(vec3(-1.0, 1.0, 1.0), vec2(0.0, 1.0)),
|
||||||
|
PT(vec3(-1.0, 1.0, -1.0), vec2(0.0, 1.0)),
|
||||||
|
PT(vec3(1.0, -1.0, 1.0), vec2(1.0, 1.0)),
|
||||||
|
PT(vec3(1.0, 1.0, 1.0), vec2(0.0, 1.0)),
|
||||||
|
PT(vec3(1.0, 1.0, -1.0), vec2(0.0, 1.0))
|
||||||
|
);
|
||||||
|
|
||||||
|
int face_1[4] = int[4](8, 6, 7, 20);
|
||||||
|
int face_2[4] = int[4](11, 9, 10, 21);
|
||||||
|
int face_4[4] = int[4](17, 15, 16, 23);
|
||||||
|
int face_8[4] = int[4](5, 3, 4, 19);
|
||||||
|
int face_16[4] = int[4](2, 0, 1, 18);
|
||||||
|
int face_32[4] = int[4](14, 12, 13, 22);
|
||||||
|
|
||||||
|
vec4 transform(vec3 p)
|
||||||
|
{
|
||||||
|
return Transform * vec4(p.xzy, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void emit_face(vec3 normal, int face[4])
|
||||||
|
{
|
||||||
|
vec3 position = gl_in[0].gl_Position.xyz;
|
||||||
|
|
||||||
|
PT vtx0 = vertices[face[0]];
|
||||||
|
gl_Position = transform(position + vtx0.Position * 0.5);
|
||||||
|
gs_out.Normal = normal.xzy;
|
||||||
|
gs_out.Texture = vtx0.Texture;
|
||||||
|
EmitVertex();
|
||||||
|
PT vtx1 = vertices[face[1]];
|
||||||
|
gl_Position = transform(position + vtx1.Position * 0.5);
|
||||||
|
gs_out.Normal = normal.xzy;
|
||||||
|
gs_out.Texture = vtx1.Texture;
|
||||||
|
EmitVertex();
|
||||||
|
PT vtx2 = vertices[face[2]];
|
||||||
|
gl_Position = transform(position + vtx2.Position * 0.5);
|
||||||
|
gs_out.Normal = normal.xzy;
|
||||||
|
gs_out.Texture = vtx2.Texture;
|
||||||
|
EmitVertex();
|
||||||
|
PT vtx3 = vertices[face[3]];
|
||||||
|
gl_Position = transform(position + vtx3.Position * 0.5);
|
||||||
|
gs_out.Normal = normal.xzy;
|
||||||
|
gs_out.Texture = vtx3.Texture;
|
||||||
|
EmitVertex();
|
||||||
|
EndPrimitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gs_out.BlockID = gs_in[0].BlockID;
|
||||||
|
int configuration = gs_in[0].Configuration;
|
||||||
|
if ((configuration & 1) != 0) emit_face(vec3(-1.0, 0.0, 0.0), face_1);
|
||||||
|
if ((configuration & 2) != 0) emit_face(vec3(0.0, -1.0, 0.0), face_2);
|
||||||
|
if ((configuration & 4) != 0) emit_face(vec3(0.0, 0.0, -1.0), face_4);
|
||||||
|
if ((configuration & 8) != 0) emit_face(vec3(0.0, 0.0, 1.0), face_8);
|
||||||
|
if ((configuration & 16) != 0) emit_face(vec3(0.0, 1.0, 0.0), face_16);
|
||||||
|
if ((configuration & 32) != 0) emit_face(vec3(1.0, 0.0, 0.0), face_32);
|
||||||
|
}
|
||||||
@ -1,23 +1,20 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
layout (location = 0) in vec3 Position;
|
layout (location = 0) in vec3 Position;
|
||||||
layout (location = 1) in vec3 Normal;
|
layout (location = 1) in float BlockID;
|
||||||
layout (location = 2) in vec3 Texture;
|
layout (location = 2) in float Configuration;
|
||||||
|
|
||||||
out vec3 PixelNormal;
|
out VS_OUT {
|
||||||
out vec2 PixelTexture;
|
int BlockID;
|
||||||
out float PixelBlock;
|
int Configuration;
|
||||||
|
} vs_out;
|
||||||
|
|
||||||
uniform mat4 Transform;
|
uniform mat4 Transform;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
//gl_Position = vec4(position, 1.0);
|
vs_out.BlockID = int(BlockID);
|
||||||
//ourColor = color;
|
vs_out.Configuration = int(Configuration);
|
||||||
|
|
||||||
PixelNormal = Normal.xzy;
|
gl_Position = vec4(Position.xyz, 1.0);
|
||||||
PixelTexture = Texture.xy;
|
|
||||||
PixelBlock = Texture.z;
|
|
||||||
|
|
||||||
gl_Position = Transform * vec4(Position.xzy, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|||||||
54
src/opengl.c
54
src/opengl.c
@ -49,14 +49,22 @@ void * read_file(const char * filename, int * out_size)
|
|||||||
|
|
||||||
unsigned int compile(const char * vertex_source,
|
unsigned int compile(const char * vertex_source,
|
||||||
int vertex_source_size,
|
int vertex_source_size,
|
||||||
|
const char * geometry_source,
|
||||||
|
int geometry_source_size,
|
||||||
const char * fragment_source,
|
const char * fragment_source,
|
||||||
int fragment_source_size)
|
int fragment_source_size)
|
||||||
{
|
{
|
||||||
int compile_status;
|
int compile_status;
|
||||||
char info_log[512];
|
char info_log[512];
|
||||||
|
|
||||||
|
// program
|
||||||
|
unsigned int shader_program = glCreateProgram();
|
||||||
|
unsigned int vertex_shader = -1;
|
||||||
|
unsigned int geometry_shader = -1;
|
||||||
|
unsigned int fragment_shader = -1;
|
||||||
|
|
||||||
// vertex shader
|
// vertex shader
|
||||||
unsigned int vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||||
glShaderSource(vertex_shader, 1, &vertex_source, &vertex_source_size);
|
glShaderSource(vertex_shader, 1, &vertex_source, &vertex_source_size);
|
||||||
glCompileShader(vertex_shader);
|
glCompileShader(vertex_shader);
|
||||||
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_status);
|
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compile_status);
|
||||||
@ -64,9 +72,23 @@ unsigned int compile(const char * vertex_source,
|
|||||||
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
|
glGetShaderInfoLog(vertex_shader, 512, NULL, info_log);
|
||||||
fprintf(stderr, "vertex shader compile: %s\n", info_log);
|
fprintf(stderr, "vertex shader compile: %s\n", info_log);
|
||||||
}
|
}
|
||||||
|
glAttachShader(shader_program, vertex_shader);
|
||||||
|
|
||||||
|
// geometry shader
|
||||||
|
if (geometry_source_size != 0) {
|
||||||
|
geometry_shader = glCreateShader(GL_GEOMETRY_SHADER);
|
||||||
|
glShaderSource(geometry_shader, 1, &geometry_source, &geometry_source_size);
|
||||||
|
glCompileShader(geometry_shader);
|
||||||
|
glGetShaderiv(geometry_shader, GL_COMPILE_STATUS, &compile_status);
|
||||||
|
if (!compile_status) {
|
||||||
|
glGetShaderInfoLog(geometry_shader, 512, NULL, info_log);
|
||||||
|
fprintf(stderr, "geometry shader compile: %s\n", info_log);
|
||||||
|
}
|
||||||
|
glAttachShader(shader_program, geometry_shader);
|
||||||
|
}
|
||||||
|
|
||||||
// fragment shader
|
// fragment shader
|
||||||
unsigned int fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
glShaderSource(fragment_shader, 1, &fragment_source, &fragment_source_size);
|
glShaderSource(fragment_shader, 1, &fragment_source, &fragment_source_size);
|
||||||
glCompileShader(fragment_shader);
|
glCompileShader(fragment_shader);
|
||||||
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compile_status);
|
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compile_status);
|
||||||
@ -74,11 +96,9 @@ unsigned int compile(const char * vertex_source,
|
|||||||
glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
|
glGetShaderInfoLog(fragment_shader, 512, NULL, info_log);
|
||||||
fprintf(stderr, "fragment shader compile: %s\n", info_log);
|
fprintf(stderr, "fragment shader compile: %s\n", info_log);
|
||||||
}
|
}
|
||||||
|
glAttachShader(shader_program, fragment_shader);
|
||||||
|
|
||||||
// link shaders
|
// link shaders
|
||||||
unsigned int shader_program = glCreateProgram();
|
|
||||||
glAttachShader(shader_program, vertex_shader);
|
|
||||||
glAttachShader(shader_program, fragment_shader);
|
|
||||||
glLinkProgram(shader_program);
|
glLinkProgram(shader_program);
|
||||||
glGetProgramiv(shader_program, GL_LINK_STATUS, &compile_status);
|
glGetProgramiv(shader_program, GL_LINK_STATUS, &compile_status);
|
||||||
if (!compile_status) {
|
if (!compile_status) {
|
||||||
@ -87,25 +107,41 @@ unsigned int compile(const char * vertex_source,
|
|||||||
}
|
}
|
||||||
|
|
||||||
glDeleteShader(vertex_shader);
|
glDeleteShader(vertex_shader);
|
||||||
|
if (geometry_source_size != 0)
|
||||||
|
glDeleteShader(geometry_shader);
|
||||||
glDeleteShader(fragment_shader);
|
glDeleteShader(fragment_shader);
|
||||||
|
|
||||||
return shader_program;
|
return shader_program;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int compile_from_files(const char * vertex_path,
|
unsigned int compile_from_files(const char * vertex_path,
|
||||||
|
const char * geometry_path,
|
||||||
const char * fragment_path)
|
const char * fragment_path)
|
||||||
{
|
{
|
||||||
int vertex_source_size;
|
int vertex_source_size = 0;
|
||||||
char * vertex_source = read_file(vertex_path, &vertex_source_size);
|
char * vertex_source = NULL;
|
||||||
|
int geometry_source_size = 0;
|
||||||
|
char * geometry_source = NULL;
|
||||||
|
int fragment_source_size = 0;
|
||||||
|
char * fragment_source = NULL;
|
||||||
|
|
||||||
|
vertex_source = read_file(vertex_path, &vertex_source_size);
|
||||||
assert(vertex_source != NULL);
|
assert(vertex_source != NULL);
|
||||||
int fragment_source_size;
|
|
||||||
char * fragment_source = read_file(fragment_path, &fragment_source_size);
|
if (geometry_path != NULL) {
|
||||||
|
geometry_source = read_file(geometry_path, &geometry_source_size);
|
||||||
|
assert(geometry_source != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
fragment_source = read_file(fragment_path, &fragment_source_size);
|
||||||
assert(fragment_source != NULL);
|
assert(fragment_source != NULL);
|
||||||
|
|
||||||
unsigned int program = compile(vertex_source, vertex_source_size,
|
unsigned int program = compile(vertex_source, vertex_source_size,
|
||||||
|
geometry_source, geometry_source_size,
|
||||||
fragment_source, fragment_source_size);
|
fragment_source, fragment_source_size);
|
||||||
|
|
||||||
free(vertex_source);
|
free(vertex_source);
|
||||||
|
free(geometry_source);
|
||||||
free(fragment_source);
|
free(fragment_source);
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
|
|||||||
98
src/test.cpp
98
src/test.cpp
@ -9,8 +9,8 @@
|
|||||||
struct location {
|
struct location {
|
||||||
struct {
|
struct {
|
||||||
unsigned int position;
|
unsigned int position;
|
||||||
unsigned int normal;
|
unsigned int block_id;
|
||||||
unsigned int texture;
|
unsigned int configuration;
|
||||||
} attrib;
|
} attrib;
|
||||||
struct {
|
struct {
|
||||||
unsigned int transform;
|
unsigned int transform;
|
||||||
@ -22,18 +22,27 @@ struct location {
|
|||||||
static unsigned int test_program;
|
static unsigned int test_program;
|
||||||
static struct location location;
|
static struct location location;
|
||||||
|
|
||||||
|
static unsigned int vertex_array_objects[4];
|
||||||
|
static unsigned int vertex_buffers[4];
|
||||||
|
static unsigned int vertex_count[4];
|
||||||
|
//static unsigned int index_buffers[4];
|
||||||
|
//static unsigned int index_count[4];
|
||||||
|
|
||||||
|
static const int vertex_size = 8;
|
||||||
|
|
||||||
void load_program()
|
void load_program()
|
||||||
{
|
{
|
||||||
unsigned int program = compile_from_files("shader/test.vert",
|
unsigned int program = compile_from_files("shader/test.vert",
|
||||||
|
"shader/test.geom",
|
||||||
"shader/test.frag");
|
"shader/test.frag");
|
||||||
|
|
||||||
location.attrib.position = glGetAttribLocation(program, "Position");
|
location.attrib.position = glGetAttribLocation(program, "Position");
|
||||||
location.attrib.normal = glGetAttribLocation(program, "Normal");
|
location.attrib.block_id = glGetAttribLocation(program, "BlockID");
|
||||||
location.attrib.texture = glGetAttribLocation(program, "Texture");
|
location.attrib.configuration = glGetAttribLocation(program, "Configuration");
|
||||||
printf("attributes:\n position %u\n normal %u\n texture %u\n",
|
printf("attributes:\n position %u\n block_id %u\n configuration %u\n",
|
||||||
location.attrib.position,
|
location.attrib.position,
|
||||||
location.attrib.normal,
|
location.attrib.block_id,
|
||||||
location.attrib.texture);
|
location.attrib.configuration);
|
||||||
|
|
||||||
location.uniform.transform = glGetUniformLocation(program, "Transform");
|
location.uniform.transform = glGetUniformLocation(program, "Transform");
|
||||||
location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler");
|
location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler");
|
||||||
@ -44,23 +53,11 @@ void load_program()
|
|||||||
test_program = program;
|
test_program = program;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int vertex_array_objects[4];
|
|
||||||
static unsigned int vertex_buffers[4];
|
|
||||||
static unsigned int index_buffers[4];
|
|
||||||
static unsigned int index_count[4];
|
|
||||||
|
|
||||||
const char * vertex_paths[] = {
|
const char * vertex_paths[] = {
|
||||||
"minecraft/region.0.0.vtx",
|
"minecraft/region.0.0.inst.vtx",
|
||||||
"minecraft/region.0.-1.vtx",
|
"minecraft/region.0.-1.inst.vtx",
|
||||||
"minecraft/region.-1.0.vtx",
|
"minecraft/region.-1.0.inst.vtx",
|
||||||
"minecraft/region.-1.-1.vtx",
|
"minecraft/region.-1.-1.inst.vtx",
|
||||||
};
|
|
||||||
|
|
||||||
static const char * index_paths[] = {
|
|
||||||
"minecraft/region.0.0.idx",
|
|
||||||
"minecraft/region.0.-1.idx",
|
|
||||||
"minecraft/region.-1.0.idx",
|
|
||||||
"minecraft/region.-1.-1.idx",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void load_vertex_buffer(int i)
|
void load_vertex_buffer(int i)
|
||||||
@ -70,10 +67,12 @@ void load_vertex_buffer(int i)
|
|||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers[i]);
|
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffers[i]);
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_data_size, vertex_buffer_data, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_data_size, vertex_buffer_data, GL_STATIC_DRAW);
|
||||||
|
vertex_count[i] = vertex_buffer_data_size / vertex_size;
|
||||||
|
|
||||||
free(vertex_buffer_data);
|
free(vertex_buffer_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void load_element_buffer(int i)
|
void load_element_buffer(int i)
|
||||||
{
|
{
|
||||||
int index_buffer_data_size;
|
int index_buffer_data_size;
|
||||||
@ -85,45 +84,49 @@ void load_element_buffer(int i)
|
|||||||
|
|
||||||
free(index_buffer_data);
|
free(index_buffer_data);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void load_vertex_attributes()
|
void load_vertex_attributes()
|
||||||
{
|
{
|
||||||
glVertexAttribPointer(location.attrib.position,
|
glVertexAttribPointer(location.attrib.position,
|
||||||
3,
|
3,
|
||||||
GL_FLOAT,
|
GL_SHORT,
|
||||||
GL_FALSE,
|
GL_FALSE,
|
||||||
(sizeof (float)) * 9,
|
vertex_size,
|
||||||
(void*)(0 * 4)
|
(void*)(0)
|
||||||
);
|
);
|
||||||
glVertexAttribPointer(location.attrib.normal,
|
glVertexAttribPointer(location.attrib.block_id,
|
||||||
3,
|
1,
|
||||||
GL_FLOAT,
|
GL_UNSIGNED_BYTE,
|
||||||
GL_FALSE,
|
GL_FALSE,
|
||||||
(sizeof (float)) * 9,
|
vertex_size,
|
||||||
(void*)(3 * 4)
|
(void*)(6)
|
||||||
);
|
);
|
||||||
glVertexAttribPointer(location.attrib.texture,
|
glVertexAttribPointer(location.attrib.configuration,
|
||||||
3,
|
1,
|
||||||
GL_FLOAT,
|
GL_UNSIGNED_BYTE,
|
||||||
GL_FALSE,
|
GL_FALSE,
|
||||||
(sizeof (float)) * 9,
|
vertex_size,
|
||||||
(void*)(6 * 4)
|
(void*)(7)
|
||||||
);
|
);
|
||||||
glEnableVertexAttribArray(location.attrib.position);
|
glEnableVertexAttribArray(location.attrib.position);
|
||||||
glEnableVertexAttribArray(location.attrib.normal);
|
glEnableVertexAttribArray(location.attrib.block_id);
|
||||||
glEnableVertexAttribArray(location.attrib.texture);
|
glEnableVertexAttribArray(location.attrib.configuration);
|
||||||
|
glVertexAttribDivisor(location.attrib.position, 1);
|
||||||
|
glVertexAttribDivisor(location.attrib.block_id, 1);
|
||||||
|
glVertexAttribDivisor(location.attrib.configuration, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_buffers()
|
void load_buffers()
|
||||||
{
|
{
|
||||||
glGenVertexArrays(4, vertex_array_objects);
|
glGenVertexArrays(4, vertex_array_objects);
|
||||||
glGenBuffers(4, index_buffers);
|
//glGenBuffers(4, index_buffers);
|
||||||
glGenBuffers(4, vertex_buffers);
|
glGenBuffers(4, vertex_buffers);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
glBindVertexArray(vertex_array_objects[i]);
|
glBindVertexArray(vertex_array_objects[i]);
|
||||||
|
|
||||||
load_element_buffer(i);
|
//load_element_buffer(i);
|
||||||
load_vertex_buffer(i);
|
load_vertex_buffer(i);
|
||||||
load_vertex_attributes();
|
load_vertex_attributes();
|
||||||
}
|
}
|
||||||
@ -234,9 +237,22 @@ void draw()
|
|||||||
//glBindBuffer(GL_UNIFORM_BUFFER, textures_ubo);
|
//glBindBuffer(GL_UNIFORM_BUFFER, textures_ubo);
|
||||||
//glBindBufferBase(GL_UNIFORM_BUFFER, 0, textures_ubo);
|
//glBindBufferBase(GL_UNIFORM_BUFFER, 0, textures_ubo);
|
||||||
|
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glCullFace(GL_FRONT);
|
||||||
|
glFrontFace(GL_CCW);
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
glBindVertexArray(vertex_array_objects[i]);
|
glBindVertexArray(vertex_array_objects[i]);
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, index_count[i], GL_UNSIGNED_INT, 0);
|
//glDrawElements(GL_TRIANGLES, index_count[i], GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
int instance_count = vertex_count[i];
|
||||||
|
//printf("instance_count %d\n", instance_count);
|
||||||
|
|
||||||
|
glPointSize(10.0);
|
||||||
|
glDrawArraysInstanced(GL_POINTS,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
instance_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user