Merged with adding-extures branch. Removed _int_primitives.h template amalgamation. Yet another refactoring is done
@ -27,24 +27,23 @@ add_compile_definitions(_POSIX_C_SOURCE=200112L)
|
||||
add_compile_definitions(_GNU_SOURCE)
|
||||
add_compile_options(-fno-trapping-math)
|
||||
|
||||
#add_executable(codegen_l1 src/l1/anne/codegen.c)
|
||||
#add_executable(codegen_l1 src/l1/anne/codegen.c)1
|
||||
#target_compile_definitions(codegen_l1
|
||||
# PRIVATE PROTOTYPE1_L1_CODEGEN_BOOTSTRAP_USE_CHICKEN_VECU8)
|
||||
|
||||
#add_executable(0_test src/l1_4/tests/t0.c)
|
||||
#add_executable(1_test src/l1_4/tests/t1.c)
|
||||
#
|
||||
add_executable(l1_4_t2 src/l1_4/tests/t2.c)
|
||||
#add_executable(l1_4_t2 src/l1_4/tests/t2.c)
|
||||
|
||||
#add_executable(codegen_l1_5 src/l1_5/anne/codegen.c)
|
||||
|
||||
add_executable(0_render_test src/l2/tests/r0/r0.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
target_link_libraries(0_render_test -lvulkan -lwayland-client -lm -lxkbcommon -lpng)
|
||||
|
||||
add_executable(0r_tex_init_prep src/l2/tests/r0/r0_tex_init_prep.c)
|
||||
target_link_libraries(0r_tex_init_prep -lm -lpng)
|
||||
|
||||
add_executable(codegen_l1_5 src/l1_5/anne/codegen.c)
|
||||
#
|
||||
#add_executable(0_render_test src/l2/tests/r0/r0.c gen/l_wl_protocols/xdg-shell-private.c
|
||||
# src/l1/core/rb_tree_node.h)
|
||||
#target_link_libraries(0_render_test -lvulkan -lwayland-client -lm -lxkbcommon -lpng)
|
||||
#
|
||||
#add_executable(0r_tex_init_prep src/l2/tests/r0/r0_tex_init_prep.c)
|
||||
#target_link_libraries(0r_tex_init_prep -lm -lpng)
|
||||
#
|
||||
#add_executable(1_render_test src/l2/tests/r1/r1.c gen/l_wl_protocols/xdg-shell-private.c)
|
||||
#target_link_libraries(1_render_test -lwayland-client -lrt -lm -lxkbcommon)
|
||||
#
|
||||
@ -58,4 +57,4 @@ add_executable(codegen_l1_5 src/l1_5/anne/codegen.c)
|
||||
#target_link_libraries(0_play_test -lncurses)
|
||||
#
|
||||
|
||||
add_executable(l2t0 src/l2/tests/data_structures/t0.c)
|
||||
#add_executable(l2t0 src/l2/tests/data_structures/t0.c)
|
||||
|
||||
@ -7,10 +7,11 @@
|
||||
|
||||
#include "some_tests.h"
|
||||
#include "util_temp_vulkan.h"
|
||||
#include "margaret/vulkan_utils.h"
|
||||
#include "margaret/margaret_misc.h"
|
||||
#include "marie/graphics_geom.h"
|
||||
#include "liza.h"
|
||||
#include "codegen_from_l1_5.h"
|
||||
#include "margaret/png_pixel_masses.h"
|
||||
|
||||
int main() {
|
||||
mkdir_nofail("l1");
|
||||
@ -21,10 +22,12 @@ int main() {
|
||||
generate_pixel_masses_header();
|
||||
generate_headers_for_r0_r1_r2_r3();
|
||||
generate_util_templ_inst_for_vulkan_headers();
|
||||
generate_margaret_eve_for_vulkan_utils();
|
||||
generate_marie_headers_for_graphics_geom();
|
||||
generate_liza_l1_headers();
|
||||
generate_l1_headers_for_l1_5();
|
||||
mkdir_nofail("l1/margaret");
|
||||
generate_margaret_eve_for_vulkan_utils(); /* margaret misc */
|
||||
generate_margaret_png_pixel_masses_header();
|
||||
finish_layer(cstr("l1"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef PROTOTYPE1_SRC_L1_ANNE_MARGARET_VULKAN_H
|
||||
#define PROTOTYPE1_SRC_L1_ANNE_MARGARET_VULKAN_H
|
||||
#ifndef PROTOTYPE1_SRC_L1_ANNE_MARGARET_MARGARET_MISC_H
|
||||
#define PROTOTYPE1_SRC_L1_ANNE_MARGARET_MARGARET_MISC_H
|
||||
|
||||
#include "../../codegen/util_template_inst.h"
|
||||
|
||||
@ -21,6 +21,8 @@ void generate_margaret_eve_for_vulkan_utils() {
|
||||
.T = cstr("PtrMargaretImageInMemoryInfo"), .t_primitive = true, .vec = true, .span = true, .mut_span = true,
|
||||
.collab_vec_span = true
|
||||
});
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretCommandForImageCopying"), true, true);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
302
src/l1/anne/margaret/png_pixel_masses.h
Normal file
@ -0,0 +1,302 @@
|
||||
#ifndef PROTOTYPE1_SRC_L1_ANNE_MARGARET_PNG_PIXEL_MASSES_H
|
||||
#define PROTOTYPE1_SRC_L1_ANNE_MARGARET_PNG_PIXEL_MASSES_H
|
||||
|
||||
#include "../../codegen/util_template_inst.h"
|
||||
|
||||
typedef struct {
|
||||
S64 channel_count;
|
||||
SpanU8 name;
|
||||
} color_type_name_in_png;
|
||||
|
||||
color_type_name_in_png color_types_names_in_png[] = {
|
||||
{1, cstr("PNG_COLOR_TYPE_GRAY")},
|
||||
{2, cstr("PNG_COLOR_TYPE_GRAY_ALPHA")},
|
||||
{3, cstr("PNG_COLOR_TYPE_RGB")},
|
||||
{4, cstr("PNG_COLOR_TYPE_RGBA")},
|
||||
};
|
||||
|
||||
NODISCARD VecU8 generate_margaret_png_texture_data_methods(SpanU8 format_signature, S64 depth, S64 channel_count) {
|
||||
if (depth != 8)
|
||||
abortf("Please no\n");
|
||||
SpanU8 color_type = cstr("");
|
||||
for (size_t i = 0; i < ARRAY_SIZE(color_types_names_in_png); i++) {
|
||||
if (color_types_names_in_png[i].channel_count == channel_count)
|
||||
color_type = color_types_names_in_png[i].name;
|
||||
}
|
||||
if (color_type.len == 0)
|
||||
abortf("Please don't\n");
|
||||
|
||||
U64 sizeof_pixel = (U64)depth / 8 * (U64)channel_count;
|
||||
VecU8 res = VecU8_new();
|
||||
|
||||
VecU8 g_promise = VecU8_fmt("MargaretPromisedPng%s", format_signature);
|
||||
SpanU8 promise = VecU8_to_span(&g_promise);
|
||||
VecU8 g_tex = VecU8_fmt("TextureData%s", format_signature);
|
||||
SpanU8 tex = VecU8_to_span(&g_tex);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD ResultVoidOrVecU8 %s_write_to_png(const %s* self, SpanU8 filename) {\n" /* tex, tex */
|
||||
SPACE "VecU8 nt_filename = VecU8_fmt(\"%%s%%c\", filename, 0);\n"
|
||||
SPACE "FILE *fp = fopen((CSTR)nt_filename.buf, \"wb\");\n"
|
||||
SPACE "VecU8_drop(nt_filename);\n"
|
||||
SPACE "if (!fp) {\n"
|
||||
SPACE SPACE "return (ResultVoidOrVecU8){.variant = Result_Err, .err = VecU8_fmt(\"Unable to open file %%s\", filename)};\n"
|
||||
SPACE "}\n"
|
||||
SPACE "png_structp pngshka = png_create_write_struct(PNG_LIBPNG_VER_STRING,\n"
|
||||
SPACE SPACE "NULL, margaret_libpng_h_error_cb, margaret_libpng_h_warning_cb);\n"
|
||||
SPACE "if (!pngshka)\n"
|
||||
SPACE SPACE "abortf(\"png_create_write_struct\");\n"
|
||||
SPACE "png_infop info = png_create_info_struct(pngshka);\n"
|
||||
SPACE "if (!info)\n"
|
||||
SPACE SPACE"abortf(\"png_create_info_struct\");\n"
|
||||
SPACE "png_bytep* row_pointers = NULL;\n"
|
||||
SPACE "if (setjmp(png_jmpbuf(pngshka))){\n"
|
||||
SPACE SPACE "png_destroy_write_struct(&pngshka, &info);\n"
|
||||
SPACE SPACE "fclose(fp);\n"
|
||||
SPACE SPACE "free(row_pointers);\n"
|
||||
SPACE SPACE "return (ResultVoidOrVecU8){.variant = Result_Err, .err = VecU8_from_cstr(\"Some png error happened\")};\n"
|
||||
SPACE "}\n"
|
||||
SPACE "png_init_io(pngshka, fp);\n"
|
||||
SPACE "U32 width = self->width;\n"
|
||||
SPACE "U32 height = self->height;\n"
|
||||
SPACE "png_set_IHDR(pngshka, info, width, height, %i, %s,\n" /* depth, color_type */
|
||||
SPACE SPACE "PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n"
|
||||
SPACE "row_pointers = calloc(height, sizeof(row_pointers));\n"
|
||||
SPACE "for (U32 y = 0; y < height; y++) {\n"
|
||||
SPACE SPACE "row_pointers[height - 1 - y] = (png_bytep)((%s_at(self, 0, y)));\n" /* tex */
|
||||
SPACE "}\n"
|
||||
SPACE "png_set_rows(pngshka, info, row_pointers);\n"
|
||||
SPACE "png_write_png(pngshka, info, 0, NULL);\n"
|
||||
SPACE "/* No more errors */\n"
|
||||
SPACE "free(row_pointers);\n"
|
||||
SPACE "png_destroy_write_struct(&pngshka, &info);\n"
|
||||
SPACE "fclose(fp);\n"
|
||||
SPACE "return (ResultVoidOrVecU8){.variant = Result_Ok};\n"
|
||||
"}\n\n"
|
||||
"/* Aborts on error */\n"
|
||||
"void %s_write_to_png_nofail(const %s* self, SpanU8 filename) {\n" /* tex, tex*/
|
||||
SPACE "ResultVoidOrVecU8 res = %s_write_to_png(self, filename);\n" /* tex */
|
||||
SPACE "if (res.variant == Result_Err) {\n"
|
||||
SPACE SPACE "SpanU8_fprint(VecU8_to_span(&res.err), stderr);\n"
|
||||
SPACE SPACE "abortf(\" %s_write_to_png\\n\");\n" /* tex */
|
||||
SPACE "}\n"
|
||||
"}\n",
|
||||
tex, tex, depth, color_type, tex, tex, tex, tex, tex));
|
||||
|
||||
/* Non clonable structure */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "FILE* fp;\n"
|
||||
SPACE "png_structp pngshka;\n"
|
||||
SPACE "png_infop info;\n"
|
||||
SPACE "png_infop end_info;\n"
|
||||
"} %s;\n\n"
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE "png_destroy_read_struct(&self.pngshka, &self.info, &self.end_info);\n"
|
||||
SPACE "fclose(self.fp);\n"
|
||||
"}\n\n",
|
||||
promise, promise, promise));
|
||||
|
||||
VecU8_append_vec(&res, generate_result_template_inst(promise, cstr("VecU8"), false, false));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD Result%sOrVecU8 %s_begin(SpanU8 filename) {\n" /* promise, promise */
|
||||
SPACE "VecU8 nt_filename = VecU8_fmt(\"%%s%%c\", filename, 0);\n"
|
||||
SPACE "FILE* fp = fopen((CSTR)nt_filename.buf, \"rb\");\n"
|
||||
SPACE "VecU8_drop(nt_filename);\n"
|
||||
SPACE "if (!fp) {\n"
|
||||
SPACE SPACE "return (Result%sOrVecU8){.variant = Result_Err,\n" /* promise */
|
||||
SPACE SPACE SPACE ".err = VecU8_fmt(\"Unable to open file %%s\", filename)};\n"
|
||||
SPACE "}\n"
|
||||
SPACE "png_structp pngshka = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, margaret_libpng_h_error_cb, margaret_libpng_h_warning_cb);\n"
|
||||
SPACE "if (!pngshka)\n"
|
||||
SPACE SPACE "abortf(\"png_create_read_struct\");\n"
|
||||
SPACE "png_infop info = png_create_info_struct(pngshka);\n"
|
||||
SPACE "if (!info)\n"
|
||||
SPACE SPACE "abortf(\"png_create_info_struct\");\n"
|
||||
SPACE "png_infop end_info = png_create_info_struct(pngshka);\n"
|
||||
SPACE "if (!end_info)\n"
|
||||
SPACE SPACE "abortf(\"png_create_info_struct\");\n"
|
||||
SPACE "if (setjmp(png_jmpbuf(pngshka))) {\n"
|
||||
SPACE SPACE "png_destroy_read_struct(&pngshka, &info, &end_info);\n"
|
||||
SPACE SPACE "fclose(fp);\n"
|
||||
SPACE SPACE "return (Result%sOrVecU8){.variant = Result_Err,\n" /* promise */
|
||||
SPACE SPACE SPACE ".err = VecU8_from_cstr(\"Some png error happened\")};\n"
|
||||
SPACE "}\n"
|
||||
SPACE "png_init_io(pngshka, fp);\n"
|
||||
SPACE "png_read_info(pngshka, info);\n"
|
||||
SPACE "U32 width, height;\n"
|
||||
SPACE "int bit_depth, color_type;\n"
|
||||
SPACE "check(png_get_IHDR(pngshka, info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL));\n",
|
||||
promise, promise, promise, promise));
|
||||
|
||||
/* We are still in PROMISE_begin method, now we need to do the conversion */
|
||||
if (depth == 8) {
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (bit_depth == 16)\n"
|
||||
SPACE SPACE "png_set_strip_16(pngshka);\n"
|
||||
SPACE "else if (color_type == PNG_COLOR_TYPE_GRAY && (bit_depth == 1 || bit_depth == 2 || bit_depth == 4))\n"
|
||||
SPACE SPACE "png_set_expand_gray_1_2_4_to_8(pngshka);\n"
|
||||
));
|
||||
} else
|
||||
assert(false);
|
||||
if (channel_count == 3 || channel_count == 4) {
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)\n"
|
||||
SPACE SPACE "png_set_gray_to_rgb(pngshka);\n"
|
||||
SPACE "else if (color_type == PNG_COLOR_TYPE_PALETTE)"
|
||||
SPACE SPACE "png_set_palette_to_rgb(pngshka);\n"
|
||||
));
|
||||
} else if (channel_count == 1 || channel_count == 2) {
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGBA) {\n"
|
||||
SPACE SPACE "png_set_rgb_to_gray_fixed(pngshka, 1, 21268, 71514);\n"
|
||||
SPACE "} else if (color_type == PNG_COLOR_TYPE_PALETTE) {\n"
|
||||
SPACE SPACE "png_set_palette_to_rgb(pngshka);\n"
|
||||
SPACE SPACE "png_set_rgb_to_gray_fixed(pngshka, 1, 21268, 71514);\n"
|
||||
SPACE "}\n"
|
||||
));
|
||||
} else
|
||||
assert(false);
|
||||
if (channel_count == 4 || channel_count == 2) {
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_PALETTE) {\n"
|
||||
SPACE SPACE "if (png_get_valid(pngshka, info, PNG_INFO_tRNS)) \n"
|
||||
SPACE SPACE SPACE "png_set_tRNS_to_alpha(pngshka);\n"
|
||||
SPACE SPACE "else\n"
|
||||
SPACE SPACE SPACE "png_set_add_alpha(pngshka, 0xFF, PNG_FILLER_AFTER);\n"
|
||||
SPACE "}\n"
|
||||
));
|
||||
} else if (channel_count == 1 || channel_count == 3) {
|
||||
VecU8_append_span(&res, cstr(
|
||||
SPACE "if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA || color_type == PNG_COLOR_TYPE_RGBA)\n"
|
||||
SPACE SPACE "png_set_strip_alpha(pngshka);\n"
|
||||
));
|
||||
} else
|
||||
assert(false);
|
||||
/* At this point we have a converted image png structure */
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "png_read_update_info(pngshka, info);\n"
|
||||
SPACE "{\n"
|
||||
SPACE SPACE "U32 new_width, new_height;\n"
|
||||
SPACE SPACE "int new_bit_depth, new_color_type;\n"
|
||||
SPACE SPACE "check(png_get_IHDR(pngshka, info, &new_width, &new_height, &new_bit_depth, &new_color_type, NULL, NULL, NULL));\n"
|
||||
SPACE SPACE "assert(new_width == width && new_height == height && new_bit_depth == %i && new_color_type == %s);\n" /* depth, color_type */
|
||||
SPACE "}\n"
|
||||
SPACE "return (Result%sOrVecU8){.variant = Result_Ok,\n" /* promise */
|
||||
SPACE SPACE ".ok = (%s){.fp = fp, .pngshka = pngshka, .info = info, .end_info = end_info}};\n" /* promise */
|
||||
"}\n\n",
|
||||
(S64)depth, color_type,
|
||||
promise, promise));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"SizeOfRectangleU32 %s_get_extent(const %s* self) {\n" /* promise, promise */
|
||||
SPACE "U32 width, height;\n"
|
||||
SPACE "int bit_depth, color_type;\n"
|
||||
SPACE "check(png_get_IHDR(self->pngshka, self->info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL));\n"
|
||||
SPACE "return (SizeOfRectangleU32){width, height};\n"
|
||||
"}\n\n",
|
||||
promise, promise));
|
||||
|
||||
assert(depth == 8 || depth == 16);
|
||||
assert(channel_count == 1 || channel_count == 2 || channel_count == 4 || channel_count == 3);
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"size_t %s_get_needed_buffer_size(const %s* self) {\n" /* promise, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %s_get_extent(self);\n" /* promise */
|
||||
SPACE "return %u * dim.width * dim.height;\n" /* sizeof_pixel */
|
||||
"}\n\n",
|
||||
promise, promise, promise, sizeof_pixel));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD ResultVoidOrVecU8 %s_finish(%s self, void* buffer) {\n" /* promise, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %s_get_extent(&self);\n" /* promise */
|
||||
SPACE "png_bytep* row_pointers = NULL;\n"
|
||||
SPACE "if (setjmp(png_jmpbuf(self.pngshka))) {\n"
|
||||
SPACE SPACE "png_destroy_read_struct(&self.pngshka, &self.info, &self.end_info);\n"
|
||||
SPACE SPACE "fclose(self.fp);\n"
|
||||
SPACE SPACE "free(row_pointers);\n"
|
||||
SPACE SPACE "return (ResultVoidOrVecU8){.variant = Result_Err, .err = VecU8_from_cstr(\"Some png error happened\")};\n"
|
||||
SPACE "}\n"
|
||||
SPACE "row_pointers = calloc(dim.height, sizeof(row_pointers));\n"
|
||||
SPACE "for (U32 y = 0; y < dim.height; y++) {\n"
|
||||
SPACE SPACE "row_pointers[dim.height - 1 - y] = ((png_bytep)buffer) + %u * dim.width * y;\n" /* sizeof_pixel */
|
||||
SPACE "}\n"
|
||||
SPACE "png_read_image(self.pngshka, row_pointers);\n"
|
||||
SPACE "png_read_end(self.pngshka, self.end_info);\n"
|
||||
SPACE "/* No more errors */\n"
|
||||
SPACE "png_destroy_read_struct(&self.pngshka, &self.info, &self.end_info);\n"
|
||||
SPACE "fclose(self.fp);\n"
|
||||
SPACE "free(row_pointers);\n"
|
||||
SPACE "return (ResultVoidOrVecU8){.variant = Result_Ok};\n"
|
||||
"}\n\n",
|
||||
promise, promise, promise, sizeof_pixel
|
||||
));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD Result%sOrVecU8 %s_finish_into_%s(%s self) {\n" /* tex, promise, tex, promise */
|
||||
SPACE "SizeOfRectangleU32 dim = %s_get_extent(&self);\n" /* promise */
|
||||
SPACE "if (dim.width >= UINT32_MAX / 10 || dim.height >= UINT32_MAX / 10) {\n"
|
||||
SPACE SPACE "return (Result%sOrVecU8){.variant = Result_Err, .err = vcstr(\"Input image is too big\")};\n" /* tex */
|
||||
SPACE "}\n"
|
||||
SPACE "%s tex = %s_new(dim.width, dim.height);\n" /* tex, tex */
|
||||
SPACE "ResultVoidOrVecU8 res = %s_finish(self, tex.pixels.buf);\n" /* promise */
|
||||
SPACE "if (res.variant == Result_Err) {\n"
|
||||
SPACE SPACE "%s_drop(tex);\n" /* tex */
|
||||
SPACE SPACE "return (Result%sOrVecU8){.variant = Result_Err, .err = res.err};\n" /* tex */
|
||||
SPACE "}\n"
|
||||
SPACE "return (Result%sOrVecU8){.variant = Result_Ok, .ok = tex};\n" /* tex */
|
||||
"}\n\n",
|
||||
tex, promise, tex, promise, promise, tex, tex, tex, promise, tex, tex, tex
|
||||
));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
|
||||
"/* aborts on error */\n"
|
||||
"NODISCARD %s %s_read_from_png_nofail(SpanU8 name) {\n" /* tex, tex */
|
||||
SPACE "Result%sOrVecU8 res_1 = %s_begin(name);\n" /* promise, promise */
|
||||
SPACE "if (res_1.variant == Result_Err) {\n"
|
||||
SPACE SPACE "SpanU8_fprint(VecU8_to_span(&res_1.err), stderr);\n"
|
||||
SPACE SPACE "abortf(\" MargaretPromisedPng_begin\\n\");\n"
|
||||
SPACE "}\n"
|
||||
SPACE "/* res_1 invalidated, we moved ownership to _finish methos */\n"
|
||||
SPACE "Result%sOrVecU8 res_2 = %s_finish_into_%s(res_1.ok);\n" /* tex, promise, tex */
|
||||
SPACE "if (res_2.variant == Result_Err) {\n"
|
||||
SPACE SPACE "SpanU8_fprint(VecU8_to_span(&res_2.err), stderr);\n"
|
||||
SPACE SPACE "abortf(\" MargaretPromisedPng_finish (into TextureData)\\n\");\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return res_2.ok;\n"
|
||||
"}\n\n",
|
||||
tex, tex, promise, promise, tex, promise, tex
|
||||
));
|
||||
|
||||
VecU8_drop(g_promise);
|
||||
VecU8_drop(g_tex);
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_margaret_png_pixel_masses_header() {
|
||||
GeneratedHeader header = begin_header(cstr("l1/margaret/png_pixel_masses.h"));
|
||||
|
||||
VecU8_append_span(&header.result, cstr(
|
||||
"#include \"../pixel_masses.h\"\n"
|
||||
"#include \"../ResultVoidOrVecU8.h\"\n"
|
||||
"#include <png.h>\n\n"));
|
||||
|
||||
VecU8_append_span(&header.result, cstr(
|
||||
"void margaret_libpng_h_error_cb(png_structp pngshka, png_const_charp err) {\n"
|
||||
SPACE "printf(\"[!] %s\\n\", err);\n"
|
||||
"}\n\n"
|
||||
"void margaret_libpng_h_warning_cb(png_structp pngshka, png_const_charp warning) {\n"
|
||||
SPACE "printf(\"[.] %s\\n\", warning);\n"
|
||||
"}\n\n"));
|
||||
|
||||
VecU8_append_vec(&header.result, generate_margaret_png_texture_data_methods(cstr("R8"), 8, 1));
|
||||
VecU8_append_vec(&header.result, generate_margaret_png_texture_data_methods(cstr("R8G8B8"), 8, 3));
|
||||
VecU8_append_vec(&header.result, generate_margaret_png_texture_data_methods(cstr("R8G8B8A8"), 8, 4));
|
||||
|
||||
finish_header(header);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -2,6 +2,7 @@
|
||||
#define PROTOTYPE_SRC_L1_CODEGEN_PIXEL_MASSES_H
|
||||
|
||||
#include "../codegen/codegen.h"
|
||||
#include "../codegen/util_template_inst.h"
|
||||
|
||||
/* Used to generate both _at() and _cat() methods */
|
||||
NODISCARD VecU8 generate_texture_data_method_at(SpanU8 tex, SpanU8 pixvec, SpanU8 memb, bool const_access) {
|
||||
@ -16,31 +17,26 @@ NODISCARD VecU8 generate_texture_data_method_at(SpanU8 tex, SpanU8 pixvec, SpanU
|
||||
|
||||
/* `tex` is the type name of texture data type
|
||||
* `memb` is the type name of pixel data type */
|
||||
NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8 memb) {
|
||||
NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8 memb, SpanU8 luminosity_formula) {
|
||||
VecU8 g_pixvec = VecU8_fmt("Vec%s", memb);
|
||||
SpanU8 pixvec = VecU8_to_span(&g_pixvec);
|
||||
|
||||
VecU8 res = VecU8_fmt(
|
||||
VecU8 res = VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "%s pixels;\n"
|
||||
SPACE "size_t width;\n"
|
||||
SPACE "size_t height;\n"
|
||||
"} %s;\n\n", pixvec, tex);
|
||||
/* Method _new() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s %s_new(U32 width, U32 height) {\n"
|
||||
SPACE "assert(!(SIZE_MAX / width / height < 100 || UINT32_MAX / width < 10 || UINT32_MAX / height < 10));\n"
|
||||
SPACE "return (%s){.pixels = %s_new_zeroinit((size_t)width * height), .width = width};\n"
|
||||
SPACE "return (%s){.pixels = %s_new_zeroinit((size_t)width * height), .width = width, .height = height};\n"
|
||||
"}\n\n", tex, tex, tex, pixvec));
|
||||
/* Method _drop() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n"
|
||||
SPACE "%s_drop(self.pixels);\n"
|
||||
"}\n\n", tex, tex, pixvec));
|
||||
/* Method _get_height() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"size_t %s_get_height(const %s* self) {\n"
|
||||
SPACE "return self->pixels.len / self->width;\n"
|
||||
"}\n\n", tex, tex));
|
||||
/* Methods _at and _cat */
|
||||
VecU8_append_vec(&res, generate_texture_data_method_at(tex, pixvec, memb, false));
|
||||
VecU8_append_vec(&res, generate_texture_data_method_at(tex, pixvec, memb, true));
|
||||
@ -76,17 +72,12 @@ NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8
|
||||
SPACE "write_whole_file_or_abort(path, VecU8_to_span(&data));\n"
|
||||
SPACE "VecU8_drop(data);\n"
|
||||
"}\n\n", tex, tex, tex));
|
||||
/* Result<texdatat, SpanU8> structure */
|
||||
VecU8 g_resoftex = VecU8_fmt("Result%sOrSpanU8", tex);
|
||||
/* Result<tex, SpanU8> structure */
|
||||
VecU8 g_resoftex = get_ResultType_inst_name(tex, cstr("SpanU8"));
|
||||
SpanU8 resoftex = VecU8_to_span(&g_resoftex);
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "Result_variant variant;\n"
|
||||
SPACE "union {\n"
|
||||
SPACE SPACE "%s ok;\n"
|
||||
SPACE SPACE "SpanU8 err;\n"
|
||||
SPACE "};\n"
|
||||
"} %s;\n\n", tex, resoftex));
|
||||
VecU8_append_vec(&res, generate_result_template_inst(tex, cstr("SpanU8"), false, true));
|
||||
/* I also add this, because why not?? Maye I will use it in the future... */
|
||||
VecU8_append_vec(&res, generate_result_template_inst(tex, cstr("VecU8"), false, false));
|
||||
/* Method _from_bitmap_text()
|
||||
* We assume that bytes are tightly packed in member type */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
@ -125,6 +116,34 @@ NODISCARD VecU8 generate_texture_data_struct_and_necc_methods(SpanU8 tex, SpanU8
|
||||
"bool %s_is_inside(const %s* self, S32 x, S32 y) {\n"
|
||||
SPACE "return x >= 0 && y >= 0 && x < (S32)self->width && self->width * y + x < self->pixels.len;\n"
|
||||
"}\n\n", tex, tex));
|
||||
/* Method _print() */
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_print(const %s* self) {\n" /* tex, tex */
|
||||
SPACE "U64 width = self->width;\n"
|
||||
SPACE "U64 height = self->height;\n"
|
||||
SPACE "U64 cell_width = MAX_U64(1, width / 190);\n"
|
||||
SPACE "U64 cell_height = MAX_U64(1, cell_width * 14 / 8);\n"
|
||||
SPACE "for (U64 CY = 0; CY < height; CY += cell_height) {\n"
|
||||
SPACE SPACE "for (U64 CX = 0; CX < width; CX += cell_width) {\n"
|
||||
SPACE SPACE SPACE "float lum = 0;\n"
|
||||
SPACE SPACE SPACE "for (U64 j = 0; j < cell_height; j++) {\n"
|
||||
SPACE SPACE SPACE SPACE "U64 y = CY + j;\n"
|
||||
SPACE SPACE SPACE SPACE "if (y >= height)\n"
|
||||
SPACE SPACE SPACE SPACE SPACE "continue;\n"
|
||||
SPACE SPACE SPACE SPACE "for (U64 i = 0; i < cell_width; i++) {\n"
|
||||
SPACE SPACE SPACE SPACE SPACE "U64 x = CX + i;\n"
|
||||
SPACE SPACE SPACE SPACE SPACE "if (x >= width)\n"
|
||||
SPACE SPACE SPACE SPACE SPACE SPACE "continue;\n"
|
||||
SPACE SPACE SPACE SPACE SPACE "%s pix = *%s_at(self, x, y);\n" /* memb, tex */
|
||||
SPACE SPACE SPACE SPACE SPACE "lum += %s;\n" /* luminosity_formula */
|
||||
SPACE SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE SPACE "}\n"
|
||||
SPACE SPACE SPACE "lum /= (float)cell_width * (float)cell_height;\n"
|
||||
SPACE SPACE SPACE "putc(lum > 0.95 ? '@' : (lum > 0.8 ? '#' : (lum > 0.65 ? '*' : (lum > 0.4 ? '_' : (lum > 0.2 ? '.' : ' ')))), stdout);\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE SPACE "putc('\\n', stdout);\n"
|
||||
SPACE "}\n"
|
||||
"}\n\n", tex, tex, memb, tex, luminosity_formula));
|
||||
|
||||
VecU8_drop(g_resoftex);
|
||||
VecU8_drop(g_pixvec);
|
||||
@ -137,9 +156,12 @@ void generate_pixel_masses_header() {
|
||||
VecU8_append_span(&res.result, cstr("#include \"../../src/l1/system/fileio.h\"\n"));
|
||||
VecU8_append_span(&res.result, cstr("#include \"VecAndSpan_cvec3.h\"\n"));
|
||||
VecU8_append_span(&res.result, cstr("#include \"VecAndSpan_cvec4.h\"\n\n"));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8"), cstr("U8")));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8"), cstr("cvec3")));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8A8"), cstr("cvec4")));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8"), cstr("U8"),
|
||||
cstr("(float)pix / 255")));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8"), cstr("cvec3"),
|
||||
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f")));
|
||||
VecU8_append_vec(&res.result, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8A8"), cstr("cvec4"),
|
||||
cstr("(float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f")));
|
||||
finish_header(res);
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,9 @@ void generate_headers_for_r0_r1_r2_r3() {
|
||||
/* r0_scene.h */
|
||||
generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("UsedGenericModelOnScene"), true, false);
|
||||
generate_eve_span_company_for_non_primitive_non_clonable(l, ns, cstr("UsedShinyModelOnScene"), true, false);
|
||||
/* r0 */
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("GenericModelTopAndTexInMemoryInfo"), true, false);
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("ShinyModelTopInMemoryInfo"), true, false);
|
||||
}
|
||||
mkdir_nofail("l1/eve/r2");
|
||||
{ /* r2 */
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
|
||||
#include "../codegen/util_template_inst.h"
|
||||
|
||||
// todo: split VecAndSpan_int_primitives into multiple files (one file per integer type)
|
||||
|
||||
/* These headers are guarded */
|
||||
void generate_util_temp_very_base_headers() {
|
||||
SpanU8 l = cstr("l1"), ns = cstr("");
|
||||
@ -52,6 +50,10 @@ void generate_util_temp_very_base_headers() {
|
||||
}
|
||||
generate_guarded_span_company_for_primitive(cstr("l1"), cstr(""),
|
||||
cstr("CSTR"), cstr(""), true, false);
|
||||
generate_guarded_header_of_result_type_instantiation(cstr("l1"), cstr(""),
|
||||
cstr(""), cstr("VecU8"), cstr("#include \"VecAndSpan_U8.h\""), true, false);
|
||||
generate_guarded_header_of_result_type_instantiation(cstr("l1"), cstr(""),
|
||||
cstr(""), cstr("SpanU8"), cstr("#include \"VecAndSpan_U8.h\""), true, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -41,6 +41,7 @@ void generate_util_templ_inst_for_vulkan_headers() {
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkSemaphore"), vulkan_dep, true, false);
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkDescriptorPoolSize"), vulkan_dep, true, false);
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkBufferCopy"), vulkan_dep, true, false);
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("VkImageMemoryBarrier"), vulkan_dep, true, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -550,6 +550,94 @@ void generate_guarded_span_company_for_non_primitive_non_clonable(
|
||||
});
|
||||
}
|
||||
|
||||
NODISCARD VecU8 get_ResultType_inst_name(SpanU8 OkT, SpanU8 ErrT){
|
||||
bool ok_t_void = OkT.len == 0;
|
||||
bool err_t_void = ErrT.len == 0;
|
||||
assert(!ok_t_void || !err_t_void);
|
||||
return VecU8_fmt("Result%s%s%s", !ok_t_void ? OkT : cstr("Void"),
|
||||
!err_t_void ? cstr("Or") : cstr(""), !err_t_void ? ErrT : cstr(""));
|
||||
}
|
||||
|
||||
/* We are talking about Result<OkT, ErrT> template instantiation */
|
||||
NODISCARD VecU8 generate_result_template_inst(SpanU8 OkT, SpanU8 ErrT, bool ok_t_primitive, bool err_t_primitive) {
|
||||
bool ok_t_void = OkT.len == 0;
|
||||
bool err_t_void = ErrT.len == 0;
|
||||
assert(!ok_t_void || !err_t_void);
|
||||
assert(!ok_t_void || ok_t_primitive);
|
||||
assert(!err_t_void || err_t_primitive);
|
||||
|
||||
VecU8 g_ResultT = get_ResultType_inst_name(OkT, ErrT);
|
||||
SpanU8 ResultT = VecU8_to_span(&g_ResultT);
|
||||
|
||||
VecU8 res = VecU8_new();
|
||||
|
||||
VecU8_append_span(&res, cstr(
|
||||
"typedef struct {\n"
|
||||
SPACE "Result_variant variant;\n"));
|
||||
if (ok_t_void && !err_t_void) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s err;\n", ErrT));
|
||||
} else if (!ok_t_void && err_t_void) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s ok;\n", OkT));
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "union {\n"
|
||||
SPACE SPACE "%s ok;\n"
|
||||
SPACE SPACE "%s err;\n"
|
||||
SPACE "};\n", OkT, ErrT));
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt("} %s;\n\n", ResultT));
|
||||
|
||||
if (!ok_t_primitive || !err_t_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_drop(%s self) {\n", ResultT, ResultT));
|
||||
if (ok_t_primitive && !err_t_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "if (self.variant == Result_Err)\n"
|
||||
SPACE SPACE "%s_drop(self.err);\n", ErrT));
|
||||
} else if (!ok_t_primitive && err_t_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "if (self.variant == Result_Ok)\n"
|
||||
SPACE SPACE "%s_drop(self.ok);\n", OkT));
|
||||
} else {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "if (self.variant == Result_Ok)\n"
|
||||
SPACE SPACE "%s_drop(self.ok);\n"
|
||||
SPACE "else\n"
|
||||
SPACE SPACE "%s_drop(self.err);\n", OkT, ErrT));
|
||||
}
|
||||
VecU8_append_span(&res, cstr("}\n\n"));
|
||||
}
|
||||
VecU8_drop(g_ResultT); /* ResultT variable invalidated */
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_eve_header_of_result_type_instantiation(
|
||||
SpanU8 l, SpanU8 ns, SpanU8 OkT, SpanU8 ErrT, bool ok_t_primitive, bool err_t_primitive
|
||||
) {
|
||||
VecU8 ResultT = get_ResultType_inst_name(OkT, ErrT);
|
||||
VecU8 nt_filepath = VecU8_fmt("%s/eve/%s/%s.h%c", l, ns, VecU8_to_span(&ResultT), 0);
|
||||
VecU8 text = generate_result_template_inst(OkT, ErrT, ok_t_primitive, err_t_primitive);
|
||||
write_whole_file_or_abort((CSTR)text.buf, VecU8_to_span(&text));
|
||||
VecU8_drop(text);
|
||||
VecU8_drop(nt_filepath);
|
||||
VecU8_drop(ResultT);
|
||||
}
|
||||
|
||||
void generate_guarded_header_of_result_type_instantiation(
|
||||
SpanU8 layer, SpanU8 bonus_ns, SpanU8 OkT, SpanU8 ErrT, SpanU8 dependencies, bool ok_t_primitive, bool err_t_primitive
|
||||
){
|
||||
assert(layer.len > 1);
|
||||
VecU8 filename = get_ResultType_inst_name(OkT, ErrT);
|
||||
VecU8 path = VecU8_fmt("%s/%s%s%s.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""), VecU8_to_span(&filename));
|
||||
GeneratedHeader head = begin_header(VecU8_to_span(&path));
|
||||
VecU8_append_span(&head.result, dependencies);
|
||||
VecU8_append_span(&head.result, cstr("\n\n"));
|
||||
VecU8_append_vec(&head.result, generate_result_template_inst(OkT, ErrT, ok_t_primitive, err_t_primitive));
|
||||
finish_header(head);
|
||||
VecU8_drop(path);
|
||||
VecU8_drop(filename);
|
||||
}
|
||||
|
||||
typedef struct{
|
||||
SpanU8 T;
|
||||
bool t_ptr;
|
||||
@ -636,6 +724,7 @@ void generate_Option_templ_inst_guarded_header(
|
||||
VecU8 path = VecU8_fmt("%s/%s%sOption%s.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""), op.T);
|
||||
GeneratedHeader head = begin_header(VecU8_to_span(&path));
|
||||
VecU8_drop(path);
|
||||
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../"));
|
||||
int to_my_layer = get_number_of_parts_in_header_namespace(bonus_ns);
|
||||
for (int i = 0; i < to_my_layer; i++)
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef uint8_t U8;
|
||||
typedef uint16_t U16;
|
||||
|
||||
29
src/l1/core/uint_segments.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef prototype1_src_l1_core_uint_segments_h
|
||||
#define prototype1_src_l1_core_uint_segments_h
|
||||
|
||||
#include "int_primitives.h"
|
||||
|
||||
typedef struct {
|
||||
U64 start;
|
||||
U64 len;
|
||||
} U64Segment;
|
||||
|
||||
bool U64Segment_equal_U64Segment(const U64Segment* A, const U64Segment* B){
|
||||
return A->start == B->start && A->len == B->len;
|
||||
}
|
||||
|
||||
bool U64Segment_equal_by_start(const U64Segment* A, const U64Segment* B){
|
||||
return A->start == B->start;
|
||||
}
|
||||
|
||||
bool U64Segment_less_by_start(const U64Segment* A, const U64Segment* B){
|
||||
return A->start < B->start;
|
||||
}
|
||||
|
||||
bool U64Segment_less_by_len_and_start(const U64Segment* A, const U64Segment* B){
|
||||
if (A->len == B->len)
|
||||
return A->start < B->start;
|
||||
return A->len < B->len;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -2,7 +2,6 @@
|
||||
#define PROTOTYPE1_SRC_CORE_UTIL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
@ -54,6 +54,13 @@ typedef struct {
|
||||
vec2 v2;
|
||||
} MarieTriangle;
|
||||
|
||||
MarieTriangle MarieTriangle_mat3x2_mul_pos(MarieTriangle self, mat3x2 trop) {
|
||||
return (MarieTriangle){
|
||||
.v0 = mat3x2_mul_vec3(trop, vec2_and_one(self.v0)),
|
||||
.v1 = mat3x2_mul_vec3(trop, vec2_and_one(self.v1)),
|
||||
.v2 = mat3x2_mul_vec3(trop, vec2_and_one(self.v2))};
|
||||
}
|
||||
|
||||
#include "../../../gen/l1/eve/marie/VecMarieTriangle.h"
|
||||
|
||||
typedef struct {
|
||||
@ -62,6 +69,14 @@ typedef struct {
|
||||
MariePlaneVertAttr v2;
|
||||
} MarieTriangleAttr;
|
||||
|
||||
MarieTriangleAttr MarieTriangle_goto_nat_cords_pres_par(MarieTriangle self, mat3x2 trop) {
|
||||
return (MarieTriangleAttr){
|
||||
{mat3x2_mul_vec3(trop, vec2_and_one(self.v0)), {self.v0.x, self.v0.y, 0, 0}},
|
||||
{mat3x2_mul_vec3(trop, vec2_and_one(self.v1)), {self.v1.x, self.v1.y, 0, 0}},
|
||||
{mat3x2_mul_vec3(trop, vec2_and_one(self.v2)), {self.v2.x, self.v2.y, 0, 0}},
|
||||
};
|
||||
}
|
||||
|
||||
#include "../../../gen/l1/eve/marie/VecMarieTriangleAttr.h"
|
||||
|
||||
vec2 marie_intersect_lines(vec2 A1, vec2 B1, vec2 A2, vec2 B2) {
|
||||
|
||||
@ -4,12 +4,33 @@
|
||||
#include "../codegen/rb_tree_set_map_template_inst.h"
|
||||
|
||||
void generate_l1_5_template_instantiation_for_base_types(){
|
||||
SpanU8 l = cstr("l1_5");
|
||||
SpanU8 ns = cstr("");
|
||||
SpanU8 l = cstr("l1_5"), ns = cstr("");
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../l1/VecAndSpan_U64.h\""),
|
||||
(set_instantiation_op){.T = cstr("U64"), .t_integer = true});
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../l1/VecAndSpan_S64.h\""),
|
||||
(set_instantiation_op){.T = cstr("S64"), .t_integer = true});
|
||||
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns,
|
||||
cstr("#include \"../l1/VecAndSpan_U64.h\""),
|
||||
(set_instantiation_op){.T = cstr("U64"), .t_integer = true});
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns,
|
||||
cstr("#include \"../l1/VecAndSpan_S64.h\""),
|
||||
(set_instantiation_op){.T = cstr("S64"), .t_integer = true});
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
|
||||
(set_instantiation_op){
|
||||
.T = cstr("U64Segment"),
|
||||
.t_primitive = true,
|
||||
.alternative_equal = cstr("U64Segment_equal_by_start"),
|
||||
.alternative_less = cstr("U64Segment_less_by_start"),
|
||||
.alternative_comp_set_name_embed = cstr("Start")
|
||||
});
|
||||
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
|
||||
(set_instantiation_op){
|
||||
.T = cstr("U64Segment"),
|
||||
.t_primitive = true,
|
||||
.alternative_less = cstr("U64Segment_less_by_len_and_start"),
|
||||
.alternative_comp_set_name_embed = cstr("LenAndStart")
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -3,8 +3,6 @@
|
||||
|
||||
#include "../../l1/codegen/util_template_inst.h"
|
||||
|
||||
// todo: continue from here
|
||||
|
||||
/* We assume that T is trivially movable */
|
||||
typedef struct {
|
||||
SpanU8 T;
|
||||
@ -12,16 +10,26 @@ typedef struct {
|
||||
bool t_integer;
|
||||
bool t_primitive;
|
||||
bool t_clonable;
|
||||
SpanU8 alternative_equal;
|
||||
SpanU8 alternative_less;
|
||||
SpanU8 alternative_comp_set_name_embed;
|
||||
} set_instantiation_op;
|
||||
|
||||
void set_instantiation_op_fix(set_instantiation_op* self){
|
||||
assert(self->T.len > 0);
|
||||
if (self->t_ptr)
|
||||
self->t_integer = true;
|
||||
if (self->t_integer)
|
||||
self->t_primitive = true;
|
||||
if (self->t_primitive)
|
||||
self->t_clonable = true;
|
||||
assert(self->T.len > 0);
|
||||
assert(!self->t_integer || self->alternative_equal.len == 0);
|
||||
assert(!self->t_integer || self->alternative_less.len == 0);
|
||||
assert((self->alternative_less.len == 0 && self->alternative_equal.len == 0
|
||||
&& self->alternative_comp_set_name_embed.len == 0
|
||||
)||(
|
||||
self->alternative_comp_set_name_embed.len != 0 &&
|
||||
(self->alternative_less.len != 0 || self->alternative_equal.len != 0)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_value_NOT_EQUAL_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key != self->el.buf[cur - 1]");
|
||||
if (op.alternative_equal.len != 0)
|
||||
return VecU8_fmt("!%s(&key, &self->el.buf[cur - 1])", op.alternative_equal);
|
||||
return VecU8_fmt("!%s_equal_%s(&key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
@ -14,6 +16,8 @@ NODISCARD VecU8 codegen_rb_tree_set_key_value_NOT_EQUAL_element(set_instantiatio
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_value_LESS_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key < self->el.buf[cur - 1]");
|
||||
if (op.alternative_less.len != 0)
|
||||
return VecU8_fmt("%s(&key, &self->el.buf[cur - 1])", op.alternative_less);
|
||||
return VecU8_fmt("%s_less_%s(&key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
@ -22,6 +26,8 @@ NODISCARD VecU8 codegen_rb_tree_set_key_value_LESS_element(set_instantiation_op
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_ref_NOT_EQUAL_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key != self->el.buf[cur - 1]");
|
||||
if (op.alternative_equal.len != 0)
|
||||
return VecU8_fmt("!%s(key, &self->el.buf[cur - 1])", op.alternative_equal);
|
||||
return VecU8_fmt("!%s_equal_%s(key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
@ -29,6 +35,8 @@ NODISCARD VecU8 codegen_rb_tree_set_key_ref_NOT_EQUAL_element(set_instantiation_
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_ref_EQUAL_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key == self->el.buf[cur - 1]");
|
||||
if (op.alternative_equal.len != 0)
|
||||
return VecU8_fmt("%s(key, &self->el.buf[cur - 1])", op.alternative_equal);
|
||||
return VecU8_fmt("%s_equal_%s(ref, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
@ -36,6 +44,8 @@ NODISCARD VecU8 codegen_rb_tree_set_key_ref_EQUAL_element(set_instantiation_op o
|
||||
NODISCARD VecU8 codegen_rb_tree_set_key_ref_LESS_element(set_instantiation_op op){
|
||||
if (op.t_integer)
|
||||
return VecU8_fmt("key < self->el.buf[cur - 1]");
|
||||
if (op.alternative_less.len != 0)
|
||||
return VecU8_fmt("%s(key, &self->el.buf[cur - 1])", op.alternative_less);
|
||||
return VecU8_fmt("%s_less_%s(key, &self->el.buf[cur - 1])", op.T, op.T);
|
||||
}
|
||||
|
||||
@ -86,6 +96,12 @@ NODISCARD VecU8 codegen_rb_tree_set_taking_ref_t_argument(set_instantiation_op o
|
||||
return !op.t_integer ? VecU8_fmt("const %s*", op.T) : VecU8_from_span(op.T);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 get_name_of_rb_tree_set_structure(set_instantiation_op op){
|
||||
if (op.alternative_comp_set_name_embed.len)
|
||||
return VecU8_fmt("BuffRBTreeBy%s_Set%s", op.alternative_comp_set_name_embed, op.T);
|
||||
return VecU8_fmt("BuffRBTree_Set%s", op.T);
|
||||
}
|
||||
|
||||
/* Generates methods _insert() _pop_substitute() _erase_substitute() for SetT
|
||||
* Takes ownership of strings Tc, Fc */
|
||||
void codegen_append_rb_tree_set_insert_kind_method(
|
||||
@ -223,7 +239,7 @@ void codegen_append_rb_tree_set_erase_kind_method(
|
||||
NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op op){
|
||||
set_instantiation_op_fix(&op);
|
||||
VecU8 res = VecU8_new();
|
||||
VecU8 g_set = VecU8_fmt("BuffRBTree_Set%s", op.T);
|
||||
VecU8 g_set = get_name_of_rb_tree_set_structure(op);
|
||||
SpanU8 set = VecU8_to_span(&g_set);
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
@ -294,7 +310,7 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find(const %s* self, %v key) {\n" /* set, set taking_ref_t_argument */
|
||||
"U64 %s_find(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0 && %v) {\n" /* key reference not equal cur element */
|
||||
SPACE SPACE "if (%v) {\n" /* key reference less than cue element */
|
||||
@ -379,20 +395,111 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
|
||||
SPACE "return self->root != 0 ? RBTree_maximum_in_subtree(self->tree.buf, self->root) : 0;\n"
|
||||
"}\n\n", set, set));
|
||||
|
||||
// todo: continue from here. Implement method _pop_and_substitute()
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find_max_less(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 last_less = 0;\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0) {\n"
|
||||
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE SPACE "if (cur == 0)\n"
|
||||
SPACE SPACE SPACE SPACE "return last_less;\n"
|
||||
SPACE SPACE SPACE "while (self->tree.buf[cur].right != 0)\n"
|
||||
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE SPACE "return cur;\n"
|
||||
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "last_less = cur;\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return last_less;\n"
|
||||
"}\n\n",
|
||||
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
|
||||
codegen_rb_tree_set_key_ref_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_ref_LESS_element(op)
|
||||
));
|
||||
|
||||
// todo: All the other methods are secondary in importance
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find_max_less_or_eq(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 last_less = 0;\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0) {\n"
|
||||
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
|
||||
SPACE SPACE SPACE "return cur;\n"
|
||||
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "last_less = cur;\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return last_less;\n"
|
||||
"}\n\n",
|
||||
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
|
||||
codegen_rb_tree_set_key_ref_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_ref_LESS_element(op)
|
||||
));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find_min_grtr(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 last_grtr = 0;\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0) {\n"
|
||||
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE SPACE "if (cur == 0)\n"
|
||||
SPACE SPACE SPACE SPACE "return last_grtr;\n"
|
||||
SPACE SPACE SPACE "while (self->tree.buf[cur].left != 0)\n"
|
||||
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE SPACE "return cur;\n"
|
||||
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
|
||||
SPACE SPACE SPACE "last_grtr = cur;\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return last_grtr;\n"
|
||||
"}\n\n",
|
||||
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
|
||||
codegen_rb_tree_set_key_ref_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_ref_LESS_element(op)
|
||||
));
|
||||
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"U64 %s_find_min_grtr_or_eq(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
|
||||
SPACE "U64 last_grtr = 0;\n"
|
||||
SPACE "U64 cur = self->root;\n"
|
||||
SPACE "while (cur != 0) {\n"
|
||||
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
|
||||
SPACE SPACE SPACE "return cur;\n"
|
||||
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
|
||||
SPACE SPACE SPACE "last_grtr = cur;\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
|
||||
SPACE SPACE "} else {\n"
|
||||
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
|
||||
SPACE SPACE "}\n"
|
||||
SPACE "}\n"
|
||||
SPACE "return last_grtr;\n"
|
||||
"}\n\n",
|
||||
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
|
||||
codegen_rb_tree_set_key_ref_EQUAL_element(op),
|
||||
codegen_rb_tree_set_key_ref_LESS_element(op)
|
||||
));
|
||||
|
||||
VecU8_drop(g_set);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void generate_rb_tree_Set_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, option_template_instantiation_op op) {
|
||||
void generate_rb_tree_Set_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, set_instantiation_op op) {
|
||||
VecU8 text = VecU8_from_cstr("/* Automatically generated file. Do not edit it.\n"
|
||||
" * Do not include it in more than one place */\n\n");
|
||||
VecU8_append_vec(&text, generate_OptionT_struct_and_methods(op));
|
||||
VecU8 nt_path = VecU8_fmt("%s/eve/%s/BuffRBTree_Set%s%c", layer, bonus_ns, op.T, 0);
|
||||
VecU8_append_vec(&text, generate_rb_tree_Set_template_instantiation(op));
|
||||
VecU8 nt_path = VecU8_fmt("%s/eve/%s/%s.h%c", layer, bonus_ns, op.T, get_name_of_rb_tree_set_structure(op));
|
||||
write_whole_file_or_abort((const char*)nt_path.buf, VecU8_to_span(&text));
|
||||
VecU8_drop(nt_path);
|
||||
VecU8_drop(text);
|
||||
@ -402,7 +509,8 @@ void generate_rb_tree_Set_templ_inst_guarded_header(
|
||||
SpanU8 layer, SpanU8 bonus_ns, SpanU8 dependencies, set_instantiation_op op
|
||||
){
|
||||
assert(layer.len > 1);
|
||||
VecU8 path = VecU8_fmt("%s/%s%sBuffRBTree_Set%s.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""), op.T);
|
||||
VecU8 path = VecU8_fmt("%s/%s%s%v.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""),
|
||||
get_name_of_rb_tree_set_structure(op));
|
||||
GeneratedHeader head = begin_header(VecU8_to_span(&path));
|
||||
VecU8_drop(path);
|
||||
VecU8_append_span(&head.result, cstr("#include \"../../"));
|
||||
|
||||
@ -42,12 +42,13 @@ NODISCARD VecU8 generate_trait_table_structure(NamedTraitDefRecordRef trait){
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NamedTraitDefRecordRef trait;
|
||||
bool box;
|
||||
bool ref;
|
||||
bool mut_ref;
|
||||
} trait_wrapper_boil_options;
|
||||
|
||||
NODISCARD VecU8 generate_trait_wrapper_boilerplate(NamedTraitDefRecordRef trait, trait_wrapper_boil_options op) {
|
||||
NODISCARD VecU8 generate_trait_wrapper_boilerplate(trait_wrapper_boil_options op) {
|
||||
VecU8 res = VecU8_new();
|
||||
// todo: write it
|
||||
return res;
|
||||
|
||||
@ -121,7 +121,7 @@ void RBTree_steal_neighbours(RBTreeNode* tree, U64* root, U64 fr, U64 to){
|
||||
/* helper function (used in _erase, _find_min methods). It is assumed that s is not null.
|
||||
* Guaranteed to return no-null
|
||||
*/
|
||||
U64 RBTree_minimum_in_subtree(RBTreeNode* tree, U64 s){
|
||||
U64 RBTree_minimum_in_subtree(const RBTreeNode* tree, U64 s){
|
||||
assert(s != 0);
|
||||
while (tree[s].left != 0)
|
||||
s = tree[s].left;
|
||||
@ -131,7 +131,7 @@ U64 RBTree_minimum_in_subtree(RBTreeNode* tree, U64 s){
|
||||
/* helper function (used in _find_max, _find_prev methods). It is assumed that s is not null.
|
||||
* Guaranteed to return no-null
|
||||
*/
|
||||
U64 RBTree_maximum_in_subtree(RBTreeNode* tree, U64 s){
|
||||
U64 RBTree_maximum_in_subtree(const RBTreeNode* tree, U64 s){
|
||||
assert(s != 0);
|
||||
while (tree[s].right != 0)
|
||||
s = tree[s].right;
|
||||
|
||||
@ -1,254 +0,0 @@
|
||||
#ifndef PROTOTYPE1_SRC_L2_MARGARET_PNG_PIXEL_MASSES_H
|
||||
#define PROTOTYPE1_SRC_L2_MARGARET_PNG_PIXEL_MASSES_H
|
||||
|
||||
#include "../../../gen/l1/pixel_masses.h"
|
||||
#include "../../l1/core/util.h"
|
||||
#include "../../l1/core/VecU8_as_str.h"
|
||||
#include <png.h>
|
||||
|
||||
// todo: generate all of this automaticcally
|
||||
|
||||
void margaret_libpng_h_error_cb(png_structp pngshka, png_const_charp err) {
|
||||
printf("[!] %s\n", err);
|
||||
}
|
||||
|
||||
void margaret_libpng_h_warning_cb(png_structp pngshka, png_const_charp warning) {
|
||||
printf("[.] %s\n", warning);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Result_variant variant;
|
||||
VecU8 err;
|
||||
} ResultVoidOrVecU8;
|
||||
|
||||
void ResultVoidOrVecU8_drop(ResultVoidOrVecU8 self) {
|
||||
if (self.variant == Result_Err)
|
||||
VecU8_drop(self.err);
|
||||
}
|
||||
|
||||
ResultVoidOrVecU8 TextureDataR8G8B8A8_write_to_png(const TextureDataR8G8B8A8* self, SpanU8 filename) {
|
||||
VecU8 nt_filename = VecU8_fmt("%s%c", filename, 0);
|
||||
FILE *fp = fopen((CSTR)nt_filename.buf, "wb");
|
||||
VecU8_drop(nt_filename);
|
||||
if (!fp) {
|
||||
return (ResultVoidOrVecU8){.variant = Result_Err, .err = VecU8_fmt("Unable to open file %s", filename)};
|
||||
}
|
||||
png_structp pngshka = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, margaret_libpng_h_error_cb, margaret_libpng_h_warning_cb);
|
||||
if (!pngshka)
|
||||
abortf("png_create_write_struct");
|
||||
png_infop info = png_create_info_struct(pngshka);
|
||||
if (!info)
|
||||
abortf("png_create_info_struct");
|
||||
|
||||
png_bytep* row_pointers = NULL;
|
||||
|
||||
if (setjmp(png_jmpbuf(pngshka))){
|
||||
png_destroy_write_struct(&pngshka, &info);
|
||||
fclose(fp);
|
||||
free(row_pointers);
|
||||
return (ResultVoidOrVecU8){.variant = Result_Err, .err = VecU8_from_cstr("Some png error happened")};
|
||||
}
|
||||
png_init_io(pngshka, fp);
|
||||
|
||||
U32 width = self->width;
|
||||
U32 height = TextureDataR8G8B8A8_get_height(self);
|
||||
|
||||
png_set_IHDR(pngshka, info, width, height, 8, PNG_COLOR_TYPE_RGBA,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
row_pointers = calloc(height, sizeof(row_pointers));
|
||||
for (U32 y = 0; y < height; y++) {
|
||||
row_pointers[height - 1 - y] = (png_bytep)((TextureDataR8G8B8A8_at(self, 0, y)));
|
||||
}
|
||||
png_set_rows(pngshka, info, row_pointers);
|
||||
png_write_png(pngshka, info, 0, NULL);
|
||||
/* No more errors */
|
||||
free(row_pointers);
|
||||
png_destroy_write_struct(&pngshka, &info);
|
||||
fclose(fp);
|
||||
return (ResultVoidOrVecU8){.variant = Result_Ok};
|
||||
}
|
||||
|
||||
/* Aborts on error */
|
||||
void TextureDataR8G8B8A8_write_to_png_nofail(const TextureDataR8G8B8A8* self, SpanU8 filename) {
|
||||
ResultVoidOrVecU8 res = TextureDataR8G8B8A8_write_to_png(self, filename);
|
||||
if (res.variant == Result_Err) {
|
||||
SpanU8_fprint(VecU8_to_span(&res.err), stderr);
|
||||
abortf(" TextureDataR8G8B8A8_write_to_png\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* This structure will be pinned */
|
||||
typedef struct {
|
||||
FILE* fp;
|
||||
png_structp pngshka;
|
||||
png_infop info;
|
||||
png_infop end_info;
|
||||
} MargaretPromisedPngR8G8B8A8;
|
||||
|
||||
void MargaretPromisedPngR8G8B8A8_drop(MargaretPromisedPngR8G8B8A8 self) {
|
||||
png_destroy_read_struct(&self.pngshka, &self.info, &self.end_info);
|
||||
fclose(self.fp);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Result_variant variant;
|
||||
union {
|
||||
MargaretPromisedPngR8G8B8A8 ok;
|
||||
VecU8 err;
|
||||
};
|
||||
} ResultMargaretPromisedPngR8G8B8A8OrVecU8;
|
||||
|
||||
void ResultMargaretPromisedPngR8G8B8A8OrVecU8_drop(ResultMargaretPromisedPngR8G8B8A8OrVecU8 self) {
|
||||
if (self.variant == Result_Ok)
|
||||
MargaretPromisedPngR8G8B8A8_drop(self.ok);
|
||||
else
|
||||
VecU8_drop(self.err);
|
||||
}
|
||||
|
||||
ResultMargaretPromisedPngR8G8B8A8OrVecU8 MargaretPromisedPngR8G8B8A8_begin(SpanU8 filename) {
|
||||
VecU8 nt_filename = VecU8_fmt("%s%c", filename, 0);
|
||||
FILE* fp = fopen((CSTR)nt_filename.buf, "rb");
|
||||
VecU8_drop(nt_filename);
|
||||
if (!fp) {
|
||||
return (ResultMargaretPromisedPngR8G8B8A8OrVecU8){.variant = Result_Err,
|
||||
.err = VecU8_fmt("Unable to open file %s", filename)};
|
||||
}
|
||||
png_structp pngshka = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, margaret_libpng_h_error_cb, margaret_libpng_h_warning_cb);
|
||||
if (!pngshka)
|
||||
abortf("png_create_read_struct");
|
||||
png_infop info = png_create_info_struct(pngshka);
|
||||
if (!info)
|
||||
abortf("png_create_info_struct");
|
||||
png_infop end_info = png_create_info_struct(pngshka);
|
||||
if (!end_info)
|
||||
abortf("png_create_info_struct");
|
||||
if (setjmp(png_jmpbuf(pngshka))) {
|
||||
png_destroy_read_struct(&pngshka, &info, &end_info);
|
||||
fclose(fp);
|
||||
return (ResultMargaretPromisedPngR8G8B8A8OrVecU8){.variant = Result_Err,
|
||||
.err = VecU8_from_cstr("Some png error happened")};
|
||||
}
|
||||
png_init_io(pngshka, fp);
|
||||
png_read_info(pngshka, info);
|
||||
U32 width, height;
|
||||
int bit_depth, color_type;
|
||||
assert(png_get_IHDR(pngshka, info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL));
|
||||
|
||||
if (bit_depth == 16) {
|
||||
png_set_strip_16(pngshka);
|
||||
}
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY) {
|
||||
if (bit_depth == 1 || bit_depth == 2 || bit_depth == 4) {
|
||||
png_set_expand_gray_1_2_4_to_8(pngshka);
|
||||
}
|
||||
png_set_gray_to_rgb(pngshka);
|
||||
if (png_get_valid(pngshka, info, PNG_INFO_tRNS)) {
|
||||
png_set_tRNS_to_alpha(pngshka);
|
||||
} else {
|
||||
png_set_add_alpha(pngshka, 0xFF, PNG_FILLER_AFTER);
|
||||
}
|
||||
} else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
|
||||
png_set_gray_to_rgb(pngshka);
|
||||
} else if (color_type == PNG_COLOR_TYPE_RGB) {
|
||||
if (png_get_valid(pngshka, info, PNG_INFO_tRNS)) {
|
||||
png_set_tRNS_to_alpha(pngshka);
|
||||
} else {
|
||||
png_set_add_alpha(pngshka, 0xFF, PNG_FILLER_AFTER);
|
||||
}
|
||||
} else if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
png_set_palette_to_rgb(pngshka);
|
||||
|
||||
if (png_get_valid(pngshka, info, PNG_INFO_tRNS)) {
|
||||
png_set_tRNS_to_alpha(pngshka);
|
||||
} else {
|
||||
png_set_add_alpha(pngshka, 0xFF, PNG_FILLER_AFTER);
|
||||
}
|
||||
}
|
||||
png_read_update_info(pngshka, info);
|
||||
|
||||
return (ResultMargaretPromisedPngR8G8B8A8OrVecU8){.variant = Result_Ok,
|
||||
.ok = (MargaretPromisedPngR8G8B8A8){.fp = fp, .pngshka = pngshka, .info = info, .end_info = end_info}};
|
||||
}
|
||||
|
||||
SizeOfRectangleU32 MargaretPromisedPngR8G8B8A8_get_extent(const MargaretPromisedPngR8G8B8A8* self) {
|
||||
U32 width, height;
|
||||
int bit_depth, color_type;
|
||||
assert(png_get_IHDR(self->pngshka, self->info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL));
|
||||
return (SizeOfRectangleU32){width, height};
|
||||
}
|
||||
|
||||
|
||||
size_t MargaretPromisedPngR8G8B8A8_get_needed_buffer_size(const MargaretPromisedPngR8G8B8A8* self) {
|
||||
SizeOfRectangleU32 dim = MargaretPromisedPngR8G8B8A8_get_extent(self);
|
||||
return 4 * dim.width * dim.height;
|
||||
}
|
||||
|
||||
ResultVoidOrVecU8 MargaretPromisedPngR8G8B8A8_finish(MargaretPromisedPngR8G8B8A8 self, void* buffer) {
|
||||
SizeOfRectangleU32 dim = MargaretPromisedPngR8G8B8A8_get_extent(&self);
|
||||
|
||||
png_bytep* row_pointers = NULL;
|
||||
if (setjmp(png_jmpbuf(self.pngshka))) {
|
||||
png_destroy_read_struct(&self.pngshka, &self.info, &self.end_info);
|
||||
fclose(self.fp);
|
||||
free(row_pointers);
|
||||
return (ResultVoidOrVecU8){.variant = Result_Err, .err = VecU8_from_cstr("Some png error happened")};
|
||||
}
|
||||
|
||||
row_pointers = calloc(dim.height, sizeof(row_pointers));
|
||||
for (U32 y = 0; y < dim.height; y++) {
|
||||
row_pointers[dim.height - 1 - y] = ((png_bytep)buffer) + 4 * dim.width * y;
|
||||
}
|
||||
png_read_image(self.pngshka, row_pointers);
|
||||
png_read_end(self.pngshka, self.end_info);
|
||||
/* No more errors */
|
||||
png_destroy_read_struct(&self.pngshka, &self.info, &self.end_info);
|
||||
fclose(self.fp);
|
||||
free(row_pointers);
|
||||
return (ResultVoidOrVecU8){.variant = Result_Ok};
|
||||
}
|
||||
|
||||
// todo: move it to pixel_masses.h (and also generate result types automatically
|
||||
typedef struct {
|
||||
Result_variant variant;
|
||||
union {
|
||||
TextureDataR8G8B8A8 ok;
|
||||
VecU8 err;
|
||||
};
|
||||
} ResultTextureDataR8G8B8A8OrVecU8;
|
||||
|
||||
void ResultTextureDataR8G8B8A8OrVecU8_drop(ResultTextureDataR8G8B8A8OrVecU8 self) {
|
||||
if (self.variant == Result_Ok)
|
||||
TextureDataR8G8B8A8_drop(self.ok);
|
||||
else
|
||||
VecU8_drop(self.err);
|
||||
}
|
||||
|
||||
ResultTextureDataR8G8B8A8OrVecU8 MargaretPromisedPngR8G8B8A8_finish_into_TextureDataR8G8B8A8(MargaretPromisedPngR8G8B8A8 self) {
|
||||
SizeOfRectangleU32 dim = MargaretPromisedPngR8G8B8A8_get_extent(&self);
|
||||
TextureDataR8G8B8A8 tex = TextureDataR8G8B8A8_new(dim.width, dim.height);
|
||||
ResultVoidOrVecU8 res = MargaretPromisedPngR8G8B8A8_finish(self, tex.pixels.buf);
|
||||
if (res.variant == Result_Err)
|
||||
return (ResultTextureDataR8G8B8A8OrVecU8){.variant = Result_Err, .err = res.err};
|
||||
return (ResultTextureDataR8G8B8A8OrVecU8){.variant = Result_Ok, .ok = tex};
|
||||
}
|
||||
|
||||
/* aborts on error */
|
||||
TextureDataR8G8B8A8 TextureDataR8G8B8A8_read_from_png_nofail(SpanU8 name) {
|
||||
ResultMargaretPromisedPngR8G8B8A8OrVecU8 res_1 = MargaretPromisedPngR8G8B8A8_begin(name);
|
||||
if (res_1.variant == Result_Err) {
|
||||
SpanU8_fprint(VecU8_to_span(&res_1.err), stderr);
|
||||
abortf(" MargaretPromisedPngR8G8B8A8_begin\n");
|
||||
}
|
||||
/* res_1 invalidated, we moved ownership to _finish methos */
|
||||
ResultTextureDataR8G8B8A8OrVecU8 res_2 = MargaretPromisedPngR8G8B8A8_finish_into_TextureDataR8G8B8A8(res_1.ok);
|
||||
if (res_2.variant == Result_Err) {
|
||||
SpanU8_fprint(VecU8_to_span(&res_2.err), stderr);
|
||||
abortf(" MargaretPromisedPngR8G8B8A8_finish (into TextureData)\n");
|
||||
}
|
||||
return res_2.ok;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1027,6 +1027,11 @@ MargaretImageInMemoryInfo margaret_prep_image_mem_info_of_gpu_texture_srgba(uint
|
||||
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT };
|
||||
}
|
||||
|
||||
MargaretImageInMemoryInfo margaret_prep_image_mem_info_of_gpu_texture_unorm_8(uint32_t w, uint32_t h){
|
||||
return (MargaretImageInMemoryInfo){ .width = w, .height = h, .format = VK_FORMAT_R8_UNORM,
|
||||
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT };
|
||||
}
|
||||
|
||||
MargaretImageInMemoryInfo margaret_prep_image_mem_info_of_gpu_texture_unorm_32(uint32_t w, uint32_t h) {
|
||||
return (MargaretImageInMemoryInfo){ .width = w, .height = h, .format = VK_FORMAT_R8G8B8A8_UNORM,
|
||||
.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT };
|
||||
@ -1103,98 +1108,107 @@ void margaret_copy_buffer_imm (
|
||||
margaret_end_and_submit_and_free_command_buffer(device, command_pool, graphics_queue, cmd_buffer);
|
||||
}
|
||||
|
||||
// todo: get rid of this crap. I can do better
|
||||
// For application initialization purposes only
|
||||
void transition_image_layout (
|
||||
VkDevice device, VkCommandPool command_pool, VkQueue graphics_queue,
|
||||
VkImage image, VkImageLayout old_layout, VkImageLayout new_layout,
|
||||
VkPipelineStageFlags src_stage_mask, VkAccessFlags src_access_mask,
|
||||
VkPipelineStageFlags dst_stage_mask, VkAccessFlags dst_access_mask
|
||||
) {
|
||||
VkCommandBuffer cmd_buffer = margaret_alloc_and_begin_single_use_command_buffer(device, command_pool);
|
||||
VkImageMemoryBarrier barrier = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = src_access_mask,
|
||||
.dstAccessMask = dst_access_mask,
|
||||
.oldLayout = old_layout,
|
||||
.newLayout = new_layout,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = image,
|
||||
.subresourceRange = (VkImageSubresourceRange){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
};
|
||||
vkCmdPipelineBarrier(cmd_buffer, src_stage_mask, dst_stage_mask,
|
||||
// Flags
|
||||
0,
|
||||
0, NULL,
|
||||
0, NULL,
|
||||
1, &barrier
|
||||
typedef struct {
|
||||
size_t host_mem_buff_offset;
|
||||
const MargaretImageInMemoryInfo* dst_image;
|
||||
} MargaretCommandForImageCopying;
|
||||
|
||||
#include "../../../gen/l1/eve/margaret/VecAndSpan_MargaretCommandForImageCopying.h"
|
||||
|
||||
#include "../../../gen/l1/vulkan/VecVkImageMemoryBarrier.h"
|
||||
|
||||
/* (destination_stage_mask, destination_access_mask) are probably
|
||||
* (VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT) */
|
||||
void margaret_rerecord_cmd_buff_for_texture_init (
|
||||
VkCommandBuffer command_buffer, VkBuffer host_mem_buffer,
|
||||
SpanMargaretCommandForImageCopying commands,
|
||||
VkPipelineStageFlags destination_stage_mask, VkAccessFlags destination_access_mask
|
||||
){
|
||||
if (vkResetCommandBuffer(command_buffer, 0) != VK_SUCCESS)
|
||||
abortf("vkResetCommandBuffer\n");
|
||||
VkCommandBufferBeginInfo begin_info = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,};
|
||||
if (vkBeginCommandBuffer(command_buffer, &begin_info) != VK_SUCCESS)
|
||||
abortf("vkBeginCommandBuffer\n");
|
||||
VecVkImageMemoryBarrier barriers = VecVkImageMemoryBarrier_new_reserved(commands.len);
|
||||
for (size_t i = 0; i < commands.len; i++) {
|
||||
MargaretCommandForImageCopying img = commands.data[i];
|
||||
VecVkImageMemoryBarrier_append(&barriers, (VkImageMemoryBarrier){
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = img.dst_image->image,
|
||||
.subresourceRange = (VkImageSubresourceRange){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
});
|
||||
}
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, /* Flags */
|
||||
0, NULL, 0, NULL,
|
||||
barriers.len, barriers.buf);
|
||||
barriers.len = 0; /* It's ok, VkImageMemoryBarrier is primitive */
|
||||
for (size_t i = 0; i < commands.len; i++) {
|
||||
MargaretCommandForImageCopying img = commands.data[i];
|
||||
VkBufferImageCopy region = {
|
||||
.bufferOffset = img.host_mem_buff_offset,
|
||||
.bufferRowLength = 0,
|
||||
.bufferImageHeight = 0,
|
||||
.imageSubresource = (VkImageSubresourceLayers){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.imageOffset = {0, 0, 0},
|
||||
.imageExtent = {
|
||||
.width = img.dst_image->width,
|
||||
.height = img.dst_image->height,
|
||||
.depth = 1
|
||||
},
|
||||
};
|
||||
vkCmdCopyBufferToImage(command_buffer, host_mem_buffer, img.dst_image->image,
|
||||
// We assume that image was already transitioned to optimal layout transition_image_layout
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
}
|
||||
/* filling buffers Vec again */
|
||||
for (size_t i = 0; i < commands.len; i++) {
|
||||
MargaretCommandForImageCopying img = commands.data[i];
|
||||
VecVkImageMemoryBarrier_append(&barriers, (VkImageMemoryBarrier){
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
.dstAccessMask = destination_access_mask,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.newLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = img.dst_image->image,
|
||||
.subresourceRange = (VkImageSubresourceRange){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.baseMipLevel = 0,
|
||||
.levelCount = 1,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
});
|
||||
}
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, destination_stage_mask,
|
||||
0, /* Flags */
|
||||
0, NULL, 0, NULL,
|
||||
barriers.len, barriers.buf
|
||||
);
|
||||
margaret_end_and_submit_and_free_command_buffer(device, command_pool, graphics_queue, cmd_buffer);
|
||||
VecVkImageMemoryBarrier_drop(barriers);
|
||||
if (vkEndCommandBuffer(command_buffer) != VK_SUCCESS)
|
||||
abortf("vkEndCommandBuffer");
|
||||
}
|
||||
|
||||
// For application initialization purposes only
|
||||
void margaret_copy_buffer_to_trans_dst_optimal_image (
|
||||
VkDevice device, VkCommandPool command_pool, VkQueue graphics_queue,
|
||||
const MargaretImageInMemoryInfo* dst_image, VkBuffer src_buffer
|
||||
) {
|
||||
VkCommandBuffer cmd_buffer = margaret_alloc_and_begin_single_use_command_buffer(device, command_pool);
|
||||
VkBufferImageCopy region = {
|
||||
.bufferOffset = 0,
|
||||
.bufferRowLength = 0,
|
||||
.bufferImageHeight = 0,
|
||||
.imageSubresource = (VkImageSubresourceLayers){
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.mipLevel = 0,
|
||||
.baseArrayLayer = 0,
|
||||
.layerCount = 1,
|
||||
},
|
||||
.imageOffset = {0, 0, 0},
|
||||
.imageExtent = {
|
||||
.width = dst_image->width,
|
||||
.height = dst_image->height,
|
||||
.depth = 1
|
||||
},
|
||||
};
|
||||
vkCmdCopyBufferToImage(cmd_buffer, src_buffer, dst_image->image,
|
||||
// We assume that image was already transitioned to optimal layout transition_image_layout
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
margaret_end_and_submit_and_free_command_buffer(device, command_pool, graphics_queue, cmd_buffer);
|
||||
}
|
||||
|
||||
// todo: AHFHDF EW WHAT IS THAT???
|
||||
// For application initialization purposes only
|
||||
void margaret_copy_buffer_to_texture_for_frag_shader_imm(
|
||||
VkDevice device, VkCommandPool command_pool, VkQueue graphics_queue,
|
||||
const MargaretImageInMemoryInfo* dst_image, VkBuffer src_buffer
|
||||
) {
|
||||
transition_image_layout(device, command_pool, graphics_queue, dst_image->image,
|
||||
// previous and new layouts
|
||||
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
// src stage and access
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
|
||||
// destination stage and access
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT
|
||||
);
|
||||
margaret_copy_buffer_to_trans_dst_optimal_image(device, command_pool, graphics_queue, dst_image, src_buffer);
|
||||
transition_image_layout(device, command_pool, graphics_queue, dst_image->image,
|
||||
// previous and new layouts
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL,
|
||||
// src stage and access
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
|
||||
// destination stage and access
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT
|
||||
);
|
||||
}
|
||||
|
||||
// todo: cjafhs WHAT IS THIS?? I need to remove this. I can do better than this
|
||||
// For texture
|
||||
VkImageView margaret_create_view_for_image (
|
||||
VkDevice device, const MargaretImageInMemoryInfo* image, VkImageAspectFlags aspect_flags
|
||||
|
||||
@ -24,7 +24,7 @@ MarieLinearFun marie_gen_scanline_borderline(vec2 a, vec2 b) {
|
||||
|
||||
/* Utility function, that is used by rasterization function.
|
||||
* Don't use in your code*/
|
||||
void marie_rasterize_line_in_triangle_with_attr_sorted(
|
||||
void marie_h_rasterize_only_one_line_of_triangle(
|
||||
vec2 v0pos, vec2 v1pos, vec2 v2pos, S32 L, S32 R, MarieVertAttr P0, MarieVertAttr P1, MarieVertAttr P2,
|
||||
float S, S32 my, FnMarieRasterizerCallback cb
|
||||
) {
|
||||
@ -44,7 +44,7 @@ void marie_rasterize_line_in_triangle_with_attr_sorted(
|
||||
|
||||
/* Utility function, that is used by rasterization function.
|
||||
* Don't use in your code*/
|
||||
void marie_scan_rast_line_in_triangle_with_attr_sorted(
|
||||
void marie_h_rasterize_half_of_triangle(
|
||||
vec2 v0pos, vec2 v1pos, vec2 v2pos, S32 below, S32 above, MarieVertAttr P0, MarieVertAttr P1, MarieVertAttr P2,
|
||||
MarieLinearFun left_border, MarieLinearFun right_border, FnMarieRasterizerCallback cb
|
||||
) {
|
||||
@ -66,7 +66,9 @@ void marie_scan_rast_line_in_triangle_with_attr_sorted(
|
||||
}
|
||||
}
|
||||
|
||||
void marie_rasterize_triangle_with_attr_sorted(
|
||||
/* Utility function, that is used by rasterization function.
|
||||
* Don't use in your code*/
|
||||
void marie_h_rasterize_triangle_with_attr_sorted(
|
||||
MariePlaneVertAttr v0, MariePlaneVertAttr v1, MariePlaneVertAttr v2, FnMarieRasterizerCallback cb
|
||||
) {
|
||||
float S = marie_surface(v0.pos, v1.pos, v2.pos);
|
||||
@ -89,22 +91,22 @@ void marie_rasterize_triangle_with_attr_sorted(
|
||||
MarieLinearFun line_12 = marie_gen_scanline_borderline(v1.pos, v2.pos);
|
||||
MarieLinearFun line_20 = marie_gen_scanline_borderline(v2.pos, v0.pos);
|
||||
|
||||
marie_rasterize_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy0, cb);
|
||||
marie_h_rasterize_only_one_line_of_triangle(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy0, cb);
|
||||
if (sy0 + 1 < sy1) {
|
||||
MarieLinearFun left_border = S > 0 ? line_20 : line_01;
|
||||
MarieLinearFun right_border = S > 0 ? line_01 : line_20;
|
||||
marie_scan_rast_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, sy0, sy1, P0, P1, P2, left_border, right_border, cb);
|
||||
marie_h_rasterize_half_of_triangle(v0.pos, v1.pos, v2.pos, sy0, sy1, P0, P1, P2, left_border, right_border, cb);
|
||||
}
|
||||
if (sy1 > sy0) {
|
||||
marie_rasterize_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy1, cb);
|
||||
marie_h_rasterize_only_one_line_of_triangle(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy1, cb);
|
||||
}
|
||||
if (sy1 + 1 < sy2) {
|
||||
MarieLinearFun left_border = S > 0 ? line_20 : line_12;
|
||||
MarieLinearFun right_border = S > 0 ? line_12 : line_20;
|
||||
marie_scan_rast_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, sy1, sy2, P0, P1, P2, left_border, right_border, cb);
|
||||
marie_h_rasterize_half_of_triangle(v0.pos, v1.pos, v2.pos, sy1, sy2, P0, P1, P2, left_border, right_border, cb);
|
||||
}
|
||||
if (sy2 > sy1) {
|
||||
marie_rasterize_line_in_triangle_with_attr_sorted(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy2, cb);
|
||||
marie_h_rasterize_only_one_line_of_triangle(v0.pos, v1.pos, v2.pos, L, R, P0, P1, P2, S, sy2, cb);
|
||||
}
|
||||
}
|
||||
void marie_rasterize_triangle_with_attr(
|
||||
@ -112,22 +114,22 @@ void marie_rasterize_triangle_with_attr(
|
||||
) {
|
||||
if (a.pos.y < b.pos.y) {
|
||||
if (b.pos.y < c.pos.y) {
|
||||
marie_rasterize_triangle_with_attr_sorted(a, b, c, cb);
|
||||
marie_h_rasterize_triangle_with_attr_sorted(a, b, c, cb);
|
||||
} else {
|
||||
if (a.pos.y < c.pos.y) {
|
||||
marie_rasterize_triangle_with_attr_sorted(a, c, b, cb);
|
||||
marie_h_rasterize_triangle_with_attr_sorted(a, c, b, cb);
|
||||
} else {
|
||||
marie_rasterize_triangle_with_attr_sorted(c, a, b, cb);
|
||||
marie_h_rasterize_triangle_with_attr_sorted(c, a, b, cb);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (a.pos.y < c.pos.y) {
|
||||
marie_rasterize_triangle_with_attr_sorted(b, a, c, cb);
|
||||
marie_h_rasterize_triangle_with_attr_sorted(b, a, c, cb);
|
||||
} else {
|
||||
if (b.pos.y < c.pos.y) {
|
||||
marie_rasterize_triangle_with_attr_sorted(b, c, a, cb);
|
||||
marie_h_rasterize_triangle_with_attr_sorted(b, c, a, cb);
|
||||
} else {
|
||||
marie_rasterize_triangle_with_attr_sorted(c, b, a, cb);
|
||||
marie_h_rasterize_triangle_with_attr_sorted(c, b, a, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,38 +2,12 @@
|
||||
#define PROTOTYPE1_SRC_L2_MARIE_TEXTURE_PROCESSING_H
|
||||
|
||||
#include "../../../gen/l1/pixel_masses.h"
|
||||
|
||||
void TextureDataR8G8B8A8_print(const TextureDataR8G8B8A8* self) {
|
||||
U64 width = self->width;
|
||||
U64 height = TextureDataR8G8B8A8_get_height(self);
|
||||
U64 cell_width = MAX_U64(1, width / 350);
|
||||
U64 cell_height = MAX_U64(1, cell_width * 14 / 8);
|
||||
for (U64 CY = 0; CY < height; CY += cell_height) {
|
||||
for (U64 CX = 0; CX < width; CX += cell_width) {
|
||||
float lum = 0;
|
||||
for (U64 j = 0; j < cell_height; j++) {
|
||||
U64 y = cell_height * CY + j;
|
||||
if (y >= height)
|
||||
continue;
|
||||
for (U64 i = 0; i < cell_width; i++) {
|
||||
U64 x = cell_width * CX + i;
|
||||
if (x >= width)
|
||||
continue;
|
||||
cvec4 pix = *TextureDataR8G8B8A8_at(self, x, y);
|
||||
lum += (float)pix.x / 255 * 0.21f + (float)pix.y / 255 * 0.71f + (float)pix.z / 255 * 0.08f;
|
||||
}
|
||||
}
|
||||
lum /= (float)cell_width * (float)cell_height;
|
||||
printf("%s", lum > 0.95 ? "@" : (lum > 0.8 ? "#" : (lum > 0.65 ? "*" : (lum > 0.4 ? "_" : (lum > 0.2 ? "." : " ")))));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
#include "rasterization.h"
|
||||
|
||||
/* Fixes several of my generated textures */
|
||||
NODISCARD TextureDataR8G8B8A8 TextureDataR8G8B8A8_expand_nontransparent_1px(const TextureDataR8G8B8A8* self) {
|
||||
S32 width = (S32)self->width;
|
||||
S32 height = (S32)TextureDataR8G8B8A8_get_height(self);
|
||||
S32 height = (S32)self->height;
|
||||
TextureDataR8G8B8A8 res = TextureDataR8G8B8A8_new(width, height);
|
||||
// S32 chain[9][2] = {{0, 0}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}};
|
||||
for (S32 y = 0; y < height; y++) {
|
||||
@ -62,4 +36,44 @@ NODISCARD TextureDataR8G8B8A8 TextureDataR8G8B8A8_expand_nontransparent_1px(cons
|
||||
return res;
|
||||
}
|
||||
|
||||
vec4 marie_color_cvec4_to_vec4(cvec4 clr) {
|
||||
return (vec4){(float)clr.x / 255, (float)clr.y / 255, (float)clr.z / 255, (float)clr.w / 255};
|
||||
}
|
||||
|
||||
cvec4 marie_color_vec4_to_cvec4(vec4 clr) {
|
||||
return (cvec4){(U8)roundf(clr.x * 255), (U8)roundf(clr.y * 255), (U8)roundf(clr.z * 255), (U8)roundf(clr.w * 255)};
|
||||
}
|
||||
|
||||
vec3 marie_color_cvec3_to_vec3(cvec3 clr) {
|
||||
return (vec3){(float)clr.x / 255, (float)clr.y / 255, (float)clr.z / 255};
|
||||
}
|
||||
|
||||
cvec3 marie_color_vec3_to_cvec3(vec3 clr) {
|
||||
return (cvec3){(U8)roundf(clr.x * 255), (U8)roundf(clr.y * 255), (U8)roundf(clr.z * 255)};
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
TextureDataR8G8B8A8* self;
|
||||
cvec4 pixel;
|
||||
} TextureDataR8G8B8A8_draw_triangle_of_one_color_H_DrawGuest;
|
||||
|
||||
void TextureDataR8G8B8A8_draw_triangle_of_one_color_h_draw_guest(void* ug, S32 x, S32 y, vec4 attr) {
|
||||
TextureDataR8G8B8A8_draw_triangle_of_one_color_H_DrawGuest *g = ug;
|
||||
if (TextureDataR8G8B8A8_is_inside(g->self, x, y))
|
||||
*TextureDataR8G8B8A8_mat(g->self, x, y) = g->pixel;
|
||||
}
|
||||
|
||||
/* Given triangle is not natural : it is from parameter space */
|
||||
void TextureDataR8G8B8A8_draw_triangle_of_one_color(
|
||||
TextureDataR8G8B8A8* self, vec3 color, MarieTriangle param_triang, mat3x2 trop
|
||||
) {
|
||||
TextureDataR8G8B8A8_draw_triangle_of_one_color_H_DrawGuest aboba =
|
||||
{ self, marie_color_vec4_to_cvec4(vec3_and_one(color)) };
|
||||
MarieTriangle natural = MarieTriangle_mat3x2_mul_pos(param_triang, trop);
|
||||
marie_rasterize_triangle_with_attr(
|
||||
(MariePlaneVertAttr){natural.v0, {}}, (MariePlaneVertAttr){natural.v1, {}}, (MariePlaneVertAttr){natural.v2, {}},
|
||||
(FnMarieRasterizerCallback){.fn = TextureDataR8G8B8A8_draw_triangle_of_one_color_h_draw_guest,
|
||||
.guest = &aboba});
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -8,6 +8,7 @@
|
||||
#include "../../../../gen/l1/VecAndSpan_vec2.h"
|
||||
#include "../../../../gen/l1/pixel_masses.h"
|
||||
#include "../../marie/rasterization.h"
|
||||
#include "../../marie/texture_processing.h"
|
||||
|
||||
typedef struct {
|
||||
vec3 pos;
|
||||
@ -32,10 +33,16 @@ GenericMeshTopology GenericMeshTopology_clone(const GenericMeshTopology* self) {
|
||||
typedef struct {
|
||||
GenericMeshTopology topology;
|
||||
U32 max_instance_count;
|
||||
VecU8 diffuse_texture_path;
|
||||
VecU8 normal_texture_path;
|
||||
VecU8 specular_texture_path;
|
||||
} GenericMeshInSceneTemplate;
|
||||
|
||||
void GenericMeshInSceneTemplate_drop(GenericMeshInSceneTemplate self) {
|
||||
GenericMeshTopology_drop(self.topology);
|
||||
VecU8_drop(self.diffuse_texture_path);
|
||||
VecU8_drop(self.normal_texture_path);
|
||||
VecU8_drop(self.specular_texture_path);
|
||||
}
|
||||
|
||||
GenericMeshInSceneTemplate GenericMeshInSceneTemplate_clone(const GenericMeshInSceneTemplate* self) {
|
||||
@ -454,6 +461,41 @@ vec2 Bublazhuzhka_get_derivative(const Bublazhuzhka* self, vec2 v) {
|
||||
return sum;
|
||||
}
|
||||
|
||||
cvec3 Bublazhuzhka_get_color(const Bublazhuzhka* self, vec2 v) {
|
||||
float flats = 0;
|
||||
for (size_t i = 0; i < self->wimbzles.len; i++) {
|
||||
Wimbzle rect = *VecWimbzle_at(&self->wimbzles, i);
|
||||
vec2 B = {rect.tr.x + rect.brd, rect.tr.y + rect.brd};
|
||||
vec2 C = {rect.bl.x - rect.brd, rect.bl.y - rect.brd};
|
||||
vec2 A = {C.x, B.y};
|
||||
vec2 D = {B.x, C.y};
|
||||
vec2 F = rect.tr;
|
||||
vec2 G = rect.bl;
|
||||
vec2 E = {G.x, F.y};
|
||||
vec2 H = {F.x, G.y};
|
||||
float slp = rect.height / rect.brd;
|
||||
if (A.x < v.x && v.x < E.x && marie_surface(E, A, v) > 0 && marie_surface(C, G, v) > 0) {
|
||||
return (cvec3){100, 30, 40};
|
||||
} else if (F.x < v.x && v.x < B.x && marie_surface(B, F, v) > 0 && marie_surface(H, D, v) > 0) {
|
||||
return (cvec3){70, 60, 45};
|
||||
} else if (C.y < v.y && v.y < G.y && marie_surface(G, C, v) > 0 && marie_surface(D, H, v) > 0) {
|
||||
return (cvec3){10, 100, 70};
|
||||
} else if (F.y < v.y && v.y < B.y && marie_surface(A, E, v) > 0 && marie_surface(F, B, v) > 0) {
|
||||
return (cvec3){25, 50, 110};
|
||||
} else if (E.x <= v.x && v.x <= F.x && G.y <= v.y && v.y <= F.y) {
|
||||
flats += rect.height;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < self->nibzles.len; i++) {
|
||||
Nibzle sphere = *VecNibzle_at(&self->nibzles, i);
|
||||
float sq_h = pow2f(sphere.rad) - pow2f(v.x - sphere.center.x) - pow2f(v.y - sphere.center.y);
|
||||
if (sq_h >= 0)
|
||||
return (cvec3){120, 120, 120};
|
||||
}
|
||||
U8 p = (U8)roundf((1.f - expf(flats)) * 60);
|
||||
return (cvec3){121 - p * 2, 30 + p, 65 - p};
|
||||
}
|
||||
|
||||
cvec3 compress_normal_vec_into_norm_texel(vec3 n) {
|
||||
return (cvec3){(U32)roundf(255 * (n.x + 1) / 2), (U32)roundf(255 * (n.y + 1) / 2), (U32)roundf(255 * (n.z + 1) / 2)};
|
||||
}
|
||||
@ -575,10 +617,36 @@ void draw_polygon_on_normal_texture_flat_param_surf(TextureDataR8G8B8A8* tex, ve
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
TextureDataR8G8B8A8* self;
|
||||
const Bublazhuzhka* bublazhuzhka;
|
||||
} TextureDataR8G8B8A8_draw_triang_part_bublazhuzhka_H_DrawGuest;
|
||||
|
||||
void TextureDataR8G8B8A8_draw_triang_part_bublazhuzhka_h_draw_guest(void* ug, S32 x, S32 y, vec4 attr) {
|
||||
TextureDataR8G8B8A8_draw_triang_part_bublazhuzhka_H_DrawGuest *g = ug;
|
||||
cvec3 clr = Bublazhuzhka_get_color(g->bublazhuzhka, (vec2){attr.x, attr.y});
|
||||
if (TextureDataR8G8B8A8_is_inside(g->self, x, y))
|
||||
*TextureDataR8G8B8A8_mat(g->self, x, y) = (cvec4){clr.x, clr.y, clr.z, 255};
|
||||
}
|
||||
|
||||
/* Not natural coordinates. Needs translation operator to convert
|
||||
* from parameter space*/
|
||||
void TextureDataR8G8B8A8_draw_triang_part_bublazhuzhka(
|
||||
TextureDataR8G8B8A8* self, const Bublazhuzhka* bublazhuzhka, MarieTriangle param_triangle, mat3x2 trop
|
||||
) {
|
||||
TextureDataR8G8B8A8_draw_triang_part_bublazhuzhka_H_DrawGuest aboba =
|
||||
{self, bublazhuzhka};
|
||||
MarieTriangleAttr natural = MarieTriangle_goto_nat_cords_pres_par(param_triangle, trop);
|
||||
// todo: continue from here
|
||||
marie_rasterize_triangle_with_attr(
|
||||
natural.v0, natural.v1, natural.v2,
|
||||
(FnMarieRasterizerCallback){.fn = TextureDataR8G8B8A8_draw_triang_part_bublazhuzhka_h_draw_guest, .guest = &aboba});
|
||||
}
|
||||
|
||||
|
||||
|
||||
TextureDataR8 generate_tex_template_for_one_fourth_of_a_cylinder(float s_resol, float w, float r, U32 k) {
|
||||
|
||||
TextureDataR8G8B8A8 generate_tex_template_for_one_fourth_of_a_cylinder(float s_resol, float w, float r, U32 k) {
|
||||
assert(k >= 1);
|
||||
const float a = M_PI_2f / (float)k;
|
||||
const float l = 2 * r * sinf(M_PI_4f / (float)k);
|
||||
@ -589,36 +657,42 @@ TextureDataR8 generate_tex_template_for_one_fourth_of_a_cylinder(float s_resol,
|
||||
const vec2 v1tex = {r + w, r};
|
||||
const vec2 v2tex = {r, 2 * r};
|
||||
const vec2 v3tex = {r + w, 2 * r};
|
||||
TextureDataR8 res = TextureDataR8_new(width_pix, height_pix);
|
||||
Vecvec2 P = Vecvec2_new_reserved(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 * (float)i), r + r * cosf(a * (float)i)});
|
||||
}
|
||||
Vecvec2_append(&P, v3tex);
|
||||
const vec2 v4tex = {r, 0};
|
||||
const vec2 v5tex = {r + w, 0};
|
||||
TextureDataR8G8B8A8 res = TextureDataR8G8B8A8_new(width_pix, height_pix);
|
||||
mat3x2 cord_resol_trop = (mat3x2){.x.x = cord_resol.x, .y.y = cord_resol.y};
|
||||
|
||||
vec3 color_1 = (vec3){0.3f, 0.5f, 0.1f};
|
||||
TextureDataR8G8B8A8_draw_triangle_of_one_color(&res, color_1, (MarieTriangle){v0tex, v4tex, v5tex}, cord_resol_trop);
|
||||
TextureDataR8G8B8A8_draw_triangle_of_one_color(&res, color_1, (MarieTriangle){v0tex, v5tex, v1tex}, cord_resol_trop);
|
||||
vec3 color_2 = (vec3){0.1f, 0.2f, 0.8f};
|
||||
vec3 color_3 = (vec3){0.2f, 0.3f, 0.9f};
|
||||
vec3 color_4 = (vec3){0.1f, 0.5f, 0.7f};
|
||||
vec3 color_5 = (vec3){0.7f, 0.05f, 0.2f};
|
||||
for (size_t i = 1; i <= k; i++) {
|
||||
Vecvec2_append(&P, (vec2){r + w, 2 * r + (float)i * l});
|
||||
vec2 A = (vec2){r - r * sinf(a * (float)i), r + r * cosf(a * (float)i)};
|
||||
vec2 B = (vec2){r - r * sinf(a * (float)(i-1)), r + r * cosf(a * (float)(i-1))};
|
||||
TextureDataR8G8B8A8_draw_triangle_of_one_color(&res, color_2, (MarieTriangle){v0tex, B, A}, cord_resol_trop);
|
||||
}
|
||||
for (size_t i = k; i > 0; i--) {
|
||||
Vecvec2_append(&P, (vec2){r, 2 * r + (float)i * l});
|
||||
}
|
||||
Vecvec2_append(&P, v2tex);
|
||||
for (size_t i = 1; i <= k; i++) {
|
||||
Vecvec2_append(&P, (vec2){r - r * sinf(a * (float)i), r + r * cosf(a * (float)i)});
|
||||
vec2 A = (vec2){r + w + r * sinf(a * (float)i), r + r * cosf(a * (float)i)};
|
||||
vec2 B = (vec2){r + w + r * sinf(a * (float)(i-1)), r + r * cosf(a * (float)(i-1))};
|
||||
TextureDataR8G8B8A8_draw_triangle_of_one_color(&res, color_3, (MarieTriangle){v1tex, A, B}, cord_resol_trop);
|
||||
}
|
||||
for (size_t i = 0; i < P.len; i++) {
|
||||
*Vecvec2_mat(&P, i) = vec2_mul_vec2(*Vecvec2_at(&P, i), cord_resol);
|
||||
for (size_t i = 1; i <= k; i++) {
|
||||
vec2 A = (vec2){r, 2 * r + (float)(i) * l};
|
||||
vec2 B = (vec2){r, 2 * r + (float)(i-1) * l};
|
||||
vec2 C = (vec2){r + w, 2 * r + (float)(i-1) * l};
|
||||
vec2 D = (vec2){r + w, 2 * r + (float)(i) * l};
|
||||
vec3 c = i % 2 ? color_4 : color_5;
|
||||
TextureDataR8G8B8A8_draw_triangle_of_one_color(&res, c, (MarieTriangle){A, B, C}, cord_resol_trop);
|
||||
TextureDataR8G8B8A8_draw_triangle_of_one_color(&res, c, (MarieTriangle){A, C, D}, cord_resol_trop);
|
||||
}
|
||||
TextureDataR8_draw_perimeter_maxing(&res, Vecvec2_to_span(&P));
|
||||
Vecvec2_drop(P);
|
||||
|
||||
Bublazhuzhka crap_on_back_side = fill_rectangle_with_crap(w, r);
|
||||
// todo: draw bublazhuzhka pixel-by-pixel myself
|
||||
Bublazhuzhka_TextureDataR8_draw_maxing(&crap_on_back_side, &res,
|
||||
(mat3x2){.x.x = cord_resol.x, .y.y = cord_resol.y, .z = vec2_mul_vec2((vec2){r, r}, cord_resol)});
|
||||
mat3x2 back_side_trop = (mat3x2){.x.x = cord_resol.x, .y.y = cord_resol.y, .z = vec2_mul_vec2((vec2){r, r}, cord_resol)};
|
||||
TextureDataR8G8B8A8_draw_triang_part_bublazhuzhka(&res, &crap_on_back_side, (MarieTriangle){{0, r}, {0, 0}, {w, 0}}, back_side_trop);
|
||||
TextureDataR8G8B8A8_draw_triang_part_bublazhuzhka(&res, &crap_on_back_side, (MarieTriangle){{0, r}, {w, 0}, {w, r}}, back_side_trop);
|
||||
Bublazhuzhka_drop(crap_on_back_side);
|
||||
return res;
|
||||
}
|
||||
@ -792,4 +866,13 @@ ShinyMeshTopology generate_shiny_rhombicuboctahedron(float r) {
|
||||
return res;
|
||||
}
|
||||
|
||||
GenericMeshInSceneTemplate GenericMeshInSceneTemplate_for_log(U32 w, U32 r, U32 k, U32 max_instance_count) {
|
||||
return (GenericMeshInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder((float)w, (float)r, k),
|
||||
.max_instance_count = max_instance_count,
|
||||
.diffuse_texture_path = VecU8_format("textures/log_%u_%u_%u_diffuse.png", w, r, k),
|
||||
.normal_texture_path = VecU8_format("textures/log_%u_%u_%u_NORMAL.png", w, r, k),
|
||||
.specular_texture_path = VecU8_format("textures/log_%u_%u_%u_specular.png", w, r, k),
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -12,12 +12,15 @@ typedef struct {
|
||||
VkBuffer instance_attr_buf;
|
||||
VkDeviceSize instance_attr_buf_offset;
|
||||
U32 limit_max_instance_count;
|
||||
} ModelOnSceneMem;
|
||||
VkImage diffuse_texture;
|
||||
VkImage normal_texture;
|
||||
VkImage specular_texture;
|
||||
} GenericModelOnSceneMem;
|
||||
|
||||
/* Contains both data for model instances attributes and buffer (+offset) where it is stored */
|
||||
/* Also, I made it non-clonable. Thus */
|
||||
typedef struct {
|
||||
ModelOnSceneMem model;
|
||||
GenericModelOnSceneMem model;
|
||||
VecGenericMeshInstance instances;
|
||||
} UsedGenericModelOnScene;
|
||||
|
||||
@ -28,7 +31,16 @@ void UsedGenericModelOnScene_drop(UsedGenericModelOnScene self) {
|
||||
#include "../../../../gen/l1/eve/r0/VecUsedGenericModelOnScene.h"
|
||||
|
||||
typedef struct {
|
||||
ModelOnSceneMem model;
|
||||
VkBuffer vbo;
|
||||
VkBuffer ebo;
|
||||
size_t indexes;
|
||||
VkBuffer instance_attr_buf;
|
||||
VkDeviceSize instance_attr_buf_offset;
|
||||
U32 limit_max_instance_count;
|
||||
} ShinyModelOnSceneMem;
|
||||
|
||||
typedef struct {
|
||||
ShinyModelOnSceneMem model;
|
||||
VecShinyMeshInstance instances;
|
||||
} UsedShinyModelOnScene;
|
||||
|
||||
@ -134,7 +146,7 @@ void SceneTemplate_copy_initial_model_topology_and_rerecord_transfer_cmd(
|
||||
// todo: ot use one buffer per all the data
|
||||
for (size_t mi = 0; mi < scene_template->generic_models.len; mi++) {
|
||||
const GenericMeshInSceneTemplate* mt = VecGenericMeshInSceneTemplate_at(&scene_template->generic_models, mi);
|
||||
const ModelOnSceneMem *m_buf = &VecUsedGenericModelOnScene_at(&scene->generic_models, mi)->model;
|
||||
const GenericModelOnSceneMem *m_buf = &VecUsedGenericModelOnScene_at(&scene->generic_models, mi)->model;
|
||||
size_t vbo_len = mt->topology.vertices.len * sizeof(GenericMeshVertex);
|
||||
memcpy(host_mem_buffer_mem + offset, mt->topology.vertices.buf, vbo_len);
|
||||
VkBufferCopy ra = {.srcOffset = offset, .dstOffset = 0, .size = vbo_len};
|
||||
@ -148,7 +160,7 @@ void SceneTemplate_copy_initial_model_topology_and_rerecord_transfer_cmd(
|
||||
}
|
||||
for (size_t mi = 0; mi < scene_template->shiny_models.len; mi++) {
|
||||
const ShinyMeshInSceneTemplate* mt = VecShinyMeshInSceneTemplate_at(&scene_template->shiny_models, mi);
|
||||
const ModelOnSceneMem *m_buf = &VecUsedShinyModelOnScene_at(&scene->shiny_models, mi)->model;
|
||||
const ShinyModelOnSceneMem *m_buf = &VecUsedShinyModelOnScene_at(&scene->shiny_models, mi)->model;
|
||||
size_t vbo_len = mt->topology.vertices.len * sizeof(ShinyMeshVertex);
|
||||
memcpy(host_mem_buffer_mem + offset, mt->topology.vertices.buf, vbo_len);
|
||||
VkBufferCopy ra = {.srcOffset = offset, .dstOffset = 0, .size = vbo_len};
|
||||
|
||||
@ -1,30 +1,46 @@
|
||||
#include "r0_assets.h"
|
||||
#include "../../marie/rasterization.h"
|
||||
#include "../../margaret/png_pixel_masses.h"
|
||||
// #include "../../margaret/png_pixel_masses.h" // todo: delete this file
|
||||
#include "../../../../gen/l1/margaret/png_pixel_masses.h"
|
||||
#include "../../marie/texture_processing.h"
|
||||
|
||||
void model_1_template() {
|
||||
TextureDataR8 tex = generate_tex_template_for_one_fourth_of_a_cylinder(120, 10, 2, 6);
|
||||
TextureDataR8G8B8A8 tex_1_big = TextureDataR8G8B8A8_new(tex.width, TextureDataR8_get_height(&tex));
|
||||
for (size_t i = 0; i < tex.pixels.len; i++) {
|
||||
U8 g = *VecU8_at(&tex.pixels, i);
|
||||
*Veccvec4_mat(&tex_1_big.pixels, i) = (cvec4){g, g, g, 255};
|
||||
void for_log(U32 w, U32 r, U32 k) {
|
||||
{
|
||||
TextureDataR8G8B8A8 tex = generate_tex_template_for_one_fourth_of_a_cylinder(120, (float)w, (float)r, k);
|
||||
TextureDataR8G8B8A8 fixed_tex = TextureDataR8G8B8A8_expand_nontransparent_1px(&tex);
|
||||
VecU8 name = VecU8_format("textures/log_%u_%u_%u_TEMPLATE.png", w, r, k);
|
||||
TextureDataR8G8B8A8_write_to_png_nofail(&fixed_tex, VecU8_to_span(&name));
|
||||
VecU8_drop(name);
|
||||
TextureDataR8G8B8A8_drop(fixed_tex);
|
||||
TextureDataR8G8B8A8_drop(tex);
|
||||
}
|
||||
{
|
||||
TextureDataR8G8B8A8 tex = generate_normal_tex_for_one_fourth_of_a_cylinder(120, (float)w, (float)r, k);
|
||||
TextureDataR8G8B8A8 fixed_tex = TextureDataR8G8B8A8_expand_nontransparent_1px(&tex);
|
||||
VecU8 name = VecU8_format("textures/log_%u_%u_%u_NORMAL.png", w, r, k);
|
||||
TextureDataR8G8B8A8_write_to_png_nofail(&fixed_tex, VecU8_to_span(&name));
|
||||
VecU8_drop(name);
|
||||
TextureDataR8G8B8A8_drop(fixed_tex);
|
||||
TextureDataR8G8B8A8_drop(tex);
|
||||
}
|
||||
TextureDataR8G8B8A8_write_to_png_nofail(&tex_1_big, cstr("textures/log_10_2_6_TEMPLATE.png"));
|
||||
TextureDataR8G8B8A8_drop(tex_1_big);
|
||||
TextureDataR8_drop(tex);
|
||||
}
|
||||
|
||||
void model_1_normal() {
|
||||
TextureDataR8G8B8A8 tex = generate_normal_tex_for_one_fourth_of_a_cylinder(120, 10, 2, 6);
|
||||
TextureDataR8G8B8A8 fixed_tex = TextureDataR8G8B8A8_expand_nontransparent_1px(&tex);
|
||||
TextureDataR8G8B8A8_write_to_png_nofail(&fixed_tex, cstr("textures/log_10_2_6_NORMAL.png"));
|
||||
TextureDataR8G8B8A8_drop(fixed_tex);
|
||||
TextureDataR8G8B8A8_drop(tex);
|
||||
}
|
||||
|
||||
int main() {
|
||||
model_1_template();
|
||||
model_1_normal();
|
||||
// TextureDataR8G8B8A8 tex = TextureDataR8G8B8A8_read_from_png_nofail(cstr("/home/gregory/test/basn3p04.png"));
|
||||
// TextureDataR8G8B8A8_print(&tex);
|
||||
// TextureDataR8G8B8A8_drop(tex);
|
||||
//
|
||||
// TextureDataR8G8B8 TEX = TextureDataR8G8B8_read_from_png_nofail(cstr("/home/gregory/test/basn3p04.png"));
|
||||
// TextureDataR8G8B8_print(&TEX);
|
||||
// TextureDataR8G8B8_drop(TEX);
|
||||
|
||||
// TextureDataR8 tex = TextureDataR8_read_from_png_nofail(cstr("textures/log_5_5_10_TEMPLATE.png"));
|
||||
// TextureDataR8_print(&tex);
|
||||
// TextureDataR8_drop(tex);
|
||||
|
||||
for_log(10, 2, 6);
|
||||
for_log(5, 5, 10);
|
||||
for_log(1, 10, 4);
|
||||
for_log(2, 1, 6);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3,11 +3,12 @@
|
||||
layout(location = 0) in vec2 fsin_tex;
|
||||
layout(location = 1) in vec3 fsin_pos;
|
||||
|
||||
/* Righ now all in set 0 */
|
||||
layout(location = 0) out vec4 fin_color;
|
||||
|
||||
/* Yes, even these guys */
|
||||
layout(binding = 1) uniform sampler2D color_tex;
|
||||
|
||||
layout(binding = 2) uniform sampler2D normal_map;
|
||||
layout(binding = 3) uniform sampler2D specular_map;
|
||||
|
||||
layout(push_constant, std430) uniform pc {
|
||||
layout(offset = 64) vec3 camera_pos;
|
||||
@ -57,7 +58,8 @@ void main(){
|
||||
Pipeline0Spotlight lamp = spotlight_arr[i];
|
||||
}
|
||||
vec3 natural_color = texture(color_tex, fsin_tex).xyz;
|
||||
// todo: add specular map texture
|
||||
vec3 color = natural_color * diffuse_illumination + 0.5 * specular_illumination;
|
||||
float specular_c = texture(specular_map, fsin_tex).x;
|
||||
vec3 color = natural_color * diffuse_illumination + specular_c * specular_illumination;
|
||||
fin_color = vec4(color, 1);
|
||||
// fin_color = vec4(specular_c, 0, 0, 1);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
BIN
src/l2/tests/r0/textures/log_10_2_6_specular.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
src/l2/tests/r0/textures/log_1_10_4_diffuse.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
src/l2/tests/r0/textures/log_1_10_4_specular.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
src/l2/tests/r0/textures/log_2_1_6_diffuse.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
src/l2/tests/r0/textures/log_2_1_6_specular.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
src/l2/tests/r0/textures/log_5_5_10_diffuse.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
src/l2/tests/r0/textures/log_5_5_10_specular.png
Normal file
|
After Width: | Height: | Size: 23 KiB |