Added a function to generate texture templates. Drawn some stupid textures for my stupid cylinders
This commit is contained in:
parent
a666755c03
commit
f66c1618d2
8
.gitignore
vendored
8
.gitignore
vendored
@ -2,5 +2,9 @@
|
||||
cmake-build-debug/
|
||||
.idea/
|
||||
vgcore.*
|
||||
gen/
|
||||
*.pdf
|
||||
/gen/
|
||||
*.pdf
|
||||
*.r8g8b8a8
|
||||
*.r8b8g8
|
||||
*.r8
|
||||
*.xcf
|
||||
|
||||
@ -15,6 +15,9 @@ add_executable(1_test src/l1/tests/t1.c)
|
||||
add_executable(0_render_test src/l2/tests/r0.c)
|
||||
target_link_libraries(0_render_test -lvulkan -lX11 -lm)
|
||||
|
||||
add_executable(0_render_test_tex_init_prep src/l2/tests/r0_tex_init_prep.c)
|
||||
target_link_libraries(0_render_test_tex_init_prep -lm)
|
||||
|
||||
add_executable(0_play_test src/l3/tests/p0.c)
|
||||
target_link_libraries(0_play_test -lncurses)
|
||||
|
||||
|
||||
@ -21,9 +21,16 @@ ConstSpanU8 ConstSpanU8_from_cstr(const char* dc) {
|
||||
}
|
||||
#define cstr(dc) ConstSpanU8_from_cstr(dc)
|
||||
|
||||
/* Not thread safe (for stdout) !*/
|
||||
void ConstSpanU8_print(ConstSpanU8 str) {
|
||||
for (size_t i = 0; i < str.len; i++)
|
||||
putchar((int)*ConstSpanU8_at(str, i));
|
||||
putc((int)*ConstSpanU8_at(str, i), stdout);
|
||||
}
|
||||
|
||||
/* Not thread safe (for `stream`) ! */
|
||||
void ConstSpanU8_fprint( ConstSpanU8 str, FILE* stream) {
|
||||
for (size_t i = 0; i < str.len; i++)
|
||||
putc((int)*ConstSpanU8_at(str, i), stream);
|
||||
}
|
||||
|
||||
SpanT_VecT_trivmove_COMPLETE_Definition(U16)
|
||||
|
||||
@ -57,5 +57,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(U64)
|
||||
int_minmax_function_Definition(float)
|
||||
int_minmax_function_Definition(double)
|
||||
|
||||
#endif
|
||||
|
||||
772
src/l1/gen/geom_and_textures.h
Normal file
772
src/l1/gen/geom_and_textures.h
Normal file
@ -0,0 +1,772 @@
|
||||
#ifndef PROTOTYPE_SRC_L1_GEN_GEOM_AND_TEXTURES_H
|
||||
#define PROTOTYPE_SRC_L1_GEN_GEOM_AND_TEXTURES_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../system/fileio.h"
|
||||
#include "../core/VecU8_format.h"
|
||||
|
||||
NODISCARD VecU8 begin_header(ConstSpanU8 guard) {
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8_append_span(&res, cstr("#ifndef "));
|
||||
VecU8_append_span(&res, guard);
|
||||
VecU8_append_span(&res, cstr("\n#define "));
|
||||
VecU8_append_span(&res, guard);
|
||||
VecU8_append_span(&res, cstr("\n/* Automatically generated file. Do not edit it. */\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Codegen script's working directory should be `gen` */
|
||||
void finish_header(VecU8 text_before_endif, const char* filename) {
|
||||
VecU8_append_span(&text_before_endif, cstr("#endif\n"));
|
||||
write_whole_file_or_abort(filename, VecU8_to_ConstSpanU8(&text_before_endif));
|
||||
VecU8_drop(text_before_endif);
|
||||
}
|
||||
|
||||
#define SPACE4 " "
|
||||
#define SPACE8 " "
|
||||
#define SPACE12 " "
|
||||
|
||||
void string_append_vec_field_name(VecU8* str, int ci) {
|
||||
assert(0 <= ci && ci < 4);
|
||||
|
||||
VecU8_append(str, ci == 3 ? 'w' : 'x' + ci);
|
||||
}
|
||||
|
||||
void string_append_xvecy(VecU8* str, ConstSpanU8 xvec, int cc) {
|
||||
VecU8_append_span(str, xvec);
|
||||
VecU8_append(str, '0' + cc);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_struct_definition(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
assert(2 <= cc && cc <= 4);
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8_append_span(&res, cstr("typedef struct {\n"));
|
||||
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
VecU8_append_span(&res, cstr(SPACE4));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_vec_field_name(&res, ci);
|
||||
VecU8_append_span(&res, cstr(";\n"));
|
||||
}
|
||||
|
||||
VecU8_append_span(&res, cstr("} "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(";\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_add_xvecy(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_add_"));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
VecU8_append_span(&res, cstr(" + B."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_minus_xvecy(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_minus_"));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
VecU8_append_span(&res, cstr(" - B."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_minus(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_minus("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("-A."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_mul_scal(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_mul_scal("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
VecU8_append_span(&res, cstr(" * B"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_div_by_scal(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_div_by_scal("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(" B){\n" SPACE4 "return "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_mul_scal(A, 1/B);\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);
|
||||
if (rows != cols) {
|
||||
VecU8_append(str, 'x');
|
||||
VecU8_append(str, '0' + rows);
|
||||
}
|
||||
}
|
||||
|
||||
/* With columns padded to 16 bytes (for std140, std140 is our everything) */
|
||||
NODISCARD VecU8 generate_xmatnm_structure_definition(ConstSpanU8 xmat, ConstSpanU8 xvec, int cols, int rows, int sizeof_member) {
|
||||
int sv = (rows * sizeof_member) % 16;
|
||||
VecU8 res = VecU8_from_cstr("typedef struct {\n");
|
||||
for (int x = 0; x < cols; x++) {
|
||||
VecU8_append_span(&res, cstr(SPACE4));
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(";\n"));
|
||||
if (sv) {
|
||||
VecU8_append_vec(&res, VecU8_format(SPACE4 "char _padding_%d[%d];\n", x, 16 - sv));
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr("} "));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(";\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
void string_append_mat_col_definition(VecU8* str, int ci) {
|
||||
VecU8_append(str, '.');
|
||||
string_append_vec_field_name(str, ci);
|
||||
VecU8_append_span(str, cstr(" = "));
|
||||
}
|
||||
|
||||
void string_append_mat_el_access(VecU8* str, int x, int y) {
|
||||
VecU8_append(str, '.');
|
||||
string_append_vec_field_name(str, x);
|
||||
VecU8_append(str, '.');
|
||||
string_append_vec_field_name(str, y);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_new(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_new("));
|
||||
for (int y = 0; y < rows; y++) {
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x > 0 || y > 0)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_vec_field_name(&res, x);
|
||||
string_append_vec_field_name(&res, y);
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr(") {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
VecU8_append_span(&res, cstr("{ "));
|
||||
for (int y = 0; y < rows; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_vec_field_name(&res, x);
|
||||
string_append_vec_field_name(&res, y);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_square_xmatnn_E_definition(ConstSpanU8 xmat, int n) {
|
||||
VecU8 res = VecU8_from_cstr("const ");
|
||||
string_append_xmatnm(&res, xmat, n, n);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, n, n);
|
||||
VecU8_append_span(&res, cstr("_E = { "));
|
||||
for (int x = 0; x < n; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
VecU8_append_span(&res, cstr("{ "));
|
||||
for (int y = 0; y < n; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append(&res, '0' + (x == y));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_add_xmatnm(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_add_"));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("_add_"));
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("(A."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(", B."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(")"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_minus_xmatnm(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_minus_"));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("_minus_"));
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("(A."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(", B."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(")"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_minus(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_minus("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("_minus(A."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(")"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_mul_scal(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_mul_scal("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("_mul_scal(A."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(", B)"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_div_by_scal(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_div_by_scal("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return "));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_mul_scal(A, 1/B);\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecn_method_dot_xvecn(ConstSpanU8 xvec, ConstSpanU8 member, int n) {
|
||||
VecU8 res = VecU8_from_span(member);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr("_dot_"));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append(&res, '(');
|
||||
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 "));
|
||||
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_xmatnm_method_mul_xvecn(ConstSpanU8 xmat, ConstSpanU8 xvec, int n, int m) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, m);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr("_mul_"));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
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, m);
|
||||
VecU8_append_span(&res, cstr("){"));
|
||||
for (int ci = 0; ci < m; ci++) {
|
||||
if (ci)
|
||||
VecU8_append(&res, ',');
|
||||
VecU8_append_span(&res, cstr("\n" SPACE8));
|
||||
for (int x = 0; x < n; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(" + "));
|
||||
VecU8_append_span(&res, cstr("A"));
|
||||
string_append_mat_el_access(&res, x, ci);
|
||||
VecU8_append_span(&res, cstr(" * B."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_mul_xmatkn(ConstSpanU8 xmat, int n, int m, int k) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, k, m);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr("_mul_"));
|
||||
string_append_xmatnm(&res, xmat, k, n);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xmatnm(&res, xmat, k, n);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, k, m);
|
||||
VecU8_append_span(&res, cstr("){"));
|
||||
for (int x = 0; x < k; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(","));
|
||||
VecU8_append_span(&res, cstr("\n" SPACE8));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
VecU8_append_span(&res, cstr("{ "));
|
||||
for (int y = 0; y < m; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
for (int z = 0; z < n; z++) {
|
||||
if (z)
|
||||
VecU8_append_span(&res, cstr(" + "));
|
||||
VecU8_append_span(&res, cstr("A"));
|
||||
string_append_mat_el_access(&res, z, y);
|
||||
VecU8_append_span(&res, cstr(" * B"));
|
||||
string_append_mat_el_access(&res, x, z);
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
VecU8 generate_xmatnm_method_transpose(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int n, int m) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, m, n);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr("_transpose("));
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, m, n);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int bx = 0; bx < m; bx++) {
|
||||
if (bx)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, bx);
|
||||
VecU8_append_span(&res, cstr("{ "));
|
||||
for (int by = 0; by < n; by++) {
|
||||
if (by)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A"));
|
||||
string_append_mat_el_access(&res, by, bx);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvec234_structs_and_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));
|
||||
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));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmat234x234_structs_and_methods(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int sizeof_member) {
|
||||
VecU8 res = VecU8_new();
|
||||
for (int cols = 2; cols <= 4; cols++) {
|
||||
for (int rows = 2; rows <= 4; rows++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_structure_definition(xmat, xvec, cols, rows, sizeof_member));
|
||||
}
|
||||
}
|
||||
for (int cols = 2; cols <= 4; cols++) {
|
||||
for (int rows = 2; rows <= 4; rows++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_new(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_add_xmatnm(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_minus_xmatnm(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_minus(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_mul_scal(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_div_by_scal(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_transpose(xmat, xvec, member, cols, rows));
|
||||
}
|
||||
}
|
||||
for (int n = 2; n <= 4; n++) {
|
||||
VecU8_append_vec(&res, generate_square_xmatnn_E_definition(xmat, n));
|
||||
}
|
||||
for (int n = 2; n <= 4; n++) {
|
||||
for (int m = 2; m <= 4; m++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_mul_xvecn(xmat, xvec, n, m));
|
||||
}
|
||||
}
|
||||
for (int n = 2; n <= 4; n++) {
|
||||
for (int m = 2; m <= 4; m++) {
|
||||
for (int k = 2; k <= 4; k++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_mul_xmatkn(xmat, n, m, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
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_methods(cstr("vec"), cstr("float")));
|
||||
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("dvec"), cstr("double")));
|
||||
VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float)));
|
||||
VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double)));
|
||||
finish_header(res, "geom.h");
|
||||
}
|
||||
|
||||
VecU8 generate_type_triv_methods_and_vec(ConstSpanU8 member) {
|
||||
VecU8 res = VecU8_from_cstr("#define ");
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr("_drop(x) {}\n#define "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr("_clone(xp) (*(xp))\n\n"));
|
||||
VecU8_append_span(&res, cstr("VecT_trivmove_struct_Definition("));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(")\nVecT_trivmove_method_Definition("));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(")\nVecT_primitive_zeroinit_method_Definition("));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(")\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
/* code generation function. We don't append vector data to vecu8, we append vector name to string in VecU8 */
|
||||
void VecU8_append_vecoft(VecU8* str, ConstSpanU8 t) {
|
||||
VecU8_append_span(str, cstr("Vec"));
|
||||
VecU8_append_span(str, t);
|
||||
}
|
||||
|
||||
void VecU8_append_resoftexdatat(VecU8* str, ConstSpanU8 texdatat) {
|
||||
VecU8_append_span(str, cstr("Result"));
|
||||
VecU8_append_span(str, texdatat);
|
||||
VecU8_append_span(str, cstr("OrConstSpanU8"));
|
||||
}
|
||||
|
||||
/* Used to generate both _at() and _cat() methods */
|
||||
VecU8 generate_texture_data_method_at(ConstSpanU8 texdatat, ConstSpanU8 member, bool const_access) {
|
||||
VecU8 res = VecU8_from_span(member);
|
||||
VecU8_append_span(&res, cstr("* "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, const_access ? cstr("_cat") : cstr("_at"));
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("* self, size_t x, size_t y) {\n" SPACE4 "assert(x < self->width);\n"
|
||||
SPACE4 "return "));
|
||||
VecU8_append_vecoft(&res, member);
|
||||
VecU8_append_span(&res, const_access ? cstr("_cat") : cstr("_at"));
|
||||
VecU8_append_span(&res, cstr("(&self->pixels, x + y * self->width);\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
VecU8 generate_texture_data_struct_and_necc_methods(ConstSpanU8 texdatat, ConstSpanU8 member) {
|
||||
VecU8 res = VecU8_from_cstr("typedef struct {\n" SPACE4);
|
||||
VecU8_append_vecoft(&res, member);
|
||||
VecU8_append_span(&res, cstr(" pixels;\n" SPACE4 "size_t width;\n} "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr(";\n\n"));
|
||||
/* Method _new() */
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_new(U32 width, U32 height) {\n"
|
||||
SPACE4 "assert(!(SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10));\n"
|
||||
SPACE4 "return ("));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("){.pixels = "));
|
||||
VecU8_append_vecoft(&res, member);
|
||||
VecU8_append_span(&res, cstr("_new_zeroinit((size_t)width * height), .width = width};\n}\n\n"));
|
||||
/* Method _drop() */
|
||||
VecU8_append_span(&res, cstr("void "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_drop("));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr(" self) {\n" SPACE4));
|
||||
VecU8_append_vecoft(&res, member);
|
||||
VecU8_append_span(&res, cstr("_drop(self.pixels);\n}\n\n"));
|
||||
/* Method _get_height() */
|
||||
VecU8_append_span(&res, cstr("size_t "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_get_height(const "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("* self) {\n" SPACE4 "return self->pixels.len / self->width;\n}\n\n"));
|
||||
/* Methods _at and _cat */
|
||||
VecU8_append_vec(&res, generate_texture_data_method_at(texdatat, member, false));
|
||||
VecU8_append_span(&res, cstr("const "));
|
||||
VecU8_append_vec(&res, generate_texture_data_method_at(texdatat, member, true));
|
||||
/* Method _get_size_in_bytes */
|
||||
VecU8_append_span(&res, cstr("size_t "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_get_size_in_bytes(const "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("* self) {\n" SPACE4 "return self->pixels.len * sizeof("));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(");\n}\n\n"));
|
||||
/* Method _to_bitmap_text()
|
||||
* We use the assumption that bytes in type member are tightly packed */
|
||||
VecU8_append_span(&res, cstr("VecU8 "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_to_bitmap_text(const "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("* self) {\n"
|
||||
SPACE4 "assert(SIZE_MAX / self->pixels.len >= 100);\n"
|
||||
SPACE4 "size_t len = self->pixels.len * sizeof("));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(");\n"
|
||||
SPACE4 "VecU8 res = VecU8_new_zeroinit(8 + len);\n"
|
||||
SPACE4 "size_t width = self->width;\n"
|
||||
SPACE4 "size_t height = self->pixels.len / self->width;\n"
|
||||
SPACE4 "assert(UINT32_MAX / width >= 10 && UINT32_MAX / height >= 10);\n"
|
||||
SPACE4 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE4 SPACE4 "*VecU8_at(&res, 0 + i) = (width >> (8 * i)) & 0xff;\n"
|
||||
SPACE4 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE4 SPACE4 "*VecU8_at(&res, 4 + i) = (height >> (8 * i)) & 0xff;\n"
|
||||
SPACE4 "memcpy(res.buf + 8, self->pixels.buf, len);\n"
|
||||
SPACE4 "return res;\n"
|
||||
"}\n\n"));
|
||||
/* Method _write_to_file
|
||||
* Aborts on failure */
|
||||
VecU8_append_span(&res, cstr("void "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_write_to_file(const "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("* self, const char* path) {\n" SPACE4 "VecU8 data = "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_to_bitmap_text(self);\n"
|
||||
SPACE4 "write_whole_file_or_abort(path, VecU8_to_ConstSpanU8(&data));\n"
|
||||
SPACE4 "VecU8_drop(data);\n"
|
||||
"}\n\n"));
|
||||
/* Result<texdatat, ConstSpanU8> stucture */
|
||||
VecU8_append_span(&res, cstr("typedef struct {\n" SPACE4 "Result_variant variant;\n" SPACE4 "union {\n" SPACE8 ));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr(" ok;\n" SPACE4 SPACE4 "ConstSpanU8 err;\n" SPACE4 "};\n} "));
|
||||
VecU8_append_resoftexdatat(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr(";\n\n"));
|
||||
/* Method _from_bitmap_text()
|
||||
* We assume that bytes are tightly packed in member type
|
||||
*/
|
||||
VecU8_append_resoftexdatat(&res, texdatat);
|
||||
VecU8_append(&res, ' ');
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_from_bitmap_text(ConstSpanU8 text) {\n"
|
||||
SPACE4 "if (text.len < 8)\n"
|
||||
SPACE4 SPACE4 "return ("));
|
||||
VecU8_append_resoftexdatat(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("){.variant = Result_Err, "
|
||||
".err = cstr(\"No header *crying emoji*\")};\n"
|
||||
SPACE4 "size_t width = 0, height = 0;\n"
|
||||
SPACE4 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE4 SPACE4 "width |= (((size_t)*ConstSpanU8_at(text, 0 + i)) << (8 * i));\n"
|
||||
SPACE4 "for (int i = 0; i < 4; i++)\n"
|
||||
SPACE4 SPACE4 "height |= (((size_t)*ConstSpanU8_at(text, 4 + i)) << (8 * i));\n"
|
||||
SPACE4 "if (SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10)\n"
|
||||
SPACE4 SPACE4 "return ("));
|
||||
VecU8_append_resoftexdatat(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("){.variant = Result_Err, "
|
||||
".err = cstr(\"Image is too big\")};\n"
|
||||
SPACE4 "size_t len = width * height * sizeof("));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(");\n"
|
||||
SPACE4 "if (text.len < 8 + len)\n"
|
||||
SPACE4 SPACE4 "return ("));
|
||||
VecU8_append_resoftexdatat(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("){.variant = Result_Err, "
|
||||
".err = cstr(\"Texture size and file size mismatch\")};\n" SPACE4));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr(" res = "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_new(width, height);\n"
|
||||
SPACE4 "memcpy(res.pixels.buf, text.data + 8, len);\n"
|
||||
SPACE4 "return ("));
|
||||
VecU8_append_resoftexdatat(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("){.variant = Result_Ok, .ok = res};\n}\n\n"));
|
||||
/* Method _read_from_file */
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append(&res, ' ');
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_read_from_file(const char* path) {\n"
|
||||
SPACE4 "VecU8 data = read_whole_file_or_abort(path);\n" SPACE4));
|
||||
VecU8_append_resoftexdatat(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr(" res = "));
|
||||
VecU8_append_span(&res, texdatat);
|
||||
VecU8_append_span(&res, cstr("_from_bitmap_text(VecU8_to_ConstSpanU8(&data));\n"
|
||||
SPACE4 "if (res.variant != Result_Ok) {\n"
|
||||
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"));
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_pixel_masses_header() {
|
||||
VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_PIXEL_MASSES"));
|
||||
VecU8_append_span(&res, cstr("#include \"geom.h\"\n\n"));
|
||||
VecU8_append_span(&res, cstr("#include \"../src/l1/core/VecSpan_int_primitives.h\"\n\n"));
|
||||
VecU8_append_span(&res, cstr("#include \"../src/l1/system/fileio.h\"\n\n"));
|
||||
VecU8_append_vec(&res, generate_type_triv_methods_and_vec(cstr("cvec3")));
|
||||
VecU8_append_vec(&res, generate_type_triv_methods_and_vec(cstr("cvec4")));
|
||||
VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8"), cstr("U8")));
|
||||
VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8"), cstr("cvec3")));
|
||||
VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8A8"), cstr("cvec4")));
|
||||
finish_header(res, "pixel_masses.h");
|
||||
}
|
||||
|
||||
#endif
|
||||
573
src/l1/main.c
573
src/l1/main.c
@ -1,573 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "system/fileio.h"
|
||||
#include "core/VecU8_format.h"
|
||||
|
||||
NODISCARD VecU8 begin_header(ConstSpanU8 guard) {
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8_append_span(&res, cstr("#ifndef "));
|
||||
VecU8_append_span(&res, guard);
|
||||
VecU8_append_span(&res, cstr("\n#define "));
|
||||
VecU8_append_span(&res, guard);
|
||||
VecU8_append_span(&res, cstr("\n/* Automatically generated file. Do not edit it. */\n\n"
|
||||
"#include \"../src/l1/core/int_primitives.h\"\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
void finish_header(VecU8 text_before_endif) {
|
||||
VecU8_append_span(&text_before_endif, cstr("#endif\n"));
|
||||
write_whole_file_or_abort("geom.h", VecU8_to_ConstSpanU8(&text_before_endif));
|
||||
VecU8_drop(text_before_endif);
|
||||
}
|
||||
|
||||
#define SPACE4 " "
|
||||
|
||||
void string_append_vec_field_name(VecU8* str, int ci) {
|
||||
assert(0 <= ci && ci < 4);
|
||||
|
||||
VecU8_append(str, ci == 3 ? 'w' : 'x' + ci);
|
||||
}
|
||||
|
||||
void string_append_xvecy(VecU8* str, ConstSpanU8 xvec, int cc) {
|
||||
VecU8_append_span(str, xvec);
|
||||
VecU8_append(str, '0' + cc);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_struct_definition(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
assert(2 <= cc && cc <= 4);
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8_append_span(&res, cstr("typedef struct {\n"));
|
||||
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
VecU8_append_span(&res, cstr(SPACE4));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_vec_field_name(&res, ci);
|
||||
VecU8_append_span(&res, cstr(";\n"));
|
||||
}
|
||||
|
||||
VecU8_append_span(&res, cstr("} "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(";\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_add_xvecy(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_add_"));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
VecU8_append_span(&res, cstr(" + B."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_minus_xvecy(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_minus_"));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
VecU8_append_span(&res, cstr(" - B."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_minus(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_minus("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("-A."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_mul_scal(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_mul_scal("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int ci = 0; ci < cc; ci++) {
|
||||
if (ci)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A."));
|
||||
string_append_vec_field_name(&res, ci);
|
||||
VecU8_append_span(&res, cstr(" * B"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecy_method_div_by_scal(ConstSpanU8 xvec, ConstSpanU8 member, int cc) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_div_by_scal("));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(" B){\n" SPACE4 "return "));
|
||||
string_append_xvecy(&res, xvec, cc);
|
||||
VecU8_append_span(&res, cstr("_mul_scal(A, 1/B);\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);
|
||||
if (rows != cols) {
|
||||
VecU8_append(str, 'x');
|
||||
VecU8_append(str, '0' + rows);
|
||||
}
|
||||
}
|
||||
|
||||
/* With columns padded to 16 bytes (for std140, std140 is our everything) */
|
||||
NODISCARD VecU8 generate_xmatnm_structure_definition(ConstSpanU8 xmat, ConstSpanU8 xvec, int cols, int rows, int sizeof_member) {
|
||||
int sv = (rows * sizeof_member) % 16;
|
||||
VecU8 res = VecU8_from_cstr("typedef struct {\n");
|
||||
for (int x = 0; x < cols; x++) {
|
||||
VecU8_append_span(&res, cstr(SPACE4));
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr(" "));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(";\n"));
|
||||
if (sv) {
|
||||
VecU8_append_vec(&res, VecU8_format(SPACE4 "char _padding_%d[%d];\n", x, 16 - sv));
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr("} "));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(";\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
void string_append_mat_col_definition(VecU8* str, int ci) {
|
||||
VecU8_append(str, '.');
|
||||
string_append_vec_field_name(str, ci);
|
||||
VecU8_append_span(str, cstr(" = "));
|
||||
}
|
||||
|
||||
void string_append_mat_el_access(VecU8* str, int x, int y) {
|
||||
VecU8_append(str, '.');
|
||||
string_append_vec_field_name(str, x);
|
||||
VecU8_append(str, '.');
|
||||
string_append_vec_field_name(str, y);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_new(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_new("));
|
||||
for (int y = 0; y < rows; y++) {
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x > 0 || y > 0)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_vec_field_name(&res, x);
|
||||
string_append_vec_field_name(&res, y);
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr(") {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
VecU8_append_span(&res, cstr("{ "));
|
||||
for (int y = 0; y < rows; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_vec_field_name(&res, x);
|
||||
string_append_vec_field_name(&res, y);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_square_xmatnn_E_definition(ConstSpanU8 xmat, int n) {
|
||||
VecU8 res = VecU8_from_cstr("const ");
|
||||
string_append_xmatnm(&res, xmat, n, n);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, n, n);
|
||||
VecU8_append_span(&res, cstr("_E = { "));
|
||||
for (int x = 0; x < n; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
VecU8_append_span(&res, cstr("{ "));
|
||||
for (int y = 0; y < n; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append(&res, '0' + (x == y));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_add_xmatnm(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_add_"));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("_add_"));
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("(A."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(", B."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(")"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_minus_xmatnm(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_minus_"));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("_minus_"));
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("(A."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(", B."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(")"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_minus(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_minus("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("_minus(A."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(")"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_mul_scal(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_mul_scal("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int x = 0; x < cols; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
string_append_xvecy(&res, xvec, rows);
|
||||
VecU8_append_span(&res, cstr("_mul_scal(A."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
VecU8_append_span(&res, cstr(", B)"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_div_by_scal(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int cols, int rows) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_div_by_scal("));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
VecU8_append_span(&res, member);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return "));
|
||||
string_append_xmatnm(&res, xmat, cols, rows);
|
||||
VecU8_append_span(&res, cstr("_mul_scal(A, 1/B);\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvecn_method_dot_xvecn(ConstSpanU8 xvec, ConstSpanU8 member, int n) {
|
||||
VecU8 res = VecU8_from_span(member);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr("_dot_"));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append(&res, '(');
|
||||
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 "));
|
||||
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_xmatnm_method_mul_xvecn(ConstSpanU8 xmat, ConstSpanU8 xvec, int n, int m) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xvecy(&res, xvec, m);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr("_mul_"));
|
||||
string_append_xvecy(&res, xvec, n);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
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, m);
|
||||
VecU8_append_span(&res, cstr("){"));
|
||||
for (int ci = 0; ci < m; ci++) {
|
||||
if (ci)
|
||||
VecU8_append(&res, ',');
|
||||
VecU8_append_span(&res, cstr("\n" SPACE4 SPACE4));
|
||||
for (int x = 0; x < n; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(" + "));
|
||||
VecU8_append_span(&res, cstr("A"));
|
||||
string_append_mat_el_access(&res, x, ci);
|
||||
VecU8_append_span(&res, cstr(" * B."));
|
||||
string_append_vec_field_name(&res, x);
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmatnm_method_mul_xmatkn(ConstSpanU8 xmat, int n, int m, int k) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, k, m);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr("_mul_"));
|
||||
string_append_xmatnm(&res, xmat, k, n);
|
||||
VecU8_append_span(&res, cstr("("));
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr(" A, "));
|
||||
string_append_xmatnm(&res, xmat, k, n);
|
||||
VecU8_append_span(&res, cstr(" B) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, k, m);
|
||||
VecU8_append_span(&res, cstr("){"));
|
||||
for (int x = 0; x < k; x++) {
|
||||
if (x)
|
||||
VecU8_append_span(&res, cstr(","));
|
||||
VecU8_append_span(&res, cstr("\n" SPACE4 SPACE4));
|
||||
string_append_mat_col_definition(&res, x);
|
||||
VecU8_append_span(&res, cstr("{ "));
|
||||
for (int y = 0; y < m; y++) {
|
||||
if (y)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
for (int z = 0; z < n; z++) {
|
||||
if (z)
|
||||
VecU8_append_span(&res, cstr(" + "));
|
||||
VecU8_append_span(&res, cstr("A"));
|
||||
string_append_mat_el_access(&res, z, y);
|
||||
VecU8_append_span(&res, cstr(" * B"));
|
||||
string_append_mat_el_access(&res, x, z);
|
||||
}
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
VecU8 generate_xmatnm_method_transpose(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int n, int m) {
|
||||
VecU8 res = VecU8_new();
|
||||
string_append_xmatnm(&res, xmat, m, n);
|
||||
VecU8_append(&res, ' ');
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr("_transpose("));
|
||||
string_append_xmatnm(&res, xmat, n, m);
|
||||
VecU8_append_span(&res, cstr(" A) {\n" SPACE4 "return ("));
|
||||
string_append_xmatnm(&res, xmat, m, n);
|
||||
VecU8_append_span(&res, cstr("){ "));
|
||||
for (int bx = 0; bx < m; bx++) {
|
||||
if (bx)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
string_append_mat_col_definition(&res, bx);
|
||||
VecU8_append_span(&res, cstr("{ "));
|
||||
for (int by = 0; by < n; by++) {
|
||||
if (by)
|
||||
VecU8_append_span(&res, cstr(", "));
|
||||
VecU8_append_span(&res, cstr("A"));
|
||||
string_append_mat_el_access(&res, by, bx);
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" }"));
|
||||
}
|
||||
VecU8_append_span(&res, cstr(" };\n}\n\n"));
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xvec234_structs_and_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));
|
||||
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));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_xmat234x234_structs_and_methods(ConstSpanU8 xmat, ConstSpanU8 xvec, ConstSpanU8 member, int sizeof_member) {
|
||||
VecU8 res = VecU8_new();
|
||||
for (int cols = 2; cols <= 4; cols++) {
|
||||
for (int rows = 2; rows <= 4; rows++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_structure_definition(xmat, xvec, cols, rows, sizeof_member));
|
||||
}
|
||||
}
|
||||
for (int cols = 2; cols <= 4; cols++) {
|
||||
for (int rows = 2; rows <= 4; rows++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_new(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_add_xmatnm(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_minus_xmatnm(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_minus(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_mul_scal(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_div_by_scal(xmat, xvec, member, cols, rows));
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_transpose(xmat, xvec, member, cols, rows));
|
||||
}
|
||||
}
|
||||
for (int n = 2; n <= 4; n++) {
|
||||
VecU8_append_vec(&res, generate_square_xmatnn_E_definition(xmat, n));
|
||||
}
|
||||
for (int n = 2; n <= 4; n++) {
|
||||
for (int m = 2; m <= 4; m++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_mul_xvecn(xmat, xvec, n, m));
|
||||
}
|
||||
}
|
||||
for (int n = 2; n <= 4; n++) {
|
||||
for (int m = 2; m <= 4; m++) {
|
||||
for (int k = 2; k <= 4; k++) {
|
||||
VecU8_append_vec(&res, generate_xmatnm_method_mul_xmatkn(xmat, n, m, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_geometry_header() {
|
||||
VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_GEOM"));
|
||||
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_methods(cstr("vec"), cstr("float")));
|
||||
VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("dvec"), cstr("double")));
|
||||
VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float)));
|
||||
VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double)));
|
||||
finish_header(res);
|
||||
}
|
||||
#include "gen/geom_and_textures.h"
|
||||
|
||||
int main() {
|
||||
generate_geometry_header();
|
||||
generate_geom_header();
|
||||
generate_pixel_masses_header();
|
||||
}
|
||||
@ -3,8 +3,6 @@
|
||||
|
||||
#include "../../l1/core/VecSpan_int_primitives.h"
|
||||
|
||||
// todo: move this out of margaret (may still keep it in l2)
|
||||
|
||||
U8 U8_to_lowercase(U8 ch) {
|
||||
if ('A' <= ch && ch <= 'Z')
|
||||
return ch - 'A' + 'a';
|
||||
@ -74,5 +74,4 @@ mat3 margaret_simple_camera_rot_m_basis_in_cols(float yaw, float pitch, float ro
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -8,11 +8,12 @@
|
||||
#include <X11/Xutil.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <vulkan/vulkan_xlib.h>
|
||||
#include "stringop.h"
|
||||
#include "../core/stringop.h"
|
||||
// #include <stdio.h>
|
||||
#include <time.h>
|
||||
// #include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include "../../l1/system/fileio.h"
|
||||
|
||||
typedef struct timespec margaret_ns_time;
|
||||
|
||||
@ -478,6 +479,59 @@ ResultMargaretChosenSwapchainDetailsOrConstSpanU8 margaret_choose_swapchain_deta
|
||||
};
|
||||
}
|
||||
|
||||
SpanT_struct_Definition(VkFormat)
|
||||
SpanT_method_Definition(VkFormat)
|
||||
|
||||
OptionT_struct_Definition(VkFormat)
|
||||
OptionT_method_Definition(VkFormat)
|
||||
|
||||
OptionVkFormat margaret_find_supported_format_for_linear_tiling(
|
||||
VkPhysicalDevice physical_device, ConstSpanVkFormat candidates, VkFormatFeatureFlags required_features
|
||||
) {
|
||||
for (size_t i = 0; i < candidates.len; i++) {
|
||||
VkFormat format = *ConstSpanVkFormat_at(candidates, i);
|
||||
VkFormatProperties properties;
|
||||
vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties);
|
||||
if ((properties.linearTilingFeatures & required_features) == required_features)
|
||||
return Some_VkFormat(format);
|
||||
}
|
||||
return None_VkFormat();
|
||||
}
|
||||
|
||||
OptionVkFormat margaret_find_supported_format_for_optimal_tiling(
|
||||
VkPhysicalDevice physical_device, ConstSpanVkFormat candidates, VkFormatFeatureFlags required_features
|
||||
) {
|
||||
for (size_t i = 0; i < candidates.len; i++) {
|
||||
VkFormat format = *ConstSpanVkFormat_at(candidates, i);
|
||||
VkFormatProperties properties;
|
||||
vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties);
|
||||
if ((properties.optimalTilingFeatures & required_features) == required_features)
|
||||
return Some_VkFormat(format);
|
||||
}
|
||||
return None_VkFormat();
|
||||
}
|
||||
|
||||
OptionVkFormat margaret_find_supported_zbuffer_format(VkPhysicalDevice physical_device) {
|
||||
VkFormat candidates[3] = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };
|
||||
return margaret_find_supported_format_for_optimal_tiling(physical_device,
|
||||
(ConstSpanVkFormat){.data = candidates, .len = ARRAY_SIZE(candidates)}, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
OptionVkFormat margaret_find_supported_hdr_buffer_format(VkPhysicalDevice physical_device) {
|
||||
// todo: use format without alpha component (even though they are probably not supported)
|
||||
VkFormat candidates[] = { /*VK_FORMAT_R16G16B16_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,*/
|
||||
VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_R32G32B32A32_SFLOAT };
|
||||
return margaret_find_supported_format_for_optimal_tiling(physical_device,
|
||||
(ConstSpanVkFormat){.data = candidates, .len = ARRAY_SIZE(candidates)},
|
||||
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT );
|
||||
}
|
||||
|
||||
bool margaret_is_format_supported_for_textures(VkPhysicalDevice physical_device, VkFormat format) {
|
||||
VkFormatProperties props;
|
||||
vkGetPhysicalDeviceFormatProperties(physical_device, format, &props);
|
||||
return props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
VkPhysicalDevice physical_device;
|
||||
S64 score;
|
||||
@ -532,6 +586,14 @@ MargaretScoredPhysicalDevice margaret_score_physical_device(
|
||||
if (swapchain_details.variant == Result_Err) {
|
||||
return (MargaretScoredPhysicalDevice){dev, -1, cstr("Physical device lacks nice swapchain support")};
|
||||
}
|
||||
if (!margaret_is_format_supported_for_textures(dev, VK_FORMAT_R8_UNORM))
|
||||
return (MargaretScoredPhysicalDevice){dev, -1, cstr("R8_UNORM format can't be used for optimal tiling of textures")};
|
||||
if (!margaret_is_format_supported_for_textures(dev, VK_FORMAT_R8G8B8A8_SRGB))
|
||||
return (MargaretScoredPhysicalDevice){dev, -1, cstr("R8G8B8A8_SRGB format can't be used for optimal tiling of textures")};
|
||||
if (!margaret_is_format_supported_for_textures(dev, VK_FORMAT_R8G8B8A8_UNORM))
|
||||
return (MargaretScoredPhysicalDevice){dev, -1, cstr("R8G8B8A8_UNORM format can't be used for optimal tiling of textures")};
|
||||
if (!margaret_is_format_supported_for_textures(dev, VK_FORMAT_R16G16B16A16_SFLOAT))
|
||||
return (MargaretScoredPhysicalDevice){dev, -1, cstr("VK_FORMAT_R16G16B16A16_SFLOAT format can't be used for optimal tiling of textures")};
|
||||
return (MargaretScoredPhysicalDevice){dev, score, ""};
|
||||
}
|
||||
|
||||
@ -1271,44 +1333,6 @@ VkSampler margaret_create_sampler(VkPhysicalDevice physical_device, VkDevice dev
|
||||
return sampler;
|
||||
}
|
||||
|
||||
SpanT_struct_Definition(VkFormat)
|
||||
SpanT_method_Definition(VkFormat)
|
||||
|
||||
OptionT_struct_Definition(VkFormat)
|
||||
OptionT_method_Definition(VkFormat)
|
||||
|
||||
OptionVkFormat margaret_find_supported_format_for_linear_tiling(
|
||||
VkPhysicalDevice physical_device, ConstSpanVkFormat candidates, VkFormatFeatureFlags required_features
|
||||
) {
|
||||
for (size_t i = 0; i < candidates.len; i++) {
|
||||
VkFormat format = *ConstSpanVkFormat_at(candidates, i);
|
||||
VkFormatProperties properties;
|
||||
vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties);
|
||||
if ((properties.linearTilingFeatures & required_features) == required_features)
|
||||
return Some_VkFormat(format);
|
||||
}
|
||||
return None_VkFormat();
|
||||
}
|
||||
|
||||
OptionVkFormat margaret_find_supported_format_for_optimal_tiling(
|
||||
VkPhysicalDevice physical_device, ConstSpanVkFormat candidates, VkFormatFeatureFlags required_features
|
||||
) {
|
||||
for (size_t i = 0; i < candidates.len; i++) {
|
||||
VkFormat format = *ConstSpanVkFormat_at(candidates, i);
|
||||
VkFormatProperties properties;
|
||||
vkGetPhysicalDeviceFormatProperties(physical_device, format, &properties);
|
||||
if ((properties.optimalTilingFeatures & required_features) == required_features)
|
||||
return Some_VkFormat(format);
|
||||
}
|
||||
return None_VkFormat();
|
||||
}
|
||||
|
||||
OptionVkFormat margaret_find_supported_zbuffer_format(VkPhysicalDevice physical_device) {
|
||||
VkFormat candidates[3] = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };
|
||||
return margaret_find_supported_format_for_optimal_tiling(physical_device,
|
||||
(ConstSpanVkFormat){.data = candidates, .len = ARRAY_SIZE(candidates)}, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
#define VkDescriptorPoolSize_drop(v) {}
|
||||
#define VkDescriptorPoolSize_clone(p) (*(p))
|
||||
|
||||
|
||||
@ -3,9 +3,8 @@
|
||||
#include <math.h>
|
||||
#include "../../l1/system/fileio.h"
|
||||
#include <time.h>
|
||||
#include "r0_assets.h"
|
||||
// Only for linux
|
||||
#include <sys/wait.h>
|
||||
#include "r0_scene.h"
|
||||
#include <sys/wait.h> // Only for linux
|
||||
|
||||
// todo: generate this class in l2
|
||||
typedef struct {
|
||||
@ -22,39 +21,57 @@ void destroy_graphics_pipeline_hands(VkDevice device, PipelineHands hands) {
|
||||
}
|
||||
|
||||
// todo: generate this function in l2
|
||||
VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat image_format) {
|
||||
// Color attachments array for our render pass
|
||||
VkAttachmentDescription all_attachments[1] = { (VkAttachmentDescription){
|
||||
.format = image_format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
|
||||
} };
|
||||
VkRenderPass create_render_pass_0(VkDevice logical_device, VkFormat colorbuffer_format, VkFormat zbuffer_format) {
|
||||
VkAttachmentDescription all_attachments[2] = {
|
||||
{
|
||||
.format = colorbuffer_format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
},
|
||||
{
|
||||
.format = zbuffer_format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
}
|
||||
};
|
||||
|
||||
// For our one single render subpass
|
||||
VkAttachmentReference color_attachment_refs[1] = { (VkAttachmentReference){
|
||||
.attachment = 0,
|
||||
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
VkAttachmentReference color_attachments_refs[1] = {
|
||||
{
|
||||
.attachment = 0,
|
||||
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
|
||||
} };
|
||||
|
||||
VkAttachmentReference depth_attachment_ref = {
|
||||
.attachment = 1,
|
||||
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
|
||||
};
|
||||
|
||||
VkSubpassDescription subpasses_descr[1] = { (VkSubpassDescription){
|
||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
.colorAttachmentCount = ARRAY_SIZE(color_attachment_refs),
|
||||
.pColorAttachments = color_attachment_refs,
|
||||
.colorAttachmentCount = ARRAY_SIZE(color_attachments_refs),
|
||||
.pColorAttachments = color_attachments_refs,
|
||||
.pDepthStencilAttachment = &depth_attachment_ref,
|
||||
} };
|
||||
|
||||
VkSubpassDependency subpass_dependencies[1] = {
|
||||
// subpass_0_external
|
||||
(VkSubpassDependency) {
|
||||
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcAccessMask = 0,
|
||||
.dstSubpass = 0,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
}};
|
||||
|
||||
@ -136,8 +153,8 @@ PipelineHands create_graphics_pipeline_0(
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||
.depthClampEnable = VK_FALSE,
|
||||
.polygonMode = VK_POLYGON_MODE_FILL,
|
||||
// .cullMode = VK_CULL_MODE_BACK_BIT,
|
||||
.cullMode = VK_CULL_MODE_NONE,
|
||||
.cullMode = VK_CULL_MODE_BACK_BIT,
|
||||
// .cullMode = VK_CULL_MODE_NONE,
|
||||
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||
.depthBiasEnable = VK_FALSE,
|
||||
.depthBiasConstantFactor = 0.0f,
|
||||
@ -156,6 +173,13 @@ PipelineHands create_graphics_pipeline_0(
|
||||
.alphaToOneEnable = VK_FALSE,
|
||||
};
|
||||
|
||||
VkPipelineDepthStencilStateCreateInfo depth_stencil_state_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||
.depthTestEnable = VK_TRUE,
|
||||
.depthWriteEnable = VK_TRUE,
|
||||
.depthCompareOp = VK_COMPARE_OP_LESS
|
||||
};
|
||||
|
||||
// For one framebuffer
|
||||
VkPipelineColorBlendAttachmentState color_blend_attachments[1] = {(VkPipelineColorBlendAttachmentState){
|
||||
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
|
||||
@ -186,7 +210,7 @@ PipelineHands create_graphics_pipeline_0(
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
// our shader variable is not an array of descriptors, so this stays 1
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
|
||||
},
|
||||
{
|
||||
.binding = 1,
|
||||
@ -204,12 +228,18 @@ PipelineHands create_graphics_pipeline_0(
|
||||
if (vkCreateDescriptorSetLayout(device, &descriptor_set_layout_crinfo, NULL, &my_descriptor_set_layout) != VK_SUCCESS)
|
||||
abortf("vkCreateDescriptorSetLayout");
|
||||
|
||||
VkPushConstantRange pc_ranges[] = {
|
||||
{
|
||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||
.offset = 0, .size = sizeof(mat4)
|
||||
}};
|
||||
|
||||
VkPipelineLayoutCreateInfo layout_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = 1,
|
||||
.pSetLayouts = &my_descriptor_set_layout,
|
||||
.pushConstantRangeCount = 0,
|
||||
.pPushConstantRanges = NULL,
|
||||
.pushConstantRangeCount = ARRAY_SIZE(pc_ranges),
|
||||
.pPushConstantRanges = pc_ranges,
|
||||
};
|
||||
VkPipelineLayout pipeline_layout;
|
||||
if (vkCreatePipelineLayout(device, &layout_crinfo, NULL, &pipeline_layout) != VK_SUCCESS)
|
||||
@ -223,7 +253,7 @@ PipelineHands create_graphics_pipeline_0(
|
||||
.pViewportState = &viewport_state,
|
||||
.pRasterizationState = &rasterizer_crinfo,
|
||||
.pMultisampleState = &multisampling_crinfo,
|
||||
.pDepthStencilState = NULL,
|
||||
.pDepthStencilState = &depth_stencil_state_crinfo,
|
||||
.pColorBlendState = &color_blending_crinfo,
|
||||
.pDynamicState = &dynamic_state_crinfo,
|
||||
.layout = pipeline_layout,
|
||||
@ -442,15 +472,16 @@ PipelineHands create_graphics_pipeline_1(
|
||||
}
|
||||
|
||||
|
||||
VkFramebuffer create_IT1_framebuffer(VkDevice device, VkImageView IT1_view, VkRenderPass render_pass_0, VkExtent2D MAX_WIN_SIZE) {
|
||||
VkImageView attachments[1] = {IT1_view};
|
||||
VkFramebuffer create_IT1_framebuffer(VkDevice device, VkImageView IT1_view, VkImageView zbuffer_view, VkRenderPass render_pass_0,
|
||||
U32 MAX_WIN_WIDTH, U32 MAX_WIN_HEIGHT) {
|
||||
VkImageView attachments[2] = {IT1_view, zbuffer_view};
|
||||
VkFramebufferCreateInfo framebuffer_crinfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.renderPass = render_pass_0,
|
||||
.attachmentCount = ARRAY_SIZE(attachments),
|
||||
.pAttachments = attachments,
|
||||
.width = MAX_WIN_SIZE.width,
|
||||
.height = MAX_WIN_SIZE.height,
|
||||
.width = MAX_WIN_WIDTH,
|
||||
.height = MAX_WIN_HEIGHT,
|
||||
.layers = 1
|
||||
};
|
||||
VkFramebuffer framebuffer;
|
||||
@ -463,7 +494,7 @@ void reset_and_record_command_buffer_0(
|
||||
VkCommandBuffer command_buffer, VkRenderPass render_pass_0,
|
||||
const PipelineHands* pipeline_and_layout,
|
||||
VkFramebuffer swapchain_image_framebuffer, VkExtent2D image_extent,
|
||||
const Scene* scene, VkDescriptorSet my_descriptor_set
|
||||
const Scene* scene, VkDescriptorSet my_descriptor_set, mat4 t_mat
|
||||
) {
|
||||
if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS)
|
||||
abortf("vkResetCommandBuffer");
|
||||
@ -471,15 +502,15 @@ void reset_and_record_command_buffer_0(
|
||||
if (vkBeginCommandBuffer(command_buffer, &info_begin) != VK_SUCCESS)
|
||||
abortf("vkBeginCommandBuffer");
|
||||
|
||||
VkClearValue clear_color[1] = {{.color = scene->color}};
|
||||
VkClearValue clear_values[2] = {{.color = scene->color}, {.depthStencil = {.depth = 1, .stencil = 0}}};
|
||||
VkRenderPassBeginInfo renderpass_begin = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.renderPass = render_pass_0,
|
||||
.framebuffer = swapchain_image_framebuffer,
|
||||
.renderArea.offset = (VkOffset2D){0, 0},
|
||||
.renderArea.extent = image_extent,
|
||||
.clearValueCount = ARRAY_SIZE(clear_color),
|
||||
.pClearValues = clear_color,
|
||||
.clearValueCount = ARRAY_SIZE(clear_values),
|
||||
.pClearValues = clear_values,
|
||||
};
|
||||
|
||||
vkCmdBeginRenderPass(command_buffer, &renderpass_begin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
@ -502,16 +533,19 @@ void reset_and_record_command_buffer_0(
|
||||
};
|
||||
vkCmdSetScissor(command_buffer, 0, 1, &scissor);
|
||||
for (size_t i = 0; i < scene->models.len; i++) {
|
||||
const ModelOnScene* models = VecModelOnScene_cat(&scene->models, i);
|
||||
VkBuffer attached_buffers[1] = { models->vbo };
|
||||
const UsedModelOnScene* model = VecUsedModelOnScene_cat(&scene->models, i);
|
||||
VkBuffer attached_buffers[1] = { model->model.vbo };
|
||||
// We use our whole buffer, no need for offset
|
||||
VkDeviceSize offsets_in_buffers[1] = {0};
|
||||
vkCmdBindVertexBuffers(command_buffer, 0, 1, attached_buffers, offsets_in_buffers);
|
||||
vkCmdBindIndexBuffer(command_buffer, models->ebo, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindIndexBuffer(command_buffer, model->model.ebo, 0, VK_INDEX_TYPE_UINT32);
|
||||
mat4 tt = mat4_mul_mat4(t_mat, model->model_t);
|
||||
vkCmdPushConstants(command_buffer, pipeline_and_layout->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT,
|
||||
0, sizeof(mat4), &tt);
|
||||
vkCmdBindDescriptorSets(
|
||||
command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_and_layout->pipeline_layout, 0,
|
||||
1, &my_descriptor_set, 0, NULL);
|
||||
vkCmdDrawIndexed(command_buffer, models->indexes, 1, 0, 0, 0);
|
||||
vkCmdDrawIndexed(command_buffer, model->model.indexes, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
vkCmdEndRenderPass(command_buffer);
|
||||
@ -661,9 +695,15 @@ int main() {
|
||||
MargaretChosenSwapchainDetails swapchain_details = swapchain_details_res.ok;
|
||||
|
||||
// We hope that the image format won't be changed even when window gets resized
|
||||
// VkSurfaceFormatKHR image_format = choose_surface_format_i_want(swap_chain_support).value();
|
||||
// (swapchain_details.surface_format.format)
|
||||
OptionVkFormat zbuffer_format = margaret_find_supported_zbuffer_format(physical_device);
|
||||
if (zbuffer_format.variant != Option_Some)
|
||||
abortf("Could not find supported zbuffer format\n");
|
||||
OptionVkFormat IT1_format = margaret_find_supported_hdr_buffer_format(physical_device);
|
||||
if (IT1_format.variant != Option_Some)
|
||||
abortf("Could not find supported hdr buffer format\n");
|
||||
|
||||
VkRenderPass render_pass_0 = create_render_pass_0(device, swapchain_details.surface_format.format);
|
||||
VkRenderPass render_pass_0 = create_render_pass_0(device, IT1_format.some, zbuffer_format.some);
|
||||
PipelineHands pipeline_hands_0 = create_graphics_pipeline_0(device, render_pass_0, 0);
|
||||
|
||||
VkRenderPass render_pass_1 = create_render_pass_1(device, swapchain_details.surface_format.format);
|
||||
@ -674,14 +714,15 @@ int main() {
|
||||
// Filling scene info
|
||||
ModelTopology cylinder_1 = generate_one_fourth_of_a_cylinder(10, 2, 6);
|
||||
ModelTopology cylinder_2 = generate_one_fourth_of_a_cylinder(5, 5, 10);
|
||||
TextureDataR8G8B8A8 wood_texture_data = generate_wood_texture();
|
||||
// TextureDataR8G8B8A8 wood_texture_data = generate_texture_for_one_fourth_of_a_cylinder(20, 10, 2, 6);
|
||||
TextureDataR8G8B8A8 wood_texture_data = TextureDataR8G8B8A8_read_from_file("test_textures/log_10_2_6.r8g8b8a8");
|
||||
|
||||
// We have only one staging buffer in host memory (because we don't really need more)
|
||||
MargaretBufferInMemoryInfo host_mem_buffer = (MargaretBufferInMemoryInfo){ .sz =
|
||||
MAX_U64(ModelTopology_get_space_needed_for_staging_buffer(&cylinder_1),
|
||||
MAX_U64(ModelTopology_get_space_needed_for_staging_buffer(&cylinder_2),
|
||||
MAX_U64(sizeof(Pipeline0UBO),
|
||||
MAX_U64(TextureDataR8G8B8A8_get_space_needed_for_staging_buffer(&wood_texture_data), 0))))
|
||||
MAX_U64(TextureDataR8G8B8A8_get_size_in_bytes(&wood_texture_data), 0))))
|
||||
, .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT };
|
||||
VkDeviceMemory host_mem = margaret_initialize_buffers_and_images(physical_device, device,
|
||||
(SpanMargaretBufferInMemoryInfo){.data = &host_mem_buffer, .len = 1}, (SpanMargaretImageInMemoryInfo){ 0 },
|
||||
@ -697,7 +738,8 @@ int main() {
|
||||
MargaretImageInMemoryInfo device_mem_images[] = {
|
||||
margaret_prep_image_mem_info_of_gpu_texture_rgba(wood_texture_data.width,
|
||||
TextureDataR8G8B8A8_get_height(&wood_texture_data)),
|
||||
margaret_prep_image_mem_info_of_colorbuffer(MAX_WIN_WIDTH, MAX_WIN_HEIGHT, swapchain_details.surface_format.format),
|
||||
margaret_prep_image_mem_info_of_colorbuffer(MAX_WIN_WIDTH, MAX_WIN_HEIGHT, IT1_format.some),
|
||||
margaret_prep_image_mem_info_of_zbuffer(MAX_WIN_WIDTH, MAX_WIN_HEIGHT, zbuffer_format.some),
|
||||
};
|
||||
VkDeviceMemory device_mem = margaret_initialize_buffers_and_images(physical_device, device,
|
||||
(SpanMargaretBufferInMemoryInfo){ .data = device_mem_buffers, .len = ARRAY_SIZE(device_mem_buffers)},
|
||||
@ -710,6 +752,7 @@ int main() {
|
||||
MargaretBufferInMemoryInfo device_ubo_my_buffer = device_mem_buffers[4];
|
||||
MargaretImageInMemoryInfo device_wood_texture = device_mem_images[0];
|
||||
MargaretImageInMemoryInfo device_IT1_image = device_mem_images[1];
|
||||
MargaretImageInMemoryInfo device_zbuffer_image = device_mem_images[2];
|
||||
|
||||
VkCommandPool command_pool = margaret_create_resettable_command_pool(device, queue_fam.for_graphics);
|
||||
VkCommandBuffer rendering_command_buffer_0 = margaret_allocate_command_buffer(device, command_pool);
|
||||
@ -748,25 +791,27 @@ int main() {
|
||||
device_ebo_2_buffer.buffer, host_mem_buffer.buffer, size);
|
||||
}
|
||||
memcpy(host_mem_buffer_mem, wood_texture_data.pixels.buf,
|
||||
TextureDataR8G8B8A8_get_space_needed_for_staging_buffer(&wood_texture_data));
|
||||
TextureDataR8G8B8A8_get_size_in_bytes(&wood_texture_data));
|
||||
margaret_copy_buffer_to_texture_for_frag_shader_imm(device, command_pool, graphics_queue,
|
||||
&device_wood_texture, host_mem_buffer.buffer);
|
||||
// We sent everything we needed. but host_mem_buffer_mem may be used later
|
||||
|
||||
// My wood texture needs VkImageView
|
||||
VkImageView wood_texture_view = margaret_create_view_for_image(device, &device_wood_texture, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
|
||||
// My zbuffer also needs a view
|
||||
VkImageView zbuffer_view = margaret_create_view_for_image(device, &device_zbuffer_image, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||
/* Here we create an image view into a temporary IT1 texture and a framebuffer for scene rendering */
|
||||
VkImageView IT1_view = margaret_create_view_for_image(device, &device_IT1_image, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
VkFramebuffer IT1_framebuffer = create_IT1_framebuffer(device, IT1_view, render_pass_0,
|
||||
(VkExtent2D){.width = MAX_WIN_WIDTH, .height = MAX_WIN_HEIGHT});
|
||||
VkFramebuffer IT1_framebuffer = create_IT1_framebuffer(device, IT1_view, zbuffer_view, render_pass_0,
|
||||
MAX_WIN_WIDTH, MAX_WIN_HEIGHT);
|
||||
|
||||
Scene scene;
|
||||
scene.models = VecModelOnScene_new_zeroinit(2);
|
||||
*VecModelOnScene_at(&scene.models, 0) = (ModelOnScene){
|
||||
.vbo = device_vbo_1_buffer.buffer, .ebo = device_ebo_1_buffer.buffer, .indexes = cylinder_1.indexes.len };
|
||||
// *VecModelOnScene_at(&scene.models, 1) = (ModelOnScene){
|
||||
// .vbo = device_vbo_2_buffer.buffer, .ebo = device_ebo_2_buffer.buffer, .indexes = cylinder_2.indexes.len };
|
||||
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}) });
|
||||
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}) });
|
||||
|
||||
// Sampler is global for a lot of my future textures
|
||||
VkSampler my_texture_sampler = margaret_create_sampler(physical_device, device);
|
||||
@ -902,9 +947,16 @@ int main() {
|
||||
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 t_mat = mat4_mul_mat4(projection_matrix, mat4_mul_mat4(camera_rotation_matrix, camera_translation_matrix));
|
||||
// mat4 t_mat = mat4_mul_mat4(camera_rotation_matrix, camera_translation_matrix);
|
||||
|
||||
{
|
||||
*(Pipeline0UBO*)host_mem_buffer_mem = (Pipeline0UBO){.t = t_mat};
|
||||
assert(scene.spotlights.len < pipeline_0_ubo_spotlight_max_count);
|
||||
assert(scene.point_lights.len < pipeline_0_ubo_point_light_max_count);
|
||||
Pipeline0UBO* subo = (Pipeline0UBO*)host_mem_buffer_mem;
|
||||
// todo: speed it up a little
|
||||
subo->spotlight_count = (int)scene.spotlights.len;
|
||||
memcpy(&subo->spotlight_arr, scene.spotlights.buf, scene.spotlights.len * sizeof(Pipeline0Spotlight));
|
||||
subo->point_light_count = (int)scene.point_lights.len;
|
||||
memcpy(&subo->point_light_arr, scene.point_lights.buf, scene.point_lights.len * sizeof(Pipeline0PointLight));
|
||||
VkCommandBuffer command_buffers[1] = { uniform_transfer_command_buffer };
|
||||
VkSemaphore signaling_semaphores[1] = { swfb.in_frame_transfer_complete };
|
||||
VkSubmitInfo ubo_copying_cmd_buffer_submit = {
|
||||
@ -918,7 +970,7 @@ int main() {
|
||||
}
|
||||
|
||||
reset_and_record_command_buffer_0(rendering_command_buffer_0, render_pass_0, &pipeline_hands_0,
|
||||
IT1_framebuffer, swfb.extent, &scene, descriptor_set_for_pipeline_0);
|
||||
IT1_framebuffer, swfb.extent, &scene, descriptor_set_for_pipeline_0, t_mat);
|
||||
|
||||
reset_and_record_command_buffer_1(rendering_command_buffer_1, render_pass_1, &pipeline_hands_1,
|
||||
*VecVkFramebuffer_cat(&swfb.framebuffers, ij),
|
||||
|
||||
@ -3,27 +3,16 @@
|
||||
|
||||
#include "../margaret/graphics_geom.h"
|
||||
#include "../../l1/core/util.h"
|
||||
#include "../../l1/core/VecSpan_int_primitives.h"
|
||||
#include "../../l1/system/fileio.h"
|
||||
#include <math.h>
|
||||
#include "../../../gen/pixel_masses.h"
|
||||
|
||||
typedef struct {
|
||||
vec3 pos;
|
||||
vec2 tex;
|
||||
} Vertex;
|
||||
|
||||
/* No offset yet */
|
||||
typedef struct {
|
||||
VkBuffer vbo;
|
||||
VkBuffer ebo;
|
||||
size_t indexes;
|
||||
} ModelOnScene;
|
||||
|
||||
#define ModelOnScene_drop(vp) {}
|
||||
#define ModelOnScene_clone(vp) (*(vp))
|
||||
|
||||
VecT_trivmove_struct_Definition(ModelOnScene)
|
||||
VecT_trivmove_method_Definition(ModelOnScene)
|
||||
VecT_primitive_zeroinit_method_Definition(ModelOnScene)
|
||||
|
||||
#define Vertex_drop(vp) {}
|
||||
#define Vertex_clone(vp) (*(vp))
|
||||
|
||||
@ -44,62 +33,6 @@ void ModelTopology_drop(ModelTopology self) {
|
||||
VecU32_drop(self.indexes);
|
||||
}
|
||||
|
||||
ModelTopology generate_one_fourth_of_a_cylinder(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);
|
||||
const vec2 v0tex = {r / (2 * r + w), 1 / (2 + k * l)};
|
||||
const vec2 v1tex = {(r + w) / (2 * r + w), 1 / (2 + k * l)};
|
||||
const vec2 v2tex = {r / (2 * r + w), 2 / (2 + k * l)};
|
||||
const vec2 v3tex = {(r + w) / (2 * r + w), 2 / (2 + k * l)};
|
||||
VecVertex vertices = VecVertex_new(); // todo: reserve 4 * k + 6
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, 0, 0}, .tex = v0tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, 0, 0}, .tex = v1tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, r, 0}, .tex = v2tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, r, 0}, .tex = v3tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, 0, r}, .tex = {r / (2 * r + w), 0}});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, 0, r}, .tex = {(r + w) / (2 * r + w), 0}});
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
.pos = {0, cosf(a * i) * r, sinf(a * i) * r},
|
||||
.tex = vec2_add_vec2(v0tex, (vec2){r / (2 * r + w) * -sinf(a * i), 1 / (2 + k * l) * cos(a * i)})
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
.pos = {w, cosf(a * i) * r, sinf(a * i) * r},
|
||||
.tex = vec2_add_vec2(v1tex, (vec2){r / (2 * r + w) * sinf(a * i), 1 / (2 + k * l) * cos(a * i)})
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
.pos = {0, cosf(a * i) * r, sinf(a * i) * r},
|
||||
.tex = {v2tex.x, v2tex.y + i * l / (2 + k * l)}
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
.pos = {w, cosf(a * i) * r, sinf(a * i) * r},
|
||||
.tex = {v3tex.x, v3tex.y + i * l / (2 + k * l)}
|
||||
});
|
||||
}
|
||||
VecU32 indexes = VecU32_new(); // todo: reserve 3 * (2+2+2*k+2*k)<
|
||||
{
|
||||
U32 _span_0[] = { 5, 0, 1, 5, 4, 0, 1, 0, 3, 3, 0, 2 };
|
||||
VecU32_append_span(&indexes, (ConstSpanU32){.data = _span_0, .len = ARRAY_SIZE(_span_0)});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
U32 _span_1[] = {
|
||||
0, 5 + i, i > 1 ? 5 + i - 1 : 2,
|
||||
1, i > 1 ? 5 + k + i - 1 : 3, 5 + k + i,
|
||||
i > 1 ? 5 + 2 * k + i - 1 : 2, 5 + 2 * k + i, i > 1 ? 5 + 3 * k + i - 1 : 3,
|
||||
5 + 3 * k + i, i > 1 ? 5 + 3 * k + i - 1 : 3, 5 + 2 * k + i
|
||||
};
|
||||
VecU32_append_span(&indexes, (ConstSpanU32){.data = _span_1, .len = ARRAY_SIZE(_span_1)});
|
||||
}
|
||||
return (ModelTopology){.vertices = vertices, .indexes = indexes};
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
vec2 win_scale;
|
||||
} Pipeline1PushRangeVertex;
|
||||
@ -112,37 +45,163 @@ typedef struct {
|
||||
} Pipeline1PushRangeFragment;
|
||||
|
||||
typedef struct {
|
||||
mat4 t;
|
||||
} Pipeline0UBO;
|
||||
vec3 pos;
|
||||
char _padding_0[4];
|
||||
vec3 dir;
|
||||
char _padding_1[4];
|
||||
vec3 color;
|
||||
char _padding_2[4];
|
||||
float d;
|
||||
char _padding_3[12];
|
||||
} Pipeline0Spotlight;
|
||||
|
||||
#define cvec4_drop(vp) {}
|
||||
#define cvec4_clone(vp) (*(vp))
|
||||
#define Pipeline0Spotlight_drop(x) {}
|
||||
#define Pipeline0Spotlight_clone(x) (*(x))
|
||||
|
||||
VecT_trivmove_struct_Definition(cvec4)
|
||||
VecT_trivmove_method_Definition(cvec4)
|
||||
VecT_primitive_zeroinit_method_Definition(cvec4)
|
||||
VecT_trivmove_struct_Definition(Pipeline0Spotlight)
|
||||
VecT_trivmove_method_Definition(Pipeline0Spotlight)
|
||||
VecT_primitive_zeroinit_method_Definition(Pipeline0Spotlight)
|
||||
|
||||
typedef struct {
|
||||
// I hate this so much uuuh. Capacity is not actually useful here...
|
||||
Veccvec4 pixels;
|
||||
size_t width;
|
||||
} TextureDataR8G8B8A8;
|
||||
vec3 pos;
|
||||
char _padding_0[4];
|
||||
vec3 color;
|
||||
char _padding_1[4];
|
||||
} Pipeline0PointLight;
|
||||
|
||||
TextureDataR8G8B8A8 TextureDataR8G8B8A8_new(size_t width, size_t height) {
|
||||
return (TextureDataR8G8B8A8){.pixels = Veccvec4_new_zeroinit(width * height), .width = width};
|
||||
#define Pipeline0PointLight_drop(x) {}
|
||||
#define Pipeline0PointLight_clone(x) (*(x))
|
||||
|
||||
VecT_trivmove_struct_Definition(Pipeline0PointLight)
|
||||
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;
|
||||
|
||||
typedef struct {
|
||||
int spotlight_count;
|
||||
int point_light_count;
|
||||
char _padding_1[8];
|
||||
Pipeline0PointLight point_light_arr[20];
|
||||
Pipeline0Spotlight spotlight_arr[120];
|
||||
} Pipeline0UBO;
|
||||
|
||||
size_t ModelTopology_get_space_needed_for_staging_buffer(const ModelTopology* self) {
|
||||
return MAX_U64(self->vertices.len * sizeof(Vertex), self->indexes.len * sizeof(U32));
|
||||
}
|
||||
|
||||
size_t TextureDataR8G8B8A8_get_height(const TextureDataR8G8B8A8* self) {
|
||||
return self->pixels.len / self->width;
|
||||
void TextureDataR8_pixel_maxing(TextureDataR8* self, S32 x, S32 y, U8 val) {
|
||||
if (x < 0 || y < 0 || x >= self->width)
|
||||
return;
|
||||
size_t p = (size_t)x + (size_t)y * self->width;
|
||||
if (p >= self->pixels.len)
|
||||
return;
|
||||
U8 b = *TextureDataR8_at(self, x, y);
|
||||
*TextureDataR8_at(self, x, y) = MAX_U8(b, val);
|
||||
}
|
||||
|
||||
void TextureDataR8G8B8A8_drop(TextureDataR8G8B8A8 self) {
|
||||
Veccvec4_drop(self.pixels);
|
||||
U8 a_small_cute_gradient(float r_cut, float r_decay, float dist) {
|
||||
return dist > r_cut ? 0 : (dist < r_decay) ? 255 : (U8)roundf( 255.f * (r_cut - dist) / (r_cut - r_decay) );
|
||||
}
|
||||
|
||||
cvec4* TextureDataR8G8B8A8_at(TextureDataR8G8B8A8* self, size_t x, size_t y) {
|
||||
assert(x < self->width);
|
||||
return Veccvec4_at(&self->pixels, x + y * self->width);
|
||||
void TextureDataR8_seg_vertical_strip_maxing(TextureDataR8* self, S32 x, float y_real, float vert_r_cut, float vert_r_decay) {
|
||||
S32 y = (S32)roundf(y_real - 0.5f);
|
||||
S32 k = (S32)ceilf(vert_r_cut);
|
||||
for (S32 j = -k+y; j <= y+k; j++) {
|
||||
float dist = fabsf(.5f + (float)j - y_real);
|
||||
TextureDataR8_pixel_maxing(self, x, j, a_small_cute_gradient(vert_r_cut, vert_r_decay, dist));
|
||||
}
|
||||
}
|
||||
|
||||
void TextureDataR8_seg_horizontal_strip_maxing(TextureDataR8* self, float x_real, S32 y, float hor_r_cut, float hor_r_decay) {
|
||||
S32 x = (S32)roundf(x_real - 0.5f);
|
||||
S32 k = (S32)ceilf(hor_r_cut);
|
||||
for (S32 i = -k+x; i < x+k; i++) {
|
||||
float dist = fabsf(.5f + (float)i - x_real);
|
||||
TextureDataR8_pixel_maxing(self, i, y, a_small_cute_gradient(hor_r_cut, hor_r_decay, dist));
|
||||
}
|
||||
}
|
||||
|
||||
// todo: complete rewrite
|
||||
/* abs(y2 - y1) < abs(x2 - x1) x1 <= x2 */
|
||||
void TextureDataR8_draw_horizontal_inner_line_maxing(TextureDataR8* self,
|
||||
float x1, float y1, float x2, float y2, float r_cut, float r_decay) {
|
||||
S32 sx1 = (S32)roundf(x1 - 0.5f);
|
||||
S32 sx2 = (S32)roundf(x2 - 0.5f);
|
||||
if (sx1 + 1 >= sx2)
|
||||
return;
|
||||
float dx = x2 - x1;
|
||||
float dy = y2 - y1;
|
||||
float xdds = 1 / dx;
|
||||
float inv_sin_a = sqrtf(dx*dx + dy*dy) / dx;
|
||||
float vert_r_cut = r_cut * inv_sin_a;
|
||||
float vert_r_decay = r_decay * inv_sin_a;
|
||||
for (S32 x = sx1 + 1; x < sx2; x++) {
|
||||
float real_x = (float)x + 0.5f;
|
||||
float real_y = y1 + dy * (real_x - x1) * xdds;
|
||||
TextureDataR8_seg_vertical_strip_maxing(self, x, real_y, vert_r_cut, vert_r_decay);
|
||||
}
|
||||
}
|
||||
|
||||
/* abs(x2 - x1) < abs(y2 - y1) y1 <= y2 */
|
||||
void TextureDataR8_draw_vertical_inner_line_maxing(TextureDataR8* self,
|
||||
float x1, float y1, float x2, float y2, float r_cut, float r_decay) {
|
||||
S32 sy1 = (S32)roundf(y1 - 0.5f);
|
||||
S32 sy2 = (S32)roundf(y2 - 0.5f);
|
||||
if (sy1 + 1 >= sy2)
|
||||
return;
|
||||
float dx = x2 - x1;
|
||||
float dy = y2 - y1;
|
||||
float ydds = 1 / dy;
|
||||
float inv_sin_a = sqrtf(dx*dx + dy*dy) / dy;
|
||||
float hor_r_cut = r_cut * inv_sin_a;
|
||||
float hor_r_decay = r_decay * inv_sin_a;
|
||||
for (S32 y = sy1 + 1; y < sy2; y++) {
|
||||
float real_y = (float)y + 0.5f;
|
||||
float real_x = x1 + dx * (real_y - y1) * ydds;
|
||||
TextureDataR8_seg_horizontal_strip_maxing(self, real_x, y, hor_r_cut, hor_r_decay);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureDataR8_draw_inner_line_maxing(TextureDataR8* self,
|
||||
float x1, float y1, float x2, float y2, float r_cut, float r_decay) {
|
||||
float dx = fabsf(x2 - x1);
|
||||
float dy = fabsf(y2 - y1);
|
||||
if (dx > dy) {
|
||||
if (x1 < x2) {
|
||||
TextureDataR8_draw_horizontal_inner_line_maxing(self, x1, y1, x2, y2, r_cut, r_decay);
|
||||
} else {
|
||||
TextureDataR8_draw_horizontal_inner_line_maxing(self, x2, y2, x1, y1, r_cut, r_decay);
|
||||
}
|
||||
} else {
|
||||
if (y1 < y2) {
|
||||
TextureDataR8_draw_vertical_inner_line_maxing(self, x1, y1, x2, y2, r_cut, r_decay);
|
||||
} else {
|
||||
TextureDataR8_draw_vertical_inner_line_maxing(self, x2, y2, x1, y1, r_cut, r_decay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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 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);
|
||||
}
|
||||
|
||||
TextureDataR8G8B8A8 generate_wood_texture() {
|
||||
@ -172,85 +231,114 @@ TextureDataR8G8B8A8 generate_wood_texture() {
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t ModelTopology_get_space_needed_for_staging_buffer(const ModelTopology* self) {
|
||||
return MAX_U64(self->vertices.len * sizeof(Vertex), self->indexes.len * sizeof(U32));
|
||||
ModelTopology generate_one_fourth_of_a_cylinder(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);
|
||||
const vec2 v0tex = {r / (2 * r + w), r / (2 * r + k * l)};
|
||||
const vec2 v1tex = {(r + w) / (2 * r + w), r / (2 * r + k * l)};
|
||||
const vec2 v2tex = {r / (2 * r + w), 2 * r / (2 * r + k * l)};
|
||||
const vec2 v3tex = {(r + w) / (2 * r + w), 2 * r / (2 * r + k * l)};
|
||||
VecVertex vertices = VecVertex_new(); // todo: reserve 4 * k + 6
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, 0, 0}, .tex = v0tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, 0, 0}, .tex = v1tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, r, 0}, .tex = v2tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, r, 0}, .tex = v3tex});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {0, 0, r}, .tex = {r / (2 * r + w), 0}});
|
||||
VecVertex_append(&vertices, (Vertex){.pos = {w, 0, r}, .tex = {(r + w) / (2 * r + w), 0}});
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
.pos = {0, cosf(a * i) * r, sinf(a * i) * r},
|
||||
.tex = vec2_add_vec2(v0tex, (vec2){r / (2 * r + w) * -sinf(a * i), r / (2 * r + k * l) * cos(a * i)})
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
.pos = {w, cosf(a * i) * r, sinf(a * i) * r},
|
||||
.tex = vec2_add_vec2(v1tex, (vec2){r / (2 * r + w) * sinf(a * i), r / (2*r + k * l) * cos(a * i)})
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
.pos = {0, cosf(a * i) * r, sinf(a * i) * r},
|
||||
.tex = {v2tex.x, v2tex.y + i * l / (2*r + k * l)}
|
||||
});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
VecVertex_append(&vertices, (Vertex){
|
||||
.pos = {w, cosf(a * i) * r, sinf(a * i) * r},
|
||||
.tex = {v3tex.x, v3tex.y + i * l / (2*r + k * l)}
|
||||
});
|
||||
}
|
||||
VecU32 indexes = VecU32_new(); // todo: reserve 3 * (2+2+2*k+2*k)<
|
||||
{
|
||||
U32 _span_0[] = { 5, 0, 1, 5, 4, 0, 1, 0, 3, 3, 0, 2 };
|
||||
VecU32_append_span(&indexes, (ConstSpanU32){.data = _span_0, .len = ARRAY_SIZE(_span_0)});
|
||||
}
|
||||
for (U32 i = 1; i <= k; i++) {
|
||||
U32 _span_1[] = {
|
||||
0, 5 + i, i > 1 ? 5 + i - 1 : 2,
|
||||
1, i > 1 ? 5 + k + i - 1 : 3, 5 + k + i,
|
||||
i > 1 ? 5 + 2 * k + i - 1 : 2, 5 + 2 * k + i, i > 1 ? 5 + 3 * k + i - 1 : 3,
|
||||
5 + 3 * k + i, i > 1 ? 5 + 3 * k + i - 1 : 3, 5 + 2 * k + i
|
||||
};
|
||||
VecU32_append_span(&indexes, (ConstSpanU32){.data = _span_1, .len = ARRAY_SIZE(_span_1)});
|
||||
}
|
||||
return (ModelTopology){.vertices = vertices, .indexes = indexes};
|
||||
}
|
||||
|
||||
size_t TextureDataR8G8B8A8_get_space_needed_for_staging_buffer(const TextureDataR8G8B8A8* self) {
|
||||
return self->pixels.len * sizeof(cvec4);
|
||||
#define vec2_drop(x) {}
|
||||
#define vec2_clone(x) (*(x))
|
||||
|
||||
VecT_trivmove_struct_Definition(vec2)
|
||||
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
|
||||
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)));
|
||||
Vecvec2 P = Vecvec2_new(); // todo: reserve 6 + k * 4
|
||||
Vecvec2_append(&P, v0tex);
|
||||
Vecvec2_append(&P, (vec2){r, 0}); // 4
|
||||
Vecvec2_append(&P, (vec2){r + w, 0}); // 5
|
||||
Vecvec2_append(&P, v1tex);
|
||||
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_scal(*Vecvec2_at(&P, i), s_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_scal(*Vecvec2_at(&P, i ? i - 1 : S - 1), s_resol);
|
||||
vec2 p = vec2_mul_scal(*Vecvec2_at(&P, i), s_resol);
|
||||
TextureDataR8_draw_inner_line_maxing(&res, pp.x, pp.y, p.x, p.y, r_cut, r_decay);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
float fov;
|
||||
mat3 cam_basis;
|
||||
vec3 pos;
|
||||
|
||||
float speed;
|
||||
float sensitivity;
|
||||
float pitch_cap;
|
||||
} CamControlInfo;
|
||||
|
||||
void CamControlInfo_forward(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.z, -self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_backward(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.z, self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_left(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.x, -self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_right(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.x, self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_down(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal((vec3){0, -1, 0}, self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_up(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal((vec3){0, 1, 0}, self->speed * 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},
|
||||
.speed = 2.7, .sensitivity = 0.5f * M_PIf / 180, .pitch_cap = M_PI * 0.49
|
||||
};
|
||||
}
|
||||
|
||||
float clamp_float(float a, float l, float r) {
|
||||
return (a < l) ? l : ((a <= r) ? a : r);
|
||||
}
|
||||
|
||||
void CamControlInfo_update_direction(CamControlInfo* self, int win_width, int win_height, int pointer_x, int pointer_y) {
|
||||
float yaw = (float)(win_width / 2 - pointer_x) * self->sensitivity;
|
||||
float pitch = clamp_float(
|
||||
(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);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
VecModelOnScene models;
|
||||
VkClearColorValue color;
|
||||
float gamma_correction_factor;
|
||||
float hdr_factor;
|
||||
float lsd_factor;
|
||||
float anim_time; // A timer, passed to functions that push push constants
|
||||
} Scene;
|
||||
|
||||
Scene Scene_new() {
|
||||
return (Scene){.models = VecModelOnScene_new(), .color = {.float32 = {1, 0.5, 0.7}},
|
||||
.gamma_correction_factor = 2.2, .hdr_factor = 1, .lsd_factor = 0, .anim_time = 0};
|
||||
}
|
||||
|
||||
void Scene_drop(Scene self) {
|
||||
VecModelOnScene_drop(self.models);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
109
src/l2/tests/r0_scene.h
Normal file
109
src/l2/tests/r0_scene.h
Normal file
@ -0,0 +1,109 @@
|
||||
#ifndef PROTOTYPE1_SRC_L2_TESTS_R0_SCENE_H
|
||||
#define PROTOTYPE1_SRC_L2_TESTS_R0_SCENE_H
|
||||
|
||||
#include "r0_assets.h"
|
||||
|
||||
/* No offset yet */
|
||||
typedef struct {
|
||||
VkBuffer vbo;
|
||||
VkBuffer ebo;
|
||||
size_t indexes;
|
||||
} ModelOnScene;
|
||||
|
||||
#define ModelOnScene_drop(vp) {}
|
||||
#define ModelOnScene_clone(vp) (*(vp))
|
||||
|
||||
VecT_trivmove_struct_Definition(ModelOnScene)
|
||||
VecT_trivmove_method_Definition(ModelOnScene)
|
||||
VecT_primitive_zeroinit_method_Definition(ModelOnScene)
|
||||
|
||||
typedef struct {
|
||||
ModelOnScene model;
|
||||
mat4 model_t;
|
||||
} UsedModelOnScene;
|
||||
|
||||
#define UsedModelOnScene_drop(vp) {}
|
||||
#define UsedModelOnScene_clone(vp) (*(vp))
|
||||
|
||||
VecT_trivmove_struct_Definition(UsedModelOnScene)
|
||||
VecT_trivmove_method_Definition(UsedModelOnScene)
|
||||
VecT_primitive_zeroinit_method_Definition(UsedModelOnScene)
|
||||
|
||||
|
||||
typedef struct {
|
||||
float fov;
|
||||
mat3 cam_basis;
|
||||
vec3 pos;
|
||||
|
||||
float speed;
|
||||
float sensitivity;
|
||||
float pitch_cap;
|
||||
} CamControlInfo;
|
||||
|
||||
void CamControlInfo_forward(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.z, -self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_backward(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.z, self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_left(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.x, -self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_right(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal(self->cam_basis.x, self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_down(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal((vec3){0, -1, 0}, self->speed * fl));
|
||||
}
|
||||
|
||||
void CamControlInfo_up(CamControlInfo* self, float fl) {
|
||||
self->pos = vec3_add_vec3(self->pos, vec3_mul_scal((vec3){0, 1, 0}, self->speed * 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},
|
||||
.speed = 2.7, .sensitivity = 0.5f * M_PIf / 180, .pitch_cap = M_PI * 0.49
|
||||
};
|
||||
}
|
||||
|
||||
float clamp_float(float a, float l, float r) {
|
||||
return (a < l) ? l : ((a <= r) ? a : r);
|
||||
}
|
||||
|
||||
void CamControlInfo_update_direction(CamControlInfo* self, int win_width, int win_height, int pointer_x, int pointer_y) {
|
||||
float yaw = (float)(win_width / 2 - pointer_x) * self->sensitivity;
|
||||
float pitch = clamp_float(
|
||||
(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);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
VecUsedModelOnScene models;
|
||||
VkClearColorValue color;
|
||||
float gamma_correction_factor;
|
||||
float hdr_factor;
|
||||
float lsd_factor;
|
||||
float anim_time; // A timer, passed to functions that push push constants
|
||||
VecPipeline0Spotlight spotlights;
|
||||
VecPipeline0PointLight point_lights;
|
||||
} Scene;
|
||||
|
||||
Scene Scene_new() {
|
||||
return (Scene){.models = VecUsedModelOnScene_new(), .color = {.float32 = {1, 0.5, 0.7}},
|
||||
.gamma_correction_factor = 2.2, .hdr_factor = 1, .lsd_factor = 0, .anim_time = 0,
|
||||
.spotlights = VecPipeline0Spotlight_new(), .point_lights = VecPipeline0PointLight_new()};
|
||||
}
|
||||
|
||||
void Scene_drop(Scene self) {
|
||||
VecUsedModelOnScene_drop(self.models);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
9
src/l2/tests/r0_tex_init_prep.c
Normal file
9
src/l2/tests/r0_tex_init_prep.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "r0_assets.h"
|
||||
#include "../../l1/system/fileio.h"
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
@ -1,4 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set +x
|
||||
cd test_shaders
|
||||
|
||||
function compile(){
|
||||
@ -9,3 +11,11 @@ function compile(){
|
||||
|
||||
compile 0
|
||||
compile 1
|
||||
|
||||
#cd ../test_textures
|
||||
#
|
||||
#function png_to_r8g8b8a8 {
|
||||
# python bitmap_convert.py to_bmp "$1.png" "$1.r8g8b8"
|
||||
#}
|
||||
#
|
||||
#png_to_r8g8b8a8 log_10_2_6
|
||||
|
||||
@ -6,6 +6,30 @@ layout(location = 0) out vec4 fin_color;
|
||||
|
||||
layout(binding = 1) uniform sampler2D color_tex;
|
||||
|
||||
|
||||
struct Pipeline0Spotlight
|
||||
{
|
||||
vec3 pos;
|
||||
vec3 dir;
|
||||
vec3 colour;
|
||||
float range;
|
||||
};
|
||||
|
||||
struct Pipeline0PointLight
|
||||
{
|
||||
vec3 pos;
|
||||
vec3 colour;
|
||||
};
|
||||
|
||||
layout(std140, binding = 0) uniform Pipeline0UBO
|
||||
{
|
||||
int spotlight_count;
|
||||
int point_light_count;
|
||||
|
||||
Pipeline0PointLight point_light_arr[20];
|
||||
Pipeline0Spotlight spotlight_arr [120];
|
||||
};
|
||||
|
||||
void main(){
|
||||
fin_color = texture(color_tex, fsin_tex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,12 +5,14 @@ layout(location = 1) in vec2 tex;
|
||||
|
||||
layout(location = 0) out vec2 vsout_tex;
|
||||
|
||||
layout(binding = 0) uniform ubo {
|
||||
layout(push_constant, std430) uniform pc {
|
||||
/* Individual transformation for a model. Fits in push constant range
|
||||
Includes global perspective matrix and camera matrix, but for each model there is a distinct
|
||||
transformation matrix. Right now I only have one instance for each model,
|
||||
otherwise I would use per-instance vertex attribute */
|
||||
mat4 t;
|
||||
};
|
||||
|
||||
// todo: add my ubo (location = 0) into the mix
|
||||
// todo: add my woiod_texture (location = 1) into the mix
|
||||
void main(){
|
||||
vsout_tex = tex;
|
||||
gl_Position = t * vec4(pos, 1);
|
||||
|
||||
0
src/l2/tests/test_shaders/glsl/0b/0b.frag
Normal file
0
src/l2/tests/test_shaders/glsl/0b/0b.frag
Normal file
0
src/l2/tests/test_shaders/glsl/0b/0b.vert
Normal file
0
src/l2/tests/test_shaders/glsl/0b/0b.vert
Normal file
119
src/l2/tests/test_textures/bitmap_converter.py
Executable file
119
src/l2/tests/test_textures/bitmap_converter.py
Executable file
@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
raw_png_conv.py
|
||||
===============
|
||||
|
||||
Convert between custom bottom‑up raw files (.r8g8b8a8 / .r8b8g8 / .r8)
|
||||
and normal PNG using Pillow.
|
||||
|
||||
Format
|
||||
------
|
||||
uint32 width (little‑endian)
|
||||
uint32 height (little‑endian)
|
||||
pixel data rows bottom‑first:
|
||||
* .r8g8b8a8 : R G B A (4× uint8)
|
||||
* .r8b8g8 : R G B (3× uint8)
|
||||
* .r8 : R (1× uint8 <- grayscale)
|
||||
|
||||
CLI
|
||||
---
|
||||
raw -> png : python raw_png_conv.py to_png input.raw output.png
|
||||
png -> raw : python raw_png_conv.py to_raw input.png output.raw
|
||||
"""
|
||||
import argparse
|
||||
import struct
|
||||
from pathlib import Path
|
||||
from PIL import Image
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# Helpers
|
||||
# --------------------------------------------------------------------- #
|
||||
|
||||
RAW_FORMATS = {
|
||||
".r8g8b8a8": {"pix_size": 4, "mode": "RGBA"},
|
||||
".r8b8g8": {"pix_size": 3, "mode": "RGB"},
|
||||
".r8": {"pix_size": 1, "mode": "L"},
|
||||
}
|
||||
|
||||
|
||||
def get_fmt(path: Path):
|
||||
fmt = RAW_FORMATS.get(path.suffix.lower())
|
||||
if not fmt:
|
||||
raise ValueError(f"Unknown raw extension: {path.suffix}")
|
||||
return fmt
|
||||
|
||||
|
||||
def read_raw(path: Path) -> Image.Image:
|
||||
"""Load any supported raw file -> Pillow Image."""
|
||||
spec = get_fmt(path)
|
||||
with path.open("rb") as f:
|
||||
header = f.read(8)
|
||||
if len(header) != 8:
|
||||
raise ValueError("File too short for header")
|
||||
w, h = struct.unpack("<II", header)
|
||||
expected = w * h * spec["pix_size"]
|
||||
data = f.read()
|
||||
if len(data) != expected:
|
||||
raise ValueError(
|
||||
f"Pixel data length mismatch: expected {expected}, got {len(data)}"
|
||||
)
|
||||
row_len = w * spec["pix_size"]
|
||||
rows = [data[i : i + row_len] for i in range(0, expected, row_len)]
|
||||
img_bytes = b"".join(reversed(rows)) # flip bottom‑up -> top‑down
|
||||
return Image.frombytes(spec["mode"], (w, h), img_bytes)
|
||||
|
||||
|
||||
def write_raw(img: Image.Image, path: Path) -> None:
|
||||
"""Write Pillow Image -> raw file chosen by path suffix."""
|
||||
spec = get_fmt(path)
|
||||
# Convert to required mode
|
||||
if img.mode != spec["mode"]:
|
||||
if spec["mode"] == "L":
|
||||
img = img.convert("L")
|
||||
elif spec["mode"] == "RGB":
|
||||
img = img.convert("RGB")
|
||||
else: # RGBA
|
||||
img = img.convert("RGBA")
|
||||
|
||||
w, h = img.size
|
||||
data = img.tobytes()
|
||||
row_len = w * spec["pix_size"]
|
||||
rows = [data[i : i + row_len] for i in range(0, len(data), row_len)]
|
||||
bottom_first = b"".join(reversed(rows)) # top‑down -> bottom‑up
|
||||
|
||||
with path.open("wb") as f:
|
||||
f.write(struct.pack("<II", w, h))
|
||||
f.write(bottom_first)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------- #
|
||||
# CLI
|
||||
# --------------------------------------------------------------------- #
|
||||
|
||||
def to_png(src: Path, dst: Path):
|
||||
read_raw(src).save(dst, "PNG")
|
||||
|
||||
|
||||
def to_raw(src: Path, dst: Path):
|
||||
write_raw(Image.open(src), dst)
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Convert raw <-> PNG")
|
||||
sub = ap.add_subparsers(dest="cmd", required=True)
|
||||
p_png = sub.add_parser("to_png", help="raw -> png")
|
||||
p_png.add_argument("src", type=Path)
|
||||
p_png.add_argument("dst", type=Path)
|
||||
p_raw = sub.add_parser("to_raw", help="png -> raw")
|
||||
p_raw.add_argument("src", type=Path)
|
||||
p_raw.add_argument("dst", type=Path)
|
||||
args = ap.parse_args()
|
||||
|
||||
if args.cmd == "to_png":
|
||||
to_png(args.src, args.dst)
|
||||
else:
|
||||
to_raw(args.src, args.dst)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
BIN
src/l2/tests/test_textures/log_10_2_6.png
Normal file
BIN
src/l2/tests/test_textures/log_10_2_6.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
src/l2/tests/test_textures/log_10_2_6_TEMPLATE.png
Normal file
BIN
src/l2/tests/test_textures/log_10_2_6_TEMPLATE.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/l2/tests/test_textures/log_10_2_6_v2.png
Normal file
BIN
src/l2/tests/test_textures/log_10_2_6_v2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Loading…
x
Reference in New Issue
Block a user