instancing.c (5818B)
1 ////////////////////////////////////////////////////////////////// 2 // instancing.c 3 4 #include "revolver_inc.h" 5 #include "revolver_inc.c" 6 7 ////////////////////////////////////////////////////////////////// 8 // data 9 10 f32 v_data[] = { 11 0.00, 0.05, 1, 0, 0, 12 -0.05, -0.05, 0, 1, 0, 13 0.05, -0.05, 0, 0, 1, 14 }; 15 16 rv_str8 v_src = S("#version 330 core\n" rv_strify( 17 layout(location = 0) in vec2 a_pos; 18 layout(location = 1) in vec3 a_color; 19 layout(location = 2) in vec2 a_offset; 20 precision mediump float; 21 uniform vec2 u_offset; 22 out vec3 f_color; 23 void main() 24 { 25 gl_Position = vec4(a_pos + a_offset + u_offset, 0.0, 1.0); 26 f_color = a_color; 27 } 28 )); 29 30 rv_str8 f_src = S("#version 330 core\n" rv_strify( 31 precision mediump float; 32 in vec3 f_color; 33 out vec4 frag_color; 34 void main() 35 { 36 frag_color = vec4(f_color, 1.0); 37 } 38 )); 39 40 rv_vec2 g_translations[100] = {0}; 41 42 ////////////////////////////////////////////////////////////////// 43 44 int main(void) { 45 rv_window_desc_t desc = {.name = S("App"), .attach_render = true}; 46 rv_window_handle_t* window = rv_create_window(desc); 47 48 rv_arena* arena = rv_arena_alloc(); 49 rv_render_pass_list_t rpass_list = {0}; 50 51 // Translation data 52 int32_t index = 0; 53 float offset = 0.1f; 54 for (int32_t y = -10; y < 10; y += 2) { 55 for (int32_t x = -10; x < 10; x += 2) { 56 g_translations[index].x = (float)x / 10.0f + offset; 57 g_translations[index].y = (float)y / 10.0f + offset; 58 index++; 59 } 60 } 61 62 // make render objects 63 rv_vbo_t* vbo = rv_push_compound(arena, rv_vbo_t, {.data = v_data, .size = sizeof(v_data)}); 64 rv_vbo_t* vboi = rv_push_compound(arena, rv_vbo_t, {.data = g_translations, .size = sizeof(g_translations)}); 65 rv_shader_t* vertex = rv_push_compound(arena, rv_shader_t, {.source = v_src, .type = RV_SHADER_TYPE_VERTEX}); 66 rv_shader_t* fragment = rv_push_compound(arena, rv_shader_t, {.source = f_src, .type = RV_SHADER_TYPE_FRAGMENT}); 67 rv_pipeline_t* pip = rv_push(arena, rv_pipeline_t); 68 69 // construct pipeline 70 rv_pipeline_push_shader(arena, pip, vertex); 71 rv_pipeline_push_shader(arena, pip, fragment); 72 rv_pipeline_push_vattr(arena, pip, RV_VATTR_TYPE_FLOAT2, 0, 0); 73 rv_pipeline_push_vattr(arena, pip, RV_VATTR_TYPE_FLOAT3, 0, 0); 74 rv_pipeline_push_vattr(arena, pip, RV_VATTR_TYPE_FLOAT2, 1, 1); 75 rv_uniform_t* u_offset = rv_pipeline_push_uniform(arena, pip, S("u_offset"), RV_UNIFORM_VEC2); 76 77 // instructions to create render objects 78 rv_command_list_t create_instructions = {0}; 79 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_CREATE, vbo); 80 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_CREATE, vboi); 81 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER, RV_RENDER_OBJ_OP_CREATE, vertex); 82 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER, RV_RENDER_OBJ_OP_CREATE, fragment); 83 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_CREATE, pip); 84 85 // instructions to render 86 rv_command_list_t render_instructions = {0}; 87 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, pip); 88 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_BIND, vbo); 89 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_BIND, vboi)->obj.vbo_bind.bind_index = 1; 90 rv_cmd_push_compound(arena, &render_instructions, RV_COMMAND_DRAW, {.draw = {.count = 3, .instances = 100}}); 91 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, NULL); 92 93 // copy over create commands 94 rv_render_pass_t* create_rpass = rv_render_push_render_pass(arena, &rpass_list); 95 rv_render_copy_commands(arena, &create_rpass->commands, &create_instructions); 96 97 while(1) { 98 rv_temp_arena scratch = rv_scratch_begin(0, 0); 99 100 // pick renderpass 101 rv_render_pass_t* rpass = rv_render_push_render_pass(scratch.arena, &rpass_list); 102 103 // process events 104 for (rv_event_t* e = rv_get_events(scratch.arena, 0); e; e = e->next) { 105 if (e->type == RV_EVENT_WINDOW_CLOSE) { 106 if (e->window_close == window) { 107 goto exit_program; 108 } 109 } 110 if (e->type == RV_EVENT_WINDOW_RESIZE) { 111 // set viewport 112 rv_command_t* viewport = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_SET_VIEWPORT); 113 viewport->viewport = rv_v4(.xy = {0, 0}, .zw = rv_window_size(window)); 114 } 115 } 116 117 118 { // clear 119 rv_command_t* clear = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_CLEAR); 120 rv_render_clear_desc_t* clear_desc = rv_render_push_clear_desc(scratch.arena, clear, RV_RENDER_CLEAR_FLAG_COLOR); 121 clear_desc->color_v = rv_v4(0.1, 0.1, 0.1, 1.0); 122 } 123 124 { // draw custom shader 125 // copy render commands 126 rv_command_t* rcmd = rv_render_copy_commands(scratch.arena, &rpass->commands, &render_instructions); 127 rv_vec2 extra_offset = rv_v2(sinf(rv_time()*10) * 0.05, cosf(rv_time()*10) * 0.05); 128 rv_cmd_insert_uniform_update(scratch.arena, &rpass->commands, rcmd, u_offset, {.v_vec2 = extra_offset}); 129 } 130 131 if (window) { // render screen 132 rv_window_render_commit(window, &rpass_list); 133 } 134 rv_scratch_end(scratch); 135 rpass_list = (rv_render_pass_list_t){0}; 136 } 137 exit_program: 138 139 return 0; 140 }