love-demo2/src/flame.cpp

107 lines
2.7 KiB
C++

#include <assert.h>
#include <stdlib.h>
#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 const * texture_data = file::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);
file::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);
}
}