До тотального отнюха бебры осталось 11 часов. Я сохраняю модель в дурацком формате и читаю их потом из файла

This commit is contained in:
Андреев Григорий 2025-12-30 00:16:52 +03:00
parent cf237d1c0b
commit f1d42f37b9
8 changed files with 439 additions and 274 deletions

View File

@ -34,14 +34,14 @@ GenericMeshTopology GenericMeshTopology_clone(const GenericMeshTopology* self) {
}
typedef struct {
GenericMeshTopology topology;
VecU8 topology_path;
VecU8 diffuse_texture_path;
VecU8 normal_texture_path;
VecU8 specular_texture_path;
} GenericMeshAndTextureFilePath;
} AliceGenericMeshPath;
void GenericMeshInSceneTemplate_drop(GenericMeshAndTextureFilePath self) {
GenericMeshTopology_drop(self.topology);
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);

108
src/l2/alice/model_file.h Normal file
View File

@ -0,0 +1,108 @@
#ifndef prototype1_src_l2_alice_model_file_h
#define prototype1_src_l2_alice_model_file_h
#include "../../l1/system/fileio.h"
#include "assets.h"
#include "stdalign.h"
static_assert(sizeof(float) == 4, "...");
static_assert(sizeof(GenericMeshVertexInc) == 4 * (3 + 2), "...");
static_assert(alignof(GenericMeshVertexInc) == 4, "...");
static_assert(sizeof(ShinyMeshVertexInc) == 4 * (3), "...");
static_assert(alignof(ShinyMeshVertexInc) == 4, "...");
/* Yes, at this point I really started thinking that maybe I should have written Alice as a template */
/* Works only within one machine. todo: rewrite to use .obj after the session is over */
void alice_write_generic_mesh_to_file(GenericMeshTopology model, VecU8 file_path){
U64 byte_size = sizeof(U64) * 2 +
sizeof(GenericMeshVertexInc) * model.vertices.len + sizeof(U32) * model.indexes.len;
VecU8 res = VecU8_new_zeroinit(byte_size);
U8* buf = res.buf;
*(U64*)buf = model.vertices.len;
buf += sizeof(U64);
*(U64*)buf = model.indexes.len;
buf += sizeof(U64);
memcpy(buf, model.vertices.buf, model.vertices.len * sizeof(GenericMeshVertexInc));
buf += model.vertices.len * sizeof(GenericMeshVertexInc);
memcpy(buf, model.indexes.buf, model.indexes.len * sizeof(U32));
VecU8_append(&file_path, 0);
write_whole_file_or_abort((const char*)file_path.buf, VecU8_to_span(&res));
GenericMeshTopology_drop(model);
VecU8_drop(file_path);
VecU8_drop(res);
}
GenericMeshTopology alice_expect_read_generic_mesh_from_file(VecU8 file_path){
VecU8 read = read_file_by_path(file_path);
U8* buf = read.buf;
U64 remaining = read.len;
if (remaining < sizeof(U64) * 2) {
abortf("Too short\n");
}
U64 vertices_len = *(U64*)buf;
buf += sizeof(U64);
U64 indexes_len = *(U64*)buf;
buf += sizeof(U64);
if (vertices_len > 1000000 || indexes_len > 1000000) {
abortf("Model is too big\n");
}
remaining -= sizeof(U64) * 2;
if (remaining != vertices_len * sizeof(GenericMeshVertexInc) + indexes_len * sizeof(U32)) {
abortf("Incorrect file size\n");
}
VecGenericMeshVertexInc vertices = VecGenericMeshVertexInc_new_zeroinit(vertices_len);
memcpy(vertices.buf, buf, vertices_len * sizeof(GenericMeshVertexInc));
buf += vertices_len * sizeof(GenericMeshVertexInc);
VecU32 indexes = VecU32_new_zeroinit(indexes_len);
memcpy(indexes.buf, buf, indexes_len * sizeof(U32));
return (GenericMeshTopology){.vertices = vertices, .indexes = indexes};
}
void alice_write_shiny_mesh_to_file(ShinyMeshTopology model, VecU8 file_path){
U64 byte_size = sizeof(U64) * 2 +
sizeof(ShinyMeshVertexInc) * model.vertices.len + sizeof(U32) * model.indexes.len;
VecU8 res = VecU8_new_zeroinit(byte_size);
U8* buf = res.buf;
*(U64*)buf = model.vertices.len;
buf += sizeof(U64);
*(U64*)buf = model.indexes.len;
buf += sizeof(U64);
memcpy(buf, model.vertices.buf, model.vertices.len * sizeof(ShinyMeshVertexInc));
buf += model.vertices.len * sizeof(ShinyMeshVertexInc);
memcpy(buf, model.indexes.buf, model.indexes.len * sizeof(U32));
VecU8_append(&file_path, 0);
write_whole_file_or_abort((const char*)file_path.buf, VecU8_to_span(&res));
ShinyMeshTopology_drop(model);
VecU8_drop(file_path);
VecU8_drop(res);
}
ShinyMeshTopology alice_expect_read_shiny_mesh_from_file(VecU8 file_path){
VecU8 read = read_file_by_path(file_path);
U8* buf = read.buf;
U64 remaining = read.len;
if (remaining < sizeof(U64) * 2) {
abortf("Too short\n");
}
U64 vertices_len = *(U64*)buf;
buf += sizeof(U64);
U64 indexes_len = *(U64*)buf;
buf += sizeof(U64);
if (vertices_len > 10000 || indexes_len > 10000)
abortf("Model is too big\n");
remaining -= sizeof(U64) * 2;
if (remaining != vertices_len * sizeof(ShinyMeshVertexInc) + indexes_len * sizeof(U32)) {
abortf("Incorrect file size\n");
}
VecShinyMeshVertexInc vertices = VecShinyMeshVertexInc_new_zeroinit(vertices_len);
memcpy(vertices.buf, buf, vertices_len * sizeof(ShinyMeshVertexInc));
buf += vertices_len * sizeof(ShinyMeshVertexInc);
VecU32 indexes = VecU32_new_zeroinit(indexes_len);
memcpy(indexes.buf, buf, indexes_len * sizeof(U32));
return (ShinyMeshTopology){.vertices = vertices, .indexes = indexes};
}
/* No beauty, just pure brute force */
#endif

