Binary level loading, separate passes for 2d and 3d

main
Cameron Murphy Reikes 12 months ago
parent 89eaad2433
commit 33e7176d19

BIN
art/art.blend (Stored with Git LFS)

Binary file not shown.

136
main.c

@ -876,7 +876,6 @@ SER_MAKE_FOR_TYPE(uint64_t);
SER_MAKE_FOR_TYPE(bool);
SER_MAKE_FOR_TYPE(double);
SER_MAKE_FOR_TYPE(float);
SER_MAKE_FOR_TYPE(MD_u64);
SER_MAKE_FOR_TYPE(ItemKind);
SER_MAKE_FOR_TYPE(PropKind);
SER_MAKE_FOR_TYPE(NpcKind);
@ -896,17 +895,28 @@ typedef struct
SER_MAKE_FOR_TYPE(Vertex);
typedef struct
typedef struct Mesh
{
struct Mesh *next;
Vertex *vertices;
MD_u64 num_vertices;
sg_buffer loaded_buffer;
MD_String8 name;
} Mesh;
typedef struct PlacedMesh
{
struct PlacedMesh *next;
Mesh *draw_with;
Vec3 offset;
} PlacedMesh;
// mesh_name is for debugging
// arena must last as long as the Mesh lasts. Internal data points to `arena`, such as
// the name of the mesh's buffer in sokol
// the name of the mesh's buffer in sokol. The returned mesh doesn't point to the binary
// file anymore.
Mesh load_mesh(MD_Arena *arena, MD_String8 binary_file, MD_String8 mesh_name)
{
MD_ArenaTemp scratch = MD_GetScratch(&arena, 1);
@ -941,6 +951,72 @@ Mesh load_mesh(MD_Arena *arena, MD_String8 binary_file, MD_String8 mesh_name)
return out;
}
typedef struct
{
Mesh *mesh_list;
PlacedMesh *placed_mesh_list;
} ThreeDeeLevel;
ThreeDeeLevel load_level(MD_Arena *arena, MD_String8 binary_file)
{
MD_ArenaTemp scratch = MD_GetScratch(&arena, 1);
SerState ser = {
.data = binary_file.str,
.max = binary_file.size,
.arena = arena,
.error_arena = scratch.arena,
.serializing = false,
};
ThreeDeeLevel out = {0};
MD_u64 num_placed = 0;
ser_MD_u64(&ser, &num_placed);
for(MD_u64 i = 0; i < num_placed; i++)
{
PlacedMesh *new_placed = MD_PushArray(arena, PlacedMesh, 1);
MD_String8 placed_mesh_name = {0};
ser_MD_String8(&ser, &placed_mesh_name, arena);
ser_Vec3(&ser, &new_placed->offset);
MD_StackPush(out.placed_mesh_list, new_placed);
// load the mesh if we haven't already
bool mesh_found = false;
for(Mesh *cur = out.mesh_list; cur; cur = cur->next)
{
if(MD_S8Match(cur->name, placed_mesh_name, 0))
{
mesh_found = true;
new_placed->draw_with = cur;
break;
}
}
if(!mesh_found)
{
MD_String8 to_load_filepath = MD_S8Fmt(scratch.arena, "assets/exported_3d/%.*s.bin", MD_S8VArg(placed_mesh_name));
Log("Loading '%.*s'...", MD_S8VArg(to_load_filepath));
MD_String8 binary_mesh_file = MD_LoadEntireFile(scratch.arena, to_load_filepath);
if(!binary_mesh_file.str)
{
ser.cur_error = (SerError){.failed = true, .why = MD_S8Fmt(ser.error_arena, "Couldn't load file '%.*s'", to_load_filepath)};
}
else
{
Mesh *new_mesh = MD_PushArray(arena, Mesh, 1);
*new_mesh = load_mesh(arena, binary_mesh_file, placed_mesh_name);
MD_StackPush(out.mesh_list, new_mesh);
new_placed->draw_with = new_mesh;
}
}
}
assert(!ser.cur_error.failed);
MD_ReleaseScratch(scratch);
return out;
}
#include "assets.gen.c"
#include "quad-sapp.glsl.h"
#include "threedee.glsl.h"
@ -2253,7 +2329,8 @@ stbtt_fontinfo font;
// @Place(sokol state struct)
static struct
{
sg_pass_action pass_action;
sg_pass_action clear_everything_pass_action;
sg_pass_action clear_depth_buffer_pass_action;
sg_pipeline pip;
sg_bindings bind;
@ -2437,6 +2514,7 @@ void do_serialization_tests()
#endif
Mesh mesh_player = {0};
ThreeDeeLevel level_threedee = {0};
void stbi_flip_into_correct_direction(bool do_it)
{
@ -2489,10 +2567,14 @@ void init(void)
load_assets();
MD_String8 binary_file = MD_LoadEntireFile(frame_arena, MD_S8Lit("assets/exported_3d/Signpost.bin"));
MD_String8 binary_file = MD_LoadEntireFile(frame_arena, MD_S8Lit("assets/exported_3d/Player.bin"));
mesh_player = load_mesh(persistent_arena, binary_file, MD_S8Lit("Player.bin"));
MD_ArenaClear(frame_arena);
binary_file = MD_LoadEntireFile(frame_arena, MD_S8Lit("assets/exported_3d/level.bin"));
level_threedee = load_level(persistent_arena, binary_file);
reset_level();
#ifdef WEB
@ -2631,15 +2713,13 @@ void init(void)
.label = "threedee",
});
state.pass_action = (sg_pass_action)
state.clear_depth_buffer_pass_action = (sg_pass_action)
{
//.colors[0] = { .action=SG_ACTION_CLEAR, .value={12.5f/255.0f, 12.5f/255.0f, 12.5f/255.0f, 1.0f } }
//.colors[0] = { .action=SG_ACTION_CLEAR, .value={255.5f/255.0f, 255.5f/255.0f, 255.5f/255.0f, 1.0f } }
// 0x898989 is the color in tiled
.colors[0] =
{ .action = SG_ACTION_CLEAR, .value = { clearcol.r, clearcol.g, clearcol.b, 1.0f } }
.colors[0] = { .action = SG_ACTION_LOAD },
.depth = { .action = SG_ACTION_CLEAR, .value = 1.0f },
};
state.clear_everything_pass_action = state.clear_depth_buffer_pass_action;
state.clear_everything_pass_action.colors[0] = (sg_color_attachment_action){ .action = SG_ACTION_CLEAR, .value = { clearcol.r, clearcol.g, clearcol.b, 1.0f } };
}
Vec2 screen_size()
@ -4216,14 +4296,10 @@ void frame(void)
movement = NormV2(movement);
}
sg_begin_default_pass(&state.pass_action, sapp_width(), sapp_height());
sg_begin_default_pass(&state.clear_everything_pass_action, sapp_width(), sapp_height());
sg_apply_pipeline(state.threedee_pip);
state.threedee_bind.vertex_buffers[0] = mesh_player.loaded_buffer;
state.threedee_bind.fs_images[SLOT_threedee_tex] = image_gigatexture;
sg_apply_bindings(&state.threedee_bind);
Mat4 model = M4D(1.0f);
Mat4 view = Translate(V3(0.0, 1.0, -5.0f));
//view = LookAt_RH(V3(0,1,-5
@ -4236,12 +4312,26 @@ void frame(void)
}
Mat4 projection = Perspective_RH_NO(PI32/4.0f, screen_size().x / screen_size().y, 0.001f, 1000.0f);
threedee_vs_params_t params = {0};
memcpy(params.model, (float*)&model, sizeof(model));
memcpy(params.view, (float*)&view, sizeof(view));
memcpy(params.projection, (float*)&projection, sizeof(projection));
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_threedee_vs_params, &SG_RANGE(params));
sg_draw(0, (int)mesh_player.num_vertices, 1);
for(PlacedMesh *cur = level_threedee.placed_mesh_list; cur; cur = cur->next)
{
Mesh *drawing = cur->draw_with;
state.threedee_bind.vertex_buffers[0] = drawing->loaded_buffer;
sg_apply_bindings(&state.threedee_bind);
Mat4 model = Translate(cur->offset);
threedee_vs_params_t params = {0};
memcpy(params.model, (float*)&model, sizeof(model));
memcpy(params.view, (float*)&view, sizeof(view));
memcpy(params.projection, (float*)&projection, sizeof(projection));
sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_threedee_vs_params, &SG_RANGE(params));
sg_draw(0, (int)drawing->num_vertices, 1);
}
sg_end_pass();
sg_begin_default_pass(&state.clear_depth_buffer_pass_action, sapp_width(), sapp_height());
sg_apply_pipeline(state.pip);

19
ser.h

@ -24,6 +24,7 @@ typedef struct
MD_b8 serializing;
} SerState;
void ser_bytes(SerState *ser, MD_u8 *bytes, MD_u64 bytes_size)
{
if(!ser->data && !ser->serializing)
@ -64,3 +65,21 @@ void ser_bytes(SerState *ser, MD_u8 *bytes, MD_u64 bytes_size)
}
SER_MAKE_FOR_TYPE(int);
SER_MAKE_FOR_TYPE(MD_u64);
// Embeds the string into the serialized binary. When deserializing copies the
// deserialized data onto a newly allocated buffer
void ser_MD_String8(SerState *ser, MD_String8 *s, MD_Arena *allocate_onto)
{
ser_MD_u64(ser, &s->size);
if(ser->serializing)
{
ser_bytes(ser, s->str, s->size);
}
else
{
s->str = MD_ArenaPush(allocate_onto, s->size);
ser_bytes(ser, s->str, s->size);
}
}

Loading…
Cancel
Save