townengine/src/twn_textures_c.h

93 lines
3.3 KiB
C

#ifndef TWN_TEXTURES_C_H
#define TWN_TEXTURES_C_H
#include "twn_util.h"
#include "twn_texture_modes.h"
#include "rendering/twn_gpu_texture_c.h"
#include <SDL2/SDL.h>
#include <stb_rect_pack.h>
#include <stdbool.h>
typedef struct Texture {
Rect srcrect; /* position in atlas */
SDL_Surface *data; /* original image data */
int atlas_index;
GPUTexture loner_texture; /* stored directly for loners, == 0 means atlas_index should be used */
GPUTexture repeating_texture; /* separately allocated Texture, for loners == loner_texture */
enum TextureMode mode;
} Texture;
typedef struct TextureCacheItem {
char *key;
struct Texture value;
} TextureCacheItem;
typedef struct TextureCache {
SDL_Window *window; /* from context */
struct TextureCacheItem *hash;
stbrp_node *node_buffer; /* used internally by stb_rect_pack */
SDL_Surface **atlas_surfaces;
GPUTexture *atlas_textures; /* shared by atlas textures */
int atlas_index; /* atlas that is currently being built */
bool is_dirty; /* current atlas needs to be recreated */
} TextureCache;
/* type safe structure for persistent texture handles */
typedef struct TextureKey { uint16_t id; } TextureKey;
/* tests whether given key structure corresponds to any texture */
#define m_texture_key_is_valid(p_key) ((p_key).id != (uint16_t)-1)
void textures_cache_init(struct TextureCache *cache, SDL_Window *window);
void textures_cache_deinit(struct TextureCache *cache);
/* for debugging */
void textures_dump_atlases(struct TextureCache *cache);
/* loads an image if it isn't in the cache, otherwise a no-op. */
/* can be called from anywhere at any time after init, useful if you want to */
/* preload textures you know will definitely be used */
// void textures_load(struct texture_cache *cache, const char *path);
/* repacks the current texture atlas based on the texture cache if needed */
/* any previously returned srcrect results are invalidated after that */
/* call it every time before rendering */
void textures_update_atlas(TextureCache *cache);
/* returns a persistent handle to some texture in cache, loading it if needed */
/* check the result with m_texture_key_is_valid() */
TextureKey textures_get_key(TextureCache *cache, const char *path);
/* returns a rect in a texture cache of the given key */
Rect textures_get_srcrect(const TextureCache *cache, TextureKey key);
/* returns a rect of dimensions of the whole texture (whole atlas) */
Rect textures_get_dims(const TextureCache *cache, TextureKey key);
/* returns an identifier that is equal for all textures placed in the same atlas */
int32_t textures_get_atlas_id(const TextureCache *cache, TextureKey key);
void textures_bind(const TextureCache *cache, TextureKey key);
void textures_bind_repeating(const TextureCache *cache, TextureKey key);
/* returns helpful information about contents of alpha channel in given texture */
TextureMode textures_get_mode(const TextureCache *cache, TextureKey key);
/* returns the number of atlases in the cache */
size_t textures_get_num_atlases(const TextureCache *cache);
/* TODO: should recieve texture_cache, get_key optimization cache should be cleared some other way */
void textures_reset_state(void);
#endif