point lighting, colored wool

This commit is contained in:
Zack Buhman 2026-03-09 18:23:46 -05:00
parent ba2247068b
commit 7428b86b9e
19 changed files with 444 additions and 124 deletions

View File

@ -7,7 +7,8 @@ extern "C" {
void load(const char * source_path);
void draw();
void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right);
int up, int down, int left, int right,
int a, int b, int x, int y);
#ifdef __cplusplus
}

View File

@ -9,7 +9,8 @@ void load(const char * source_path);
void update_window(int width, int height);
void draw();
void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right);
int up, int down, int left, int right,
int a, int b, int x, int y);
]]
local source_path = love.filesystem.getSource()
test = ffi.load(source_path .. "/test.so")
@ -29,7 +30,11 @@ local update = function(dt)
local down = joystick:isGamepadDown("dpdown")
local left = joystick:isGamepadDown("dpleft")
local right = joystick:isGamepadDown("dpright")
test.update(lx, ly, rx, ry, tl, tr, up, down, left, right)
local a = joystick:isGamepadDown("a")
local b = joystick:isGamepadDown("b")
local x = joystick:isGamepadDown("x")
local y = joystick:isGamepadDown("y")
test.update(lx, ly, rx, ry, tl, tr, up, down, left, right, a, b, x, y)
end
end

Binary file not shown.

View File

@ -1,15 +1,13 @@
import struct
import data
import sys
unk = 185
unk = 253
lookup = {
k: v for k, v, _ in mapping
}
with open("block_id_to_texture_id.data", "wb") as f:
with open(sys.argv[1], "wb") as f:
for i in range(256):
value = lookup.get(i, unk)
if i in data.tiles_by_id:
value = data.tiles_by_id[i].texture
else:
value = unk
f.write(struct.pack("<i", value))
print(str(value).rjust(3), end=', ')
if i % 16 == 15:
print()

4
minecraft/gen/blocks.sh Normal file
View File

@ -0,0 +1,4 @@
set -eux
cd ./minecraft/gen
PYTHON=pypy3.11
$PYTHON blocks.py ../block_id_to_texture_id.data

View File

