当前位置: 首页>>代码示例>>C++>>正文


C++ IShaderSource类代码示例

本文整理汇总了C++中IShaderSource的典型用法代码示例。如果您正苦于以下问题:C++ IShaderSource类的具体用法?C++ IShaderSource怎么用?C++ IShaderSource使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了IShaderSource类的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: initMaterial

void RenderingCoreInterlaced::initMaterial()
{
	IShaderSource *s = client->getShaderSource();
	mat.UseMipMaps = false;
	mat.ZBuffer = false;
	mat.ZWriteEnable = false;
	u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC, 0);
	mat.MaterialType = s->getShaderInfo(shader).material;
	for (int k = 0; k < 3; ++k) {
		mat.TextureLayer[k].AnisotropicFilter = false;
		mat.TextureLayer[k].BilinearFilter = false;
		mat.TextureLayer[k].TrilinearFilter = false;
		mat.TextureLayer[k].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
		mat.TextureLayer[k].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
	}
}
开发者ID:ShadowNinja,项目名称:minetest,代码行数:16,代码来源:interlaced.cpp

示例2: m_mesh

MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
	m_mesh(new scene::SMesh()),
	m_gamedef(data->m_gamedef),
	m_animation_force_timer(0), // force initial animation
	m_last_crack(-1),
	m_crack_materials(),
	m_last_daynight_ratio((u32) -1),
	m_daynight_diffs()
{
	// 4-21ms for MAP_BLOCKSIZE=16  (NOTE: probably outdated)
	// 24-155ms for MAP_BLOCKSIZE=32  (NOTE: probably outdated)
	//TimeTaker timer1("MapBlockMesh()");

	std::vector<FastFace> fastfaces_new;

	/*
		We are including the faces of the trailing edges of the block.
		This means that when something changes, the caller must
		also update the meshes of the blocks at the leading edges.

		NOTE: This is the slowest part of this method.
	*/
	{
		// 4-23ms for MAP_BLOCKSIZE=16  (NOTE: probably outdated)
		//TimeTaker timer2("updateAllFastFaceRows()");
		updateAllFastFaceRows(data, fastfaces_new);
	}
	// End of slow part

	/*
		Convert FastFaces to MeshCollector
	*/

	MeshCollector collector;

	{
		// avg 0ms (100ms spikes when loading textures the first time)
		// (NOTE: probably outdated)
		//TimeTaker timer2("MeshCollector building");

		for(u32 i=0; i<fastfaces_new.size(); i++)
		{
			FastFace &f = fastfaces_new[i];

			const u16 indices[] = {0,1,2,2,3,0};
			const u16 indices_alternate[] = {0,1,3,2,3,1};
			
			if(f.tile.texture == NULL)
				continue;

			const u16 *indices_p = indices;
			
			/*
				Revert triangles for nicer looking gradient if vertices
				1 and 3 have same color or 0 and 2 have different color.
				getRed() is the day color.
			*/
			if(f.vertices[0].Color.getRed() != f.vertices[2].Color.getRed()
					|| f.vertices[1].Color.getRed() == f.vertices[3].Color.getRed())
				indices_p = indices_alternate;
			
			collector.append(f.tile, f.vertices, 4, indices_p, 6);
		}
	}

	/*
		Add special graphics:
		- torches
		- flowing water
		- fences
		- whatever
	*/

	mapblock_mesh_generate_special(data, collector);
	

	/*
		Convert MeshCollector to SMesh
	*/
	bool enable_shaders     = g_settings->getBool("enable_shaders");
	bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
	bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");

	video::E_MATERIAL_TYPE  shadermat1, shadermat2, shadermat3,
							shadermat4, shadermat5;
	shadermat1 = shadermat2 = shadermat3 = shadermat4 = shadermat5 = 
		video::EMT_SOLID;

	if (enable_shaders) {
		IShaderSource *shdrsrc = m_gamedef->getShaderSource();
		shadermat1 = shdrsrc->getShader("solids_shader").material;
		shadermat2 = shdrsrc->getShader("liquids_shader").material;
		shadermat3 = shdrsrc->getShader("alpha_shader").material;
		shadermat4 = shdrsrc->getShader("leaves_shader").material;
		shadermat5 = shdrsrc->getShader("plants_shader").material;
	}

	for(u32 i = 0; i < collector.prebuffers.size(); i++)
	{
		PreMeshBuffer &p = collector.prebuffers[i];
//.........这里部分代码省略.........
开发者ID:andrew889,项目名称:minetest-1,代码行数:101,代码来源:mapblock_mesh.cpp

示例3: setItem

void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
{
	ITextureSource *tsrc = client->getTextureSource();
	IItemDefManager *idef = client->getItemDefManager();
	IShaderSource *shdrsrc = client->getShaderSource();
	const NodeDefManager *ndef = client->getNodeDefManager();
	const ItemDefinition &def = item.getDefinition(idef);
	const ContentFeatures &f = ndef->get(def.name);
	content_t id = ndef->getId(def.name);

	scene::SMesh *mesh = nullptr;

	if (m_enable_shaders) {
		u32 shader_id = shdrsrc->getShader("wielded_shader", TILE_MATERIAL_BASIC, NDT_NORMAL);
		m_material_type = shdrsrc->getShaderInfo(shader_id).material;
	}

	// Color-related
	m_colors.clear();
	m_base_color = idef->getItemstackColor(item, client);

	// If wield_image is defined, it overrides everything else
	if (!def.wield_image.empty()) {
		setExtruded(def.wield_image, def.wield_overlay, def.wield_scale, tsrc,
			1);
		m_colors.emplace_back();
		// overlay is white, if present
		m_colors.emplace_back(true, video::SColor(0xFFFFFFFF));
		return;
	}

	// Handle nodes
	// See also CItemDefManager::createClientCached()
	if (def.type == ITEM_NODE) {
		if (f.mesh_ptr[0]) {
			// e.g. mesh nodes and nodeboxes
			mesh = cloneMesh(f.mesh_ptr[0]);
			postProcessNodeMesh(mesh, f, m_enable_shaders, true,
				&m_material_type, &m_colors);
			changeToMesh(mesh);
			mesh->drop();
			// mesh is pre-scaled by BS * f->visual_scale
			m_meshnode->setScale(
					def.wield_scale * WIELD_SCALE_FACTOR
					/ (BS * f.visual_scale));
		} else {
			switch (f.drawtype) {
				case NDT_AIRLIKE: {
					changeToMesh(nullptr);
					break;
				}
				case NDT_PLANTLIKE: {
					setExtruded(tsrc->getTextureName(f.tiles[0].layers[0].texture_id),
						tsrc->getTextureName(f.tiles[0].layers[1].texture_id),
						def.wield_scale, tsrc,
						f.tiles[0].layers[0].animation_frame_count);
					// Add color
					const TileLayer &l0 = f.tiles[0].layers[0];
					m_colors.emplace_back(l0.has_color, l0.color);
					const TileLayer &l1 = f.tiles[0].layers[1];
					m_colors.emplace_back(l1.has_color, l1.color);
					break;
				}
				case NDT_PLANTLIKE_ROOTED: {
					setExtruded(tsrc->getTextureName(f.special_tiles[0].layers[0].texture_id),
						"", def.wield_scale, tsrc,
						f.special_tiles[0].layers[0].animation_frame_count);
					// Add color
					const TileLayer &l0 = f.special_tiles[0].layers[0];
					m_colors.emplace_back(l0.has_color, l0.color);
					break;
				}
				case NDT_NORMAL:
				case NDT_ALLFACES:
				case NDT_LIQUID:
				case NDT_FLOWINGLIQUID: {
					setCube(f, def.wield_scale);
					break;
				}
				default: {
					mesh = createSpecialNodeMesh(client, id, &m_colors);
					changeToMesh(mesh);
					mesh->drop();
					m_meshnode->setScale(
							def.wield_scale * WIELD_SCALE_FACTOR
							/ (BS * f.visual_scale));
				}
			}
		}
		u32 material_count = m_meshnode->getMaterialCount();
		for (u32 i = 0; i < material_count; ++i) {
			video::SMaterial &material = m_meshnode->getMaterial(i);
			material.MaterialType = m_material_type;
			material.setFlag(video::EMF_BACK_FACE_CULLING, true);
			material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter);
			material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter);
		}
		return;
	}
	else if (!def.inventory_image.empty()) {
//.........这里部分代码省略.........
开发者ID:Gael-de-Sailly,项目名称:minetest,代码行数:101,代码来源:wieldmesh.cpp

示例4: clearHardwareBuffer

MapBlockMesh::MapBlockMesh(MeshMakeData *data, v3s16 camera_offset):
	clearHardwareBuffer(false),
	step(data->step),
	timestamp(data->timestamp),
	m_mesh(new scene::SMesh()),
	m_gamedef(data->m_gamedef),
	m_animation_force_timer(0), // force initial animation
	m_last_crack(-1),
	m_crack_materials(),
	m_highlighted_materials(),
	m_last_daynight_ratio((u32) -1),
	m_daynight_diffs(),
	m_usage_timer(0)
{
	m_enable_shaders = g_settings->getBool("enable_shaders");
	m_enable_highlighting = g_settings->getBool("enable_node_highlighting");

	// 4-21ms for MAP_BLOCKSIZE=16  (NOTE: probably outdated)
	// 24-155ms for MAP_BLOCKSIZE=32  (NOTE: probably outdated)
	//TimeTaker timer1("MapBlockMesh()");

	data->fill_data();

	std::vector<FastFace> fastfaces_new;

	/*
		We are including the faces of the trailing edges of the block.
		This means that when something changes, the caller must
		also update the meshes of the blocks at the leading edges.

		NOTE: This is the slowest part of this method.
	*/
	{
		// 4-23ms for MAP_BLOCKSIZE=16  (NOTE: probably outdated)
		//TimeTaker timer2("updateAllFastFaceRows()");
		updateAllFastFaceRows(data, fastfaces_new, step);
	}
	// End of slow part

	//if (data->debug) infostream<<" step="<<step<<" fastfaces_new.size="<<fastfaces_new.size()<<std::endl;

	/*
		Convert FastFaces to MeshCollector
	*/

	MeshCollector collector;

	{
		// avg 0ms (100ms spikes when loading textures the first time)
		// (NOTE: probably outdated)
		//TimeTaker timer2("MeshCollector building");

		for(u32 i=0; i<fastfaces_new.size(); i++)
		{
			FastFace &f = fastfaces_new[i];

			const u16 indices[] = {0,1,2,2,3,0};
			const u16 indices_alternate[] = {0,1,3,2,3,1};

			if(f.tile.texture == NULL)
				continue;

			const u16 *indices_p = indices;

			/*
				Revert triangles for nicer looking gradient if vertices
				1 and 3 have same color or 0 and 2 have different color.
				getRed() is the day color.
			*/
			if(f.vertices[0].Color.getRed() != f.vertices[2].Color.getRed()
					|| f.vertices[1].Color.getRed() == f.vertices[3].Color.getRed())
				indices_p = indices_alternate;

			collector.append(f.tile, f.vertices, 4, indices_p, 6);
		}
	}

	/*
		Add special graphics:
		- torches
		- flowing water
		- fences
		- whatever
	*/

	if(step <= 1)
	mapblock_mesh_generate_special(data, collector);

	m_highlight_mesh_color = data->m_highlight_mesh_color;

	/*
		Convert MeshCollector to SMesh
	*/
	ITextureSource *tsrc = m_gamedef->tsrc();
	IShaderSource *shdrsrc = m_gamedef->getShaderSource();

	for(u32 i = 0; i < collector.prebuffers.size(); i++)
	{
		PreMeshBuffer &p = collector.prebuffers[i];

//.........这里部分代码省略.........
开发者ID:gourytch,项目名称:freeminer,代码行数:101,代码来源:mapblock_mesh.cpp

示例5: void

void CNodeDefManager::updateTextures(IGameDef *gamedef,
	void (*progress_callback)(void *progress_args, u32 progress, u32 max_progress),
	void *progress_callback_args)
{
#ifndef SERVER
	infostream << "CNodeDefManager::updateTextures(): Updating "
		"textures in node definitions" << std::endl;

	ITextureSource *tsrc = gamedef->tsrc();
	IShaderSource *shdsrc = gamedef->getShaderSource();
	scene::ISceneManager* smgr = gamedef->getSceneManager();
	scene::IMeshManipulator* meshmanip = smgr->getMeshManipulator();

	bool new_style_water           = g_settings->getBool("new_style_water");
	bool new_style_leaves          = g_settings->getBool("new_style_leaves");
	bool connected_glass           = g_settings->getBool("connected_glass");
	bool opaque_water              = g_settings->getBool("opaque_water");
	bool enable_shaders            = g_settings->getBool("enable_shaders");
	bool enable_bumpmapping        = g_settings->getBool("enable_bumpmapping");
	bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");
	bool enable_mesh_cache         = g_settings->getBool("enable_mesh_cache");

	bool use_normal_texture = enable_shaders &&
		(enable_bumpmapping || enable_parallax_occlusion);

	u32 size = m_content_features.size();

	for (u32 i = 0; i < size; i++) {
		ContentFeatures *f = &m_content_features[i];

		// Figure out the actual tiles to use
		TileDef tiledef[6];
		for (u32 j = 0; j < 6; j++) {
			tiledef[j] = f->tiledef[j];
			if (tiledef[j].name == "")
				tiledef[j].name = "unknown_node.png";
		}

		bool is_liquid = false;
		bool is_water_surface = false;

		u8 material_type = (f->alpha == 255) ?
			TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;

		switch (f->drawtype) {
		default:
		case NDT_NORMAL:
			f->solidness = 2;
			break;
		case NDT_AIRLIKE:
			f->solidness = 0;
			break;
		case NDT_LIQUID:
			assert(f->liquid_type == LIQUID_SOURCE);
			if (opaque_water)
				f->alpha = 255;
			if (new_style_water){
				f->solidness = 0;
			} else {
				f->solidness = 1;
				f->backface_culling = false;
			}
			is_liquid = true;
			break;
		case NDT_FLOWINGLIQUID:
			assert(f->liquid_type == LIQUID_FLOWING);
			f->solidness = 0;
			if (opaque_water)
				f->alpha = 255;
			is_liquid = true;
			break;
		case NDT_GLASSLIKE:
			f->solidness = 0;
			f->visual_solidness = 1;
			break;
		case NDT_GLASSLIKE_FRAMED:
			f->solidness = 0;
			f->visual_solidness = 1;
			break;
		case NDT_GLASSLIKE_FRAMED_OPTIONAL:
			f->solidness = 0;
			f->visual_solidness = 1;
			f->drawtype = connected_glass ? NDT_GLASSLIKE_FRAMED : NDT_GLASSLIKE;
			break;
		case NDT_ALLFACES:
			f->solidness = 0;
			f->visual_solidness = 1;
			break;
		case NDT_ALLFACES_OPTIONAL:
			if (new_style_leaves) {
				f->drawtype = NDT_ALLFACES;
				f->solidness = 0;
				f->visual_solidness = 1;
			} else {
				f->drawtype = NDT_NORMAL;
				f->solidness = 2;
				for (u32 i = 0; i < 6; i++)
					tiledef[i].name += std::string("^[noalpha");
			}
			if (f->waving == 1)
//.........这里部分代码省略.........
开发者ID:4aiman,项目名称:MultiCraft,代码行数:101,代码来源:nodedef.cpp

示例6: setItem

void WieldMeshSceneNode::setItem(const ItemStack &item, Client *client)
{
	ITextureSource *tsrc = client->getTextureSource();
	IItemDefManager *idef = client->getItemDefManager();
	IShaderSource *shdrsrc = client->getShaderSource();
	INodeDefManager *ndef = client->getNodeDefManager();
	const ItemDefinition &def = item.getDefinition(idef);
	const ContentFeatures &f = ndef->get(def.name);
	content_t id = ndef->getId(def.name);

	if (m_enable_shaders) {
		u32 shader_id = shdrsrc->getShader("wielded_shader", TILE_MATERIAL_BASIC, NDT_NORMAL);
		m_material_type = shdrsrc->getShaderInfo(shader_id).material;
	}
	m_colors.clear();

	// If wield_image is defined, it overrides everything else
	if (def.wield_image != "") {
		setExtruded(def.wield_image, def.wield_scale, tsrc, 1);
		return;
	}
	// Handle nodes
	// See also CItemDefManager::createClientCached()
	else if (def.type == ITEM_NODE) {
		if (f.mesh_ptr[0]) {
			// e.g. mesh nodes and nodeboxes
			changeToMesh(f.mesh_ptr[0]);
			// mesh_ptr[0] is pre-scaled by BS * f->visual_scale
			m_meshnode->setScale(
					def.wield_scale * WIELD_SCALE_FACTOR
					/ (BS * f.visual_scale));
		} else if (f.drawtype == NDT_AIRLIKE) {
			changeToMesh(NULL);
		} else if (f.drawtype == NDT_PLANTLIKE) {
			setExtruded(tsrc->getTextureName(f.tiles[0].texture_id), def.wield_scale, tsrc, f.tiles[0].animation_frame_count);
		} else if (f.drawtype == NDT_NORMAL || f.drawtype == NDT_ALLFACES) {
			setCube(f.tiles, def.wield_scale, tsrc);
		} else {
			MeshMakeData mesh_make_data(client, false);
			MapNode mesh_make_node(id, 255, 0);
			mesh_make_data.fillSingleNode(&mesh_make_node);
			MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
			changeToMesh(mapblock_mesh.getMesh());
			translateMesh(m_meshnode->getMesh(), v3f(-BS, -BS, -BS));
			m_meshnode->setScale(
					def.wield_scale * WIELD_SCALE_FACTOR
					/ (BS * f.visual_scale));
		}
		u32 material_count = m_meshnode->getMaterialCount();
		if (material_count > 6) {
			errorstream << "WieldMeshSceneNode::setItem: Invalid material "
				"count " << material_count << ", truncating to 6" << std::endl;
			material_count = 6;
		}
		for (u32 i = 0; i < material_count; ++i) {
			const TileSpec *tile = &(f.tiles[i]);
			video::SMaterial &material = m_meshnode->getMaterial(i);
			material.setFlag(video::EMF_BACK_FACE_CULLING, true);
			material.setFlag(video::EMF_BILINEAR_FILTER, m_bilinear_filter);
			material.setFlag(video::EMF_TRILINEAR_FILTER, m_trilinear_filter);
			bool animated = (tile->animation_frame_count > 1);
			if (animated) {
				FrameSpec animation_frame = tile->frames[0];
				material.setTexture(0, animation_frame.texture);
			} else {
				material.setTexture(0, tile->texture);
			}
			m_colors.push_back(tile->color);
			material.MaterialType = m_material_type;
			if (m_enable_shaders) {
				if (tile->normal_texture) {
					if (animated) {
						FrameSpec animation_frame = tile->frames[0];
						material.setTexture(1, animation_frame.normal_texture);
					} else {
						material.setTexture(1, tile->normal_texture);
					}
				}
				material.setTexture(2, tile->flags_texture);
			}
		}
		return;
	}
	else if (def.inventory_image != "") {
		setExtruded(def.inventory_image, def.wield_scale, tsrc, 1);
		return;
	}

	// no wield mesh found
	changeToMesh(NULL);
}
开发者ID:DomtronVox,项目名称:minetest,代码行数:91,代码来源:wieldmesh.cpp

示例7: myrand_range

bool MapBlockMesh::animate(bool faraway, float time, int crack, u32 daynight_ratio)
{
	bool enable_shaders = g_settings->getBool("enable_shaders");
	bool enable_bumpmapping = g_settings->getBool("enable_bumpmapping");
	bool enable_parallax_occlusion = g_settings->getBool("enable_parallax_occlusion");

	if(!m_has_animation)
	{
		m_animation_force_timer = 100000;
		return false;
	}

	m_animation_force_timer = myrand_range(5, 100);

	// Cracks
	if(crack != m_last_crack)
	{
		for(std::map<u32, std::string>::iterator
				i = m_crack_materials.begin();
				i != m_crack_materials.end(); i++)
		{
			scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
			std::string basename = i->second;

			// Create new texture name from original
			ITextureSource *tsrc = m_gamedef->getTextureSource();
			std::ostringstream os;
			os<<basename<<crack;
			u32 new_texture_id = 0;
			video::ITexture *new_texture =
				tsrc->getTexture(os.str(), &new_texture_id);
			buf->getMaterial().setTexture(0, new_texture);

			// If the current material is also animated,
			// update animation info
			std::map<u32, TileSpec>::iterator anim_iter =
				m_animation_tiles.find(i->first);
			if(anim_iter != m_animation_tiles.end()){
				TileSpec &tile = anim_iter->second;
				tile.texture = new_texture;
				tile.texture_id = new_texture_id;
				// force animation update
				m_animation_frames[i->first] = -1;
			}
		}

		m_last_crack = crack;
	}

	// Texture animation
	for(std::map<u32, TileSpec>::iterator
			i = m_animation_tiles.begin();
			i != m_animation_tiles.end(); i++)
	{
		const TileSpec &tile = i->second;
		// Figure out current frame
		int frameoffset = m_animation_frame_offsets[i->first];
		int frame = (int)(time * 1000 / tile.animation_frame_length_ms
				+ frameoffset) % tile.animation_frame_count;
		// If frame doesn't change, skip
		if(frame == m_animation_frames[i->first])
			continue;

		m_animation_frames[i->first] = frame;

		scene::IMeshBuffer *buf = m_mesh->getMeshBuffer(i->first);
		ITextureSource *tsrc = m_gamedef->getTextureSource();
		IShaderSource *shdrsrc = m_gamedef->getShaderSource();

		// Create new texture name from original
		std::ostringstream os(std::ios::binary);
		os<<tsrc->getTextureName(tile.texture_id);
		os<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
		// Set the texture
		buf->getMaterial().setTexture(0, tsrc->getTexture(os.str()));
		if (enable_shaders){
			buf->getMaterial().setTexture(2, tsrc->getTexture("disable_img.png"));
			buf->getMaterial().MaterialType = shdrsrc->getShaderInfo(tile.shader_id).material;
			if (enable_bumpmapping || enable_parallax_occlusion){
				if (tsrc->isKnownSourceImage("override_normal.png")){
					buf->getMaterial().setTexture(1, tsrc->getTexture("override_normal.png"));
					buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
				} else {
					std::string fname_base,fname_normal;
					fname_base = tsrc->getTextureName(tile.texture_id);
					unsigned pos;
					pos = fname_base.find(".");
					fname_normal = fname_base.substr (0, pos);
					fname_normal += "_normal.png";
					if (tsrc->isKnownSourceImage(fname_normal)){
						os.str("");
						os<<fname_normal<<"^[verticalframe:"<<(int)tile.animation_frame_count<<":"<<frame;
						buf->getMaterial().setTexture(1, tsrc->getTexture(os.str()));
						buf->getMaterial().setTexture(2, tsrc->getTexture("enable_img.png"));
					}
				}
			}
		}
	}

//.........这里部分代码省略.........
开发者ID:iamnerotic,项目名称:minetest,代码行数:101,代码来源:mapblock_mesh.cpp

示例8: OnPrepare

void IShader::OnPrepare(IRender& render) {
	IShaderSource* source = render.QueryShaderSource(QueryUnique().info->typeName);
	assert(source != NULL);
	source->Apply(*this);
}
开发者ID:paintdream,项目名称:PaintsNow,代码行数:5,代码来源:IShader.cpp


注:本文中的IShaderSource类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。