uniform.c (5968B)
1 ////////////////////////////////////////////////////////////////// 2 // uniform.c 3 4 #include "revolver_inc.h" 5 #include "revolver_inc.c" 6 7 ////////////////////////////////////////////////////////////////// 8 // data 9 10 f32 v_data[] = { 11 0.0f, 0.5f, 1, 0, 0, 12 -0.5f, -0.5f, 0, 1, 0, 13 0.5f, -0.5f, 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 precision mediump float; 20 uniform mat4 u_model; 21 out vec3 f_color; 22 void main() 23 { 24 gl_Position = u_model * vec4(a_pos, 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 uniform vec3 u_color; 34 void main() 35 { 36 frag_color = vec4(u_color * f_color, 1.0); 37 } 38 )); 39 40 ////////////////////////////////////////////////////////////////// 41 42 int main(void) { 43 rv_window_desc_t desc = {.name = S("App"), .attach_render = true}; 44 rv_window_handle_t* window = rv_create_window(desc); 45 46 rv_arena* arena = rv_arena_alloc(); 47 rv_render_pass_list_t rpass_list = {0}; 48 49 // make render objects 50 rv_vbo_t* vbo = rv_push_compound(arena, rv_vbo_t, {.data = v_data, .size = sizeof(v_data)}); 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); 59 rv_pipeline_push_vattr(arena, pip, RV_VATTR_TYPE_FLOAT3); 60 rv_uniform_t* u_color = rv_pipeline_push_uniform(arena, pip, S("u_color"), RV_UNIFORM_VEC3); 61 rv_uniform_t* u_model = rv_pipeline_push_uniform(arena, pip, S("u_model"), RV_UNIFORM_MAT4); 62 63 // instructions to create render objects 64 rv_command_list_t create_instructions = {0}; 65 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_CREATE, vbo); 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 // instructions to render 71 rv_command_list_t render_instructions = {0}; 72 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, pip); 73 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_BIND, vbo); 74 rv_cmd_push_type(arena, &render_instructions, RV_COMMAND_DRAW)->draw.count = 3; 75 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, NULL); 76 77 // copy over create commands 78 rv_render_pass_t* create_rpass = rv_render_push_render_pass(arena, &rpass_list); 79 rv_render_copy_commands(arena, &create_rpass->commands, &create_instructions); 80 81 82 while(1) { 83 rv_temp_arena scratch = rv_scratch_begin(0, 0); 84 85 // pick renderpass 86 rv_render_pass_t* rpass = rv_render_push_render_pass(scratch.arena, &rpass_list); 87 88 // process events 89 for (rv_event_t* e = rv_get_events(scratch.arena, 0); e; e = e->next) { 90 if (e->type == RV_EVENT_WINDOW_CLOSE) { 91 if (e->window_close == window) { 92 goto exit_program; 93 } 94 } 95 if (e->type == RV_EVENT_WINDOW_RESIZE) { 96 // set viewport 97 rv_command_t* viewport = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_SET_VIEWPORT); 98 viewport->viewport = rv_v4(.xy = {0, 0}, .zw = rv_window_size(window)); 99 } 100 } 101 102 103 { // clear 104 rv_command_t* clear = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_CLEAR); 105 rv_render_clear_desc_t* clear_desc = rv_render_push_clear_desc(scratch.arena, clear, RV_RENDER_CLEAR_FLAG_COLOR); 106 clear_desc->color_v = rv_v4(0.1, 0.1, 0.1, 1.0); 107 } 108 109 { // draw custom shader 110 111 // copy render commands 112 rv_command_t* rcmd = rv_render_copy_commands(scratch.arena, &rpass->commands, &render_instructions); 113 114 // find the pipeline command 115 rv_command_t* pipeline_cmd = rcmd; 116 for (; pipeline_cmd; pipeline_cmd = pipeline_cmd->next) { 117 if (rv_command_has_pipeline(pipeline_cmd, pip)) break; 118 } 119 120 if (pipeline_cmd) { 121 // add uniform updates 122 const f64 t = rv_time(); 123 const f32 r = sinf(t) * 0.5f + 0.5f; 124 const f32 g = cosf(t * 6.f) * 0.5f + 0.5f; 125 const f32 b = sinf(t * 3.f) * 0.5f + 0.5f; 126 rv_cmd_insert_uniform_update(scratch.arena, &rpass->commands, pipeline_cmd, u_color, {.v_vec3 = rv_v3(r, g, b)}); 127 128 const f32 st = sin(t); 129 rv_mat4 rot = rv_mat4_rotatev(t, RV_ZAXIS); 130 rv_mat4 scl = rv_mat4_scalev(rv_v3(st, st, st)); 131 rv_mat4 model = rv_mat4_mul_list(2, scl, rot); 132 rv_command_t* update_u_model = rv_cmd_insert_type(scratch.arena, &rpass->commands, pipeline_cmd, RV_COMMAND_UNIFORM_UPDATE); 133 update_u_model->uniform_update.desc = u_model; 134 update_u_model->uniform_update.value.v_mat4 = model; 135 } 136 } 137 138 if (window) { // render screen 139 rv_window_render_commit(window, &rpass_list); 140 } 141 rv_scratch_end(scratch); 142 rpass_list = (rv_render_pass_list_t){0}; 143 } 144 exit_program: 145 146 return 0; 147 }