render to geometry buffer

This commit is contained in:
Zack Buhman 2026-03-09 00:29:05 -05:00
parent 9ed9f70ec5
commit ba2247068b
14 changed files with 349 additions and 102 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ main
*.so *.so
*.dylib *.dylib
__pycache__ __pycache__
minecraft/region*.lights.vtx

View File

@ -59,10 +59,10 @@ namespace font {
} cell; } cell;
}; };
void load_element_buffer();
void load_shader(); void load_shader();
font load_font(font_desc const& desc); font load_font(font_desc const& desc);
void load_fonts(font * const fonts, font_desc const * const descs, int length); void load_fonts(font * const fonts, font_desc const * const descs, int length);
int best_font(font_desc const * const descs, int length); int best_font(font_desc const * const descs, int length);
void draw_start(font const& font, unsigned int vertex_array_object, unsigned int index_buffer);
void draw_string(font const& font, char const * const s, int x, int y); void draw_string(font const& font, char const * const s, int x, int y);
} }

View File

@ -5,7 +5,6 @@ extern "C" {
#endif #endif
void load(const char * source_path); void load(const char * source_path);
void draw_hud();
void draw(); void draw();
void update(float lx, float ly, float rx, float ry, float tl, float tr, 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);

View File

@ -8,7 +8,6 @@ function init()
void load(const char * source_path); void load(const char * source_path);
void update_window(int width, int height); void update_window(int width, int height);
void draw(); void draw();
void draw_hud();
void update(float lx, float ly, float rx, float ry, float tl, float tr, 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);
]] ]]
@ -36,7 +35,6 @@ end
local draw = function() local draw = function()
test.draw() test.draw()
test.draw_hud()
end end
function love.run() function love.run()

View File

@ -114,11 +114,17 @@ def pack_instance_data(position, block_id):
0) 0)
return packed return packed
def pack_light_data(position, block_id):
packed = struct.pack("<iiii", position[0], position[1], position[2], block_id)
return packed
def build_block_instances(blocks): def build_block_instances(blocks):
by_configuration = defaultdict(list) by_configuration = defaultdict(list)
deferred_blocks = defaultdict(list) deferred_blocks = defaultdict(list)
light_sources = []
def is_deferred_block(position, block_id): def is_deferred_block(position, block_id):
for i, custom_block_types in enumerate(custom_blocks): for i, custom_block_types in enumerate(custom_blocks):
if block_id in custom_block_types: if block_id in custom_block_types:
@ -127,6 +133,8 @@ def build_block_instances(blocks):
return False return False
for position, block_id, normal_indices in blocks: for position, block_id, 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):
assert block_id in non_solid_blocks assert block_id in non_solid_blocks
continue continue
@ -170,6 +178,11 @@ def build_block_instances(blocks):
#print(instance_count, offset) #print(instance_count, offset)
f.write(struct.pack("<ii", instance_count, offset)) f.write(struct.pack("<ii", instance_count, offset))
with open(f"{data_path}.lights.vtx", "wb") as f:
for position, block_id in light_sources:
packed = pack_light_data(position, block_id)
f.write(packed)
def level_table_from_path(level_table, path): def level_table_from_path(level_table, path):
with open(path, "rb") as f: with open(path, "rb") as f:
buf = f.read() buf = f.read()

View File

@ -5,3 +5,7 @@ $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.-1.-1.mcr ../region.-1.-1 &
$PYTHON mc.py ~/Love2DWorld/region/r.0.-1.mcr ../region.0.-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 & $PYTHON mc.py ~/Love2DWorld/region/r.-1.0.mcr ../region.-1.0 &
wait
cat ../region*.lights.vtx > ../global.lights.vtx

BIN
minecraft/global.lights.vtx Normal file

Binary file not shown.

58
shader/lighting.frag Normal file
View File

@ -0,0 +1,58 @@
#version 330 core
in VS_OUT {
vec3 Normal;
vec2 Texture;
flat int BlockID;
} fs_in;
out vec4 FragColor;
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
);
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);
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);
vec4 texture_color = texelFetch(TerrainSampler, coord, 0);
if (texture_color.w != 1.0) {
discard;
return;
}
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);
}

13
shader/quad.frag Normal file
View File

