.
This commit is contained in:
parent
1c13514a4d
commit
5d1fa53405
11 changed files with 396 additions and 121 deletions
BIN
data/scene2.glb
Normal file
BIN
data/scene2.glb
Normal file
Binary file not shown.
103
src/computer.c
Normal file
103
src/computer.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#include "game.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libs/cgltf.h"
|
||||
#include "utils.h"
|
||||
#include "gfx.h"
|
||||
|
||||
#define PC_SCREEN_WIDTH 200
|
||||
#define PC_SCREEN_HEIGHT 150
|
||||
|
||||
entity_t *computer_init(void) {
|
||||
entity_t *e = game_new_entity(ENTITY_COMPUTER);
|
||||
|
||||
e->offscreen.resolve = sg_make_image(&(sg_image_desc){
|
||||
.usage.resolve_attachment = true,
|
||||
.pixel_format = SG_PIXELFORMAT_RGBA8,
|
||||
.width = PC_SCREEN_WIDTH,
|
||||
.height = PC_SCREEN_HEIGHT,
|
||||
});
|
||||
|
||||
e->offscreen.colors = sg_make_image(&(sg_image_desc) {
|
||||
.usage.color_attachment = true,
|
||||
.pixel_format = SG_PIXELFORMAT_RGBA8,
|
||||
.width = PC_SCREEN_WIDTH,
|
||||
.height = PC_SCREEN_HEIGHT,
|
||||
.sample_count = 2,
|
||||
});
|
||||
|
||||
e->offscreen.attachments = (sg_attachments) {
|
||||
.colors[0] = sg_make_view(&(sg_view_desc){
|
||||
.color_attachment.image = e->offscreen.colors,
|
||||
}),
|
||||
.resolves[0] = sg_make_view(&(sg_view_desc){
|
||||
.resolve_attachment.image = e->offscreen.resolve,
|
||||
}),
|
||||
};
|
||||
|
||||
obj_t *screen = NULL;
|
||||
entity_t *scene = game_get_entity_of_type(ENTITY_SCENE);
|
||||
for (int i = 0; i < scene->model.object_count; ++i) {
|
||||
obj_t *obj = &scene->model.objects[i];
|
||||
if (strcmp(obj->name, "screen") == 0) {
|
||||
screen = obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (screen) {
|
||||
screen->bindings.views[0] = sg_make_view(&(sg_view_desc){
|
||||
.texture = e->offscreen.resolve
|
||||
});
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void computer__update(entity_t *e, float dt) {
|
||||
strview_t string = strv("hello world :)");
|
||||
static int pos = 0;
|
||||
static float timer = 0;
|
||||
static float frame = 0.5f;
|
||||
|
||||
timer += dt;
|
||||
while (timer >= frame) {
|
||||
timer -= frame;
|
||||
if (++pos > string.len) {
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// screen pass
|
||||
sg_begin_pass(&(sg_pass){
|
||||
.action = {
|
||||
.colors[0] = {
|
||||
.load_action = SG_LOADACTION_CLEAR,
|
||||
.store_action = SG_STOREACTION_DONTCARE,
|
||||
.clear_value = { 0, 0, 0, 1},
|
||||
},
|
||||
},
|
||||
.attachments = e->offscreen.attachments,
|
||||
});
|
||||
batcher.render_data.one_over_window_size = v2(
|
||||
1.f / PC_SCREEN_WIDTH,
|
||||
1.f / PC_SCREEN_HEIGHT
|
||||
);
|
||||
gfx_batcher_puts(&(gfx_print_desc_t){
|
||||
.str = strv_sub(string, 0, pos),
|
||||
.col = v4(1, 1, 1, 1),
|
||||
.pos = v2(1, 1),
|
||||
});
|
||||
gfx_batcher_present();
|
||||
sg_end_pass();
|
||||
}
|
||||
|
||||
void computer_frame(arena_t frame_arena, entity_t *players, float dt) {
|
||||
for_each (e, players) {
|
||||
computer__update(e, dt);
|
||||
}
|
||||
}
|
||||
|
||||
void computer_draw(arena_t frame_arena, entity_t *players) {
|
||||
}
|
||||
22
src/game.c
22
src/game.c
|
|
@ -6,6 +6,10 @@
|
|||
ENTITY_KIND(FRAME_X)
|
||||
#undef FRAME_X
|
||||
|
||||
#define DRAW_X(_, name) extern void name##_draw(arena_t scratch, entity_t *entities);
|
||||
ENTITY_KIND(DRAW_X)
|
||||
#undef DRAW_X
|
||||
|
||||
entity_update_fn game_frame_fn[ENTITY__COUNT] = {
|
||||
NULL,
|
||||
#define FN_X(_, name) name##_frame,
|
||||
|
|
@ -13,6 +17,13 @@ ENTITY_KIND(FN_X)
|
|||
#undef FN_X
|
||||
};
|
||||
|
||||
entity_draw_fn game_draw_fn[ENTITY__COUNT] = {
|
||||
NULL,
|
||||
#define FN_X(_, name) name##_draw,
|
||||
ENTITY_KIND(FN_X)
|
||||
#undef FN_X
|
||||
};
|
||||
|
||||
game_t game = {0};
|
||||
|
||||
void game_init() {
|
||||
|
|
@ -32,6 +43,13 @@ void game_frame(float dt) {
|
|||
#undef FRAME_X
|
||||
}
|
||||
|
||||
void game_draw(void) {
|
||||
#define DRAW_X(enumval, name) \
|
||||
name##_draw(game.frame_arena, game.active_by_type[ENTITY_##enumval]);
|
||||
ENTITY_KIND(DRAW_X);
|
||||
#undef DRAW_X
|
||||
}
|
||||
|
||||
entity_t *game_new_entity(entity_kind_e kind) {
|
||||
entity_t *e = game.freelist;
|
||||
list_pop(game.freelist);
|
||||
|
|
@ -47,6 +65,10 @@ entity_t *game_new_entity(entity_kind_e kind) {
|
|||
return e;
|
||||
}
|
||||
|
||||
entity_t *game_get_entity_of_type(entity_kind_e kind) {
|
||||
return game.active_by_type[kind];
|
||||
}
|
||||
|
||||
void game_entity_destroy(entity_t *e) {
|
||||
dlist_pop(game.active_by_type[e->kind], e);
|
||||
dlist_push(game.freelist, e);
|
||||
|
|
|
|||
18
src/game.h
18
src/game.h
|
|
@ -1,10 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "colla/colla.h"
|
||||
#include "libs/sokol_gfx.h"
|
||||
#include "libs/cgltf.h"
|
||||
#include "camera.h"
|
||||
#include "obj.h"
|
||||
|
||||
#define ENTITY_KIND(X) \
|
||||
X(PLAYER, player) \
|
||||
X(SCENE, scene) \
|
||||
X(COMPUTER, computer) \
|
||||
|
||||
typedef enum {
|
||||
ENTITY_NONE,
|
||||
|
|
@ -19,14 +24,23 @@ typedef enum {
|
|||
typedef struct entity_t entity_t;
|
||||
|
||||
typedef void (*entity_update_fn)(arena_t scratch, entity_t *entites, float dt);
|
||||
typedef void (*entity_draw_fn)(arena_t scratch, entity_t *entites);
|
||||
|
||||
struct entity_t {
|
||||
entity_kind_e kind;
|
||||
entity_t *next;
|
||||
entity_t *prev;
|
||||
|
||||
camera_t camera;
|
||||
vec3 position;
|
||||
|
||||
camera_t camera;
|
||||
scene_t model;
|
||||
|
||||
struct {
|
||||
sg_image colors;
|
||||
sg_image resolve;
|
||||
sg_attachments attachments;
|
||||
} offscreen;
|
||||
};
|
||||
|
||||
typedef struct game_t game_t;
|
||||
|
|
@ -42,6 +56,8 @@ void game_init(void);
|
|||
void game_cleanup(void);
|
||||
|
||||
void game_frame(float dt);
|
||||
void game_draw(void);
|
||||
|
||||
entity_t *game_new_entity(entity_kind_e kind);
|
||||
entity_t *game_get_entity_of_type(entity_kind_e kind);
|
||||
void game_entity_destroy(entity_t *e);
|
||||
|
|
|
|||
44
src/gfx.c
44
src/gfx.c
|
|
@ -8,35 +8,6 @@
|
|||
|
||||
// batcher stuff ////////////////////////////////////
|
||||
|
||||
typedef struct gfx_batch_render_data_t gfx_batch_render_data_t;
|
||||
struct gfx_batch_render_data_t {
|
||||
vec2 one_over_window_size;
|
||||
// float2 one_over_texture_size;
|
||||
float zoom;
|
||||
float padding;
|
||||
};
|
||||
|
||||
struct gfx_batcher_t {
|
||||
sg_buffer render_buffer;
|
||||
sg_buffer instance_buffer;
|
||||
sg_pipeline pipeline;
|
||||
sg_image empty_texture;
|
||||
sg_sampler sampler;
|
||||
|
||||
sg_image texture;
|
||||
|
||||
gfx_batch_render_data_t render_data;
|
||||
gfx_batch_t *batch_data;
|
||||
uint instance_count;
|
||||
uint max_instances;
|
||||
|
||||
float zoom;
|
||||
|
||||
sg_image font;
|
||||
int font_width;
|
||||
int font_height;
|
||||
};
|
||||
|
||||
gfx_batcher_t batcher = {0};
|
||||
|
||||
bool gfx_init_batcher(arena_t *arena, uint max_instances) {
|
||||
|
|
@ -62,7 +33,7 @@ bool gfx_init_batcher(arena_t *arena, uint max_instances) {
|
|||
.label = "batcher",
|
||||
});
|
||||
|
||||
sg_update_buffer(batcher.render_buffer, SG_RANGE_REF(batcher.render_data));
|
||||
// sg_update_buffer(batcher.render_buffer, SG_RANGE_REF(batcher.render_data));
|
||||
|
||||
batcher.instance_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.usage = {
|
||||
|
|
@ -83,6 +54,12 @@ bool gfx_init_batcher(arena_t *arena, uint max_instances) {
|
|||
[ATTR_batcher_colour].format = SG_VERTEXFORMAT_FLOAT4,
|
||||
},
|
||||
},
|
||||
.sample_count = 2,
|
||||
.colors[0].pixel_format = SG_PIXELFORMAT_RGBA8,
|
||||
.depth = {
|
||||
.pixel_format = SG_PIXELFORMAT_NONE,
|
||||
.write_enabled = false,
|
||||
},
|
||||
});
|
||||
|
||||
u32 empty_image[] = {
|
||||
|
|
@ -221,13 +198,6 @@ void gfx_batcher_push_arr(gfx_batch_t *arr, uint count) {
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct gfx_print_desc_t gfx_print_desc_t;
|
||||
struct gfx_print_desc_t {
|
||||
strview_t str;
|
||||
vec2 pos;
|
||||
vec4 col;
|
||||
};
|
||||
|
||||
void gfx_batcher_puts(gfx_print_desc_t *desc) {
|
||||
float atlas_1ow = 1.f / (float)batcher.font_width;
|
||||
float atlas_1oh = 1.f / (float)batcher.font_height;
|
||||
|
|
|
|||
38
src/gfx.h
38
src/gfx.h
|
|
@ -20,7 +20,43 @@ struct gfx_batch_t {
|
|||
vec4 colour;
|
||||
};
|
||||
|
||||
typedef struct gfx_batch_render_data_t gfx_batch_render_data_t;
|
||||
struct gfx_batch_render_data_t {
|
||||
vec2 one_over_window_size;
|
||||
// float2 one_over_texture_size;
|
||||
float zoom;
|
||||
float padding;
|
||||
};
|
||||
|
||||
typedef struct gfx_batcher_t gfx_batcher_t;
|
||||
struct gfx_batcher_t {
|
||||
sg_buffer render_buffer;
|
||||
sg_buffer instance_buffer;
|
||||
sg_pipeline pipeline;
|
||||
sg_image empty_texture;
|
||||
sg_sampler sampler;
|
||||
|
||||
sg_image texture;
|
||||
|
||||
gfx_batch_render_data_t render_data;
|
||||
gfx_batch_t *batch_data;
|
||||
uint instance_count;
|
||||
uint max_instances;
|
||||
|
||||
float zoom;
|
||||
|
||||
sg_image font;
|
||||
int font_width;
|
||||
int font_height;
|
||||
};
|
||||
|
||||
typedef struct gfx_print_desc_t gfx_print_desc_t;
|
||||
struct gfx_print_desc_t {
|
||||
strview_t str;
|
||||
vec2 pos;
|
||||
vec4 col;
|
||||
};
|
||||
|
||||
extern gfx_batcher_t batcher;
|
||||
|
||||
bool gfx_init_batcher(arena_t *arena, uint max_instances);
|
||||
|
|
@ -34,4 +70,6 @@ void gfx_batcher_set_texture(sg_image texture);
|
|||
void gfx_batcher_push(gfx_batch_t *data);
|
||||
void gfx_batcher_push_arr(gfx_batch_t *arr, uint count);
|
||||
|
||||
void gfx_batcher_puts(gfx_print_desc_t *desc);
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
139
src/main.c
139
src/main.c
|
|
@ -8,6 +8,9 @@
|
|||
#error "unsupported os"
|
||||
#endif
|
||||
|
||||
#define SCREEN_WIDTH 200
|
||||
#define SCREEN_HEIGHT 150
|
||||
|
||||
#include "libs/sokol_app.h"
|
||||
#include "libs/sokol_gfx.h"
|
||||
#include "libs/sokol_time.h"
|
||||
|
|
@ -22,6 +25,8 @@
|
|||
#include "camera.c"
|
||||
#include "game.c"
|
||||
#include "player.c"
|
||||
#include "scene.c"
|
||||
#include "computer.c"
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
|
|
@ -33,7 +38,12 @@ scene_t scene = {0};
|
|||
u64 time_last = 0;
|
||||
// gfx_batcher_t *batch = NULL;
|
||||
|
||||
obj_vs_params_t vs_params = {0};
|
||||
struct {
|
||||
sg_image colors;
|
||||
sg_image resolve;
|
||||
sg_pass_action pass_action;
|
||||
sg_attachments attachments;
|
||||
} screen = {0};
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
|
|
@ -62,6 +72,23 @@ void sokol_log_cb(
|
|||
);
|
||||
}
|
||||
|
||||
bool scene_material_cb(arena_t scratch, cgltf_material *mat, sg_image *out, void *ud) {
|
||||
if (strcmp(mat->name, "screen") != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
screen.resolve = sg_make_image(&(sg_image_desc){
|
||||
.pixel_format = SG_PIXELFORMAT_RGBA8,
|
||||
.width = SCREEN_WIDTH,
|
||||
.height = SCREEN_HEIGHT,
|
||||
.usage.resolve_attachment = true,
|
||||
});
|
||||
|
||||
*out = screen.resolve;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void app_init(void) {
|
||||
sg_setup(&(sg_desc){
|
||||
.environment = sglue_environment(),
|
||||
|
|
@ -77,30 +104,18 @@ void app_init(void) {
|
|||
gfx_init_batcher(&game.arena, 128);
|
||||
|
||||
player_init();
|
||||
scene_init();
|
||||
computer_init();
|
||||
|
||||
arena_t scratch = game.arena;
|
||||
|
||||
scene = obj_load_gltf(scratch, strv("data/scene.glb"));
|
||||
|
||||
sg_shader shd = sg_make_shader(obj_shader_desc(sg_query_backend()));
|
||||
|
||||
pip = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = shd,
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
// .cull_mode = SG_CULLMODE_BACK,
|
||||
.depth = {
|
||||
.compare = SG_COMPAREFUNC_LESS_EQUAL,
|
||||
.write_enabled = true,
|
||||
#if 0
|
||||
screen.pass_action = (sg_pass_action){
|
||||
.colors[0] = {
|
||||
.load_action = SG_LOADACTION_CLEAR,
|
||||
.store_action = SG_STOREACTION_DONTCARE,
|
||||
.clear_value = { 0, 0, 0, 1},
|
||||
},
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[3].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
#endif
|
||||
|
||||
pass_action = (sg_pass_action){
|
||||
.colors[0] = {
|
||||
|
|
@ -118,50 +133,59 @@ void app_frame(void) {
|
|||
u64 dt_ticks = stm_laptime(&time_last);
|
||||
float dt = (float)stm_sec(dt_ticks);
|
||||
|
||||
utils_update();
|
||||
game_frame(dt);
|
||||
|
||||
entity_t *player = &game.active_by_type[ENTITY_PLAYER][0];
|
||||
camera_t *cam = &player->camera;
|
||||
|
||||
float aspect_ratio = sapp_widthf() / sapp_heightf();
|
||||
|
||||
mat4 view = cam_view(cam);
|
||||
mat4 proj = cam_proj(cam);
|
||||
mat4 model = HMM_Translate(v3(0, 0, -10));
|
||||
|
||||
vs_params.mvp = hmm_mul(proj, view);
|
||||
vs_params.cam_pos = cam->pos;
|
||||
|
||||
sg_begin_pass(&(sg_pass){ .action = pass_action, .swapchain = sglue_swapchain() });
|
||||
{
|
||||
sg_apply_pipeline(pip);
|
||||
sg_apply_uniforms(0, SG_RANGE_REF(vs_params));
|
||||
for (int i = 0; i < scene.object_count; ++i) {
|
||||
sg_apply_bindings(&scene.objects[i].bindings);
|
||||
sg_draw(0, scene.objects[i].draw_count, 1);
|
||||
}
|
||||
if (is_key_pressed(SAPP_KEYCODE_TAB)) {
|
||||
sapp_lock_mouse(!sapp_mouse_locked());
|
||||
}
|
||||
|
||||
// main pass
|
||||
sg_begin_pass(&(sg_pass){ .action = pass_action, .swapchain = sglue_swapchain() });
|
||||
game_draw();
|
||||
|
||||
{
|
||||
// SHIT ASS CODE PLEASE DON'T LOOK
|
||||
static float dt_avg = 0.f;
|
||||
static u32 dt_count = 0;
|
||||
static float ms_avg[100] = {0};
|
||||
static u32 ms_count = 0;
|
||||
static int ms_tail = 0;
|
||||
|
||||
dt_avg += dt;
|
||||
dt_count++;
|
||||
float ms = stm_ms(dt_ticks);
|
||||
ms_avg[ms_tail++] = ms;
|
||||
if (ms_tail >= arrlen(ms_avg)) {
|
||||
ms_tail = 0;
|
||||
}
|
||||
|
||||
float delta_avg = dt_avg / (float)dt_count;
|
||||
int cur = ms_tail;
|
||||
for (int i = 0; i < ms_count; ++i) {
|
||||
ms += ms_avg[cur++];
|
||||
if (cur >= arrlen(ms_avg)) {
|
||||
cur = 0;
|
||||
}
|
||||
}
|
||||
|
||||
str_t fps = str_fmt(&game.frame_arena, "dt: %.5f // fps: %.2f", delta_avg, 1.f / delta_avg);
|
||||
gfx_batcher_puts(&(gfx_print_desc_t){
|
||||
.str = strv(fps),
|
||||
.col = v4(0.93, 0.6, 0.26, 1),
|
||||
});
|
||||
gfx_batcher_present();
|
||||
ms_count++;
|
||||
if (ms_count > arrlen(ms_avg)) {
|
||||
ms_count = arrlen(ms_avg);
|
||||
}
|
||||
|
||||
ms /= ms_count;
|
||||
|
||||
// batcher.zoom = 2.f;
|
||||
|
||||
// str_t fps = str_fmt(
|
||||
// &game.frame_arena,
|
||||
// "ms: %.2f // fps: %.2f",
|
||||
// ms, 1000.f / ms
|
||||
// );
|
||||
// gfx_batcher_puts(&(gfx_print_desc_t){
|
||||
// .str = strv(fps),
|
||||
// .col = v4(0.93, 0.6, 0.26, 1),
|
||||
// });
|
||||
// gfx_batcher_present();
|
||||
}
|
||||
sg_end_pass();
|
||||
sg_commit();
|
||||
|
||||
utils_update();
|
||||
}
|
||||
|
||||
void app_event(const sapp_event *e) {
|
||||
|
|
@ -204,6 +228,9 @@ sapp_desc sokol_main(int argc, char* argv[]) {
|
|||
};
|
||||
}
|
||||
|
||||
#define CGLTF_IMPLEMENTATION
|
||||
#include "libs/cgltf.h"
|
||||
|
||||
#define SOKOL_IMPL
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
|
||||
|
|
|
|||
48
src/obj.c
48
src/obj.c
|
|
@ -1,26 +1,13 @@
|
|||
#include "obj.h"
|
||||
|
||||
#include "colla/colla.h"
|
||||
#include "libs/sokol_gfx.h"
|
||||
#include "libs/stb_image.h"
|
||||
|
||||
#define CGLTF_IMPLEMENTATION
|
||||
#include "libs/cgltf.h"
|
||||
|
||||
#include "libs/handmademath.h"
|
||||
|
||||
typedef struct vertex_t vertex_t;
|
||||
struct vertex_t {
|
||||
vec3 pos;
|
||||
vec3 norm;
|
||||
vec2 tex;
|
||||
vec2 lightmap;
|
||||
};
|
||||
|
||||
typedef struct obj_t obj_t;
|
||||
struct obj_t {
|
||||
sg_bindings bindings;
|
||||
u16 draw_count;
|
||||
};
|
||||
|
||||
cgltf_result obj__cgltf_file_read_cb(
|
||||
const cgltf_memory_options *m,
|
||||
const cgltf_file_options *opt,
|
||||
|
|
@ -51,14 +38,6 @@ void obj__cgltf_file_release_callback(
|
|||
// no-op
|
||||
}
|
||||
|
||||
#define MAX_SCENE_OBJECTS 64
|
||||
|
||||
typedef struct scene_t scene_t;
|
||||
struct scene_t {
|
||||
obj_t objects[MAX_SCENE_OBJECTS];
|
||||
int object_count;
|
||||
};
|
||||
|
||||
#define CACHE_SIZE (64)
|
||||
#define MAX_CACHE_NAME_LEN (64)
|
||||
|
||||
|
|
@ -130,8 +109,12 @@ sg_image obj__load_texture(arena_t scratch, cgltf_texture *texture) {
|
|||
return out;
|
||||
}
|
||||
|
||||
scene_t obj_load_gltf(arena_t scratch, strview_t filename) {
|
||||
scene_t obj_load_gltf(arena_t scratch, strview_t filename, obj_desc_t *desc) {
|
||||
scene_t scene = {0};
|
||||
obj_desc_t default_settings = {0};
|
||||
if (!desc) {
|
||||
desc = &default_settings;
|
||||
}
|
||||
|
||||
str_t fname = str(&scratch, filename);
|
||||
buffer_t buf = os_file_read_all(&scratch, filename);
|
||||
|
|
@ -208,10 +191,21 @@ scene_t obj_load_gltf(arena_t scratch, strview_t filename) {
|
|||
}
|
||||
|
||||
cgltf_material *mat = prim->material;
|
||||
sg_image image = {0};
|
||||
|
||||
strview_t material_name = strv(mat->name);
|
||||
usize to_copy = MIN(material_name.len, arrlen(obj->name) - 1);
|
||||
memmove(obj->name, material_name.buf, to_copy);
|
||||
|
||||
if (!
|
||||
(desc->material_cb &&
|
||||
desc->material_cb(scratch, mat, &image, desc->userdata))
|
||||
) {
|
||||
// diffuse texture
|
||||
cgltf_texture_view texture_view = mat->pbr_metallic_roughness.base_color_texture;
|
||||
image = obj__load_texture(scratch, texture_view.texture);
|
||||
}
|
||||
|
||||
// diffuse texture
|
||||
cgltf_texture_view texture_view = mat->pbr_metallic_roughness.base_color_texture;
|
||||
sg_image image = obj__load_texture(scratch, texture_view.texture);
|
||||
if (image.id == 0) {
|
||||
image = missing_img;
|
||||
}
|
||||
|
|
|
|||
39
src/obj.h
Normal file
39
src/obj.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include "libs/sokol_gfx.h"
|
||||
#include "libs/handmademath.h"
|
||||
#include "libs/cgltf.h"
|
||||
#include "colla/colla.h"
|
||||
|
||||
|
||||
#define MAX_SCENE_OBJECTS 64
|
||||
|
||||
typedef struct vertex_t vertex_t;
|
||||
struct vertex_t {
|
||||
vec3 pos;
|
||||
vec3 norm;
|
||||
vec2 tex;
|
||||
vec2 lightmap;
|
||||
};
|
||||
|
||||
typedef struct obj_t obj_t;
|
||||
struct obj_t {
|
||||
char name[16];
|
||||
sg_bindings bindings;
|
||||
u16 draw_count;
|
||||
};
|
||||
|
||||
typedef struct scene_t scene_t;
|
||||
struct scene_t {
|
||||
obj_t objects[MAX_SCENE_OBJECTS];
|
||||
int object_count;
|
||||
};
|
||||
|
||||
typedef bool (*obj_material_cb)(arena_t scratch, cgltf_material *material, sg_image *out, void *userdata);
|
||||
typedef struct obj_desc_t obj_desc_t;
|
||||
struct obj_desc_t {
|
||||
obj_material_cb material_cb;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
scene_t obj_load_gltf(arena_t scratch, strview_t filename, obj_desc_t *desc);
|
||||
|
|
@ -22,3 +22,6 @@ void player_frame(arena_t frame_arena, entity_t *players, float dt) {
|
|||
player__update(e, dt);
|
||||
}
|
||||
}
|
||||
|
||||
void player_draw(arena_t frame_arena, entity_t *players) {
|
||||
}
|
||||
|
|
|
|||
63
src/scene.c
Normal file
63
src/scene.c
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#include "game.h"
|
||||
|
||||
#include "gen/obj.h"
|
||||
|
||||
sg_pipeline scene_pipeline = {0};
|
||||
obj_vs_params_t scene_vs_params = {0};
|
||||
|
||||
entity_t *scene_init(void) {
|
||||
entity_t *e = game_new_entity(ENTITY_SCENE);
|
||||
|
||||
e->model = obj_load_gltf(game.frame_arena, strv("data/scene2.glb"), NULL);
|
||||
e->position = v3(-10, 0, 0);
|
||||
|
||||
if (sg_query_pipeline_state(scene_pipeline) != SG_RESOURCESTATE_VALID) {
|
||||
sg_shader shd = sg_make_shader(obj_shader_desc(sg_query_backend()));
|
||||
|
||||
scene_pipeline = sg_make_pipeline(&(sg_pipeline_desc){
|
||||
.shader = shd,
|
||||
.index_type = SG_INDEXTYPE_UINT16,
|
||||
.cull_mode = SG_CULLMODE_FRONT,
|
||||
.depth = {
|
||||
.compare = SG_COMPAREFUNC_LESS_EQUAL,
|
||||
.write_enabled = true,
|
||||
},
|
||||
.layout = {
|
||||
.attrs = {
|
||||
[0].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[1].format = SG_VERTEXFORMAT_FLOAT3,
|
||||
[2].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
[3].format = SG_VERTEXFORMAT_FLOAT2,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void scene_frame(arena_t frame_arena, entity_t *scenes, float dt) {
|
||||
entity_t *player = game_get_entity_of_type(ENTITY_PLAYER);
|
||||
camera_t *cam = &player->camera;
|
||||
mat4 view = cam_view(cam);
|
||||
mat4 proj = cam_proj(cam);
|
||||
|
||||
// for_each (s, scenes) {
|
||||
mat4 model = HMM_Translate(v3(-5, 0, 0));
|
||||
// }
|
||||
|
||||
scene_vs_params.mvp = hmm_mul(proj, hmm_mul(view, model));
|
||||
scene_vs_params.cam_pos = cam->pos;
|
||||
}
|
||||
|
||||
void scene_draw(arena_t frame_arena, entity_t *players) {
|
||||
sg_apply_pipeline(scene_pipeline);
|
||||
sg_apply_uniforms(UB_obj_vs_params, SG_RANGE_REF(scene_vs_params));
|
||||
|
||||
for_each (e, players) {
|
||||
for (int i = 0; i < e->model.object_count; ++i) {
|
||||
sg_apply_bindings(&e->model.objects[i].bindings);
|
||||
sg_draw(0, e->model.objects[i].draw_count, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue