Triangle rasterization
This commit is contained in:
parent
f66c1618d2
commit
b526157870
@ -6,6 +6,7 @@ set(CMAKE_C_FLAGS "-Wall -Wextra -Werror=implicit-function-declaration -Werror=r
|
||||
|
||||
add_compile_definitions(_POSIX_C_SOURCE=200112L)
|
||||
add_compile_definitions(_GNU_SOURCE)
|
||||
add_compile_options(-fno-trapping-math)
|
||||
|
||||
add_executable(main src/l1/main.c)
|
||||
|
||||
|
||||
@ -56,6 +56,7 @@ T MAX_##T (T a, T b){ return a < b ? b : a; }
|
||||
|
||||
int_minmax_function_Definition(U8)
|
||||
int_minmax_function_Definition(U32)
|
||||
int_minmax_function_Definition(S32)
|
||||
int_minmax_function_Definition(U64)
|
||||
int_minmax_function_Definition(float)
|
||||
int_minmax_function_Definition(double)
|
||||
|
||||
@ -168,6 +168,52 @@ NODISCARD VecU8 generate_xvecy_method_div_by_scal(ConstSpanU8 xvec, ConstSpanU8
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_mul_xvecy(ConstSpanU8 xvec, ConstSpanU8 member, int n) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr("_mul_"));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A."));
|
||||
string_append_vec_field_name(&res, i);
|
||||
VecU8_append_span(&res, cstr(" * B."));
|
||||
string_append_vec_field_name(&res, i);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_and_one(ConstSpanU8 xvec, int n) {
|
||||
assert(2 <= n && n < 4);
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, n + 1);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr("_and_one("));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return ("));
|
||||
string_append_xvecy(&res, xvec, n + 1);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int i = 0; i < n; i++) {
|
||||
VecU8_append_span(&res, cstr("A."));
|
||||
string_append_vec_field_name(&res, i);
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
}
|
||||
VecU8_append_span(&res, cstr("1 };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
void string_append_xmatnm(VecU8* str, ConstSpanU8 xmat, int cols, int rows) {
|
||||
VecU8_append_span(str, xmat);
|
||||
VecU8_append(str, '0' + cols);
|
||||
@ -512,16 +558,26 @@ VecU8 generate_xmatnm_method_transpose(ConstSpanU8 xmat, ConstSpanU8 xvec, Const
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvec234_structs_and_methods(ConstSpanU8 xvec, ConstSpanU8 member) {
|
||||
NODISCARD VecU8 generate_xvec234_structs_and_important_methods(ConstSpanU8 xvec, ConstSpanU8 member) {
|
||||
VecU8 res = VecU8_new();
|
||||
for (int cc = 2; cc <= 4; cc++) {
|
||||
VecU8_append_vec(&res, generate_xvecy_struct_definition(xvec, member, cc));
|
||||
VecU8_append_vec(&res, generate_xvecy_method_add_xvecy(xvec, member, cc));
|
||||
VecU8_append_vec(&res, generate_xvecy_method_minus_xvecy(xvec, member, cc));
|
||||
VecU8_append_vec(&res, generate_xvecy_method_minus(xvec, member, cc));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvec234_structs_and_methods(ConstSpanU8 xvec, ConstSpanU8 member) {
|
||||
VecU8 res = generate_xvec234_structs_and_important_methods(xvec, member);
|
||||
for (int cc = 2; cc <= 4; cc++) {
|
||||
VecU8_append_vec(&res, generate_xvecy_method_mul_scal(xvec, member, cc));
|
||||
VecU8_append_vec(&res, generate_xvecy_method_div_by_scal(xvec, member, cc));
|
||||
VecU8_append_vec(&res, generate_xvecy_method_mul_xvecy(xvec, member, cc));
|
||||
}
|
||||
for (int n = 2; n <= 3; n++)
|
||||
VecU8_append_vec(&res, generate_xvecy_method_and_one(xvec, n));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -564,8 +620,8 @@ NODISCARD VecU8 generate_xmat234x234_structs_and_methods(ConstSpanU8 xmat, Const
|
||||
void generate_geom_header() {
|
||||
VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_GEOM"));
|
||||
VecU8_append_span(&res, cstr("#include \"../src/l1/core/int_primitives.h\"\n\n"));
|
||||
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("cvec"), cstr("U8")));
|
||||
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("ivec"), cstr("S32")));
|
||||
VecU8_append_vec(&res, generate_xvec234_structs_and_important_methods(cstr("cvec"), cstr("U8")));
|
||||
VecU8_append_vec(&res, generate_xvec234_structs_and_important_methods(cstr("ivec"), cstr("S32")));
|
||||
|
||||
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("vec"), cstr("float")));
|
||||
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("dvec"), cstr("double")));
|
||||
@ -753,6 +809,14 @@ VecU8 generate_texture_data_struct_and_necc_methods(ConstSpanU8 texdatat, ConstS
|
||||
SPACE8 "fprintf(stderr, \"Tried loading bitmap texture from file, but encountered decoding error: \");\n"
|
||||
SPACE8 "ConstSpanU8_fprint(res.err, stderr);\n"
|
||||
SPACE8 "abortf(\"\\n\");\n" SPACE4 "}\n" SPACE4 "VecU8_drop(data);\n" SPACE4 "return res.ok;\n}\n\n"));
|
||||
/* Method _is_inside() */
|
||||
VecU8_append_span(&res, cstr("bool "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_is_inside(const "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("* self, S32 x, S32 y) {\n"
|
||||
SPACE4 "return x >= 0 && y >= 0 && x < self->width && self->width * y + x < self->pixels.len;\n"
|
||||
"}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef PROTOTYPE1_SRC_L2_MARGARET_STRINGOP_H
|
||||
#define PROTOTYPE1_SRC_L2_MARGARET_STRINGOP_H
|
||||
#ifndef PROTOTYPE1_SRC_L2_CORE_STRINGOP_H
|
||||
#define PROTOTYPE1_SRC_L2_CORE_STRINGOP_H
|
||||
|
||||
#include "../../l1/core/VecSpan_int_primitives.h"
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
#ifndef PROTOTYPE1_SRC_L2_MARGARET_GRAPHICS_GEOM_H
|
||||
#define PROTOTYPE1_SRC_L2_MARGARET_GRAPHICS_GEOM_H
|
||||
#ifndef PROTOTYPE1_SRC_L2_MARIE_GRAPHICS_GEOM_H
|
||||
#define PROTOTYPE1_SRC_L2_MARIE_GRAPHICS_GEOM_H
|
||||
|
||||
#include "../../../gen/geom.h"
|
||||
#include "math.h"
|
||||
|
||||
mat4 margaret_translation_mat4(vec3 vec) {
|
||||
mat4 marie_translation_mat4(vec3 vec) {
|
||||
return mat4_new(
|
||||
1, 0, 0, vec.x,
|
||||
0, 1, 0, vec.y,
|
||||
@ -13,7 +13,7 @@ mat4 margaret_translation_mat4(vec3 vec) {
|
||||
);
|
||||
}
|
||||
|
||||
mat3 margaret_3d_rot_mat3(vec3 r, float a) {
|
||||
mat3 marie_3d_rot_mat3(vec3 r, float a) {
|
||||
float cosa = cosf(a);
|
||||
float sina = sinf(a);
|
||||
return mat3_new(
|
||||
@ -23,7 +23,7 @@ mat3 margaret_3d_rot_mat3(vec3 r, float a) {
|
||||
);
|
||||
}
|
||||
|
||||
mat4 margaret_mat3_to_mat4(mat3 A) {
|
||||
mat4 marie_mat3_to_mat4(mat3 A) {
|
||||
return mat4_new(
|
||||
A.x.x, A.y.x, A.z.x, 0,
|
||||
A.x.y, A.y.y, A.z.y, 0,
|
||||
@ -31,7 +31,7 @@ mat4 margaret_mat3_to_mat4(mat3 A) {
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
mat4 margaret_mat3_to_mat4_transposed(mat3 A) {
|
||||
mat4 marie_mat3_to_mat4_transposed(mat3 A) {
|
||||
return mat4_new(
|
||||
A.x.x, A.x.y, A.x.z, 0,
|
||||
A.y.x, A.y.y, A.y.z, 0,
|
||||
@ -39,12 +39,12 @@ mat4 margaret_mat3_to_mat4_transposed(mat3 A) {
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
mat4 margaret_3d_rot_mat4(vec3 r, double a) {
|
||||
return margaret_mat3_to_mat4(margaret_3d_rot_mat3(r, a));
|
||||
mat4 marie_3d_rot_mat4(vec3 r, double a) {
|
||||
return marie_mat3_to_mat4(marie_3d_rot_mat3(r, a));
|
||||
}
|
||||
|
||||
|
||||
mat4 margaret_perspective_projection_mat4(float right, float top, float near, float far) {
|
||||
mat4 marie_perspective_projection_mat4(float right, float top, float near, float far) {
|
||||
return mat4_new(
|
||||
near/right, 0, 0, 0,
|
||||
0, -near/top, 0, 0,
|
||||
@ -52,15 +52,15 @@ mat4 margaret_perspective_projection_mat4(float right, float top, float near, fl
|
||||
0, 0, -1, 0 );
|
||||
}
|
||||
|
||||
mat4 margaret_perspective_projection_fov_mat4(float win_width, float win_height, float fov,
|
||||
mat4 marie_perspective_projection_fov_mat4(float win_width, float win_height, float fov,
|
||||
float spat_frustum_near, float spat_frustum_far) {
|
||||
float right = tanf(fov / 2) * spat_frustum_near;
|
||||
float top = win_height * right / win_width;
|
||||
return margaret_perspective_projection_mat4(right, top, spat_frustum_near, spat_frustum_far);
|
||||
return marie_perspective_projection_mat4(right, top, spat_frustum_near, spat_frustum_far);
|
||||
}
|
||||
|
||||
|
||||
mat3 margaret_simple_camera_rot_m_basis_in_cols(float yaw, float pitch, float roll) {
|
||||
mat3 marie_simple_camera_rot_m_basis_in_cols(float yaw, float pitch, float roll) {
|
||||
float cos_ya = cosf(yaw);
|
||||
float sin_ya = sinf(yaw);
|
||||
float cos_pi = cosf(pitch);
|
||||
181
src/l2/marie/rasterization.h
Normal file
181
src/l2/marie/rasterization.h
Normal file
@ -0,0 +1,181 @@
|
||||
#ifndef SPLITTER_DRAFT_SRC_L2_MARIE_RASTERIZATION_H
|
||||
#define SPLITTER_DRAFT_SRC_L2_MARIE_RASTERIZATION_H
|
||||
|
||||
#include "../../../gen/geom.h"
|
||||
#include "../../../gen/pixel_masses.h"
|
||||
#include "math.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
|
||||
/* float size check and IEEE‑754 binary32 characteristic checks */
|
||||
_Static_assert(sizeof(float) == 4,
|
||||
"This code assumes 32‑bit floats");
|
||||
#if defined(__STDC_IEC_559__) /* implementation claims IEC 60559 */
|
||||
_Static_assert(__STDC_IEC_559__, "Implementation is not IEC 60559");
|
||||
#else
|
||||
/* Fall back to value‑based checks: radix 2, 24‑bit mantissa, exponent ranges.
|
||||
These values are unique to binary32 among the formats in actual use. */
|
||||
_Static_assert(FLT_RADIX == 2, "Non‑binary radix");
|
||||
_Static_assert(FLT_MANT_DIG == 24, "Float is not binary32");
|
||||
_Static_assert(FLT_MAX_EXP == 128, "Float is not binary32");
|
||||
_Static_assert(FLT_MIN_EXP == -125, "Float is not binary32");
|
||||
#endif
|
||||
|
||||
// todo: move line rasterization here (from r0 test)
|
||||
|
||||
uint32_t marie_pun_float2u32(float f) {
|
||||
uint32_t u;
|
||||
memcpy(&u, &f, sizeof u);
|
||||
return u;
|
||||
}
|
||||
|
||||
bool marie_same_dir3(float A0, float A1, float A2, float B) {
|
||||
uint32_t bb = marie_pun_float2u32(B);
|
||||
uint32_t diff = (marie_pun_float2u32(A0) ^ bb) |
|
||||
(marie_pun_float2u32(A1) ^ bb) |
|
||||
(marie_pun_float2u32(A2) ^ bb);
|
||||
return A0 == 0 || A1 == 0 || A2 == 0 || (diff & 0x80000000u) == 0;
|
||||
}
|
||||
|
||||
typedef vec4 MarieVertAttr;
|
||||
|
||||
typedef struct {
|
||||
/* guest, x, y, attribute (custom) */
|
||||
void (*fn)(void*, S32, S32, MarieVertAttr);
|
||||
void* guest;
|
||||
} FnMarieRasterizerCallback;
|
||||
|
||||
typedef struct {
|
||||
vec2 pos;
|
||||
MarieVertAttr attr;
|
||||
} MariePlaneVertAttr;
|
||||
|
||||
float marie_surface(vec2 vi, vec2 vj, vec2 u) {
|
||||
return u.x * (vi.y - vj.y) + u.y * (vj.x - vi.x) + (vi.x * vj.y - vj.x * vi.y);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
float c1;
|
||||
float c0;
|
||||
} MarieLinearFun;
|
||||
|
||||
|
||||
/* f(y) = (y + 0.5 - a.y) / (b.y - a.y) * (b.x - a.x) + a.x - 0.5 */
|
||||
MarieLinearFun marie_gen_scanline_borderline(vec2 a, vec2 b) {
|
||||
return (MarieLinearFun){.c1 = (b.x - a.x) / (b.y - a.y),
|
||||
.c0 = (0.5 - a.y) * (b.x - a.x) / (b.y - a.y) + a.x - 0.5 };
|
||||
}
|
||||
|
||||
/* Utility function, that is used by rasterization function.
|
||||
* Don't use in your code*/
|
||||
void marie_rasterize_line_in_triangle_with_attr_sorted(
|
||||
vec2 v0pos, vec2 v1pos, vec2 v2pos, S32 L, S32 R, MarieVertAttr P0, MarieVertAttr P1, MarieVertAttr P2,
|
||||
float S, S32 my, FnMarieRasterizerCallback cb
|
||||
) {
|
||||
float E01 = marie_surface(v0pos, v1pos, (vec2){L + 0.5, my + 0.5});
|
||||
float E12 = marie_surface(v1pos, v2pos, (vec2){L + 0.5, my + 0.5});
|
||||
float E20 = marie_surface(v2pos, v0pos, (vec2){L + 0.5, my + 0.5});
|
||||
for (S32 x = L; x <= R; x++) {
|
||||
if (marie_same_dir3(E01, E12, E20, S)) {
|
||||
cb.fn(cb.guest, x, my, vec4_add_vec4(vec4_mul_scal(P0, E12),
|
||||
vec4_add_vec4(vec4_mul_scal(P1, E20), vec4_mul_scal(P2, E01))));
|
||||
}
|
||||
E01 += (v0pos.y - v1pos.y);
|
||||
E12 += (v1pos.y - v2pos.y);
|
||||
E20 += (v2pos.y - v0pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
/* Utility function, that is used by rasterization function.
|
||||
* Don't use in your code*/
|
||||
void marie_scan_rast_line_in_triangle_with_attr_sorted(
|
||||
vec2 v0pos, vec2 v1pos, vec2 v2pos, S32 below, S32 above, MarieVertAttr P0, MarieVertAttr P1, MarieVertAttr P2,
|
||||
MarieLinearFun left_border, MarieLinearFun right_border, FnMarieRasterizerCallback cb
|
||||
) {
|
||||
for (S32 my = below + 1; my < above; my++) {
|
||||
S32 left = (S32)ceilf(left_border.c1 * (float)my + left_border.c0);
|
||||
S32 right = (S32)floorf(right_border.c1 * (float)my + right_border.c0);
|
||||
MarieVertAttr Q0 = vec4_mul_scal(P0, marie_surface(v1pos, v2pos, (vec2){left + 0.5, (float)my + 0.5}));
|
||||
MarieVertAttr Q1 = vec4_mul_scal(P1, marie_surface(v2pos, v0pos, (vec2){left + 0.5, (float)my + 0.5}));
|
||||
MarieVertAttr Q2 = vec4_mul_scal(P2, marie_surface(v0pos, v1pos, (vec2){left + 0.5, (float)my + 0.5}));
|
||||
MarieVertAttr dq0 = vec4_mul_scal(P0, v1pos.y - v2pos.y);
|
||||
MarieVertAttr dq1 = vec4_mul_scal(P1, v2pos.y - v0pos.y);
|
||||
MarieVertAttr dq2 = vec4_mul_scal(P2, v0pos.y - v1pos.y);
|
||||
for (S32 x = left; x <= right; x++) {
|
||||
cb.fn(cb.guest, x, my, vec4_add_vec4(Q0, vec4_add_vec4(Q1, Q2)));
|
||||
Q0 = vec4_add_vec4(Q0, dq0);
|
||||
Q1 = vec4_add_vec4(Q1, dq1);
|
||||
Q2 = vec4_add_vec4(Q2, dq2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void marie_rasterize_triangle_with_attr_sorted(
|
||||
MariePlaneVertAttr v0, MariePlaneVertAttr v1, MariePlaneVertAttr v2, FnMarieRasterizerCallback cb
|
||||
) {
|
||||
float S = marie_surface(v0.pos, v1.pos, v2.pos);
|
||||
S32 sx0 = (S32)roundf(v0.pos.x - 0.5);
|
||||
S32 sy0 = (S32)roundf(v0.pos.y - 0.5);
|
||||
S32 sx1 = (S32)roundf(v1.pos.x - 0.5);
|
||||
S32 sy1 = (S32)roundf(v1.pos.y - 0.5);
|
||||
S32 sx2 = (S32)roundf(v2.pos.x - 0.5);
|
||||
S32 sy2 = (S32)roundf(v2.pos.y - 0.5);
|
||||
|
||||
S32 L = MIN_S32(sx0, MIN_S32(sx1, sx2));
|
||||
S32 R = MAX_S32(sx0, MAX_S32(sx1, sx2));
|
||||
|
||||
MarieVertAttr P0 = vec4_div_by_scal(v0.attr, S);
|
||||
MarieVertAttr P1 = vec4_div_by_scal(v1.attr, S);
|
||||
MarieVertAttr P2 = vec4_div_by_scal(v2.attr, S);
|
||||
|
||||
/* I compile with -fno-trapping-math, so I hope nothing bad would happen */
|
||||
MarieLinearFun line_01 = marie_gen_scanline_borderline(v0.pos, v1.pos);
|
||||
MarieLinearFun line_12 = marie_gen_scanline_borderline(v1.pos, v2.pos);
|
||||
MarieLinearFun line_20 = marie_gen_scanline_borderline(v2.pos, v0.pos);
|
||||
|
||||
marie_rasterize_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy0, cb);
|
||||
if (sy0 + 1 < sy1) {
|
||||
MarieLinearFun left_border = S > 0 ? line_20 : line_01;
|
||||
MarieLinearFun right_border = S > 0 ? line_01 : line_20;
|
||||
marie_scan_rast_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, sy0, sy1, P0, P1, P2, left_border, right_border, cb);
|
||||
}
|
||||
if (sy1 > sy0) {
|
||||
marie_rasterize_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy1, cb);
|
||||
}
|
||||
if (sy1 + 1 < sy2) {
|
||||
MarieLinearFun left_border = S > 0 ? line_20 : line_12;
|
||||
MarieLinearFun right_border = S > 0 ? line_12 : line_20;
|
||||
marie_scan_rast_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, sy1, sy2, P0, P1, P2, left_border, right_border, cb);
|
||||
}
|
||||
if (sy2 > sy1) {
|
||||
marie_rasterize_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy2, cb);
|
||||
}
|
||||
}
|
||||
void marie_rasterize_triangle_with_attr(
|
||||
MariePlaneVertAttr a, MariePlaneVertAttr b, MariePlaneVertAttr c, FnMarieRasterizerCallback cb
|
||||
) {
|
||||
if (a.pos.y < b.pos.y) {
|
||||
if (b.pos.y < c.pos.y) {
|
||||
marie_rasterize_triangle_with_attr_sorted(a, b, c, cb);
|
||||
} else {
|
||||
if (a.pos.y < c.pos.y) {
|
||||
marie_rasterize_triangle_with_attr_sorted(a, c, b, cb);
|
||||
} else {
|
||||
marie_rasterize_triangle_with_attr_sorted(c, a, b, cb);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (a.pos.y < c.pos.y) {
|
||||
marie_rasterize_triangle_with_attr_sorted(b, a, c, cb);
|
||||
} else {
|
||||
if (b.pos.y < c.pos.y) {
|
||||
marie_rasterize_triangle_with_attr_sorted(b, c, a, cb);
|
||||
} else {
|
||||
marie_rasterize_triangle_with_attr_sorted(c, b, a, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -808,10 +808,10 @@ int main() {
|
||||
Scene scene = Scene_new();
|
||||
VecUsedModelOnScene_append(&scene.models, (UsedModelOnScene){.model = {
|
||||
.vbo = device_vbo_1_buffer.buffer, .ebo = device_ebo_1_buffer.buffer, .indexes = cylinder_1.indexes.len
|
||||
}, .model_t = margaret_translation_mat4((vec3){1, -1, 5}) });
|
||||
}, .model_t = marie_translation_mat4((vec3){1, -1, 5}) });
|
||||
VecUsedModelOnScene_append(&scene.models, (UsedModelOnScene){.model = {
|
||||
.vbo = device_vbo_2_buffer.buffer, .ebo = device_ebo_2_buffer.buffer, .indexes = cylinder_2.indexes.len
|
||||
}, .model_t = margaret_translation_mat4((vec3){6, -3, 7}) });
|
||||
}, .model_t = marie_translation_mat4((vec3){6, -3, 7}) });
|
||||
|
||||
// Sampler is global for a lot of my future textures
|
||||
VkSampler my_texture_sampler = margaret_create_sampler(physical_device, device);
|
||||
@ -942,10 +942,10 @@ int main() {
|
||||
float ae = margaret_ns_time_sec_diff(start, frame_A0);
|
||||
scene.anim_time = ae;
|
||||
scene.color = (VkClearColorValue){{0.5f, fabsf(sinf(ae)), .3f, 1.0f}};
|
||||
mat4 projection_matrix = margaret_perspective_projection_fov_mat4((float)wep.width, (float)wep.height,
|
||||
mat4 projection_matrix = marie_perspective_projection_fov_mat4((float)wep.width, (float)wep.height,
|
||||
my_cam_control_info.fov, 0.01f, 1000);
|
||||
mat4 camera_rotation_matrix = margaret_mat3_to_mat4_transposed(my_cam_control_info.cam_basis);
|
||||
mat4 camera_translation_matrix = margaret_translation_mat4(vec3_minus(my_cam_control_info.pos));
|
||||
mat4 camera_rotation_matrix = marie_mat3_to_mat4_transposed(my_cam_control_info.cam_basis);
|
||||
mat4 camera_translation_matrix = marie_translation_mat4(vec3_minus(my_cam_control_info.pos));
|
||||
mat4 t_mat = mat4_mul_mat4(projection_matrix, mat4_mul_mat4(camera_rotation_matrix, camera_translation_matrix));
|
||||
|
||||
{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef SPLITTER_DRAFT_SRC_L2_TESTS_R0_ASSETS_H
|
||||
#define SPLITTER_DRAFT_SRC_L2_TESTS_R0_ASSETS_H
|
||||
|
||||
#include "../margaret/graphics_geom.h"
|
||||
#include "../marie/graphics_geom.h"
|
||||
#include "../../l1/core/util.h"
|
||||
#include "../../l1/core/VecSpan_int_primitives.h"
|
||||
#include "../../l1/system/fileio.h"
|
||||
@ -77,14 +77,14 @@ VecT_trivmove_method_Definition(Pipeline0PointLight)
|
||||
VecT_primitive_zeroinit_method_Definition(Pipeline0PointLight)
|
||||
|
||||
const size_t pipeline_0_ubo_point_light_max_count = 20;
|
||||
const size_t pipeline_0_ubo_spotlight_max_count = 20;
|
||||
const size_t pipeline_0_ubo_spotlight_max_count = 120;
|
||||
|
||||
typedef struct {
|
||||
int spotlight_count;
|
||||
int point_light_count;
|
||||
char _padding_1[8];
|
||||
Pipeline0PointLight point_light_arr[20];
|
||||
Pipeline0Spotlight spotlight_arr[120];
|
||||
Pipeline0PointLight point_light_arr[pipeline_0_ubo_point_light_max_count];
|
||||
Pipeline0Spotlight spotlight_arr[pipeline_0_ubo_spotlight_max_count];
|
||||
} Pipeline0UBO;
|
||||
|
||||
size_t ModelTopology_get_space_needed_for_staging_buffer(const ModelTopology* self) {
|
||||
@ -183,25 +183,25 @@ void TextureDataR8_draw_inner_line_maxing(TextureDataR8* self,
|
||||
}
|
||||
}
|
||||
|
||||
void TextureDataR8_draw_spot_maxing(TextureDataR8* self, float x, float y, float r_cut, float r_decay) {
|
||||
S32 sx = (S32)roundf(x - .5f);
|
||||
S32 sy = (S32)roundf(y - .5f);
|
||||
void TextureDataR8_draw_spot_maxing(TextureDataR8* self, vec2 v, float r_cut, float r_decay) {
|
||||
S32 sx = (S32)roundf(v.x - .5f);
|
||||
S32 sy = (S32)roundf(v.y - .5f);
|
||||
S32 k = (S32)ceilf(r_cut);
|
||||
for (S32 i = sx-k; i <= sx+k; i++) {
|
||||
for (S32 j = sy-k; j <= sy+k; j++) {
|
||||
float dx = 0.5f + (float)i - x;
|
||||
float dy = 0.5f + (float)j - y;
|
||||
float dx = 0.5f + (float)i - v.x;
|
||||
float dy = 0.5f + (float)j - v.y;
|
||||
float dist = sqrtf(dx*dx + dy*dy);
|
||||
TextureDataR8_pixel_maxing(self, i, j, a_small_cute_gradient(r_cut, r_decay, dist));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TextureDataR8G8B8A8_draw_one_segment_maxing_alpha(TextureDataR8* self,
|
||||
float x1, float y1, float x2, float y2, float r_cut, float r_decay) {
|
||||
TextureDataR8_draw_spot_maxing(self, x1, y1, r_cut, r_decay);
|
||||
TextureDataR8_draw_spot_maxing(self, x2, y2, r_cut, r_decay);
|
||||
TextureDataR8_draw_inner_line_maxing(self, x1, y1, x2, y2, r_cut, r_decay);
|
||||
void TextureDataR8_draw_one_segment_maxing(TextureDataR8* self,
|
||||
vec2 v1, vec2 v2, float r_cut, float r_decay) {
|
||||
TextureDataR8_draw_spot_maxing(self, v1, r_cut, r_decay);
|
||||
TextureDataR8_draw_spot_maxing(self, v2, r_cut, r_decay);
|
||||
TextureDataR8_draw_inner_line_maxing(self, v1.x, v1.y, v2.x, v2.y, r_cut, r_decay);
|
||||
}
|
||||
|
||||
TextureDataR8G8B8A8 generate_wood_texture() {
|
||||
@ -287,6 +287,63 @@ ModelTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) {
|
||||
return (ModelTopology){.vertices = vertices, .indexes = indexes};
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
vec2 bl;
|
||||
vec2 tr;
|
||||
float height;
|
||||
float brd;
|
||||
} Wimbzle;
|
||||
|
||||
#define Wimbzle_drop(x) {}
|
||||
#define Wimbzle_clone(xp) (*(xp))
|
||||
|
||||
VecT_trivmove_struct_Definition(Wimbzle)
|
||||
VecT_trivmove_method_Definition(Wimbzle)
|
||||
VecT_primitive_zeroinit_method_Definition(Wimbzle)
|
||||
|
||||
typedef struct {
|
||||
vec2 center;
|
||||
vec2 rad;
|
||||
float hc;
|
||||
} Nibzle;
|
||||
|
||||
#define Nibzle_drop(x) {}
|
||||
#define Nibzle_clone(xp) (*(xp))
|
||||
|
||||
VecT_trivmove_struct_Definition(Nibzle)
|
||||
VecT_trivmove_method_Definition(Nibzle)
|
||||
VecT_primitive_zeroinit_method_Definition(Nibzle)
|
||||
|
||||
typedef struct {
|
||||
VecWimbzle wibmzles;
|
||||
VecNibzle nibzles;
|
||||
} Bublazhuzhka;
|
||||
|
||||
Bublazhuzhka Bublazhuzhka_new() {
|
||||
return (Bublazhuzhka){.wibmzles = VecWimbzle_new(), .nibzles = VecNibzle_new()};
|
||||
}
|
||||
|
||||
void Bublazhuzhka_drop(Bublazhuzhka self) {
|
||||
VecWimbzle_drop(self.wibmzles);
|
||||
VecNibzle_drop(self.nibzles);
|
||||
}
|
||||
|
||||
void Bublazhuzhka_TextureDataR8_draw_maxing(const Bublazhuzhka* self, TextureDataR8* canvas, vec2) {
|
||||
for (size_t i = 0; i < self->wibmzles.len; i++) {
|
||||
Wimbzle rect = *VecWimbzle_cat(&self->wibmzles, i);
|
||||
vec2 B = {rect.tr.x + rect.brd, rect.tr.y + rect.brd};
|
||||
vec2 C = {rect.bl.x - rect.brd, rect.bl.y - rect.brd};
|
||||
vec2 A = {C.x, B.y};
|
||||
vec2 D = {B.x, C.y};
|
||||
vec2 F = rect.tr;
|
||||
vec2 G = rect.bl;
|
||||
vec2 E = {G.x, F.y};
|
||||
vec2 H = {F.x, G.y};
|
||||
|
||||
TextureDataR8_draw_one_segment_maxing(canvas, A, B, 1.5, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#define vec2_drop(x) {}
|
||||
#define vec2_clone(x) (*(x))
|
||||
|
||||
@ -295,17 +352,17 @@ VecT_trivmove_method_Definition(vec2)
|
||||
VecT_primitive_zeroinit_method_Definition(vec2)
|
||||
|
||||
TextureDataR8 generate_tex_template_for_one_fourth_of_a_cylinder(float s_resol, float w, float r, U32 k) {
|
||||
assert(k >= 1);
|
||||
assert(k >= 1);
|
||||
const float a = M_PI_2f / (float)k;
|
||||
const float l = 2 * r * sin(M_PI_4f / (float)k);
|
||||
// We will multiply everything by s_resol at the end
|
||||
size_t width_pix = (size_t)ceilf(s_resol * (2 * r + w));
|
||||
size_t height_pix = (size_t)ceilf(s_resol * (2 * r + k * l));
|
||||
vec2 cord_resol = {(float)width_pix / (2 * r + w), (float)height_pix / (2 * r + k * l)};
|
||||
const vec2 v0tex = {r, r};
|
||||
const vec2 v1tex = {r + w, r};
|
||||
const vec2 v2tex = {r, 2 * r};
|
||||
const vec2 v3tex = {r + w, 2 * r};
|
||||
TextureDataR8 res = TextureDataR8_new((size_t)ceilf((float)s_resol * (2 * r + w)),
|
||||
(size_t)ceilf((float)s_resol * (2 * r + k * l)));
|
||||
TextureDataR8 res = TextureDataR8_new(width_pix, height_pix);
|
||||
Vecvec2 P = Vecvec2_new(); // todo: reserve 6 + k * 4
|
||||
Vecvec2_append(&P, v0tex);
|
||||
Vecvec2_append(&P, (vec2){r, 0}); // 4
|
||||
@ -330,15 +387,59 @@ TextureDataR8 generate_tex_template_for_one_fourth_of_a_cylinder(float s_resol,
|
||||
float r_cut = 2;
|
||||
float r_decay = 1;
|
||||
for (size_t i = 0; i < S; i++) {
|
||||
vec2 p = vec2_mul_scal(*Vecvec2_at(&P, i), s_resol);
|
||||
TextureDataR8_draw_spot_maxing(&res, p.x, p.y, r_cut, r_decay);
|
||||
vec2 p = vec2_mul_vec2(*Vecvec2_at(&P, i), cord_resol);
|
||||
TextureDataR8_draw_spot_maxing(&res, p, r_cut, r_decay);
|
||||
}
|
||||
for (size_t i = 0; i < S; i++) {
|
||||
vec2 pp = vec2_mul_scal(*Vecvec2_at(&P, i ? i - 1 : S - 1), s_resol);
|
||||
vec2 p = vec2_mul_scal(*Vecvec2_at(&P, i), s_resol);
|
||||
vec2 pp = vec2_mul_vec2(*Vecvec2_at(&P, i ? i - 1 : S - 1), cord_resol);
|
||||
vec2 p = vec2_mul_vec2(*Vecvec2_at(&P, i), cord_resol);
|
||||
TextureDataR8_draw_inner_line_maxing(&res, pp.x, pp.y, p.x, p.y, r_cut, r_decay);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
TextureDataR8G8B8 generate_normal_tex_for_one_fourth_of_a_cylinder(float s_resol, float w, float r, U32 k) {
|
||||
assert(k >= 1);
|
||||
const float a = M_PI_2f / (float)k;
|
||||
const float l = 2 * r * sin(M_PI_4f / (float)k);
|
||||
size_t width_pix = (size_t)ceilf(s_resol * (2 * r + w));
|
||||
size_t height_pix = (size_t)ceilf(s_resol * (2 * r + k * l));
|
||||
vec2 cord_resol = {(float)width_pix / (2 * r + w), (float)height_pix / (2 * r + k * l)};
|
||||
const vec2 v0tex = {r, r};
|
||||
const vec2 v1tex = {r + w, r};
|
||||
const vec2 v2tex = {r, 2 * r};
|
||||
const vec2 v3tex = {r + w, 2 * r};
|
||||
TextureDataR8G8B8 res = TextureDataR8G8B8_new(width_pix, height_pix);
|
||||
// Vecvec2 P = Vecvec2_new(); // todo: reserve 6 + k * 4
|
||||
// for (size_t i = k; i > 0; i--) {
|
||||
// Vecvec2_append(&P, (vec2){r + w + r * sinf(a * i), r + r * cos(a * i)});
|
||||
// }
|
||||
// Vecvec2_append(&P, v3tex);
|
||||
// for (size_t i = 1; i <= k; i++) {
|
||||
// Vecvec2_append(&P, (vec2){r + w, 2 * r + i * l});
|
||||
// }
|
||||
// for (size_t i = k; i > 0; i--) {
|
||||
// Vecvec2_append(&P, (vec2){r, 2 * r + i * l});
|
||||
// }
|
||||
// Vecvec2_append(&P, v2tex);
|
||||
// for (size_t i = 1; i <= k; i++) {
|
||||
// Vecvec2_append(&P, (vec2){r - r * sinf(a * i), r + r * cos(a * i)});
|
||||
// }
|
||||
// size_t S = 6 + 4 * k;
|
||||
// assert(P.len == S);
|
||||
// float r_cut = 2;
|
||||
// float r_decay = 1;
|
||||
// for (size_t i = 0; i < S; i++) {
|
||||
// vec2 p = vec2_mul_vec2(*Vecvec2_at(&P, i), cord_resol);
|
||||
// TextureDataR8_draw_spot_maxing(&res, p.x, p.y, r_cut, r_decay);
|
||||
// }
|
||||
// for (size_t i = 0; i < S; i++) {
|
||||
// vec2 pp = vec2_mul_vec2(*Vecvec2_at(&P, i ? i - 1 : S - 1), cord_resol);
|
||||
// vec2 p = vec2_mul_vec2(*Vecvec2_at(&P, i), cord_resol);
|
||||
// TextureDataR8_draw_inner_line_maxing(&res, pp.x, pp.y, p.x, p.y, r_cut, r_decay);
|
||||
// }
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -66,7 +66,7 @@ void CamControlInfo_up(CamControlInfo* self, float fl) {
|
||||
|
||||
CamControlInfo CamControlInfo_new() {
|
||||
return (CamControlInfo){
|
||||
.fov = 1.5, .cam_basis = margaret_simple_camera_rot_m_basis_in_cols(0, 0, 0), .pos = {0, 0, 0},
|
||||
.fov = 1.5, .cam_basis = marie_simple_camera_rot_m_basis_in_cols(0, 0, 0), .pos = {0, 0, 0},
|
||||
.speed = 2.7, .sensitivity = 0.5f * M_PIf / 180, .pitch_cap = M_PI * 0.49
|
||||
};
|
||||
}
|
||||
@ -81,7 +81,7 @@ void CamControlInfo_update_direction(CamControlInfo* self, int win_width, int wi
|
||||
(float)(win_height / 2 - pointer_y) * self->sensitivity,
|
||||
-self->pitch_cap, self->pitch_cap
|
||||
);
|
||||
self->cam_basis = margaret_simple_camera_rot_m_basis_in_cols(yaw, pitch, 0);
|
||||
self->cam_basis = marie_simple_camera_rot_m_basis_in_cols(yaw, pitch, 0);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
||||
@ -1,9 +1,34 @@
|
||||
#include "r0_assets.h"
|
||||
#include "../../l1/system/fileio.h"
|
||||
#include "../marie/rasterization.h"
|
||||
|
||||
void draw_cool_triangle_h_frag(void* ug, S32 x, S32 y, MarieVertAttr attr_col) {
|
||||
TextureDataR8G8B8* tex = (TextureDataR8G8B8*)ug;
|
||||
if (TextureDataR8G8B8_is_inside(tex, x, y)) {
|
||||
*TextureDataR8G8B8_at(tex, x, y) = (cvec3){255, (S32)roundf(attr_col.x * 255), (S32)roundf(attr_col.y * 255)};
|
||||
}
|
||||
}
|
||||
|
||||
void draw_cool_triangle(TextureDataR8G8B8* tex, vec2 A, vec2 B, vec2 C) {
|
||||
marie_rasterize_triangle_with_attr((MariePlaneVertAttr){.pos = A, .attr = {A.x / 1000, A.y / 1000, 0, 1}},
|
||||
(MariePlaneVertAttr){.pos = B, .attr = {B.x / 1000, B.y / 1000, 0, 1}},
|
||||
(MariePlaneVertAttr){.pos = C, .attr = {C.x / 1000, C.y / 1000, 0, 1}},
|
||||
(FnMarieRasterizerCallback){.fn = draw_cool_triangle_h_frag, .guest = (void*)tex});
|
||||
}
|
||||
|
||||
int main() {
|
||||
TextureDataR8 tex_1 = generate_tex_template_for_one_fourth_of_a_cylinder(20, 10, 2, 6);
|
||||
TextureDataR8_write_to_file(&tex_1, "log_10_2_6_TEMPLATE.r8");
|
||||
TextureDataR8_drop(tex_1);
|
||||
// TextureDataR8 tex_1 = generate_tex_template_for_one_fourth_of_a_cylinder(20, 10, 2, 6);
|
||||
// TextureDataR8_write_to_file(&tex_1, "log_10_2_6_TEMPLATE.r8");
|
||||
// TextureDataR8_drop(tex_1);
|
||||
TextureDataR8G8B8 t = TextureDataR8G8B8_new(1000, 1000);\
|
||||
vec2 center = {500, 500};
|
||||
for (int i = 0; i < 70; i++) {
|
||||
float a1 = (float)i * 2 * M_PIf / 70;
|
||||
float a2 = (float)(i + 1) * 2 * M_PIf / 70;
|
||||
vec2 A = vec2_add_vec2(center, vec2_mul_scal((vec2){cosf(a1), sinf(a1)}, 480));
|
||||
vec2 B = vec2_add_vec2(center, vec2_mul_scal((vec2){cosf(a2), sinf(a2)}, 480));
|
||||
draw_cool_triangle(&t, B, A, center);
|
||||
}
|
||||
TextureDataR8G8B8_write_to_file(&t, "experiment.r8g8b8");
|
||||
TextureDataR8G8B8_drop(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ from PIL import Image
|
||||
|
||||
RAW_FORMATS = {
|
||||
".r8g8b8a8": {"pix_size": 4, "mode": "RGBA"},
|
||||
".r8b8g8": {"pix_size": 3, "mode": "RGB"},
|
||||
".r8g8b8": {"pix_size": 3, "mode": "RGB"},
|
||||
".r8": {"pix_size": 1, "mode": "L"},
|
||||
}
|
||||
|
||||
|
||||
BIN
src/l2/tests/test_textures/experiment.r8g8b8
Normal file
BIN
src/l2/tests/test_textures/experiment.r8g8b8
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user