Example #1
0
Offline::OfflineRenderDeviceCaps LoadPlatformConfig(std::string const & platform)
{
	ResIdentifierPtr plat = ResLoader::Instance().Open("PlatConf/" + platform + ".plat");

	KlayGE::XMLDocument doc;
	XMLNodePtr root = doc.Parse(plat);

	Offline::OfflineRenderDeviceCaps caps;

	caps.platform = RetrieveAttrValue(root, "name", "");
	caps.major_version = static_cast<uint8_t>(RetrieveAttrValue(root, "major_version", 0));
	caps.minor_version = static_cast<uint8_t>(RetrieveAttrValue(root, "minor_version", 0));

	caps.requires_flipping = RetrieveNodeValue(root, "requires_flipping", 0) ? true : false;
	std::string const fourcc_str = RetrieveNodeValue(root, "native_shader_fourcc", "");
	caps.native_shader_fourcc = (fourcc_str[0] << 0) + (fourcc_str[1] << 8) + (fourcc_str[2] << 16) + (fourcc_str[3] << 24);
	caps.native_shader_version = RetrieveNodeValue(root, "native_shader_version", 0);

	XMLNodePtr max_shader_model_node = root->FirstNode("max_shader_model");
	caps.max_shader_model = ShaderModel(static_cast<uint8_t>(RetrieveAttrValue(max_shader_model_node, "major", 0)),
		static_cast<uint8_t>(RetrieveAttrValue(max_shader_model_node, "minor", 0)));

	caps.max_texture_depth = RetrieveNodeValue(root, "max_texture_depth", 0);
	caps.max_texture_array_length = RetrieveNodeValue(root, "max_texture_array_length", 0);
	caps.max_pixel_texture_units = static_cast<uint8_t>(RetrieveNodeValue(root, "max_pixel_texture_units", 0));
	caps.max_simultaneous_rts = static_cast<uint8_t>(RetrieveNodeValue(root, "max_simultaneous_rts", 0));

	caps.standard_derivatives_support = RetrieveNodeValue(root, "standard_derivatives_support", 0) ? true : false;
	caps.shader_texture_lod_support = RetrieveNodeValue(root, "shader_texture_lod_support", 0) ? true : false;
	caps.fp_color_support = RetrieveNodeValue(root, "fp_color_support", 0) ? true : false;
	caps.pack_to_rgba_required = RetrieveNodeValue(root, "pack_to_rgba_required", 0) ? true : false;

	caps.gs_support = RetrieveNodeValue(root, "gs_support", 0) ? true : false;
	caps.cs_support = RetrieveNodeValue(root, "cs_support", 0) ? true : false;
	caps.hs_support = RetrieveNodeValue(root, "hs_support", 0) ? true : false;
	caps.ds_support = RetrieveNodeValue(root, "ds_support", 0) ? true : false;

	caps.bc4_support = RetrieveNodeValue(root, "bc4_support", 0) ? true : false;
	caps.bc5_support = RetrieveNodeValue(root, "bc5_support", 0) ? true : false;
	caps.frag_depth_support = RetrieveNodeValue(root, "frag_depth_support", 0) ? true : false;
	caps.ubo_support = RetrieveNodeValue(root, "ubo_support", 0) ? true : false;

	return caps;
}
Example #2
0
void PackJTML(std::string const & jtml_name)
{
	Timer timer;

	ResIdentifierPtr jtml = ResLoader::Instance().Open(jtml_name);

	KlayGE::XMLDocument doc;
	XMLNodePtr root = doc.Parse(jtml);

	uint32_t n = root->AttribInt("num_tiles", 2048);
	uint32_t num_tiles = 1;
	while (num_tiles * 2 <= n)
	{
		num_tiles *= 2;
	}

	uint32_t tile_size = root->AttribInt("tile_size", 128);
	std::string fmt_str = root->AttribString("format", "");
	ElementFormat format = EF_ARGB8;
	if ("ARGB8" == fmt_str)
	{
		format = EF_ARGB8;
	}
	else if ("ABGR8" == fmt_str)
	{
		format = EF_ABGR8;
	}
	uint32_t pixel_size = NumFormatBytes(format);

	JudaTexturePtr juda_tex = MakeSharedPtr<JudaTexture>(num_tiles, tile_size, format);

	uint32_t level = juda_tex->TreeLevels() - 1;

	RenderFactory& rf = Context::Instance().RenderFactoryInstance();
	uint32_t attr = 0;
	for (XMLNodePtr node = root->FirstNode("image"); node; node = node->NextSibling("image"), ++ attr)
	{
		timer.restart();

		std::string name = node->AttribString("name", "");
		int32_t x = node->AttribInt("x", 0);
		int32_t y = node->AttribInt("y", 0);
		std::string address_u_str = node->AttribString("address_u", "wrap");
		std::string address_v_str = node->AttribString("address_v", "wrap");
		Color border_clr;
		border_clr.r() = node->AttribFloat("border_r", 0.0f);
		border_clr.g() = node->AttribFloat("border_g", 0.0f);
		border_clr.b() = node->AttribFloat("border_b", 0.0f);
		border_clr.a() = node->AttribFloat("border_a", 0.0f);
		uint32_t border_clr_u8;
		switch (format)
		{
		case EF_ARGB8:
			border_clr_u8 = border_clr.ARGB();
			break;

		case EF_ABGR8:
			border_clr_u8 = border_clr.ABGR();
			break;

		default:
			border_clr_u8 = 0;
			break;
		}

		TexAddressingMode addr_u, addr_v;
		std::shared_ptr<address_calculator> calc_u, calc_v;
		if ("mirror" == address_u_str)
		{
			addr_u = TAM_Mirror;
			calc_u = address_calculators[TAM_Mirror];
		}
		else if ("clamp" == address_u_str)
		{
			addr_u = TAM_Clamp;
			calc_u = address_calculators[TAM_Clamp];
		}
		else if ("border" == address_u_str)
		{
			addr_u = TAM_Border;
			calc_u = address_calculators[TAM_Border];
		}
		else
		{
			addr_u = TAM_Wrap;
			calc_u = address_calculators[TAM_Wrap];
		}
		if ("mirror" == address_v_str)
		{
			addr_v = TAM_Mirror;
			calc_v = address_calculators[TAM_Mirror];
		}
		else if ("clamp" == address_v_str)
		{
			addr_v = TAM_Clamp;
			calc_v = address_calculators[TAM_Clamp];
		}
		else if ("border" == address_v_str)
		{
			addr_v = TAM_Border;
			calc_v = address_calculators[TAM_Border];
		}
		else
		{
			addr_v = TAM_Wrap;
			calc_v = address_calculators[TAM_Wrap];
		}

		cout << "Processing " << name << "... ";

		TexturePtr src_texture = SyncLoadTexture(name, EAH_CPU_Read | EAH_CPU_Write);
		if (src_texture->Type() != Texture::TT_2D)
		{
			cout << "Texture " << name << "is not 2D texture. Skipped." << endl;
			continue;
		}

		uint32_t in_width = src_texture->Width(0);
		uint32_t in_height = src_texture->Height(0);

		TexturePtr texture = rf.MakeTexture2D(in_width, in_height, 1, 1, format, 1, 0, EAH_CPU_Read | EAH_CPU_Write);
		src_texture->CopyToTexture(*texture);

		Texture::Mapper mapper(*texture, 0, 0, TMA_Read_Only, 0, 0, in_width, in_height);
		uint8_t const * in_data_p = mapper.Pointer<uint8_t>();

		int32_t in_num_tiles_x = std::min((in_width + tile_size - 1) / tile_size, num_tiles);
		int32_t in_num_tiles_y = std::min((in_height + tile_size - 1) / tile_size, num_tiles);

		int32_t beg_tile_x = 0;
		int32_t end_tile_x = std::min(static_cast<int32_t>(x + in_num_tiles_x), static_cast<int32_t>(num_tiles)) - x;
		int32_t beg_tile_y = 0;
		int32_t end_tile_y = std::min(static_cast<int32_t>(y + in_num_tiles_y), static_cast<int32_t>(num_tiles)) - y;

		juda_tex->AddImageEntry(name, x, y, in_num_tiles_x, in_num_tiles_y, addr_u, addr_v, border_clr);

		std::vector<std::vector<uint8_t>> tiles;
		std::vector<uint32_t> tile_ids;
		std::vector<uint32_t> tile_attrs;
		for (int32_t by = beg_tile_y; by < end_tile_y; ++ by)
		{
			tiles.clear();
			tile_ids.clear();
			tile_attrs.clear();
			for (int32_t bx = beg_tile_x; bx < end_tile_x; ++ bx)
			{
				uint32_t xindex = bx - beg_tile_x;

				tiles.push_back(std::vector<uint8_t>(tile_size * tile_size * pixel_size, 0));
				tile_ids.push_back(juda_tex->EncodeTileID(level, bx + x, by + y));
				tile_attrs.push_back(attr);
				for (size_t dy = 0; dy < tile_size; ++ dy)
				{
					int32_t tex_y = (*calc_v)(static_cast<int32_t>(by * tile_size + dy), in_height);
					if (tex_y >= 0)
					{
						for (size_t dx = 0; dx < tile_size; ++ dx)
						{
							int32_t tex_x = (*calc_u)(static_cast<int32_t>(bx * tile_size + dx), in_width);
							if (tex_x >= 0)
							{
								std::memcpy(&tiles[xindex][(dy * tile_size + dx) * pixel_size],
									&in_data_p[tex_y * mapper.RowPitch() + tex_x * pixel_size],
									pixel_size);
							}
							else
							{
								std::memcpy(&tiles[xindex][(dy * tile_size + dx) * pixel_size],
									&border_clr_u8,
									pixel_size);
							}
						}
					}
					else
					{
						for (size_t dx = 0; dx < tile_size; ++ dx)
						{
							std::memcpy(&tiles[xindex][(dy * tile_size + dx) * pixel_size],
								&border_clr_u8,
								pixel_size);
						}
					}
				}
			}

			juda_tex->CommitTiles(tiles, tile_ids, tile_attrs);
		}

		cout << "Takes " << timer.elapsed() << "s" << endl;
	}

	cout << "Total tiles: " << ((1UL << (juda_tex->TreeLevels() * 2)) - 1) / (4 - 1) << endl;
	cout << "Non empty tiles: " << juda_tex->NumNonEmptyNodes() << endl;
	cout << "Tree depth: " << juda_tex->TreeLevels() << endl;

	std::string base_name = jtml_name.substr(0, jtml_name.find_last_of('.'));

	cout << "Saving... ";
	timer.restart();
	SaveJudaTexture(juda_tex, base_name + ".jdt");
	cout << "Takes " << timer.elapsed() << "s" << endl << endl;
}
Example #3
0
	void SaveRenderMaterial(RenderMaterialPtr const & mtl, std::string const & mtlml_name)
	{
		KlayGE::XMLDocument doc;

		XMLNodePtr root = doc.AllocNode(XNT_Element, "material");
		doc.RootNode(root);

		{
			XMLNodePtr albedo_node = doc.AllocNode(XNT_Element, "albedo");

			std::string color_str = boost::lexical_cast<std::string>(mtl->albedo.x())
				+ ' ' + boost::lexical_cast<std::string>(mtl->albedo.y())
				+ ' ' + boost::lexical_cast<std::string>(mtl->albedo.z())
				+ ' ' + boost::lexical_cast<std::string>(mtl->albedo.w());
			albedo_node->AppendAttrib(doc.AllocAttribString("color", color_str));

			if (!mtl->tex_names[RenderMaterial::TS_Albedo].empty())
			{
				albedo_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Albedo]));
			}

			root->AppendNode(albedo_node);
		}

		if ((mtl->metalness > 0) || !mtl->tex_names[RenderMaterial::TS_Metalness].empty())
		{
			XMLNodePtr metalness_node = doc.AllocNode(XNT_Element, "metalness");

			if (mtl->metalness > 0)
			{
				metalness_node->AppendAttrib(doc.AllocAttribFloat("value", mtl->metalness));
			}
			if (!mtl->tex_names[RenderMaterial::TS_Metalness].empty())
			{
				metalness_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Metalness]));
			}

			root->AppendNode(metalness_node);
		}

		if ((mtl->glossiness > 0) || !mtl->tex_names[RenderMaterial::TS_Glossiness].empty())
		{
			XMLNodePtr glossiness_node = doc.AllocNode(XNT_Element, "glossiness");

			if (mtl->glossiness > 0)
			{
				glossiness_node->AppendAttrib(doc.AllocAttribFloat("value", mtl->glossiness));
			}
			if (!mtl->tex_names[RenderMaterial::TS_Glossiness].empty())
			{
				glossiness_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Glossiness]));
			}

			root->AppendNode(glossiness_node);
		}

		if ((mtl->emissive.x() > 0) || (mtl->emissive.y() > 0) || (mtl->emissive.z() > 0)
			|| (!mtl->tex_names[RenderMaterial::TS_Emissive].empty()))
		{
			XMLNodePtr emissive_node = doc.AllocNode(XNT_Element, "emissive");

			if ((mtl->emissive.x() > 0) || (mtl->emissive.y() > 0) || (mtl->emissive.z() > 0))
			{
				std::string color_str = boost::lexical_cast<std::string>(mtl->emissive.x())
					+ ' ' + boost::lexical_cast<std::string>(mtl->emissive.y())
					+ ' ' + boost::lexical_cast<std::string>(mtl->emissive.z());
				emissive_node->AppendAttrib(doc.AllocAttribString("color", color_str));
			}
			if (!mtl->tex_names[RenderMaterial::TS_Emissive].empty())
			{
				emissive_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Emissive]));
			}

			root->AppendNode(emissive_node);
		}

		if (!mtl->tex_names[RenderMaterial::TS_Normal].empty())
		{
			XMLNodePtr normal_node = doc.AllocNode(XNT_Element, "normal");

			normal_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Normal]));

			root->AppendNode(normal_node);
		}

		if (!mtl->tex_names[RenderMaterial::TS_Height].empty())
		{
			XMLNodePtr height_node = doc.AllocNode(XNT_Element, "height");

			height_node->AppendAttrib(doc.AllocAttribString("texture", mtl->tex_names[RenderMaterial::TS_Height]));
			height_node->AppendAttrib(doc.AllocAttribFloat("offset", mtl->height_offset_scale.x()));
			height_node->AppendAttrib(doc.AllocAttribFloat("scale", mtl->height_offset_scale.y()));

			root->AppendNode(height_node);
		}

		if (mtl->detail_mode != RenderMaterial::SDM_Parallax)
		{
			XMLNodePtr detail_node = doc.AllocNode(XNT_Element, "detail");

			std::string detail_mode_str;
			switch (mtl->detail_mode)
			{
			case RenderMaterial::SDM_FlatTessellation:
				detail_mode_str = "Flat Tessellation";
				break;

			case RenderMaterial::SDM_SmoothTessellation:
				detail_mode_str = "Smooth Tessellation";
				break;

			default:
				KFL_UNREACHABLE("Invalid surface detail mode");
			}
			detail_node->AppendAttrib(doc.AllocAttribString("mode", detail_mode_str));

			{
				XMLNodePtr tess_node = doc.AllocNode(XNT_Element, "tess");
				tess_node->AppendAttrib(doc.AllocAttribFloat("edge_hint", mtl->tess_factors.x()));
				tess_node->AppendAttrib(doc.AllocAttribFloat("inside_hint", mtl->tess_factors.y()));
				tess_node->AppendAttrib(doc.AllocAttribFloat("min", mtl->tess_factors.z()));
				tess_node->AppendAttrib(doc.AllocAttribFloat("max", mtl->tess_factors.w()));
				detail_node->AppendNode(tess_node);
			}

			root->AppendNode(detail_node);
		}

		if (mtl->transparent)
		{
			XMLNodePtr transparent_node = doc.AllocNode(XNT_Element, "transparent");

			transparent_node->AppendAttrib(doc.AllocAttribString("value", "1"));

			root->AppendNode(transparent_node);
		}

		if (mtl->alpha_test > 0)
		{
			XMLNodePtr alpha_test_node = doc.AllocNode(XNT_Element, "alpha_test");

			alpha_test_node->AppendAttrib(doc.AllocAttribFloat("value", mtl->alpha_test));

			root->AppendNode(alpha_test_node);
		}

		if (mtl->sss)
		{
			XMLNodePtr sss_node = doc.AllocNode(XNT_Element, "sss");

			sss_node->AppendAttrib(doc.AllocAttribString("value", "1"));

			root->AppendNode(sss_node);
		}

		if (mtl->two_sided)
		{
			XMLNodePtr two_sided_node = doc.AllocNode(XNT_Element, "two_sided");

			two_sided_node->AppendAttrib(doc.AllocAttribString("value", "1"));

			root->AppendNode(two_sided_node);
		}

		std::ofstream ofs(mtlml_name.c_str());
		if (!ofs)
		{
			ofs.open((ResLoader::Instance().LocalFolder() + mtlml_name).c_str());
		}
		doc.Print(ofs);
	}
