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
*.dylib
__pycache__
minecraft/region*.lights.vtx

View File

@ -59,10 +59,10 @@ namespace font {
} cell;
};
void load_element_buffer();
void load_shader();
font load_font(font_desc const& desc);
void load_fonts(font * const fonts, 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);
}

View File

@ -5,7 +5,6 @@ extern "C" {
#endif
void load(const char * source_path);
void draw_hud();
void draw();
void update(float lx, float ly, float rx, float ry, float tl, float tr,
int up, int down, int left, int right);

View File

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

View File

@ -114,11 +114,17 @@ def pack_instance_data(position, block_id):
0)
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):
by_configuration = defaultdict(list)
deferred_blocks = defaultdict(list)
light_sources = []
def is_deferred_block(position, block_id):
for i, custom_block_types in enumerate(custom_blocks):
if block_id in custom_block_types:
@ -127,6 +133,8 @@ def build_block_instances(blocks):
return False
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):
assert block_id in non_solid_blocks
continue
@ -170,6 +178,11 @@ def build_block_instances(blocks):
#print(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):
with open(path, "rb") as f:
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.0.-1.mcr ../region.0.-1 &
$PYTHON mc.py ~/Love2DWorld/region/r.-1.0.mcr ../region.-1.0 &
wait
cat ../region*.lights.vtx > ../global.lights.vtx

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
in VS_OUT {
vec3 Position; // world coordinates
vec3 Normal;
vec2 Texture;
flat int BlockID;
} 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;
@ -31,9 +34,6 @@ int Textures[256] = int[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);
int terrain_ix = int(Textures[int(fs_in.BlockID)]);
int terrain_x = 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
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);
Position = fs_in.Position;
Normal = normalize(fs_in.Normal);
Color = texture_color.xyz;
}

View File

