diff options
Diffstat (limited to 'src/core/texture.c')
-rw-r--r-- | src/core/texture.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/core/texture.c b/src/core/texture.c index 7104bfb..1b70e4b 100644 --- a/src/core/texture.c +++ b/src/core/texture.c @@ -1,3 +1,81 @@ #include "texture.h" +#define STB_IMAGE_IMPLEMENTATION +#include "../lib/stb_image.h" +#include <stdio.h> +static void texture_abgr2argb(Texture* tex) { + ssr_assert(tex); + int width = tex->width, height = tex->height; + Color* pixels = tex->pixels; + for (int i = 0; i < width * height; ++i) { + uint r = (pixels[i] & 0xff) << 16; + uint g = ((pixels[i] >> 8) & 0xff) << 8; + uint b = ((pixels[i] >> 16) & 0xff); + uint a = ((pixels[i] >> 24) & 0xff) << 24; + pixels[i] = r | g | b | a; + } +} +Texture* texture_loadfromfile(const char* path) { + ssr_assert(path); + FILE* file = fopen(path, "rb"); + ssr_assert(file); + fseek(file, 0, SEEK_END); + int size = ftell(file); + fseek(file, 0, SEEK_SET); + char* buffer = ssrM_newvector(char, size); + ssr_assert(buffer); + int l = fread(buffer, 1, size, file); + if ( l!= size) { + free(buffer); + fclose(file); + return NULL; + } + fclose(file); + int width, height; + Color* pixels = (Color*)stbi_load_from_memory((unsigned char*)buffer, size, &width, &height, NULL, STBI_rgb_alpha); + ssrM_free(buffer); + if (!pixels) return NULL; + Texture* texture = ssrM_new(Texture); + texture->width = width; texture->height = height; + texture->pixels = pixels; + texture_abgr2argb(texture); + return texture; +} + +static Color32 sampling(Texture* tex, WrapMode wrap_mode, int x, int y) { + Color32 color; + if (wrap_mode == WRAPMODE_CLAMP) { /*clamp*/ + x = clamp(x, 0, tex->width - 1); + y = clamp(y, 0, tex->height - 1); + } else { /*repeat*/ + x = x % tex->width; + y = y % tex->height; + } + color_tocolor32(tex->pixels[x + y * tex->width], &color); + return color; +} + +Color32 texture_sampling(Texture* tex, FilterMode filter_mode, WrapMode wrap_mode, float x01, float y01) { + ssr_assert(tex); + int x = x01 * tex->width, y = (1 - y01) * tex->height; /*map to texture coordinate*/ + if (filter_mode == FILTERMODE_POINT) { + return sampling(tex, wrap_mode, x, y); + } + else if (filter_mode == FILTERMODE_BILINEAR) { + int x_min = floor(x), y_min = floor(y); + int x_max = ceil(x), y_max = ceil(y); + static Color32 tl, tr, bl, br, t, b, out; + tl = sampling(tex, wrap_mode, x_min, y_min); + tr = sampling(tex, wrap_mode, x_max, y_min); + bl = sampling(tex, wrap_mode, x_min, y_max); + br = sampling(tex, wrap_mode, x_max, y_max); + vec4_lerp(&tl, &tr, x - x_min, &t); + vec4_lerp(&bl, &br, x - x_min, &b); + vec4_lerp(&t, &b, y - y_min, &out); + return out; + } + else if (filter_mode == FILTERMODE_TRILINEAR) { + /*TODO*/ + } +} |