Wrote a cute little program where you can shoot bullets at ONE FOURTH OF A CYLINDER. Too bad they still don't rotate the cylinder

This commit is contained in:
Андреев Григорий 2026-02-02 02:48:49 +03:00
parent f99e673d79
commit 53dd36ab7c
9 changed files with 294 additions and 172 deletions

View File

@ -18,6 +18,11 @@ void generate_headers_for_r0_r1_r2_r3() {
.T = cstr("PlayingSound"), .vec_extended = true
}, false);
}
mkdir_nofail("l1/eve/r4");
{ /* r4 */
SpanU8 ns = cstr("r4");
generate_eve_span_company_for_primitive(l, ns, cstr("LightSourceState"), true, false);
}
mkdir_nofail("l1/eve/ds_test");
{ /* This structure is needed for testing purposes only */
generate_eve_span_company_for_primitive(l, cstr("ds_test"), cstr("RefRBTreeNode_S64"), true, false);

36
src/l1_5/core/color.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
#include "../../../gen/l1/geom.h"
#include "randomness.h"
// Convert HSV (hue is in degrees; s, v in [0,1]) to RGB (in [0,1]^3)
static vec3 hsv_to_rgb(float h, float s, float v) {
h = fmodf(h, 360.0f);
if (h < 0.0f) h += 360.0f;
float hf = h / 60.0f;
int i = (int)floorf(hf);
float f = hf - (float)i;
float p = v * (1.0f - s);
float q = v * (1.0f - s * f);
float t = v * (1.0f - s * (1.0f - f));
vec3 rgb;
switch (i) {
case 0: rgb.x = v; rgb.y = t; rgb.z = p; break;
case 1: rgb.x = q; rgb.y = v; rgb.z = p; break;
case 2: rgb.x = p; rgb.y = v; rgb.z = t; break;
case 3: rgb.x = p; rgb.y = q; rgb.z = v; break;
case 4: rgb.x = t; rgb.y = p; rgb.z = v; break;
default: // i == 5:
rgb.x = v; rgb.y = p; rgb.z = q; break;
}
return rgb;
}
/* Cute little function that has nothing to do with rainbows */
vec3 sample_rainbow_color() {
float hue = frand01() * 360.0f;
float s = 0.95f + 0.05f * frand01(); // in [0.95, 1.0]
float v = 0.85f + 0.15f * frand01(); // in [0.85, 1.0]
return hsv_to_rgb(hue, s, v);
}

View File

@ -0,0 +1,7 @@
#pragma once
#include "stdlib.h"
float frand01(void) {
return (float)rand() / (float)RAND_MAX;
}

View File

@ -32,9 +32,9 @@ bool marie_intersect_triangle_and_ray(vec3 A, vec3 B, vec3 C, vec3 P, vec3 Q, ve
if (det_alpha_beta_gamma < 0.0001)
return false;
float b_0 = det_delta_beta_gamma / det_alpha_beta_gamma;
float b_1 = det_delta_beta_gamma / det_alpha_beta_gamma;
float t = det_delta_beta_gamma / det_alpha_beta_gamma;
if (b_0 < 0 || b_0 > 1 || b_1 < 0 || b_1 > 1 || t < 0)
float b_1 = det_alpha_delta_gamma / det_alpha_beta_gamma;
float t = det_alpha_beta_delta / det_alpha_beta_gamma;
if (b_0 < 0 || b_1 < 0 || b_0 + b_1 > 1 || t < 0)
return false;
*ret = vec3_add_vec3(P, vec3_mul_scal(gamma, -t));
return true;

View File

@ -32,26 +32,18 @@ GenericMeshTopology GenericMeshTopology_clone(const GenericMeshTopology* self) {
return (GenericMeshTopology){.vertices = VecGenericMeshVertexInc_clone(&self->vertices), .indexes = VecU32_clone(&self->indexes)};
}
/* non-primitive */
typedef struct {
GenericMeshTopology topology;
VecU8 diffuse_texture_path;
VecU8 normal_texture_path;
VecU8 specular_texture_path;
} AliceGenericMeshTopology_TexturePaths;
} AliceGenericMeshTexturePaths;
/* non-primitive */
typedef struct {
VecU8 topology_path;
VecU8 diffuse_texture_path;
VecU8 normal_texture_path;
VecU8 specular_texture_path;
} AliceGenericMeshPath;
void AliceGenericMeshPath_drop(AliceGenericMeshPath self) {
VecU8_drop(self.topology_path);
VecU8_drop(self.diffuse_texture_path);
VecU8_drop(self.normal_texture_path);
VecU8_drop(self.specular_texture_path);
}
AliceGenericMeshTexturePaths tex;
} AliceGenericMeshPaths;
typedef struct {
mat4 model_t;

View File

@ -824,35 +824,36 @@ struct Alice {
VkDescriptorSet descriptor_set_for_pipeline_1;
};
ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericMeshPath paths){
GenericMeshTopology topology;
if (SpanU8_is_postfix(cstr(".AliceGenericMesh"), VecU8_to_span(&paths.topology_path) )) {
topology = alice_expect_read_generic_mesh_from_file(paths.topology_path);
} else if (SpanU8_is_postfix(cstr(".obj"), VecU8_to_span(&paths.topology_path) )) {
topology = alice_expect_read_generic_mesh_from_obj_file(paths.topology_path);
} else {
abortf("Иди своей дорогой\n");
}
ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, const GenericMeshTopology* topology,
AliceGenericMeshTexturePaths t_paths){
// GenericMeshTopology topology;
// if (SpanU8_is_postfix(cstr(".AliceGenericMesh"), VecU8_to_span(&paths.topology_path) )) {
// topology = alice_expect_read_generic_mesh_from_file(paths.topology_path);
// } else if (SpanU8_is_postfix(cstr(".obj"), VecU8_to_span(&paths.topology_path) )) {
// topology = alice_expect_read_generic_mesh_from_obj_file(paths.topology_path);
// } else {
// abortf("Иди своей дорогой\n");
// }
ListNodeAliceGenericMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceGenericMeshHand));
AliceGenericMeshHand* mm = &mm_node->el;
mm->indexes = topology.indexes.len;
mm->indexes = topology->indexes.len;
mm->instance_attr.count = 0;
mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 200);
mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 200);
mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers,
topology.vertices.len * sizeof(GenericMeshVertex));
topology->vertices.len * sizeof(GenericMeshVertex));
mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers,
topology.indexes.len * sizeof(U32));
topology->indexes.len * sizeof(U32));
// todo: change this, I don't like this at all :(
mm->pixels_diffuse = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&paths.diffuse_texture_path));
mm->pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&paths.normal_texture_path));
mm->pixels_specular = TextureDataR8_read_from_png_nofail(VecU8_to_span(&paths.specular_texture_path));
VecU8_drop(paths.diffuse_texture_path);
VecU8_drop(paths.normal_texture_path);
VecU8_drop(paths.specular_texture_path);
mm->pixels_diffuse = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&t_paths.diffuse_texture_path));
mm->pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&t_paths.normal_texture_path));
mm->pixels_specular = TextureDataR8_read_from_png_nofail(VecU8_to_span(&t_paths.specular_texture_path));
VecU8_drop(t_paths.diffuse_texture_path);
VecU8_drop(t_paths.normal_texture_path);
VecU8_drop(t_paths.specular_texture_path);
mm->staging_diffuse_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers,
mm->pixels_diffuse.pixels.len * sizeof(cvec4));
@ -862,9 +863,9 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericM
mm->pixels_specular.pixels.len * sizeof(U8));
mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
topology.vertices.len * sizeof(GenericMeshVertex));
topology->vertices.len * sizeof(GenericMeshVertex));
mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
topology.indexes.len * sizeof(U32));
topology->indexes.len * sizeof(U32));
mm->diffuse_texture = MargaretImgAllocator_alloc(&alice->dev_local_images,
mm->pixels_diffuse.width, mm->pixels_diffuse.height,
@ -883,20 +884,20 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericM
/* We allocated enough memory, but now it's time to actually fill staging buffers */
/* Filleing staging VBO */
assert(mm->staging_vbo.len >= topology.vertices.len * sizeof(GenericMeshVertex));
assert(mm->vbo.len >= topology.vertices.len * sizeof(GenericMeshVertex));
assert(mm->staging_vbo.len >= topology->vertices.len * sizeof(GenericMeshVertex));
assert(mm->vbo.len >= topology->vertices.len * sizeof(GenericMeshVertex));
GenericMeshVertex* staging_vbo = (GenericMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo);
for (U64 i = 0; i < topology.vertices.len; i++) {
staging_vbo[i].base = topology.vertices.buf[i];
for (U64 i = 0; i < topology->vertices.len; i++) {
staging_vbo[i].base = topology->vertices.buf[i];
}
assert(topology.indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < topology.indexes.len; ti++) {
U32 v0 = topology.indexes.buf[ti * 3 + 0];
U32 v1 = topology.indexes.buf[ti * 3 + 1];
U32 v2 = topology.indexes.buf[ti * 3 + 2];
const GenericMeshVertexInc* A0 = VecGenericMeshVertexInc_at(&topology.vertices, v0);
const GenericMeshVertexInc* A1 = VecGenericMeshVertexInc_at(&topology.vertices, v1);
const GenericMeshVertexInc* A2 = VecGenericMeshVertexInc_at(&topology.vertices, v2);
assert(topology->indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < topology->indexes.len; ti++) {
U32 v0 = topology->indexes.buf[ti * 3 + 0];
U32 v1 = topology->indexes.buf[ti * 3 + 1];
U32 v2 = topology->indexes.buf[ti * 3 + 2];
const GenericMeshVertexInc* A0 = VecGenericMeshVertexInc_at(&topology->vertices, v0);
const GenericMeshVertexInc* A1 = VecGenericMeshVertexInc_at(&topology->vertices, v1);
const GenericMeshVertexInc* A2 = VecGenericMeshVertexInc_at(&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;
@ -913,11 +914,11 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericM
staging_vbo[v0].tang_V = staging_vbo[v1].tang_V = staging_vbo[v2].tang_V = tang_U_V.y;
}
/* Filling EBO is easy */
assert(topology.indexes.len == mm->indexes);
size_t ebo_len = topology.indexes.len * sizeof(U32);
assert(topology->indexes.len == mm->indexes);
size_t ebo_len = topology->indexes.len * sizeof(U32);
assert(mm->ebo.len >= ebo_len);
U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo);
memcpy(staging_ebo, topology.indexes.buf, ebo_len);
memcpy(staging_ebo, topology->indexes.buf, ebo_len);
/* Filling staging textures from memory pixel data */
/* todo: do it immediately ON THE READ */
memcpy(MargaretSubbuf_get_mapped(&mm->staging_diffuse_tex_buf), mm->pixels_diffuse.pixels.buf,
@ -1003,56 +1004,55 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericM
return mm_node;
}
ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, VecU8 path){
ShinyMeshTopology topology = alice_expect_read_shiny_mesh_from_file(path);
ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, const ShinyMeshTopology* topology){
ListNodeAliceShinyMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceShinyMeshHand));
AliceShinyMeshHand* mm = &mm_node->el;
mm->indexes = topology.indexes.len;
mm->indexes = topology->indexes.len;
mm->instance_attr.count = 0;
mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 128);
mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 128);
mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers,
topology.vertices.len * sizeof(ShinyMeshVertex));
topology->vertices.len * sizeof(ShinyMeshVertex));
mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers,
topology.indexes.len * sizeof(U32));
topology->indexes.len * sizeof(U32));
mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
topology.vertices.len * sizeof(ShinyMeshVertex));
topology->vertices.len * sizeof(ShinyMeshVertex));
mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
topology.indexes.len * sizeof(U32));
topology->indexes.len * sizeof(U32));
ListAliceShinyMeshHand_insert_node(&alice->shiny_models.hands, mm_node);
VecRefListNodeAliceShinyMeshHand_append(&alice->shiny_models.to_be_copied_to_device_next_cycle, mm_node);
/* We allocated enough memory, now it's time to actually fill staging buffers */
/* And we start by filling staging VBO */
assert(mm->staging_vbo.len >= topology.vertices.len * sizeof(ShinyMeshVertex));
assert(mm->vbo.len >= topology.vertices.len * sizeof(ShinyMeshVertex));
assert(mm->staging_vbo.len >= topology->vertices.len * sizeof(ShinyMeshVertex));
assert(mm->vbo.len >= topology->vertices.len * sizeof(ShinyMeshVertex));
ShinyMeshVertex* staging_vbo = (ShinyMeshVertex*)MargaretSubbuf_get_mapped(&mm->staging_vbo);
for (U64 i = 0; i < topology.vertices.len; i++) {
staging_vbo[i].base = topology.vertices.buf[i];
for (U64 i = 0; i < topology->vertices.len; i++) {
staging_vbo[i].base = topology->vertices.buf[i];
}
assert(topology.indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < topology.indexes.len; ti++) {
U32 v0 = topology.indexes.buf[ti * 3 + 0];
U32 v1 = topology.indexes.buf[ti * 3 + 1];
U32 v2 = topology.indexes.buf[ti * 3 + 2];
vec3 p0 = VecShinyMeshVertexInc_at(&topology.vertices, v0)->pos;
vec3 p1 = VecShinyMeshVertexInc_at(&topology.vertices, v1)->pos;
vec3 p2 = VecShinyMeshVertexInc_at(&topology.vertices, v2)->pos;
assert(topology->indexes.len % 3 == 0);
for (size_t ti = 0; ti * 3 < topology->indexes.len; ti++) {
U32 v0 = topology->indexes.buf[ti * 3 + 0];
U32 v1 = topology->indexes.buf[ti * 3 + 1];
U32 v2 = topology->indexes.buf[ti * 3 + 2];
vec3 p0 = VecShinyMeshVertexInc_at(&topology->vertices, v0)->pos;
vec3 p1 = VecShinyMeshVertexInc_at(&topology->vertices, v1)->pos;
vec3 p2 = VecShinyMeshVertexInc_at(&topology->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;
}
/* Filling staging EBO is super-duper easy */
assert(topology.indexes.len == mm->indexes);
size_t ebo_len = topology.indexes.len * sizeof(U32);
assert(topology->indexes.len == mm->indexes);
size_t ebo_len = topology->indexes.len * sizeof(U32);
assert(mm->ebo.len >= ebo_len);
U32* staging_ebo = (U32*)MargaretSubbuf_get_mapped(&mm->staging_ebo);
memcpy(staging_ebo, topology.indexes.buf, ebo_len);
memcpy(staging_ebo, topology->indexes.buf, ebo_len);
return mm_node;
}

View File

@ -164,8 +164,6 @@ void LucyRenderer_another_frame(LucyRenderer* self){
MargaretBufAllocator_expand_or_free_old(self->ve.dev_local_buffers, &self->vbo, needed_vbo_length);
}
if ((self->need_to_transfer) && self->glyphs_count > 0) {
printf("LucyRenderer: we are doing copying\n");
self->need_to_transfer = false;
margaret_rec_cmd_copy_buffer_one_to_one_part(self->ve.transfer_cmd_buffer,
&self->staging_vbo, &self->vbo, 0, needed_vbo_length);

View File

@ -1,24 +1,44 @@
#include "../../l2/core/glb_file.h"
#include "../../l2/alice/engine.h"
#include "../../l1_5/core/quaternion.h"
#include "../../l1_5/marie/prim_shape_geom.h"
#include "../../../gen/l1/VecAndSpan_vec3.h"
#include "../../l1_5/core/color.h"
typedef struct{
vec3 pos;
vec3 color;
float magnitude;
} LightSourceState;
#include "../../../gen/l1/eve/r4/VecLightSourceState.h"
typedef struct {
float mass;
/* Center of mass relative to "center of mesh" */
vec3 mass_center;
} RigidBodyConfig;
typedef struct {
RigidBodyConfig p;
vec3 pos;
vec3 speed;
vec3 rot;
vec3 rot_speed;
quaternion_t rot;
quaternion_t rot_speed;
} RigidBodyState;
AliceGenericMeshPath AliceGenericMeshPath_for_log(SpanU8 root_dir, U64 w, U64 r, U64 k) {
return (AliceGenericMeshPath){
.topology_path = VecU8_fmt("%s/gen/l2/models/log_%u_%u_%u.AliceGenericMesh", root_dir, w, r, k),
.diffuse_texture_path = VecU8_fmt("%s/src/l3/textures/log_%u_%u_%u_diffuse.png", root_dir, w, r, k),
.normal_texture_path = VecU8_fmt("%s/gen/l2/textures/log_%u_%u_%u_NORMAL.png", root_dir, w, r, k),
.specular_texture_path = VecU8_fmt("%s/src/l3/textures/log_%u_%u_%u_specular.png", root_dir, w, r, k),
};
/* point `M` is relative to the center of mass */
vec3 RigidBodyState_translate_point(const RigidBodyState* self, vec3 M){
return vec3_add_vec3(self->pos, M);
}
vec3 RigidBodyState_translate_point_of_mesh(const RigidBodyState* self, vec3 M){
return RigidBodyState_translate_point(self, vec3_minus_vec3(M, self->p.mass_center));
}
/* Transforms points relative to center of mass. To get model_t for mesh, multiply transition matrix by this matrix */
mat4 RigidBodyState_get_tran_mat(const RigidBodyState* self){
return marie_translation_mat4(self->pos);
}
vec3 project_dir_onto_plane_xz(vec3 v){
@ -31,13 +51,62 @@ typedef struct{
LucyFace* font_face;
RBTreeNodeLucyFaceFixedSize* font_face_of_size_40;
vec3 hero_pos;
} R4AlphaStuff;
ListNodeAliceGenericMeshHand* ROA_mesh;
GenericMeshTopology ROA_topology;
RigidBodyState ROA_state;
ListNodeAliceShinyMeshHand* LS_mesh;
VecLightSourceState LS_state;
U64 misses_count;
U64 hits_count;
Vecvec3 bullets_stuck_on_ROA;
} R4BetaState;
/* We are surrounded by a giant cubic mesh of light sources */
const int lighting_system_dim = 4;
void main_h_on_wayland_keyboard_key(void* data, U32 keysym, U32 act){
R4BetaState *st = data;
Alice* alice = st->alice;
if (act == WL_KEYBOARD_KEY_STATE_RELEASED && keysym == XKB_KEY_Return) {
printf("Shot a bullet!\n");
vec3 P = alice->cam_info.cam.pos;
vec3 dir = vec3_minus(alice->cam_info.cam.cam_basis.z);
vec3 Q = vec3_add_vec3(P, dir);
bool hit = false;
vec3 impact;
VecU32* Is = &st->ROA_topology.indexes;
VecGenericMeshVertexInc* Vs = &st->ROA_topology.vertices;
assert(Is->len % 3 == 0);
// todo: when I make model-t more complex (add rotation), this code will need to be updated
for (size_t i = 0; i < Is->len; i += 3) {
vec3 A = Vs->buf[Is->buf[i + 0]].pos;
vec3 B = Vs->buf[Is->buf[i + 1]].pos;
vec3 C = Vs->buf[Is->buf[i + 2]].pos;
A = RigidBodyState_translate_point_of_mesh(&st->ROA_state, A);
B = RigidBodyState_translate_point_of_mesh(&st->ROA_state, B);
C = RigidBodyState_translate_point_of_mesh(&st->ROA_state, C);
hit = marie_intersect_triangle_and_ray(A, B, C, P, Q, &impact);
if (hit)
break;
}
if (hit) {
st->hits_count++;
/* See, for some dumb reason I decided that bullets share a mesh with light sources. They are all cubes */
// U64 n = st->bullets_stuck_on_ROA.len + st->LS_state.len;
assert(st->bullets_stuck_on_ROA.len + st->LS_state.len == st->LS_mesh->el.instance_attr.count);
vec3 impact_from_center = vec3_minus_vec3(impact, st->ROA_state.pos);
Vecvec3_append(&st->bullets_stuck_on_ROA, impact_from_center);
} else {
st->misses_count++;
}
}
}
void main_h_on_another_frame(void* data, float fl){
R4AlphaStuff *st = data;
R4BetaState *st = data;
Alice* alice = st->alice;
vec3 proj_back = project_dir_onto_plane_xz(alice->cam_info.cam.cam_basis.z);
vec3 proj_right = project_dir_onto_plane_xz(alice->cam_info.cam.cam_basis.x);
@ -62,16 +131,56 @@ void main_h_on_another_frame(void* data, float fl){
}
alice->cam_info.cam.pos = st->hero_pos;
// margaret_ns_time TIME = margaret_clock_gettime_monotonic_raw();
// printf("Updating text\n");
// LucyRenderer_clear(&alice->lucy_renderer);
// VecU8 text = VecU8_fmt("Time is %u.%u\nHave a good day sir\n", (U64)TIME.tv_sec, (U64)TIME.tv_nsec);
// LucyRenderer_add_text(&alice->lucy_renderer, st->font_face_of_size_40, (vec4){0.1f, 0.2f, 0, 1}, 0,
// VecU8_to_span(&text), (ivec2){100, 100});
AliceGenericMeshHand_set_inst(&st->ROA_mesh->el, 0, (GenericMeshInstanceInc){
.model_t = mat4_mul_mat4(RigidBodyState_get_tran_mat(&st->ROA_state),
marie_translation_mat4(vec3_minus(st->ROA_state.p.mass_center))),
});
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&st->alice->pipeline0_ubo.staging);
assert(pipeline_0_ubo_point_light_max_count >= st->LS_state.len);
for (size_t i = 0; i < st->LS_state.len; i++) {
LightSourceState* ls = &st->LS_state.buf[i];
AliceShinyMeshHand_set_inst(&st->LS_mesh->el, i, (ShinyMeshInstanceInc){
.color_on = ls->color,
.model_t = marie_translation_mat4(ls->pos),
});
ubo->point_light_arr[i] = (Pipeline0PointLight){
.pos = ls->pos, .color = vec3_mul_scal(ls->color, 21)};
}
if (st->LS_state.len + st->bullets_stuck_on_ROA.len > st->LS_mesh->el.instance_attr.count) {
AliceShinyMeshHand_resize_instance_arr(alice, &st->LS_mesh->el, st->LS_state.len + st->bullets_stuck_on_ROA.len);
}
for (size_t i = 0; i < st->bullets_stuck_on_ROA.len; i++) {
vec3 bul_pos = st->bullets_stuck_on_ROA.buf[i];
AliceShinyMeshHand_set_inst(&st->LS_mesh->el, st->LS_state.len + i, (ShinyMeshInstanceInc){
.color_on = (vec3){2, 0, 0},
.model_t = mat4_mul_mat4(mat4_mul_mat4(
RigidBodyState_get_tran_mat(&st->ROA_state),
marie_translation_mat4(bul_pos)),
marie_3d_scal_mat4(0.069f)),
});
}
LucyRenderer_clear(&alice->lucy_renderer);
VecU8 text = VecU8_new();
if (st->misses_count == 0 && st->hits_count == 0) {
VecU8_append_cstr(&text, "Press ENTER to shoot\n");
}
if (st->misses_count > 0) {
VecU8_append_fmt(&text, "You missed %u times\n", st->misses_count);
}
if (st->hits_count > 0) {
VecU8_append_fmt(&text, "You hit ROA %u times\n", st->hits_count);
}
LucyRenderer_add_simple_label(&alice->lucy_renderer, st->font_face_of_size_40, (vec4){0, 0, 0, 1}, 0,
VecU8_to_span(&text), (ivec2){10, 10});
VecU8_drop(text);
}
void run_app(){
R4AlphaStuff st;
R4BetaState st;
st.hero_pos = (vec3){0, 0.81f, 0};
Alice* alice = Alice_new();
st.alice = alice;
@ -98,83 +207,68 @@ void run_app(){
LucyGlyphCache_add_glyphs(lucy_requests);
LucyRenderer_add_simple_label(&st.alice->lucy_renderer, st.font_face_of_size_40, (vec4){0, 0, 0, 1}, 0,
cstr("Bebra budet\nотнюхана\n"), (ivec2){10, 10});
cstr("..."), (ivec2){10, 10});
ListNodeAliceGenericMeshHand* model_gen = Alice_add_generic_mesh(st.alice, AliceGenericMeshPath_for_log(cstr("."), 10, 2, 6));
AliceGenericMeshHand_resize_instance_arr(st.alice, &model_gen->el, 1);
VecU8 ROA_mesh_path = vcstr("./gen/l2/models/log_10_2_6.AliceGenericMesh");
st.ROA_topology = alice_expect_read_generic_mesh_from_file(ROA_mesh_path);
for (int X = 0; X < 1; X++) {
for (int Z = 0; Z < 1; Z++) {
AliceGenericMeshHand_set_inst(&model_gen->el, X * 10 + Z, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){11.f * (float)X, -6, 4.f * (float)Z}),
});
}
}
ListNodeAliceShinyMeshHand *model_sh = Alice_add_shiny_mesh(st.alice, vcstr("./gen/l2/models/cube.AliceShinyMesh"));
AliceShinyMeshHand_resize_instance_arr(st.alice, &model_sh->el, 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
AliceShinyMeshHand_set_inst(&model_sh->el, X * 10 + Z, (ShinyMeshInstanceInc){
.color_on = {0, 1, 0},
.model_t = marie_translation_mat4((vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}),
});
st.ROA_mesh = Alice_add_generic_mesh(st.alice, &st.ROA_topology,
(AliceGenericMeshTexturePaths){
.diffuse_texture_path = vcstr("./src/l3/textures/log_10_2_6_diffuse.png"),
.normal_texture_path = vcstr("./gen/l2/textures/log_10_2_6_NORMAL.png"),
.specular_texture_path = vcstr("./src/l3/textures/log_10_2_6_specular.png")
});
AliceGenericMeshHand_resize_instance_arr(st.alice, &st.ROA_mesh->el, 1);
st.ROA_state = (RigidBodyState){
.p.mass = 100.f, .p.mass_center = (vec3){5, 0.77f, -0.77f},
.pos = (vec3){11.f, 3, 4}, .speed = {0},
.rot = (vec4){1, 0, 0, 0}, .rot_speed = (vec4){1, 0, 0, 0}};
ShinyMeshTopology LS_topology = alice_expect_read_shiny_mesh_from_file(vcstr("./gen/l2/models/cube.AliceShinyMesh"));
st.LS_mesh = Alice_add_shiny_mesh(st.alice, &LS_topology);
ShinyMeshTopology_drop(LS_topology);
const int cubes_in_light_wall = lighting_system_dim * lighting_system_dim;
st.LS_state = VecLightSourceState_new_reserved(cubes_in_light_wall * 6);
const vec3 light_cage_ways[6][2] = {
{{0, 1, 0}, {0, 0, 1}}, {{0, 0, 1}, {0, 1, 0}},
{{1, 0, 0}, {0, 0, 1}}, {{0, 0, 1}, {1, 0, 0}},
{{1, 0, 0}, {0, 1, 0}}, {{0, 1, 0}, {1, 0, 0}},
};
const float light_case_edge_offset = 6.1f;
const float light_case_gap = 12.5f;
const float light_cage_rad = (float)(lighting_system_dim - 1) * light_case_gap / 2 + light_case_edge_offset;
for (U64 s = 0; s < 6; s++) {
vec3 u = light_cage_ways[s][0];
vec3 v = light_cage_ways[s][1];
vec3 dir = vec3_mul_scal(vec3_cross(u, v), light_cage_rad);
for (U64 i = 0; i < lighting_system_dim; i++) {
for (U64 j = 0; j < lighting_system_dim; j++) {
vec3 clr = sample_rainbow_color();
VecLightSourceState_append(&st.LS_state, (LightSourceState){
.pos = vec3_add_vec3(dir, vec3_add_vec3(
vec3_mul_scal(u, -light_cage_rad + light_case_edge_offset + light_case_gap * (float)i),
vec3_mul_scal(v, -light_cage_rad + light_case_edge_offset + light_case_gap * (float)j))),
.color = clr,
.magnitude = 1
});
}
}
}
AliceShinyMeshHand_resize_instance_arr(st.alice, &st.LS_mesh->el, st.LS_state.len);
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&st.alice->pipeline0_ubo.staging);
assert(pipeline_0_ubo_point_light_max_count >= 100);
ubo->point_light_count = 100;
assert(pipeline_0_ubo_point_light_max_count >= st.LS_state.len);
ubo->point_light_count = (int)st.LS_state.len;
ubo->spotlight_count = 0;
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
ubo->point_light_arr[X * 10 + Z] = (Pipeline0PointLight){
.pos = (vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10},
.color = {5, 5, 5}
};
}
}
ubo->point_light_arr[0].color = (vec3){100, 100, 100};
st.misses_count = 0;
st.hits_count = 0;
st.bullets_stuck_on_ROA = Vecvec3_new();
ListNodeAliceGenericMeshHand* skeleton_mesh = Alice_add_generic_mesh(st.alice, (AliceGenericMeshPath){
.topology_path = vcstr("./src/l3/models/skeleton.obj"),
.diffuse_texture_path = vcstr("./src/l3/models/bone.png"),
.normal_texture_path = vcstr("./gen/l2/textures/flat_NORMAL.png"),
.specular_texture_path = vcstr("./gen/l2/textures/flat_NORMAL.png"),
});
AliceGenericMeshHand_resize_instance_arr(alice, &skeleton_mesh->el, 1);
AliceGenericMeshHand_set_inst(&skeleton_mesh->el, 0, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){5.f, -3, 12.f}),
});
ListNodeAliceGenericMeshHand* floor1_mesh = Alice_add_generic_mesh(st.alice, (AliceGenericMeshPath){
.topology_path = vcstr("gen/l2/models/floor1.AliceGenericMesh"),
.diffuse_texture_path = vcstr("src/l3/textures/wood.png"),
.normal_texture_path = vcstr("gen/l2/textures/flat_NORMAL.png"),
.specular_texture_path = vcstr("gen/l2/textures/no_SPECULAR.png"),
});
AliceGenericMeshHand_resize_instance_arr(alice, &floor1_mesh->el, 1);
AliceGenericMeshHand_set_inst(&floor1_mesh->el, 0, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){0, 0, 0}),
});
ListNodeAliceGenericMeshHand* model_puck = Alice_add_generic_mesh(st.alice, (AliceGenericMeshPath){
.topology_path = vcstr("gen/l2/models/puck.AliceGenericMesh"),
.diffuse_texture_path = vcstr("src/l3/textures/puck_diffuse.png"),
.normal_texture_path = vcstr("gen/l2/textures/puck_NORMAL.png"),
.specular_texture_path = vcstr("src/l3/textures/puck_specular.png"),
});
AliceGenericMeshHand_resize_instance_arr(st.alice, &model_puck->el, 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
AliceGenericMeshHand_set_inst(&model_puck->el, X * 10 + Z, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){11.f * (float)X - 20, -1, 4.f * (float)Z - 10}),
});
}
}
Alice_mainloop(st.alice, &(AliceCallbacks){
.on_wl_keyboard_key = main_h_on_wayland_keyboard_key,
.on_another_frame = main_h_on_another_frame,
@ -183,14 +277,4 @@ void run_app(){
int main(){
run_app();
VecU8 file = read_file_by_path(vcstr("./src/l3/models/skeleton.glb"));
GLBFileSegments data;
int c = glb_file_get_segments(VecU8_to_span(&file), &data);
if (c > 0) {
abortf("Incorrect glb ==> %d\n", c);
}
VecU8 json_text = json_encode(&data.gltf);
VecU8_print(json_text);
GLBFileSegments_drop(data);
VecU8_drop(file);
}

View File

@ -1,7 +1,7 @@
#version 450
layout(location = 0) in vec3 norm;
layout(location = 1) in vec3 color_off;
layout(location = 1) in vec3 color_off;
layout(location = 2) in vec3 color_on;
layout(location = 3) in vec3 pos;