#include "tex.h" #include #include // TODO: write my own qoi implemenation, so that this isn't just here #define QOI_IMPLEMENTATION #include #include "renderer.h" #include "context.h" static struct texture load_texture_from_handle(u32 handle, int width, int height) { struct texture tex; tex.handle = handle; tex.width = width; tex.height = height; return tex; } static u32 get_texture_handle(u8 *data, int width, int height, u32 type) { u32 handle; glGenTextures(1, &handle); glBindTexture(GL_TEXTURE_2D, handle); glTexImage2D( GL_TEXTURE_2D, 0, type, width, height, 0, type, GL_UNSIGNED_BYTE, data ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); return handle; } struct texture load_texture(const char *file_path) { size_t size; char *file_dat = read_file(file_path, &size); qoi_desc desc; void *image_dat = qoi_decode(file_dat, size, &desc, 4); struct texture tex = load_texture_from_mem( image_dat, desc.width, desc.height ); mem_free(file_dat); mem_free(image_dat); return tex; } struct texture load_texture_from_mem(u8 *data, int width, int height) { struct texture tex; tex.width = width; tex.height = height; tex.handle = get_texture_handle(data, width, height, GL_RGBA); glGenerateMipmap(GL_TEXTURE_2D); return tex; } void free_texture(struct texture tex) { glDeleteTextures(1, &tex.handle); } bool is_texture_init(struct texture tex) { return tex.handle != 0 && tex.width > 0 && tex.height > 0; } struct render_texture create_render_texture( int width, int height, bool add_depth ) { u32 fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); struct texture depth = {0}; u32 color_handle = get_texture_handle(NULL, width, height, GL_RGB); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_handle, 0 ); struct texture color = load_texture_from_handle( color_handle, width, height ); if (add_depth) { u32 depth_handle = get_texture_handle( NULL, width, height, GL_DEPTH_COMPONENT ); glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_handle, 0 ); depth = load_texture_from_handle( depth_handle, width, height ); } if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) log_warn("framebuffer %d could not be completed", fbo); glBindFramebuffer(GL_FRAMEBUFFER, 0); struct render_texture rtex; rtex.handle = fbo; rtex.color = color; rtex.depth = depth; rtex.width = width; rtex.height = height; return rtex; } void free_render_texture(struct render_texture rtex) { glDeleteFramebuffers(1, &rtex.handle); free_texture(rtex.color); if (is_texture_init(rtex.depth)) free_texture(rtex.depth); }