Ejemplo n.º 1
0
void Sprite_Impl::draw(Canvas &canvas, const Rect &p_src, const Pointf &p_dest, const Pointf &p_scale)
{
	SpriteFrame &frame = frames[current_frame];

	// Find size of surface:
	float src_width  = (float) p_src.get_width();
	float src_height = (float) p_src.get_height();

	// Calculate translation hotspot
	Pointf target_translation_hotspot = calc_hotspot(
		translation_origin,
		(float) (translation_hotspot.x + frame.offset.x),
		(float) (translation_hotspot.y + frame.offset.y),
		src_width,
		src_height);

	// Calculate rotation hotspot:
	Pointf target_rotation_hotspot = calc_hotspot(
		rotation_origin,
		(float) (rotation_hotspot.x + frame.offset.x),
		(float) (rotation_hotspot.y + frame.offset.y),
		src_width,
		src_height);

	// Find top left point of destination rectangle and map rotation hotspot to screen coordinates:
	float destWidth = src_width * p_scale.x;
	float destHeight = src_height * p_scale.y;
	float pixDestX = p_dest.x -target_translation_hotspot.x * p_scale.x;
	float pixDestY = p_dest.y -target_translation_hotspot.y * p_scale.y;
	target_rotation_hotspot.x = float(pixDestX + target_rotation_hotspot.x * p_scale.x);
	target_rotation_hotspot.y = float(pixDestY + target_rotation_hotspot.y * p_scale.y);

	// Calculate unit vectors for rotated surface:
	// (cached for speed reasons)
	static float vect_rotate_x[2] = { 1.0f, 0.0f };
	static float vect_rotate_y[2] = { 0.0f, 1.0f };
	static Angle last_angle(0, angle_radians);

	Angle target_rotate_angle = angle - base_angle;
	if (last_angle != target_rotate_angle)
	{
		float angle_degrees = target_rotate_angle.to_degrees();
		if (angle_degrees == 0.0f)
		{
			vect_rotate_x[0] = 1.0;
			vect_rotate_x[1] = 0.0;
			vect_rotate_y[0] = 0.0;
			vect_rotate_y[1] = 1.0;
		}
		else if (angle_degrees == 90.0f)
		{
			vect_rotate_x[0] = 0.0;
			vect_rotate_x[1] = 1.0;
			vect_rotate_y[0] = -1.0;
			vect_rotate_y[1] = 0.0;
		}
		else if (angle_degrees == 180.0f)
		{
			vect_rotate_x[0] = -1.0;
			vect_rotate_x[1] = 0.0;
			vect_rotate_y[0] = 0.0;
			vect_rotate_y[1] = -1.0;
		}
		else if (angle_degrees == 270.0f)
		{
			vect_rotate_x[0] = 0.0;
			vect_rotate_x[1] = -1.0;
			vect_rotate_y[0] = 1.0;
			vect_rotate_y[1] = 0.0;
		}
		else
		{
			float angle_rad = target_rotate_angle.to_radians();
			vect_rotate_x[0] = cos(angle_rad);
			vect_rotate_x[1] = sin(angle_rad);
			vect_rotate_y[0] = cos(PI/2+angle_rad);
			vect_rotate_y[1] = sin(PI/2+angle_rad);
		}
	}

	// Calculate final source rectangle points for render:
	const Texture2D &texture = frames[current_frame].texture;
	float texture_width = texture.get_width();
	float texture_height = texture.get_height();

	Pointf texture_position[4];	// Scaled to the range of 0.0f to 1.0f
	Pointf dest_position[4];

	texture_position[0].x = (((float) p_src.left) ) / texture_width;
	texture_position[1].x = (((float) p_src.left+src_width) ) / texture_width;
	texture_position[2].x = (((float) p_src.left) ) / texture_width;
	texture_position[3].x = (((float) p_src.left+src_width) ) / texture_width;

	texture_position[0].y = (((float) p_src.top) ) / texture_height;
	texture_position[1].y = (((float) p_src.top) ) / texture_height;
	texture_position[2].y = (((float) p_src.top+src_height) ) / texture_height;
	texture_position[3].y = (((float) p_src.top+src_height) ) / texture_height;

	// Calculate final destination rectangle points for surface rectangle:
	if (target_rotate_angle.to_radians() == 0.0f)
	{
		dest_position[0].x = pixDestX;
		dest_position[1].x = pixDestX+destWidth;
		dest_position[2].x = pixDestX;
		dest_position[3].x = pixDestX+destWidth;

		dest_position[0].y = pixDestY;
		dest_position[1].y = pixDestY;
		dest_position[2].y = pixDestY+destHeight;
		dest_position[3].y = pixDestY+destHeight;
	}
	else
	{
		// Roll
		dest_position[0].x = calc_rotate_x(pixDestX, pixDestY, target_rotation_hotspot.x, target_rotation_hotspot.y, vect_rotate_x[0], vect_rotate_y[0]);
		dest_position[1].x = calc_rotate_x(pixDestX+destWidth, pixDestY, target_rotation_hotspot.x, target_rotation_hotspot.y, vect_rotate_x[0], vect_rotate_y[0]);
		dest_position[2].x = calc_rotate_x(pixDestX, pixDestY+destHeight, target_rotation_hotspot.x, target_rotation_hotspot.y, vect_rotate_x[0], vect_rotate_y[0]);
		dest_position[3].x = calc_rotate_x(pixDestX+destWidth, pixDestY+destHeight, target_rotation_hotspot.x, target_rotation_hotspot.y, vect_rotate_x[0], vect_rotate_y[0]);

		dest_position[0].y = calc_rotate_y(pixDestX, pixDestY, target_rotation_hotspot.x, target_rotation_hotspot.y, vect_rotate_x[1], vect_rotate_y[1]);
		dest_position[1].y = calc_rotate_y(pixDestX+destWidth, pixDestY, target_rotation_hotspot.x, target_rotation_hotspot.y, vect_rotate_x[1], vect_rotate_y[1]);
		dest_position[2].y = calc_rotate_y(pixDestX, pixDestY+destHeight, target_rotation_hotspot.x, target_rotation_hotspot.y, vect_rotate_x[1], vect_rotate_y[1]);
		dest_position[3].y = calc_rotate_y(pixDestX+destWidth, pixDestY+destHeight, target_rotation_hotspot.x, target_rotation_hotspot.y, vect_rotate_x[1], vect_rotate_y[1]);
	}

	RenderBatchTriangle *batcher = canvas.impl->batcher.get_triangle_batcher();
	batcher->draw_sprite(canvas, texture_position, dest_position, frames[current_frame].texture, color);

}
Ejemplo n.º 2
0
void CL_Sprite_Impl::draw_calcs_step2(
	const CL_Surface_DrawParams2 & params2,
	const CL_Surface_TargetDrawParams1 *t_params1,
	CL_Surface_DrawParams1 &params1)
{
	// Calculate unit vectors for rotated surface:
	// (cached for speed reasons)
	static float vect_rotate_x[2] = { 1.0f, 0.0f };
	static float vect_rotate_y[2] = { 0.0f, 1.0f };
	static CL_Angle last_angle(0, cl_radians);

	if (last_angle != params2.rotate_angle)
	{
		if (params2.rotate_angle.to_degrees() == 0.0f)
		{
			vect_rotate_x[0] = 1.0;
			vect_rotate_x[1] = 0.0;
			vect_rotate_y[0] = 0.0;
			vect_rotate_y[1] = 1.0;
		}
		else if (params2.rotate_angle.to_degrees() == 90.0f)
		{
			vect_rotate_x[0] = 0.0;
			vect_rotate_x[1] = 1.0;
			vect_rotate_y[0] = -1.0;
			vect_rotate_y[1] = 0.0;
		}
		else if (params2.rotate_angle.to_degrees() == 180.0f)
		{
			vect_rotate_x[0] = -1.0;
			vect_rotate_x[1] = 0.0;
			vect_rotate_y[0] = 0.0;
			vect_rotate_y[1] = -1.0;
		}
		else if (params2.rotate_angle.to_degrees() == 270.0f)
		{
			vect_rotate_x[0] = 0.0;
			vect_rotate_x[1] = -1.0;
			vect_rotate_y[0] = 1.0;
			vect_rotate_y[1] = 0.0;
		}
		else
		{
			float angle_rad = params2.rotate_angle.to_radians();
			vect_rotate_x[0] = cos(angle_rad);
			vect_rotate_x[1] = sin(angle_rad);
			vect_rotate_y[0] = cos(CL_PI/2+angle_rad);
			vect_rotate_y[1] = sin(CL_PI/2+angle_rad);
		}
	}

	// Calculate final source rectangle points for render:
	const CL_Texture &texture = frames[current_frame].texture;
	float texture_width = texture.get_width();
	float texture_height = texture.get_height();

	params1.texture_position[0].x = (((float) params2.srcX) ) / texture_width;
	params1.texture_position[1].x = (((float) params2.srcX+params2.srcWidth) ) / texture_width;
	params1.texture_position[2].x = (((float) params2.srcX) ) / texture_width;
	params1.texture_position[3].x = (((float) params2.srcX+params2.srcWidth) ) / texture_width;

	params1.texture_position[0].y = (((float) params2.srcY) ) / texture_height;
	params1.texture_position[1].y = (((float) params2.srcY) ) / texture_height;
	params1.texture_position[2].y = (((float) params2.srcY+params2.srcHeight) ) / texture_height;
	params1.texture_position[3].y = (((float) params2.srcY+params2.srcHeight) ) / texture_height;

	// Calculate final destination rectangle points for surface rectangle:
	if (params2.rotate_angle.to_radians() == 0.0f)
	{
		params1.dest_position[0].x = t_params1->pixDestX;
		params1.dest_position[1].x = t_params1->pixDestX+t_params1->destWidth;
		params1.dest_position[2].x = t_params1->pixDestX;
		params1.dest_position[3].x = t_params1->pixDestX+t_params1->destWidth;

		params1.dest_position[0].y = t_params1->pixDestY;
		params1.dest_position[1].y = t_params1->pixDestY;
		params1.dest_position[2].y = t_params1->pixDestY+t_params1->destHeight;
		params1.dest_position[3].y = t_params1->pixDestY+t_params1->destHeight;
	}
	else
	{
		// Roll
		params1.dest_position[0].x = calc_rotate_x(t_params1->pixDestX, t_params1->pixDestY, t_params1->rotation_hotspot.x, t_params1->rotation_hotspot.y, vect_rotate_x[0], vect_rotate_y[0]);
		params1.dest_position[1].x = calc_rotate_x(t_params1->pixDestX+t_params1->destWidth, t_params1->pixDestY, t_params1->rotation_hotspot.x, t_params1->rotation_hotspot.y, vect_rotate_x[0], vect_rotate_y[0]);
		params1.dest_position[2].x = calc_rotate_x(t_params1->pixDestX, t_params1->pixDestY+t_params1->destHeight, t_params1->rotation_hotspot.x, t_params1->rotation_hotspot.y, vect_rotate_x[0], vect_rotate_y[0]);
		params1.dest_position[3].x = calc_rotate_x(t_params1->pixDestX+t_params1->destWidth, t_params1->pixDestY+t_params1->destHeight, t_params1->rotation_hotspot.x, t_params1->rotation_hotspot.y, vect_rotate_x[0], vect_rotate_y[0]);

		params1.dest_position[0].y = calc_rotate_y(t_params1->pixDestX, t_params1->pixDestY, t_params1->rotation_hotspot.x, t_params1->rotation_hotspot.y, vect_rotate_x[1], vect_rotate_y[1]);
		params1.dest_position[1].y = calc_rotate_y(t_params1->pixDestX+t_params1->destWidth, t_params1->pixDestY, t_params1->rotation_hotspot.x, t_params1->rotation_hotspot.y, vect_rotate_x[1], vect_rotate_y[1]);
		params1.dest_position[2].y = calc_rotate_y(t_params1->pixDestX, t_params1->pixDestY+t_params1->destHeight, t_params1->rotation_hotspot.x, t_params1->rotation_hotspot.y, vect_rotate_x[1], vect_rotate_y[1]);
		params1.dest_position[3].y = calc_rotate_y(t_params1->pixDestX+t_params1->destWidth, t_params1->pixDestY+t_params1->destHeight, t_params1->rotation_hotspot.x, t_params1->rotation_hotspot.y, vect_rotate_x[1], vect_rotate_y[1]);
	}

	// Pitch
	if (params2.rotate_pitch.to_radians() != 0.0f)
	{
		float pitch_rad = sin(CL_PI/2 + params2.rotate_pitch.to_radians());
		params1.dest_position[0].y = (params1.dest_position[0].y - t_params1->rotation_hotspot.y) * pitch_rad + t_params1->rotation_hotspot.y;
		params1.dest_position[1].y = (params1.dest_position[1].y - t_params1->rotation_hotspot.y) * pitch_rad + t_params1->rotation_hotspot.y;
		params1.dest_position[2].y = (params1.dest_position[2].y - t_params1->rotation_hotspot.y) * pitch_rad + t_params1->rotation_hotspot.y;
		params1.dest_position[3].y = (params1.dest_position[3].y - t_params1->rotation_hotspot.y) * pitch_rad + t_params1->rotation_hotspot.y;
	}
	// Yaw
	if (params2.rotate_yaw.to_radians() != 0.0f)
	{
		float yaw_rad = cos(params2.rotate_yaw.to_radians());
		params1.dest_position[0].x = (params1.dest_position[0].x - t_params1->rotation_hotspot.x) * yaw_rad + t_params1->rotation_hotspot.x;
		params1.dest_position[1].x = (params1.dest_position[1].x - t_params1->rotation_hotspot.x) * yaw_rad + t_params1->rotation_hotspot.x;
		params1.dest_position[2].x = (params1.dest_position[2].x - t_params1->rotation_hotspot.x) * yaw_rad + t_params1->rotation_hotspot.x;
		params1.dest_position[3].x = (params1.dest_position[3].x - t_params1->rotation_hotspot.x) * yaw_rad + t_params1->rotation_hotspot.x;
	}

	params1.color[0] = params2.color;
	params1.color[1] = params2.color;
	params1.color[2] = params2.color;
	params1.color[3] = params2.color;

	params1.destZ = params2.destZ;
}