diff --git a/Makefile b/Makefile index 0aafa8a..bdb08ab 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,7 @@ OBJS = \ src/collada/animate.o \ src/lua_api.o \ src/pixel_line_art.o \ + src/flame.o \ data/scenes/ship20/ship20.o \ data/scenes/noodle/noodle.o \ data/scenes/shadow_test/shadow_test.o \ diff --git a/include/flame.h b/include/flame.h new file mode 100644 index 0000000..b4b9a70 --- /dev/null +++ b/include/flame.h @@ -0,0 +1,7 @@ +#pragma once + +namespace flame { + void load_program(); + void load_texture(); + void draw(unsigned int light_uniform_buffer, int light_count); +} diff --git a/include/view.h b/include/view.h index 47c04ed..320737c 100644 --- a/include/view.h +++ b/include/view.h @@ -1,5 +1,7 @@ #pragma once +#include "directxmath/directxmath.h" + namespace view { struct view_state { // positions diff --git a/minecraft/flame.data b/minecraft/flame.data new file mode 100644 index 0000000..11beae7 Binary files /dev/null and b/minecraft/flame.data differ diff --git a/minecraft/gen/mc.py b/minecraft/gen/mc.py index b4bf43e..f22459c 100644 --- a/minecraft/gen/mc.py +++ b/minecraft/gen/mc.py @@ -113,8 +113,8 @@ def pack_instance_data(position, block_id, block_data, texture_id): block_id, block_data, texture_id, special) return packed -def pack_light_data(position, block_id): - packed = struct.pack(" +#include + +#include "glad/gl.h" + +#include "file.h" +#include "opengl.h" + +#include "flame.h" +#include "view.h" + +extern unsigned int quad_index_buffer; +extern unsigned int empty_vertex_array_object; + +namespace flame { + static unsigned int program; + static unsigned int flame_texture; + static unsigned int vertex_array_object; + + const int per_instance_size = 4 * (sizeof (float)); + + struct layout { + struct { + unsigned int flame_sampler; + unsigned int frame; + unsigned int transform; + unsigned int eye; + } uniform; + struct { + unsigned int lights; + } binding; + }; + + layout layout = { + .uniform = { + .flame_sampler = 0, + .frame = 1, + .transform = 2, + .eye = 3, + }, + .binding = { + .lights = 0, + }, + }; + + void load_program() + { + program = compile_from_files("shader/flame.vert", + nullptr, + "shader/flame.frag"); + } + + void load_texture() + { + unsigned int texture; + glGenTextures(1, &texture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + 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); + + int texture_data_size; + void * texture_data = read_file("minecraft/flame.data", &texture_data_size); + assert(texture_data != nullptr); + + int width = 16; + int height = 80; + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture_data); + + free(texture_data); + + glBindTexture(GL_TEXTURE_2D, 0); + + flame_texture = texture; + } + + static int frame = 0; + + void draw(unsigned int light_uniform_buffer, int light_count) + { + glUseProgram(program); + + glBlendFunc(GL_ONE, GL_ZERO); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_GREATER); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, flame_texture); + glUniform1i(layout.uniform.frame, (frame / 20) % 4); + frame++; + + glUniformMatrix4fv(layout.uniform.transform, 1, false, (float *)&view::state.float_transform); + XMFLOAT3 eye; + XMStoreFloat3(&eye, view::state.eye); + glUniform3fv(layout.uniform.eye, 1, (float *)&eye); + + glBindBufferBase(GL_UNIFORM_BUFFER, layout.binding.lights, light_uniform_buffer); + + glBindVertexArray(empty_vertex_array_object); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_index_buffer); + + glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, (void *)0, light_count); + } +} diff --git a/src/hud.cpp b/src/hud.cpp index c6f3eb5..8db6edc 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -101,9 +101,9 @@ namespace hud { y += ter_best.desc->glyph_height; */ - y = draw_vector(ter_best, buf, y, "eye", view::state.eye); - y = draw_vector(ter_best, buf, y, "at", view::state.at); - y = draw_vector(ter_best, buf, y, "forward", view::state.forward); + y = draw_vector(ter_best, buf, y, "eye", XMVectorSetW(view::state.eye, 0)); + y = draw_vector(ter_best, buf, y, "at", XMVectorSetW(view::state.at, 0)); + y = draw_vector(ter_best, buf, y, "forward", XMVectorSetW(view::state.forward, 0)); labeled_value(buf, "pitch: ", "%.4f", view::state.pitch); font::draw_string(ter_best, buf, 10, y); diff --git a/src/test.cpp b/src/test.cpp index 37df43d..68f08b4 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -25,6 +25,7 @@ #include "collada/types.h" #include "collada/instance_types.h" #include "pixel_line_art.h" +#include "flame.h" #include "world/entry_table.h" #include "world/world.h" @@ -195,6 +196,13 @@ void load(const char * source_path) //node_at = scene_state.find_node_by_name("Camera001.Target"); //assert(node_at != nullptr); + + ////////////////////////////////////////////////////////////////////// + // flame + ////////////////////////////////////////////////////////////////////// + + flame::load_program(); + flame::load_texture(); } void update_keyboard(int up, int down, int left, int right, @@ -418,13 +426,15 @@ void draw() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); minecraft::draw(); - //draw_line(); + non_block::draw(); + flame::draw(minecraft::current_world->light_uniform_buffer, + minecraft::current_world->light_count); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - lighting::draw(minecraft::current_world->light_uniform_buffer, minecraft::current_world->light_count); //draw_quad(); diff --git a/src/view.cpp b/src/view.cpp index 8e539bf..84ea569 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -97,14 +97,14 @@ namespace view { state.up = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f); state.fov = 1.5; - state.pitch = -0.7; + state.pitch = -0.5520; - state.forward = XMVector3Normalize(XMVectorSet(-0.64, 0.77, 0, 0)); + state.forward = XMVector3Normalize(XMVectorSet(0.66, -0.75, 0, 0)); state.normal = get_normal(); // on forward change state.direction = get_direction(); // on forward/normal/pitch change // position - state.eye = XMVectorSet(-45.5f, 43.25f, 63.0f, 1); + state.eye = XMVectorSet(4.71f, 65.30, 57.92, 1); state.at = state.eye + state.direction * at_distance; //state.at = XMVectorSet(0, 0, 0, 1); //state.eye = XMVectorSet(0, -100, 0, 1);