#ifndef TEXTURE_H #define TEXTURE_H #include "Common.h" #include "cglm/struct/vec4.h" #include #include #define INVALID_TEXTURE_ID 0xffff typedef enum { WM_REPEAT, WM_CLAMP, } wrap_mode_t; typedef enum { FM_NEAREST, FM_LINEAR, } filter_mode_t; typedef enum { UINT_8 = 1, UINT_16 = 2, FLOAT_32 = 4, } stride_t; typedef struct { uint32_t width; uint32_t height; char* data; } mipmap_t; typedef struct { vec2s texel_size; uint32_t width; uint32_t height; wrap_mode_t wrap_mode; filter_mode_t filter_mode; stride_t stride; uint8_t channel_count; uint8_t max_mip; mipmap_t* data; } texture_t; typedef struct { char* full_name; texture_t texture; } texture_asset_t; typedef struct { uint16_t count; uint16_t size; texture_asset_t* buffer; } texture_collection_t; typedef struct { uint16_t id; } texture_handle_t; typedef struct { vec3s view_direction; vec3s normal; vec3s edge1; vec3s edge2; vec2s uv1; vec2s uv2; float ray_width; float distance; } texture_sample_context_t; bool texture_collection_init(uint16_t size, texture_collection_t* textures); void texture_collection_resize(texture_collection_t* textures, uint16_t size); void texture_collection_free(texture_collection_t* textures); texture_handle_t texture_load(const char* filename, bool srgb, bool mipmap, stride_t stride, texture_collection_t* textures); vec4s texture_get_pixel(const texture_t* texture, vec2s uv, uint8_t lod); float texture_get_sample_lod(const texture_t* texture, const texture_sample_context_t* sample_context); vec4s texture_sample(const texture_t* texture, const texture_sample_context_t* sample_context, vec2s uv); vec4s texture_sample_lod(const texture_t* texture, vec2s uv, float lod); void texture_free(texture_t* texture); inline texture_handle_t invalid_texture_handle() { return (texture_handle_t){.id = INVALID_TEXTURE_ID}; } inline bool is_texture_entity_valid(texture_handle_t entity) { return entity.id != INVALID_TEXTURE_ID; } inline texture_t* get_texture(const texture_collection_t* textures, texture_handle_t entity) { if (entity.id >= textures->count || !is_texture_entity_valid(entity)) { return NULL; } return &textures->buffer[entity.id].texture; } inline size_t texture_get_pixel_index(texture_t* texture, uint32_t x, uint32_t y) { return (size_t)(y * texture->width + x) * texture->channel_count * texture->stride; } inline void texture_uv_to_index(texture_t* texture, vec2s uv, uint32_t* x, uint32_t* y) { uv_to_index(uv, texture->width, texture->height, x, y); } #endif // TEXTURE_H