simple_texture.c (6328B)
1 ////////////////////////////////////////////////////////////////// 2 // simple_texture.c 3 4 #include "revolver_inc.h" 5 #include "revolver_inc.c" 6 7 #define ROW_COL_CT 14 8 9 ////////////////////////////////////////////////////////////////// 10 // data 11 12 // Vertex data for quad 13 f32 v_data[] = { 14 // Positions UVs 15 -0.5f, -0.5f, 0.0f, 0.0f, // Top Left 16 0.5f, -0.5f, 1.0f, 0.0f, // Top Right 17 -0.5f, 0.5f, 0.0f, 1.0f, // Bottom Left 18 0.5f, 0.5f, 1.0f, 1.0f // Bottom Right 19 }; 20 21 // Index data for quad 22 uint32_t i_data[] = { 23 0, 1, 2, // First Triangle 24 1, 2, 3 // Second Triangle 25 }; 26 27 rv_str8 v_src = S("#version 330 core\n" rv_strify( 28 layout(location = 0) in vec2 a_pos; 29 layout(location = 1) in vec2 a_uv; 30 precision mediump float; 31 out vec2 uv; 32 void main() 33 { 34 gl_Position = vec4(a_pos, 0.0, 1.0); 35 uv = a_uv; 36 } 37 )); 38 39 rv_str8 f_src = S("#version 330 core\n" rv_strify( 40 precision mediump float; 41 uniform sampler2D u_tex; 42 in vec2 uv; 43 out vec4 frag_color; 44 void main() 45 { 46 frag_color = texture(u_tex, uv); 47 } 48 )); 49 50 ////////////////////////////////////////////////////////////////// 51 52 53 int main(void) { 54 rv_window_desc_t desc = {.name = S("App"), .attach_render = true}; 55 rv_window_handle_t* window = rv_create_window(desc); 56 57 rv_arena* arena = rv_arena_alloc(); 58 rv_render_pass_list_t rpass_list = {0}; 59 60 61 // Generate procedural texture data (checkered texture) 62 rv_color_t c0 = RV_COLOR_BLACK; 63 rv_color_t c1 = RV_COLOR_BLUE; 64 rv_color_t pixels[ROW_COL_CT * ROW_COL_CT] = {0}; 65 for (uint32_t r = 0; r < ROW_COL_CT; ++r) { 66 for (uint32_t c = 0; c < ROW_COL_CT; ++c) { 67 const bool32 re = (r % 2) == 0; 68 const bool32 ce = (c % 2) == 0; 69 uint32_t idx = r * ROW_COL_CT + c; 70 pixels[idx] = (re && ce) ? c0 : (re) ? c1 : (ce) ? c1 : c0; 71 } 72 } 73 74 // make render objects 75 rv_texture_t* tex = rv_push_compound(arena, rv_texture_t, {.data = pixels, .size = rv_v2s(ROW_COL_CT)}); 76 rv_vbo_t* vbo = rv_push_compound(arena, rv_vbo_t, {.data = v_data, .size = sizeof(v_data)}); 77 rv_vbo_t* ibo = rv_push_compound(arena, rv_ibo_t, {.data = i_data, .size = sizeof(i_data), .elem_size = sizeof(i_data[0])}); 78 rv_shader_t* vertex = rv_push_compound(arena, rv_shader_t, {.source = v_src, .type = RV_SHADER_TYPE_VERTEX}); 79 rv_shader_t* fragment = rv_push_compound(arena, rv_shader_t, {.source = f_src, .type = RV_SHADER_TYPE_FRAGMENT}); 80 rv_pipeline_t* pip = rv_push(arena, rv_pipeline_t); 81 82 // construct pipeline 83 rv_pipeline_push_shader(arena, pip, vertex); 84 rv_pipeline_push_shader(arena, pip, fragment); 85 rv_pipeline_push_vattr(arena, pip, RV_VATTR_TYPE_FLOAT2, 0, 0); 86 rv_pipeline_push_vattr(arena, pip, RV_VATTR_TYPE_FLOAT2, 0, 0); 87 rv_uniform_t* u_tex = rv_pipeline_push_uniform(arena, pip, S("u_tex"), RV_UNIFORM_TEX); 88 89 // instructions to create render objects 90 rv_command_list_t create_instructions = {0}; 91 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_TEXTURE, RV_RENDER_OBJ_OP_CREATE, tex); 92 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_CREATE, vbo); 93 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_INDEX, RV_RENDER_OBJ_OP_CREATE, ibo); 94 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER, RV_RENDER_OBJ_OP_CREATE, vertex); 95 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_SHADER, RV_RENDER_OBJ_OP_CREATE, fragment); 96 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_CREATE, pip); 97 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, pip); 98 rv_cmd_push_uniform_update(arena, &create_instructions, u_tex, {.v_tex = tex}); 99 rv_cmd_push_obj(arena, &create_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, NULL); 100 101 // instructions to render 102 rv_command_list_t render_instructions = {0}; 103 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, pip); 104 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_VERTEX, RV_RENDER_OBJ_OP_BIND, vbo); 105 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_INDEX, RV_RENDER_OBJ_OP_BIND, ibo); 106 rv_cmd_push_type(arena, &render_instructions, RV_COMMAND_DRAW)->draw.count = 6; 107 rv_cmd_push_obj(arena, &render_instructions, RV_COMMAND_OBJ_PIPELINE, RV_RENDER_OBJ_OP_BIND, NULL); 108 109 // copy over create commands 110 rv_render_pass_t* create_rpass = rv_render_push_render_pass(arena, &rpass_list); 111 rv_render_copy_commands(arena, &create_rpass->commands, &create_instructions); 112 113 114 while(1) { 115 rv_temp_arena scratch = rv_scratch_begin(0, 0); 116 117 // pick renderpass 118 rv_render_pass_t* rpass = rv_render_push_render_pass(scratch.arena, &rpass_list); 119 120 // process events 121 for (rv_event_t* e = rv_get_events(scratch.arena, 0); e; e = e->next) { 122 if (e->type == RV_EVENT_WINDOW_CLOSE) { 123 if (e->window_close == window) { 124 goto exit_program; 125 } 126 } 127 if (e->type == RV_EVENT_WINDOW_RESIZE) { 128 // set viewport 129 rv_command_t* viewport = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_SET_VIEWPORT); 130 viewport->viewport = rv_v4(.xy = {0, 0}, .zw = rv_window_size(window)); 131 } 132 } 133 134 { // clear 135 rv_command_t* clear = rv_cmd_push_type(scratch.arena, &rpass->commands, RV_COMMAND_CLEAR); 136 rv_render_clear_desc_t* clear_desc = rv_render_push_clear_desc(scratch.arena, clear, RV_RENDER_CLEAR_FLAG_COLOR); 137 clear_desc->color_v = rv_v4(0.1, 0.1, 0.1, 1.0); 138 } 139 140 { // draw custom shader 141 // copy render commands 142 rv_render_copy_commands(scratch.arena, &rpass->commands, &render_instructions); 143 } 144 145 if (window) { // render screen 146 rv_window_render_commit(window, &rpass_list); 147 } 148 rv_scratch_end(scratch); 149 rpass_list = (rv_render_pass_list_t){0}; 150 } 151 exit_program: 152 153 return 0; 154 }