From fb10c204ad331dd369af99ec38a66dc1231e324d Mon Sep 17 00:00:00 2001 From: Andreev Gregory Date: Tue, 5 Aug 2025 15:04:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=AF=20=D0=BC=D0=B0=D0=BB=D0=B5=D0=BD=D1=8C?= =?UTF-8?q?=D0=BA=D0=B8=D0=B9=20=D0=BA=D0=BE=D1=82=D1=91=D0=BD=D0=BE=D1=87?= =?UTF-8?q?=D0=B5=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 2 +- src/l1/core/util.h | 3 + src/l1/system/fsmanip.h | 17 ++ src/l2/codegen.c | 5 + src/l2/codegen/clipping.h | 179 +++++++++++++++++++ src/l2/codegen/geom.h | 6 +- src/l2/codegen/pixel_masses.h | 8 +- src/l2/marie/clipping.h | 8 - src/l2/marie/geom_alg_utils.h | 86 +++++++++ src/l2/marie/graphics_geom.h | 4 - src/l2/marie/rasterization.h | 45 +---- src/l2/tests/r0/r0_assets.h | 9 +- src/l2/tests/r0/test_shaders/glsl/0/0.frag | 5 +- src/l2/tests/r0/test_shaders/glsl/0b/0b.frag | 55 ++++++ src/l2/tests/r0/test_shaders/glsl/0b/0b.vert | 27 +++ 15 files changed, 393 insertions(+), 66 deletions(-) create mode 100644 src/l1/system/fsmanip.h create mode 100644 src/l2/codegen/clipping.h delete mode 100644 src/l2/marie/clipping.h create mode 100644 src/l2/marie/geom_alg_utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f656de..85d0bd0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.30) -project(splitter_draft C) +project(prototype1 C) #include_directories(${CMAKE_SOURCE_DIR}) set(CMAKE_C_FLAGS "-Wall -Wextra -Werror=implicit-function-declaration -Werror=return-type --std=c99 -g -ggdb -O0") diff --git a/src/l1/core/util.h b/src/l1/core/util.h index 886cd44..bec94b7 100644 --- a/src/l1/core/util.h +++ b/src/l1/core/util.h @@ -86,6 +86,9 @@ void VecT##_drop(VecT obj) { \ T ## _drop(obj.buf[i]); \ free(obj.buf); \ } \ +VecT VecT##_new_reserved(size_t n) {\ + return (VecT){ .buf = safe_calloc(n, sizeof(T)), .len = 0, .capacity = n };\ +} \ NODISCARD VecT VecT##_new_filled(size_t len, const T* el) { \ VecT res = (VecT){.buf = safe_calloc(len, sizeof(T)), .len = len, .capacity = len}; \ for (size_t i = 0; i < len; i++) \ diff --git a/src/l1/system/fsmanip.h b/src/l1/system/fsmanip.h new file mode 100644 index 0000000..2e30482 --- /dev/null +++ b/src/l1/system/fsmanip.h @@ -0,0 +1,17 @@ +#ifndef PROTOTYPE1_SRC_L1_SYSTEM_FSMANIP_H +#define PROTOTYPE1_SRC_L1_SYSTEM_FSMANIP_H + +/* For posix */ +#include "sys/stat.h" +#include +#include "../core/util.h" + +/* Aborts on error */ +void make_dir_nofail(const char* filename) { + int ret = mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); + if (ret < 0 && errno != EEXIST) + abortf("Unable to create directory %s\n", filename); +} + + +#endif diff --git a/src/l2/codegen.c b/src/l2/codegen.c index 518bf26..0c7c97c 100644 --- a/src/l2/codegen.c +++ b/src/l2/codegen.c @@ -1,8 +1,13 @@ #include "codegen/geom.h" #include "codegen/pixel_masses.h" +#include "codegen/clipping.h" +#include "../l1/system/fsmanip.h" int main() { + make_dir_nofail("l2"); generate_geom_header(); generate_pixel_masses_header(); + make_dir_nofail("l2/marie"); + generate_clipping_header(); return 0; } diff --git a/src/l2/codegen/clipping.h b/src/l2/codegen/clipping.h new file mode 100644 index 0000000..4c3a49c --- /dev/null +++ b/src/l2/codegen/clipping.h @@ -0,0 +1,179 @@ +#ifndef PROTOTYPE1_SRC_L2_CODEGEN_CLIPPING_H +#define PROTOTYPE1_SRC_L2_CODEGEN_CLIPPING_H + +#include "../../l1/codegen/codegen.h" + +// todo: move all of this to marie namespace + +typedef struct { + int order; + bool negate; +} PossiblyNegatedTriangle; + +int comparison_triang_groups[18][3] = { + {10, 11, 20}, {10, 11, 21}, {10, 11, 22}, + {11, 12, 20}, {11, 12, 21}, {11, 12, 22}, + {12, 10, 20}, {12, 10, 21}, {12, 10, 22}, + + {20, 21, 10}, {20, 21, 11}, {20, 21, 12}, + {21, 22, 10}, {21, 22, 11}, {21, 22, 12}, + {22, 20, 10}, {22, 20, 11}, {22, 20, 12}, +}; + +int permutations_of_sigma3(int ns[static 3]) { + return (ns[0] > ns[1]) + (ns[1] > ns[2]) + (ns[0] > ns[2]); +} + +PossiblyNegatedTriangle get_order_var_of_triangle_merged_ns(int arg[static 3]) { + for (int ord = 0; ord < 18; ord++) { + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 3; y++) { + if (comparison_triang_groups[ord][y] == arg[x]) + goto found_this_one; + } + goto nah_not_this_one; + found_this_one: + } + return (PossiblyNegatedTriangle){ .order = ord, + .negate = ((permutations_of_sigma3(comparison_triang_groups[ord]) + + permutations_of_sigma3(arg)) % 2 == 1) }; + nah_not_this_one: /* We continue out search*/ + } + abortf("Impossible"); +} + + +PossiblyNegatedTriangle get_order_var_of_triangle(char tri, int idi, char trj, int idj, char tru, int idu) { + assert(tri == 'C' || tri == 'T'); + assert(trj == 'C' || trj == 'T'); + assert(tru == 'C' || tru == 'T'); + assert(0 <= idi && idi < 3); + assert(0 <= idj && idj < 3); + assert(0 <= idu && idu < 3); + assert(!(tri == trj && trj == tru)); + assert(!(tri == trj && idi == idj)); + assert(!(trj == tru && idj == idu)); + assert(!(tri == tru && idi == idu)); + int arg[3] = { (tri == 'C' ? 10 : 20) + idi, (trj == 'C' ? 10 : 20) + idj, (tru == 'C' ? 10 : 20) + idu }; + return get_order_var_of_triangle_merged_ns(arg); +} + +/* Appends code to string with code. + * Triangle is either 'T' or 'C' + * Vertexes in triangle are numbered 0,1,2 + * vertex vi: (index idi of triangle tri) + * vertex vj: (index idj of triangle trj) + * vertex u: (index idu of triangle tru) + * We walk along the vi -> vj ray. If u is on the left, this statement will show true + */ +void append_on_the_left_stmt(VecU8* str, char tri, int idi, char trj, int idj, char tru, int idu) { + PossiblyNegatedTriangle measure = get_order_var_of_triangle(tri, idi, trj, idj, tru, idu); + if (measure.negate) + VecU8_append(str, '!'); + VecU8_append_vec(str, VecU8_format("M%d", measure.order)); +} + +void append_on_the_right_stmt(VecU8* str, char tri, int idi, char trj, int idj, char tru, int idu) { + PossiblyNegatedTriangle measure = get_order_var_of_triangle(tri, idi, trj, idj, tru, idu); + if (!measure.negate) + VecU8_append(str, '!'); + VecU8_append_vec(str, VecU8_format("M%d", measure.order)); +} + +/* Generates statement that intersects two segments from 2 different triangles: + * First segment: (tr1::A1) to (tr1::B1) + * Second segment: (tr2::A2) to (tr2::B2) + * */ +void append_intersection_stmt(VecU8* str, char tr1, int A1, int B1, char tr2, int A2, int B2) { + assert((tr1 == 'C' && tr2 == 'T') || (tr1 == 'T' && tr2 == 'C')); + assert(0 <= A1 && A1 < 3); + assert(0 <= B1 && B1 < 3); + assert(0 <= A2 && A2 < 3); + assert(0 <= B2 && B2 < 3); + assert(A1 != B1 && A2 != B2); + VecU8_append_vec(str, VecU8_format("marie_intersect_lines(T.v%d, T.v%d, C.v%d, C.v%d)", + A1, B1, A2, B2)); +} + +ConstSpanU8 marie_names_of_two_clipping_triangles[6] = { + {"C.v0", 4}, {"C.v1", 4}, {"C.v2", 4}, + {"T.v0", 4}, {"T.v1", 4}, {"T.v2", 4}, +}; + +NODISCARD ConstSpanU8 get_firstborn_vertex_stmt(char tr, int id) { + assert(0 <= id && id < 3); + if (tr == 'C') + return marie_names_of_two_clipping_triangles[id]; + if (tr == 'T') + return marie_names_of_two_clipping_triangles[3 + id]; + abortf("Wrong triangle"); +} + +void append_triangle_registration_stmt(VecU8* str, ConstSpanU8 P0, ConstSpanU8 P1, ConstSpanU8 P2) { + VecU8_append_span(str, cstr("VecMarieTriangle_append(pile, (MarieTriangle){")); + VecU8_append_span(str, P0); + VecU8_append_span(str, cstr(", ")); + VecU8_append_span(str, P1); + VecU8_append_span(str, cstr(", ")); + VecU8_append_span(str, P2); + VecU8_append_span(str, cstr("});\n")); +} + +int mod3_inc(int x) { + return x == 2 ? 0 : x + 1; +} + +int mod3_dec(int x) { + return x ? x - 1 : 2; +} + +void generate_func_clip_triang_on_triang_case_where_some_vertex_stuck(VecU8* res, char tC, char tT) { + /* Case where all 3 vertices of tT are inside tC */ + VecU8_append_span(res, cstr(SPACE4 "if (")); + for (int cs = 0; cs < 3; cs++) { + for (int tv = 0; tv < 3; tv++) { + if (cs != 0 || tv != 0) + VecU8_append_span(res, cstr(" && ")); + append_on_the_left_stmt(res, tC, cs, tC, (cs + 1) % 3, tT, tv); + } + } + VecU8_append_span(res, cstr(") {\n" SPACE8)); + append_triangle_registration_stmt(res, + get_firstborn_vertex_stmt(tT, 0), get_firstborn_vertex_stmt(tT, 1), get_firstborn_vertex_stmt(tT, 2)); + VecU8_append_span(res, cstr(SPACE8 "return;\n" SPACE4 "}\n")); + + /* Cases where two vertices of tT are inside tC, but one is outside */ + +} + +NODISCARD VecU8 generate_func_clip_ccw_triang_with_ccw_triang_append_to_Vec() { + VecU8 res = VecU8_from_cstr( + "void marie_clip_ccw_triang_with_ccw_triang_append_to_Vec(MarieTriangle C, MarieTriangle T, VecMarieTriangle* pile) {\n"); + for (int ord = 0; ord < 18; ord++) { + VecU8_append_vec(&res, VecU8_format(SPACE4 "bool M%d = marie_surface(", ord)); + for (int a = 0; a < 3; a++) { + if (a) + VecU8_append_span(&res, cstr(", ")); + int vsh = comparison_triang_groups[ord][a]; + VecU8_append(&res, (vsh / 10) == 1 ? 'C' : 'T'); + VecU8_append_span(&res, cstr(".v")); + VecU8_append(&res, '0' + vsh % 10); + } + VecU8_append_span(&res, cstr(") > 0;\n")); + } + generate_func_clip_triang_on_triang_case_where_some_vertex_stuck(&res, 'C', 'T'); + generate_func_clip_triang_on_triang_case_where_some_vertex_stuck(&res, 'T', 'C'); + VecU8_append_span(&res, cstr("abortf(\"todo\\n\");\n")); // todo: check for 3 hard cases: David, wedge and non-intersecting + VecU8_append_span(&res, cstr("}\n\n")); + return res; +} + +void generate_clipping_header() { + VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_L2_MARIE_CLIPPING")); + VecU8_append_span(&res, cstr("#include \"../geom.h\"\n" + "#include \"../../../src/l2/marie/geom_alg_utils.h\"\n\n")); + VecU8_append_vec(&res, generate_func_clip_ccw_triang_with_ccw_triang_append_to_Vec()); + finish_header(res, "l2/marie/clipping.h"); +} + +#endif diff --git a/src/l2/codegen/geom.h b/src/l2/codegen/geom.h index abefdb7..31cb916 100644 --- a/src/l2/codegen/geom.h +++ b/src/l2/codegen/geom.h @@ -610,8 +610,8 @@ NODISCARD VecU8 generate_xmat234x234_structs_and_methods(ConstSpanU8 xmat, Const } void generate_geom_header() { - VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_GEOM")); - VecU8_append_span(&res, cstr("#include \"../src/l1/core/int_primitives.h\"\n\n")); + VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_L2_GEOM")); + VecU8_append_span(&res, cstr("#include \"../../src/l1/core/int_primitives.h\"\n\n")); VecU8_append_vec(&res, generate_xvec234_structs_and_important_methods(cstr("cvec"), cstr("U8"))); VecU8_append_vec(&res, generate_xvec234_structs_and_important_methods(cstr("ivec"), cstr("S32"))); @@ -619,7 +619,7 @@ void generate_geom_header() { VecU8_append_vec(&res, generate_xvec234_structs_and_methods(cstr("dvec"), cstr("double"))); VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float))); VecU8_append_vec(&res, generate_xmat234x234_structs_and_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double))); - finish_header(res, "geom.h"); + finish_header(res, "l2/geom.h"); } #endif diff --git a/src/l2/codegen/pixel_masses.h b/src/l2/codegen/pixel_masses.h index d3a98f0..96ccd01 100644 --- a/src/l2/codegen/pixel_masses.h +++ b/src/l2/codegen/pixel_masses.h @@ -172,16 +172,16 @@ VecU8 generate_texture_data_struct_and_necc_methods(ConstSpanU8 texdatat, ConstS } void generate_pixel_masses_header() { - VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_PIXEL_MASSES")); + VecU8 res = begin_header(cstr("PROTOTYPE1_GEN_L2_PIXEL_MASSES")); VecU8_append_span(&res, cstr("#include \"geom.h\"\n\n")); - VecU8_append_span(&res, cstr("#include \"../src/l1/core/VecSpan_int_primitives.h\"\n\n")); - VecU8_append_span(&res, cstr("#include \"../src/l1/system/fileio.h\"\n\n")); + VecU8_append_span(&res, cstr("#include \"../../src/l1/core/VecSpan_int_primitives.h\"\n\n")); + VecU8_append_span(&res, cstr("#include \"../../src/l1/system/fileio.h\"\n\n")); VecU8_append_vec(&res, generate_type_triv_methods_and_vec(cstr("cvec3"))); VecU8_append_vec(&res, generate_type_triv_methods_and_vec(cstr("cvec4"))); VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8"), cstr("U8"))); VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8"), cstr("cvec3"))); VecU8_append_vec(&res, generate_texture_data_struct_and_necc_methods(cstr("TextureDataR8G8B8A8"), cstr("cvec4"))); - finish_header(res, "pixel_masses.h"); + finish_header(res, "l2/pixel_masses.h"); } diff --git a/src/l2/marie/clipping.h b/src/l2/marie/clipping.h deleted file mode 100644 index dd7d40a..0000000 --- a/src/l2/marie/clipping.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef PROTOTYPE1_SRC_L2_MARIE_CLIPPING_H -#define PROTOTYPE1_SRC_L2_MARIE_CLIPPING_H - -#include "graphics_geom.h" - - - -#endif diff --git a/src/l2/marie/geom_alg_utils.h b/src/l2/marie/geom_alg_utils.h new file mode 100644 index 0000000..f3e1540 --- /dev/null +++ b/src/l2/marie/geom_alg_utils.h @@ -0,0 +1,86 @@ +#ifndef PROTOTYPE_1_SRC_L2_MARIE_GEOM_ALG_UTILS_H +#define PROTOTYPE_1_SRC_L2_MARIE_GEOM_ALG_UTILS_H + +#include +#include +#include +#include +#include "../../../gen/l2/geom.h" +#include "../../l1/core/util.h" + +/* float size check and IEEE‑754 binary32 characteristic checks */ +_Static_assert(sizeof(float) == 4, + "This code assumes 32‑bit floats"); +#if defined(__STDC_IEC_559__) /* implementation claims IEC 60559 */ +_Static_assert(__STDC_IEC_559__, "Implementation is not IEC 60559"); +#else +/* Fall back to value‑based checks: radix 2, 24‑bit mantissa, exponent ranges. + These values are unique to binary32 among the formats in actual use. */ +_Static_assert(FLT_RADIX == 2, "Non‑binary radix"); +_Static_assert(FLT_MANT_DIG == 24, "Float is not binary32"); +_Static_assert(FLT_MAX_EXP == 128, "Float is not binary32"); +_Static_assert(FLT_MIN_EXP == -125, "Float is not binary32"); +#endif + +uint32_t marie_pun_float2u32(float f) { + uint32_t u; + memcpy(&u, &f, sizeof u); + return u; +} + +bool marie_same_dir3(float A0, float A1, float A2, float B) { + uint32_t bb = marie_pun_float2u32(B); + uint32_t diff = (marie_pun_float2u32(A0) ^ bb) | + (marie_pun_float2u32(A1) ^ bb) | + (marie_pun_float2u32(A2) ^ bb); + return A0 == 0 || A1 == 0 || A2 == 0 || (diff & 0x80000000u) == 0; +} + +float marie_surface(vec2 vi, vec2 vj, vec2 u) { + return u.x * (vi.y - vj.y) + u.y * (vj.x - vi.x) + (vi.x * vj.y - vj.x * vi.y); +} + +typedef vec4 MarieVertAttr; + +typedef struct { + vec2 pos; + MarieVertAttr attr; +} MariePlaneVertAttr; + +typedef struct { + vec2 v0; + vec2 v1; + vec2 v2; +} MarieTriangle; + +#define MarieTriangle_drop(x) {} +#define MarieTriangle_clone(xp) (*(xp)) + +VecT_trivmove_struct_Definition(MarieTriangle) +VecT_trivmove_method_Definition(MarieTriangle) +VecT_primitive_zeroinit_method_Definition(MarieTriangle) + +typedef struct { + MariePlaneVertAttr v0; + MariePlaneVertAttr v1; + MariePlaneVertAttr v2; +} MarieTriangleAttr; + +#define MarieTriangleAttr_drop(x) {} +#define MarieTriangleAttr_clone(xp) (*(xp)) + +VecT_trivmove_struct_Definition(MarieTriangleAttr) +VecT_trivmove_method_Definition(MarieTriangleAttr) +VecT_primitive_zeroinit_method_Definition(MarieTriangleAttr) + +vec2 marie_intersect_lines(vec2 A1, vec2 B1, vec2 A2, vec2 B2) { + vec2 alpha = vec2_minus_vec2(B1, A1); + vec2 beta = vec2_minus_vec2(A2, B2); + vec2 gamma = vec2_minus_vec2(A2, A1); + float det_alpha_beta = alpha.x * beta.y - alpha.y * beta.x; + float det_gamma_beta = gamma.x * beta.y - gamma.y * beta.x; + float t1 = det_gamma_beta / det_alpha_beta; + return vec2_add_vec2(A1, vec2_mul_scal(alpha, t1)); +} + +#endif diff --git a/src/l2/marie/graphics_geom.h b/src/l2/marie/graphics_geom.h index 0d58e3f..9491328 100644 --- a/src/l2/marie/graphics_geom.h +++ b/src/l2/marie/graphics_geom.h @@ -83,9 +83,5 @@ vec3 marie_normal_from_tang_space_gradient(float delt_x, float delta_z) { return (vec3){-delt_x * N, N, -delta_z * N}; } -float marie_surface(vec2 vi, vec2 vj, vec2 u) { - return u.x * (vi.y - vj.y) + u.y * (vj.x - vi.x) + (vi.x * vj.y - vj.x * vi.y); -} - #endif diff --git a/src/l2/marie/rasterization.h b/src/l2/marie/rasterization.h index 764671c..39b2789 100644 --- a/src/l2/marie/rasterization.h +++ b/src/l2/marie/rasterization.h @@ -1,44 +1,10 @@ #ifndef SPLITTER_DRAFT_SRC_L2_MARIE_RASTERIZATION_H #define SPLITTER_DRAFT_SRC_L2_MARIE_RASTERIZATION_H -#include "../../../gen/geom.h" -#include "../../../gen/pixel_masses.h" +#include "../../../gen/l2/geom.h" +#include "../../../gen/l2/pixel_masses.h" #include "math.h" - -#include -#include - -/* float size check and IEEE‑754 binary32 characteristic checks */ -_Static_assert(sizeof(float) == 4, - "This code assumes 32‑bit floats"); -#if defined(__STDC_IEC_559__) /* implementation claims IEC 60559 */ -_Static_assert(__STDC_IEC_559__, "Implementation is not IEC 60559"); -#else -/* Fall back to value‑based checks: radix 2, 24‑bit mantissa, exponent ranges. - These values are unique to binary32 among the formats in actual use. */ -_Static_assert(FLT_RADIX == 2, "Non‑binary radix"); -_Static_assert(FLT_MANT_DIG == 24, "Float is not binary32"); -_Static_assert(FLT_MAX_EXP == 128, "Float is not binary32"); -_Static_assert(FLT_MIN_EXP == -125, "Float is not binary32"); -#endif - -// todo: move line rasterization here (from r0 test) - -uint32_t marie_pun_float2u32(float f) { - uint32_t u; - memcpy(&u, &f, sizeof u); - return u; -} - -bool marie_same_dir3(float A0, float A1, float A2, float B) { - uint32_t bb = marie_pun_float2u32(B); - uint32_t diff = (marie_pun_float2u32(A0) ^ bb) | - (marie_pun_float2u32(A1) ^ bb) | - (marie_pun_float2u32(A2) ^ bb); - return A0 == 0 || A1 == 0 || A2 == 0 || (diff & 0x80000000u) == 0; -} - -typedef vec4 MarieVertAttr; +#include "geom_alg_utils.h" typedef struct { /* guest, x, y, attribute (custom) */ @@ -46,11 +12,6 @@ typedef struct { void* guest; } FnMarieRasterizerCallback; -typedef struct { - vec2 pos; - MarieVertAttr attr; -} MariePlaneVertAttr; - typedef struct { float c1; float c0; diff --git a/src/l2/tests/r0/r0_assets.h b/src/l2/tests/r0/r0_assets.h index 4798f0e..c6bf6ec 100644 --- a/src/l2/tests/r0/r0_assets.h +++ b/src/l2/tests/r0/r0_assets.h @@ -6,7 +6,7 @@ #include "../../../l1/core/VecSpan_int_primitives.h" #include "../../../l1/system/fileio.h" #include -#include "../../../../gen/pixel_masses.h" +#include "../../../../gen/l2/pixel_masses.h" #include "../../marie/rasterization.h" typedef struct { @@ -73,6 +73,13 @@ typedef struct { vec3 normal; } ShinyMeshVertex; +#define ShinyMeshVertex_drop(vp) {} +#define ShinyMeshVertex_clone(vp) (*(vp)) + +VecT_trivmove_struct_Definition(ShinyMeshVertex) +VecT_trivmove_method_Definition(ShinyMeshVertex) +VecT_primitive_zeroinit_method_Definition(ShinyMeshVertex) + typedef struct { mat4 model_t; vec3 color_off; diff --git a/src/l2/tests/r0/test_shaders/glsl/0/0.frag b/src/l2/tests/r0/test_shaders/glsl/0/0.frag index e533b42..aee790f 100644 --- a/src/l2/tests/r0/test_shaders/glsl/0/0.frag +++ b/src/l2/tests/r0/test_shaders/glsl/0/0.frag @@ -55,8 +55,7 @@ void main(){ Pipeline0Spotlight lamp = spotlight_arr[i]; } vec3 natural_color = texture(color_tex, fsin_tex).xyz; - // todo: add specular texture -// vec3 color = natural_color * (diffuse_illumination + specular_illumination); - vec3 color = natural_color * ( specular_illumination); + // todo: add specular map texture + vec3 color = natural_color * diffuse_illumination + 0.5 * specular_illumination; fin_color = vec4(color, 1); } diff --git a/src/l2/tests/r0/test_shaders/glsl/0b/0b.frag b/src/l2/tests/r0/test_shaders/glsl/0b/0b.frag index e69de29..d8dd12b 100644 --- a/src/l2/tests/r0/test_shaders/glsl/0b/0b.frag +++ b/src/l2/tests/r0/test_shaders/glsl/0b/0b.frag @@ -0,0 +1,55 @@ +#version 450 + +layout(location = 0) in vec3 norm; +layout(location = 1) in vec3 color_off; +layout(location = 2) in vec3 color_on; +layout(location = 3) in vec3 pos; + +layout(location = 0) out vec4 fin_color; + +layout(push_constant, std430) uniform pc { + layout(offset = 64) vec3 camera_pos; +}; + +struct Pipeline0Spotlight { + vec3 pos; + vec3 dir; + vec3 color; + float range; +}; + +struct Pipeline0PointLight { + vec3 pos; + vec3 color; +}; + +layout(std140, binding = 0) uniform Pipeline0UBO { + int point_light_count; + int spotlight_count; + Pipeline0PointLight point_light_arr[20]; + Pipeline0Spotlight spotlight_arr [120]; +}; + +float get_intensity(float dist){ + return 1 / pow(dist + 1, 2); +} + +void main(){ + vec3 diffuse_illumination = vec3(0); + vec3 specular_illumination = vec3(0); + for (int i = 0; i < point_light_count; i++) { + Pipeline0PointLight lamp = point_light_arr[i]; + vec3 to_light = -fsin_pos + lamp.pos; + float dist = length(to_light); + vec3 U = to_light / dist; + diffuse_illumination += get_intensity(dist) * max(0.02, dot(U, norm)) * lamp.color; + vec3 A = reflect(-U, norm); + vec3 B = normalize(-fsin_pos+camera_pos); + specular_illumination += get_intensity(dist) * pow(max(0, dot(A, B)), 256) * lamp.color; + } + for (int i = 0; i < spotlight_count; i++) { + Pipeline0Spotlight lamp = spotlight_arr[i]; + } + vec3 color = color_off * diffuse_illumination + 0.5 * specular_illumination + color_on; + fin_color = vec4(color, 1); +} diff --git a/src/l2/tests/r0/test_shaders/glsl/0b/0b.vert b/src/l2/tests/r0/test_shaders/glsl/0b/0b.vert index e69de29..dab3f15 100644 --- a/src/l2/tests/r0/test_shaders/glsl/0b/0b.vert +++ b/src/l2/tests/r0/test_shaders/glsl/0b/0b.vert @@ -0,0 +1,27 @@ +#version 450 + +layout(location = 0) in vec3 pos; +layout(location = 1) in vec3 normal; + +layout(location = 2) in mat4 model_t; +/* 2 <- 3,4,5 */ +layout(location = 6) in vec3 color_off; +layout(location = 7) in vec3 color_on; + +layout(location = 0) out vec3 vsout_normal; +layout(location = 1) out vec3 vsout_color_off; +layout(location = 2) out vec3 vsout_color_on; +layout(location = 3) out vec3 vsout_pos; + +layout(push_constant, std430) uniform pc { + mat4 proj_cam_t; +}; + +void main(){ + vsout_normal = normal; + vsout_color_off = color_off; + vsout_color_on = color_on; + vec4 real_pos = model_t * vec4(pos, 1); + vsout_pos = real_pos.xyz; + gl_Position = proj_cam_t * real_pos; +} \ No newline at end of file