Implement shaders (#1)
Reviewed-on: #1 * Start implementing shaders and move vector code to dedicated files * Extract shader into its own header * Ensure pixel coordinates are within bounds * Refactor shader code and implement fragment shaders * Create shaders * Reorganise code Co-authored-by: Abdelrahman <said.abdelrahman89@gmail.com> Co-committed-by: Abdelrahman <said.abdelrahman89@gmail.com>
This commit was merged in pull request #1.
This commit is contained in:
57
src/vec/vec.c
Normal file
57
src/vec/vec.c
Normal file
@@ -0,0 +1,57 @@
|
||||
#include "vec.h"
|
||||
|
||||
#define DEPTH_MAX 255
|
||||
|
||||
M4x4f lookat(V3f eye, V3f target, V3f up) {
|
||||
V3f z = V3(V3f, f32, target.x, target.y, target.z, eye.x, eye.y, eye.z);
|
||||
normalise_v3(z);
|
||||
V3f x = cross_product(up, z);
|
||||
normalise_v3(x);
|
||||
V3f y = cross_product(z, x);
|
||||
normalise_v3(y);
|
||||
|
||||
M4x4f rotation = mat4x4_identity;
|
||||
rotation.row0.x = x.x;
|
||||
rotation.row0.y = x.y;
|
||||
rotation.row0.z = x.z;
|
||||
rotation.row1.x = y.x;
|
||||
rotation.row1.y = y.y;
|
||||
rotation.row1.z = y.z;
|
||||
rotation.row2.x = z.x;
|
||||
rotation.row2.y = z.y;
|
||||
rotation.row2.z = z.z;
|
||||
|
||||
M4x4f translation = mat4x4_identity;
|
||||
translation.row0.w = -(eye.x);
|
||||
translation.row1.w = -(eye.y);
|
||||
translation.row2.w = -(eye.z);
|
||||
|
||||
return mat4x4_mul(rotation, translation);
|
||||
}
|
||||
|
||||
M4x4f projection(f32 coeff) {
|
||||
// clang-format off
|
||||
return (M4x4f){
|
||||
.row0 = {1.0f, 0.0f, 0.0f, 0.0f},
|
||||
.row1 = {0.0f, 1.0f, 0.0f, 0.0f},
|
||||
.row2 = {0.0f, 0.0f, 1.0f, 0.0f},
|
||||
.row3 = {0.0f, 0.0f, coeff, 1.0f},
|
||||
};
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
M4x4f viewport(f32 x, f32 y, u64 w, u64 h) {
|
||||
M4x4f output = mat4x4_identity;
|
||||
|
||||
f32 half_width = (f32)w * 0.5f;
|
||||
f32 half_height = (f32)h * 0.5f;
|
||||
f32 half_depth = (f32)DEPTH_MAX * 0.5f;
|
||||
|
||||
output.row0.x = half_width;
|
||||
output.row0.w = x + half_width;
|
||||
output.row1.y = half_height;
|
||||
output.row1.w = y + half_height;
|
||||
output.row2.z = output.row2.w = half_depth;
|
||||
|
||||
return output;
|
||||
}
|
||||
163
src/vec/vec.h
Normal file
163
src/vec/vec.h
Normal file
@@ -0,0 +1,163 @@
|
||||
#ifndef VEC_H
|
||||
#define VEC_H
|
||||
|
||||
#include "aliases.h"
|
||||
#include "typed_list.h"
|
||||
#include <math.h>
|
||||
|
||||
typedef struct i64x2 V2i;
|
||||
struct i64x2 {
|
||||
i64 x;
|
||||
i64 y;
|
||||
};
|
||||
|
||||
typedef struct u64x2 V2u;
|
||||
struct u64x2 {
|
||||
u64 x;
|
||||
u64 y;
|
||||
};
|
||||
|
||||
typedef struct f32x2 V2f;
|
||||
struct f32x2 {
|
||||
union {
|
||||
f32 x;
|
||||
f32 u;
|
||||
};
|
||||
union {
|
||||
f32 y;
|
||||
f32 v;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct f32x3 V3f;
|
||||
struct f32x3 {
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
};
|
||||
|
||||
typedef struct f32x4 V4f;
|
||||
struct f32x4 {
|
||||
f32 x;
|
||||
f32 y;
|
||||
f32 z;
|
||||
f32 w;
|
||||
};
|
||||
|
||||
typedef struct u64x3 V3u;
|
||||
struct u64x3 {
|
||||
u64 x;
|
||||
u64 y;
|
||||
u64 z;
|
||||
};
|
||||
|
||||
typedef struct f32_3x3 M3x3f;
|
||||
struct f32_3x3 {
|
||||
V3f row0;
|
||||
V3f row1;
|
||||
V3f row2;
|
||||
};
|
||||
|
||||
typedef struct f32_4x4 M4x4f;
|
||||
struct f32_4x4 {
|
||||
V4f row0;
|
||||
V4f row1;
|
||||
V4f row2;
|
||||
V4f row3;
|
||||
};
|
||||
|
||||
MAKE_LIST_TYPE(V3f);
|
||||
MAKE_LIST_TYPE(V2f);
|
||||
|
||||
#define V2(T, ELEM_T, X0, Y0, X1, Y1) \
|
||||
((T){(ELEM_T)X1 - (ELEM_T)X0, (ELEM_T)Y1 - (ELEM_T)Y0})
|
||||
|
||||
#define V3(T, ELEM_T, X0, Y0, Z0, X1, Y1, Z1) \
|
||||
((T){(ELEM_T)X1 - (ELEM_T)X0, (ELEM_T)Y1 - (ELEM_T)Y0, \
|
||||
(ELEM_T)Z1 - (ELEM_T)Z0})
|
||||
|
||||
#define dot_v2(V1, V2) ((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y)
|
||||
|
||||
#define dot_v3(V1, V2) \
|
||||
((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y + (f32)V1.z * (f32)V2.z)
|
||||
|
||||
#define magnitude_v3(V) (sqrtf(dot_v3(V, V)))
|
||||
|
||||
#define normalise_v3(V) \
|
||||
do { \
|
||||
f32 magnitude = magnitude_v3(V); \
|
||||
V.x /= magnitude; \
|
||||
V.y /= magnitude; \
|
||||
V.z /= magnitude; \
|
||||
} while (0)
|
||||
|
||||
#define cross_product(V1, V2) \
|
||||
((V3f){ \
|
||||
.x = V1.y * V2.z - V1.z * V2.y, \
|
||||
.y = V1.z * V2.x - V1.x * V2.z, \
|
||||
.z = V1.x * V2.y - V1.y * V2.x, \
|
||||
})
|
||||
|
||||
#define mat4x4_identity \
|
||||
((M4x4f){ \
|
||||
.row0 = {1.0f, 0.0f, 0.0f, 0.0f}, \
|
||||
.row1 = {0.0f, 1.0f, 0.0f, 0.0f}, \
|
||||
.row2 = {0.0f, 0.0f, 1.0f, 0.0f}, \
|
||||
.row3 = {0.0f, 0.0f, 0.0f, 1.0f}, \
|
||||
})
|
||||
|
||||
#define mat4x4_mul(MAT1, MAT2) \
|
||||
((M4x4f){ \
|
||||
.row0.x = MAT1.row0.x * MAT2.row0.x + MAT1.row0.y * MAT2.row1.x + \
|
||||
MAT1.row0.z * MAT2.row2.x + MAT1.row0.w * MAT2.row3.x, \
|
||||
.row0.y = MAT1.row0.x * MAT2.row0.y + MAT1.row0.y * MAT2.row1.y + \
|
||||
MAT1.row0.z * MAT2.row2.y + MAT1.row0.w * MAT2.row3.y, \
|
||||
.row0.z = MAT1.row0.x * MAT2.row0.z + MAT1.row0.y * MAT2.row1.z + \
|
||||
MAT1.row0.z * MAT2.row2.z + MAT1.row0.w * MAT2.row3.z, \
|
||||
.row0.w = MAT1.row0.x * MAT2.row0.w + MAT1.row0.y * MAT2.row1.w + \
|
||||
MAT1.row0.z * MAT2.row2.w + MAT1.row0.w * MAT2.row3.w, \
|
||||
.row1.x = MAT1.row1.x * MAT2.row0.x + MAT1.row1.y * MAT2.row1.x + \
|
||||
MAT1.row1.z * MAT2.row2.x + MAT1.row1.w * MAT2.row3.x, \
|
||||
.row1.y = MAT1.row1.x * MAT2.row0.y + MAT1.row1.y * MAT2.row1.y + \
|
||||
MAT1.row1.z * MAT2.row2.y + MAT1.row1.w * MAT2.row3.y, \
|
||||
.row1.z = MAT1.row1.x * MAT2.row0.z + MAT1.row1.y * MAT2.row1.z + \
|
||||
MAT1.row1.z * MAT2.row2.z + MAT1.row1.w * MAT2.row3.z, \
|
||||
.row1.w = MAT1.row1.x * MAT2.row0.w + MAT1.row1.y * MAT2.row1.w + \
|
||||
MAT1.row1.z * MAT2.row2.w + MAT1.row1.w * MAT2.row3.w, \
|
||||
.row2.x = MAT1.row2.x * MAT2.row0.x + MAT1.row2.y * MAT2.row1.x + \
|
||||
MAT1.row2.z * MAT2.row2.x + MAT1.row2.w * MAT2.row3.x, \
|
||||
.row2.y = MAT1.row2.x * MAT2.row0.y + MAT1.row2.y * MAT2.row1.y + \
|
||||
MAT1.row2.z * MAT2.row2.y + MAT1.row2.w * MAT2.row3.y, \
|
||||
.row2.z = MAT1.row2.x * MAT2.row0.z + MAT1.row2.y * MAT2.row1.z + \
|
||||
MAT1.row2.z * MAT2.row2.z + MAT1.row2.w * MAT2.row3.z, \
|
||||
.row2.w = MAT1.row2.x * MAT2.row0.w + MAT1.row2.y * MAT2.row1.w + \
|
||||
MAT1.row2.z * MAT2.row2.w + MAT1.row2.w * MAT2.row3.w, \
|
||||
.row3.x = MAT1.row3.x * MAT2.row0.x + MAT1.row3.y * MAT2.row1.x + \
|
||||
MAT1.row3.z * MAT2.row2.x + MAT1.row3.w * MAT2.row3.x, \
|
||||
.row3.y = MAT1.row3.x * MAT2.row0.y + MAT1.row3.y * MAT2.row1.y + \
|
||||
MAT1.row3.z * MAT2.row2.y + MAT1.row3.w * MAT2.row3.y, \
|
||||
.row3.z = MAT1.row3.x * MAT2.row0.z + MAT1.row3.y * MAT2.row1.z + \
|
||||
MAT1.row3.z * MAT2.row2.z + MAT1.row3.w * MAT2.row3.z, \
|
||||
.row3.w = MAT1.row3.x * MAT2.row0.w + MAT1.row3.y * MAT2.row1.w + \
|
||||
MAT1.row3.z * MAT2.row2.w + MAT1.row3.w * MAT2.row3.w, \
|
||||
})
|
||||
|
||||
#define mat4x4_mul_vec4(MAT, V) \
|
||||
((V4f){ \
|
||||
.x = MAT.row0.x * V.x + MAT.row0.y * V.y + MAT.row0.z * V.z + \
|
||||
MAT.row0.w * V.w, \
|
||||
.y = MAT.row1.x * V.x + MAT.row1.y * V.y + MAT.row1.z * V.z + \
|
||||
MAT.row1.w * V.w, \
|
||||
.z = MAT.row2.x * V.x + MAT.row2.y * V.y + MAT.row2.z * V.z + \
|
||||
MAT.row2.w * V.w, \
|
||||
.w = MAT.row3.x * V.x + MAT.row3.y * V.y + MAT.row3.z * V.z + \
|
||||
MAT.row3.w * V.w, \
|
||||
})
|
||||
|
||||
#define project_vec4(V) ((V3f){.x = V.x / V.w, .y = V.y / V.w, .z = V.z / V.w})
|
||||
|
||||
M4x4f lookat(V3f eye, V3f target, V3f up);
|
||||
M4x4f projection(f32 coeff);
|
||||
M4x4f viewport(f32 x, f32 y, u64 w, u64 h);
|
||||
|
||||
#endif // VEC_H
|
||||
Reference in New Issue
Block a user