void sprite::set(const assets::texture_id _tex, const rgba _color) { tex = _tex; color = _color; has_neon_map = get_resource_manager().find_neon_map(tex) != nullptr; update_size_from_texture_dimensions(); }
void load_standard_behaviour_trees() { auto& soldier_movement = get_resource_manager().create(assets::behaviour_tree_id::SOLDIER_MOVEMENT); soldier_movement.root.mode = resources::behaviour_tree::node::type::SELECTOR; soldier_movement.root.branch( new behaviours::immediate_evasion, new behaviours::minimize_recoil_through_movement, new behaviours::navigate_to_last_seen_position_of_target, new behaviours::explore_in_search_for_last_seen_target ); soldier_movement.build_tree(); auto& hands_actor = get_resource_manager().create(assets::behaviour_tree_id::HANDS_ACTOR); hands_actor.root.branch(new behaviours::pull_trigger); hands_actor.root; hands_actor.build_tree(); auto& item_picker = get_resource_manager().create(assets::behaviour_tree_id::ITEM_PICKER); //item_picker.root.branch(new behaviours::usable_item_marker); item_picker.build_tree(); auto& inventory_actor = get_resource_manager().create(assets::behaviour_tree_id::INVENTORY_ACTOR); inventory_actor.root; inventory_actor.build_tree(); auto& hostile_target_prioritization = get_resource_manager().create(assets::behaviour_tree_id::HOSTILE_TARGET_PRIORITIZATION); hostile_target_prioritization.root.branch(new behaviours::target_closest_enemy); hostile_target_prioritization.build_tree(); }
void sprite::draw(const drawing_input& in) const { ensure(tex != assets::texture_id::INVALID); vec2i transform_pos = in.renderable_transform.pos; const float final_rotation = in.renderable_transform.rotation + rotation_offset; auto screen_space_pos = in.camera[transform_pos]; const auto drawn_size = size*size_multiplier; if (center_offset.non_zero()) { screen_space_pos -= vec2(center_offset).rotate(final_rotation, vec2(0, 0)); } if (in.drawing_type == renderable_drawing_type::NEON_MAPS && has_neon_map) { draw(in, get_resource_manager().find_neon_map(tex)->tex, screen_space_pos, final_rotation, vec2(get_resource_manager().find_neon_map(tex)->tex.get_size()) / vec2(get_resource_manager().find(tex)->tex.get_size()) * drawn_size); } else if (in.drawing_type == renderable_drawing_type::NORMAL) { draw(in, get_resource_manager().find(tex)->tex, screen_space_pos, final_rotation, drawn_size); } else if (in.drawing_type == renderable_drawing_type::SPECULAR_HIGHLIGHTS) { const auto& anim = *get_resource_manager().find(assets::animation_id::BLINK_ANIMATION); const auto frame_duration_ms = static_cast<unsigned>(anim.frames[0].duration_milliseconds); const auto frame_count = anim.frames.size(); const auto animation_max_duration = frame_duration_ms * frame_count; for (unsigned m = 0; m < max_specular_blinks; ++m) { const auto total_ms = static_cast<unsigned>(in.global_time_seconds * 1000 + (animation_max_duration / max_specular_blinks) * m); const auto spatial_hash = std::hash<vec2>()(in.renderable_transform.pos); std::minstd_rand0 generator(spatial_hash + m*30 + total_ms / animation_max_duration); const unsigned animation_current_ms = total_ms % (animation_max_duration); const auto& target_frame = anim.frames[animation_current_ms / frame_duration_ms]; vec2i blink_offset = { int(generator() % unsigned(drawn_size.x)), int(generator() % unsigned(drawn_size.y)) }; blink_offset -= drawn_size / 2; draw(in, get_resource_manager().find(target_frame.sprite.tex)->tex, screen_space_pos + blink_offset, final_rotation, assets::get_size(target_frame.sprite.tex)); } } }
void light_system::render_all_lights(augs::renderer& output, const std::array<float, 16> projection_matrix, const viewing_step step, std::function<void()> neon_callback) { const auto& cosmos = step.cosm; const auto dt = step.get_delta(); const float global_time_seconds = static_cast<float>(step.get_interpolated_total_time_passed_in_seconds()); ensure_eq(0, output.get_triangle_count()); output.light_fbo.use(); glClearColor(0.1f, 0.2f, 0.2f, 1.0f); output.clear_current_fbo(); glClearColor(0.f, 0.f, 0.f, 0.f); auto& light_program = *get_resource_manager().find(assets::program_id::LIGHT); auto& default_program = *get_resource_manager().find(assets::program_id::DEFAULT); light_program.use(); const auto light_pos_uniform = glGetUniformLocation(light_program.id, "light_pos"); const auto light_max_distance_uniform = glGetUniformLocation(light_program.id, "max_distance"); const auto light_attenuation_uniform = glGetUniformLocation(light_program.id, "light_attenuation"); const auto light_multiply_color_uniform = glGetUniformLocation(light_program.id, "multiply_color"); const auto projection_matrix_uniform = glGetUniformLocation(light_program.id, "projection_matrix"); const auto& interp = step.session.systems_audiovisual.get<interpolation_system>(); const auto& particles = step.session.systems_audiovisual.get<particles_simulation_system>(); const auto& visible_per_layer = step.visible.per_layer; std::vector<messages::visibility_information_request> requests; std::vector<messages::visibility_information_response> responses; glUniformMatrix4fv(projection_matrix_uniform, 1, GL_FALSE, projection_matrix.data()); for (const auto it : cosmos.get(processing_subjects::WITH_LIGHT)) { messages::visibility_information_request request; request.eye_transform = it.viewing_transform(interp); request.filter = filters::line_of_sight_query(); request.square_side = it.get<components::light>().max_distance.base_value; request.subject = it; requests.push_back(request); } { std::vector<messages::line_of_sight_response> dummy; visibility_system().respond_to_visibility_information_requests(cosmos, {}, requests, dummy, responses); } const auto camera_transform = step.camera.transform; const auto camera_size = step.camera.visible_world_area; const auto camera_offset = -camera_transform.pos + camera_size / 2; glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE); glerr; for (size_t i = 0; i < responses.size(); ++i) { const auto& r = responses[i]; const auto& light_entity = cosmos[requests[i].subject]; const auto& light = light_entity.get<components::light>(); auto& cache = per_entity_cache[light_entity.get_id().pool.indirection_index]; const float delta = dt.in_seconds(); light.constant.variation.update_value(rng, cache.all_variation_values[0], delta); light.linear.variation.update_value(rng, cache.all_variation_values[1], delta); light.quadratic.variation.update_value(rng, cache.all_variation_values[2], delta); light.wall_constant.variation.update_value(rng, cache.all_variation_values[3], delta); light.wall_linear.variation.update_value(rng, cache.all_variation_values[4], delta); light.wall_quadratic.variation.update_value(rng, cache.all_variation_values[5], delta); light.position_variations[0].update_value(rng, cache.all_variation_values[6], delta); light.position_variations[1].update_value(rng, cache.all_variation_values[7], delta); for (size_t t = 0; t < r.get_num_triangles(); ++t) { const auto world_light_tri = r.get_world_triangle(t, requests[i].eye_transform.pos); augs::vertex_triangle renderable_light_tri; renderable_light_tri.vertices[0].pos = world_light_tri.points[0] + camera_offset; renderable_light_tri.vertices[1].pos = world_light_tri.points[1] + camera_offset; renderable_light_tri.vertices[2].pos = world_light_tri.points[2] + camera_offset; auto considered_color = light.color; if (considered_color == black) { considered_color.set_hsv({ fmod(global_time_seconds / 16.f, 1.f), 1.0, 1.0 }); } renderable_light_tri.vertices[0].color = considered_color; renderable_light_tri.vertices[1].color = considered_color; renderable_light_tri.vertices[2].color = considered_color; output.push_triangle(renderable_light_tri); } //for (size_t d = 0; d < r.get_num_discontinuities(); ++d) { // const auto world_discontinuity = *r.get_discontinuity(d); // // if (!world_discontinuity.is_boundary) { // vertex_triangle renderable_light_tri; // // const float distance_from_light = (requests[i].eye_transform.pos - world_discontinuity.points.first).length(); // const float angle = 80.f / ((distance_from_light+0.1f)/50.f); // // //(requests[i].eye_transform.pos - world_discontinuity.points.first).length(); // // if (world_discontinuity.winding == world_discontinuity.RIGHT) { // renderable_light_tri.vertices[0].pos = world_discontinuity.points.first + camera_offset; // renderable_light_tri.vertices[1].pos = world_discontinuity.points.second + camera_offset; // renderable_light_tri.vertices[2].pos = vec2(world_discontinuity.points.second).rotate(-angle, world_discontinuity.points.first) + camera_offset; // } // else { // renderable_light_tri.vertices[0].pos = world_discontinuity.points.first + camera_offset; // renderable_light_tri.vertices[1].pos = world_discontinuity.points.second + camera_offset; // renderable_light_tri.vertices[2].pos = vec2(world_discontinuity.points.second).rotate(angle, world_discontinuity.points.first) + camera_offset; // } // // renderable_light_tri.vertices[0].color = light.color; // renderable_light_tri.vertices[1].color = light.color; // renderable_light_tri.vertices[2].color = light.color; // // output.push_triangle(renderable_light_tri); // } //} vec2 light_displacement = vec2(cache.all_variation_values[6], cache.all_variation_values[7]); auto screen_pos = requests[i].eye_transform - camera_transform; screen_pos.pos.x += camera_size.x * 0.5f; screen_pos.pos.y = camera_size.y - (screen_pos.pos.y + camera_size.y * 0.5f); screen_pos += light_displacement; glUniform2f(light_pos_uniform, screen_pos.pos.x, screen_pos.pos.y); glUniform1f(light_max_distance_uniform, light.max_distance.base_value); glUniform3f(light_attenuation_uniform, cache.all_variation_values[0] + light.constant.base_value, cache.all_variation_values[1] + light.linear.base_value, cache.all_variation_values[2] + light.quadratic.base_value ); glUniform3f(light_multiply_color_uniform, 1.f, 1.f, 1.f); output.call_triangles(); output.clear_triangles(); light_program.use(); glUniform1f(light_max_distance_uniform, light.wall_max_distance.base_value); glUniform3f(light_attenuation_uniform, cache.all_variation_values[3] + light.wall_constant.base_value, cache.all_variation_values[4] + light.wall_linear.base_value, cache.all_variation_values[5] + light.wall_quadratic.base_value ); glUniform3f(light_multiply_color_uniform, light.color.r/255.f, light.color.g/255.f, light.color.b/255.f); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::DYNAMIC_BODY], step.camera, renderable_drawing_type::NORMAL); output.call_triangles(); output.clear_triangles(); glUniform3f(light_multiply_color_uniform, 1.f, 1.f, 1.f); } default_program.use(); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::DYNAMIC_BODY], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::SMALL_DYNAMIC_BODY], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::FLYING_BULLETS], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::CAR_INTERIOR], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::CAR_WHEEL], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::EFFECTS], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::ON_GROUND], step.camera, renderable_drawing_type::NEON_MAPS); render_system().draw_entities(interp, global_time_seconds,output.triangles, visible_per_layer[render_layer::ON_TILED_FLOOR], step.camera, renderable_drawing_type::NEON_MAPS); { particles_simulation_system::drawing_input in(output.triangles); in.camera = step.camera; in.drawing_type = renderable_drawing_type::NEON_MAPS; particles.draw(render_layer::EFFECTS, in); } neon_callback(); output.call_triangles(); output.clear_triangles(); glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); glerr; augs::graphics::fbo::use_default(); output.set_active_texture(2); output.bind_texture(output.light_fbo); output.set_active_texture(0); }
void sprite::update_size_from_texture_dimensions() { size = vec2i(get_resource_manager().find(tex)->tex.get_size()); }
void standard_rendering(const viewing_step step) { const auto& camera = step.camera; auto& renderer = step.renderer; auto& output = renderer.triangles; const auto& cosmos = step.cosm; const auto& controlled_entity = cosmos[step.viewed_character]; const auto& interp = step.session.systems_audiovisual.get<interpolation_system>(); const float global_time_seconds = static_cast<float>(step.get_interpolated_total_time_passed_in_seconds()); const auto& visible_per_layer = step.visible.per_layer; const auto matrix = augs::orthographic_projection<float>(0, camera.visible_world_area.x, camera.visible_world_area.y, 0, 0, 1); auto& default_shader = *get_resource_manager().find(assets::program_id::DEFAULT); auto& pure_color_highlight_shader = *get_resource_manager().find(assets::program_id::PURE_COLOR_HIGHLIGHT); auto& border_highlight_shader = pure_color_highlight_shader; // the same auto& circular_bars_shader = *get_resource_manager().find(assets::program_id::CIRCULAR_BARS); default_shader.use(); { const auto projection_matrix_uniform = glGetUniformLocation(default_shader.id, "projection_matrix"); glUniformMatrix4fv(projection_matrix_uniform, 1, GL_FALSE, matrix.data()); } for (int i = render_layer::UNDER_GROUND; i > render_layer::DYNAMIC_BODY; --i) { render_system().draw_entities(interp, global_time_seconds,output, visible_per_layer[i], camera, renderable_drawing_type::NORMAL); } renderer.call_triangles(); renderer.clear_triangles(); border_highlight_shader.use(); { const auto projection_matrix_uniform = glGetUniformLocation(border_highlight_shader.id, "projection_matrix"); glUniformMatrix4fv(projection_matrix_uniform, 1, GL_FALSE, matrix.data()); } render_system().draw_entities(interp, global_time_seconds,output, visible_per_layer[render_layer::SMALL_DYNAMIC_BODY], camera, renderable_drawing_type::BORDER_HIGHLIGHTS); renderer.call_triangles(); renderer.clear_triangles(); default_shader.use(); for (int i = render_layer::DYNAMIC_BODY; i >= 0; --i) { render_system().draw_entities(interp, global_time_seconds,output, visible_per_layer[i], camera, renderable_drawing_type::NORMAL); } renderer.call_triangles(); renderer.clear_triangles(); circular_bars_shader.use(); { const auto projection_matrix_uniform = glGetUniformLocation(circular_bars_shader.id, "projection_matrix"); glUniformMatrix4fv(projection_matrix_uniform, 1, GL_FALSE, matrix.data()); vec2 upper(0.0f, 0.0f); vec2 lower(1.0f, 1.0f); (*assets::texture_id::HUD_CIRCULAR_BAR_MEDIUM).get_uv(upper); (*assets::texture_id::HUD_CIRCULAR_BAR_MEDIUM).get_uv(lower); const auto center = (upper + lower) / 2; glUniform2f(glGetUniformLocation(circular_bars_shader.id, "texture_center"), center.x, center.y); } const auto& hud = step.session.hud; const auto& textual_infos = hud.draw_circular_bars_and_get_textual_info(step); renderer.call_triangles(); renderer.clear_triangles(); default_shader.use(); renderer.call_triangles(textual_infos); pure_color_highlight_shader.use(); hud.draw_pure_color_highlights(step); renderer.call_triangles(); renderer.clear_triangles(); default_shader.use(); hud.draw_vertically_flying_numbers(step); if (controlled_entity.has<components::gui_element>()) { components::gui_element::draw_complete_gui_for_camera_rendering_request(output, controlled_entity, step); } renderer.bind_texture(*get_resource_manager().find(assets::atlas_id::GAME_WORLD_ATLAS)); renderer.call_triangles(); renderer.clear_triangles(); renderer.draw_debug_info( camera.visible_world_area, camera.transform, assets::texture_id::BLANK, {}, step.get_delta().view_interpolation_ratio()); }