summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortalha <sarcxd@gmail.com>2024-10-31 00:24:52 +0500
committertalha <sarcxd@gmail.com>2024-10-31 00:24:52 +0500
commit949261f56f7c99a79e495b7d84bf8abc71f54f50 (patch)
tree43671ed6cac8468fbf6898abc655aeacbdfcfc75
parentcaa97b9fc4f25e0db64ff38fbd8c3c4d49ceef4a (diff)
Added ColumnMajor matrix multiplication.
Main code path is disabled until I get everything working correctly. Also added tags to gitignore
-rw-r--r--.gitignore1
-rwxr-xr-xsource/main.cpp60
-rwxr-xr-xsource/math.h99
3 files changed, 130 insertions, 30 deletions
diff --git a/.gitignore b/.gitignore
index 567609b..332b722 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
build/
+tags
diff --git a/source/main.cpp b/source/main.cpp
index 0e38806..2035da3 100755
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -27,12 +27,13 @@
* - Fixed framerate to prevent weird quirks with movement
* - Basic camera follower
* TODO:
+* - move from row-major to column major setup for math library
+* - Efficient Quad Renderer
* - Some way to make and define levels
* - Update camera follower for centering player in view (with limits) after
* a few seconds (maybe like 2 seconds)
* - Level completion Object
* - Implement Broad Phase Collision for efficient collision handling
-* - Efficient Quad Renderer
* - Audio
* - Level Creation
*/
@@ -333,10 +334,10 @@ void gl_draw_colored_quad(
// setting quad size
Mat4 model = init_value4m(1.0);
Mat4 scale = scaling_matrix4m(size.x, size.y, 0.0f);
- model = multiply4m(scale, model);
+ model = multiply4m_rm(scale, model);
// setting quad position
Mat4 translation = translation_matrix4m(position.x, position.y, position.z);
- model = multiply4m(translation, model);
+ model = multiply4m_rm(translation, model);
// setting color
glUniform3fv(glGetUniformLocation(renderer->cq_sp, "Color"), 1, color.data);
@@ -491,7 +492,7 @@ void gl_render_text(GLRenderer *renderer, char* text, Vec2 position, r32 size, V
Mat4 sm = scaling_matrix4m(w, h, 0);
Mat4 tm = translation_matrix4m(xpos, ypos, 0);
- Mat4 model = multiply4m(tm, sm);
+ Mat4 model = multiply4m_rm(tm, sm);
renderer->ui_text.transforms[running_index] = model;
renderer->ui_text.char_indexes[running_index] = int(*char_iter);
@@ -597,6 +598,55 @@ Vec3 get_screen_position_from_percent(GameState state, Vec3 v) {
int main(int argc, char* argv[])
{
+ // @matrix testing
+ Mat4ColumnMajor a = {0};
+ Mat4ColumnMajor b = {0};
+
+ a.data[0][0] = 4;
+ a.data[0][1] = 2;
+ a.data[0][2] = 0;
+ a.data[0][3] = 0;
+
+ a.data[1][0] = 0;
+ a.data[1][1] = 8;
+ a.data[1][2] = 1;
+ a.data[1][3] = 0;
+
+ a.data[2][0] = 0;
+ a.data[2][1] = 1;
+ a.data[2][2] = 0;
+ a.data[2][3] = 0;
+
+ a.data[3][0] = 0;
+ a.data[3][1] = 0;
+ a.data[3][2] = 0;
+ a.data[3][3] = 0;
+
+ b.data[0][0] = 4;
+ b.data[0][1] = 2;
+ b.data[0][2] = 1;
+ b.data[0][3] = 0;
+
+ b.data[1][0] = 2;
+ b.data[1][1] = 0;
+ b.data[1][2] = 4;
+ b.data[1][3] = 0;
+
+ b.data[2][0] = 9;
+ b.data[2][1] = 4;
+ b.data[2][2] = 2;
+ b.data[2][3] = 0;
+
+ b.data[3][0] = 0;
+ b.data[3][1] = 0;
+ b.data[3][2] = 0;
+ b.data[3][3] = 0;
+
+ Mat4 product = multiply4m_cm(a,b);
+
+ int dbg = 1;
+ return 0;
+#if DISABLE_MAIN_GAME
u32 scr_width = 1024;
u32 scr_height = 768;
@@ -1195,6 +1245,7 @@ int main(int argc, char* argv[])
Vec3{0.0f, 0.0f, 0.0f}); // color
sprintf(fmt_buffer, "%f pixels", pd_1.x);
+
gl_render_text(renderer,
fmt_buffer,
Vec2{500.0f, 200.0f}, // position
@@ -1218,4 +1269,5 @@ int main(int argc, char* argv[])
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
+#endif
}
diff --git a/source/math.h b/source/math.h
index 7deb0bc..d7bf215 100755
--- a/source/math.h
+++ b/source/math.h
@@ -108,12 +108,19 @@ union Vec4 {
r32 data[4];
};
+// @note: matrix and all matrix operations will be done in column major
+// @todo: be able to specify and configure this in the future
+// possibly through separate functions
union Mat4 {
Vec4 xyzw[4];
r32 data[4][4];
r32 buffer[16];
};
+typedef Mat4 Mat4RowMajor;
+typedef Mat4 Mat4ColumnMajor;
+
+
// ==== Vec2 ====
Vec2 v2(r32 v) {
return Vec2{v, v};
@@ -346,7 +353,7 @@ Mat4 subtract4m(Mat4 a, Mat4 b)
return res;
}
-Vec4 multiply4vm(Vec4 vec, Mat4 mat)
+Vec4 multiply4mv_rm(Mat4RowMajor mat, Vec4 vec)
{
/*
* @note: Incase I get confused about this in the future.
@@ -372,23 +379,62 @@ Vec4 multiply4vm(Vec4 vec, Mat4 mat)
return res;
}
-Mat4 multiply4m(Mat4 a, Mat4 b)
+Mat4RowMajor multiply4m_rm(Mat4RowMajor a, Mat4RowMajor b)
{
- Mat4 res = { 0 };
-
- res.xyzw[0] = multiply4vm(a.xyzw[0], b);
- res.xyzw[1] = multiply4vm(a.xyzw[1], b);
- res.xyzw[2] = multiply4vm(a.xyzw[2], b);
- res.xyzw[3] = multiply4vm(a.xyzw[3], b);
-
- return res;
+ 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;
+}
+
+Vec4 multiply4mv_cm(Mat4ColumnMajor m, Vec4 v)
+{
+ Vec4 res = {0};
+
+ res.x += m.data[0][0]*v.x;
+ res.y += m.data[0][1]*v.x;
+ res.z += m.data[0][2]*v.x;
+ res.w += m.data[0][3]*v.x;
+
+ res.x += m.data[1][0]*v.y;
+ res.y += m.data[1][1]*v.y;
+ res.z += m.data[1][2]*v.y;
+ res.w += m.data[1][3]*v.y;
+
+ res.x += m.data[2][0]*v.z;
+ res.y += m.data[2][1]*v.z;
+ res.z += m.data[2][2]*v.z;
+ res.w += m.data[2][3]*v.z;
+
+ res.x += m.data[3][0]*v.w;
+ res.y += m.data[3][1]*v.w;
+ res.z += m.data[3][2]*v.w;
+ res.w += m.data[3][3]*v.w;
+
+ return res;
}
+Mat4ColumnMajor multiply4m_cm(Mat4ColumnMajor a, Mat4ColumnMajor b)
+{
+ Mat4ColumnMajor res = { 0 };
+
+ res.xyzw[0] = multiply4mv_cm(b, a.xyzw[0]);
+ res.xyzw[1] = multiply4mv_cm(b, a.xyzw[1]);
+ res.xyzw[2] = multiply4mv_cm(b, a.xyzw[2]);
+ res.xyzw[3] = multiply4mv_cm(b, a.xyzw[3]);
+
+ return res;
+}
// ==== Matrix Transformation ====
-Mat4 scaling_matrix4m(r32 x, r32 y, r32 z) // generates a 4x4 scaling matrix for scaling each of the x,y,z axis
+Mat4RowMajor scaling_matrix4m(r32 x, r32 y, r32 z)
{
- Mat4 res = init_value4m(1.0f);
+ // generates a 4x4 scaling matrix for scaling each of the x,y,z axis
+ Mat4RowMajor res = init_value4m(1.0f);
res.data[0][0] = x;
res.data[1][1] = y;
res.data[2][2] = z;
@@ -396,9 +442,10 @@ Mat4 scaling_matrix4m(r32 x, r32 y, r32 z) // generates a 4x4 scaling matrix for
return res;
}
-Mat4 translation_matrix4m(r32 x, r32 y, r32 z) // generates a 4x4 translation matrix for translation along each of the x,y,z axis
+Mat4RowMajor translation_matrix4m(r32 x, r32 y, r32 z)
{
- Mat4 res = init_value4m(1.0f);
+ // 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;
@@ -406,9 +453,9 @@ Mat4 translation_matrix4m(r32 x, r32 y, r32 z) // generates a 4x4 translation ma
return res;
}
-Mat4 rotation_matrix4m(r32 angle_radians, Vec3 axis) // generates a 4x4 rotation matrix for rotation along each of the x,y,z axis
+Mat4RowMajor rotation_matrix4m(r32 angle_radians, Vec3 axis) // generates a 4x4 rotation matrix for rotation along each of the x,y,z axis
{
- Mat4 res = init_value4m(1.0f);
+ Mat4RowMajor res = init_value4m(1.0f);
axis = normalize3v(axis);
r32 cos_theta = cosf(angle_radians);
@@ -430,9 +477,9 @@ Mat4 rotation_matrix4m(r32 angle_radians, Vec3 axis) // generates a 4x4 rotation
return res;
}
-Mat4 perspective_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far)
+Mat4RowMajor perspective_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far)
{
- Mat4 res = { 0 };
+ Mat4RowMajor res = { 0 };
res.data[0][0] = (2.0 * near)/(right - left);
res.data[0][2] = (right + left)/(right - left);
@@ -448,11 +495,11 @@ Mat4 perspective_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 near
return res;
}
-Mat4 perspective4m(r32 fov, r32 aspect_ratio, r32 near, r32 far)
+Mat4RowMajor perspective4m(r32 fov, r32 aspect_ratio, r32 near, r32 far)
{
r32 cotangent = 1.0f / tanf(fov / 2.0f);
- Mat4 res = { 0 };
+ Mat4RowMajor res = { 0 };
res.data[0][0] = cotangent / aspect_ratio;
@@ -466,10 +513,10 @@ Mat4 perspective4m(r32 fov, r32 aspect_ratio, r32 near, r32 far)
return res;
}
-Mat4 orthographic_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far)
+Mat4RowMajor orthographic_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far)
{
// @todo: understand the derivation once I am done experimenting
- Mat4 res = { 0 };
+ 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);
@@ -478,7 +525,7 @@ Mat4 orthographic_projection4m(r32 left, r32 right, r32 bottom, r32 top, r32 nea
return res;
}
-Mat4 lookat4m(Vec3 up, Vec3 forward, Vec3 right, Vec3 position)
+Mat4RowMajor 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
@@ -490,7 +537,7 @@ Mat4 lookat4m(Vec3 up, Vec3 forward, Vec3 right, Vec3 position)
*
* I am guessing this is not useful for 2D stuff
*/
- Mat4 res = init_value4m(1.0);
+ 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) };
@@ -510,7 +557,7 @@ Vec3 camera_look_around(r32 angle_pitch, r32 angle_yaw)
return camera_look;
}
-Mat4 camera_create4m(Vec3 camera_pos, Vec3 camera_look, Vec3 camera_up)
+Mat4RowMajor 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.
@@ -520,7 +567,7 @@ Mat4 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));
- Mat4 res = lookat4m(camera_up_dir, camera_forward_dir, camera_right_dir, camera_pos);
+ Mat4RowMajor res = lookat4m(camera_up_dir, camera_forward_dir, camera_right_dir, camera_pos);
return res;
}