Added this stupid normal vector inference bullshit from learnopeng.com. I checked, it's garbage. Will probably change it. But now I have to write GenericModel normal vector inference. And it's, like, 200x times harder. And normal texture generation is the type of hell you don't just drop on somebody. I dropped it on myself anyway...

This commit is contained in:
Андреев Григорий 2025-12-19 01:21:01 +03:00
parent 8e3a306459
commit 5615594762
13 changed files with 384 additions and 190 deletions

View File

@ -27,12 +27,14 @@ 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)
#target_compile_definitions(codegen_l1
# PRIVATE PROTOTYPE1_L1_CODEGEN_BOOTSTRAP_USE_CHICKEN_VECU8)
add_executable(codegen_l1 src/l1/anne/codegen.c)
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(3_test src/l1_4/tests/t3.c)
target_link_libraries(3_test -lm)
#
#add_executable(l1_4_t2 src/l1_4/tests/t2.c)

View File

@ -337,6 +337,76 @@ NODISCARD VecU8 generate_square_xmatn_methods(SpanU8 xmat, SpanU8 xvec, SpanU8 m
return res;
}
NODISCARD VecU8 generate_xmat4_inverse_method(SpanU8 xmat, SpanU8 xvec, SpanU8 memb){
VecU8 g_xmat4 = codegen_name_xmatnm(xmat, 4, 4);
SpanU8 xmat4 = VecU8_to_span(&g_xmat4);
VecU8 res = VecU8_fmt(
"%s %s_inverse(%s A) {\n"
SPACE "%s m2[6][6] = {\n",
xmat4, xmat4, xmat4, memb);
SpanU8 first_of_pair[6] = {cstr("x"), cstr("x"), cstr("x"), cstr("y"), cstr("y"), cstr("z")};
SpanU8 second_of_pair[6] = {cstr("y"), cstr("z"), cstr("w"), cstr("z"), cstr("w"), cstr("w")};
for (int w_col = 0; w_col < 6; w_col++) {
VecU8_append_span(&res, cstr(SPACE SPACE "{ "));
for (int w_row = 0; w_row < 6; w_row++) {
if (w_row)
VecU8_append_span(&res, cstr(", "));
/* first first = A second first = B
* first second = C second second = D
* A * D - B * C */
VecU8_append_vec(&res, VecU8_fmt("A.%s.%s * A.%s.%s - A.%s.%s * A.%s.%s",
first_of_pair[w_col], first_of_pair[w_row], second_of_pair[w_col], second_of_pair[w_row],
second_of_pair[w_col], first_of_pair[w_row], first_of_pair[w_col], second_of_pair[w_row]
));
}
VecU8_append_span(&res, cstr(" },\n"));
}
VecU8_append_span(&res, cstr(SPACE "};\n"));
U64 a0_contr[4] = {5, 5, 4, 3};
U64 a1_contr[4] = {4, 2, 2, 1};
U64 a2_contr[4] = {3, 1, 0, 0};
SpanU8 a0[4] = {cstr("y"), cstr("x"), cstr("x"), cstr("x")};
SpanU8 a1[4] = {cstr("z"), cstr("z"), cstr("y"), cstr("y")};
SpanU8 a2[4] = {cstr("w"), cstr("w"), cstr("w"), cstr("z")};
VecU8_append_vec(&res, VecU8_fmt(SPACE "%s m3[4][4] = {\n", memb));
for (int no_col = 0; no_col < 4; no_col++) {
SpanU8 walking_column = a0[no_col];
U64 minor_col_pair = a0_contr[no_col];
VecU8_append_span(&res, cstr(SPACE SPACE "{ "));
for (int no_row = 0; no_row < 4; no_row++) {
if (no_row)
VecU8_append_span(&res, cstr(", \n" SPACE SPACE));
VecU8_append_vec(&res, VecU8_fmt(
"A.%s.%s * m2[%u][%u] - A.%s.%s * m2[%u][%u] + A.%s.%s * m2[%u][%u]",
walking_column, a0[no_row], minor_col_pair, a0_contr[no_row],
walking_column, a1[no_row], minor_col_pair, a1_contr[no_row],
walking_column, a2[no_row], minor_col_pair, a2_contr[no_row]));
}
VecU8_append_span(&res, cstr(" },\n"));
}
VecU8_append_span(&res, cstr(SPACE "};\n"));
VecU8_append_vec(&res, VecU8_fmt(
SPACE "%s d = 1 / (A.x.x * m3[0][0] - A.x.y * m3[0][1] + A.x.z * m3[0][2] - A.x.w * m3[0][3]);\n"
SPACE "return (mat4){ "
, memb));
for (U64 i = 0; i < 4; i++) {
if (i)
VecU8_append_span(&res, cstr(",\n" SPACE SPACE ));
VecU8_append_vec(&res, VecU8_fmt(".%s={ ", vec_field_name((int)i)));
for (U64 j = 0; j < 4; j++) {
if (j)
VecU8_append_span(&res, cstr(", "));
VecU8_append_vec(&res, VecU8_fmt("%sm3[%u][%u] * d",
(i + j) % 2 ? cstr("-") : cstr(""), j, i));
}
VecU8_append_span(&res, cstr(" }"));
}
VecU8_append_span(&res, cstr(" };\n}\n\n"));
VecU8_drop(g_xmat4);
return res;
}
NODISCARD VecU8 generate_xmatnm_method_mul_xmatkn(SpanU8 xmat, int n, int m, int k) {
VecU8 g_xmatkm = codegen_name_xmatnm(xmat, k, m);
VecU8 g_xmatnm = codegen_name_xmatnm(xmat, n, m);
@ -414,6 +484,7 @@ NODISCARD VecU8 generate_xmat234x234_structs_methods(SpanU8 xmat, SpanU8 xvec, S
}
}
}
VecU8_append_vec(&res, generate_xmat4_inverse_method(xmat, xvec, memb));
return res;
}
@ -428,7 +499,7 @@ void generate_geom_header() {
VecU8_append_vec(&res.result, generate_xvec234_structs_and_cool_methods(cstr("vec"), cstr("float"), cstr("sqrtf")));
VecU8_append_vec(&res.result, generate_xvec234_structs_and_cool_methods(cstr("dvec"), cstr("double"), cstr("sqrt")));
VecU8_append_vec(&res.result, generate_xmat234x234_structs_methods(cstr("mat"), cstr("vec"), cstr("float"), sizeof(float)));
VecU8_append_vec(&res.result, generate_xmat234x234_structs_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double)));
/* VecU8_append_vec(&res.result, generate_xmat234x234_structs_methods(cstr("dmat"), cstr("dvec"), cstr("double"), sizeof(double))); */
finish_header(res);
}