View File

@ -7,6 +7,8 @@
module Allie (justFuckingDoSomething) where
import Geom
import Data.Word (Word8, Word16, Word32, Word64)
import Data.Int (Int8, Int16, Int32, Int64)
import Foreign.Ptr (Ptr, FunPtr, nullPtr, plusPtr, castPtr)
@ -17,8 +19,9 @@ import qualified Data.Text
import Data.Text.Encoding (encodeUtf8)
import Data.ByteString (useAsCStringLen)
data AliceOpaque
type Alice = Ptr AliceOpaque
--import Geom
type Alice = Ptr Word8
foreign import ccall "Alice_new" newAlice :: IO Alice
@ -27,6 +30,18 @@ data AliceAnotherFrameCap s = AliceAnotherFrameCap Alice
foreign import ccall "wrapper" allieMkAliceOnWaylandKeyboardKey :: (Alice -> IO ()) -> IO (FunPtr (Alice -> IO ()))
foreign import ccall "wrapper" allieMkAliceOnAnotherFrame :: (Alice -> IO ()) -> IO (FunPtr (Alice -> IO ()))
-- All of that is inside Alice. They hold pointers to Alice
type LucyFontFace = Ptr Word8
-- Actually stores a pointer to rb-tree node in LucyFontFace tree. Must not be deleted by without caution
type LucyFontFaceFixedSize = Ptr Word8
type AliceGenericMeshHand = Ptr Word8
type AliceShinyMeshHand = Ptr Word8
alicePipeline0PointLightMaxCount :: Int
alicePipeline0PointLightMaxCount = 120
data Callbacks = Callbacks {
onWaylandKeyboardKey :: (Alice -> IO ()),
onAnotherFrame :: (forall s. AliceAnotherFrameCap s -> IO ())
@ -59,13 +74,18 @@ foreign import ccall "allie_Alice_add_screen_text_label" allieAliceAddScreenText
aliceAddScreenTextLabel :: AliceAnotherFrameCap s -> String -> IO ()
aliceAddScreenTextLabel (AliceAnotherFrameCap alice) str = useAsCStringLen (encodeUtf8 $ Data.Text.pack $ str) $ \(cstr, len) -> allieAliceAddScreenTextLabel alice (castPtr cstr) (fromIntegral len)
my2onAnotherFrame :: p -> IO ()
my2onAnotherFrame alicePerm = putStrLn "ahahhahah"
--allieRunAlice :: Callbacks ->
-- Function to run the main loop with callbacks
justFuckingDoSomething :: IO ()
justFuckingDoSomething = do
alice <- newAlice
state <- newIORef 67
-- Create the Callbacks structure.
let callbacks = Callbacks myonKeyboardKey myonAnotherFrame where
let callbacks = Callbacks myonKeyboardKey my2onAnotherFrame where
myonKeyboardKey _ = do
old <- readIORef state
writeIORef state (old + 1)

44
src/l2/allie/Geom.hs Normal file
View File

@ -0,0 +1,44 @@
module Geom(Vec2(..), Vec3(..), Vec4(..), Mat4(..), Addable(..), Multipliable(..)) where
data Vec2 = Vec2 !Float !Float
deriving (Eq, Show)
data Vec3 = Vec3 !Float !Float !Float
deriving (Eq, Show)
data Vec4 = Vec4 !Float !Float !Float !Float
deriving (Eq, Show)
infixl 6 ^+^
class Addable a where
(^+^) :: a -> a -> a
instance Addable Vec2 where
(Vec2 ax ay) ^+^ (Vec2 bx by) = Vec2 (ax + bx) (ay + by)
instance Addable Vec3 where
(Vec3 ax ay az) ^+^ (Vec3 bx by bz) =
Vec3 (ax + bx) (ay + by) (az + bz)
instance Addable Vec4 where
(Vec4 a1 a2 a3 a4) ^+^ (Vec4 b1 b2 b3 b4) =
Vec4 (a1 + b1) (a2 + b2) (a3 + b3) (a4 + b4)
infixl 7 ^*^
class Multipliable a b c where
(^*^) :: a -> b -> c
instance Multipliable Vec2 Float Vec2 where
(Vec2 ax ay) ^*^ b = Vec2 (ax * b) (ay * b)
instance Multipliable Vec3 Float Vec3 where
(Vec3 ax ay az) ^*^ b = Vec3 (ax * b) (ay * b) (az * b)
instance Multipliable Vec4 Float Vec4 where
(Vec4 ax ay az aw) ^*^ b = Vec4 (ax * b) (ay * b) (az * b) (aw * b)
data Mat4 = Mat4 !Vec4 !Vec4 !Vec4 !Vec4
mat4Transit :: Vec3 -> Mat4
mat4Transit (Vec3 x y z) = Mat4 (Vec4 1 0 0 0) (Vec4 0 1 0 0) (Vec4 0 0 1 0) (Vec4 x y z 1)

View File

@ -1,5 +1,4 @@
#include "../alice/assets.h"
#include "../anne/r4_models.h" // todo: this is very illegal, this is very-very illegal. Please, don't do this
#include "../alice/model_file.h"
#include "../../l1/marie/geom_alg_utils.h"
#include "../margaret/vulkan_utils.h"
#include "../lucy/glyph_render.h"
@ -820,35 +819,30 @@ struct Alice {
VkFramebuffer IT1_framebuffer;
VkDescriptorSet descriptor_set_for_pipeline_0b;
VkDescriptorSet descriptor_set_for_pipeline_1;
/* todo: it is not actually a part of engine code, it is an app code. I will delete it */
LucyFace font_face;
RBTreeNodeLucyFaceFixedSize* font_face_of_size_40;
ListNodeAliceGenericMeshHand* model_gen;
ListNodeAliceShinyMeshHand* model_sh;
};
ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, GenericMeshAndTextureFilePath mt){
ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, AliceGenericMeshPath paths){
GenericMeshTopology topology = alice_expect_read_generic_mesh_from_file(paths.topology_path);
ListNodeAliceGenericMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceGenericMeshHand));
AliceGenericMeshHand* mm = &mm_node->el;
mm->indexes = mt.topology.indexes.len;
mm->indexes = topology.indexes.len;
mm->instance_attr.count = 0;
mm->instance_attr.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, 69);
mm->instance_attr.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, 69);
mm->staging_vbo = MargaretBufAllocator_alloc(&alice->staging_buffers,
mt.topology.vertices.len * sizeof(GenericMeshVertex));
topology.vertices.len * sizeof(GenericMeshVertex));
mm->staging_ebo = MargaretBufAllocator_alloc(&alice->staging_buffers,
mt.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(&mt.diffuse_texture_path));
mm->pixels_normal = TextureDataR8G8B8A8_read_from_png_nofail(VecU8_to_span(&mt.normal_texture_path));
mm->pixels_specular = TextureDataR8_read_from_png_nofail(VecU8_to_span(&mt.specular_texture_path));
VecU8_drop(mt.diffuse_texture_path);
VecU8_drop(mt.normal_texture_path);
VecU8_drop(mt.specular_texture_path);
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->staging_diffuse_tex_buf = MargaretBufAllocator_alloc(&alice->staging_buffers,
mm->pixels_diffuse.pixels.len * sizeof(cvec4));
@ -858,9 +852,9 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, GenericMeshAn
mm->pixels_specular.pixels.len * sizeof(U8));
mm->vbo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
mt.topology.vertices.len * sizeof(GenericMeshVertex));
topology.vertices.len * sizeof(GenericMeshVertex));
mm->ebo = MargaretBufAllocator_alloc(&alice->dev_local_buffers,
mt.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,
@ -879,20 +873,20 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, GenericMeshAn
/* We allocated enough memory, but now it's time to actually fill staging buffers */
/* Filleing staging VBO */
assert(mm->staging_vbo.len >= mt.topology.vertices.len * sizeof(GenericMeshVertex));
assert(mm->vbo.len >= mt.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 < mt.topology.vertices.len; i++) {
staging_vbo[i].base = mt.topology.vertices.buf[i];
for (U64 i = 0; i < topology.vertices.len; i++) {
staging_vbo[i].base = 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);
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;
@ -909,11 +903,11 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, GenericMeshAn
staging_vbo[v0].tang_V = staging_vbo[v1].tang_V = staging_vbo[v2].tang_V = tang_U_V.y;
}
/* Filling EBO is easy */
assert(mt.topology.indexes.len == mm->indexes);
size_t ebo_len = mt.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, mt.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,
@ -999,7 +993,9 @@ ListNodeAliceGenericMeshHand* Alice_add_generic_mesh(Alice* alice, GenericMeshAn
return mm_node;
}
ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, ShinyMeshTopology topology){
ListNodeAliceShinyMeshHand* Alice_add_shiny_mesh(Alice* alice, VecU8 path){
ShinyMeshTopology topology = alice_expect_read_shiny_mesh_from_file(path);
ListNodeAliceShinyMeshHand* mm_node = safe_calloc(1, sizeof(ListNodeAliceShinyMeshHand));
AliceShinyMeshHand* mm = &mm_node->el;
@ -1558,18 +1554,11 @@ void alice_frame_drawing(Alice* alice) {
alice->callbacks.on_another_frame(alice);
margaret_reset_and_begin_command_buffer(alice->transfer_command_buf);
AliceScene__another_frame(alice);
LucyGlyphCache_another_frame(&alice->lucy_cache);
// LucyRenderer_clear(&alice->lucy_renderer);
// LucyRenderer_add_text(&alice->lucy_renderer, alice->font_face_of_size_40, (vec4){1, 0, 0, 1}, 0,
// VecU8_to_span(&alice->scene.text_on_screen), (ivec2){10, 10});
LucyRenderer_another_frame(&alice->lucy_renderer);
margaret_end_command_buffer(alice->transfer_command_buf);
alice_reset_and_record_command_buffer_0(alice, t_mat);
alice_reset_and_record_command_buffer_1(alice, *VecVkFramebuffer_at(&alice->swfb.framebuffers, ij));
check(vkQueueSubmit(alice->queues.graphics_queue, 1, &(VkSubmitInfo){
@ -2066,6 +2055,8 @@ Alice* Alice_new(){
alice->shiny_models = AliceAllMeshesShiny_new();
alice->pipeline0_ubo.staging = MargaretBufAllocator_alloc(&alice->staging_buffers, sizeof(Pipeline0UBO));
alice->pipeline0_ubo.device_local = MargaretBufAllocator_alloc(&alice->dev_local_buffers, sizeof(Pipeline0UBO));
Pipeline0UBO* ubo0 = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
ubo0->point_light_count = ubo0->spotlight_count = 0;
alice->cam_info = AliceCamVerticalControl_new();
alice->rendering_config = AliceRenderConfig_new();
@ -2097,77 +2088,31 @@ Alice* Alice_new(){
alice->wl.prev_key_frame_time = margaret_clock_gettime_monotonic_raw();
alice->wl.frame_count_since_key = 0;
/* Alice initialization complete */
/* todo: delete exaple data initialization. Yes, this is not part of an engine. It is an example I need to delete this */
alice->font_face = LucyFace_new(alice->ft_library, &alice->lucy_cache,
VecU8_fmt("%s/src/l3/fonts/DMSerifText-Regular.ttf", root_dir));
alice->font_face_of_size_40 = LucyFace_of_size(&alice->font_face, 40);
{
VecLucyGlyphCachingRequest lucy_requests = VecLucyGlyphCachingRequest_new();
VecU32Segment ranges_needed = VecU32Segment_new();
VecU32Segment_append(&ranges_needed, (U32Segment){.start = 32, .len = 126 - 32 + 1});
VecLucyGlyphCachingRequest_append(&lucy_requests, (LucyGlyphCachingRequest){
.sized_face = alice->font_face_of_size_40, .codepoint_ranges = ranges_needed,
});
LucyGlyphCache_add_glyphs(lucy_requests);
}
{
alice->model_gen = Alice_add_generic_mesh(alice, GenericMeshAndTextureFilePath_for_log(root_dir, 10, 2, 6));
AliceGenericMeshHand_resize_instance_arr(alice, &alice->model_gen->el, 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
AliceGenericMeshHand_set(&alice->model_gen->el, X * 10 + Z, (GenericMeshInstanceInc){
.model_t = marie_translation_mat4((vec3){11.f * (float)X, -6, 4.f * (float)Z}),
});
}
}
alice->model_sh = Alice_add_shiny_mesh(alice, generate_shiny_cube(0.3f));
AliceShinyMeshHand_resize_instance_arr(alice, &alice->model_sh->el, 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
AliceShinyMeshHand_set(&alice->model_sh->el, X * 10 + Z, (ShinyMeshInstanceInc){
.color_on = {0, 1, 0}, .color_off = {0.3f, 0.6f, 0.3f},
.model_t = marie_translation_mat4((vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}),
});
}
}
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
assert(pipeline_0_ubo_point_light_max_count >= 100);
ubo->point_light_count = 100;
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};
}
LucyRenderer_add_text(&alice->lucy_renderer, alice->font_face_of_size_40, (vec4){1, 0, 0, 1}, 0,
cstr("Bebra budet\notnyahana"), (ivec2){10, 10});
return alice;
}
void Alice_set_point_light_count(Alice* alice, int new_count){
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
assert(new_count <= pipeline_0_ubo_point_light_max_count);
ubo->point_light_count = new_count;
}
void Alice_set_point_light(Alice* alice, int index, Pipeline0PointLight data){
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
assert(index < pipeline_0_ubo_point_light_max_count);
ubo->point_light_arr[index] = data;
}
void Alice_clear_screen_text(Alice* alice){
LucyRenderer_clear(&alice->lucy_renderer);
}
void Alice_add_screen_text_label(Alice* alice, SpanU8 text){
LucyRenderer_add_text(&alice->lucy_renderer, alice->font_face_of_size_40, (vec4){1, 0, 0, 1}, 0,
text, (ivec2){10, 10});
}
void allie_Alice_add_screen_text_label(Alice* alice, const U8* data, U64 len){
Alice_add_screen_text_label(alice, (SpanU8){data, len});
void Alice_add_screen_text(Alice* alice, RBTreeNodeLucyFaceFixedSize* ffs, vec4 color, SpanU8 text, ivec2 start_pos){
LucyRenderer_add_text(&alice->lucy_renderer, ffs, color, 0, text, start_pos);
}
/* This function actually consumes alice handler */
void Alice_mainloop(Alice* alice, const AliceCallbacks* callbacks) {
alice->callbacks.on_wl_keyboard_key = callbacks->on_wl_keyboard_key;
alice->callbacks.on_another_frame = callbacks->on_another_frame;
@ -2218,5 +2163,5 @@ void Alice_mainloop(Alice* alice, const AliceCallbacks* callbacks) {
// if (alice->wl.wl_seat)
// wl_seat_destroy(alice->wl.wl_seat);
// wl_registry_destroy(alice->wl.wl_registry);
// wl_display_disconnect(alice->wl.wl_display);
wl_display_disconnect(alice->wl.wl_display);
}

View File

@ -1,7 +1,7 @@
#ifndef prototype1_src_l2_anne_r4_h
#define prototype1_src_l2_anne_r4_h
#include "r4_models.h"
#include "../alice/assets.h"
#include "../../../gen/l1/pixel_masses.h"
#include "../marie/rasterization.h"
#include "../marie/texture_processing.h"
@ -526,9 +526,149 @@ TextureDataR8G8B8A8 generate_normal_tex_for_one_fourth_of_a_cylinder(float s_res
return res;
}
GenericMeshTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) {
assert(k >= 1);
const float a = M_PI_2f / (float)k;
const float l = 2 * r * sinf(M_PI_4f / (float)k);
float tex_width = 2 * r + w;
float tex_height = 2 * r + (float)k * l;
const vec2 v0tex = {r / tex_width, r / tex_height};
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};
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++) {
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}
});
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 == 8 + 4 * k);
for (U32 i = 0; i <= k; i++) {
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},
});
}
VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {0, 0, 0}, .tex = v0tex});
for (U32 i = 0; i <= k; i++) {
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},
});
}
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[] = {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[] = {
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)});
}
return (GenericMeshTopology){.vertices = vertices, .indexes = indexes};
}
U32 quad_to_triangles_conv_arr[6] = {0, 1, 2, 0, 2, 3};
ShinyMeshTopology generate_shiny_cube(float r) {
ShinyMeshVertexInc vert[24] = {
{{+r, +r, +r}},
{{+r, -r, +r}},
{{+r, -r, -r}},
{{+r, +r, -r}},
{{-r, -r, -r}},
{{-r, -r, +r}},
{{-r, +r, +r}},
{{-r, +r, -r}},
{{+r, +r, +r}},
{{+r, +r, -r}},
{{-r, +r, -r}},
{{-r, +r, +r}},
{{-r, -r, -r}},
{{+r, -r, -r}},
{{+r, -r, +r}},
{{-r, -r, +r}},
{{+r, +r, +r}},
{{-r, +r, +r}},
{{-r, -r, +r}},
{{+r, -r, +r}},
{{-r, -r, -r}},
{{-r, +r, -r}},
{{+r, +r, -r}},
{{+r, -r, -r}},
};
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++)
VecU32_append(&indexes_vec, f * 4 + quad_to_triangles_conv_arr[j]);
}
return (ShinyMeshTopology){ .vertices = vertices_vec, .indexes = indexes_vec};
}
typedef struct {
int face;
/* There is a counterclockwise one-to-one correspondence between vertexes of face and edges of face */
int vert_on_it;
} CubeVertOfFace;
CubeVertOfFace CubeVertOfFace_jump(CubeVertOfFace vert) {
const CubeVertOfFace cube_detour_get_neighbour_face[6][4] = {
{{4, 3}, {3, 1}, {5, 2}, {2, 0}},
{{3, 3}, {4, 1}, {2, 2}, {5, 0}},
{{0, 3}, {5, 1}, {1, 2}, {4, 0}},
{{5, 3}, {0, 1}, {4, 2}, {1, 0}},
{{2, 3}, {1, 1}, {3, 2}, {0, 0}},
{{1, 3}, {2, 1}, {0, 2}, {3, 0}}
};
return cube_detour_get_neighbour_face[vert.face][vert.vert_on_it];
}
U32 CubeVertOfFace_to_vid(CubeVertOfFace vert) {
return 4 * vert.face + vert.vert_on_it;
}
CubeVertOfFace CubeVertOfFace_next(CubeVertOfFace vert) {
return (CubeVertOfFace){vert.face, (vert.vert_on_it + 1) % 4};
}
#include "../../../gen/l1/margaret/png_pixel_masses.h"
#include "../marie/texture_processing.h"
#include "../../l1/system/fsmanip.h"
#include "../alice/model_file.h"
void for_log(U64 w, U64 r, U64 k) {
{
@ -549,16 +689,19 @@ void for_log(U64 w, U64 r, U64 k) {
TextureDataR8G8B8A8_drop(fixed_tex);
TextureDataR8G8B8A8_drop(tex);
}
GenericMeshTopology top = generate_one_fourth_of_a_cylinder((float)w, (float)r, k);
alice_write_generic_mesh_to_file(top, VecU8_fmt("l2/models/log_%u_%u_%u.AliceGenericMesh", w, r, k));
}
/* We are on l2 */
int gen_assets_for_r4() {
mkdir_nofail("l2/models");
mkdir_nofail("l2/textures");
mkdir_nofail("l2/textures/r4");
for_log(10, 2, 6);
// for_log(5, 5, 10);
// for_log(1, 10, 4);
// for_log(2, 1, 6);
alice_write_shiny_mesh_to_file(generate_shiny_cube(0.3f), vcstr("l2/models/cube.AliceShinyMesh"));
return 0;
}

View File

@ -1,156 +0,0 @@
#ifndef prototype1_src_l2_anne_r4_models_h
#define prototype1_src_l2_anne_r4_models_h
#include "../alice/assets.h"
#include "../../l1/core/VecU8_as_str.h"
GenericMeshTopology generate_one_fourth_of_a_cylinder(float w, float r, U32 k) {
assert(k >= 1);
const float a = M_PI_2f / (float)k;
const float l = 2 * r * sinf(M_PI_4f / (float)k);
float tex_width = 2 * r + w;
float tex_height = 2 * r + (float)k * l;
const vec2 v0tex = {r / tex_width, r / tex_height};
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};
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++) {
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}
});
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 == 8 + 4 * k);
for (U32 i = 0; i <= k; i++) {
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},
});
}
VecGenericMeshVertexInc_append(&vertices, (GenericMeshVertexInc){.pos = {0, 0, 0}, .tex = v0tex});
for (U32 i = 0; i <= k; i++) {
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},
});
}
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[] = {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[] = {
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)});
}
return (GenericMeshTopology){.vertices = vertices, .indexes = indexes};
}
U32 quad_to_triangles_conv_arr[6] = {0, 1, 2, 0, 2, 3};
ShinyMeshTopology generate_shiny_cube(float r) {
ShinyMeshVertexInc vert[24] = {
{{+r, +r, +r}},
{{+r, -r, +r}},
{{+r, -r, -r}},
{{+r, +r, -r}},
{{-r, -r, -r}},
{{-r, -r, +r}},
{{-r, +r, +r}},
{{-r, +r, -r}},
{{+r, +r, +r}},
{{+r, +r, -r}},
{{-r, +r, -r}},
{{-r, +r, +r}},
{{-r, -r, -r}},
{{+r, -r, -r}},
{{+r, -r, +r}},
{{-r, -r, +r}},
{{+r, +r, +r}},
{{-r, +r, +r}},
{{-r, -r, +r}},
{{+r, -r, +r}},
{{-r, -r, -r}},
{{-r, +r, -r}},
{{+r, +r, -r}},
{{+r, -r, -r}},
};
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++)
VecU32_append(&indexes_vec, f * 4 + quad_to_triangles_conv_arr[j]);
}
return (ShinyMeshTopology){ .vertices = vertices_vec, .indexes = indexes_vec};
}
typedef struct {
int face;
/* There is a counterclockwise one-to-one correspondence between vertexes of face and edges of face */
int vert_on_it;
} CubeVertOfFace;
CubeVertOfFace CubeVertOfFace_jump(CubeVertOfFace vert) {
const CubeVertOfFace cube_detour_get_neighbour_face[6][4] = {
{{4, 3}, {3, 1}, {5, 2}, {2, 0}},
{{3, 3}, {4, 1}, {2, 2}, {5, 0}},
{{0, 3}, {5, 1}, {1, 2}, {4, 0}},
{{5, 3}, {0, 1}, {4, 2}, {1, 0}},
{{2, 3}, {1, 1}, {3, 2}, {0, 0}},
{{1, 3}, {2, 1}, {0, 2}, {3, 0}}
};
return cube_detour_get_neighbour_face[vert.face][vert.vert_on_it];
}
U32 CubeVertOfFace_to_vid(CubeVertOfFace vert) {
return 4 * vert.face + vert.vert_on_it;
}
CubeVertOfFace CubeVertOfFace_next(CubeVertOfFace vert) {
return (CubeVertOfFace){vert.face, (vert.vert_on_it + 1) % 4};
}
// todo: yes, it is AGAINST THE RULES to take from l3 when being on l2, but we fjsdafklj lI WILL REMOVE THIS OK, MAN CALM DOWN
GenericMeshAndTextureFilePath GenericMeshAndTextureFilePath_for_log(SpanU8 root_dir, U64 w, U64 r, U64 k) {
return (GenericMeshAndTextureFilePath){.topology = generate_one_fourth_of_a_cylinder((float)w, (float)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/r4/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),
};
}
// todo: separate model data generation and create a function that writes it to .obj file
// todo numero 2: stop generating model data on the fly in r4 and start loading it from generated file
#endif

