Exemple #1
0
void Canvas::fill_rect(float x1, float y1, float x2, float y2, const Gradient &gradient)
{
	Vec2f positions[6] =
	{
		Vec2f(x1, y1),
		Vec2f(x2, y1),
		Vec2f(x1, y2),
		Vec2f(x2, y1),
		Vec2f(x1, y2),
		Vec2f(x2, y2)
	};

	Vec4f colors[6] =
	{
		Vec4f(gradient.top_left),
		Vec4f(gradient.top_right),
		Vec4f(gradient.bottom_left),
		Vec4f(gradient.top_right),
		Vec4f(gradient.bottom_left),
		Vec4f(gradient.bottom_right)
	};

	RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
	batcher->fill_triangle(*this, positions, colors, 6);

}
Exemple #2
0
	void Font_DrawFlat::draw_text(Canvas &canvas, const Pointf &position, const std::string &text, const Colorf &color, float line_spacing)
	{
		float offset_x = 0;
		float offset_y = 0;
		UTF8_Reader reader(text.data(), text.length());
		RenderBatchTriangle *batcher = canvas.impl->batcher.get_triangle_batcher();

		while (!reader.is_end())
		{
			unsigned int glyph = reader.get_char();
			reader.next();

			if (glyph == '\n')
			{
				offset_x = 0;
				offset_y += line_spacing;
				continue;
			}

			Font_TextureGlyph *gptr = glyph_cache->get_glyph(canvas, font_engine, glyph);
			if (gptr)
			{
				if (!gptr->texture.is_null())
				{
					float xp = offset_x + position.x + gptr->offset.x;
					float yp = offset_y + position.y + gptr->offset.y;

					Rectf dest_size(xp, yp, Sizef(gptr->geometry.get_size()));
					batcher->draw_image(canvas, gptr->geometry, dest_size, color, gptr->texture);
				}
				offset_x += gptr->metrics.advance.width;
				offset_y += gptr->metrics.advance.height;
			}
		}
	}
Exemple #3
0
void Canvas::fill_triangles(const std::vector<Vec2f> &positions, const std::vector<Vec2f> &texture_positions, const Texture2D &texture, const std::vector<Colorf> &colors)
{
	if (!positions.empty())
	{
		RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
		batcher->fill_triangles(*this, &positions[0], &texture_positions[0], positions.size(), texture, &colors[0]);
	}
}
Exemple #4
0
void Canvas::fill_triangles(const std::vector<Vec2f> &triangles, const Colorf &color)
{
	if (!triangles.empty())
	{
		RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
		batcher->fill_triangle(*this, &triangles[0], color, triangles.size());
	}
}
Exemple #5
0
void Canvas::fill_triangles(const Vec2f *triangle_positions, int num_vertices, const Texture2D &texture, const Rect &texture_rect, const Colorf &color)
{
	if (num_vertices)
	{
		std::vector<Vec2f> texture_positions;
		Canvas_Impl::get_texture_coords(triangle_positions, num_vertices, texture, texture_rect, texture_positions);

		RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
		batcher->fill_triangles(*this, triangle_positions, &texture_positions[0], num_vertices, texture, color);
	}
}
Exemple #6
0
void Canvas::fill_triangles(const std::vector<Vec2f> &positions, const Texture2D &texture, const Rect &texture_rect, const Colorf &color)
{
	if (!positions.empty())
	{
		std::vector<Vec2f> texture_positions;
		Canvas_Impl::get_texture_coords(&positions[0], positions.size(), texture, texture_rect, texture_positions);

		RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
		batcher->fill_triangles(*this, &positions[0], &texture_positions[0], positions.size(), texture, color);
	}
}
Exemple #7
0
void Canvas::fill_triangles(const std::vector<Vec2f> &triangles, const Gradient &gradient)
{
	if (!triangles.empty())
	{
		std::vector<Colorf> colors;
		Canvas_Impl::get_gradient_colors(&triangles[0], triangles.size(), gradient, colors);

		RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
		batcher->fill_triangle(*this, &triangles[0], &colors[0], triangles.size());

	}
}
Exemple #8
0
void Canvas::fill_triangles(const Vec2f *triangle_positions, int num_vertices, const Gradient &gradient)
{
	if (num_vertices)
	{
		std::vector<Colorf> colors;
		Canvas_Impl::get_gradient_colors(triangle_positions, num_vertices, gradient, colors);

		RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
		batcher->fill_triangle(*this, triangle_positions, &colors[0], num_vertices);

	}
}
Exemple #9
0
void Canvas::fill_triangle(const Pointf &a, const Pointf &b, const Pointf &c, const Colorf &color)
{
	Vec2f positions[3] =
	{
		Vec2f(a.x, a.y),
		Vec2f(b.x, b.y),
		Vec2f(c.x, c.y)
	};

	RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
	batcher->fill_triangle(*this, positions, color, 3);
}
	void Font_DrawScaled::draw_text(Canvas &canvas, const Pointf &position, const std::string &text, const Colorf &color, float line_spacing)
	{
		float offset_x = 0;
		float offset_y = 0;
		UTF8_Reader reader(text.data(), text.length());
		RenderBatchTriangle *batcher = canvas.impl->batcher.get_triangle_batcher();

		const Mat4f original_transform = canvas.get_transform();
		clan::Mat4f scale_matrix = clan::Mat4f::scale(scaled_height, scaled_height, scaled_height);
		Sizef advance;

		while (!reader.is_end())
		{
			unsigned int glyph = reader.get_char();
			reader.next();

			if (glyph == '\n')
			{
				offset_x = 0;
				offset_y += line_spacing * scaled_height;
				continue;
			}

			canvas.set_transform(original_transform * Mat4f::translate(position.x + offset_x, position.y + offset_y, 0) * scale_matrix);
			Font_TextureGlyph *gptr = glyph_cache->get_glyph(canvas, font_engine, glyph);
			if (gptr)
			{
				if (!gptr->texture.is_null())
				{
					float xp = gptr->offset.x;
					float yp = gptr->offset.y;

					Rectf dest_size(xp, yp, gptr->size);
					batcher->draw_image(canvas, gptr->geometry, dest_size, color, gptr->texture);
				}
				offset_x += gptr->metrics.advance.width * scaled_height;
				offset_y += gptr->metrics.advance.height * scaled_height;
			}
		}
		canvas.set_transform(original_transform);
	}