View File

@ -10,17 +10,15 @@ void generate_headers_for_r0_r1_r2_r3() {
SpanU8 ns = cstr("r0");
generate_eve_span_company_for_primitive(l, ns, cstr("GenericMeshVertex"), 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("GenericMeshInstance"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("ShinyMeshVertex"), true, true);
// generate_eve_span_company_for_primitive(l, ns, cstr("ShinyMeshInstance"), 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);
// generate_eve_span_company_for_primitive(l, ns, cstr("Pipeline0Spotlight"), true, false);
// generate_eve_span_company_for_primitive(l, ns, cstr("Pipeline0PointLight"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("Wimbzle"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("Nibzle"), true, false);
/* r0_scene.h */
generate_eve_span_company_for_primitive(l, ns, cstr("GenericModelOnSceneMem"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("ShinyModelOnSceneMem"), true, false);
generate_eve_span_company_for_primitive(l, ns, cstr("ObjectInfo"), true, false);
/* r0 */
generate_eve_span_company_for_primitive(l, ns, cstr("GenericModelTexVulkPointers"), true, false);
}

View File

@ -135,7 +135,12 @@ void U64_stringification_into_buf(U64 x, VecU8* targ){
}
}
// todo: add %d (when I figure out how to do it)
/* %s - SpanU8
* %v - VecU8
* %u - U64
* %c - int (one byte character)
* %i - S64
*/
NODISCARD VecU8 VecU8_fmt(const char* fmt, ...) {
assert(fmt);
size_t k = 0;

45
src/l1_4/tests/t3.c Normal file
View File

@ -0,0 +1,45 @@
#include "../../../gen/l1/geom.h"
#include <stdio.h>
#include <stdlib.h>
float random_float(float a, float b){
int r = rand();
return a + (b - a) * ((float)r / (float)RAND_MAX);
}
float random_float100(){
return random_float(-100, 100);
}
mat4 random_big_matrix(){
return mat4_new(random_float100(), random_float100(), random_float100(), random_float100(),
random_float100(), random_float100(), random_float100(), random_float100(),
random_float100(), random_float100(), random_float100(), random_float100(),
random_float100(), random_float100(), random_float100(), random_float100());
}
#define flPr "%02.05f"
void test_matrix(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",
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());
}

View File

@ -329,6 +329,7 @@ VkDevice margaret_create_logical_device(VkPhysicalDevice physical_device, Margar
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
.pNext = (void*)&used_synchronization2_features,
.features = (VkPhysicalDeviceFeatures) {
.geometryShader = true,
.samplerAnisotropy = physical_features.samplerAnisotropy,
},
};
@ -565,7 +566,7 @@ MargaretScoredPhysicalDevice margaret_score_physical_device(
else if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
score += 100;
if (!features2.features.geometryShader)
return (MargaretScoredPhysicalDevice){dev, -1, cstr("No geometry shader")};
return (MargaretScoredPhysicalDevice){dev, -1, cstr("No geometry shaders")};
if (!synchronization2_features.synchronization2)
return (MargaretScoredPhysicalDevice){dev, -1, cstr("No synchronization2")};
if (features2.features.samplerAnisotropy)
@ -997,23 +998,10 @@ void margaret_end_command_buffer(VkCommandBuffer command_buffer){
check(vkEndCommandBuffer(command_buffer) == VK_SUCCESS);
}
VkPipelineShaderStageCreateInfo margaret_shader_stage_vertex_crinfo(VkShaderModule module) {
return (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .module = module,
.stage = VK_SHADER_STAGE_VERTEX_BIT, .pName = "main",
};
}
VkPipelineShaderStageCreateInfo margaret_shader_stage_fragment_crinfo(VkShaderModule module) {
return (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .module = module,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT, .pName = "main",
};
}
typedef struct {
VkPipelineLayout pipeline_layout;
VecU8 vertex_shader_code;
VecU8 geometry_shader_code;
VecU8 fragment_shader_code;
U32 vertexBindingDescriptionCount;
VkVertexInputBindingDescription* pVertexBindingDescriptions;
@ -1028,18 +1016,32 @@ VkPipeline margaret_create_triangle_pipeline_one_attachment(
VkDevice device, VkRenderPass render_pass, U32 renderpass_subpass,
MargaretMostImportantPipelineOptions op
){
VkShaderModule vert_module = margaret_VkShaderModule_new(device, op.vertex_shader_code);
VkShaderModule frag_module = margaret_VkShaderModule_new(device, op.fragment_shader_code);
VkPipelineShaderStageCreateInfo shader_modules[3] = {
(VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.module = margaret_VkShaderModule_new(device, op.vertex_shader_code),
.stage = VK_SHADER_STAGE_VERTEX_BIT, .pName = "main",
},
(VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.module = margaret_VkShaderModule_new(device, op.fragment_shader_code),
.stage = VK_SHADER_STAGE_FRAGMENT_BIT, .pName = "main",
},
};
U32 shader_modules_c = 2;
if (op.geometry_shader_code.len > 0) {
shader_modules[shader_modules_c] = (VkPipelineShaderStageCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.module = margaret_VkShaderModule_new(device, op.geometry_shader_code),
.stage = VK_SHADER_STAGE_GEOMETRY_BIT, .pName = "main",
};
shader_modules_c++;
}
VkGraphicsPipelineCreateInfo pipeline_crinfo = {
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
.stageCount = 2,
.pStages = (VkPipelineShaderStageCreateInfo[]){
margaret_shader_stage_vertex_crinfo(vert_module),
margaret_shader_stage_fragment_crinfo(frag_module)
},
.stageCount = shader_modules_c,
.pStages = shader_modules,
.pVertexInputState = &(VkPipelineVertexInputStateCreateInfo){
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
.vertexBindingDescriptionCount = op.vertexBindingDescriptionCount,
@ -1118,8 +1120,9 @@ VkPipeline margaret_create_triangle_pipeline_one_attachment(
VkPipeline pipeline;
check(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_crinfo, NULL, &pipeline) == VK_SUCCESS);
vkDestroyShaderModule(device, frag_module, NULL);
vkDestroyShaderModule(device, vert_module, NULL);
for (U32 i = 0; i < shader_modules_c; i++) {
vkDestroyShaderModule(device, shader_modules[i].module, NULL);
}
return pipeline;
}
@ -1153,7 +1156,7 @@ void margaret_rec_cmd_copy_buffer_one_to_one_part(
const MargaretSubbuf* src_allocation,
const MargaretSubbuf* dst_allocation, U64 offset, U64 length){
assert(offset + length <= src_allocation->len);
assert(src_allocation->len == dst_allocation->len);
assert(offset + length <= dst_allocation->len);
vkCmdCopyBuffer(cmd_buf,
MargaretSubbuf_get_buffer(src_allocation), MargaretSubbuf_get_buffer(dst_allocation),
1, &(VkBufferCopy){
@ -1162,11 +1165,11 @@ void margaret_rec_cmd_copy_buffer_one_to_one_part(
void margaret_rec_cmd_copy_buffer_one_to_one(
VkCommandBuffer cmd_buf, const MargaretSubbuf* src_allocation, const MargaretSubbuf* dst_allocation){
assert(src_allocation->len == dst_allocation->len);
U64 copying_len = MIN_U64(src_allocation->len, dst_allocation->len);
vkCmdCopyBuffer(cmd_buf,
MargaretSubbuf_get_buffer(src_allocation), MargaretSubbuf_get_buffer(dst_allocation),
1, &(VkBufferCopy){
.srcOffset = src_allocation->start, .dstOffset = dst_allocation->start, .size = src_allocation->len});
.srcOffset = src_allocation->start, .dstOffset = dst_allocation->start, .size = copying_len});
}
/* (destination_stage_mask, destination_access_mask) are probably

View File

@ -91,5 +91,12 @@ vec3 marie_normal_from_tang_space_gradient(float delt_x, float delta_z) {
return (vec3){-delt_x * N, N, -delta_z * N};
}
mat4 marie_3d_scal_mat4(float scale){
return mat4_new(scale, 0, 0, 0,
0, scale, 0, 0,
0, 0, scale, 0,
0, 0, 0, 1);
}
#endif

View File

@ -175,40 +175,34 @@ PipelineHands create_graphics_pipeline_0(
};
VkVertexInputAttributeDescription vertex_attributes[2 + 4] = {
{
.location = 0,
.binding = 0,
.location = 0, .binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(GenericMeshVertex, pos),
},
{
.location = 1,
.binding = 0,
.location = 1, .binding = 0,
.format = VK_FORMAT_R32G32_SFLOAT,
.offset = offsetof(GenericMeshVertex, tex),
},
/* This is a mat4 datatype, so it will take 4 entire 'locations' */
{
.location = 2,
.binding = 1,
.location = 2, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(GenericMeshInstance, model_t) + offsetof(mat4, x)
},
{
.location = 3,
.binding = 1,
.location = 3, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(GenericMeshInstance, model_t) + offsetof(mat4, y)
},
{
.location = 4,
.binding = 1,
.location = 4, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(GenericMeshInstance, model_t) + offsetof(mat4, z)
},
{
.location = 5,
.binding = 1,
.location = 5, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(GenericMeshInstance, model_t) + offsetof(mat4, w)
},
@ -275,56 +269,63 @@ PipelineHands create_graphics_pipeline_0_b(
.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE,
}
};
VkVertexInputAttributeDescription vertex_attributes[2 + 4 + 2] = {
VkVertexInputAttributeDescription vertex_attributes[2 + 4 + 2 + 3] = {
{
.location = 0,
.binding = 0,
.location = 0, .binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(ShinyMeshVertex, pos),
},
{
.location = 1,
.binding = 0,
.location = 1, .binding = 0,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(ShinyMeshVertex, normal),
},
/* This is a mat4 datatype, so it will take 4 entire 'locations' */
{
.location = 2,
.binding = 1,
.location = 2, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, model_t) + offsetof(mat4, x)
.offset = offsetof(ShinyMeshInstanceInc, model_t) + offsetof(mat4, x)
},
{
.location = 3,
.binding = 1,
.location = 3, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, model_t) + offsetof(mat4, y)
.offset = offsetof(ShinyMeshInstanceInc, model_t) + offsetof(mat4, y)
},
{
.location = 4,
.binding = 1,
.location = 4, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, model_t) + offsetof(mat4, z)
.offset = offsetof(ShinyMeshInstanceInc, model_t) + offsetof(mat4, z)
},
{
.location = 5,
.binding = 1,
.location = 5, .binding = 1,
.format = VK_FORMAT_R32G32B32A32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, model_t) + offsetof(mat4, w)
.offset = offsetof(ShinyMeshInstanceInc, model_t) + offsetof(mat4, w)
},
{
.location = 6,
.binding = 1,
.location = 6, .binding = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, color_off)
.offset = offsetof(ShinyMeshInstanceInc, color_off)
},
{
.location = 7,
.binding = 1,
.location = 7, .binding = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, color_on)
.offset = offsetof(ShinyMeshInstanceInc, color_on)
},
{
.location = 8, .binding = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, normal_t) + offsetof(mat3, x)
},
{
.location = 9, .binding = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, normal_t) + offsetof(mat3, y)
},
{
.location = 10, .binding = 1,
.format = VK_FORMAT_R32G32B32_SFLOAT,
.offset = offsetof(ShinyMeshInstance, normal_t) + offsetof(mat3, z)
},
};
@ -808,6 +809,36 @@ void update_state(state_r0* state, uint32_t dur) {
if (state->first_0x80_keys[XKB_KEY_e])
CamControlInfo_up(&state->vk.scene.cam, fl);
if (state->first_0x80_keys[XKB_KEY_bracketright]) {
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;
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);
Scene_update_smeshnyavka_3(&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;
oi->scale *= (1 - 0.01f * fl * fac);
Scene_update_smeshnyavka_3(&state->vk.scene, i);
}
}
if (state->first_0x80_keys[XKB_KEY_equal]) {
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;
oi->scale *= (1 + 0.01f * fl * fac);
Scene_update_smeshnyavka_3(&state->vk.scene, i);
}
}
{
GenericModelOnSceneMem* model = VecGenericModelOnSceneMem_mat(&state->vk.scene.generic_models, 0);
assert(model->instance_attr.count >= 1);
@ -1225,8 +1256,8 @@ static void main_h_wl_keyboard_key(
p.y += 1.5f;
ShinyModelOnSceneMem* model = VecShinyModelOnSceneMem_mat(&state->vk.scene.shiny_models, 0);
assert(model->instance_attr.count >= 1);
ShinyMeshInstance* instances = (ShinyMeshInstance*)MargaretSubbuf_get_mapped(&model->instance_attr.staging_updatable);
instances[0].model_t = marie_translation_mat4(p);
VecObjectInfo_mat(&state->vk.scene.smeshnyavka_3, 0)->pos = p;
Scene_update_smeshnyavka_3(&state->vk.scene, 0);
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&state->vk.scene.pipeline0_ubo.staging_updatable);
assert(ubo->point_light_count >= 1);
@ -1392,14 +1423,20 @@ static const struct wl_callback_listener main_h_wl_surface_frame_listener = {
.done = main_h_wl_surface_frame_done,
};
void compile_shader_dir(SpanU8 name) {
void compile_shader_dir(SpanU8 name, bool have_geom) {
mkdir_nofail("shaders/spv");
VecU8 spv_shader_dir_name = VecU8_fmt("shaders/spv/%s%c", name, 0);
mkdir_nofail((CSTR)spv_shader_dir_name.buf);
VecU8_drop(spv_shader_dir_name);
// todo: write a function that takes a SpanU8
VecU8 vert_cmd = VecU8_fmt("glslc -o shaders/spv/%s/vert.spv shaders/glsl/%s/%s.vert%c", name, name, name, 0);
calling_system_func_nofail((CSTR)vert_cmd.buf);
VecU8_drop(vert_cmd);
if (have_geom) {
VecU8 geom_cmd = VecU8_fmt("glslc -o shaders/spv/%s/geom.spv shaders/glsl/%s/%s.geom%c", name, name, name, 0);
calling_system_func_nofail((CSTR)geom_cmd.buf);
VecU8_drop(geom_cmd);
}
VecU8 frag_cmd = VecU8_fmt("glslc -o shaders/spv/%s/frag.spv shaders/glsl/%s/%s.frag%c", name, name, name, 0);
calling_system_func_nofail((CSTR)frag_cmd.buf);
VecU8_drop(frag_cmd);
@ -1407,9 +1444,9 @@ void compile_shader_dir(SpanU8 name) {
int main() {
compile_shader_dir(cstr("0"));
compile_shader_dir(cstr("0b"));
compile_shader_dir(cstr("1"));
compile_shader_dir(cstr("0"), false);
compile_shader_dir(cstr("0b"), false);
compile_shader_dir(cstr("1"), false);
SpanU8 GPU = cstr("nvidia");
SpanU8 bugged_GPU = cstr("nothere");
@ -1553,7 +1590,7 @@ int main() {
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
/* | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT */,
mem_type_id_device_local, 3, false, 16);
mem_type_id_device_local, 6, false, 16);
vk->dev_local_images = MargaretImgAllocator_new(vk->device, vk->physical_device,
mem_type_id_device_local, 16);
@ -1574,8 +1611,7 @@ int main() {
GenericMeshInSceneTemplate_for_log(10, 2, 6));
VecGenericMeshInSceneTemplate_append(&vk->scene_template.generic_models,
GenericMeshInSceneTemplate_for_log(5, 5, 10));
VecShinyMeshTopology_append(&vk->scene_template.shiny_models, generate_shiny_rhombicuboctahedron(0.3f));
VecShinyMeshTopology_append(&vk->scene_template.shiny_models, generate_shiny_cube(0.2f));
VecShinyMeshTopology_append(&vk->scene_template.shiny_models, generate_shiny_cube(0.3f));
VecGenericModelOnSceneMem generic_model_mem = VecGenericModelOnSceneMem_new();
VecShinyModelOnSceneMem shiny_model_mem = VecShinyModelOnSceneMem_new();
@ -1694,29 +1730,12 @@ int main() {
}
model_g2->instance_attr.count = 25;
ShinyModelOnSceneMem* model_sh = VecShinyModelOnSceneMem_mat(&vk->scene.shiny_models, 0);
ShinyMeshInstance* sh_instances = (ShinyMeshInstance*)MargaretSubbuf_get_mapped(&model_sh->instance_attr.staging_updatable);
assert(model_sh->instance_attr.cap >= 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
sh_instances[X * 10 + Z] = (ShinyMeshInstance){
.model_t = marie_translation_mat4((vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}),
.color_on = {0, 1, 0}, .color_off = {1, 0.4f, 0.5f} };
Scene_add_smeshnyavka_3(&vk->scene, (ObjectInfo){.rotation = mat3_E,
.pos = (vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}, .scale = 1, .color_on = {0, 1, 0}});
}
}
model_sh->instance_attr.count = 100;
ShinyModelOnSceneMem* model_sh2 = VecShinyModelOnSceneMem_mat(&vk->scene.shiny_models, 1);
ShinyMeshInstance* sh2_instances = (ShinyMeshInstance*)MargaretSubbuf_get_mapped(&model_sh2->instance_attr.staging_updatable);
assert(model_sh2->instance_attr.cap >= 25);
for (int X = 0; X < 25; X++) {
for (int Z = 0; Z < 25; Z++) {
sh2_instances[X * 5 + Z] = (ShinyMeshInstance){
.model_t = marie_translation_mat4((vec3){3.f * (float)X - 20, 12, 3.f * (float)Z - 14}),
.color_on = {0.1f, 0.1f, 1}, .color_off = {0.3f, 0.4f, 1.f} };
}
}
model_sh2->instance_attr.count = 25;
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&vk->scene.pipeline0_ubo.staging_updatable);
assert(pipeline_0_ubo_point_light_max_count >= 100);

View File

@ -60,30 +60,40 @@ typedef struct {
typedef struct {
vec3 pos;
vec3 normal;
} ShinyMeshVertex;
#include "../../../../gen/l1/eve/r0/VecAndSpan_ShinyMeshVertex.h"
} ShinyMeshVertexInc;
typedef struct {
VecShinyMeshVertex vertices;
vec3 pos;
vec3 normal;
} ShinyMeshVertex;
#include "../../../../gen/l1/eve/r0/VecAndSpan_ShinyMeshVertexInc.h"
typedef struct {
VecShinyMeshVertexInc vertices;
VecU32 indexes;
} ShinyMeshTopology;
void ShinyMeshTopology_drop(ShinyMeshTopology self) {
VecShinyMeshVertex_drop(self.vertices);
VecShinyMeshVertexInc_drop(self.vertices);
VecU32_drop(self.indexes);
}
ShinyMeshTopology ShinyMeshTopology_clone(const ShinyMeshTopology* self) {
return (ShinyMeshTopology){.vertices = VecShinyMeshVertex_clone(&self->vertices), VecU32_clone(&self->indexes)};
return (ShinyMeshTopology){.vertices = VecShinyMeshVertexInc_clone(&self->vertices),
VecU32_clone(&self->indexes)};
}
#include "../../../../gen/l1/eve/r0/VecShinyMeshTopology.h"
typedef struct {
typedef struct{
mat4 model_t;
vec3 color_off;
vec3 color_on;
} ShinyMeshInstanceInc;
typedef struct {
ShinyMeshInstanceInc base;
mat3 normal_t;
} ShinyMeshInstance;
typedef struct {
@ -700,39 +710,39 @@ TextureDataR8G8B8A8 generate_normal_tex_for_one_fourth_of_a_cylinder(float s_res
U32 quad_to_triangles_conv_arr[6] = {0, 1, 2, 0, 2, 3};
ShinyMeshTopology generate_shiny_cube(float r) {
ShinyMeshVertex vert[24] = {
{{+r, +r, +r}, {1, 0, 0}},
{{+r, -r, +r}, {1, 0, 0}},
{{+r, -r, -r}, {1, 0, 0}},
{{+r, +r, -r}, {1, 0, 0}},
ShinyMeshVertexInc vert[24] = {
{{+r, +r, +r}},
{{+r, -r, +r}},
{{+r, -r, -r}},
{{+r, +r, -r}},
{{-r, -r, -r}, {-1, 0, 0}},
{{-r, -r, +r}, {-1, 0, 0}},
{{-r, +r, +r}, {-1, 0, 0}},
{{-r, +r, -r}, {-1, 0, 0}},
{{-r, -r, -r}},
{{-r, -r, +r}},
{{-r, +r, +r}},
{{-r, +r, -r}},
{{+r, +r, +r}, {0, 1, 0}},
{{+r, +r, -r}, {0, 1, 0}},
{{-r, +r, -r}, {0, 1, 0}},
{{-r, +r, +r}, {0, 1, 0}},
{{+r, +r, +r}},
{{+r, +r, -r}},
{{-r, +r, -r}},
{{-r, +r, +r}},
{{-r, -r, -r}, {0, -1, 0}},
{{+r, -r, -r}, {0, -1, 0}},
{{+r, -r, +r}, {0, -1, 0}},
{{-r, -r, +r}, {0, -1, 0}},
{{-r, -r, -r}},
{{+r, -r, -r}},
{{+r, -r, +r}},
{{-r, -r, +r}},
{{+r, +r, +r}, {0, 0, 1}},
{{-r, +r, +r}, {0, 0, 1}},
{{-r, -r, +r}, {0, 0, 1}},
{{+r, -r, +r}, {0, 0, 1}},
{{+r, +r, +r}},
{{-r, +r, +r}},
{{-r, -r, +r}},
{{+r, -r, +r}},
{{-r, -r, -r}, {0, 0, -1}},
{{-r, +r, -r}, {0, 0, -1}},
{{+r, +r, -r}, {0, 0, -1}},
{{+r, -r, -r}, {0, 0, -1}},
{{-r, -r, -r}},
{{-r, +r, -r}},
{{+r, +r, -r}},
{{+r, -r, -r}},
};
VecShinyMeshVertex vertices_vec = VecShinyMeshVertex_new_zeroinit(24);
memcpy(vertices_vec.buf, vert, sizeof(vert));
VecShinyMeshVertexInc vertices_vec = VecShinyMeshVertexInc_from_span(
(SpanShinyMeshVertexInc){ .data = vert, .len = ARRAY_SIZE(vert) });
VecU32 indexes_vec = VecU32_new_reserved(36);
for (U32 f = 0; f < 6; f++) {
for (U32 j = 0; j < 6; j++)
@ -767,49 +777,6 @@ CubeVertOfFace CubeVertOfFace_next(CubeVertOfFace vert) {
return (CubeVertOfFace){vert.face, (vert.vert_on_it + 1) % 4};
}
ShinyMeshTopology generate_shiny_rhombicuboctahedron(float r) {
ShinyMeshTopology res = generate_shiny_cube(r);
for (int f = 0; f < 6; f++) {
vec3 growth = vec3_mul_scal((*VecShinyMeshVertex_at(&res.vertices, f * 4)).normal, M_SQRT1_2);
for (int i = 0; i < 4; i++) {
vec3* pos = &VecShinyMeshVertex_mat(&res.vertices, f * 4 + i)->pos;
*pos = vec3_add_vec3(*pos, growth);
}
}
for (int f = 0; f < 6; f++) {
for (int i = 0; i < 2; i++) {
CubeVertOfFace vof = {f, 2*i+(f%2)};
ShinyMeshVertex A = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(vof));
ShinyMeshVertex B = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_next(CubeVertOfFace_jump(vof))));
ShinyMeshVertex C = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_jump(vof)));
ShinyMeshVertex D = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_next(vof)));
vec3 norm = vec3_normalize(vec3_add_vec3(A.normal, B.normal));
ShinyMeshVertex quad_v[4] = {{A.pos, norm}, {B.pos, norm}, {C.pos, norm}, {D.pos, norm}};
size_t b = res.vertices.len;
VecShinyMeshVertex_append_span(&res.vertices, (SpanShinyMeshVertex){quad_v, ARRAY_SIZE(quad_v)});
for (U32 j = 0; j < 6; j++)
VecU32_append(&res.indexes, b + quad_to_triangles_conv_arr[j]);
}
}
for (int f = 0; f < 2; f++) {
for (int e = 0; e < 4; e++) {
CubeVertOfFace vof = {f, e};
ShinyMeshVertex A = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_next(vof)));
ShinyMeshVertex B = *VecShinyMeshVertex_at(&res.vertices, CubeVertOfFace_to_vid(CubeVertOfFace_jump(vof)));
ShinyMeshVertex C = *VecShinyMeshVertex_at(&res.vertices,
CubeVertOfFace_to_vid(CubeVertOfFace_next(CubeVertOfFace_jump(CubeVertOfFace_next(vof)))));
vec3 norm = vec3_normalize(vec3_add_vec3(A.normal, vec3_add_vec3(B.normal, C.normal)));
ShinyMeshVertex ang_v[3] = {{A.pos, norm}, {B.pos, norm}, {C.pos, norm}};
size_t b = res.vertices.len;
VecShinyMeshVertex_append_span(&res.vertices, (SpanShinyMeshVertex){ang_v, ARRAY_SIZE(ang_v)});
for (int i = 0; i < 3; i++)
VecU32_append(&res.indexes, b + i);
}
}
return res;
}
GenericMeshInSceneTemplate GenericMeshInSceneTemplate_for_log(U32 w, U32 r, U32 k) {
return (GenericMeshInSceneTemplate){.topology = generate_one_fourth_of_a_cylinder((float)w, (float)r, k),
.diffuse_texture_path = VecU8_format("textures/log_%u_%u_%u_diffuse.png", w, r, k),

View File

@ -59,6 +59,17 @@ typedef struct {
#include "../../../../gen/l1/eve/r0/VecShinyModelOnSceneMem.h"
void ShinyModelOnSceneMem_set(ShinyModelOnSceneMem* self, size_t instance, ShinyMeshInstanceInc uncomp){
assert(instance < self->instance_attr.count);
ShinyMeshInstance* staging = (ShinyMeshInstance*)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 {
float fov;
mat3 cam_basis;
@ -96,7 +107,7 @@ void CamControlInfo_up(CamControlInfo* self, float fl) {
CamControlInfo CamControlInfo_new() {
return (CamControlInfo){
.fov = 1.5f, .cam_basis = marie_simple_camera_rot_m_basis_in_cols(0, 0, 0), .pos = {0, 0, 0},
.speed = 2.7f, .sensitivity = 0.5f * M_PIf / 180, .pitch_cap = M_PIf * 0.49f
.speed = 6.7f, .sensitivity = 0.5f * M_PIf / 180, .pitch_cap = M_PIf * 0.49f
};
}
@ -115,6 +126,16 @@ typedef struct {
MargaretSubbuf device_local;
} Pipeline0Transfer;
// Just for a test in r0
typedef struct {
mat3 rotation;
vec3 pos;
float scale;
vec3 color_on;
} ObjectInfo;
#include "../../../../gen/l1/eve/r0/VecObjectInfo.h"
/* Non copyable */
typedef struct {
VecGenericModelOnSceneMem generic_models;
@ -131,14 +152,55 @@ typedef struct {
CamControlInfo cam;
vec3 funny_vector;
VecObjectInfo smeshnyavka_1;
VecObjectInfo smeshnyavka_2;
VecObjectInfo smeshnyavka_3;
} Scene;
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} };
}
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));
}
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));
}
Scene Scene_new(VecGenericModelOnSceneMem generic_models, VecShinyModelOnSceneMem shiny_models,
Pipeline0Transfer pipeline0_ubo) {
return (Scene){.generic_models = generic_models, .shiny_models = shiny_models,
.color = {.float32 = {0, 0, 0, 1}},
.gamma_correction_factor = 2.2f, .hdr_factor = 1, .lsd_factor = 0, .anim_time = 0,
.pipeline0_ubo = pipeline0_ubo, .cam = CamControlInfo_new(), .funny_vector = {0, 0, 0}
.pipeline0_ubo = pipeline0_ubo, .cam = CamControlInfo_new(), .funny_vector = {0, 0, 0},
.smeshnyavka_1 = VecObjectInfo_new(), .smeshnyavka_2 = VecObjectInfo_new(),
.smeshnyavka_3 = VecObjectInfo_new(), // todo: remove this shit and rewrite everything in haskell
};
}
@ -176,10 +238,24 @@ void SceneTemplate_copy_initial_model_topology_cmd_buf_recording(
const ShinyMeshTopology* mt = VecShinyMeshTopology_at(&scene_template->shiny_models, mi);
const ShinyModelOnSceneMem *mm = VecShinyModelOnSceneMem_at(&scene->shiny_models, mi);
size_t vbo_len = mt->vertices.len * sizeof(ShinyMeshVertex);
assert(mm->vbo.len >= vbo_len);
assert(mm->staging_vbo.len >= mt->vertices.len * sizeof(ShinyMeshVertex));
assert(mm->vbo.len >= mt->vertices.len * sizeof(ShinyMeshVertex));
ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo);
memcpy(staging_vbo, mt->vertices.buf, vbo_len);
for (U64 i = 0; i < mt->vertices.len; i++) {
staging_vbo[i].pos = mt->vertices.buf[i].pos;
}
assert(mt->indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < mt->indexes.len; ti++) {
U32 v0 = mt->indexes.buf[ti * 3 + 0];
U32 v1 = mt->indexes.buf[ti * 3 + 1];
U32 v2 = mt->indexes.buf[ti * 3 + 2];
vec3 p0 = VecShinyMeshVertexInc_at(&mt->vertices, v0)->pos;
vec3 p1 = VecShinyMeshVertexInc_at(&mt->vertices, v1)->pos;
vec3 p2 = VecShinyMeshVertexInc_at(&mt->vertices, v2)->pos;
vec3 norm = vec3_normalize(vec3_cross(vec3_minus_vec3(p1, p0), vec3_minus_vec3(p2, p0)));
staging_vbo[v0].normal = staging_vbo[v1].normal = staging_vbo[v2].normal = norm;
}
margaret_rec_cmd_copy_buffer_one_to_one(command_buffer, &mm->staging_vbo, &mm->vbo);
assert(mt->indexes.len == mm->indexes);

