summaryrefslogtreecommitdiff
path: root/src/core/texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/texture.c')
-rw-r--r--src/core/texture.c78
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*/
+ }
+}