render to geometry buffer
This commit is contained in:
parent
9ed9f70ec5
commit
ba2247068b
1
.gitignore
vendored
1
.gitignore
vendored
@ -7,3 +7,4 @@ main
|
||||
*.so
|
||||
*.dylib
|
||||
__pycache__
|
||||
minecraft/region*.lights.vtx
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
2
main.lua
2
main.lua
@ -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()
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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
BIN
minecraft/global.lights.vtx
Normal file
Binary file not shown.
58
shader/lighting.frag
Normal file
58
shader/lighting.frag
Normal 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
13
shader/quad.frag
Normal 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
17
shader/quad.vert
Normal 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);
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
27
src/font.cpp
27
src/font.cpp
@ -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++];
|
||||
|
||||
286
src/test.cpp
286
src/test.cpp
@ -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");
|
||||
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",
|
||||
location.uniform.transform,
|
||||
location.uniform.terrain_sampler);
|
||||
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();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user