summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example.h8
-rw-r--r--examples/uv.c57
-rw-r--r--platform_win32.c6
-rw-r--r--sponge.h42
4 files changed, 112 insertions, 1 deletions
diff --git a/example.h b/example.h
index 5c34ea1..df671e1 100644
--- a/example.h
+++ b/example.h
@@ -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);
}
diff --git a/sponge.h b/sponge.h
index d1a6b66..5484711 100644
--- a/sponge.h
+++ b/sponge.h
@@ -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