revolver

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

framebuffer.c (10493B)


      1 
      2 //////////////////////////////////////////////////////////////////
      3 // framebuffer.c
      4 
      5 #include "revolver_inc.h"
      6 #include "revolver_inc.c"
      7 
      8 //////////////////////////////////////////////////////////////////
      9 // triangle data
     10 
     11 f32 triangle_v_data[] = {
     12      0.0,  0.5, 1, 0, 0,
     13     -0.5, -0.5, 0, 1, 0,
     14      0.5, -0.5, 0, 0, 1,
     15 };
     16 
     17 rv_str8 triangle_v_src = S("#version 330 core\n" rv_strify(
     18     layout(location = 0) in vec2 a_pos;
     19     layout(location = 1) in vec3 a_color;
     20     precision mediump float;
     21     out vec3 f_color;
     22     void main()
     23     {
     24         gl_Position = vec4(a_pos, 0.0, 1.0);
     25         f_color = a_color;
     26     }
     27 ));
     28 
     29 rv_str8 triangle_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 // post processing data
     41 
     42 // Vertex data for quad
     43 f32 post_v_data[] = {
     44     // Positions | UV
     45     -1, -1,        0, 0,  // Top Left
     46      1, -1,        1, 0,  // Top Right
     47     -1,  1,        0, 1,  // Bottom Left
     48      1,  1,        1, 1,  // Bottom Right
     49 };
     50 
     51 // Index data for quad
     52 uint32_t post_i_data[] = {
     53     0, 3, 2,    // First Triangle
     54     0, 1, 3     // Second Triangle
     55 };
     56 
     57 rv_str8 post_v_src = S("#version 330 core\n" rv_strify(
     58     layout(location = 0) in vec2 a_pos;
     59     layout(location = 1) in vec2 a_uv;
     60     precision mediump float;
     61     out vec2 uv;
     62     void main()
     63     {
     64         gl_Position = vec4(a_pos, 0.0, 1.0);
     65         uv = a_uv;
     66     }
     67 ));
     68 
     69 rv_str8 post_f_src = S("#version 330 core\n" rv_strify(
     70     precision mediump float;
     71     in vec2 uv;
     72     uniform sampler2D u_tex;
     73     uniform float u_time;
     74     out vec4 frag_color;
     75     void main()
     76     {
     77         frag_color = texture(u_tex, uv);
     78         float percent = (sin(u_time) + 1.0) * 0.5;
     79         if (uv.x > percent) {
     80             frag_color = vec4(vec3(1.0, 1.0, 1.0) - texture(u_tex, uv).xyz, 1.0);
     81         }
     82     }
     83 ));
     84 
     85 //////////////////////////////////////////////////////////////////
     86 
     87 int main(void) {
     88     rv_window_desc_t desc = {.name = S("App"), .attach_render = true};
     89     rv_window_handle_t* window = rv_create_window(desc);
     90 
     91     rv_arena* arena = rv_arena_alloc();
     92     rv_render_pass_list_t rpass_list = {0};
     93 
     94     rv_command_list_t create_instructions = {0};
     95     rv_command_list_t triangle_render_instructions = {0};
     96     rv_command_list_t post_render_instructions = {0};
     97 
     98 
     99     //////////////////////////////////////////////////////////////////
    100     // triangle
    101 
    102     // make render objects
    103     rv_vbo_t*      triangle_vbo      = rv_push_compound(arena, rv_vbo_t,     {.data   = triangle_v_data, .size = sizeof(triangle_v_data)});
    104     rv_shader_t*   triangle_vertex   = rv_push_compound(arena, rv_shader_t,  {.source = triangle_v_src,  .type = RV_SHADER_TYPE_VERTEX});
    105     rv_shader_t*   triangle_fragment = rv_push_compound(arena, rv_shader_t,  {.source = triangle_f_src,  .type = RV_SHADER_TYPE_FRAGMENT});
    106     rv_pipeline_t* triangle_pip       = rv_push(arena, rv_pipeline_t);
    107 
    108     // construct pipeline
    109     rv_pipeline_push_shader(arena, triangle_pip, triangle_vertex);
    110     rv_pipeline_push_shader(arena, triangle_pip, triangle_fragment);
    111     rv_pipeline_push_vattr(arena,  triangle_pip, RV_VATTR_TYPE_FLOAT2);
    112     rv_pipeline_push_vattr(arena,  triangle_pip, RV_VATTR_TYPE_FLOAT3);
    113 
    114     // instructions to create render objects
    115     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_VERTEX,   RV_RENDER_OBJ_OP_CREATE, triangle_vbo);
    116     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER,   RV_RENDER_OBJ_OP_CREATE, triangle_vertex);
    117     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER,   RV_RENDER_OBJ_OP_CREATE, triangle_fragment);
    118     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_CREATE, triangle_pip);
    119 
    120     // instructions to render
    121     rv_cmd_push_obj(arena,  &triangle_render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, triangle_pip);
    122     rv_cmd_push_obj(arena,  &triangle_render_instructions, RV_COMMAND_OBJ_VERTEX,   RV_RENDER_OBJ_OP_BIND, triangle_vbo);
    123     rv_cmd_push_type(arena, &triangle_render_instructions, RV_COMMAND_DRAW)->draw.count = 3;
    124     rv_cmd_push_obj(arena,  &triangle_render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, NULL);
    125 
    126     //////////////////////////////////////////////////////////////////
    127     // post processing
    128 
    129     // make render objects
    130     rv_vbo_t*         post_vbo      = rv_push_compound(arena, rv_vbo_t,     {.data   = post_v_data, .size = sizeof(post_v_data)});
    131     rv_vbo_t*         post_ibo      = rv_push_compound(arena, rv_ibo_t,     {.data   = post_i_data, .size = sizeof(post_i_data), .elem_size = sizeof(post_i_data[0])});
    132     rv_shader_t*      post_vertex   = rv_push_compound(arena, rv_shader_t,  {.source = post_v_src,  .type = RV_SHADER_TYPE_VERTEX});
    133     rv_shader_t*      post_fragment = rv_push_compound(arena, rv_shader_t,  {.source = post_f_src,  .type = RV_SHADER_TYPE_FRAGMENT});
    134     rv_pipeline_t*    post_pip      = rv_push(arena, rv_pipeline_t);
    135 
    136     // construct pipeline
    137     rv_pipeline_push_shader(arena, post_pip, post_vertex);
    138     rv_pipeline_push_shader(arena, post_pip, post_fragment);
    139     rv_pipeline_push_vattr(arena,  post_pip, RV_VATTR_TYPE_FLOAT2);
    140     rv_pipeline_push_vattr(arena,  post_pip, RV_VATTR_TYPE_FLOAT2);
    141     rv_uniform_t* u_tex  = rv_pipeline_push_uniform(arena, post_pip, S("u_tex"), RV_UNIFORM_TEX);
    142     rv_uniform_t* u_time = rv_pipeline_push_uniform(arena, post_pip, S("u_time"), RV_UNIFORM_F32);
    143 
    144     // instructions to create render objects
    145     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_VERTEX,   RV_RENDER_OBJ_OP_CREATE, post_vbo);
    146     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_INDEX,    RV_RENDER_OBJ_OP_CREATE, post_ibo);
    147     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER,   RV_RENDER_OBJ_OP_CREATE, post_vertex);
    148     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER,   RV_RENDER_OBJ_OP_CREATE, post_fragment);
    149     rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_CREATE, post_pip);
    150 
    151     // instructions to render
    152     rv_cmd_push_obj(arena,  &post_render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, post_pip);
    153     rv_cmd_push_obj(arena,  &post_render_instructions, RV_COMMAND_OBJ_VERTEX,   RV_RENDER_OBJ_OP_BIND, post_vbo);
    154     rv_cmd_push_obj(arena,  &post_render_instructions, RV_COMMAND_OBJ_INDEX,    RV_RENDER_OBJ_OP_BIND, post_ibo);
    155     rv_cmd_push_type(arena, &post_render_instructions, RV_COMMAND_DRAW)->draw.count = 6;
    156     rv_cmd_push_obj(arena,  &post_render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, NULL);
    157 
    158     //////////////////////////////////////////////////////////////////
    159     // fbuf
    160 
    161     rv_framebuffer_t* fbuf = rv_framebuffer_color_simple(arena, rv_v2(1920, 1080), &create_instructions);
    162     // set uniform texture to fbuf
    163     rv_cmd_push_obj(arena,            &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, post_pip);
    164     rv_cmd_push_uniform_update(arena, &create_instructions, u_tex, {.v_tex = fbuf->color_attachement_first->tex});
    165     rv_cmd_push_obj(arena,            &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, NULL);
    166 
    167     //////////////////////////////////////////////////////////////////
    168 
    169     // copy over create commands
    170     rv_render_pass_t* create_rpass = rv_render_push_render_pass(arena, &rpass_list);
    171     rv_render_copy_commands(arena, &create_rpass->commands, &create_instructions);
    172 
    173     while(1) {
    174         rv_temp_arena scratch = rv_scratch_begin(0, 0);
    175 
    176         // process events
    177         for (rv_event_t* e = rv_get_events(scratch.arena, 0); e; e = e->next) {
    178             if (e->type == RV_EVENT_WINDOW_CLOSE) {
    179                 if (e->window_close == window) {
    180                     goto exit_program;
    181                 }
    182             }
    183         }
    184 
    185         { // add off-screen rendering first
    186             rv_render_pass_t* off_screen_rpass = rv_render_push_render_pass(scratch.arena, &rpass_list);
    187 
    188             { // set viewport
    189                 rv_command_t* viewport = rv_cmd_push_type(scratch.arena, &off_screen_rpass->commands, RV_COMMAND_SET_VIEWPORT);
    190                 viewport->viewport = rv_v4(0, 0, 1920, 1080);
    191             }
    192 
    193             { // clear
    194                 rv_command_t* clear = rv_cmd_push_type(scratch.arena, &off_screen_rpass->commands, RV_COMMAND_CLEAR);
    195                 rv_render_clear_desc_t* clear_desc = rv_render_push_clear_desc(scratch.arena, clear, RV_RENDER_CLEAR_FLAG_COLOR);
    196                 clear_desc->color_v = rv_v4(0.1, 0.1, 0.1, 1.0);
    197             }
    198 
    199             off_screen_rpass->framebuffer = fbuf;
    200             rv_render_copy_commands(scratch.arena, &off_screen_rpass->commands, &triangle_render_instructions);
    201         }
    202 
    203         // main renderpass
    204         rv_render_pass_t* rpass = rv_render_push_render_pass(scratch.arena, &rpass_list);
    205 
    206         { // set viewport
    207             rv_command_t* viewport = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_SET_VIEWPORT);
    208             viewport->viewport = rv_v4(.xy = {0, 0}, .zw = rv_window_size(window));
    209         }
    210 
    211         { // clear
    212             rv_command_t* clear = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_CLEAR);
    213             rv_render_clear_desc_t* clear_desc = rv_render_push_clear_desc(scratch.arena, clear, RV_RENDER_CLEAR_FLAG_COLOR);
    214             clear_desc->color_v = rv_v4(0.1, 0.1, 0.1, 1.0);
    215         }
    216 
    217         { // draw post processing
    218 #if 1
    219             rv_command_t* rcmd = rv_render_copy_commands(scratch.arena, &rpass->commands, &post_render_instructions);
    220 
    221             // find the pipeline command
    222             rv_command_t* pipeline_cmd = rcmd;
    223             for (; pipeline_cmd; pipeline_cmd = pipeline_cmd->next) {
    224                 if (rv_command_has_pipeline(pipeline_cmd, post_pip)) break;
    225             }
    226             if (pipeline_cmd) {
    227                 rv_cmd_insert_uniform_update(scratch.arena, &rpass->commands, pipeline_cmd, u_time, {.v_f32 = (f32)rv_time()});
    228             }
    229 #else
    230             rv_render_copy_commands(scratch.arena, &rpass->commands, &triangle_render_instructions);
    231 #endif
    232         }
    233 
    234         if (window) { // render screen
    235             rv_window_render_commit(window, &rpass_list);
    236         }
    237         rv_scratch_end(scratch);
    238         rpass_list = (rv_render_pass_list_t){0};
    239     }
    240 exit_program:
    241 
    242     return 0;
    243 }