@ -9,6 +9,7 @@ in vec3 BlockPosition;
in float BlockID;
out VS_OUT {
vec3 Position;
vec3 Normal;
vec2 Texture;
flat int BlockID;
@ -18,9 +19,12 @@ uniform mat4 Transform;
void main()
{
vec3 position = Position + BlockPosition; // world coordinates
vs_out.Position = position;
vs_out.Normal = Normal.xzy;
vs_out.Texture = Texture;
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 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()
{
unsigned int program = compile_from_files("shader/font.vert",
@ -53,7 +34,8 @@ namespace font {
location.uniform.texture_sampler = glGetUniformLocation(program, "TextureSampler");
location.uniform.cell = glGetUniformLocation(program, "Cell");
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.texture_sampler,
location.uniform.cell,
@ -150,7 +132,7 @@ namespace font {
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);
glDepthFunc(GL_ALWAYS);
@ -163,7 +145,10 @@ namespace font {
glBindVertexArray(vertex_array_object);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
}
void draw_string(font const& font, char const * const s, int x, int y)
{
int i = 0;
while (s[i] != 0) {
char c = s[i++];

View File

@ -11,7 +11,7 @@
#include "data.inc"
struct location {
struct test_location {
struct {
unsigned int position;
unsigned int normal;
@ -25,10 +25,16 @@ struct location {
unsigned int terrain_sampler;
} uniform;
};
// state
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 {
const char * vtx;
@ -63,34 +69,68 @@ struct instance_cfg {
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",
NULL, //"shader/test.geom",
NULL,
"shader/test.frag");
location.attrib.position = glGetAttribLocation(program, "Position");
location.attrib.normal = glGetAttribLocation(program, "Normal");
location.attrib.texture = glGetAttribLocation(program, "Texture");
test_location.attrib.position = glGetAttribLocation(program, "Position");
test_location.attrib.normal = glGetAttribLocation(program, "Normal");
test_location.attrib.texture = glGetAttribLocation(program, "Texture");
location.attrib.block_position = glGetAttribLocation(program, "BlockPosition");
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",
location.attrib.position,
location.attrib.normal,
location.attrib.texture,
location.attrib.block_position,
location.attrib.block_id);
test_location.attrib.block_position = glGetAttribLocation(program, "BlockPosition");
test_location.attrib.block_id = glGetAttribLocation(program, "BlockID");
printf("test program:\n");
printf(" attributes:\n position %u\n normal %u\n texture %u\n block_position %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);
location.uniform.transform = glGetUniformLocation(program, "Transform");
location.uniform.terrain_sampler = glGetUniformLocation(program, "TerrainSampler");
printf("uniforms:\n transform %u\n terrain_sampler %u\n",
location.uniform.transform,
location.uniform.terrain_sampler);
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.transform,
test_location.uniform.terrain_sampler);
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)
{
int vertex_buffer_data_size;
@ -106,6 +146,8 @@ void load_per_instance_vertex_buffer(int i)
void load_per_vertex_buffer()
{
glGenBuffers(1, &per_vertex_buffer);
int 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()
{
glGenBuffers(1, &index_buffer);
int 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);
}
void load_vertex_attributes()
void load_test_vertex_attributes()
{
glGenVertexArrays(1, &vertex_array_object);
glBindVertexArray(vertex_array_object);
@ -138,25 +182,25 @@ void load_vertex_attributes()
glVertexBindingDivisor(0, 0);
glVertexBindingDivisor(1, 1);
glEnableVertexAttribArray(location.attrib.position);
glVertexAttribFormat(location.attrib.position, 3, GL_HALF_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(location.attrib.position, 0);
glEnableVertexAttribArray(test_location.attrib.position);
glVertexAttribFormat(test_location.attrib.position, 3, GL_HALF_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(test_location.attrib.position, 0);
glEnableVertexAttribArray(location.attrib.normal);
glVertexAttribFormat(location.attrib.normal, 3, GL_HALF_FLOAT, GL_FALSE, 6);
glVertexAttribBinding(location.attrib.normal, 0);
glEnableVertexAttribArray(test_location.attrib.normal);
glVertexAttribFormat(test_location.attrib.normal, 3, GL_HALF_FLOAT, GL_FALSE, 6);
glVertexAttribBinding(test_location.attrib.normal, 0);
glEnableVertexAttribArray(location.attrib.texture);
glVertexAttribFormat(location.attrib.texture, 2, GL_HALF_FLOAT, GL_FALSE, 12);
glVertexAttribBinding(location.attrib.texture, 0);
glEnableVertexAttribArray(test_location.attrib.texture);
glVertexAttribFormat(test_location.attrib.texture, 2, GL_HALF_FLOAT, GL_FALSE, 12);
glVertexAttribBinding(test_location.attrib.texture, 0);
glEnableVertexAttribArray(location.attrib.block_position);
glVertexAttribFormat(location.attrib.block_position, 3, GL_SHORT, GL_FALSE, 0);
glVertexAttribBinding(location.attrib.block_position, 1);
glEnableVertexAttribArray(test_location.attrib.block_position);
glVertexAttribFormat(test_location.attrib.block_position, 3, GL_SHORT, GL_FALSE, 0);
glVertexAttribBinding(test_location.attrib.block_position, 1);
glEnableVertexAttribArray(location.attrib.block_id);
glVertexAttribFormat(location.attrib.block_id, 1, GL_UNSIGNED_BYTE, GL_FALSE, 6);
glVertexAttribBinding(location.attrib.block_id, 1);
glEnableVertexAttribArray(test_location.attrib.block_id);
glVertexAttribFormat(test_location.attrib.block_id, 1, GL_UNSIGNED_BYTE, GL_FALSE, 6);
glVertexAttribBinding(test_location.attrib.block_id, 1);
glBindVertexArray(0);
}
@ -170,25 +214,97 @@ void load_instance_cfg(int i)
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()
{
load_vertex_attributes();
load_test_vertex_attributes();
// per-vertex buffer
glGenBuffers(1, &per_vertex_buffer);
load_per_vertex_buffer();
// per-instance buffer
glGenBuffers(region_count, per_instance_vertex_buffers);
for (int i = 0; i < region_count; i++) {
load_per_instance_vertex_buffer(i);
load_instance_cfg(i);
}
// index buffer
glGenBuffers(1, &index_buffer);
load_index_buffer();
}
@ -217,22 +333,24 @@ void load_textures()
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;
glGenBuffers(1, &buffer);
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
int textures_data_size;
void * textures_data = read_file("minecraft/block_id_to_texture_id.data", &textures_data_size);
assert(textures_data != NULL);
int data_size;
void * data = read_file("minecraft/global.lights.vtx", &data_size);
assert(data != NULL);
glBufferData(GL_UNIFORM_BUFFER, textures_data_size, textures_data, GL_STATIC_DRAW);
free(textures_data);
glBufferData(GL_UNIFORM_BUFFER, data_size, data, GL_STATIC_DRAW);
free(data);
textures_ubo = buffer;
light_uniform_buffer = buffer;
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
extern "C" {
@ -261,7 +379,7 @@ void load(const char * source_path)
fprintf(stderr, "getproc %p\n", SDL_GL_GetProcAddress);
gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress);
load_program();
load_test_program();
load_buffers();
load_textures();
@ -273,21 +391,27 @@ void load(const char * source_path)
view_state.fov = 1.5;
//load_texture_shader_storage();
load_light_uniform_buffer();
//unsigned int textures_layout = glGetUniformBlockIndex(test_program, "TexturesLayout");
//glUniformBlockBinding(test_program, textures_layout, 0);
//location.uniform.light_block = glGetUniformBlockIndex(test_program, "TexturesLayout");
//glUniformBlockBinding(ProgramName, location.uniform.light_block, bindingPoint);
//printf("textures_layout %d\n", textures_layout);
//////////////////////////////////////////////////////////////////////
// font
//////////////////////////////////////////////////////////////////////
font::load_element_buffer();
font::load_shader();
terminus_fonts = (font::font *)malloc((sizeof (font::font)) * 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;
@ -339,6 +463,8 @@ void draw_hud()
int font_ix = font::best_font(font::terminus, font::terminus_length);
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);
font::draw_string(ter_best, buf, 10, y);
y += ter_best.desc->glyph_height;
@ -352,8 +478,11 @@ void draw_hud()
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);
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 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);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniformMatrix4fv(location.uniform.transform, 1, false, (float *)&transform);
glUniform1i(location.uniform.terrain_sampler, 0);
glUniformMatrix4fv(test_location.uniform.transform, 1, false, (float *)&transform);
glUniform1i(test_location.uniform.terrain_sampler, 0);
//glBindBuffer(GL_UNIFORM_BUFFER, textures_ubo);
//glBindBufferBase(GL_UNIFORM_BUFFER, 0, textures_ubo);
//glBindBufferBase(GL_UNIFORM_BUFFER, location.binding.light_block, light_uniform_buffer);
//glEnable(GL_CULL_FACE);
//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();
}