From 6c581ff56dfcc22c25538e305e58efd967dd640a Mon Sep 17 00:00:00 2001 From: omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Thu, 14 Mar 2024 21:54:55 +1100 Subject: lights, camera, action --- src/renderer/render.c | 48 ++++++++++++++++++++++++++++++++++++++++----- src/renderer/render.h | 2 +- src/renderer/render_types.h | 34 ++++++++++++++++++++++++++++++-- src/resources/obj.c | 23 ++++++++++++++-------- 4 files changed, 91 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/renderer/render.c b/src/renderer/render.c index dc541d2..1c979e5 100644 --- a/src/renderer/render.c +++ b/src/renderer/render.c @@ -80,7 +80,7 @@ void default_material_init() { texture_data_upload(&DEFAULT_MATERIAL.specular_texture); } -void draw_model(renderer* ren, camera* camera, model* model, transform tf) { +void draw_model(renderer* ren, camera* camera, model* model, transform tf, scene* scene) { // TRACE("Drawing model: %s", model->name); mat4 view; mat4 proj; @@ -88,13 +88,22 @@ void draw_model(renderer* ren, camera* camera, model* model, transform tf) { set_shader(ren->blinn_phong); + // set camera uniform + uniform_vec3f(ren->blinn_phong.program_id, "viewPos", &camera->position); + // set light uniforms + dir_light_upload_uniforms(ren->blinn_phong, &scene->dir_light); + for (int i = 0; i < scene->n_point_lights; i ++) { + point_light_upload_uniforms(ren->blinn_phong, &scene->point_lights[i], '0' + i); + } + for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) { mesh* m = &model->meshes->data[i]; if (vertex_darray_len(m->vertices) == 0) { continue; } // TRACE("Drawing mesh %d", i); - draw_mesh(ren, m, tf, &(DEFAULT_MATERIAL), &view, &proj); + material* mat = &model->materials->data[m->material_index]; + draw_mesh(ren, m, tf, mat, &view, &proj); } } @@ -127,8 +136,6 @@ void draw_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, mat4* vie void model_upload_meshes(renderer* ren, model* model) { INFO("Upload mesh vertex data to GPU for model %s", model->name); - // DEBUG("Loading model with handle %d", model_handle.raw); - // model m = models->data[model_handle.raw]; size_t num_meshes = mesh_darray_len(model->meshes); u32 VBOs[num_meshes]; @@ -148,7 +155,7 @@ void model_upload_meshes(renderer* ren, model* model) { glBindBuffer(GL_ARRAY_BUFFER, VBOs[mesh_i]); size_t num_vertices = vertex_darray_len(model->meshes->data[mesh_i].vertices); - TRACE("Uploading vertex array data: %d verts", num_vertices); + // TRACE("Uploading vertex array data: %d verts", num_vertices); total_verts += num_vertices; // TODO: convert this garbage into a function @@ -256,3 +263,34 @@ void texture_data_upload(texture* tex) { DEBUG("Freeing texture image data after uploading to GPU"); // stbi_image_free(tex->image_data); // data is on gpu now so we dont need it around } + +void dir_light_upload_uniforms(shader shader, directional_light *light) { + uniform_vec3f(shader.program_id, "dirLight.direction", &light->direction); + uniform_vec3f(shader.program_id, "dirLight.ambient", &light->ambient); + uniform_vec3f(shader.program_id, "dirLight.diffuse", &light->diffuse); + uniform_vec3f(shader.program_id, "dirLight.specular", &light->specular); +} + +void point_light_upload_uniforms(shader shader, point_light *light, char index) { + char position_str[] = "pointLights[x].position"; + position_str[12] = (char)index; + char ambient_str[] = "pointLights[x].ambient"; + ambient_str[12] = (char)index; + char diffuse_str[] = "pointLights[x].diffuse"; + diffuse_str[12] = (char)index; + char specular_str[] = "pointLights[x].specular"; + specular_str[12] = (char)index; + char constant_str[] = "pointLights[x].constant"; + constant_str[12] = (char)index; + char linear_str[] = "pointLights[x].linear"; + linear_str[12] = (char)index; + char quadratic_str[] = "pointLights[x].quadratic"; + quadratic_str[12] = (char)index; + uniform_vec3f(shader.program_id, position_str, &light->position); + uniform_vec3f(shader.program_id, ambient_str, &light->ambient); + uniform_vec3f(shader.program_id, diffuse_str, &light->diffuse); + uniform_vec3f(shader.program_id, specular_str, &light->specular); + uniform_f32(shader.program_id, constant_str, light->constant); + uniform_f32(shader.program_id, linear_str, light->linear); + uniform_f32(shader.program_id, quadratic_str, light->quadratic); +} \ No newline at end of file diff --git a/src/renderer/render.h b/src/renderer/render.h index 35c2d91..10702e3 100644 --- a/src/renderer/render.h +++ b/src/renderer/render.h @@ -17,7 +17,7 @@ void render_frame_end(renderer* ren); // --- models meshes void model_upload_meshes(renderer* ren, model* model); -void draw_model(renderer* ren, camera* camera, model* model, transform tf); +void draw_model(renderer* ren, camera* camera, model* model, transform tf, scene* scene); void draw_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, mat4* view, mat4* proj); // --- diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h index 746dfce..483e392 100644 --- a/src/renderer/render_types.h +++ b/src/renderer/render_types.h @@ -78,6 +78,27 @@ KITC_DECL_TYPED_ARRAY(material) // creates "material_darray" #define TYPED_MATERIAL_ARRAY #endif +// lights +typedef struct point_light { + vec3 position; + f32 constant, linear, quadratic; + vec3 ambient; + vec3 diffuse; + vec3 specular; +} point_light; + +typedef struct directional_light { + vec3 direction; + vec3 ambient; + vec3 diffuse; + vec3 specular; +} directional_light; + +void point_light_upload_uniforms(shader shader, point_light *light, char index); +void dir_light_upload_uniforms(shader shader, directional_light *light); + +// --- Models & Meshes + /** @brief Vertex format for a static mesh */ typedef struct vertex { vec3 position; @@ -90,8 +111,6 @@ KITC_DECL_TYPED_ARRAY(vertex) // creates "vertex_darray" #define TYPED_VERTEX_ARRAY #endif -// --- Models & Meshes - typedef struct mesh { vertex_darray *vertices; u32 vertex_size; /** size in bytes of each vertex including necessary padding */ @@ -121,6 +140,17 @@ KITC_DECL_TYPED_ARRAY(model) // creates "model_darray" #define TYPED_MODEL_ARRAY #endif +// --- Scene + +// NOTE: This struct won't stay like this for a long time. It's somewhat temporary +// in order to get a basic scene working without putting burden on the caller of +// draw_model() +typedef struct scene { + directional_light dir_light; + point_light point_lights[4]; + size_t n_point_lights; +} scene; + // --- Graphics API related typedef enum cel_primitive_topology { diff --git a/src/resources/obj.c b/src/resources/obj.c index 658967e..221e3aa 100644 --- a/src/resources/obj.c +++ b/src/resources/obj.c @@ -35,7 +35,7 @@ KITC_DECL_TYPED_ARRAY(face) void create_submesh(mesh_darray *meshes, vec3_darray *tmp_positions, vec3_darray *tmp_normals, vec2_darray *tmp_uvs, face_darray *tmp_faces, material_darray *materials, bool material_loaded, char current_material_name[256]); -bool load_material_lib(const char *path, material_darray *materials); +bool load_material_lib(const char *path, str8 relative_path, material_darray *materials); bool model_load_obj_str(const char *file_string, str8 relative_path, model *out_model, bool invert_textures_y); @@ -182,7 +182,7 @@ bool model_load_obj_str(const char *file_string, str8 relative_path, model *out_ sscanf(pch + offset, "%s", filename); char mtllib_path[1024]; snprintf(mtllib_path, sizeof(mtllib_path), "%s/%s", relative_path.buf, filename); - if (!load_material_lib(mtllib_path, out_model->materials)) { + if (!load_material_lib(mtllib_path, relative_path, out_model->materials)) { ERROR("couldnt load material lib"); return false; } @@ -262,7 +262,6 @@ void create_submesh(mesh_darray *meshes, vec3_darray *tmp_positions, vec3_darray material_darray_iter mat_iter = material_darray_iter_new(materials); blinn_phong_material *cur_material; while ((cur_material = material_darray_iter_next(&mat_iter))) { - printf("Material name %s vs %s \n", cur_material->name, current_material_name); if (strcmp(cur_material->name, current_material_name) == 0) { DEBUG("Found match"); m.material_index = mat_iter.current_idx - 1; @@ -280,7 +279,7 @@ void create_submesh(mesh_darray *meshes, vec3_darray *tmp_positions, vec3_darray mesh_darray_push(meshes, m); } -bool load_material_lib(const char *path, material_darray *materials) { +bool load_material_lib(const char *path,str8 relative_path, material_darray *materials) { TRACE("BEGIN load material lib at %s", path); const char *file_string = string_from_file(path); @@ -338,9 +337,12 @@ bool load_material_lib(const char *path, material_darray *materials) { // specular exponent sscanf(pch + offset, "%f", ¤t_material.spec_exponent); } else if (strcmp(line_header, "map_Kd") == 0) { - char diffuse_map_path[1024] = "assets/"; - sscanf(pch + offset, "%s", diffuse_map_path + 7); + char diffuse_map_filename[1024]; + sscanf(pch + offset, "%s", diffuse_map_filename); + char diffuse_map_path[1024]; + snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf, diffuse_map_filename); printf("load from %s\n", diffuse_map_path); + // -------------- texture diffuse_texture = texture_data_load(diffuse_map_path, true); current_material.diffuse_texture = diffuse_texture; @@ -348,8 +350,13 @@ bool load_material_lib(const char *path, material_darray *materials) { texture_data_upload(¤t_material.diffuse_texture); // -------------- } else if (strcmp(line_header, "map_Ks") == 0) { - char specular_map_path[1024] = "assets/"; - sscanf(pch + offset, "%s", specular_map_path + 7); + // char specular_map_path[1024] = "assets/"; + // sscanf(pch + offset, "%s", specular_map_path + 7); + char specular_map_filename[1024]; + sscanf(pch + offset, "%s", specular_map_filename); + char specular_map_path[1024]; + snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf, specular_map_filename); + printf("load from %s\n", specular_map_path); // -------------- texture specular_texture = texture_data_load(specular_map_path, true); current_material.specular_texture = specular_texture; -- cgit v1.2.3-70-g09d2 From b240374c23365e33727d78ca74e901bcb383e077 Mon Sep 17 00:00:00 2001 From: omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Thu, 14 Mar 2024 21:55:25 +1100 Subject: chore: format --- examples/obj_loading/ex_obj_loading.c | 28 ++++++++++++---------------- src/renderer/render.c | 6 +++--- src/resources/obj.c | 8 +++++--- 3 files changed, 20 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/examples/obj_loading/ex_obj_loading.c b/examples/obj_loading/ex_obj_loading.c index 02ed606..6f1f12a 100644 --- a/examples/obj_loading/ex_obj_loading.c +++ b/examples/obj_loading/ex_obj_loading.c @@ -9,10 +9,10 @@ #include "render_types.h" const vec3 pointlight_positions[4] = { - {0.7, 0.2, 2.0}, - {2.3, -3.3, -4.0}, - {-4.0, 2.0, -12.0}, - {0.0, 0.0, -3.0}, + { 0.7, 0.2, 2.0 }, + { 2.3, -3.3, -4.0 }, + { -4.0, 2.0, -12.0 }, + { 0.0, 0.0, -3.0 }, }; point_light point_lights[4]; @@ -34,28 +34,24 @@ int main() { // 4. create lights // directional (sun) light setup - directional_light dir_light = {.direction = (vec3){-0.2, -1.0, -0.3}, - .ambient = (vec3){0.2, 0.2, 0.2}, - .diffuse = (vec3){0.5, 0.5, 0.5}, - .specular = (vec3){1.0, 1.0, 1.0}}; + directional_light dir_light = { .direction = (vec3){ -0.2, -1.0, -0.3 }, + .ambient = (vec3){ 0.2, 0.2, 0.2 }, + .diffuse = (vec3){ 0.5, 0.5, 0.5 }, + .specular = (vec3){ 1.0, 1.0, 1.0 } }; // point lights setup for (int i = 0; i < 4; i++) { point_lights[i].position = pointlight_positions[i]; - point_lights[i].ambient = (vec3){0.05, 0.05, 0.05}; - point_lights[i].diffuse = (vec3){0.8, 0.8, 0.8}; - point_lights[i].specular = (vec3){1.0, 1.0, 1.0}; + point_lights[i].ambient = (vec3){ 0.05, 0.05, 0.05 }; + point_lights[i].diffuse = (vec3){ 0.8, 0.8, 0.8 }; + point_lights[i].specular = (vec3){ 1.0, 1.0, 1.0 }; point_lights[i].constant = 1.0; point_lights[i].linear = 0.09; point_lights[i].quadratic = 0.032; } - scene our_scene = { - .dir_light = dir_light, - .n_point_lights = 4 - }; + scene our_scene = { .dir_light = dir_light, .n_point_lights = 4 }; memcpy(&our_scene.point_lights, &point_lights, sizeof(point_light[4])); - // --- Enter Main loop while (!glfwWindowShouldClose(core->renderer.window)) { input_update(&core->input); diff --git a/src/renderer/render.c b/src/renderer/render.c index 1c979e5..7884db6 100644 --- a/src/renderer/render.c +++ b/src/renderer/render.c @@ -92,7 +92,7 @@ void draw_model(renderer* ren, camera* camera, model* model, transform tf, scene uniform_vec3f(ren->blinn_phong.program_id, "viewPos", &camera->position); // set light uniforms dir_light_upload_uniforms(ren->blinn_phong, &scene->dir_light); - for (int i = 0; i < scene->n_point_lights; i ++) { + for (int i = 0; i < scene->n_point_lights; i++) { point_light_upload_uniforms(ren->blinn_phong, &scene->point_lights[i], '0' + i); } @@ -264,14 +264,14 @@ void texture_data_upload(texture* tex) { // stbi_image_free(tex->image_data); // data is on gpu now so we dont need it around } -void dir_light_upload_uniforms(shader shader, directional_light *light) { +void dir_light_upload_uniforms(shader shader, directional_light* light) { uniform_vec3f(shader.program_id, "dirLight.direction", &light->direction); uniform_vec3f(shader.program_id, "dirLight.ambient", &light->ambient); uniform_vec3f(shader.program_id, "dirLight.diffuse", &light->diffuse); uniform_vec3f(shader.program_id, "dirLight.specular", &light->specular); } -void point_light_upload_uniforms(shader shader, point_light *light, char index) { +void point_light_upload_uniforms(shader shader, point_light* light, char index) { char position_str[] = "pointLights[x].position"; position_str[12] = (char)index; char ambient_str[] = "pointLights[x].ambient"; diff --git a/src/resources/obj.c b/src/resources/obj.c index 221e3aa..710d5f0 100644 --- a/src/resources/obj.c +++ b/src/resources/obj.c @@ -279,7 +279,7 @@ void create_submesh(mesh_darray *meshes, vec3_darray *tmp_positions, vec3_darray mesh_darray_push(meshes, m); } -bool load_material_lib(const char *path,str8 relative_path, material_darray *materials) { +bool load_material_lib(const char *path, str8 relative_path, material_darray *materials) { TRACE("BEGIN load material lib at %s", path); const char *file_string = string_from_file(path); @@ -340,7 +340,8 @@ bool load_material_lib(const char *path,str8 relative_path, material_darray *mat char diffuse_map_filename[1024]; sscanf(pch + offset, "%s", diffuse_map_filename); char diffuse_map_path[1024]; - snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf, diffuse_map_filename); + snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf, + diffuse_map_filename); printf("load from %s\n", diffuse_map_path); // -------------- @@ -355,7 +356,8 @@ bool load_material_lib(const char *path,str8 relative_path, material_darray *mat char specular_map_filename[1024]; sscanf(pch + offset, "%s", specular_map_filename); char specular_map_path[1024]; - snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf, specular_map_filename); + snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf, + specular_map_filename); printf("load from %s\n", specular_map_path); // -------------- texture specular_texture = texture_data_load(specular_map_path, true); -- cgit v1.2.3-70-g09d2 From 2b83174a87f5a1e4991cc9153309ad0f73450b44 Mon Sep 17 00:00:00 2001 From: omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Thu, 14 Mar 2024 22:29:15 +1100 Subject: fix cube texture path now that we can load relative path --- assets/models/obj/cube/cube.mtl | 2 +- src/resources/obj.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'src') diff --git a/assets/models/obj/cube/cube.mtl b/assets/models/obj/cube/cube.mtl index 9a17b69..aa04436 100644 --- a/assets/models/obj/cube/cube.mtl +++ b/assets/models/obj/cube/cube.mtl @@ -10,4 +10,4 @@ Ke 0.0 0.0 0.0 Ni 1.450000 d 1.000000 illum 2 -map_Kd models/obj/cube/container.jpg +map_Kd container.jpg diff --git a/src/resources/obj.c b/src/resources/obj.c index 710d5f0..56f885f 100644 --- a/src/resources/obj.c +++ b/src/resources/obj.c @@ -45,11 +45,8 @@ model_handle model_load_obj(core *core, const char *path, bool invert_textures_y if (!relative_path.has_value) { WARN("Couldnt get a relative path for the path to use for loading materials & textures later"); } - printf("Relative path: %s\n", relative_path.path.buf); const char *file_string = string_from_file(path); - // TODO: store the relative path without the name.obj at the end - model model = { 0 }; model.name = str8_cstr_view(path); model.meshes = mesh_darray_new(1); -- cgit v1.2.3-70-g09d2 From 51b4a3fc75351d6ecd2142c228d31a1f7ed52152 Mon Sep 17 00:00:00 2001 From: Omniscient <17525998+omnisci3nce@users.noreply.github.com> Date: Sun, 17 Mar 2024 15:00:53 +1100 Subject: fix a bug with dirname seg faulting when passed a string literal it doesnt like things in readonly memory i guess. now we create an arena for the obj load and create a dynamically allocated copy of the string --- examples/obj_loading/ex_obj_loading.c | 4 ++-- src/platform/path.c | 9 +++++++-- src/platform/path.h | 2 +- src/resources/obj.c | 9 ++++++++- src/std/mem.c | 6 ++++-- src/std/mem.h | 1 + 6 files changed, 23 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/examples/obj_loading/ex_obj_loading.c b/examples/obj_loading/ex_obj_loading.c index ecb2e54..6e63938 100644 --- a/examples/obj_loading/ex_obj_loading.c +++ b/examples/obj_loading/ex_obj_loading.c @@ -60,8 +60,8 @@ int main() { render_frame_begin(&core->renderer); // Draw the backpack - transform model_tf = - transform_create(vec3(0.0, -0.4, 0.0), quat_ident(), 1.8); // make the backpack a bit bigger + transform model_tf = transform_create(vec3(0.0, -0.4, 0.0), quat_ident(), + 1.8); // make the backpack a bit bigger draw_model(&core->renderer, &cam, backpack, model_tf, &our_scene); render_frame_end(&core->renderer); diff --git a/src/platform/path.c b/src/platform/path.c index e67102b..9572941 100644 --- a/src/platform/path.c +++ b/src/platform/path.c @@ -1,12 +1,17 @@ #include "path.h" #include +#include #include +#include "mem.h" #include "str.h" #if defined(CEL_PLATFORM_LINUX) || defined(CEL_PLATFORM_MAC) -path_opt path_parent(const char* path) { - char* path_dirname = dirname(path); +path_opt path_parent(arena* a, const char* path) { + // Duplicate the string because dirname doesnt like const literals + char* path_copy = arena_alloc(a, strlen(path) + 1); + strcpy(path_copy, path); + char* path_dirname = dirname(path_copy); return (path_opt){ .path = str8_cstr_view(path_dirname), .has_value = true }; } #endif diff --git a/src/platform/path.h b/src/platform/path.h index 0ec6993..73063ea 100644 --- a/src/platform/path.h +++ b/src/platform/path.h @@ -13,4 +13,4 @@ typedef struct path_opt { bool has_value; } path_opt; -path_opt path_parent(const char* path); // TODO: convert to using str8 \ No newline at end of file +path_opt path_parent(arena* a, const char* path); // TODO: convert to using str8 \ No newline at end of file diff --git a/src/resources/obj.c b/src/resources/obj.c index 56f885f..c6e9fa6 100644 --- a/src/resources/obj.c +++ b/src/resources/obj.c @@ -15,6 +15,7 @@ #include "file.h" #include "log.h" #include "maths.h" +#include "mem.h" #include "path.h" #include "render.h" #include "render_types.h" @@ -40,8 +41,11 @@ bool model_load_obj_str(const char *file_string, str8 relative_path, model *out_ bool invert_textures_y); model_handle model_load_obj(core *core, const char *path, bool invert_textures_y) { + size_t arena_size = 1024; + arena scratch = arena_create(malloc(arena_size), arena_size); + TRACE("Loading model at Path %s\n", path); - path_opt relative_path = path_parent(path); + path_opt relative_path = path_parent(&scratch, path); if (!relative_path.has_value) { WARN("Couldnt get a relative path for the path to use for loading materials & textures later"); } @@ -61,6 +65,9 @@ model_handle model_load_obj(core *core, const char *path, bool invert_textures_y u32 index = model_darray_len(core->models); model_darray_push(core->models, model); + + arena_free_all(&scratch); + arena_free_storage(&scratch); return (model_handle){ .raw = index }; } diff --git a/src/std/mem.c b/src/std/mem.c index f5b92d4..d7c0f4c 100644 --- a/src/std/mem.c +++ b/src/std/mem.c @@ -16,7 +16,7 @@ void* arena_alloc_align(arena* a, size_t size, size_t align) { ERROR_EXIT("Arena ran out of memory\n"); } void* p = a->begin + padding; - a->begin += padding + size; + a->curr += padding + size; return memset(p, 0, size); } void* arena_alloc(arena* a, size_t size) { return arena_alloc_align(a, size, DEFAULT_ALIGNMENT); } @@ -29,4 +29,6 @@ arena arena_create(void* backing_buffer, size_t capacity) { void arena_free_all(arena* a) { a->curr = a->begin; // pop everything at once and reset to the start. -} \ No newline at end of file +} + +void arena_free_storage(arena* a) { free(a->begin); } \ No newline at end of file diff --git a/src/std/mem.h b/src/std/mem.h index c3ec61d..2f92894 100644 --- a/src/std/mem.h +++ b/src/std/mem.h @@ -22,4 +22,5 @@ arena arena_create(void* backing_buffer, size_t capacity); void* arena_alloc(arena* a, size_t size); void* arena_alloc_align(arena* a, size_t size, size_t align); void arena_free_all(arena* a); +void arena_free_storage(arena* a); // TODO: arena_resize \ No newline at end of file -- cgit v1.2.3-70-g09d2