Ejemplo n.º 1
0
void TexturePacker::process_resource(CL_Resource &item_resource, std::vector<CL_Subtexture> &packed_sub_textures, std::map<CL_Texture, CL_String> &generated_texture_filenames, int &generated_texture_index, const CL_String &image_pathname )
{
	// Found a sprite resource, lets modify its content!
	CL_Resource resource = item_resource;

	// Iterate through all nodes, and remove all previous image tags
	CL_DomElement &element = resource.get_element();
	CL_DomNode cur = element.get_first_child();
	while (!cur.is_null())
	{
		CL_DomNode next = cur.get_next_sibling();
		CL_DomNode::NodeType nodeType = (CL_DomNode::NodeType)cur.get_node_type();

		// Only remove the <image> tag, as we want to keep the other sprite attributes
		if (cur.get_node_name() == "image")
			element.remove_child(cur);

		cur = next;
	}

	// Add new image tag to resource DOM
	std::vector<CL_Subtexture>::size_type index, size;
	size = packed_sub_textures.size();
	for(index = 0; index < size; ++index)
	{
		CL_Subtexture subtexture = packed_sub_textures[index];

		// Try to find out if we already have created a texture-on-disk for this subtexture
		CL_String texture_filename;
		CL_Texture texture = subtexture.get_texture();
		std::map<CL_Texture, CL_String>::iterator it;
		it = generated_texture_filenames.find(texture);
		if(it == generated_texture_filenames.end())
		{
			// Texture not found, generate a filename and dump texture to disk
			texture_filename = cl_format("texture%1.png", ++generated_texture_index);
			CL_PNGProvider::save(texture.get_pixeldata(), image_pathname + texture_filename);
			generated_texture_filenames[texture] = texture_filename;
		}
		else
		{
			// Previously dumped textures, lets reuse the filename
			texture_filename = (*it).second;
		}

		// Add <grid> DOM element
		CL_DomElement new_grid_element = element.get_owner_document().create_element("grid");
		new_grid_element.set_attribute("pos", cl_format("%1,%2", subtexture.get_geometry().left + last_border_size, subtexture.get_geometry().top + last_border_size));
		new_grid_element.set_attribute("size", cl_format("%1,%2", subtexture.get_geometry().get_width()- last_border_size*2, subtexture.get_geometry().get_height()- last_border_size*2));

		// Add <image> DOM element
		CL_DomElement new_image_element = element.get_owner_document().create_element("image");
		new_image_element.set_attribute("file", texture_filename);
		new_image_element.append_child(new_grid_element);

		// Add <image> element under <sprite> element
		element.append_child(new_image_element);
	}
}
Ejemplo n.º 2
0
void CL_TextureGroup_Impl::remove(CL_Subtexture &subtexture)
{
	// Find the texture
	Node *node = NULL;
	CL_Texture texture = subtexture.get_texture();
	CL_Rect rect = subtexture.get_geometry();

	std::vector<RootNode *>::size_type index, size;
	size = root_nodes.size();
	for(index = 0; index < size; ++index)
	{
		// Find a texture match
		if (root_nodes[index]->texture == texture )
		{
			node = root_nodes[index]->node.find_image_rect(rect);
			break;
		}
	}
	if (node)
	{
		node->clear();
		if(root_nodes[index]->node.get_subtexture_count() <= 0)
		{
			root_nodes[index]->node.clear();
			delete root_nodes[index];
			root_nodes.erase(root_nodes.begin() + index);
		}
		if(root_nodes.empty())
		{
			active_root = 0;
		}
		else
		{
			active_root = root_nodes.back();
		}
	}
	else
	{
		throw CL_Exception("Cannot find the SubTexture in the TextureGroup");
	}
}
Ejemplo n.º 3
0
void CL_Sprite_Impl::create_textures(CL_GraphicContext &gc, const CL_SpriteDescription &description)
{
	// Fetch frames
	const std::vector<CL_SpriteDescriptionFrame> &description_frames = description.get_frames();
	std::vector<CL_SpriteDescriptionFrame>::const_iterator it_frames;

	// Calculate estimated texture group size
	if (texture_group.is_null())
	{
		// *** This algorithm may not work! ***
		int max_width = 1;
		int max_height = 1;
		int num_objects = 0;
		int min_width = 9999999;
		int min_height = min_width;
		int total_width = 1;

		const int allowed_pixel_gap = 4;

		for (it_frames = description_frames.begin(); it_frames != description_frames.end(); ++it_frames)
		{
			CL_SpriteDescriptionFrame description_frame = (*it_frames);
			int width = description_frame.rect.get_width();
			int height = description_frame.rect.get_width();

			if (max_width < width) max_width = width;
			if (max_height < height) max_height = height;

			if (min_width > width) min_width = width;
			if (min_height > height) min_height = height;

			total_width += width + allowed_pixel_gap;

			num_objects++;
		}

		int group_width = total_width;
		int group_height = max_height;

		// Check all will fit into a single line
		const int max_group_size = 512;
		if (group_width > max_group_size)
		{
			group_width = max_group_size;
			group_height *= (total_width + max_group_size - 1) / max_group_size;
		}

		// Ensure power of 2 - width
		if (group_width > 256)
			group_width = 512;
		else if (group_width > 128)
			group_width = 256;
		else if (group_width > 64)
			group_width = 128;
		else if (group_width > 32)
			group_width = 64;
		else group_width = 32;

		// Ensure power of 2 - height
		if (group_height > 256)
			group_height = 512;
		else if (group_height > 128)
			group_height = 256;
		else if (group_height > 64)
			group_height = 128;
		else if (group_height > 32)
			group_height = 64;
		else group_height = 32;

		// Only create group if an object will definately fit into it
		if ( (group_width >= min_width) && (group_height >= min_height) && (num_objects > 1) )
		{
			texture_group = CL_TextureGroup(CL_Size(group_width, group_height));
		}
	}

	int texture_group_width;
	int texture_group_height;

	if (texture_group.is_null())
	{
		texture_group_width = -1;
		texture_group_height = -1;
	}
	else
	{
		CL_Size size = texture_group.get_texture_sizes();
		texture_group_width = size.width;
		texture_group_height = size.height;
	}

	for (it_frames = description_frames.begin(); it_frames != description_frames.end(); ++it_frames)
	{
		CL_SpriteDescriptionFrame description_frame = (*it_frames);

		if(description_frame.type == CL_SpriteDescriptionFrame::type_pixelbuffer)
		{
			CL_PixelBuffer image = description_frame.pixelbuffer;
			if (texture_group_width >0 &&
				description_frame.rect.get_width() <= texture_group_width &&
				description_frame.rect.get_height() <= texture_group_height)
			{
				CL_Subtexture subtexture = texture_group.add(gc, description_frame.rect.get_size());
				subtexture.get_texture().set_subimage(subtexture.get_geometry().get_top_left(), image, description_frame.rect);
				subtexture.get_texture().set_mag_filter(linear_filter ? cl_filter_linear : cl_filter_nearest);
				subtexture.get_texture().set_min_filter(linear_filter ? cl_filter_linear : cl_filter_nearest);

				SpriteFrame frame;
				frame.position = subtexture.get_geometry();
				frame.texture = subtexture.get_texture();
				frame.delay_ms = 60;
				frame.offset = CL_Point(0, 0);
				frames.push_back(frame);
			}
			else
			{
				int width = description_frame.rect.get_width();
				int height = description_frame.rect.get_height();

				// Note, forced power of 2 textures have clamping issues
				int texture_width = width;
				int texture_height = height;

				CL_Texture texture(gc, texture_width, texture_height);
				texture.set_subimage(CL_Point(0,0), image, description_frame.rect);
				texture.set_mag_filter(linear_filter ? cl_filter_linear : cl_filter_nearest);
				texture.set_min_filter(linear_filter ? cl_filter_linear : cl_filter_nearest);

				SpriteFrame frame;
				frame.position = CL_Rect(0, 0, width, height);
				frame.texture = texture;
				frame.delay_ms = 60;
				frame.offset = CL_Point(0, 0);
				frames.push_back(frame);
			}
		}
		else if(description_frame.type == CL_SpriteDescriptionFrame::type_texture)
		{
			SpriteFrame frame;
			frame.position = description_frame.rect;
			frame.texture = description_frame.texture;
			frame.delay_ms = 60;
			frame.offset = CL_Point(0, 0);
			frames.push_back(frame);
		}
	}
}