#include #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); } }