gs_material.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "graphics/gs_material.h"
  2. #include "graphics/gs_graphics.h"
  3. gs_resource(gs_material_t) gs_material_new(gs_shader_t shader)
  4. {
  5. gs_graphics_i* gfx = gs_engine_subsystem(graphics);
  6. gs_material_t mat = {0};
  7. mat.shader = shader;
  8. mat.uniforms = gfx->uniform_i->construct();
  9. gs_resource(gs_material_t) handle = gs_resource_cache_insert(gfx->material_cache, mat);
  10. return handle;
  11. }
  12. void __gs_material_i_set_uniform(gs_resource(gs_material_t) handle, gs_uniform_type type, const char* name, void* data)
  13. {
  14. gs_graphics_i* gfx = gs_engine_instance()->ctx.graphics;
  15. gs_uniform_block_i* uapi = gfx->uniform_i;
  16. gs_material_t* mat = gs_resource_cache_get_ptr(gfx->material_cache, handle);
  17. // Either look for uniform or construct it
  18. // Look for uniform name in uniforms
  19. // Grab uniform from uniforms
  20. u64 hash_id = gs_hash_str_64(name);
  21. gs_uniform_t uniform = {0};
  22. gs_uniform_block_t* u_block = gs_slot_array_get_ptr(uapi->uniform_blocks, mat->uniforms.id);
  23. if (!gs_hash_table_exists(u_block->offset_lookup_table, hash_id))
  24. {
  25. // Construct or get existing uniform
  26. uniform = gfx->construct_uniform(mat->shader, name, type);
  27. // Insert buffer position into offset table (which should be end)
  28. gs_hash_table_insert(u_block->uniforms, hash_id, uniform);
  29. }
  30. else
  31. {
  32. uniform = gs_hash_table_get(u_block->uniforms, hash_id);
  33. }
  34. usize sz = 0;
  35. switch (type)
  36. {
  37. case gs_uniform_type_mat4: sz = sizeof(gs_uniform_block_type(mat4)); break;
  38. case gs_uniform_type_vec4: sz = sizeof(gs_uniform_block_type(vec4)); break;
  39. case gs_uniform_type_vec3: sz = sizeof(gs_uniform_block_type(vec3)); break;
  40. case gs_uniform_type_vec2: sz = sizeof(gs_uniform_block_type(vec2)); break;
  41. case gs_uniform_type_float: sz = sizeof(gs_uniform_block_type(float)); break;
  42. case gs_uniform_type_int: sz = sizeof(gs_uniform_block_type(int)); break;
  43. case gs_uniform_type_sampler2d: sz = sizeof(gs_uniform_block_type(texture_sampler)); break;
  44. };
  45. uapi->set_uniform(mat->uniforms, uniform, name, data, sz);
  46. }
  47. void __gs_material_i_bind_uniforms(gs_command_buffer_t* cb, gs_resource(gs_material_t) handle)
  48. {
  49. gs_graphics_i* gfx = gs_engine_subsystem(graphics);
  50. gs_material_t* mat = gs_resource_cache_get_ptr(gfx->material_cache, handle);
  51. gfx->uniform_i->bind_uniforms(cb, mat->uniforms);
  52. }
  53. gs_material_i __gs_material_i_new()
  54. {
  55. gs_material_i api = {0};
  56. api.construct = &gs_material_new;
  57. api.set_uniform = &__gs_material_i_set_uniform;
  58. api.bind_uniforms = &__gs_material_i_bind_uniforms;
  59. return api;
  60. }