View File

@ -47,7 +47,7 @@ void main(){
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;
diffuse_illumination += get_intensity(dist) * max(0, dot(U, norm)) * lamp.color;
vec3 A = reflect(-U, norm);
vec3 to_cam = -fsin_pos+camera_pos;
float dist_to_cam = length(to_cam);

View File

@ -42,15 +42,14 @@ void main(){
vec3 to_light = -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;
diffuse_illumination += get_intensity(dist) * max(0, dot(U, norm)) * lamp.color;
vec3 A = reflect(-U, norm);
vec3 B = normalize(-pos+camera_pos);
specular_illumination += get_intensity(dist) * pow(max(0, dot(A, B)), 256) * lamp.color;
// 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);
// fin_color = vec4(length(norm) / 2, 0, 0, 1);
}

View File

@ -4,9 +4,11 @@ layout(location = 0) in vec3 pos;
layout(location = 1) in vec3 normal;
layout(location = 2) in mat4 model_t;
/* 2 <- 3,4,5 */
/* 2 <- 3, 4, 5 */
layout(location = 6) in vec3 color_off;
layout(location = 7) in vec3 color_on;
layout(location = 8) in mat3 normal_t;
/* 8 <- 9, 10 */
layout(location = 0) out vec3 vsout_normal;
layout(location = 1) out vec3 vsout_color_off;
@ -18,7 +20,7 @@ layout(push_constant, std430) uniform pc {
};
void main(){
vsout_normal = normal;
vsout_normal = normalize(normal_t * normal);
vsout_color_off = color_off;
vsout_color_on = color_on;
vec4 real_pos = model_t * vec4(pos, 1);