revolver

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

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 }