Example #4
0
		void SubThreadStage()
		{
			ResIdentifierPtr psmm_input = ResLoader::Instance().Open(ps_desc_.res_name);

			KlayGE::XMLDocument doc;
			XMLNodePtr root = doc.Parse(psmm_input);

			{
				XMLNodePtr particle_node = root->FirstNode("particle");
				{
					XMLNodePtr alpha_node = particle_node->FirstNode("alpha");
					ps_desc_.ps_data->particle_alpha_from_tex = alpha_node->Attrib("from")->ValueString();
					ps_desc_.ps_data->particle_alpha_to_tex = alpha_node->Attrib("to")->ValueString();
				}
				{
					XMLNodePtr color_node = particle_node->FirstNode("color");
					{
						Color from;
						XMLAttributePtr attr = color_node->Attrib("from");
						if (attr)
						{
							std::vector<std::string> strs;
							boost::algorithm::split(strs, attr->ValueString(), boost::is_any_of(" "));
							for (size_t i = 0; i < 3; ++ i)
							{
								if (i < strs.size())
								{
									boost::algorithm::trim(strs[i]);
									from[i] = static_cast<float>(atof(strs[i].c_str()));
								}
								else
								{
									from[i] = 0;
								}
							}
						}
						from.a() = 1;
						ps_desc_.ps_data->particle_color_from = from;

						Color to;
						attr = color_node->Attrib("to");
						if (attr)
						{
							std::vector<std::string> strs;
							boost::algorithm::split(strs, attr->ValueString(), boost::is_any_of(" "));
							for (size_t i = 0; i < 3; ++ i)
							{
								if (i < strs.size())
								{
									boost::algorithm::trim(strs[i]);
									to[i] = static_cast<float>(atof(strs[i].c_str()));
								}
								else
								{
									to[i] = 0;
								}
							}
						}
						to.a() = 1;
						ps_desc_.ps_data->particle_color_to = to;
					}
				}
			}

			{
				XMLNodePtr emitter_node = root->FirstNode("emitter");

				XMLAttributePtr type_attr = emitter_node->Attrib("type");
				if (type_attr)
				{
					ps_desc_.ps_data->emitter_type = type_attr->ValueString();
				}
				else
				{
					ps_desc_.ps_data->emitter_type = "point";
				}

				XMLNodePtr freq_node = emitter_node->FirstNode("frequency");
				if (freq_node)
				{
					XMLAttributePtr attr = freq_node->Attrib("value");
					ps_desc_.ps_data->frequency = attr->ValueFloat();
				}

				XMLNodePtr angle_node = emitter_node->FirstNode("angle");
				if (angle_node)
				{
					XMLAttributePtr attr = angle_node->Attrib("value");
					ps_desc_.ps_data->angle = attr->ValueInt() * DEG2RAD;
				}

				XMLNodePtr pos_node = emitter_node->FirstNode("pos");
				if (pos_node)
				{
					float3 min_pos(0, 0, 0);
					XMLAttributePtr attr = pos_node->Attrib("min");
					if (attr)
					{
						std::vector<std::string> strs;
						boost::algorithm::split(strs, attr->ValueString(), boost::is_any_of(" "));
						for (size_t i = 0; i < 3; ++ i)
						{
							if (i < strs.size())
							{
								boost::algorithm::trim(strs[i]);
								min_pos[i] = static_cast<float>(atof(strs[i].c_str()));
							}
							else
							{
								min_pos[i] = 0;
							}
						}
					}
					ps_desc_.ps_data->min_pos = min_pos;
			
					float3 max_pos(0, 0, 0);
					attr = pos_node->Attrib("max");
					if (attr)
					{
						std::vector<std::string> strs;
						boost::algorithm::split(strs, attr->ValueString(), boost::is_any_of(" "));
						for (size_t i = 0; i < 3; ++ i)
						{
							if (i < strs.size())
							{
								boost::algorithm::trim(strs[i]);
								max_pos[i] = static_cast<float>(atof(strs[i].c_str()));
							}
							else
							{
								max_pos[i] = 0;
							}
						}
					}			
					ps_desc_.ps_data->max_pos = max_pos;
				}

				XMLNodePtr vel_node = emitter_node->FirstNode("vel");
				if (vel_node)
				{
					XMLAttributePtr attr = vel_node->Attrib("min");
					ps_desc_.ps_data->min_vel = attr->ValueFloat();

					attr = vel_node->Attrib("max");
					ps_desc_.ps_data->max_vel = attr->ValueFloat();
				}

				XMLNodePtr life_node = emitter_node->FirstNode("life");
				if (life_node)
				{
					XMLAttributePtr attr = life_node->Attrib("min");
					ps_desc_.ps_data->min_life = attr->ValueFloat();

					attr = life_node->Attrib("max");
					ps_desc_.ps_data->max_life = attr->ValueFloat();
				}
			}

			{
				XMLNodePtr updater_node = root->FirstNode("updater");

				XMLAttributePtr type_attr = updater_node->Attrib("type");
				if (type_attr)
				{
					ps_desc_.ps_data->updater_type = type_attr->ValueString();
				}
				else
				{
					ps_desc_.ps_data->updater_type = "polyline";
				}

				if ("polyline" == ps_desc_.ps_data->updater_type)
				{
					for (XMLNodePtr node = updater_node->FirstNode("curve"); node; node = node->NextSibling("curve"))
					{
						std::vector<float2> xys;
						for (XMLNodePtr ctrl_point_node = node->FirstNode("ctrl_point"); ctrl_point_node; ctrl_point_node = ctrl_point_node->NextSibling("ctrl_point"))
						{
							XMLAttributePtr attr_x = ctrl_point_node->Attrib("x");
							XMLAttributePtr attr_y = ctrl_point_node->Attrib("y");

							xys.push_back(float2(attr_x->ValueFloat(), attr_y->ValueFloat()));
						}

						XMLAttributePtr attr = node->Attrib("name");
						size_t const name_hash = RT_HASH(attr->ValueString().c_str());
						if (CT_HASH("size_over_life") == name_hash)
						{
							ps_desc_.ps_data->size_over_life_ctrl_pts = xys;
						}
						else if (CT_HASH("mass_over_life") == name_hash)
						{
							ps_desc_.ps_data->mass_over_life_ctrl_pts = xys;
						}
						else if (CT_HASH("opacity_over_life") == name_hash)
						{
							ps_desc_.ps_data->opacity_over_life_ctrl_pts = xys;
						}
					}
				}
			}

			RenderFactory& rf = Context::Instance().RenderFactoryInstance();
			RenderDeviceCaps const & caps = rf.RenderEngineInstance().DeviceCaps();
			if (caps.multithread_res_creating_support)
			{
				this->MainThreadStage();
			}
		}