@ -0,0 +1,13 @@
#version 330 core
uniform sampler2D TextureSampler;
layout (location = 0) out vec4 Color;
in vec4 PixelTexture;
void main()
{
vec4 sample = texture(TextureSampler, PixelTexture.xy);
Color = vec4(sample.xyz, 1.0);
}

17
shader/quad.vert Normal file
View File

@ -0,0 +1,17 @@
#version 330 core
const vec2 vtx[4] = vec2[](vec2(-1.0, 1.0), // tl
vec2( 1.0, 1.0), // tr
vec2( 1.0, -1.0), // br
vec2(-1.0, -1.0)); // bl
out vec4 PixelTexture;
void main()
{
vec2 vertex = vtx[gl_VertexID];
PixelTexture = vec4(vertex * 0.5 + 0.5, 0, 0);
gl_Position = vec4(vertex, 0.0, 1.0);
}

View File

@ -1,12 +1,15 @@
#version 330 core #version 330 core
in VS_OUT { in VS_OUT {
vec3 Position; // world coordinates
vec3 Normal; vec3 Normal;
vec2 Texture; vec2 Texture;
flat int BlockID; flat int BlockID;
} fs_in; } fs_in;
out vec4 FragColor; layout (location = 0) out vec3 Position;
layout (location = 1) out vec3 Normal;
layout (location = 2) out vec3 Color;
uniform sampler2D TerrainSampler; uniform sampler2D TerrainSampler;
@ -31,9 +34,6 @@ int Textures[256] = int[256](
void main() 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);
int terrain_ix = int(Textures[int(fs_in.BlockID)]); int terrain_ix = int(Textures[int(fs_in.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;
@ -49,10 +49,7 @@ void main()
if (fs_in.BlockID == 18 || fs_in.BlockID == 31) // leaves if (fs_in.BlockID == 18 || fs_in.BlockID == 31) // leaves
texture_color.xyz *= vec3(0.125, 0.494, 0.027); texture_color.xyz *= vec3(0.125, 0.494, 0.027);
if (diffuse_intensity < 0.1) Position = fs_in.Position;
diffuse_intensity = 0.1; Normal = normalize(fs_in.Normal);
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 Color = texture_color.xyz;
diffuse_intensity = 1.0;
FragColor = vec4(texture_color.xyz * vec3(diffuse_intensity), 1.0);
} }

View File

@ -9,6 +9,7 @@ in vec3 BlockPosition;
in float BlockID; in float BlockID;
out VS_OUT { out VS_OUT {
vec3 Position;
vec3 Normal; vec3 Normal;
vec2 Texture; vec2 Texture;
flat int BlockID; flat int BlockID;
@ -18,9 +19,12 @@ uniform mat4 Transform;
void main() void main()
{ {
vec3 position = Position + BlockPosition; // world coordinates
vs_out.Position = position;
vs_out.Normal = Normal.xzy; vs_out.Normal = Normal.xzy;
vs_out.Texture = Texture; vs_out.Texture = Texture;
vs_out.BlockID = int(BlockID); vs_out.BlockID = int(BlockID);
gl_Position = Transform * vec4((Position + BlockPosition).xzy, 1.0); gl_Position = Transform * vec4(position.xzy, 1.0);
} }

View File

@ -24,25 +24,6 @@ namespace font {
static unsigned int font_program = -1; static unsigned int font_program = -1;
static unsigned int vertex_array_object = -1;
static unsigned int index_buffer = -1;
void load_element_buffer()
{
uint8_t const data[] = {
1, 0, 2, 3,
};
int const data_size = (sizeof (data));
glGenBuffers(1, &index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, data_size, data, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glGenVertexArrays(1, &vertex_array_object);
}
void load_shader() void load_shader()
{ {
unsigned int program = compile_from_files("shader/font.vert", unsigned int program = compile_from_files("shader/font.vert",
@ -53,7 +34,8 @@ namespace font {
location.uniform.texture_sampler = glGetUniformLocation(program, "TextureSampler"); location.uniform.texture_sampler = glGetUniformLocation(program, "TextureSampler");
location.uniform.cell = glGetUniformLocation(program, "Cell"); location.uniform.cell = glGetUniformLocation(program, "Cell");
location.uniform.glyph = glGetUniformLocation(program, "Glyph"); location.uniform.glyph = glGetUniformLocation(program, "Glyph");
printf("font uniforms:\n transform %u\n texture_sampler %u\n cell %u\n glyph %u\n", printf("font program:\n");
printf(" uniforms:\n transform %u\n texture_sampler %u\n cell %u\n glyph %u\n",
location.uniform.transform, location.uniform.transform,
location.uniform.texture_sampler, location.uniform.texture_sampler,
location.uniform.cell, location.uniform.cell,
@ -150,7 +132,7 @@ namespace font {
return transformf; return transformf;
} }
void draw_string(font const& font, char const * const s, int x, int y) void draw_start(font const& font, unsigned int vertex_array_object, unsigned int index_buffer)
{ {
glUseProgram(font_program); glUseProgram(font_program);
glDepthFunc(GL_ALWAYS); glDepthFunc(GL_ALWAYS);
@ -163,7 +145,10 @@ namespace font {
glBindVertexArray(vertex_array_object); glBindVertexArray(vertex_array_object);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
}
void draw_string(font const& font, char const * const s, int x, int y)
{
int i = 0; int i = 0;
while (s[i] != 0) { while (s[i] != 0) {
char c = s[i++]; char c = s[i++];

View File

@ -11,7 +11,7 @@
#include "data.inc" #include "data.inc"
struct location { struct test_location {
struct { struct {
unsigned int position; unsigned int position;
unsigned int normal; unsigned int normal;
@ -25,10 +25,16 @@ struct location {
unsigned int terrain_sampler; unsigned int terrain_sampler;
} uniform; } uniform;
}; };
// state
static unsigned int test_program; static unsigned int test_program;
static struct location location; static test_location test_location;
struct quad_location {
struct {
unsigned int texture_sampler;
} uniform;
};
static unsigned int quad_program;
static quad_location quad_location;
struct char_tpl { struct char_tpl {
const char * vtx; const char * vtx;
@ -63,34 +69,68 @@ struct instance_cfg {
static instance_cfg instance_cfg[region_count]; static instance_cfg instance_cfg[region_count];
void load_program() static unsigned int empty_vertex_array_object = -1;
static unsigned int quad_index_buffer = -1;
void load_quad_index_buffer()
{
uint8_t const data[] = {
1, 0, 2, 3,
};
int const data_size = (sizeof (data));
glGenBuffers(1, &quad_index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, data_size, data, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glGenVertexArrays(1, &empty_vertex_array_object);
}
void load_test_program()
{ {
unsigned int program = compile_from_files("shader/test.vert", unsigned int program = compile_from_files("shader/test.vert",
NULL, //"shader/test.geom", NULL,
"shader/test.frag"); "shader/test.frag");
location.attrib.position = glGetAttribLocation(program, "Position"); test_location.attrib.position = glGetAttribLocation(program, "Position");
location.attrib.normal = glGetAttribLocation(program, "Normal"); test_location.attrib.normal = glGetAttribLocation(program, "Normal");
location.attrib.texture = glGetAttribLocation(program, "Texture"); test_location.attrib.texture = glGetAttribLocation(program, "Texture");
location.attrib.block_position = glGetAttribLocation(program, "BlockPosition"); test_location.attrib.block_position = glGetAttribLocation(program, "BlockPosition");
location.attrib.block_id = glGetAttribLocation(program, "BlockID"); test_location.attrib.block_id = glGetAttribLocation(program, "BlockID");
printf("attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n block_id %u\n\n", printf("test program:\n");
location.attrib.position, printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %u\n block_id %u\n",
location.attrib.normal, test_location.attrib.position,
location.attrib.texture, test_location.attrib.normal,
location.attrib.block_position, test_location.attrib.texture,
location.attrib.block_id); test_location.attrib.block_position,
test_location.attrib.block_id);
location.uniform.transform = glGetUniformLocation(program, "Transform"); test_location.uniform.transform = glGetUniformLocation(program, "Transform");
location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler"); test_location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler");
printf(" uniforms:\n transform %u\n terrain_sampler %u\n", printf(" uniforms:\n transform %u\n terrain_sampler %u\n",
location.uniform.transform, test_location.uniform.transform,
location.uniform.terrain_sampler); test_location.uniform.terrain_sampler);
test_program = program; test_program = program;
} }
void load_quad_program()
{
unsigned int program = compile_from_files("shader/quad.vert",
NULL,
"shader/quad.frag");
quad_location.uniform.texture_sampler = glGetUniformLocation(program, "TextureSampler");
printf("quad program:\n");
printf(" uniforms:\n texture_sampler %u\n",
quad_location.uniform.texture_sampler);
quad_program = program;
}
void load_per_instance_vertex_buffer(int i) void load_per_instance_vertex_buffer(int i)
{ {
int vertex_buffer_data_size; int vertex_buffer_data_size;
@ -106,6 +146,8 @@ void load_per_instance_vertex_buffer(int i)
void load_per_vertex_buffer() void load_per_vertex_buffer()
{ {
glGenBuffers(1, &per_vertex_buffer);
int vertex_buffer_data_size; int vertex_buffer_data_size;
void * vertex_buffer_data = read_file("minecraft/per_vertex.vtx", &vertex_buffer_data_size); void * vertex_buffer_data = read_file("minecraft/per_vertex.vtx", &vertex_buffer_data_size);
@ -119,6 +161,8 @@ void load_per_vertex_buffer()
void load_index_buffer() void load_index_buffer()
{ {
glGenBuffers(1, &index_buffer);
int index_buffer_data_size; int index_buffer_data_size;
void * index_buffer_data = read_file("minecraft/configuration.idx", &index_buffer_data_size); void * index_buffer_data = read_file("minecraft/configuration.idx", &index_buffer_data_size);
@ -130,7 +174,7 @@ void load_index_buffer()
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
} }
void load_vertex_attributes() void load_test_vertex_attributes()
{ {
glGenVertexArrays(1, &vertex_array_object); glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object); glBindVertexArray(vertex_array_object);
@ -138,25 +182,25 @@ void load_vertex_attributes()
glVertexBindingDivisor(0, 0); glVertexBindingDivisor(0, 0);
glVertexBindingDivisor(1, 1); glVertexBindingDivisor(1, 1);
glEnableVertexAttribArray(location.attrib.position); glEnableVertexAttribArray(test_location.attrib.position);
glVertexAttribFormat(location.attrib.position, 3, GL_HALF_FLOAT, GL_FALSE, 0); glVertexAttribFormat(test_location.attrib.position, 3, GL_HALF_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(location.attrib.position, 0); glVertexAttribBinding(test_location.attrib.position, 0);
glEnableVertexAttribArray(location.attrib.normal); glEnableVertexAttribArray(test_location.attrib.normal);
glVertexAttribFormat(location.attrib.normal, 3, GL_HALF_FLOAT, GL_FALSE, 6); glVertexAttribFormat(test_location.attrib.normal, 3, GL_HALF_FLOAT, GL_FALSE, 6);
glVertexAttribBinding(location.attrib.normal, 0); glVertexAttribBinding(test_location.attrib.normal, 0);
glEnableVertexAttribArray(location.attrib.texture); glEnableVertexAttribArray(test_location.attrib.texture);
glVertexAttribFormat(location.attrib.texture, 2, GL_HALF_FLOAT, GL_FALSE, 12); glVertexAttribFormat(test_location.attrib.texture, 2, GL_HALF_FLOAT, GL_FALSE, 12);
glVertexAttribBinding(location.attrib.texture, 0); glVertexAttribBinding(test_location.attrib.texture, 0);
glEnableVertexAttribArray(location.attrib.block_position); glEnableVertexAttribArray(test_location.attrib.block_position);
glVertexAttribFormat(location.attrib.block_position, 3, GL_SHORT, GL_FALSE, 0); glVertexAttribFormat(test_location.attrib.block_position, 3, GL_SHORT, GL_FALSE, 0);
glVertexAttribBinding(location.attrib.block_position, 1); glVertexAttribBinding(test_location.attrib.block_position, 1);
glEnableVertexAttribArray(location.attrib.block_id); glEnableVertexAttribArray(test_location.attrib.block_id);
glVertexAttribFormat(location.attrib.block_id, 1, GL_UNSIGNED_BYTE, GL_FALSE, 6); glVertexAttribFormat(test_location.attrib.block_id, 1, GL_UNSIGNED_BYTE, GL_FALSE, 6);
glVertexAttribBinding(location.attrib.block_id, 1); glVertexAttribBinding(test_location.attrib.block_id, 1);
glBindVertexArray(0); glBindVertexArray(0);
} }
@ -170,25 +214,97 @@ void load_instance_cfg(int i)
memcpy(&instance_cfg[i], data, data_size); memcpy(&instance_cfg[i], data, data_size);
} }
struct target_name {
enum {
POSITION = 0,
NORMAL = 1,
COLOR = 2,
};
};
template <int render_target_count>
struct geometry_buffer {
unsigned int framebuffer;
unsigned int target[render_target_count]; // textures
unsigned int renderbuffer;
int initialized;
int width;
int height;
};
struct target_type {
GLint internal_format;
GLenum attachment;
};
static geometry_buffer<3> geometry_buffer_pnc = {};
static target_type const geometry_buffer_pnc_types[3] = {
[target_name::POSITION] = { GL_RGBA16F, GL_COLOR_ATTACHMENT0 },
[target_name::NORMAL] = { GL_RGBA16F, GL_COLOR_ATTACHMENT1 },
[target_name::COLOR] = { GL_RGBA8, GL_COLOR_ATTACHMENT2 },
};
template <int render_target_count>
void init_geometry_buffer(geometry_buffer<render_target_count>& geometry_buffer, target_type const * const types)
{
int width = g_window_width;
int height = g_window_height;
if ((geometry_buffer.initialized == 1) && (width == geometry_buffer.width) && (height == geometry_buffer.height)) {
return;
}
if (geometry_buffer.initialized) {
glDeleteFramebuffers(1, &geometry_buffer.framebuffer);
glDeleteTextures(render_target_count, geometry_buffer.target);
glDeleteRenderbuffers(1, &geometry_buffer.renderbuffer);
}
glGenFramebuffers(1, &geometry_buffer.framebuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, geometry_buffer.framebuffer);
glGenTextures(render_target_count, geometry_buffer.target);
for (int i = 0; i < render_target_count; i++) {
glBindTexture(GL_TEXTURE_2D, geometry_buffer.target[i]);
glTexImage2D(GL_TEXTURE_2D, 0, types[i].internal_format, width, height, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, types[i].attachment, GL_TEXTURE_2D, geometry_buffer.target[i], 0);
}
static_assert(render_target_count == 3);
GLenum attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers(3, attachments); // bound to GL_DRAW_FRAMEBUFFER
glGenRenderbuffers(1, &geometry_buffer.renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, geometry_buffer.renderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, geometry_buffer.renderbuffer);
assert(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
geometry_buffer.initialized = 1;
geometry_buffer.width = width;
geometry_buffer.height = height;
}
void load_buffers() void load_buffers()
{ {
load_vertex_attributes(); load_test_vertex_attributes();
// per-vertex buffer // per-vertex buffer
glGenBuffers(1, &per_vertex_buffer);
load_per_vertex_buffer(); load_per_vertex_buffer();
// per-instance buffer // per-instance buffer
glGenBuffers(region_count, per_instance_vertex_buffers); glGenBuffers(region_count, per_instance_vertex_buffers);
for (int i = 0; i < region_count; i++) { for (int i = 0; i < region_count; i++) {
load_per_instance_vertex_buffer(i); load_per_instance_vertex_buffer(i);
load_instance_cfg(i); load_instance_cfg(i);
} }
// index buffer // index buffer
glGenBuffers(1, &index_buffer);
load_index_buffer(); load_index_buffer();
} }
@ -217,22 +333,24 @@ void load_textures()
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
static unsigned int textures_ubo; static unsigned int light_uniform_buffer;
void load_texture_shader_storage() void load_light_uniform_buffer()
{ {
unsigned int buffer; unsigned int buffer;
glGenBuffers(1, &buffer); glGenBuffers(1, &buffer);
glBindBuffer(GL_UNIFORM_BUFFER, buffer); glBindBuffer(GL_UNIFORM_BUFFER, buffer);
int textures_data_size; int data_size;
void * textures_data = read_file("minecraft/block_id_to_texture_id.data", &textures_data_size); void * data = read_file("minecraft/global.lights.vtx", &data_size);
assert(textures_data != NULL); assert(data != NULL);
glBufferData(GL_UNIFORM_BUFFER, textures_data_size, textures_data, GL_STATIC_DRAW); glBufferData(GL_UNIFORM_BUFFER, data_size, data, GL_STATIC_DRAW);
free(textures_data); free(data);
textures_ubo = buffer; light_uniform_buffer = buffer;
glBindBuffer(GL_UNIFORM_BUFFER, 0);
} }
extern "C" { extern "C" {
@ -261,7 +379,7 @@ void load(const char * source_path)
fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress); fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress);
gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress); gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress);
load_program(); load_test_program();
load_buffers(); load_buffers();
load_textures(); load_textures();
@ -273,21 +391,27 @@ void load(const char * source_path)
view_state.fov = 1.5; view_state.fov = 1.5;
//load_texture_shader_storage(); load_light_uniform_buffer();
//unsigned int textures_layout = glGetUniformBlockIndex(test_program, "TexturesLayout"); //location.uniform.light_block = glGetUniformBlockIndex(test_program, "TexturesLayout");
//glUniformBlockBinding(test_program, textures_layout, 0); //glUniformBlockBinding(ProgramName, location.uniform.light_block, bindingPoint);
//printf("textures_layout %d\n", textures_layout); //printf("textures_layout %d\n", textures_layout);
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// font // font
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
font::load_element_buffer();
font::load_shader(); font::load_shader();
terminus_fonts = (font::font *)malloc((sizeof (font::font)) * font::terminus_length); terminus_fonts = (font::font *)malloc((sizeof (font::font)) * font::terminus_length);
font::load_fonts(terminus_fonts, font::terminus, font::terminus_length); font::load_fonts(terminus_fonts, font::terminus, font::terminus_length);
//////////////////////////////////////////////////////////////////////
// quad
//////////////////////////////////////////////////////////////////////
load_quad_program();
load_quad_index_buffer();
} }
float _ry = 0.0; float _ry = 0.0;
@ -339,6 +463,8 @@ void draw_hud()
int font_ix = font::best_font(font::terminus, font::terminus_length); int font_ix = font::best_font(font::terminus, font::terminus_length);
font::font const& ter_best = terminus_fonts[font_ix]; font::font const& ter_best = terminus_fonts[font_ix];
font::draw_start(ter_best, empty_vertex_array_object, quad_index_buffer);
labeled_value<float>(buf, "fov: ", "%.3f", view_state.fov); labeled_value<float>(buf, "fov: ", "%.3f", view_state.fov);
font::draw_string(ter_best, buf, 10, y); font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height; y += ter_best.desc->glyph_height;
@ -352,8 +478,11 @@ void draw_hud()
y += ter_best.desc->glyph_height; y += ter_best.desc->glyph_height;
} }
void draw() void draw_minecraft()
{ {
// possibly re-initialize geometry buffer if window width/height changes
init_geometry_buffer(geometry_buffer_pnc, geometry_buffer_pnc_types);
XMVECTOR at = XMVectorAdd(view_state.eye, view_state.direction); XMVECTOR at = XMVectorAdd(view_state.eye, view_state.direction);
XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up); XMMATRIX view = XMMatrixLookAtRH(view_state.eye, at, view_state.up);
@ -364,23 +493,19 @@ void draw()
XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z); XMMATRIX projection = XMMatrixPerspectiveFovRH(fov_angle_y, aspect_ratio, near_z, far_z);
XMMATRIX transform = view * projection; XMMATRIX transform = view * projection;
glClearColor(0.1f, 0.1f, 0.1f, 0.1f);
glClearDepth(-1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(test_program); glUseProgram(test_program);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER); glDepthFunc(GL_GREATER);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
glUniformMatrix4fv(location.uniform.transform, 1, false, (float *)&transform); glUniformMatrix4fv(test_location.uniform.transform, 1, false, (float *)&transform);
glUniform1i(location.uniform.terrain_sampler, 0); glUniform1i(test_location.uniform.terrain_sampler, 0);
//glBindBuffer(GL_UNIFORM_BUFFER, textures_ubo); //glBindBufferBase(GL_UNIFORM_BUFFER, location.binding.light_block, light_uniform_buffer);
//glBindBufferBase(GL_UNIFORM_BUFFER, 0, textures_ubo);
//glEnable(GL_CULL_FACE); //glEnable(GL_CULL_FACE);
//glCullFace(GL_FRONT); //glCullFace(GL_FRONT);
@ -423,3 +548,36 @@ void draw()
} }
} }
} }
void draw_quad()
{
glUseProgram(quad_program);
glDepthFunc(GL_ALWAYS);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, geometry_buffer_pnc.target[1]);
glUniform1i(quad_location.uniform.texture_sampler, 0);
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);
glClearDepth(-1.0f);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, geometry_buffer_pnc.framebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_minecraft();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_quad();
//draw_hud();
}