View File

@ -1,5 +1,14 @@
#include "../../l2/allie/allie.c"
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/r4/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),
};
}
void main_h_on_wayland_keyboard_key(Alice* alice){
}
@ -10,6 +19,58 @@ void main_h_on_another_frame(Alice* alice){
int main(){
Alice* alice = Alice_new();
LucyFace font_face = LucyFace_new(alice->ft_library, &alice->lucy_cache,
VecU8_fmt("%s/src/l3/fonts/DMSerifText-Regular.ttf", cstr(".")));
RBTreeNodeLucyFaceFixedSize* font_face_of_size_40 = LucyFace_of_size(&font_face, 40);
VecLucyGlyphCachingRequest lucy_requests = VecLucyGlyphCachingRequest_new();
VecU32Segment ranges_needed = VecU32Segment_new();
VecU32Segment_append(&ranges_needed, (U32Segment){.start = 32, .len = 126 - 32 + 1});
VecLucyGlyphCachingRequest_append(&lucy_requests, (LucyGlyphCachingRequest){
.sized_face = font_face_of_size_40, .codepoint_ranges = ranges_needed,
});
LucyGlyphCache_add_glyphs(lucy_requests);
ListNodeAliceGenericMeshHand* model_gen = Alice_add_generic_mesh(alice, AliceGenericMeshPath_for_log(cstr("."), 10, 2, 6));
AliceGenericMeshHand_resize_instance_arr(alice, &model_gen->el, 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
AliceGenericMeshHand_set(&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(alice, vcstr("./gen/l2/models/cube.AliceShinyMesh"));
AliceShinyMeshHand_resize_instance_arr(alice, &model_sh->el, 100);
for (int X = 0; X < 10; X++) {
for (int Z = 0; Z < 10; Z++) {
AliceShinyMeshHand_set(&model_sh->el, X * 10 + Z, (ShinyMeshInstanceInc){
.color_on = {0, 1, 0}, .color_off = {0.3f, 0.6f, 0.3f},
.model_t = marie_translation_mat4((vec3){11.f * (float)X - 20, 10, 4.f * (float)Z - 10}),
});
}
}
Pipeline0UBO* ubo = (Pipeline0UBO*)MargaretSubbuf_get_mapped(&alice->pipeline0_ubo.staging);
assert(pipeline_0_ubo_point_light_max_count >= 100);
ubo->point_light_count = 100;
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};
LucyRenderer_add_text(&alice->lucy_renderer, font_face_of_size_40, (vec4){1, 0, 0, 1}, 0,
cstr("Bebra budet\notnyahana"), (ivec2){10, 10});
Alice_mainloop(alice, &(AliceCallbacks){
.on_wl_keyboard_key = main_h_on_wayland_keyboard_key,
.on_another_frame = main_h_on_another_frame,