/* * Implementation of render target for debug rendering */ // TOP #include "cd_random.h" #include "cd_world.h" struct Game_Renderer_Vars{ Partition part; b32 initialized; }; inline void do_quad(u32 texture_id, vec4 color, vec2 center, vec2 half_x, vec2 half_y, f32 s, f32 t){ vec2 p; glBindTexture(GL_TEXTURE_2D, texture_id); glColor4f(color.r, color.g, color.b, color.a); glBegin(GL_QUADS); { p = center - half_x + half_y; glTexCoord2f(0.f, t); glVertex2f(p.x, p.y); p = center + half_x + half_y; glTexCoord2f(s, t); glVertex2f(p.x, p.y); p = center + half_x - half_y; glTexCoord2f(s, 0.f); glVertex2f(p.x, p.y); p = center - half_x - half_y; glTexCoord2f(0.f, 0.f); glVertex2f(p.x, p.y); } glEnd(); } Render_Execute_Sig(game_render_execute){ Game_Renderer_Vars *vars = (Game_Renderer_Vars*)target->memory; if (!vars->initialized){ vars->initialized = true; vars->part = make_partition(target->memory, target->memory_size); push_type(&vars->part, Game_Renderer_Vars); } Transform me_to_pixel = target->me_to_pixel_transform; Partition *part = &vars->part; Temp_Memory temp = begin_temp(part); f32 *lane_y = push_array(part, f32, total_lanes); for (i32 i = 0; i < total_lanes; ++i){ lane_y[i] = -5000.f; } glClearColor(0.f, 0.f, 0.f, 1.f); glClear(GL_COLOR_BUFFER_BIT); Render_Command_Header *h; for (h = (Render_Command_Header*)target->push_part.base; h->type; h = NextHeader(h)){ switch (h->type){ case render_lane: { Render_Lane *l = (Render_Lane*)(h + 1); lane_y[l->lane_index] = l->y_position; }break; case render_obstacle: { Render_Obstacle *o = (Render_Obstacle*)(h + 1); Random_Series randgen = random_seed(o->seed); Image *image = 0; u32 image_id = 0; f32 theta = random_between(&randgen, 0.0f, 0.3f); theta *= theta * o->x; theta += random_between(&randgen, 0.f, 6.2f); if (random_unilateral(&randgen) > 0.7f){ theta *= -1.f; } f32 scale = 0.5f; switch (o->type){ case ET_Obstacle: image_id = ASTEROID1 + random_choice(&randgen, 6); scale = 0.4f; break; } image = get_image(bank, image_id); if (image){ vec2 center = v2(o->x, lane_y[o->lane]); vec2 half_x = v2(image->width*scale, 0); vec2 half_y = v2(0, image->height*scale); f32 s = image->tex_x; f32 t = image->tex_y; center = do_transform(center, me_to_pixel); Basis rotation = get_rotation(theta); half_x = do_basis(half_x, rotation); half_y = do_basis(half_y, rotation); do_quad(image->texture_id, v4(1.f, 1.f, 1.f, 1.f), center, half_x, half_y, s, t); } }break; case render_image: { Render_Image *i = (Render_Image*)(h + 1); Image *image = get_image(bank, i->image_id); if (image){ vec2 center = i->transform.pos; vec2 half_x = i->transform.basis.x; vec2 half_y = i->transform.basis.y; f32 s = image->tex_x; f32 t = image->tex_y; center = do_transform(center, me_to_pixel); do_quad(image->texture_id, v4(1.f, 1.f, 1.f, 1.f), center, half_x, half_y, s, t); } }break; } } end_temp(temp); // NOTE(allen): In dev mode multiple renderers may // be used in each frame so clearing the depth buffer // when everything is done keeps everything in order. #ifdef DEVELOPER glClearDepth(1.f); #endif } Render_Get_Functions_Sig(target_get_functions){ target->execute = game_render_execute; target->init = init; target->display = display; target->set_screen = set_screen; } Bank_Get_Functions_Sig(bank_get_functions){ bank->begin_setup = begin_setup; bank->end_setup = end_setup; bank->bind_font = bind_font; bank->bind_bmp = bind_bmp; bank->replace_bmp = replace_bmp; } // BOTTOM