diff options
| author | kkard2 <[email protected]> | 2025-09-19 20:43:34 +0200 |
|---|---|---|
| committer | kkard2 <[email protected]> | 2025-09-19 20:43:34 +0200 |
| commit | 0004eecef7a7693831bb5fd8b4cb3884ce7d4466 (patch) | |
| tree | 2e4493d53b5d2647c1e5947f521868346696a34c | |
| parent | 8af35e5ed10f1b4cbef908948355a2832ea36fbe (diff) | |
add matrices (not tested enough)
| -rw-r--r-- | examples/matrix.c | 30 | ||||
| -rw-r--r-- | sponge.h | 97 |
2 files changed, 127 insertions, 0 deletions
diff --git a/examples/matrix.c b/examples/matrix.c new file mode 100644 index 0000000..0b0ac91 --- /dev/null +++ b/examples/matrix.c @@ -0,0 +1,30 @@ +#include "../sponge.h" +#define SPONGE_EXAMPLE_IMPLEMENTATION +#include "../example.h" + +#define PI ((float)3.14159265358979323846) +#define SPEED ((1.0f / 360.0f) * 2 * PI) +static float angle = 0.0f; + +void draw_frame(sponge_Texture c) { + sponge_clear(c, sponge_color32_make(0xFF000000)); + angle += SPEED; + sponge_Vec3 v0 = sponge_vec3_make(0.0f, -0.8f, 0.0f); + sponge_Vec3 v1 = sponge_vec3_make(0.8f, 0.8f, 0.0f); + sponge_Vec3 v2 = sponge_vec3_make(-0.8f, 0.8f, 0.0f); + + sponge_Mat4 m = sponge_mat4_rotate(sponge_vec3_make(0.0f, 0.0f, angle)); + m = sponge_mat4_mul_mat4(m, sponge_mat4_translate(sponge_vec3_make(1.0f, 1.0f, 0.0f))); + m = sponge_mat4_mul_mat4(m, sponge_mat4_scale(sponge_vec3_make((float)(c.width / 2), (float)(c.height / 2), 1.0f))); + + v0 = sponge_vec3_mul_mat4(v0, m); + v1 = sponge_vec3_mul_mat4(v1, m); + v2 = sponge_vec3_mul_mat4(v2, m); + + sponge_draw_triangle_col3( + c, + sponge_vec2i_make((int32_t)v0.x, (int32_t)v0.y), + sponge_vec2i_make((int32_t)v1.x, (int32_t)v1.y), + sponge_vec2i_make((int32_t)v2.x, (int32_t)v2.y), + sponge_colorf_make(0xFFFF0000), sponge_colorf_make(0xFF00FF00), sponge_colorf_make(0xFF0000FF)); +} @@ -69,6 +69,29 @@ sponge_Vec4 sponge_vec4_mul(sponge_Vec4 v0, float f); sponge_ColorF sponge_color32_to_colorf(sponge_Color32 col); sponge_Color32 sponge_colorf_to_color32(sponge_ColorF col); + +// row-major +typedef union { + struct { + float c00; float c01; float c02; float c03; + float c10; float c11; float c12; float c13; + float c20; float c21; float c22; float c23; + float c30; float c31; float c32; float c33; + }; + float m[4][4]; + sponge_Vec4 rows[4]; +} sponge_Mat4; + +sponge_Mat4 sponge_mat4_mul_mat4(sponge_Mat4 m0, sponge_Mat4 m1); +sponge_Vec4 sponge_vec4_mul_mat4(sponge_Vec4 v0, sponge_Mat4 m0); +sponge_Vec3 sponge_vec3_mul_mat4(sponge_Vec3 v0, sponge_Mat4 m0); // sets .w to 1 and divides by .w at the end if necessary +sponge_Mat4 sponge_mat4_identity(); +sponge_Mat4 sponge_mat4_translate(sponge_Vec3 translation); +// TODO(kard): quaternion type beat +sponge_Mat4 sponge_mat4_rotate(sponge_Vec3 euler); // y -> x -> z order +sponge_Mat4 sponge_mat4_scale(sponge_Vec3 scale); + + // checks if tex.width or tex.height is equal to 0 // calling sponge functions with invalid textures is not supported int32_t sponge_texture_valid(sponge_Texture tex); @@ -202,6 +225,80 @@ sponge_Vec4 sponge_vec4_mul(sponge_Vec4 v0, float f) { return v0; } +sponge_Mat4 sponge_mat4_mul_mat4(sponge_Mat4 m0, sponge_Mat4 m1) { + sponge_Mat4 result; + for (int32_t i = 0; i < 4; i++) { + for (int32_t j = 0; j < 4; j++) { + result.m[i][j] = + (m0.m[i][0] * m1.m[0][j]) + + (m0.m[i][1] * m1.m[1][j]) + + (m0.m[i][2] * m1.m[2][j]) + + (m0.m[i][3] * m1.m[3][j]); + } + } + return result; +} +sponge_Vec4 sponge_vec4_mul_mat4(sponge_Vec4 v0, sponge_Mat4 m0) { + sponge_Vec4 v; + v.x = (v0.x * m0.c00) + (v0.y * m0.c10) + (v0.z * m0.c20) + (v0.w * m0.c30); + v.y = (v0.x * m0.c01) + (v0.y * m0.c11) + (v0.z * m0.c21) + (v0.w * m0.c31); + v.z = (v0.x * m0.c02) + (v0.y * m0.c12) + (v0.z * m0.c22) + (v0.w * m0.c32); + v.w = (v0.x * m0.c03) + (v0.y * m0.c13) + (v0.z * m0.c23) + (v0.w * m0.c33); + return v; +} +sponge_Vec3 sponge_vec3_mul_mat4(sponge_Vec3 v0, sponge_Mat4 m0) { + sponge_Vec4 v = sponge_vec4_mul_mat4(sponge_vec4_make(v0.x, v0.y, v0.z, 1.0f), m0); + if (v.w != 1.0f && v.w != 0.0f) + return sponge_vec3_make(v.x / v.w, v.y / v.w, v.z / v.w); + else + return sponge_vec3_make(v.x, v.y, v.z); +} + +sponge_Mat4 sponge_mat4_identity() { + sponge_Mat4 m; + m.c00 = 1.0f; m.c01 = 0.0f; m.c02 = 0.0f; m.c03 = 0.0f; + m.c10 = 0.0f; m.c11 = 1.0f; m.c12 = 0.0f; m.c13 = 0.0f; + m.c20 = 0.0f; m.c21 = 0.0f; m.c22 = 1.0f; m.c23 = 0.0f; + m.c30 = 0.0f; m.c31 = 0.0f; m.c32 = 0.0f; m.c33 = 1.0f; + return m; +} + +sponge_Mat4 sponge_mat4_translate(sponge_Vec3 translation) { + sponge_Mat4 m = sponge_mat4_identity(); + m.c30 = translation.x; + m.c31 = translation.y; + m.c32 = translation.z; + return m; +} + +sponge_Mat4 sponge_mat4_rotate(sponge_Vec3 euler) { + // TOOD(kard): make this not stupid + float sx = sinf(euler.x); float cx = cosf(euler.x); + float sy = sinf(euler.y); float cy = cosf(euler.y); + float sz = sinf(euler.z); float cz = cosf(euler.z); + sponge_Mat4 mx = sponge_mat4_identity(); + mx.c00 = 1; mx.c01 = 0; mx.c02 = 0; + mx.c10 = 0; mx.c11 = cx; mx.c12 = sx; + mx.c20 = 0; mx.c21 = -sx; mx.c22 = cx; + sponge_Mat4 my = sponge_mat4_identity(); + my.c00 = cy; my.c01 = 0; my.c02 = -sy; + my.c10 = 0; my.c11 = 1; my.c12 = 0; + my.c20 = sy; my.c21 = 0; my.c22 = cy; + sponge_Mat4 mz = sponge_mat4_identity(); + mz.c00 = cz; mz.c01 = sz; mz.c02 = 0; + mz.c10 = -sz; mz.c11 = cz; mz.c12 = 0; + mz.c20 = 0; mz.c21 = 0; mz.c22 = 1; + return sponge_mat4_mul_mat4(sponge_mat4_mul_mat4(my, mx), mz); +} + +sponge_Mat4 sponge_mat4_scale(sponge_Vec3 scale) { + sponge_Mat4 m = sponge_mat4_identity(); + m.c00 = scale.x; + m.c11 = scale.y; + m.c22 = scale.z; + return m; +} + int32_t sponge_texture_valid(sponge_Texture tex) { return tex.width != 0 && tex.height != 0 && tex.stride_pixels != 0; |
