revolver

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

bump_cache.c (8560B)


      1 //////////////////////////////////////////////////////////////////
      2 // bump_cache.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     out vec3 f_color;
     22     void main()
     23     {
     24         gl_Position = vec4(a_pos + a_offset, 0.0, 1.0);
     25         f_color = a_color;
     26     }
     27 ));
     28 
     29 rv_str8 f_src = S("#version 330 core\n" rv_strify(
     30     precision mediump float;
     31     in vec3 f_color;
     32     out vec4 frag_color;
     33     void main()
     34     {
     35         frag_color = vec4(f_color, 1.0);
     36     }
     37 ));
     38 
     39 //////////////////////////////////////////////////////////////////
     40 
     41 int main(void) {
     42     rv_window_desc_t desc = {.name = S("App"), .attach_render = true};
     43     rv_window_handle_t* window = rv_create_window(desc);
     44 
     45     rv_arena* arena = rv_arena_alloc();
     46     rv_render_pass_list_t rpass_list = {0};
     47 
     48     // make render objects
     49     rv_vbo_t*      vbo      = rv_push_compound(arena, rv_vbo_t,     {.data   = v_data,         .size = sizeof(v_data)});
     50     rv_vbo_t*      vboi     = rv_push_compound(arena, rv_vbo_t,     {.usage = RV_BUFFER_USAGE_DYNAMIC});
     51     rv_shader_t*   vertex   = rv_push_compound(arena, rv_shader_t,  {.source = v_src,          .type = RV_SHADER_TYPE_VERTEX});
     52     rv_shader_t*   fragment = rv_push_compound(arena, rv_shader_t,  {.source = f_src,          .type = RV_SHADER_TYPE_FRAGMENT});
     53     rv_pipeline_t* pip       = rv_push(arena, rv_pipeline_t);
     54 
     55     // construct pipeline
     56     rv_pipeline_push_shader(arena, pip, vertex);
     57     rv_pipeline_push_shader(arena, pip, fragment);
     58     rv_pipeline_push_vattr(arena,  pip, RV_VATTR_TYPE_FLOAT2, 0, 0);
     59     rv_pipeline_push_vattr(arena,  pip, RV_VATTR_TYPE_FLOAT3, 0, 0);
     60     rv_pipeline_push_vattr(arena,  pip, RV_VATTR_TYPE_FLOAT2, 1, 1);
     61 
     62     // instructions to create render objects
     63     rv_command_list_t create_instructions = {0};
     64     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_VERTEX,   RV_RENDER_OBJ_OP_CREATE, vbo);
     65     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_VERTEX,   RV_RENDER_OBJ_OP_CREATE, vboi);
     66     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER,   RV_RENDER_OBJ_OP_CREATE, vertex);
     67     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER,   RV_RENDER_OBJ_OP_CREATE, fragment);
     68     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_CREATE, pip);
     69 
     70     // copy over create commands
     71     rv_render_pass_t* create_rpass = rv_render_push_render_pass(arena, &rpass_list);
     72     rv_render_copy_commands(arena, &create_rpass->commands, &create_instructions);
     73 
     74     // create vertex cache
     75     rv_bump_cache_ctx_t bc = {0};
     76     rv_bump_cache_create(&bc, sizeof(rv_vec2));
     77 
     78     while(1) {
     79         rv_temp_arena scratch = rv_scratch_begin(0, 0);
     80 
     81         // pick renderpass
     82         rv_render_pass_t* rpass = rv_render_push_render_pass(scratch.arena, &rpass_list);
     83 
     84         // process events
     85         for (rv_event_t* e = rv_get_events(scratch.arena, 0); e; e = e->next) {
     86             if (e->type == RV_EVENT_WINDOW_CLOSE) {
     87                 if (e->window_close == window) {
     88                     goto exit_program;
     89                 }
     90             }
     91             if (e->type == RV_EVENT_WINDOW_RESIZE) {
     92                 // set viewport
     93                 rv_command_t* viewport = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_SET_VIEWPORT);
     94                 viewport->viewport = rv_v4(.xy = {0, 0}, .zw = rv_window_size(window));
     95             }
     96         }
     97 
     98 
     99         { // clear
    100             rv_command_t* clear = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_CLEAR);
    101             rv_render_clear_desc_t* clear_desc = rv_render_push_clear_desc(scratch.arena, clear, RV_RENDER_CLEAR_FLAG_COLOR);
    102             clear_desc->color_v = rv_v4(0.1, 0.1, 0.1, 1.0);
    103         }
    104 
    105         { // draw using vertex cache
    106             // bind pipeline
    107             rv_cmd_push_obj(arena, &rpass->commands, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, pip);
    108             rv_cmd_push_obj(arena, &rpass->commands, RV_COMMAND_OBJ_VERTEX,   RV_RENDER_OBJ_OP_BIND, vbo);
    109 
    110             { // draw custom shader first time
    111                 { // Translation data
    112                     int32_t index = 0;
    113                     float offset = 0.1f;
    114                     s32 peak_to_peak = 10.0;
    115                     for (int32_t y = -peak_to_peak; y < peak_to_peak; y += 2) {
    116                         if (sinf(rv_time()*5) * 9.0f < y)
    117                             break;
    118                         for (int32_t x = -peak_to_peak; x < peak_to_peak; x += 2) {
    119                             if (cosf(rv_time()*5) * 9.0f < x)
    120                                 break;
    121                             rv_vec2 vertex = {0};
    122                             vertex.x = (float)x / 10.0f + offset;
    123                             vertex.y = (float)y / 10.0f + offset;
    124                             rv_bump_cache_push(&bc, &vertex);
    125                             index++;
    126                         }
    127                     }
    128                 }
    129 
    130                 // insert break, push draw command
    131                 s64 offset, instances;
    132                 rv_bump_cache_break(&bc, &offset, &instances);
    133 
    134                 rv_command_t bind_command = rv_cmd_obj(RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_BIND, vboi);
    135                 bind_command.obj.vbo_bind.bind_index = 1;
    136                 bind_command.obj.vbo_bind.base_offset = offset * bc.element_size;
    137                 rv_command_t draw_command = rv_cmd(RV_COMMAND_DRAW, {.draw.count = 3, .draw.instances = instances});
    138 
    139                 if (instances) {
    140                     rv_cmd_push_copy(scratch.arena, &rpass->commands, bind_command);
    141                     rv_cmd_push_copy(scratch.arena, &rpass->commands, draw_command);
    142                 }
    143             }
    144 
    145             { // draw custom shader second time
    146                 { // Translation data
    147                     rv_vec2 extra_offset = rv_v2(sinf(rv_time()*10) * 0.05, cosf(rv_time()*10) * 0.05);
    148                     int32_t index = 0;
    149                     float offset = 0.1f;
    150                     s32 peak_to_peak = 10;
    151                     for (int32_t y = -peak_to_peak; y < peak_to_peak; y += 2) {
    152                         for (int32_t x = -peak_to_peak; x < peak_to_peak; x += 2) {
    153                             rv_vec2 vertex = {0};
    154                             vertex.x = (float)x / 10.0f + offset + extra_offset.x;
    155                             vertex.y = (float)y / 10.0f + offset + extra_offset.y;
    156                             rv_bump_cache_push(&bc, &vertex);
    157                             index++;
    158                         }
    159                     }
    160                 }
    161 
    162                 // insert break, push draw command
    163                 s64 offset, instances;
    164                 rv_bump_cache_break(&bc, &offset, &instances);
    165 
    166                 rv_command_t bind_command = rv_cmd_obj(RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_BIND, vboi);
    167                 bind_command.obj.vbo_bind.bind_index = 1;
    168                 bind_command.obj.vbo_bind.base_offset = offset * bc.element_size;
    169                 rv_command_t draw_command = rv_cmd(RV_COMMAND_DRAW, {.draw.count = 3, .draw.instances = instances});
    170 
    171                 if (instances) {
    172                     rv_cmd_push_copy(scratch.arena, &rpass->commands, bind_command);
    173                     rv_cmd_push_copy(scratch.arena, &rpass->commands, draw_command);
    174                 }
    175             }
    176 
    177             // unbind pipeline
    178             rv_cmd_push_obj(arena, &rpass->commands, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, NULL);
    179 
    180             {
    181                 // when done, upload all the data
    182                 // must be done before render commands of course
    183                 rv_command_t change_command = rv_cmd_obj(RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_UPDATE, vboi);
    184                 rv_bump_cache_upload_and_reset(&bc, scratch.arena, &change_command.obj.vbo_update.data, &change_command.obj.vbo_update.size);
    185                 rv_cmd_insert_copy(scratch.arena, &rpass->commands, rpass->commands.first, change_command);
    186             }
    187         }
    188 
    189         if (window) { // render screen
    190             rv_window_render_commit(window, &rpass_list);
    191         }
    192         rv_scratch_end(scratch);
    193         rpass_list = (rv_render_pass_list_t){0};
    194     }
    195 exit_program:
    196 
    197     return 0;
    198 }