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
|
*.so
|
||||||
*.dylib
|
*.dylib
|
||||||
__pycache__
|
__pycache__
|
||||||
|
minecraft/region*.lights.vtx
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
2
main.lua
2
main.lua
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
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
|
#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);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/font.cpp
27
src/font.cpp
@ -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++];
|
||||||
|
|||||||
288
src/test.cpp
288
src/test.cpp
@ -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();
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user