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); }
void Context::SaveCfg(std::string const & cfg_file) { XMLDocument cfg_doc; XMLNodePtr root = cfg_doc.AllocNode(XNT_Element, "configure"); cfg_doc.RootNode(root); XMLNodePtr context_node = cfg_doc.AllocNode(XNT_Element, "context"); { XMLNodePtr rf_node = cfg_doc.AllocNode(XNT_Element, "render_factory"); rf_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.render_factory_name)); context_node->AppendNode(rf_node); XMLNodePtr af_node = cfg_doc.AllocNode(XNT_Element, "audio_factory"); af_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.audio_factory_name)); context_node->AppendNode(af_node); XMLNodePtr if_node = cfg_doc.AllocNode(XNT_Element, "input_factory"); if_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.input_factory_name)); context_node->AppendNode(if_node); XMLNodePtr sm_node = cfg_doc.AllocNode(XNT_Element, "scene_manager"); sm_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.scene_manager_name)); context_node->AppendNode(sm_node); XMLNodePtr sf_node = cfg_doc.AllocNode(XNT_Element, "show_factory"); sf_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.show_factory_name)); context_node->AppendNode(sf_node); XMLNodePtr scf_node = cfg_doc.AllocNode(XNT_Element, "script_factory"); scf_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.script_factory_name)); context_node->AppendNode(scf_node); XMLNodePtr adsf_node = cfg_doc.AllocNode(XNT_Element, "audio_data_source_factory"); adsf_node->AppendAttrib(cfg_doc.AllocAttribString("name", cfg_.audio_data_source_factory_name)); context_node->AppendNode(adsf_node); } root->AppendNode(context_node); XMLNodePtr graphics_node = cfg_doc.AllocNode(XNT_Element, "graphics"); { XMLNodePtr frame_node = cfg_doc.AllocNode(XNT_Element, "frame"); frame_node->AppendAttrib(cfg_doc.AllocAttribInt("width", cfg_.graphics_cfg.width)); frame_node->AppendAttrib(cfg_doc.AllocAttribInt("height", cfg_.graphics_cfg.height)); std::string color_fmt_str; switch (cfg_.graphics_cfg.color_fmt) { case EF_ARGB8: color_fmt_str = "ARGB8"; break; case EF_ABGR8: color_fmt_str = "ABGR8"; break; case EF_A2BGR10: color_fmt_str = "A2BGR10"; break; default: color_fmt_str = "ARGB8"; break; } frame_node->AppendAttrib(cfg_doc.AllocAttribString("color_fmt", color_fmt_str)); std::string depth_stencil_fmt_str; switch (cfg_.graphics_cfg.depth_stencil_fmt) { case EF_D16: depth_stencil_fmt_str = "D16"; break; case EF_D24S8: depth_stencil_fmt_str = "D24S8"; break; case EF_D32F: depth_stencil_fmt_str = "D32F"; break; default: depth_stencil_fmt_str = "D16"; break; } frame_node->AppendAttrib(cfg_doc.AllocAttribString("depth_stencil_fmt", depth_stencil_fmt_str)); frame_node->AppendAttrib(cfg_doc.AllocAttribInt("fullscreen", cfg_.graphics_cfg.full_screen)); { XMLNodePtr sample_node = cfg_doc.AllocNode(XNT_Element, "sample"); sample_node->AppendAttrib(cfg_doc.AllocAttribInt("count", cfg_.graphics_cfg.sample_count)); sample_node->AppendAttrib(cfg_doc.AllocAttribInt("quality", cfg_.graphics_cfg.sample_quality)); frame_node->AppendNode(sample_node); } graphics_node->AppendNode(frame_node); XMLNodePtr sync_interval_node = cfg_doc.AllocNode(XNT_Element, "sync_interval"); sync_interval_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.sync_interval)); graphics_node->AppendNode(sync_interval_node); XMLNodePtr motion_blur_node = cfg_doc.AllocNode(XNT_Element, "motion_blur"); motion_blur_node->AppendAttrib(cfg_doc.AllocAttribInt("frames", cfg_.graphics_cfg.motion_frames)); graphics_node->AppendNode(motion_blur_node); XMLNodePtr hdr_node = cfg_doc.AllocNode(XNT_Element, "hdr"); hdr_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.hdr)); graphics_node->AppendNode(hdr_node); XMLNodePtr ppaa_node = cfg_doc.AllocNode(XNT_Element, "ppaa"); ppaa_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.ppaa)); graphics_node->AppendNode(ppaa_node); XMLNodePtr gamma_node = cfg_doc.AllocNode(XNT_Element, "gamma"); gamma_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.gamma)); graphics_node->AppendNode(gamma_node); XMLNodePtr color_grading_node = cfg_doc.AllocNode(XNT_Element, "color_grading"); color_grading_node->AppendAttrib(cfg_doc.AllocAttribInt("value", cfg_.graphics_cfg.color_grading)); graphics_node->AppendNode(color_grading_node); XMLNodePtr stereo_node = cfg_doc.AllocNode(XNT_Element, "stereo"); std::string method_str; switch (cfg_.graphics_cfg.stereo_method) { case STM_None: method_str = "none"; break; case STM_ColorAnaglyph_RedCyan: method_str = "red_cyan"; break; case STM_ColorAnaglyph_YellowBlue: method_str = "yellow_blue"; break; case STM_ColorAnaglyph_GreenRed: method_str = "green_red"; break; case STM_LCDShutter: method_str = "lcd_shutter"; break; case STM_HorizontalInterlacing: method_str = "hor_interlacing"; break; case STM_VerticalInterlacing: method_str = "ver_interlacing"; break; case STM_Horizontal: method_str = "horizontal"; break; case STM_Vertical: method_str = "vertical"; break; } stereo_node->AppendAttrib(cfg_doc.AllocAttribString("method", method_str)); std::ostringstream oss; oss.precision(2); oss << std::fixed << cfg_.graphics_cfg.stereo_separation; stereo_node->AppendAttrib(cfg_doc.AllocAttribString("separation", oss.str())); graphics_node->AppendNode(stereo_node); } root->AppendNode(graphics_node); std::ofstream ofs(cfg_file.c_str()); cfg_doc.Print(ofs); }