diff options
| author | kkard2 <[email protected]> | 2025-09-14 13:04:56 +0200 |
|---|---|---|
| committer | kkard2 <[email protected]> | 2025-09-14 13:04:56 +0200 |
| commit | 8af35e5ed10f1b4cbef908948355a2832ea36fbe (patch) | |
| tree | 39893f071aee046dfad11bdf1494873e9ec49da1 | |
| parent | d30d4c2c3832c1e4df1d4fb266b04ca4dfdd828b (diff) | |
uv
| -rw-r--r-- | example.h | 8 | ||||
| -rw-r--r-- | examples/uv.c | 57 | ||||
| -rw-r--r-- | platform_win32.c | 6 | ||||
| -rw-r--r-- | sponge.h | 42 |
4 files changed, 112 insertions, 1 deletions
@@ -1,6 +1,8 @@ +#include <stdint.h> + void init(); void draw_frame(sponge_Texture c); - +void mouse_move(int32_t x, int32_t y); #ifdef SPONGE_EXAMPLE_IMPLEMENTATION @@ -8,4 +10,8 @@ void draw_frame(sponge_Texture c); void init() {} #endif // SPONGE_EXAMPLE_INIT_DEFINED +#ifndef SPONGE_EXAMPLE_MOUSE_MOVE_DEFINED +void mouse_move(int32_t x, int32_t y) {} +#endif // SPONGE_EXAMPLE_MOUSE_MOVE_DEFINED + #endif // SPONGE_EXAMPLE_IMPLEMENTATION diff --git a/examples/uv.c b/examples/uv.c new file mode 100644 index 0000000..937c4d5 --- /dev/null +++ b/examples/uv.c @@ -0,0 +1,57 @@ +#include <assert.h> + +#include "../sponge.h" +#define SPONGE_EXAMPLE_IMPLEMENTATION +#define SPONGE_EXAMPLE_INIT_DEFINED +#define SPONGE_EXAMPLE_MOUSE_MOVE_DEFINED +#include "../example.h" +#include "../stb_image.h" + +sponge_Texture texture; + +int32_t mouse_x; +int32_t mouse_y; + +void init() { + unsigned char *data = stbi_load("examples/kot.png", &texture.width, &texture.height, NULL, 4); + if (!data) { + printf("%s\n", stbi_failure_reason()); + assert(0); + } + + texture.stride_pixels = texture.width; + texture.pixels = (sponge_Color32 *)data; // NOTE(kard): be careful if changing following loop + + // converting from stbi's RGBA + for (size_t i = 0; i < texture.width * texture.height; i++) { + sponge_Color32 result; + result.r = data[i * 4 + 0]; + result.g = data[i * 4 + 1]; + result.b = data[i * 4 + 2]; + result.a = data[i * 4 + 3]; + texture.pixels[i] = result; + } + + mouse_x = 100; + mouse_y = 100; +} + +void mouse_move(int32_t x, int32_t y) { + mouse_x = x; + mouse_y = y; +} + +void draw_frame(sponge_Texture c) { + sponge_clear(c, sponge_color32_make(0xFF000000)); + sponge_Vec2I v0 = sponge_vec2i_make(mouse_x, mouse_y); + sponge_Vec2I v1 = sponge_vec2i_make(c.width - 100, 100); + sponge_Vec2I v2 = sponge_vec2i_make(100, c.height - 100); + sponge_Vec2I v3 = sponge_vec2i_make(c.width - 100, c.height - 100); + sponge_Vec2 uv0 = sponge_vec2_make(0.0f, 0.0f); + sponge_Vec2 uv1 = sponge_vec2_make(1.0f, 0.0f); + sponge_Vec2 uv2 = sponge_vec2_make(0.0f, 1.0f); + sponge_Vec2 uv3 = sponge_vec2_make(1.0f, 1.0f); + + sponge_draw_triangle_uv(c, v0, v1, v3, uv0, uv1, uv3, texture); + sponge_draw_triangle_uv(c, v0, v3, v2, uv0, uv3, uv2, texture); +} diff --git a/platform_win32.c b/platform_win32.c index be4d478..a8facc4 100644 --- a/platform_win32.c +++ b/platform_win32.c @@ -1,5 +1,6 @@ #define UNICODE #include <windows.h> +#include <windowsx.h> #include <assert.h> #include <stdio.h> #include <io.h> @@ -74,6 +75,11 @@ LRESULT __stdcall WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // TODO(kard): handle properly? (what does that even mean) assert(update_canvas(&canvas, width, height)); } + case WM_MOUSEMOVE: { + int32_t x = GET_X_LPARAM(lParam); + int32_t y = GET_Y_LPARAM(lParam); + mouse_move(x, y); + } default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } @@ -60,6 +60,7 @@ sponge_Vec2I sponge_vec2i_make(int32_t x, int32_t y); sponge_Vec2 sponge_vec2_add(sponge_Vec2 v0, sponge_Vec2 v1); sponge_Vec2 sponge_vec2_sub(sponge_Vec2 v0, sponge_Vec2 v1); +sponge_Vec2 sponge_vec2_mul(sponge_Vec2 v0, float f); float sponge_vec2_dot(sponge_Vec2 v0, sponge_Vec2 v1); sponge_Vec4 sponge_vec4_add(sponge_Vec4 v0, sponge_Vec4 v1); @@ -79,6 +80,8 @@ void sponge_draw_rect (sponge_Texture c, sponge_Vec2I v0, sponge_Vec2I v1, spo void sponge_draw_line (sponge_Texture c, sponge_Vec2I v0, sponge_Vec2I v1, sponge_Color32 col); void sponge_draw_texture(sponge_Texture c, sponge_Vec2I offset, sponge_Texture tex); +sponge_Color32 sponge_sample_texture(sponge_Vec2 uv, sponge_Texture tex); + // tests on which side of the line p is (negative on the left, positive on the right) int32_t sponge_edge_function(sponge_Vec2I p, sponge_Vec2I v0, sponge_Vec2I v1); @@ -96,6 +99,10 @@ void sponge_draw_triangle_col3( sponge_Texture c, sponge_Vec2I v0, sponge_Vec2I v1, sponge_Vec2I v2, sponge_ColorF col0, sponge_ColorF col1, sponge_ColorF col2); +void sponge_draw_triangle_uv( + sponge_Texture c, + sponge_Vec2I v0, sponge_Vec2I v1, sponge_Vec2I v2, + sponge_Vec2 uv0, sponge_Vec2 uv1, sponge_Vec2 uv2, sponge_Texture tex); #define SPONGE_CLAMP(val, min, max) ((val) < (min) ? (min) : ((val) > (max) ? (max) : (val))) #define SPONGE_MIN(x, y) ((x) < (y) ? (x) : (y)) @@ -166,6 +173,9 @@ sponge_Vec2 sponge_vec2_add(sponge_Vec2 v0, sponge_Vec2 v1) { sponge_Vec2 sponge_vec2_sub(sponge_Vec2 v0, sponge_Vec2 v1) { return (sponge_Vec2){ .x = v0.x - v1.x, .y = v0.y - v1.y }; } +sponge_Vec2 sponge_vec2_mul(sponge_Vec2 v0, float f) { + return (sponge_Vec2){ .x = v0.x * f, .y = v0.y * f }; +} float sponge_vec2_dot(sponge_Vec2 v0, sponge_Vec2 v1) { return (v0.x * v1.x) + (v0.y * v1.y); } @@ -274,6 +284,13 @@ void sponge_draw_texture(sponge_Texture c, sponge_Vec2I offset, sponge_Texture t } } +sponge_Color32 sponge_sample_texture(sponge_Vec2 uv, sponge_Texture tex) { + SPONGE_ASSERT(sponge_texture_valid(tex)); + uint32_t x = SPONGE_CLAMP((uint32_t)((float)tex.width * uv.x), 0, tex.width - 1); + uint32_t y = SPONGE_CLAMP((uint32_t)((float)tex.height * uv.y), 0, tex.height - 1); + return tex.pixels[(y * tex.stride_pixels) + x]; +} + int32_t sponge_edge_function(sponge_Vec2I v0, sponge_Vec2I v1, sponge_Vec2I p) { return ((p.x - v0.x) * (v1.y - v0.y)) - ((p.y - v0.y) * (v1.x - v0.x)); } @@ -282,6 +299,7 @@ void sponge_draw_triangle_init( sponge_Texture c, sponge_Vec2I v0, sponge_Vec2I v1, sponge_Vec2I v2, sponge_Vec2I *out_min, sponge_Vec2I *out_max, float *out_area2 ) { + SPONGE_ASSERT(sponge_texture_valid(c)); *out_min = sponge_vec2i_make( SPONGE_MAX(0, SPONGE_MIN(SPONGE_MIN(v0.x, v1.x), v2.x)), SPONGE_MAX(0, SPONGE_MIN(SPONGE_MIN(v0.y, v1.y), v2.y))); @@ -335,4 +353,28 @@ void sponge_draw_triangle_col3( } } +void sponge_draw_triangle_uv( + sponge_Texture c, + sponge_Vec2I v0, sponge_Vec2I v1, sponge_Vec2I v2, + sponge_Vec2 uv0, sponge_Vec2 uv1, sponge_Vec2 uv2, sponge_Texture tex +) { + sponge_Vec2I min, max; + float area2; + sponge_draw_triangle_init(c, v0, v1, v2, &min, &max, &area2); + sponge_Color32 *row = c.pixels + (min.y * c.stride_pixels); + + for (int32_t y = min.y; y <= max.y; y++, row += c.stride_pixels) { + for (int32_t x = min.x; x <= max.x; x++) { + float w0, w1, w2; + if (sponge_draw_triangle_iter(sponge_vec2i_make(x, y), v0, v1, v2, area2, &w0, &w1, &w2)) { + sponge_Vec2 uv = sponge_vec2_make(0.0f, 0.0f); + uv = sponge_vec2_add(uv, sponge_vec2_mul(uv0, w0)); + uv = sponge_vec2_add(uv, sponge_vec2_mul(uv1, w1)); + uv = sponge_vec2_add(uv, sponge_vec2_mul(uv2, w2)); + row[x] = sponge_sample_texture(uv, tex); + } + } + } +} + #endif // SPONGE_IMPLEMENTATION |
