render_helpers.c (5537B)
1 ////////////////////////////////////////////////////////////////// 2 // render_helpers.c 3 4 // render pass 5 RV_GLOBAL rv_render_pass_t* rv_render_push_render_pass(rv_arena* arena, rv_render_pass_list_t* rpass_list) 6 { 7 rv_render_pass_t* res = rv_push(arena, rv_render_pass_t); 8 rv_llist_queue_push(rpass_list->first, rpass_list->last, res); 9 return res; 10 } 11 12 // command list 13 RV_GLOBAL rv_command_t* rv_cmd_copy(rv_command_t* dest, rv_command_t source) { 14 rv_command_t* next = dest->next; 15 rv_command_t* prev = dest->prev; 16 17 *dest = source; 18 19 dest->next = next; 20 dest->prev = prev; 21 22 return dest; 23 } 24 25 RV_GLOBAL rv_command_t* rv_cmd_push(rv_arena* arena, rv_command_list_t* commands) 26 { 27 rv_command_t* res = rv_push(arena, rv_command_t); 28 rv_dll_push_back(commands->first, commands->last, res); 29 return res; 30 } 31 32 RV_GLOBAL rv_command_t* rv_cmd_insert(rv_arena* arena, rv_command_list_t* commands, rv_command_t* after) 33 { 34 rv_command_t* res = rv_push(arena, rv_command_t); 35 rv_dll_insert(commands->first, commands->last, after, res); 36 return res; 37 } 38 39 RV_GLOBAL rv_command_t* rv_render_copy_commands(rv_arena* arena, rv_command_list_t* dest, rv_command_list_t* source) 40 { 41 rv_command_t* res = NULL; 42 for (rv_command_t* c = source->first; c; c = c->next) { 43 if (!res) res = rv_cmd_copy(rv_cmd_push(arena, dest), *c); 44 else rv_cmd_copy(rv_cmd_push(arena, dest), *c); 45 } 46 return res; 47 } 48 49 // ctors 50 RV_GLOBAL rv_command_t rv_cmd_type(rv_command_type_t type) 51 { 52 return (rv_command_t){.type = type}; 53 } 54 55 RV_GLOBAL rv_command_t rv_cmd_obj(rv_command_type_t type, rv_command_obj_operation_t operation, void* obj) 56 { 57 rv_assert(type >= RV_COMMAND_OBJ_VERTEX && type <= RV_COMMAND_OBJ_FRAMEBUFFER); 58 59 return (rv_command_t) { 60 .type = type, 61 .obj.operation = operation, 62 .obj.generic = obj, 63 }; 64 } 65 66 RV_GLOBAL rv_command_t rv_cmd_uniform_update(rv_uniform_t* uniform, rv_uniform_variant_t value) 67 { 68 return (rv_command_t) { 69 .type = RV_COMMAND_UNIFORM_UPDATE, 70 .uniform_update.desc = uniform, 71 .uniform_update.value = value, 72 }; 73 } 74 75 // command modification helpers 76 RV_GLOBAL rv_render_clear_desc_t* rv_render_push_clear_desc(rv_arena* arena, rv_command_t* clear, rv_graphics_clear_flag_t flags) 77 { 78 rv_assert(clear->type == RV_COMMAND_CLEAR); 79 rv_render_clear_desc_t* res = rv_push_compound(arena, rv_render_clear_desc_t, {.flags = flags}); 80 rv_llist_queue_push(clear->clear.first, clear->clear.last, res); 81 return res; 82 } 83 84 RV_GLOBAL bool32 rv_command_has_pipeline(rv_command_t* command, rv_pipeline_t* pipeline) 85 { 86 return command->type == RV_COMMAND_OBJ_PIPELINE && command->obj.pipeline == pipeline; 87 } 88 89 // framebuffer modificatoin helpers 90 RV_GLOBAL void rv_framebuffer_push_texture(rv_arena* arena, rv_framebuffer_t* fbuf, rv_texture_t* tex) 91 { 92 rv_texture_node_t* tnode = rv_push_compound(arena, rv_texture_node_t, {.tex = tex}); 93 rv_llist_stack_push(fbuf->color_attachement_first, tnode); 94 } 95 96 RV_GLOBAL rv_framebuffer_t* rv_framebuffer_color_simple(rv_arena* arena, rv_vec2 color_size, rv_command_list_t* append_construction) 97 { 98 rv_framebuffer_t* fbuf = rv_push(arena, rv_framebuffer_t); 99 100 rv_texture_t* tex = rv_push_compound(arena, rv_texture_t, {.data = NULL, .size = color_size}); 101 rv_framebuffer_push_texture(arena, fbuf, tex); 102 103 rv_cmd_push_obj(arena, append_construction, RV_COMMAND_OBJ_TEXTURE, RV_RENDER_OBJ_OP_CREATE, tex); 104 rv_cmd_push_obj(arena, append_construction, RV_COMMAND_OBJ_FRAMEBUFFER, RV_RENDER_OBJ_OP_CREATE, fbuf); 105 106 return fbuf; 107 } 108 109 // pipeline modificatoin helpers 110 RV_GLOBAL rv_shader_node_t* rv_pipeline_push_shader(rv_arena* arena, rv_pipeline_t* pipeline, rv_shader_t* shader) 111 { 112 rv_shader_node_t* res = rv_push_compound(arena, rv_shader_node_t, {.shader = shader}); 113 rv_llist_stack_push(pipeline->shader_first, res); 114 return res; 115 } 116 117 RV_GLOBAL rv_uniform_t* rv_pipeline_push_uniform(rv_arena* arena, rv_pipeline_t* pipeline, rv_str8 name, rv_uniform_type_t type) 118 { 119 rv_uniform_t* res = rv_push_compound(arena, rv_uniform_t, {.name_null_terminated = rv_str8_copy(arena, name) , .type = type}); 120 rv_llist_stack_push(pipeline->uniform_desc_first, res); 121 return res; 122 } 123 124 RV_GLOBAL rv_vattr_t* rv_pipeline_push_vattr(rv_arena* arena, rv_pipeline_t* pipeline, rv_vattr_type_t type, s32 bind_index, s32 divisor) 125 { 126 rv_vattr_t* res = rv_push_compound(arena, rv_vattr_t, {.type = type, .bind_index = bind_index, .divisor = divisor}); 127 rv_llist_queue_push(pipeline->vattr_first, pipeline->vattr_last, res); 128 return res; 129 } 130 131 RV_GLOBAL void rv_get_default_texture(void** data_out, rv_vec2* size_out) 132 { 133 #define RV_DEFAULT_TEX_ROW_COL_CT 6 134 135 RV_LOCAL_PERSIST rv_color_t pixels[RV_DEFAULT_TEX_ROW_COL_CT * RV_DEFAULT_TEX_ROW_COL_CT]; 136 RV_LOCAL_PERSIST bool32 loaded = false; 137 138 if (!loaded) { 139 // Generate default texture (checkered purple/black texture) 140 rv_color_t c0 = RV_COLOR_BLACK; 141 rv_color_t c1 = RV_COLOR_PURPLE; 142 for (s32 r = 0; r < RV_DEFAULT_TEX_ROW_COL_CT; ++r) { 143 for (s32 c = 0; c < RV_DEFAULT_TEX_ROW_COL_CT; ++c) { 144 const bool32 re = (r % 2) == 0; 145 const bool32 ce = (c % 2) == 0; 146 s32 idx = r * RV_DEFAULT_TEX_ROW_COL_CT + c; 147 pixels[idx] = (re && ce) ? c0 : (re) ? c1 : (ce) ? c1 : c0; 148 } 149 } 150 } 151 152 *data_out = pixels; 153 *size_out = rv_v2(RV_DEFAULT_TEX_ROW_COL_CT, RV_DEFAULT_TEX_ROW_COL_CT); 154 }