@ -118,9 +118,9 @@ class BlockID:
CLOTH_51 = 114
CLOTH_61 = 115
INFO_UPDATEGAME1 = 248
INFO_UPDATEGAME2 = 249
LEAVES_CARRIED = 254
# modded
YELLOW_COBBLE = 128
MARBLE_YELLOW = 248
class Texture:
GRASS_TOP = 0
@ -272,6 +272,10 @@ class Texture:
LAVA_PLACEHOLDER = 255
# modded
YELLOW_COBBLE = 213
MARBLE_YELLOW = 214
@dataclass
class Tile:
block_id: BlockID
@ -299,6 +303,7 @@ tiles = [
Tile(BlockID.ORE_LAPIS, Texture.ORE_LAPIS),
Tile(BlockID.BLOCK_LAPIS, Texture.LAPIS),
Tile(BlockID.SANDSTONE, Texture.SANDSTONE_SIDE),
Tile(BlockID.CLOTH, Texture.CLOTH_64), # wool, colored
Tile(BlockID.FLOWER, Texture.FLOWER),
Tile(BlockID.ROSE, Texture.ROSE),
Tile(BlockID.MUSHROOM_1, Texture.MUSHROOM_BROWN),
@ -332,7 +337,7 @@ tiles = [
Tile(BlockID.FENCE, Texture.PLANKS),
Tile(BlockID.INVISIBLE, Texture.STONE),
Tile(BlockID.WOOD, Texture.PLANKS),
Tile(BlockID.LEAVES_CARRIED, Texture.LEAVES_TRANSPARENT), # fixme
#Tile(BlockID.LEAVES_CARRIED, Texture.LEAVES_TRANSPARENT), # fixme
Tile(BlockID.FIRE, Texture.FIRE1),
Tile(BlockID.SAPLING, Texture.SAPLING),
Tile(BlockID.SPONGE, Texture.SPONGE),
@ -346,6 +351,10 @@ tiles = [
Tile(BlockID.COBWEB, Texture.COBWEB),
Tile(BlockID.WORKBENCH, Texture.WORKBENCH_TOP), # fixme
Tile(BlockID.WHEAT, Texture.WHEAT_0),
# modded blocks
Tile(BlockID.YELLOW_COBBLE, Texture.YELLOW_COBBLE),
Tile(BlockID.MARBLE_YELLOW, Texture.MARBLE_YELLOW),
]
tiles_by_id = {

View File

@ -62,6 +62,9 @@ def block_neighbors(level_table, chunk_x, chunk_z, block_index):
if block_id == data.BlockID.AIR:
return
block_data = level_table[(chunk_x, chunk_z)].data[block_index // 2]
block_data = (block_data >> (1 - (block_index % 2)) * 4) & 0xf
xyz = mcregion.xyz_from_block_index(block_index)
center_position = vec3.add(xyz, (chunk_x * 16, 0, chunk_z * 16))
@ -74,7 +77,7 @@ def block_neighbors(level_table, chunk_x, chunk_z, block_index):
normal_indices = list(find_non_neighbors())
if block_id in non_solid_blocks or normal_indices:
yield center_position, block_id, normal_indices
yield center_position, block_id, block_data, normal_indices
def devoxelize_region(level_table, level_table_keys):
for chunk_x, chunk_z in level_table_keys:
@ -107,15 +110,15 @@ def build_block_configuration_table():
indices.extend(vertex_buffer.faces_by_normal[vertex_buffer.normals[j]])
yield indices
def pack_instance_data(position, block_id):
def pack_instance_data(position, block_id, block_data):
packed = struct.pack("<hhhBB",
position[0], position[1], position[2],
block_id,
0)
block_data)
return packed
def pack_light_data(position, block_id):
packed = struct.pack("<iiii", position[0], position[1], position[2], block_id)
packed = struct.pack("<ffff", position[0], position[1], position[2], block_id)
return packed
def build_block_instances(blocks):
@ -125,21 +128,21 @@ def build_block_instances(blocks):
light_sources = []
def is_deferred_block(position, block_id):
def is_deferred_block(position, block_id, block_data):
for i, custom_block_types in enumerate(custom_blocks):
if block_id in custom_block_types:
deferred_blocks[i].append((position, block_id))
deferred_blocks[i].append((position, block_id, block_data))
return True
return False
for position, block_id, normal_indices in blocks:
for position, block_id, block_data, normal_indices in blocks:
if block_id == data.BlockID.TORCH:
light_sources.append((position, block_id))
if is_deferred_block(position, block_id):
if is_deferred_block(position, block_id, block_data):
assert block_id in non_solid_blocks
continue
configuration = normal_indices_as_block_configuration(normal_indices)
by_configuration[configuration].append((position, block_id))
by_configuration[configuration].append((position, block_id, block_data))
offset = 0
configuration_instance_count_offset = []
@ -153,9 +156,9 @@ def build_block_instances(blocks):
continue
_blocks = by_configuration[configuration]
configuration_instance_count_offset.append((len(_blocks), offset))
for position, block_id in _blocks:
for position, block_id, block_data in _blocks:
assert block_id not in non_solid_blocks, block_id
packed = pack_instance_data(position, block_id)
packed = pack_instance_data(position, block_id, block_data)
f.write(packed)
offset += len(packed)
@ -165,9 +168,9 @@ def build_block_instances(blocks):
for custom_block_ix in range(len(custom_blocks)):
nc_offset = offset
nc_instance_count = 0
for position, block_id in deferred_blocks[custom_block_ix]:
for position, block_id, block_data in deferred_blocks[custom_block_ix]:
assert block_id in non_solid_blocks, block_id
packed = pack_instance_data(position, block_id)
packed = pack_instance_data(position, block_id, block_data)
f.write(packed)
offset += len(packed)
nc_instance_count += 1

View File

@ -0,0 +1,150 @@
import struct
from collections import defaultdict
import sys
import data
files = sys.argv[1:]
by_block_id = defaultdict(list)
no_tile = defaultdict(list)
block_ids = {
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
}
for filename in files:
with open(filename, 'rb') as f:
buf = f.read()
for i in range(len(buf) // 8):
x, y, z, block_id, block_data = struct.unpack("<hhhBB", buf[i*8:i*8+8])
if block_id == 35:
print(x, y, z, block_data)
if block_id not in block_ids and block_id not in data.tiles_by_id:
by_block_id[block_id].append((x, y, z, block_data))
elif block_id not in data.tiles_by_id:
no_tile[block_id].append((x, y, z, block_data))
print("no block id:")
for key in sorted(by_block_id.keys()):
print(" ", key, len(by_block_id[key]), by_block_id[key][0])
print("no tile:")
for key in sorted(no_tile.keys()):
print(" ", key, len(no_tile[key]), no_tile[key][0])

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1,58 +1,40 @@
#version 330 core
in VS_OUT {
vec3 Normal;
vec2 Texture;
flat int BlockID;
} fs_in;
uniform sampler2D PositionSampler;
uniform sampler2D NormalSampler;
uniform sampler2D ColorSampler;
out vec4 FragColor;
uniform float Linear;
uniform float Quadratic;
uniform vec3 Eye;
uniform sampler2D TerrainSampler;
layout (location = 0) out vec4 Color;
int Textures[256] = int[256](
185, 1, 0, 2, 16, 4, 15, 17, 205, 205, 237, 237, 18, 19, 32, 33,
34, 20, 52, 48, 49, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 39,
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
);
in vec4 PixelTexture;
layout (std140) uniform Lights
{
vec4 light[256];
};
void main()
{
vec3 light_direction = normalize(vec3(-1, -0.5, 0.5));
float diffuse_intensity = max(dot(normalize(fs_in.Normal), light_direction), 0.0);
vec4 position = texture(PositionSampler, PixelTexture.xy);
vec4 normal = texture(NormalSampler, PixelTexture.xy);
vec4 color = texture(ColorSampler, PixelTexture.xy);
int terrain_ix = int(Textures[int(fs_in.BlockID)]);
int terrain_x = terrain_ix % 16;
int terrain_y = terrain_ix / 16;
ivec2 coord = ivec2(terrain_x, terrain_y) * 16;
coord += ivec2(fs_in.Texture.xy * 16.0);
vec3 out_color = color.xyz * 0.1;
for (int i = 0; i < 82; i++) {
vec3 light_position = light[i].xzy;
float light_distance = length(light_position - position.xyz);
vec3 light_direction = normalize(light_position - position.xyz);
float diffuse = max(dot(normal.xyz, light_direction), 0.0);
//float attenuation = 1.0 / (1.0 + Linear * light_distance + Quadratic * light_distance * light_distance);
vec4 texture_color = texelFetch(TerrainSampler, coord, 0);
if (texture_color.w != 1.0) {
discard;
return;
float attenuation = 1.0 / (1.0 + Quadratic * light_distance * light_distance);
out_color += color.xyz * attenuation * diffuse;
//out_color = vec3(diffuse);
}
if (fs_in.BlockID == 18 || fs_in.BlockID == 31) // leaves
texture_color.xyz *= vec3(0.125, 0.494, 0.027);
if (diffuse_intensity < 0.1)
diffuse_intensity = 0.1;
if (fs_in.BlockID == 31 || fs_in.BlockID == 39 || fs_in.BlockID == 40 || fs_in.BlockID == 37 || fs_in.BlockID == 38 || fs_in.BlockID == 6) // tall_grass
diffuse_intensity = 1.0;
FragColor = vec4(texture_color.xyz * vec3(diffuse_intensity), 1.0);
Color = vec4(out_color, 1.0);
}

View File

@ -5,6 +5,7 @@ in VS_OUT {
vec3 Normal;
vec2 Texture;
flat int BlockID;
flat int Data;
} fs_in;
layout (location = 0) out vec3 Position;
@ -13,28 +14,37 @@ layout (location = 2) out vec3 Color;
uniform sampler2D TerrainSampler;
int Textures[256] = int[256](
185, 1, 0, 2, 16, 4, 15, 17, 205, 205, 237, 237, 18, 19, 32, 33,
34, 20, 52, 48, 49, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 39,
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
);
layout (std140) uniform TextureID
{
ivec4 block_id_to_texture_id[256 / 4];
};
int wool[16] = int[16]( 64, // 0 64
210, // 32 208
194, // 32 192
178, // 32 176
162, // 32 160
146, // 32 144
130, // 32 128
114, // 32 112
225, // 16 224
209, // 16 208
193, // 16 192
177, // 16 176
161, // 16 160
145, // 16 144
129, // 16 128
113 // 16 112
);
void main()
{
int terrain_ix = int(Textures[int(fs_in.BlockID)]);
int terrain_ix;
if (fs_in.BlockID == 35) // cloth
terrain_ix = wool[fs_in.Data];
else
terrain_ix = block_id_to_texture_id[fs_in.BlockID / 4][fs_in.BlockID % 4];
int terrain_x = terrain_ix % 16;
int terrain_y = terrain_ix / 16;
ivec2 coord = ivec2(terrain_x, terrain_y) * 16;
@ -49,7 +59,7 @@ void main()
if (fs_in.BlockID == 18 || fs_in.BlockID == 31) // leaves
texture_color.xyz *= vec3(0.125, 0.494, 0.027);
Position = fs_in.Position;
Normal = normalize(fs_in.Normal);
Position = fs_in.Position.xzy;
Normal = normalize(fs_in.Normal.xzy);
Color = texture_color.xyz;
}

View File

@ -7,12 +7,14 @@ in vec2 Texture;
// per-instance:
in vec3 BlockPosition;
in float BlockID;
in float Data;
out VS_OUT {
vec3 Position;
vec3 Normal;
vec2 Texture;
flat int BlockID;
flat int Data;
} vs_out;
uniform mat4 Transform;
@ -22,9 +24,10 @@ void main()
vec3 position = Position + BlockPosition; // world coordinates
vs_out.Position = position;
vs_out.Normal = Normal.xzy;
vs_out.Normal = Normal;
vs_out.Texture = Texture;
vs_out.BlockID = int(BlockID);
vs_out.Data = int(Data);
gl_Position = Transform * vec4(position.xzy, 1.0);
}

View File

@ -18,12 +18,17 @@ struct test_location {
unsigned int texture;
unsigned int block_position;
unsigned int block_id;
//unsigned int configuration;
unsigned int data;
} attrib;
struct {
unsigned int transform;
unsigned int terrain_sampler;
unsigned int texture_id;
} uniform;
struct {
unsigned int texture_id;
} binding;
};
static unsigned int test_program;
static test_location test_location;
@ -36,6 +41,24 @@ struct quad_location {
static unsigned int quad_program;
static quad_location quad_location;
struct lighting_location {
struct {
unsigned int position_sampler;
unsigned int normal_sampler;
unsigned int color_sampler;
unsigned int quadratic;
unsigned int linear;
unsigned int eye;
unsigned int lights;
} uniform;
struct {
unsigned int lights;
} binding;
};
static unsigned int lighting_program;
static lighting_location lighting_location;
struct char_tpl {
const char * vtx;
const char * cfg;
@ -100,19 +123,26 @@ void load_test_program()
test_location.attrib.block_position = glGetAttribLocation(program, "BlockPosition");
test_location.attrib.block_id = glGetAttribLocation(program, "BlockID");
test_location.attrib.data = glGetAttribLocation(program, "Data");
printf("test program:\n");
printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n block_id %u\n",
printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n block_id %u\n block_id %u\n",
test_location.attrib.position,
test_location.attrib.normal,
test_location.attrib.texture,
test_location.attrib.block_position,
test_location.attrib.block_id);
test_location.attrib.block_id,
test_location.attrib.data);
test_location.uniform.transform = glGetUniformLocation(program, "Transform");
test_location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler");
printf(" uniforms:\n transform %u\n terrain_sampler %u\n",
test_location.uniform.texture_id = glGetUniformBlockIndex(program, "TextureID");
printf(" uniforms:\n transform %u\n terrain_sampler %u\n texture_id %u\n",
test_location.uniform.transform,
test_location.uniform.terrain_sampler);
test_location.uniform.terrain_sampler,
test_location.uniform.texture_id);
test_location.binding.texture_id = 0;
glUniformBlockBinding(program, test_location.uniform.texture_id, test_location.binding.texture_id);
test_program = program;
}
@ -131,6 +161,33 @@ void load_quad_program()
quad_program = program;
}
void load_lighting_program()
{
unsigned int program = compile_from_files("shader/quad.vert",
NULL,
"shader/lighting.frag");
lighting_location.uniform.position_sampler = glGetUniformLocation(program, "PositionSampler");
lighting_location.uniform.normal_sampler = glGetUniformLocation(program, "NormalSampler");
lighting_location.uniform.color_sampler = glGetUniformLocation(program, "ColorSampler");
lighting_location.uniform.quadratic = glGetUniformLocation(program, "Quadratic");
lighting_location.uniform.linear = glGetUniformLocation(program, "Linear");
lighting_location.uniform.eye = glGetUniformLocation(program, "Eye");
lighting_location.uniform.lights = glGetUniformBlockIndex(program, "Lights");
fprintf(stderr, "lighting program:\n");
fprintf(stderr, " uniforms:\n position_sampler %u normal_sampler %u color_sampler %u lights %u\n",
lighting_location.uniform.position_sampler,
lighting_location.uniform.normal_sampler,
lighting_location.uniform.color_sampler,
lighting_location.uniform.lights);
lighting_location.binding.lights = 0;
glUniformBlockBinding(program, lighting_location.uniform.lights, lighting_location.binding.lights);
lighting_program = program;
}
void load_per_instance_vertex_buffer(int i)
{
int vertex_buffer_data_size;
@ -202,6 +259,10 @@ void load_test_vertex_attributes()
glVertexAttribFormat(test_location.attrib.block_id, 1, GL_UNSIGNED_BYTE, GL_FALSE, 6);
glVertexAttribBinding(test_location.attrib.block_id, 1);
glEnableVertexAttribArray(test_location.attrib.data);
glVertexAttribFormat(test_location.attrib.data, 1, GL_UNSIGNED_BYTE, GL_FALSE, 7);
glVertexAttribBinding(test_location.attrib.data, 1);
glBindVertexArray(0);
}
@ -334,23 +395,34 @@ void load_textures()
}
static unsigned int light_uniform_buffer;
static unsigned int texture_id_uniform_buffer;
void load_light_uniform_buffer()
unsigned int load_uniform_buffer(char const * const path)
{
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
int data_size;
void * data = read_file("minecraft/global.lights.vtx", &data_size);
void * data = read_file(path, &data_size);
assert(data != NULL);
glBufferData(GL_UNIFORM_BUFFER, data_size, data, GL_STATIC_DRAW);
free(data);
light_uniform_buffer = buffer;
glBindBuffer(GL_UNIFORM_BUFFER, 0);
return buffer;
}
void load_light_uniform_buffer()
{
light_uniform_buffer = load_uniform_buffer("minecraft/global.lights.vtx");
}
void load_texture_id_uniform_buffer()
{
texture_id_uniform_buffer = load_uniform_buffer("minecraft/block_id_to_texture_id.data");
}
extern "C" {
@ -382,21 +454,16 @@ void load(const char * source_path)
load_test_program();
load_buffers();
load_textures();
load_texture_id_uniform_buffer();
view_state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
view_state.eye = XMVectorSet(0, 0, 0, 1);
view_state.forward = XMVectorSet(1, 0, 0, 0);
view_state.eye = XMVectorSet(50.5f, 40.25f, 59.0f, 1);
view_state.forward = XMVectorSet(0.93, -0.38, 0, 0);
view_state.direction = view_state.forward;
view_state.pitch = 0.0;
view_state.pitch = -0.278;
view_state.fov = 1.5;
load_light_uniform_buffer();
//location.uniform.light_block = glGetUniformBlockIndex(test_program, "TexturesLayout");
//glUniformBlockBinding(ProgramName, location.uniform.light_block, bindingPoint);
//printf("textures_layout %d\n", textures_layout);
//////////////////////////////////////////////////////////////////////
// font
//////////////////////////////////////////////////////////////////////
@ -412,22 +479,39 @@ void load(const char * source_path)
load_quad_program();
load_quad_index_buffer();
//////////////////////////////////////////////////////////////////////
// lighting
//////////////////////////////////////////////////////////////////////
load_lighting_program();
load_light_uniform_buffer();
}
float _ry = 0.0;
struct light_parameters {
float quadratic;
float linear;
};
light_parameters lighting = {
.quadratic = 1.0,
.linear = 1.0
};
void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right)
int up, int down, int left, int right,
int a, int b, int x, int y)
{
//view_state.yaw += rx;
XMMATRIX mrz = XMMatrixRotationZ(rx * -0.035);
view_state.forward = XMVector3Transform(view_state.forward, mrz);
view_state.forward = XMVector3Transform(XMVector3NormalizeEst(view_state.forward), mrz);
XMVECTOR normal = XMVector3NormalizeEst(XMVector3Cross(view_state.forward, view_state.up));
view_state.pitch += ry * -0.035;
if (view_state.pitch > 1.5f) view_state.pitch = 1.5f;
if (view_state.pitch < -1.5f) view_state.pitch = -1.5f;
if (view_state.pitch > 1.57f) view_state.pitch = 1.57f;
if (view_state.pitch < -1.57f) view_state.pitch = -1.57f;
XMMATRIX mrn = XMMatrixRotationAxis(normal, view_state.pitch);
view_state.direction = XMVector3Transform(view_state.forward, mrn);
@ -438,6 +522,12 @@ void update(float lx, float ly, float rx, float ry, float tl, float tr,
if (new_fov > 0.00001f) {
view_state.fov = new_fov;
}
lighting.quadratic += 0.01 * a + -0.01 * b;
if (lighting.quadratic < 0.0f)
lighting.quadratic = 0.0f;
lighting.linear += 0.01 * x + -0.01 * y;
if (lighting.linear < 0.0f)
lighting.linear = 0.0f;
}
static inline int popcount(int x)
@ -454,6 +544,20 @@ void labeled_value(char * const buf, char const * const label, char const * cons
buf[label_length + len] = 0;
}
inline static float draw_vector(font::font const& ter_best, char * const buf, float y, char const * const label, XMVECTOR vec)
{
labeled_value<float>(buf, label, ".x: %.2f", XMVectorGetX(vec));
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
labeled_value<float>(buf, label, ".y: %.2f", XMVectorGetY(vec));
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
labeled_value<float>(buf, label, ".z: %.2f", XMVectorGetZ(vec));
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
return y;
}
void draw_hud()
{
char buf[512];
@ -469,11 +573,22 @@ void draw_hud()
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
labeled_value<float>(buf, "pitch: ", "%.9f", view_state.pitch);
labeled_value<int>(buf, "font_height: ", "%d", ter_best.desc->glyph_height);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
labeled_value<int>(buf, "font_height: ", "%d", ter_best.desc->glyph_height);
labeled_value<float>(buf, "lighting.quadratic: ", "%.2f", lighting.quadratic);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
labeled_value<float>(buf, "lighting.linear: ", "%.2f", lighting.linear);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
y = draw_vector(ter_best, buf, y, "eye", view_state.eye);
y = draw_vector(ter_best, buf, y, "forward", view_state.forward);
labeled_value<float>(buf, "pitch: ", "%.9f", view_state.pitch);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
}
@ -505,7 +620,7 @@ void draw_minecraft()
glUniformMatrix4fv(test_location.uniform.transform, 1, false, (float *)&transform);
glUniform1i(test_location.uniform.terrain_sampler, 0);
//glBindBufferBase(GL_UNIFORM_BUFFER, location.binding.light_block, light_uniform_buffer);
glBindBufferBase(GL_UNIFORM_BUFFER, test_location.binding.texture_id, texture_id_uniform_buffer);
//glEnable(GL_CULL_FACE);
//glCullFace(GL_FRONT);
@ -565,6 +680,45 @@ void draw_quad()
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
}
static inline bool near_zero(float a)
{
return (fabsf(a) < 0.00001f);
}
void draw_lighting()
{
glUseProgram(lighting_program);
glDepthFunc(GL_ALWAYS);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, geometry_buffer_pnc.target[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, geometry_buffer_pnc.target[1]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, geometry_buffer_pnc.target[2]);
glUniform1i(lighting_location.uniform.position_sampler, 0);
glUniform1i(lighting_location.uniform.normal_sampler, 1);
glUniform1i(lighting_location.uniform.color_sampler, 2);
float quadratic = near_zero(lighting.quadratic) ? 0.0 : 1.0f / lighting.quadratic;
float linear = near_zero(lighting.linear) ? 0.0 : 1.0f / lighting.linear;
glUniform1f(lighting_location.uniform.quadratic, quadratic);
glUniform1f(lighting_location.uniform.linear, linear);
XMFLOAT3 eye;
XMStoreFloat3(&eye, view_state.eye);
glUniform3fv(lighting_location.uniform.eye, 1, (float*)&eye);
glBindBufferBase(GL_UNIFORM_BUFFER, lighting_location.binding.lights, light_uniform_buffer);
glBindVertexArray(empty_vertex_array_object);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0);
}
void draw()
{
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@ -578,6 +732,7 @@ void draw()
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_quad();
//draw_hud();
draw_lighting();
//draw_quad();
draw_hud();
}