Exemple #11
0
void GlyphCache::draw_text(FontEngine *font_engine, Canvas &canvas, float xpos, float ypos, const std::string &text, const Colorf &color) 
{
	std::string::size_type string_length = text.length();
	if (string_length==0)
	{
		return;
	}

	RenderBatchTriangle *batcher = canvas.impl->batcher.get_triangle_batcher();
	GraphicContext &gc = canvas.get_gc();
	// Scan the string
	UTF8_Reader reader(text.data(), text.length());
	while(!reader.is_end())
	{
		unsigned int glyph = reader.get_char();
		reader.next();

		Font_TextureGlyph *gptr = get_glyph(font_engine, gc, glyph);
		if (gptr == NULL) continue;

		if (!gptr->texture.is_null())
		{
			float xp = xpos + gptr->offset.x;
			float yp = ypos + gptr->offset.y;

			Rectf dest_size(xp, yp, Sizef(gptr->geometry.get_size()));
			if (enable_subpixel)
			{
				batcher->draw_glyph_subpixel(canvas, gptr->geometry, dest_size, color, gptr->texture);
			}else
			{
				batcher->draw_image(canvas, gptr->geometry, dest_size, color, gptr->texture);
			}
		}
		xpos += gptr->increment.x;
		ypos += gptr->increment.y;
	}
}
Exemple #12
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);

}
Exemple #13
0
void Canvas::fill_triangles(const Vec2f *positions, const Vec2f *texture_positions, int num_vertices, const Texture2D &texture, const Colorf *colors)
{
	RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
	batcher->fill_triangles(*this, positions, texture_positions, num_vertices, texture, colors);
}
Exemple #14
0
void Canvas::fill_triangles(const Vec2f *triangle_positions, int num_vertices, const Colorf &color)
{
	RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
	batcher->fill_triangle(*this, triangle_positions, color, num_vertices);
}
Exemple #15
0
void Canvas::fill_circle(const Pointf &center, const Pointf &centergradient, float radius, const Gradient &gradient)
{
	float offset_x = 0;
	float offset_y = 0;

	float rotationcount = max(5.0f, (radius - 3.0f));
	float halfpi = 1.5707963267948966192313216916398f;
	float turn = halfpi / rotationcount;

	if(center.distance(center + centergradient) < radius)
	{
		offset_x = centergradient.x;
		offset_y = -centergradient.y;
	}

	Vec4f colors[3] =
	{
		Vec4f(gradient.top_left.get_red(), gradient.top_left.get_green(), gradient.top_left.get_blue(), gradient.top_left.get_alpha()),
		Vec4f(gradient.bottom_right.get_red(), gradient.bottom_right.get_green(), gradient.bottom_right.get_blue(), gradient.bottom_right.get_alpha()),
		Vec4f(gradient.bottom_right.get_red(), gradient.bottom_right.get_green(), gradient.bottom_right.get_blue(), gradient.bottom_right.get_alpha())
	};

	Vec4f triangle_colors[4*3];
	for (int i=0; i<3; i++)
	{
		triangle_colors[0*3+i] = colors[i];
		triangle_colors[1*3+i] = colors[i];
		triangle_colors[2*3+i] = colors[i];
		triangle_colors[3*3+i] = colors[i];
	}

	RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();

	for(float i = 0; i < rotationcount ; i++)
	{
		float pos1 = cos(i * turn);
		float pos2 = sin(i * turn);
		float pos3 = cos((i+1) * turn);
		float pos4 = sin((i+1) * turn);

		Vec2f positions[4*3] =
		{
			// 90 triangle:
			Vec2f(center.x + offset_x , center.y + offset_y),
			Vec2f(center.x + ((float)radius * pos1), center.y + ((float)radius * pos2)),
			Vec2f(center.x + ((float)radius * pos3), center.y + ((float)radius * pos4)),

			// 0 triangle:
			Vec2f(center.x + offset_x , center.y + offset_y),
			Vec2f(center.x + ((float)radius * pos2), center.y - ((float)radius * pos1)),
			Vec2f(center.x + ((float)radius * pos4), center.y - ((float)radius * pos3)),

			// 270 triangle:
			Vec2f(center.x + offset_x , center.y + offset_y),
			Vec2f(center.x - ((float)radius * pos1), center.y - ((float)radius * pos2)),
			Vec2f(center.x - ((float)radius * pos3), center.y - ((float)radius * pos4)),

			// 180 triangle:
			Vec2f(center.x + offset_x , center.y + offset_y),
			Vec2f(center.x - ((float)radius * pos2), center.y + ((float)radius * pos1)),
			Vec2f(center.x - ((float)radius * pos4), center.y + ((float)radius * pos3))
		};

		batcher->fill_triangle(*this, positions, triangle_colors, 4*3);

	}
}
Exemple #16
0
void Canvas::fill_rect(float x1, float y1, float x2, float y2, const Colorf &color)
{
	RenderBatchTriangle *batcher = impl->batcher.get_triangle_batcher();
	batcher->fill(*this, x1, y1, x2, y2, color);
}