diff options
author | talha <sarcxd@gmail.com> | 2024-12-11 00:53:05 +0500 |
---|---|---|
committer | talha <sarcxd@gmail.com> | 2024-12-11 00:53:05 +0500 |
commit | 9022d6c1fa64689ab9203d967a8cd31b406155da (patch) | |
tree | 5a85440c894545fc0e8dd823b6cc626c2be01fbc /source/math.h | |
parent | 60085c01f190c01adaf24b6f337e2528d1de23b7 (diff) |
Added batch rendering (however basic it might be)
Diffstat (limited to 'source/math.h')
-rwxr-xr-x | source/math.h | 228 |
1 files changed, 91 insertions, 137 deletions
diff --git a/source/math.h b/source/math.h index e516569..22966ec 100755 --- a/source/math.h +++ b/source/math.h @@ -117,12 +117,6 @@ union Mat4 { r32 buffer[16]; }; -union Mat4RowMajor { - Vec4 xyzw[4]; - r32 data[4][4]; - r32 buffer[16]; -}; - // ==== Vec2 ==== Vec2 v2(r32 v) { return Vec2{v, v}; @@ -355,47 +349,7 @@ Mat4 subtract4m(Mat4 a, Mat4 b) return res; } -#if disabled -Vec4 multiply4mv_rm(Mat4RowMajor mat, Vec4 vec) -{ - /* - * @note: Incase I get confused about this in the future. - * - * Everything is row-order, which means that things in memory are laid out row first. So with a sample matrix - * we have this order in memory: r1c1 r1c2 r1c3 r1c4 r2c1 ... (r = row, c = column). The same holds true for - * vectors. (maybe move this explanation to the top) - * - * Now, multiply4vm will multiply a vector with a matrix. Conventionally that does not make any sense as - * a vector is usually 4x1 and a matrix ix 4x4. - * What this function considers a vector, while it is a vector, it is infact a row from a matrix, which - * means that the vector is 1x4 and the matrix is 4x4. - * - * The function is meant to supplement the matrix multiplication process to alleviate the multiple lines of code - * we have to write when multiplying the row of a left matrix to each column of the right matrix - */ - Vec4 res = { 0 }; - res.x = (mat.data[0][0] * vec.x) + (mat.data[0][1] * vec.y) + (mat.data[0][2] * vec.z) + (mat.data[0][3] * vec.w); - res.y = (mat.data[1][0] * vec.x) + (mat.data[1][1] * vec.y) + (mat.data[1][2] * vec.z) + (mat.data[1][3] * vec.w); - res.z = (mat.data[2][0] * vec.x) + (mat.data[2][1] * vec.y) + (mat.data[2][2] * vec.z) + (mat.data[2][3] * vec.w); - res.w = (mat.data[3][0] * vec.x) + (mat.data[3][1] * vec.y) + (mat.data[3][2] * vec.z) + (mat.data[3][3] * vec.w); - - return res; -} - -Mat4RowMajor multiply4m_rm(Mat4RowMajor a, Mat4RowMajor b) -{ - Mat4RowMajor res = { 0 }; - - res.xyzw[0] = multiply4mv_rm(b, a.xyzw[0]); - res.xyzw[1] = multiply4mv_rm(b, a.xyzw[1]); - res.xyzw[2] = multiply4mv_rm(b, a.xyzw[2]); - res.xyzw[3] = multiply4mv_rm(b, a.xyzw[3]); - - return res; -} -#endif - -Vec4 multiply4vm(Vec4 v, Mat4 m) +Vec4 multiply4mv(Mat4 m, Vec4 v) { Vec4 res = {0}; @@ -426,10 +380,10 @@ Mat4 multiply4m(Mat4 a, Mat4 b) { Mat4 res = { 0 }; - res.row[0] = multiply4vm(b.row[0], a); - res.row[1] = multiply4vm(b.row[1], a); - res.row[2] = multiply4vm(b.row[2], a); - res.row[3] = multiply4vm(b.row[3], a); + res.row[0] = multiply4mv(a, b.row[0]); + res.row[1] = multiply4mv(a, b.row[1]); + res.row[2] = multiply4mv(a, b.row[2]); + res.row[3] = multiply4mv(a, b.row[3]); return res; } @@ -446,20 +400,7 @@ Mat4 scaling_matrix4m(r32 x, r32 y, r32 z) return res; } -#if Disabled -Mat4RowMajor translation_matrix4m_rm(r32 x, r32 y, r32 z) -{ - // generates a 4x4 translation matrix for translation along each of the x,y,z axis - Mat4RowMajor res = init_value4m(1.0f); - res.data[0][3] = x; - res.data[1][3] = y; - res.data[2][3] = z; - - return res; -} -#endif - -Mat4 translation_matrix4m_cm(r32 x, r32 y, r32 z) +Mat4 translation_matrix4m(r32 x, r32 y, r32 z) { Mat4 res = init_value4m(1.0f); res.row[3] = Vec4{x, y, z, 1.0f}; @@ -467,80 +408,46 @@ Mat4 translation_matrix4m_cm(r32 x, r32 y, r32 z) return res; } -#if Disabled -Mat4RowMajor rotation_matrix4m(r32 angle_radians, Vec3 axis) // generates a 4x4 rotation matrix for rotation along each of the x,y,z axis +Mat4 rotation_matrix4m(r32 angle_radians, Vec3 axis) { - Mat4RowMajor res = init_value4m(1.0f); - axis = normalize3v(axis); - - r32 cos_theta = cosf(angle_radians); - r32 sin_theta = sinf(angle_radians); - r32 cos_value = 1.0f - cos_theta; - - res.data[0][0] = (axis.x * axis.x * cos_value) + cos_theta; - res.data[0][1] = (axis.x * axis.y * cos_value) + (axis.z * sin_theta); - res.data[0][2] = (axis.x * axis.z * cos_value) - (axis.y * sin_theta); - - res.data[1][0] = (axis.x * axis.y * cos_value) - (axis.z * sin_theta); - res.data[1][1] = (axis.y * axis.y * cos_value) + cos_theta; - res.data[1][2] = (axis.y * axis.z * cos_value) + (axis.x * sin_theta); - - res.data[2][0] = (axis.x * axis.z * cos_value) + (axis.y * sin_theta); - res.data[2][1] = (axis.z * axis.y * cos_value) - (axis.x * sin_theta); - res.data[2][2] = (axis.z * axis.z * cos_value) + cos_theta; - - return res; -} + Mat4 res = init_value4m(1.0f); + axis = normalize3v(axis); -Mat4RowMajor perspective_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far) -{ - Mat4RowMajor res = { 0 }; - - res.data[0][0] = (2.0 * near)/(right - left); - res.data[0][2] = (right + left)/(right - left); - - res.data[1][1] = (2.0 * near)/(top - bottom); - res.data[1][2] = (top + bottom)/(top - bottom); - - res.data[2][2] = -(far + near)/(far - near); - res.data[2][3] = -2.0*far*near/(far - near); - - res.data[3][2] = -1.0; - - return res; -} + r32 cos_theta = cosf(angle_radians); + r32 sin_theta = sinf(angle_radians); + r32 cos_value = 1.0f - cos_theta; -Mat4RowMajor perspective4m(r32 fov, r32 aspect_ratio, r32 near, r32 far) -{ - r32 cotangent = 1.0f / tanf(fov / 2.0f); - - Mat4RowMajor res = { 0 }; - - res.data[0][0] = cotangent / aspect_ratio; - - res.data[1][1] = cotangent; - - res.data[2][2] = -(far + near) / (far - near); - res.data[2][3] = -2.0f * far * near / (far - near); - - res.data[3][2] = -1.0f; - - return res; + res.data[0][0] = (axis.x * axis.x * cos_value) + cos_theta; + res.data[0][1] = (axis.x * axis.y * cos_value) + (axis.z * sin_theta); + res.data[0][2] = (axis.x * axis.z * cos_value) - (axis.y * sin_theta); + + res.data[1][0] = (axis.x * axis.y * cos_value) - (axis.z * sin_theta); + res.data[1][1] = (axis.y * axis.y * cos_value) + cos_theta; + res.data[1][2] = (axis.y * axis.z * cos_value) + (axis.x * sin_theta); + + res.data[2][0] = (axis.x * axis.z * cos_value) + (axis.y * sin_theta); + res.data[2][1] = (axis.y * axis.z * cos_value) - (axis.x * sin_theta); + res.data[2][2] = (axis.z * axis.z * cos_value) + cos_value; + + return res; } -Mat4RowMajor orthographic_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far) +Mat4 orthographic4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far) { - // @todo: understand the derivation once I am done experimenting - Mat4RowMajor res = { 0 }; - res.data[0][0] = 2.0f/(right - left); res.data[0][3] = -(right + left)/(right - left); - res.data[1][1] = 2.0f/(top - bottom); res.data[1][3] = -(top + bottom)/(top - bottom); - res.data[2][2] = -2.0f/(far - near); res.data[2][3] = -(far + near)/(far - near); + Mat4 res = init_value4m(0); + + res.data[0][0] = 2.0f/(right - left); + res.data[1][1] = 2.0f/(top - bottom); + res.data[2][2] = 2.0f/(near - far); + res.data[3][0] = (right + left)/(left - right); + res.data[3][1] = (top + bottom)/(bottom - top); + res.data[3][2] = (far + near)/(near - far); res.data[3][3] = 1.0f; return res; } -Mat4RowMajor lookat4m(Vec3 up, Vec3 forward, Vec3 right, Vec3 position) +Mat4 lookat4m(Vec3 up, Vec3 forward, Vec3 right, Vec3 position) { /* * @note: The construction of the lookat matrix is not obvious. For that reason here is the supplemental matrial I have used to understand @@ -549,14 +456,16 @@ Mat4RowMajor lookat4m(Vec3 up, Vec3 forward, Vec3 right, Vec3 position) * It is because, we are moving from the position matrix which is a global to the view matrix which * is a local. It won't be very clear from this illustration alone, so you would be best served watching the video and recollecting and understanding from there. * 2. This article (https://twodee.org/blog/17560) derives (or rather shows), in a very shallow way how we get to the look at matrix. - * - * I am guessing this is not useful for 2D stuff */ - Mat4RowMajor res = init_value4m(1.0); - res.xyzw[0] = Vec4{ right.x, right.y, right.z, -dot_multiply3v(right, position) }; - res.xyzw[1] = Vec4{ up.x, up.y, up.z, -dot_multiply3v(up, position) }; - res.xyzw[2] = Vec4{ forward.x, forward.y, forward.z, -dot_multiply3v(forward, position) }; - res.xyzw[3] = Vec4{ 0.0f, 0.0f, 0.0f, 1.0f }; + Mat4 res = init_value4m(1.0f); + res.row[0] = Vec4{ right.x, up.x, forward.x, 0.0f }; + res.row[1] = Vec4{ right.y, up.y, forward.y, 0.0f }; + res.row[2] = Vec4{ right.z, up.z, forward.z, 0.0f }; + + res.data[3][0] = -dot_multiply3v(right, position); + res.data[3][1] = -dot_multiply3v(up, position); + res.data[3][2] = -dot_multiply3v(forward, position); + res.data[3][3] = 1.0f; return res; } @@ -572,7 +481,7 @@ Vec3 camera_look_around(r32 angle_pitch, r32 angle_yaw) return camera_look; } -Mat4RowMajor camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up) +Mat4 camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up) { // @note: We do this because this allows the camera to have the axis it looks at // inwards be the +z axis. @@ -582,7 +491,52 @@ Mat4RowMajor camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up) Vec3 camera_right_dir = normalize3v(cross_multiply3v(camera_up, camera_forward_dir)); Vec3 camera_up_dir = normalize3v(cross_multiply3v(camera_forward_dir, camera_right_dir)); - Mat4RowMajor res = lookat4m(camera_up_dir, camera_forward_dir, camera_right_dir, camera_pos); + Mat4 res = lookat4m(camera_up_dir, camera_forward_dir, camera_right_dir, camera_pos); + + return res; +} + +Mat4 calculate_mvp4m(Mat4 Model, Mat4 View, Mat4 Projection) +{ + Mat4 mv = multiply4m(View, Model); + Mat4 mvp = multiply4m(Projection, mv); + + return mvp; +} + +#if Disabled +Mat4RowMajor perspective_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far) +{ + Mat4RowMajor res = { 0 }; + + res.data[0][0] = (2.0 * near)/(right - left); + res.data[0][2] = (right + left)/(right - left); + + res.data[1][1] = (2.0 * near)/(top - bottom); + res.data[1][2] = (top + bottom)/(top - bottom); + + res.data[2][2] = -(far + near)/(far - near); + res.data[2][3] = -2.0*far*near/(far - near); + + res.data[3][2] = -1.0; + + return res; +} + +Mat4RowMajor perspective4m(r32 fov, r32 aspect_ratio, r32 near, r32 far) +{ + r32 cotangent = 1.0f / tanf(fov / 2.0f); + + Mat4RowMajor res = { 0 }; + + res.data[0][0] = cotangent / aspect_ratio; + + res.data[1][1] = cotangent; + + res.data[2][2] = -(far + near) / (far - near); + res.data[2][3] = -2.0f * far * near / (far - near); + + res.data[3][2] = -1.0f; return res; } |