gs_quad_batch.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #include "graphics/gs_quad_batch.h"
  2. #include "graphics/gs_material.h"
  3. gs_quad_batch_t gs_quad_batch_new(gs_resource(gs_material_t) handle)
  4. {
  5. gs_graphics_i* gfx = gs_engine_instance()->ctx.graphics;
  6. gs_quad_batch_i* qbi = gfx->quad_batch_i;
  7. gs_quad_batch_t qb = {0};
  8. qb.raw_vertex_data = gs_byte_buffer_new();
  9. if (handle.id == gs_resource_invalid(gs_material_t).id)
  10. {
  11. // Terrible naming for these apis. Very confusing. Need to standardize this more.
  12. handle = gfx->material_i->construct(qbi->shader);
  13. }
  14. qb.material = handle;
  15. // Calculate layout size from layout
  16. void* layout = (void*)gfx->quad_batch_i->vert_info.layout;
  17. u32 layout_count = gs_dyn_array_size(gfx->quad_batch_i->vert_info.layout);
  18. // The data for will be empty for now
  19. qb.mesh.vbo = gfx->construct_vertex_buffer(layout, layout_count * sizeof(gs_vertex_attribute_type), NULL, 0);
  20. return qb;
  21. }
  22. void __gs_quad_batch_default_begin(gs_quad_batch_t* batch)
  23. {
  24. // Reset position of vertex data
  25. gs_byte_buffer_clear(&batch->raw_vertex_data);
  26. batch->mesh.vertex_count = 0;
  27. }
  28. void __gs_quad_batch_add_raw_vert_data(gs_quad_batch_t* qb, void* data, usize data_size)
  29. {
  30. gs_graphics_i* gfx = gs_engine_instance()->ctx.graphics;
  31. gs_quad_batch_i* qbi = gfx->quad_batch_i;
  32. // Calculate layout size from layout
  33. void* layout = (void*)qbi->vert_info.layout;
  34. u32 layout_count = gs_dyn_array_size(qbi->vert_info.layout);
  35. // Calculate vert size
  36. usize vert_size = gfx->calculate_vertex_size_in_bytes(layout, layout_count);
  37. // In here, you need to know how to read/structure your data to parse the package
  38. u32 vert_count = data_size / vert_size;
  39. gs_byte_buffer_bulk_write(&qb->raw_vertex_data, data, data_size);
  40. qb->mesh.vertex_count += vert_count;
  41. }
  42. void __gs_quad_batch_default_add(gs_quad_batch_t* qb, void* quad_info_data)
  43. {
  44. gs_graphics_i* gfx = gs_engine_instance()->ctx.graphics;
  45. gs_default_quad_info_t* quad_info = (gs_default_quad_info_t*)(quad_info_data);
  46. if (!quad_info) {
  47. gs_assert(false);
  48. }
  49. gs_vqs transform = quad_info->transform;
  50. gs_vec4 uv = quad_info->uv;
  51. gs_vec4 color = quad_info->color;
  52. // Add as many vertices as you want into the batch...should I perhaps just call this a triangle batch instead?
  53. // For now, no rotation (just position and scale)
  54. gs_mat4 model = gs_vqs_to_mat4(&transform);
  55. gs_vec3 _tl = (gs_vec3){-0.5f, -0.5f, 0.f};
  56. gs_vec3 _tr = (gs_vec3){ 0.5f, -0.5f, 0.f};
  57. gs_vec3 _bl = (gs_vec3){-0.5f, 0.5f, 0.f};
  58. gs_vec3 _br = (gs_vec3){ 0.5f, 0.5f, 0.f};
  59. gs_vec4 position = {0};
  60. gs_quad_batch_default_vert_t tl = {0};
  61. gs_quad_batch_default_vert_t tr = {0};
  62. gs_quad_batch_default_vert_t bl = {0};
  63. gs_quad_batch_default_vert_t br = {0};
  64. // Top Left
  65. position = gs_mat4_mul_vec4(model, (gs_vec4){_tl.x, _tl.y, _tl.z, 1.0f});
  66. position = gs_vec4_scale(position, 1.0f / position.w);
  67. tl.position = (gs_vec3){position.x, position.y, position.z};
  68. tl.uv = (gs_vec2){uv.x, uv.y};
  69. tl.color = color;
  70. // Top Right
  71. position = gs_mat4_mul_vec4(model, (gs_vec4){_tr.x, _tr.y, _tr.z, 1.0f});
  72. position = gs_vec4_scale(position, 1.0f / position.w);
  73. tr.position = (gs_vec3){position.x, position.y, position.z};
  74. tr.uv = (gs_vec2){uv.z, uv.y};
  75. tr.color = color;
  76. // Bottom Left
  77. position = gs_mat4_mul_vec4(model, (gs_vec4){_bl.x, _bl.y, _bl.z, 1.0f});
  78. position = gs_vec4_scale(position, 1.0f / position.w);
  79. bl.position = (gs_vec3){position.x, position.y, position.z};
  80. bl.uv = (gs_vec2){uv.x, uv.w};
  81. bl.color = color;
  82. // Bottom Right
  83. position = gs_mat4_mul_vec4(model, (gs_vec4){_br.x, _br.y, _br.z, 1.0f});
  84. position = gs_vec4_scale(position, 1.0f / position.w);
  85. br.position = (gs_vec3){position.x, position.y, position.z};
  86. br.uv = (gs_vec2){uv.z, uv.w};
  87. br.color = color;
  88. gs_quad_batch_default_vert_t verts[] = {
  89. tl, br, bl, tl, tr, br
  90. };
  91. __gs_quad_batch_add_raw_vert_data(qb, verts, sizeof(verts));
  92. }
  93. void __gs_quad_batch_default_end(gs_quad_batch_t* batch)
  94. {
  95. gs_graphics_i* gfx = gs_engine_instance()->ctx.graphics;
  96. gfx->update_vertex_buffer_data(batch->mesh.vbo, batch->raw_vertex_data.data, batch->raw_vertex_data.size);
  97. }
  98. void __gs_quad_batch_default_free(gs_quad_batch_t* batch)
  99. {
  100. // Free byte buffer
  101. gs_byte_buffer_free(&batch->raw_vertex_data);
  102. }
  103. void __gs_quad_batch_default_submit(gs_command_buffer_t* cb, gs_quad_batch_t* batch)
  104. {
  105. gs_graphics_i* gfx = gs_engine_instance()->ctx.graphics;
  106. // Bind material shader
  107. gfx->bind_material_shader(cb, batch->material);
  108. // Not liking this too much...
  109. gfx->bind_material_uniforms(cb, batch->material);
  110. // Bind quad batch mesh vbo
  111. gfx->bind_vertex_buffer(cb, batch->mesh.vbo);
  112. // Draw
  113. gfx->draw(cb, 0, batch->mesh.vertex_count);
  114. }
  115. void __gs_quad_batch_i_set_layout(gs_quad_batch_i* api, void* layout, usize layout_size)
  116. {
  117. gs_dyn_array_clear(api->vert_info.layout);
  118. u32 count = layout_size / sizeof(gs_vertex_attribute_type);
  119. gs_for_range_i(count)
  120. {
  121. gs_dyn_array_push(api->vert_info.layout, ((gs_vertex_attribute_type*)layout)[i]);
  122. }
  123. }
  124. void __gs_quad_batch_i_set_shader(gs_quad_batch_i* api, gs_shader_t shader)
  125. {
  126. api->shader = shader;
  127. }
  128. gs_quad_batch_i __gs_quad_batch_i_new()
  129. {
  130. gs_quad_batch_i api = {0};
  131. api.begin = &__gs_quad_batch_default_begin;
  132. api.end = &__gs_quad_batch_default_end;
  133. api.add = &__gs_quad_batch_default_add;
  134. api.begin = &__gs_quad_batch_default_begin;
  135. api.construct = &gs_quad_batch_new;
  136. api.free = &__gs_quad_batch_default_free;
  137. api.submit = &__gs_quad_batch_default_submit;
  138. api.set_layout = &__gs_quad_batch_i_set_layout;
  139. api.set_shader = &__gs_quad_batch_i_set_shader;
  140. api.vert_info.layout = gs_dyn_array_new(gs_vertex_attribute_type);
  141. gs_dyn_array_push(api.vert_info.layout, gs_vertex_attribute_float3); // Position
  142. gs_dyn_array_push(api.vert_info.layout, gs_vertex_attribute_float2); // UV
  143. gs_dyn_array_push(api.vert_info.layout, gs_vertex_attribute_float4); // Color
  144. return api;
  145. }
  146. const char* __gs_default_quad_batch_vertex_src()
  147. {
  148. return "#version 330 core\n"
  149. "layout(location = 0) in vec3 a_pos;\n"
  150. "layout(location = 1) in vec2 a_uv;\n"
  151. "layout(location = 2) in vec4 a_color;\n"
  152. "uniform mat4 u_model;\n"
  153. "uniform mat4 u_view;\n"
  154. "uniform mat4 u_proj;\n"
  155. "out vec2 uv;\n"
  156. "out vec4 color;\n"
  157. "void main()\n"
  158. "{\n"
  159. " gl_Position = u_proj * u_view * u_model * vec4(a_pos, 1.0);\n"
  160. " uv = a_uv;\n"
  161. " color = a_color;\n"
  162. "}";
  163. }
  164. const char* __gs_default_quad_batch_frag_src()
  165. {
  166. return "#version 330 core\n"
  167. "uniform sampler2D u_tex;\n"
  168. "in vec2 uv;\n"
  169. "in vec4 color;\n"
  170. "out vec4 frag_color;\n"
  171. "void main()\n"
  172. "{\n"
  173. " frag_color = color * texture(u_tex, uv);\n"
  174. "}";
  175. }