예제 #1
0
	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();
	}
예제 #2
0
	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();
	}
예제 #3
0
	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));
			}
		}
	}
예제 #4
0
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);
}
예제 #5
0
	void sprite::update_size_from_texture_dimensions() {
		size = vec2i(get_resource_manager().find(tex)->tex.get_size());
	}
예제 #6
0
	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());
	}