diff --git a/src/l1/anne/some_tests.h b/src/l1/anne/some_tests.h index 48203a5..cfbdc2e 100644 --- a/src/l1/anne/some_tests.h +++ b/src/l1/anne/some_tests.h @@ -8,7 +8,7 @@ void generate_headers_for_r0_r1_r2_r3() { mkdir_nofail("l1/eve/r0"); { /* Needed in r0_assets.h */ SpanU8 ns = cstr("r0"); - generate_eve_span_company_for_primitive(l, ns, cstr("GenericMeshVertex"), true, true); + generate_eve_span_company_for_primitive(l, ns, cstr("GenericMeshVertexInc"), true, true); generate_eve_span_company_for_non_primitive_clonable(l, ns, cstr("GenericMeshInSceneTemplate"), true, false); generate_eve_span_company_for_primitive(l, ns, cstr("ShinyMeshVertexInc"), true, true); generate_eve_span_company_for_non_primitive_clonable(l, ns, cstr("ShinyMeshTopology"), true, false); diff --git a/src/l1_4/tests/t3.c b/src/l1_4/tests/t3.c index 25fa8d5..b487ebe 100644 --- a/src/l1_4/tests/t3.c +++ b/src/l1_4/tests/t3.c @@ -2,6 +2,7 @@ #include #include +#include float random_float(float a, float b){ int r = rand(); @@ -19,27 +20,56 @@ mat4 random_big_matrix(){ random_float100(), random_float100(), random_float100(), random_float100()); } +mat2 random_smol_matrix(){ + return mat2_new(random_float100(), random_float100(), random_float100(), random_float100()); +} + #define flPr "%02.05f" -void test_matrix(mat4 A){ +void test_mat4(mat4 A){ mat4 iA = mat4_inverse(A); mat4 product = mat4_mul_mat4(iA, A); printf(flPr " " flPr " " flPr " " flPr "\n" - flPr " " flPr " " flPr " " flPr "\n" - flPr " " flPr " " flPr " " flPr "\n" - flPr " " flPr " " flPr " " flPr "\n", + flPr " " flPr " " flPr " " flPr "\n" + flPr " " flPr " " flPr " " flPr "\n" + flPr " " flPr " " flPr " " flPr "\n", product.x.x, product.y.x, product.z.x, product.w.x, product.x.y, product.y.y, product.z.y, product.w.y, product.x.z, product.y.z, product.z.z, product.w.z, product.x.w, product.y.w, product.z.w, product.w.w); } -int main() { - test_matrix(random_big_matrix()); - test_matrix(random_big_matrix()); - test_matrix(random_big_matrix()); - test_matrix(random_big_matrix()); - test_matrix(random_big_matrix()); - test_matrix(random_big_matrix()); - test_matrix(random_big_matrix()); +void test_mat2(mat2 A){ + mat2 iA = mat2_inverse(A); + mat2 product = mat2_mul_mat2(iA, A); + printf(flPr " " flPr "\n" + flPr " " flPr "\n", + product.x.x, product.y.x, + product.x.y, product.y.y); +} + +void test(){ + mat2x3 A = (mat2x3){.x = {1, 2, 3}, .y = {4, 5, 6}}; + mat3x2 At = mat2x3_transpose(A); + assert(At.x.x == 1); + assert(At.x.y == 4); + assert(At.y.x == 2); + assert(At.y.y == 5); + assert(At.z.x == 3); + assert(At.z.y == 6); +} + +int main() { + test(); + test_mat4(random_big_matrix()); + test_mat4(random_big_matrix()); + test_mat4(random_big_matrix()); + test_mat4(random_big_matrix()); + test_mat4(random_big_matrix()); + test_mat4(random_big_matrix()); + test_mat4(random_big_matrix()); + test_mat2(random_smol_matrix()); + test_mat2(random_smol_matrix()); + test_mat2(random_smol_matrix()); + test_mat2(random_smol_matrix()); } diff --git a/src/l2/margaret/vulkan_utils.h b/src/l2/margaret/vulkan_utils.h index 2cb908d..9624070 100644 --- a/src/l2/margaret/vulkan_utils.h +++ b/src/l2/margaret/vulkan_utils.h @@ -1065,8 +1065,8 @@ VkPipeline margaret_create_triangle_pipeline_one_attachment( .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, .depthClampEnable = VK_FALSE, .polygonMode = VK_POLYGON_MODE_FILL, - // .cullMode = VK_CULL_MODE_BACK_BIT, - .cullMode = VK_CULL_MODE_NONE, + .cullMode = VK_CULL_MODE_BACK_BIT, + // .cullMode = VK_CULL_MODE_NONE, .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, .depthBiasEnable = VK_FALSE, .depthBiasConstantFactor = 0.0f, diff --git a/src/l2/tests/r0/r0.c b/src/l2/tests/r0/r0.c index f32ab31..d38be21 100644 --- a/src/l2/tests/r0/r0.c +++ b/src/l2/tests/r0/r0.c @@ -173,38 +173,68 @@ PipelineHands create_graphics_pipeline_0( .inputRate = VK_VERTEX_INPUT_RATE_INSTANCE, } }; - VkVertexInputAttributeDescription vertex_attributes[2 + 4] = { + VkVertexInputAttributeDescription vertex_attributes[2 + 3 + 4 + 3] = { { .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, - .offset = offsetof(GenericMeshVertex, pos), + .offset = offsetof(GenericMeshVertexInc, pos), }, { .location = 1, .binding = 0, .format = VK_FORMAT_R32G32_SFLOAT, - .offset = offsetof(GenericMeshVertex, tex), + .offset = offsetof(GenericMeshVertexInc, tex), + }, + { + .location = 2, .binding = 0, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(GenericMeshVertex, norm), + }, + { + .location = 3, .binding = 0, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(GenericMeshVertex, tang_U), + }, + { + .location = 4, .binding = 0, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(GenericMeshVertex, tang_V), }, /* This is a mat4 datatype, so it will take 4 entire 'locations' */ - { - .location = 2, .binding = 1, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = offsetof(GenericMeshInstance, model_t) + offsetof(mat4, x) - }, - { - .location = 3, .binding = 1, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = offsetof(GenericMeshInstance, model_t) + offsetof(mat4, y) - }, - { - .location = 4, .binding = 1, - .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = offsetof(GenericMeshInstance, model_t) + offsetof(mat4, z) - }, { .location = 5, .binding = 1, .format = VK_FORMAT_R32G32B32A32_SFLOAT, - .offset = offsetof(GenericMeshInstance, model_t) + offsetof(mat4, w) + .offset = offsetof(GenericMeshInstanceInc, model_t) + offsetof(mat4, x) + }, + { + .location = 6, .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(GenericMeshInstanceInc, model_t) + offsetof(mat4, y) + }, + { + .location = 7, .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(GenericMeshInstanceInc, model_t) + offsetof(mat4, z) + }, + { + .location = 8, .binding = 1, + .format = VK_FORMAT_R32G32B32A32_SFLOAT, + .offset = offsetof(GenericMeshInstanceInc, model_t) + offsetof(mat4, w) + }, + { + .location = 9, .binding = 1, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(GenericMeshInstance, normal_t) + offsetof(mat3, x) + }, + { + .location = 10, .binding = 1, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(GenericMeshInstance, normal_t) + offsetof(mat3, y) + }, + { + .location = 11, .binding = 1, + .format = VK_FORMAT_R32G32B32_SFLOAT, + .offset = offsetof(GenericMeshInstance, normal_t) + offsetof(mat3, z) }, }; @@ -273,7 +303,7 @@ PipelineHands create_graphics_pipeline_0_b( { .location = 0, .binding = 0, .format = VK_FORMAT_R32G32B32_SFLOAT, - .offset = offsetof(ShinyMeshVertex, pos), + .offset = offsetof(ShinyMeshVertexInc, pos), }, { .location = 1, .binding = 0, @@ -814,16 +844,23 @@ void update_state(state_r0* state, uint32_t dur) { ObjectInfo* oi = &state->vk.scene.smeshnyavka_3.buf[i]; vec3 p1 = state->vk.scene.cam.pos; vec3 r = vec3_normalize(vec3_minus_vec3(p1, oi->pos)); - oi->rotation = mat3_mul_mat3(marie_3d_rot_mat3(r, fl * 0.5f), oi->rotation); + oi->rotation = mat3_mul_mat3(marie_3d_rot_mat3(r, fl * 0.7f), oi->rotation); Scene_update_smeshnyavka_3(&state->vk.scene, i); } } + if (state->first_0x80_keys[XKB_KEY_bracketleft]) { + for (size_t i = 0; i < state->vk.scene.smeshnyavka_1.len; i++) { + ObjectInfo* oi = &state->vk.scene.smeshnyavka_1.buf[i]; + oi->rotation = mat3_mul_mat3(marie_3d_rot_mat3((vec3){0, 0, 1}, fl * 0.4f), oi->rotation); + Scene_update_smeshnyavka_1(&state->vk.scene, i); + } + } if (state->first_0x80_keys[XKB_KEY_minus]) { for (size_t i = 0; i < state->vk.scene.smeshnyavka_3.len; i++) { ObjectInfo* oi = &state->vk.scene.smeshnyavka_3.buf[i]; vec3 p1 = state->vk.scene.cam.pos; float dist = vec3_length(vec3_minus_vec3(p1, oi->pos)); - float fac = 40/dist; + float fac = 80/dist; oi->scale *= (1 - 0.01f * fl * fac); Scene_update_smeshnyavka_3(&state->vk.scene, i); } @@ -833,7 +870,7 @@ void update_state(state_r0* state, uint32_t dur) { ObjectInfo* oi = &state->vk.scene.smeshnyavka_3.buf[i]; vec3 p1 = state->vk.scene.cam.pos; float dist = vec3_length(vec3_minus_vec3(p1, oi->pos)); - float fac = 40/dist; + float fac = 80/dist; oi->scale *= (1 + 0.01f * fl * fac); Scene_update_smeshnyavka_3(&state->vk.scene, i); } @@ -842,22 +879,21 @@ void update_state(state_r0* state, uint32_t dur) { { GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_mat(&state->vk.scene.generic_models, 0); assert(model->instance_attr.count >= 1); - GenericMeshInstance* instances = (GenericMeshInstance*)MargaretSubbuf_get_mapped(&model->instance_attr.staging_updatable); if (state->first_0x80_keys[XKB_KEY_j]) { state->vk.scene.funny_vector.x -= fl; - instances[0].model_t = marie_translation_mat4(state->vk.scene.funny_vector); + GenericModelOnSceneMem_set(model, 0, (GenericMeshInstanceInc){.model_t = marie_translation_mat4(state->vk.scene.funny_vector)}); } if (state->first_0x80_keys[XKB_KEY_k]) { state->vk.scene.funny_vector.z -= fl; - instances[0].model_t = marie_translation_mat4(state->vk.scene.funny_vector); + GenericModelOnSceneMem_set(model, 0, (GenericMeshInstanceInc){.model_t = marie_translation_mat4(state->vk.scene.funny_vector)}); } if (state->first_0x80_keys[XKB_KEY_l]) { state->vk.scene.funny_vector.z += fl; - instances[0].model_t = marie_translation_mat4(state->vk.scene.funny_vector); + GenericModelOnSceneMem_set(model, 0, (GenericMeshInstanceInc){.model_t = marie_translation_mat4(state->vk.scene.funny_vector)}); } if (state->first_0x80_keys[XKB_KEY_semicolon]) { state->vk.scene.funny_vector.x += fl; - instances[0].model_t = marie_translation_mat4(state->vk.scene.funny_vector); + GenericModelOnSceneMem_set(model, 0, (GenericMeshInstanceInc){.model_t = marie_translation_mat4(state->vk.scene.funny_vector)}); } } } @@ -1553,7 +1589,7 @@ int main() { vk->host_visible_mem_mv_command_buf = margaret_allocate_command_buffer(vk->device, vk->command_pool); // todo: write a descriptor set allocator (in Margaret) that manages synamic descript or pool allocatrinonsasdasdasd - vk->descriptor_pool = margaret_create_descriptor_set_pool(vk->device, 100 ,100, 100); + vk->descriptor_pool = margaret_create_descriptor_set_pool(vk->device, 100, 100, 100); /* Here we search physical device memory types for the one with host-visible flag and the other with device-local flag */ VkPhysicalDeviceMemoryProperties mem_properties; @@ -1609,8 +1645,8 @@ int main() { VecGenericMeshInSceneTemplate_append(&vk->scene_template.generic_models, GenericMeshInSceneTemplate_for_log(10, 2, 6)); - VecGenericMeshInSceneTemplate_append(&vk->scene_template.generic_models, - GenericMeshInSceneTemplate_for_log(5, 5, 10)); + // VecGenericMeshInSceneTemplate_append(&vk->scene_template.generic_models, + // GenericMeshInSceneTemplate_for_log(5, 5, 10)); VecShinyMeshTopology_append(&vk->scene_template.shiny_models, generate_shiny_cube(0.3f)); VecGenericModelOnSceneMem generic_model_mem = VecGenericModelOnSceneMem_new(); @@ -1709,26 +1745,14 @@ int main() { { GenericModelOnSceneMem *model_g = VecGenericModelOnSceneMem_mat(&vk->scene.generic_models, 0); - GenericMeshInstance* g_instances = (GenericMeshInstance*)MargaretSubbuf_get_mapped(&model_g->instance_attr.staging_updatable); assert(model_g->instance_attr.cap >= 100); for (int X = 0; X < 10; X++) { for (int Z = 0; Z < 10; Z++) { - g_instances[X * 10 + Z] = (GenericMeshInstance){ - .model_t = marie_translation_mat4((vec3){11.f * (float)X, -6, 4.f * (float)Z}) }; + Scene_add_smeshnyavka_1(&vk->scene, (ObjectInfo){ + .pos = (vec3){11.f * (float)X, -6, 4.f * (float)Z}, + .scale = 1, .rotation = mat3_E}); } } - model_g->instance_attr.count = 100; - - GenericModelOnSceneMem *model_g2 = VecGenericModelOnSceneMem_mat(&vk->scene.generic_models, 1); - GenericMeshInstance* g2_instances = (GenericMeshInstance*)MargaretSubbuf_get_mapped(&model_g2->instance_attr.staging_updatable); - assert(model_g2->instance_attr.cap >= 25); - for (int X = 0; X < 5; X++) { - for (int Z = 0; Z < 5; Z++) { - g2_instances[X * 5 + Z] = (GenericMeshInstance){ - .model_t = marie_translation_mat4((vec3){6.f * (float)X, -12, 6.f * (float)Z}) }; - } - } - model_g2->instance_attr.count = 25; for (int X = 0; X < 10; X++) { for (int Z = 0; Z < 10; Z++) { diff --git a/src/l2/tests/r0/r0_assets.h b/src/l2/tests/r0/r0_assets.h index f63b5c3..888d27e 100644 --- a/src/l2/tests/r0/r0_assets.h +++ b/src/l2/tests/r0/r0_assets.h @@ -13,21 +13,29 @@ typedef struct { vec3 pos; vec2 tex; -} GenericMeshVertex; -#include "../../../../gen/l1/eve/r0/VecAndSpan_GenericMeshVertex.h" +} GenericMeshVertexInc; + +#include "../../../../gen/l1/eve/r0/VecAndSpan_GenericMeshVertexInc.h" typedef struct { - VecGenericMeshVertex vertices; + GenericMeshVertexInc base; + vec3 norm; + vec3 tang_U; + vec3 tang_V; +} GenericMeshVertex; + +typedef struct { + VecGenericMeshVertexInc vertices; VecU32 indexes; } GenericMeshTopology; void GenericMeshTopology_drop(GenericMeshTopology self) { - VecGenericMeshVertex_drop(self.vertices); + VecGenericMeshVertexInc_drop(self.vertices); VecU32_drop(self.indexes); } GenericMeshTopology GenericMeshTopology_clone(const GenericMeshTopology* self) { - return (GenericMeshTopology){.vertices = VecGenericMeshVertex_clone(&self->vertices), .indexes = VecU32_clone(&self->indexes)}; + return (GenericMeshTopology){.vertices = VecGenericMeshVertexInc_clone(&self->vertices), .indexes = VecU32_clone(&self->indexes)}; } typedef struct { @@ -55,6 +63,11 @@ GenericMeshInSceneTemplate GenericMeshInSceneTemplate_clone(const GenericMeshInS typedef struct { mat4 model_t; +} GenericMeshInstanceInc; + +typedef struct { + GenericMeshInstanceInc base; + mat3 normal_t; } GenericMeshInstance; @@ -63,7 +76,7 @@ typedef struct { } ShinyMeshVertexInc; typedef struct { - vec3 pos; + ShinyMeshVertexInc base; vec3 normal; } ShinyMeshVertex; #include "../../../../gen/l1/eve/r0/VecAndSpan_ShinyMeshVertexInc.h" @@ -186,53 +199,55 @@ GenericMeshTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) { const vec2 v1tex = {(r + w) / tex_width, r / tex_height}; const vec2 v2tex = {r / tex_width, 2 * r / tex_height}; const vec2 v3tex = {(r + w) / tex_width, 2 * r / tex_height}; - VecGenericMeshVertex vertices = VecGenericMeshVertex_new_reserved(6 + 4 * k + (k + 2) * 2); - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {0, 0, 0}, .tex = v0tex}); - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {w, 0, 0}, .tex = v1tex}); - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {0, r, 0}, .tex = v2tex}); - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {w, r, 0}, .tex = v3tex}); - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {0, 0, -r}, .tex = {r / tex_width, 0}}); - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {w, 0, -r}, .tex = {(r + w) / tex_width, 0}}); + VecGenericMeshVertexInc vertices = VecGenericMeshVertexInc_new_reserved(8 + 4 * k + (k + 2) * 2); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {0, 0, 0}, .tex = v0tex}); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {w, 0, 0}, .tex = v1tex}); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {0, r, 0}, .tex = v2tex}); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {w, r, 0}, .tex = v3tex}); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {0, 0, 0}, .tex = v0tex}); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {w, 0, 0}, .tex = v1tex}); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {0, 0, -r}, .tex = {r / tex_width, 0}}); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {w, 0, -r}, .tex = {(r + w) / tex_width, 0}}); for (U32 i = 0; i < k; i++) { for (int j = 0; j < 2; j++) { - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){ + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){ .pos = {0, cosf(a * (float)(i + j)) * r, -sinf(a * (float)(i + j)) * r}, .tex = {v2tex.x, v2tex.y + (float)(i + j) * l / tex_height} }); - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){ + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){ .pos = {w, cosf(a * (float)(i + j)) * r, -sinf(a * (float)(i + j)) * r}, .tex = {v3tex.x, v3tex.y + (float)(i + j) * l / tex_height} }); } } - assert(vertices.len == 6 + 4 * k); + assert(vertices.len == 8 + 4 * k); for (U32 i = 0; i <= k; i++) { - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){ + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){ .pos = {0, cosf(a * (float)i) * r, -sinf(a * (float)i) * r}, .tex = (vec2){ (r - r *sinf(a * (float)i)) / tex_width, (r + r * cosf(a * (float)i)) / tex_height}, }); } - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {0, 0, 0}, .tex = v0tex}); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {0, 0, 0}, .tex = v0tex}); for (U32 i = 0; i <= k; i++) { - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){ + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){ .pos = {w, cosf(a * (float)i) * r, -sinf(a * (float)i) * r}, .tex = (vec2){ (r + w + r * sinf(a * (float)i)) / tex_width, (r + r * cosf(a * (float)i)) / tex_height}, }); } - VecGenericMeshVertex_append(&vertices, (GenericMeshVertex){.pos = {w, 0, 0}, .tex = v1tex}); - assert(vertices.len == 6 + 4 * k + (k + 2) * 2); + VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {w, 0, 0}, .tex = v1tex}); + assert(vertices.len == 8 + 4 * k + (k + 2) * 2); VecU32 indexes = VecU32_new_reserved(3*(4+2*k+2*k)); - U32 _span_0[] = {5, 1, 0, 5, 0, 4, 1, 3, 0, 3, 2, 0}; + U32 _span_0[] = {7, 5, 4, 7, 4, 6, 1, 3, 0, 3, 2, 0}; VecU32_append_span(&indexes, (SpanU32){.data = _span_0, .len = ARRAY_SIZE(_span_0)}); for (U32 i = 0; i < k; i++) { U32 _span_1[] = { - 6 + 4 * k + k + 1, 6 + 4 * k + i, 6 + 4 * k + i + 1, - 6 + 4 * k + 2 * k + 3, 6 + 4 * k + (k + 2) + i + 1, 6 + 4 * k + (k + 2) + i, - 6 + 4 * i + 0, 6 + 4 * i + 1, 6 + 4 * i + 3, - 6 + 4 * i + 0, 6 + 4 * i + 3, 6 + 4 * i + 2, + 8 + 4 * k + k + 1, 8 + 4 * k + i, 8 + 4 * k + i + 1, + 8 + 4 * k + 2 * k + 3, 8 + 4 * k + (k + 2) + i + 1, 8 + 4 * k + (k + 2) + i, + 8 + 4 * i + 0, 8 + 4 * i + 1, 8 + 4 * i + 3, + 8 + 4 * i + 0, 8 + 4 * i + 3, 8 + 4 * i + 2, }; VecU32_append_span(&indexes, (SpanU32){.data = _span_1, .len = ARRAY_SIZE(_span_1)}); } @@ -458,8 +473,8 @@ cvec3 Bublazhuzhka_get_color(const Bublazhuzhka* self, vec2 v) { 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)}; +cvec4 compress_normal_vec_into_norm_texel(vec3 n) { + return (cvec4){(U32)roundf(255 * (n.x + 1) / 2), (U32)roundf(255 * (n.y + 1) / 2), (U32)roundf(255 * (n.z + 1) / 2), 255}; } @@ -477,8 +492,7 @@ typedef struct { void draw_polygon_on_normal_texture_smooth_param_surf_h_draw_cb(void* ug, S32 x, S32 y, vec4 attr) { draw_polygon_on_normal_texture_smooth_param_surf_H_DrawGuest* g = ug; vec3 normal = g->my_client.fn(g->my_client.guest, (vec2){attr.x, attr.y}); - cvec3 ans = compress_normal_vec_into_norm_texel(normal); - *TextureDataR8G8B8A8_mat(g->tex, x, y) = (cvec4){ans.x, ans.y, ans.z, 255}; + *TextureDataR8G8B8A8_mat(g->tex, x, y) = compress_normal_vec_into_norm_texel(normal); } void draw_polygon_on_normal_texture_smooth_param_surf( @@ -501,21 +515,27 @@ typedef struct { } FnNormalVectorGenExaggParamCallback; typedef struct { - TextureDataR8G8B8* tex; + TextureDataR8G8B8A8* tex; FnNormalVectorGenExaggParamCallback my_client; + mat3 BNT_trans; } draw_polygon_on_normal_texture_exaggerated_param_surf_H_DrawGuest; void draw_polygon_on_normal_texture_exaggerated_param_surf_draw_cb(void* ug, S32 x, S32 y, vec4 attr) { draw_polygon_on_normal_texture_exaggerated_param_surf_H_DrawGuest* g = ug; vec3 normal = g->my_client.fn(g->my_client.guest, (vec3){attr.x, attr.y, attr.z}); - *TextureDataR8G8B8_mat(g->tex, x, y) = compress_normal_vec_into_norm_texel(normal); + vec3 tang_normal = mat3_mul_vec3(g->BNT_trans, normal); + *TextureDataR8G8B8A8_mat(g->tex, x, y) = compress_normal_vec_into_norm_texel(tang_normal); } -/* We can't derive texture coordinates from parameter space coordinates, you have to do it yourself */ +/* We can't derive texture coordinates from parameter space coordinates, you have to do it yourself. + * Also, we have to convert normal vector in world space to normal space in tangent space. + * You specify an orthogonal basis of tangent space of that triangle: BNT - { tangent_U, normal vector tangent_ } */ void draw_polygon_on_normal_texture_nat_cords_exaggerated_param_surf( - TextureDataR8G8B8* tex, vec2 ta, vec2 tb, vec2 tc, vec3 pa, vec3 pb, vec3 pc, FnNormalVectorGenExaggParamCallback cb + TextureDataR8G8B8A8* tex, vec2 ta, vec2 tb, vec2 tc, vec3 pa, vec3 pb, vec3 pc, FnNormalVectorGenExaggParamCallback cb, + mat3 BNT ) { - draw_polygon_on_normal_texture_exaggerated_param_surf_H_DrawGuest aboba = {.tex = tex, .my_client = cb}; + draw_polygon_on_normal_texture_exaggerated_param_surf_H_DrawGuest aboba = {.tex = tex, .my_client = cb, + .BNT_trans = mat3_transpose(BNT)}; marie_rasterize_triangle_with_attr( (MariePlaneVertAttr){.pos = ta, .attr = {pa.x, pa.y, pa.z, 0} }, (MariePlaneVertAttr){.pos = tb, .attr = {pb.x, pb.y, pb.z, 0} }, @@ -523,32 +543,33 @@ void draw_polygon_on_normal_texture_nat_cords_exaggerated_param_surf( (FnMarieRasterizerCallback){draw_polygon_on_normal_texture_exaggerated_param_surf_draw_cb, (void*)&aboba}); } // todo: add a version for that function with non-native coordinate system (on vertex) (like I did with absolutely flat surface) +// todo: also, maybe, add a function to derive BNT and do cool stuff with trop mat3x2 typedef struct { TextureDataR8G8B8A8* tex; - cvec3 normal_compr; } draw_polygon_on_normal_texture_absolutely_flat_H_DrawGuest; void draw_polygon_on_normal_texture_absolutely_flat_h_draw_cb(void* ug, S32 x, S32 y, vec4 attr) { draw_polygon_on_normal_texture_absolutely_flat_H_DrawGuest* g = ug; - *TextureDataR8G8B8A8_mat(g->tex, x, y) = (cvec4){g->normal_compr.x, g->normal_compr.y, g->normal_compr.z, 255}; + *TextureDataR8G8B8A8_mat(g->tex, x, y) = compress_normal_vec_into_norm_texel((vec3){0, 1, 0}); } void draw_polygon_on_normal_texture_nat_cords_absolutely_flat(TextureDataR8G8B8A8* tex, - vec2 ta, vec2 tb, vec2 tc, vec3 c_normal + vec2 ta, vec2 tb, vec2 tc ) { - draw_polygon_on_normal_texture_absolutely_flat_H_DrawGuest aboba = {tex, compress_normal_vec_into_norm_texel(c_normal)}; + draw_polygon_on_normal_texture_absolutely_flat_H_DrawGuest aboba = {tex}; marie_rasterize_triangle_with_attr((MariePlaneVertAttr){.pos = ta}, (MariePlaneVertAttr){.pos = tb}, (MariePlaneVertAttr){.pos = tc}, (FnMarieRasterizerCallback){ .fn = draw_polygon_on_normal_texture_absolutely_flat_h_draw_cb, .guest = (void*)&aboba}); } +// todo: replace it with a "color everything in one color" function void draw_polygon_on_normal_texture_absolutely_flat(TextureDataR8G8B8A8* tex, - vec2 pa, vec2 pb, vec2 pc, mat3x2 trop, vec3 c_normal - ) { + vec2 pa, vec2 pb, vec2 pc, mat3x2 trop +) { draw_polygon_on_normal_texture_nat_cords_absolutely_flat(tex, mat3x2_mul_vec3(trop, vec2_and_one(pa)), - mat3x2_mul_vec3(trop, vec2_and_one(pb)), mat3x2_mul_vec3(trop, vec2_and_one(pc)), c_normal); + mat3x2_mul_vec3(trop, vec2_and_one(pb)), mat3x2_mul_vec3(trop, vec2_and_one(pc))); } @@ -559,21 +580,20 @@ typedef struct { } FnHeightMapGradFlatSurfCallback; typedef struct { - mat3 surf_orient; FnHeightMapGradFlatSurfCallback my_client; } draw_polygon_on_normal_texture_flat_param_surf_H_DrawGuest; vec3 draw_polygon_on_normal_texture_flat_param_surf_h_draw_cb(void* ug, vec2 p) { draw_polygon_on_normal_texture_flat_param_surf_H_DrawGuest* g = ug; vec2 grad = g->my_client.fn(g->my_client.guest, p); - return mat3_mul_vec3(g->surf_orient, marie_normal_from_tang_space_gradient(grad.x, grad.y)); + return marie_normal_from_tang_space_gradient(grad.x, grad.y); // todo: remove this cluster, while leaving only this function where it's nee } /* The simplest case of normal texture generation: for a smooth flat surface of a polygon */ void draw_polygon_on_normal_texture_flat_param_surf(TextureDataR8G8B8A8* tex, vec2 pa, vec2 pb, vec2 pc, mat3x2 trop, - mat3 surf_orient, FnHeightMapGradFlatSurfCallback height_map_cb + FnHeightMapGradFlatSurfCallback height_map_cb ) { - draw_polygon_on_normal_texture_flat_param_surf_H_DrawGuest aboba = {surf_orient, height_map_cb}; + draw_polygon_on_normal_texture_flat_param_surf_H_DrawGuest aboba = {height_map_cb}; draw_polygon_on_normal_texture_smooth_param_surf(tex, pa, pb, pc, trop, (FnNormalVectorGenCallback){ .fn = draw_polygon_on_normal_texture_flat_param_surf_h_draw_cb, .guest = (void*)&aboba}); } @@ -683,34 +703,32 @@ TextureDataR8G8B8A8 generate_normal_tex_for_one_fourth_of_a_cylinder(float s_res Bublazhuzhka crap_on_the_back_side = fill_rectangle_with_crap(w, r); mat3x2 trop_back_side = {.x.x = cord_resol.x, .y.y = cord_resol.y, .z = vec2_mul_vec2((vec2){r, r}, cord_resol)}; - mat3 orient_back_side = {.x = {1, 0, 0}, .y = {0, 0, 1}, .z = {0, 1, 0}}; - draw_polygon_on_normal_texture_flat_param_surf(&res, (vec2){0, 0}, (vec2){w, 0}, (vec2){w, r}, trop_back_side, orient_back_side, + draw_polygon_on_normal_texture_flat_param_surf(&res, (vec2){0, 0}, (vec2){w, 0}, (vec2){w, r}, trop_back_side, (FnHeightMapGradFlatSurfCallback){.fn = height_map_cb_that_uses_bublazhuzhka, .guest = &crap_on_the_back_side}); - draw_polygon_on_normal_texture_flat_param_surf(&res, (vec2){0, 0}, (vec2){0, r}, (vec2){w, r}, trop_back_side, orient_back_side, + draw_polygon_on_normal_texture_flat_param_surf(&res, (vec2){0, 0}, (vec2){0, r}, (vec2){w, r}, trop_back_side, (FnHeightMapGradFlatSurfCallback){.fn = height_map_cb_that_uses_bublazhuzhka, .guest = &crap_on_the_back_side}); Bublazhuzhka_drop(crap_on_the_back_side); mat3x2 str = {.x.x = cord_resol.x, .y.y = cord_resol.y}; - draw_polygon_on_normal_texture_absolutely_flat(&res, v0tex, v1tex, v4tex, str, (vec3){0, -1, 0}); - draw_polygon_on_normal_texture_absolutely_flat(&res, v1tex, v4tex, v5tex, str, (vec3){0, -1, 0}); + draw_polygon_on_normal_texture_absolutely_flat(&res, v0tex, v1tex, v4tex, str); + draw_polygon_on_normal_texture_absolutely_flat(&res, v1tex, v4tex, v5tex, str); for (size_t i = 0; i < k; i++) { vec2 A = {r - sinf((float)i * a) * r, r + cosf((float)i * a) * r}; vec2 B = {r - sinf((float)(i + 1) * a) * r, r + cosf((float)(i + 1) * a) * r}; - draw_polygon_on_normal_texture_absolutely_flat(&res, A, B, (vec2){r, r}, str, (vec3){-1, 0, 0}); + draw_polygon_on_normal_texture_absolutely_flat(&res, A, B, (vec2){r, r}, str); } for (size_t i = 0; i < k; i++) { vec2 A = {r + w + sinf((float)i * a) * r, r + cosf((float)i * a) * r}; vec2 B = {r + w + sinf((float)(i + 1) * a) * r, r + cosf((float)(i + 1) * a) * r}; - draw_polygon_on_normal_texture_absolutely_flat(&res, A, B, (vec2){r + w, r}, str, (vec3){1, 0, 0}); + draw_polygon_on_normal_texture_absolutely_flat(&res, A, B, (vec2){r + w, r}, str); } for (size_t i = 0; i < k; i++) { vec2 A = {r, 2 * r + (float)i * l}; vec2 B = {r + w, 2 * r + (float)i * l}; vec2 C = {r, 2 * r + (float)i * l + l}; vec2 D = {r + w, 2 * r + (float)i * l + l}; - vec3 n = {0, cosf(a / 2 + a * (float)i), -sinf(a / 2 + a * (float)i)}; - draw_polygon_on_normal_texture_absolutely_flat(&res, A, B, C, str, n); - draw_polygon_on_normal_texture_absolutely_flat(&res, D, B, C, str, n); + draw_polygon_on_normal_texture_absolutely_flat(&res, A, B, C, str); + draw_polygon_on_normal_texture_absolutely_flat(&res, D, B, C, str); } return res; } diff --git a/src/l2/tests/r0/r0_scene.h b/src/l2/tests/r0/r0_scene.h index 8b08a26..2c955ae 100644 --- a/src/l2/tests/r0/r0_scene.h +++ b/src/l2/tests/r0/r0_scene.h @@ -46,6 +46,17 @@ typedef struct { #include "../../../../gen/l1/eve/r0/VecGenericModelOnSceneMem.h" +void GenericModelOnSceneMem_set(GenericModelOnSceneMem* self, size_t instance, GenericMeshInstanceInc uncomp){ + assert(instance < self->instance_attr.count); + GenericMeshInstance* staging = (GenericMeshInstance*)MargaretSubbuf_get_mapped(&self->instance_attr.staging_updatable); + staging[instance].base = uncomp; + mat4 tr_inv = mat4_transpose(mat4_inverse(uncomp.model_t)); + staging[instance].normal_t = mat3_new( + tr_inv.x.x, tr_inv.y.x, tr_inv.z.x, + tr_inv.x.y, tr_inv.y.y, tr_inv.z.y, + tr_inv.x.z, tr_inv.y.z, tr_inv.z.z ); +} + typedef struct { size_t indexes; @@ -161,38 +172,56 @@ typedef struct { ShinyMeshInstanceInc ShinyMeshInstanceInc_from_ObjectInfo(const ObjectInfo* oi){ return (ShinyMeshInstanceInc){ .model_t = mat4_mul_mat4(marie_translation_mat4(oi->pos), - mat4_mul_mat4(mat4_new( - oi->scale, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, oi->scale, 0, - 0, 0, 0, 1), marie_mat3_to_mat4(oi->rotation))), - .color_on = oi->color_on, .color_off = {1, 0.4f, 0.5f} }; + mat4_mul_mat4(marie_3d_scal_mat4(oi->scale), marie_mat3_to_mat4(oi->rotation))), + .color_on = oi->color_on, .color_off = {1, 0.4f, 0.5f} + }; } +// todo: remove this shit void Scene_add_smeshnyavka_3(Scene* self, ObjectInfo oi){ ShinyModelOnSceneMem* model_sh = VecShinyModelOnSceneMem_mat(&self->shiny_models, 0); size_t ni = self->smeshnyavka_3.len; assert(ni < model_sh->instance_attr.cap); VecObjectInfo_append(&self->smeshnyavka_3, oi); model_sh->instance_attr.count = ni + 1; - // ShinyModelOnSceneMem_set(model_sh, ni, (ShinyMeshInstanceInc){ - // .model_t = mat4_mul_mat4(marie_translation_mat4(oi.pos), - // mat4_mul_mat4(marie_3d_scal_mat4(oi.scale), marie_mat3_to_mat4(oi.rotation))), - // .color_on = oi.color_on, .color_off = {1, 0.4f, 0.5f} }); ShinyModelOnSceneMem_set(model_sh, ni, ShinyMeshInstanceInc_from_ObjectInfo(&oi)); } +// todo: remove this shit void Scene_update_smeshnyavka_3(Scene* self, size_t sh_id){ assert(sh_id < self->smeshnyavka_3.len); const ObjectInfo* oi = VecObjectInfo_at(&self->smeshnyavka_3, sh_id); ShinyModelOnSceneMem* model_sh = VecShinyModelOnSceneMem_mat(&self->shiny_models, 0); - // ShinyModelOnSceneMem_set(model_sh, sh_id, (ShinyMeshInstanceInc){ - // .model_t = mat4_mul_mat4(marie_translation_mat4(oi->pos), - // mat4_mul_mat4(marie_3d_scal_mat4(oi->scale), marie_mat3_to_mat4(oi->rotation))), - // .color_on = oi->color_on, .color_off = {1, 0.4f, 0.5f} }); ShinyModelOnSceneMem_set(model_sh, sh_id, ShinyMeshInstanceInc_from_ObjectInfo(oi)); } +GenericMeshInstanceInc GenericMeshInstanceInc_from_ObjectInfo(const ObjectInfo* oi){ + return (GenericMeshInstanceInc){ + .model_t = mat4_mul_mat4(marie_translation_mat4(oi->pos), + mat4_mul_mat4(marie_3d_scal_mat4(oi->scale), marie_mat3_to_mat4(oi->rotation))), + }; +} + +// todo: remove this shit +void Scene_add_smeshnyavka_1(Scene* self, ObjectInfo oi){ + GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_mat(&self->generic_models, 0); + size_t ni = self->smeshnyavka_1.len; + assert(ni < model->instance_attr.cap); + VecObjectInfo_append(&self->smeshnyavka_1, oi); + model->instance_attr.count = ni + 1; + GenericModelOnSceneMem_set(model, ni, GenericMeshInstanceInc_from_ObjectInfo(&oi)); +} + +// todo: remove this shit +void Scene_update_smeshnyavka_1(Scene* self, size_t sh_id){ + assert(sh_id < self->smeshnyavka_1.len); + const ObjectInfo* oi = VecObjectInfo_at(&self->smeshnyavka_1, sh_id); + GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_mat(&self->generic_models, 0); + GenericModelOnSceneMem_set(model, sh_id, GenericMeshInstanceInc_from_ObjectInfo(oi)); +} + + + Scene Scene_new(VecGenericModelOnSceneMem generic_models, VecShinyModelOnSceneMem shiny_models, Pipeline0Transfer pipeline0_ubo) { return (Scene){.generic_models = generic_models, .shiny_models = shiny_models, @@ -220,10 +249,35 @@ void SceneTemplate_copy_initial_model_topology_cmd_buf_recording( const GenericMeshInSceneTemplate* mt = VecGenericMeshInSceneTemplate_at(&scene_template->generic_models, mi); const GenericModelOnSceneMem *mm = VecGenericModelOnSceneMem_at(&scene->generic_models, mi); - size_t vbo_len = mt->topology.vertices.len * sizeof(GenericMeshVertex); - assert(mm->vbo.len >= vbo_len); + assert(mm->staging_vbo.len >= mt->topology.vertices.len * sizeof(GenericMeshVertex)); + assert(mm->vbo.len >= mt->topology.vertices.len * sizeof(GenericMeshVertex)); GenericMeshVertex* staging_vbo = (GenericMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo); - memcpy(staging_vbo, mt->topology.vertices.buf, vbo_len); + for (U64 i = 0; i < mt->topology.vertices.len; i++) { + staging_vbo[i].base = mt->topology.vertices.buf[i]; + } + assert(mt->topology.indexes.len % 3 == 0); + for (size_t ti = 0; ti * 3 < mt->topology.indexes.len; ti++) { + U32 v0 = mt->topology.indexes.buf[ti * 3 + 0]; + U32 v1 = mt->topology.indexes.buf[ti * 3 + 1]; + U32 v2 = mt->topology.indexes.buf[ti * 3 + 2]; + const GenericMeshVertexInc* A0 = VecGenericMeshVertexInc_at(&mt->topology.vertices, v0); + const GenericMeshVertexInc* A1 = VecGenericMeshVertexInc_at(&mt->topology.vertices, v1); + const GenericMeshVertexInc* A2 = VecGenericMeshVertexInc_at(&mt->topology.vertices, v2); + vec3 dp1 = vec3_minus_vec3(A1->pos, A0->pos); + vec3 dp2 = vec3_minus_vec3(A2->pos, A0->pos); + float du1 = A1->tex.x - A0->tex.x; + float dv1 = A1->tex.y - A0->tex.y; + float du2 = A2->tex.x - A0->tex.x; + float dv2 = A2->tex.y - A0->tex.y; + vec3 norm = vec3_normalize(vec3_cross(dp1, dp2)); + mat2x3 tang_U_V = mat3x2_transpose(mat2_mul_mat3x2( + mat2_inverse(mat2_new(du1, dv1, du2, dv2)), + mat2x3_transpose((mat2x3){.x = dp1, .y = dp2}) + )); + staging_vbo[v0].norm = staging_vbo[v1].norm = staging_vbo[v2].norm = norm; + staging_vbo[v0].tang_U = staging_vbo[v1].tang_U = staging_vbo[v2].tang_U = tang_U_V.x; + staging_vbo[v0].tang_V = staging_vbo[v1].tang_V = staging_vbo[v2].tang_V = tang_U_V.y; + } margaret_rec_cmd_copy_buffer_one_to_one(command_buffer, &mm->staging_vbo, &mm->vbo); assert(mt->topology.indexes.len == mm->indexes); @@ -242,7 +296,7 @@ void SceneTemplate_copy_initial_model_topology_cmd_buf_recording( assert(mm->vbo.len >= mt->vertices.len * sizeof(ShinyMeshVertex)); ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo); for (U64 i = 0; i < mt->vertices.len; i++) { - staging_vbo[i].pos = mt->vertices.buf[i].pos; + staging_vbo[i].base = mt->vertices.buf[i]; } assert(mt->indexes.len % 3 == 0); for (size_t ti = 0; ti * 3 < mt->indexes.len; ti++) { diff --git a/src/l2/tests/r0/shaders/glsl/0/0.frag b/src/l2/tests/r0/shaders/glsl/0/0.frag index 62108ba..663c54e 100644 --- a/src/l2/tests/r0/shaders/glsl/0/0.frag +++ b/src/l2/tests/r0/shaders/glsl/0/0.frag @@ -1,9 +1,12 @@ #version 450 -layout(location = 0) in vec2 fsin_tex; -layout(location = 1) in vec3 fsin_pos; +layout(location = 0) in vec3 tang_norm; +layout(location = 1) in vec3 tang_U; +layout(location = 2) in vec3 tang_V; +layout(location = 3) in vec2 tex; +layout(location = 4) in vec3 pos; -/* Righ now all in set 0 */ +/* Right now all in set 0 */ layout(location = 0) out vec4 fin_color; /* Yes, even these guys */ layout(binding = 1) uniform sampler2D color_tex; @@ -38,18 +41,19 @@ float get_intensity(float dist){ } void main(){ - vec3 compressed_normal = texture(normal_map, fsin_tex).xyz; - vec3 norm = compressed_normal * 2 - 1; + vec3 compressed_normal = texture(normal_map, tex).xyz; + vec3 correct_norm_on_tang = compressed_normal * 2 - 1; + vec3 norm = normalize(mat3(tang_U, tang_norm, tang_V) * correct_norm_on_tang); 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; + vec3 to_light = -pos + lamp.pos; float dist = length(to_light); vec3 U = to_light / dist; diffuse_illumination += get_intensity(dist) * max(0, dot(U, norm)) * lamp.color; vec3 A = reflect(-U, norm); - vec3 to_cam = -fsin_pos+camera_pos; + vec3 to_cam = -pos+camera_pos; float dist_to_cam = length(to_cam); vec3 B = to_cam / dist_to_cam; specular_illumination += get_intensity(dist) * pow(max(0, dot(A, B)), 32) * lamp.color; @@ -57,8 +61,8 @@ void main(){ for (int i = 0; i < spotlight_count; i++) { Pipeline0Spotlight lamp = spotlight_arr[i]; } - vec3 natural_color = texture(color_tex, fsin_tex).xyz; - float specular_c = texture(specular_map, fsin_tex).x; + vec3 natural_color = texture(color_tex, tex).xyz; + float specular_c = texture(specular_map, tex).x; vec3 color = natural_color * diffuse_illumination + specular_c * specular_illumination; fin_color = vec4(color, 1); } diff --git a/src/l2/tests/r0/shaders/glsl/0/0.vert b/src/l2/tests/r0/shaders/glsl/0/0.vert index d00b8bf..b1bac22 100644 --- a/src/l2/tests/r0/shaders/glsl/0/0.vert +++ b/src/l2/tests/r0/shaders/glsl/0/0.vert @@ -2,19 +2,31 @@ layout(location = 0) in vec3 pos; layout(location = 1) in vec2 tex; -layout(location = 2) in mat4 model_t; -/* 2 <- 3, 4, 5 */ +layout(location = 2) in vec3 norm; +layout(location = 3) in vec3 tang_U; +layout(location = 4) in vec3 tang_V; -layout(location = 0) out vec2 vsout_tex; -layout(location = 1) out vec3 vsout_pos; +layout(location = 5) in mat4 model_t; +/* 5 <- 6, 7, 8 */ +layout(location = 9) in mat3 normal_t; +/* 9 <- 10, 11 */ + +layout(location = 0) out vec3 out_norm; +layout(location = 1) out vec3 out_tang_U; +layout(location = 2) out vec3 out_tang_V; +layout(location = 3) out vec2 out_tex; +layout(location = 4) out vec3 out_pos; layout(push_constant, std430) uniform pc { mat4 proj_cam_t; }; void main(){ - vsout_tex = tex; + out_norm = normalize(normal_t * norm); + out_tang_U = normalize(normal_t * tang_U); + out_tang_V = normalize(normal_t * tang_V); + out_tex = tex; vec4 real_pos = model_t * vec4(pos, 1); - vsout_pos = real_pos.xyz; + out_pos = real_pos.xyz; gl_Position = proj_cam_t * real_pos; } \ No newline at end of file