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


C++ IRenderable类代码示例

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


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

示例1: render

void CompositeRenderable::render(GLenum renderingMode)
{
    for (vector<IRenderable*>::iterator it = components.begin() ; it < components.end() ; it++) {
        IRenderable* target = *it;
        target->fullRender(renderingMode);
    }
}
开发者ID:ofavre,项目名称:Breach,代码行数:7,代码来源:renderable.cpp

示例2: OnUpdateShaderParameters

	bool LambertShader::OnUpdateShaderParameters(unsigned int pass, IRenderable& renderable, const Camera& camera)
	{
		(void)pass;

		// Texture
		const TexturePtr texture = renderable.GetTexture();
		if (texture)
		{
			if (!m_paramTexture->SetValue(*texture))
				return false;
		}

		// World
		const Matrix4& worldMat = renderable.GetWorldMatrix();
		if (!m_paramWorld->SetValue(worldMat))
			return false;

		// WorldInverseTranspose
		if (!m_paramWorldInvTrans->SetValue(worldMat.Invert().Transpose()))
			return false;

		// WorldViewProjection
		const Matrix4 wvpMat = worldMat * 
			camera.GetViewMatrix() *
			camera.GetProjectionMatrix();

		if (!m_paramWorldViewProj->SetValue(wvpMat))
			return false;

		return true;
	}
开发者ID:likeleon,项目名称:skengine,代码行数:31,代码来源:SkLambertShader.cpp

示例3: FOR_EACH_SIZE

void IRenderQueue::PrintRenderQueue(const RenderableNodeList& nodes)
{
	HeapString testStr;
	size_t count = nodes.Count();
	FOR_EACH_SIZE(i, count)
	{
		IRenderable* node = (IRenderable*)nodes[i];
		testStr.AppendFormat("{}:{}:{}\n", node->Id(), node->Material()->Name().c_str(), node->Name().c_str());
	}
开发者ID:johndpope,项目名称:Medusa,代码行数:9,代码来源:IRenderQueue.cpp

示例4: AddNodeToBuffer

void BaseBufferRenderBatch::AddNodeToBuffer(uint& refVertexIndex, uint& refIndexIndex, IRenderable& node)
{
	auto mesh = node.Mesh();
	const Matrix4& newMatrix = node.WorldMatrix();

	mesh->AddToVertexBufferObject(mVertexBufferObject, refVertexIndex,  newMatrix);
	mesh->AddToNormalBufferObject(mNormalBufferObject, refVertexIndex,  newMatrix);
	mesh->AddToTexCoordBufferObject(mTexcoordBufferObject, refVertexIndex);
	mesh->AddToColorBufferObject(mColorBufferObject, refVertexIndex, node.WorldColor());
	mesh->AddToIndexBufferObject(mIndexBufferObject, refVertexIndex, refIndexIndex);

	uintp vertexCount = mesh->VertexCount();
	uintp indexCount = mesh->IndexCount();
	node.SetBatch(this, refVertexIndex, (uint)vertexCount, refIndexIndex, (uint)indexCount);
	refVertexIndex += (uint)vertexCount;
	refIndexIndex += (uint)indexCount;
	RenderingStatics::Instance().IncreaseChangedNodeCount();

}
开发者ID:fjz13,项目名称:Medusa,代码行数:19,代码来源:BaseBufferRenderBatch.cpp

示例5: RETURN_IF_EQUAL

void BaseSingleBatchRenderQueue::Update(RenderableChangedFlags changedFlag)
{
	RETURN_IF_EQUAL(changedFlag, RenderableChangedFlags::None);

	if (changedFlag.IsBatchChanged()||changedFlag.IsRenderQueueChanged())
	{
		mBatch->Prepare();
		if (!mNodes.IsEmpty())
		{
			IRenderable* node = mNodes.First();
			mBatch->SetEffect(node->Material()->Effect());
			mBatch->SetMaterial(node->Material());
			mBatch->SetDrawMode(node->Material()->DrawMode());
			mBatch->SetStateTreeNode(node->RenderStateTreeNode());
		}

		FOR_EACH_COLLECTION(i, mNodes)
		{
			mBatch->AddNode(*i);
		}
开发者ID:johndpope,项目名称:Medusa,代码行数:20,代码来源:BaseSingleBatchRenderQueue.cpp

示例6: Render

void Graphics::Render(IRenderable &renderable)
{
	Shader.setModel(renderable.getTransformation());
	CheckGlErrors();
	GLuint texture = renderable.getTexture();
	CheckGlErrors();
	if(LastTexture != texture)
	{
		glActiveTexture(GL_TEXTURE0);
		CheckGlErrors();
		glBindTexture(GL_TEXTURE_2D, texture);
		CheckGlErrors();
		Shader.setTexture(0);
		CheckGlErrors();
		LastTexture = texture;
	}

	glDrawArrays(GL_TRIANGLES, 0, 6);		
	CheckGlErrors();
}
开发者ID:AndriusDap,项目名称:SDL2,代码行数:20,代码来源:Graphics.cpp

示例7: UpdateNodeToBuffer

void BaseBufferRenderBatch::UpdateNodeToBuffer(uint& refVertexIndex, uint& refIndexIndex, IRenderable& node, RenderableChangedFlags changedFlags)
{
	auto mesh = node.Mesh();
	if (MEDUSA_FLAG_HAS(changedFlags,RenderableChangedFlags::NewVertex))
	{
		const Matrix4& newMatrix = node.WorldMatrix();
		mesh->AddToVertexBufferObject(mVertexBufferObject, refVertexIndex,  newMatrix);
	}

	if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewNormal))
	{
		const Matrix4& newMatrix = node.WorldMatrix();
		mesh->AddToNormalBufferObject(mNormalBufferObject, refVertexIndex,  newMatrix);
	}

	if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewTexCoord))
	{
		mesh->AddToTexCoordBufferObject(mTexcoordBufferObject, refVertexIndex);
	}

	if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewColor))
	{
		mesh->AddToColorBufferObject(mColorBufferObject, refVertexIndex, node.WorldColor());
	}

	if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewIndex))
	{
		mesh->AddToIndexBufferObject(mIndexBufferObject, refVertexIndex, refIndexIndex);
	}

	uintp vertexCount = mesh->VertexCount();
	uintp indexCount = mesh->IndexCount();
	node.SetBatch(this, refVertexIndex, (uint)vertexCount, refIndexIndex, (uint)indexCount);
	refVertexIndex += (uint)vertexCount;
	refIndexIndex += (uint)indexCount;
	RenderingStatics::Instance().IncreaseChangedNodeCount();
}
开发者ID:fjz13,项目名称:Medusa,代码行数:37,代码来源:BaseBufferRenderBatch.cpp

示例8: renderObject

void renderObject(IRenderable& object, glm::mat4 mvp, uint32_t matrix)
{
    auto mesh = dynamic_cast<MeshComponent*>(&object.ComponentsForTag(MeshComponent::TAG)[0]);
    auto transform = dynamic_cast<TransformComponent*>(&object.ComponentsForTag(TransformComponent::TAG)[0]);
    auto vbuffer = dynamic_cast<GLVertexBuffer*>(mesh->vertexBuffer.get());

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbuffer->vbo);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, vbuffer->cbo);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glUniformMatrix4fv(matrix, 1, GL_FALSE, &mvp[0][0]);
    glDrawArrays(GL_TRIANGLES, 0, 12 * 3);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);

    for (IRenderable child : object.children.begin)
    {
        renderObject(child, mvp, matrix);
    }
}
开发者ID:berwyn,项目名称:GameExperiment,代码行数:24,代码来源:Triangle.cpp

示例9: Render

void AnimatedObject::Render(void){
	IRenderable *currMesh = dynamic_cast<IRenderable *>(GetMember(frameNames[currentFrame]));

	if (currMesh != 0) currMesh->Render();
}
开发者ID:LuckiiGoggy,项目名称:OpenGL-Game,代码行数:5,代码来源:AnimatedObject.cpp

示例10: if

void
Font::createSentenceRenderable(IRenderable &renderable, std::string sentence)
{
	assert(mMaterialName != "");

	int aux = sentence.length();
	int size = 0;

	for (int count = 0; count < aux; count++) {
	
		// if char exists in the font definition
		if (mChars.count(sentence[count])) 
			size++;
	}

	assert(size);

	// need to clear previous mesh 
	//Mesh *renderable = (Mesh *)RESOURCEMANAGER->createRenderable("Mesh", sentence, "Sentence");
	//renderable->setDrawingPrimitive(curitiba::render::IRenderer::TRIANGLES);

	std::vector<VertexData::Attr> *vertices = new std::vector<VertexData::Attr>(size*6);
	std::vector<VertexData::Attr> *texCoords = new std::vector<VertexData::Attr>(size*6);
	std::vector<VertexData::Attr> *normals = new std::vector<VertexData::Attr>(size*6);



	int i = 0;
	float hDisp = 0.0f, vDisp = 0.0f;

	for (int count = 0; count < aux; count++) {
	
		// get char at position count
		char c = sentence[count];
		if (c == ' ') {
			if (mFixedSize)
				hDisp += mChars[c].C + mChars[c].A; 
			else
				hDisp += mChars[c].C;	
		}
		// if char exists in the font definition
		else if (mChars.count(c)) {
			vertices->at(6*i  ).set(hDisp, vDisp + mHeight, 0.0f, 1.0f);
			vertices->at(6*i+1).set(hDisp + mChars[c].width, vDisp, 0.0f, 1.0f);
			vertices->at(6*i+2).set(hDisp, vDisp, 0.0f, 1.0f);			
			vertices->at(6*i+3).set(hDisp + mChars[c].width, vDisp, 0.0f, 1.0f);			
			vertices->at(6*i+4).set(hDisp, vDisp + mHeight,0.0f, 1.0f);			
			vertices->at(6*i+5).set(hDisp + mChars[c].width, vDisp + mHeight, 0.0f, 1.0f);		

			normals->at(6*i    ).set(0,0,1);
			normals->at(6*i+1  ).set(0,0,1);
			normals->at(6*i+2  ).set(0,0,1);
			normals->at(6*i+3  ).set(0,0,1);
			normals->at(6*i+4  ).set(0,0,1);
			normals->at(6*i+5  ).set(0,0,1);

			texCoords->at(6*i  ).set(mChars[c].x1, 1-mChars[c].y2, 0.0f, 1.0f);
			texCoords->at(6*i+1).set(mChars[c].x2, 1-mChars[c].y1, 0.0f, 1.0f);
			texCoords->at(6*i+2).set(mChars[c].x1, 1-mChars[c].y1, 0.0f, 1.0f);
			texCoords->at(6*i+3).set(mChars[c].x2, 1-mChars[c].y1, 0.0f, 1.0f);
			texCoords->at(6*i+4).set(mChars[c].x1, 1-mChars[c].y2, 0.0f, 1.0f);
			texCoords->at(6*i+5).set(mChars[c].x2, 1-mChars[c].y2, 0.0f, 1.0f);

			if (mFixedSize)
				hDisp += mChars[c].C + mChars[c].A; 
			else
				hDisp += mChars[c].C;
			i++;
		}
		// newline
		else if (c == '\n') {
			vDisp += mHeight;
			hDisp = 0.0f;
		}
	}

	VertexData &vertexData = renderable.getVertexData();
	vertexData.setDataFor (VertexData::getAttribIndex("position"), vertices);
	vertexData.setDataFor (VertexData::getAttribIndex("normal"), normals);
	vertexData.setDataFor (VertexData::getAttribIndex("texCoord0"), texCoords);

	std::vector<unsigned int> *indices = new std::vector<unsigned int>(size*6);
	for (int j = 0; j < size*6 ; j++)
		indices->push_back(j);

	MaterialGroup* auxMG;

	std::vector<IMaterialGroup *> aMatG = renderable.getMaterialGroups();
	if (aMatG.size()) {
		auxMG = (MaterialGroup *)aMatG[0];
		auxMG->setIndexList (indices);
	}
	else {
		auxMG = new MaterialGroup();
		auxMG->setMaterialName(mMaterialName);
		auxMG->setParent(&renderable);
		auxMG->setIndexList (indices);
		renderable.addMaterialGroup(auxMG);
	}
}
开发者ID:pspkzar,项目名称:Ray-Tracing-plus-Rasterization,代码行数:100,代码来源:font.cpp

示例11: TAL_SCOPED_TASK_NAMED


//.........这里部分代码省略.........
			set_Object							(0);
			g_hud->Render_First					( );	// R1 shadows
			g_hud->Render_Last					( );	
			u32 uID_LTRACK						= 0xffffffff;
			if (phase==PHASE_NORMAL)			{
				uLastLTRACK	++;
				if (lstRenderables.size())		uID_LTRACK	= uLastLTRACK%lstRenderables.size();

				// update light-vis for current entity / actor
				CObject*	O					= g_pGameLevel->CurrentViewEntity();
				if (O)		{
					CROS_impl*	R					= (CROS_impl*) O->ROS();
					if (R)		R->update			(O);
				}
			}
			for (u32 o_it=0; o_it<lstRenderables.size(); o_it++)
			{
				ISpatial*	spatial		= lstRenderables[o_it];		spatial->spatial_updatesector	();
				CSector*	sector		= (CSector*)spatial->spatial.sector	;
				if	(0==sector)										
					continue;	// disassociated from S/P structure

				// Filter only not light spatial
				if	(PortalTraverser.i_marker != sector->r_marker && (spatial->spatial.type & STYPE_RENDERABLE) )	continue;	// inactive (untouched) sector

				if (spatial->spatial.type & STYPE_RENDERABLE)
				{
					for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)
					{
						set_Frustum			(&(sector->r_frustums[v_it]));

						if (!View->testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R) /*&& (spatial->spatial.type & STYPE_RENDERABLE)*/)	continue;
						// renderable
						IRenderable*	renderable		= spatial->dcast_Renderable	();
						if (0==renderable)	{
							// It may be an glow
							CGlow*		glow				= dynamic_cast<CGlow*>(spatial);
							VERIFY							(glow);
							L_Glows->add					(glow);
						} else {
							// Occlusiond
							vis_data&		v_orig			= renderable->renderable.visual->getVisData();
							vis_data		v_copy			= v_orig;
							v_copy.box.xform				(renderable->renderable.xform);
							BOOL			bVisible		= HOM.visible(v_copy);
							v_orig.accept_frame				= v_copy.accept_frame;
							v_orig.marker					= v_copy.marker;
							v_orig.hom_frame				= v_copy.hom_frame;
							v_orig.hom_tested				= v_copy.hom_tested;
							if (!bVisible)					break;	// exit loop on frustums

							// rendering
							if (o_it==uID_LTRACK && renderable->renderable_ROS())	{
								// track lighting environment
								CROS_impl*		T = (CROS_impl*)renderable->renderable_ROS();
								T->update			(renderable);
							}
							set_Object						(renderable);
							renderable->renderable_Render	();
							set_Object						(0);	//? is it needed at all
						}
						break;	// exit loop on frustums
					}
				} 
				else
				{
开发者ID:2asoft,项目名称:xray-16,代码行数:67,代码来源:FStaticRender.cpp

示例12: IsAvailableFor

bool IRenderBatch::IsAvailableFor(const IRenderable& node) const
{
	IMesh* mesh = node.Mesh();
	return IsAvailableFor(mesh->VertexCount(), mesh->IndexCount());
}
开发者ID:johndpope,项目名称:Medusa,代码行数:5,代码来源:IRenderBatch.cpp

示例13: SUBSYSTEMX

/**
* renderlmpl for edge hight light and blur
* @ param IRenderSystem for set render state or texture.., SceneManger for ger render queue and so on
* @ return null
* @ flow: render target-> render state->setupStream-> setTexture-> setTechnique->begin pass->end pass
* @ author Milong.Wu 
*/
void EdgeblurPostEffect::renderImpl( IRenderSystem* pRenderSys, SceneManager* scene )
{
	if(!postEffect) 
		return;

	SceneManager * scenemgr = SUBSYSTEMX(SceneManager,ISceneManager);
	SceneRender * scenerender = scenemgr->getSceneRender(); 
	StagedForwardSceneRender *Stagescenerender=(StagedForwardSceneRender*)scenerender ;

	const RenderQueue::RenderableList& highItems =(*Stagescenerender).specialRenderQueue.getRenderableList((RenderQueueOrder)StagedForwardSceneRender::RENDER_QUEUE_HIGHLIGHT);
	if (highItems.size() <= 0)
		return ;

	uint blurRTT1 = scene->currentView->getFullRGBRTT1();
	uint blurRTT2 = scene->currentView->getFullRGBRTT2();
	float viewSizeFactor = 0.5f;

	if(blurRTT1 == 0 || blurRTT2 == 0)
		return;
	int numRendered = 0;

	uint oldTarget = pRenderSys->getCurrentRenderTarget();

	pRenderSys->setCurrentRenderTarget(blurRTT1);
    // so the unsee part can't be hightlihght
	pRenderSys->setDepthBufferCheckEnabled(true);
	pRenderSys->setDepthBufferFunction(CMP_LESSEQUAL);
	pRenderSys->setDepthBufferWriteEnabled(false);
	pRenderSys->setCullingMode(CULL_NONE);
	//setup common rendering state
	pRenderSys->clearFrameBuffer(ColorValue(0,0,0,0), 1.0f);

	setupRenderingState(pRenderSys);
	//get highlight queue
	
	int colorID = 0;
	int idCount = 0;
	FillMode oldFillMode = pRenderSys->getFillMode();
	bool highlight = false;

	for(size_t qi = 0; qi <highItems.size()  && colorID <Stagescenerender->highLights.num(); ++qi)
	{
		highlight = true;
		IRenderable *renderable = highItems[qi];
		const Appearance& appear = renderable->getAppearance();
		Appearance::Geometry  geo = appear.geometry;
		geo.indexBuffer =  appear.geometry.indexBuffer;     
		if(appear.material[eMaterial_0].renderOrder < RENDER_QUEUE_BLEND && geo.indexBuffer)
		{
			appear.geometry.setupStream(pRenderSys);
			//edgeColor and rimback_biggerFactor  are uniform values defined in this pass of edgeblur.fx (../date/shader) file
			postEffect->setupAutoParameters(renderable);
			postEffect->setVector4("edgeColor", (Vector4*)(&Stagescenerender->highLights(colorID).color));  
			ColorValue *ed = (ColorValue*)(&Stagescenerender->highLights(colorID).color);
			setupRenderingState(pRenderSys);  

			if(appear.material[eMaterial_0].numTextureUnit)
				appear.material[eMaterial_0].setTextureUnit(pRenderSys,0);
			else
				pRenderSys->setTexture(0, 0); 

			//postEffect->setupAutoParameters(renderable);
			uint iPass;
			//"Rimback" is defined in edgeblur.fx (../date/shader) file
			int macAcount=0;
			const EffectMacro *mac = postEffect->getMacros(macAcount);

			// for the weapon can not be paint, as no maco, so use a special technique
			if(geo.isSkinning())
			{
				postEffect->setTechnique("Rimback");
			}
			else{
				postEffect->setTechnique("RimbackNomaco");
			}
			postEffect->begin(&iPass);
			postEffect->beginPass(0);
			pRenderSys->drawRangeIndexedPrimitive(PT_TRIANGLES, geo.indexBuffer->getType(),geo.indexStart,geo.indexCount,geo.vertexStart,geo.vertexEnd);
			postEffect->endPass();
			postEffect->end();
			appear.geometry.resetStream(pRenderSys);
		}
		idCount++;
		if(idCount >= Stagescenerender->highLights(colorID).numRenderable)
		{
			colorID++;
			idCount = 0;
		}
	}

	if(highlight)
	{
		pRenderSys->setCurrentRenderTarget(blurRTT2);
//.........这里部分代码省略.........
开发者ID:codeAPmind,项目名称:Edgeblur,代码行数:101,代码来源:EdgeblurPostEffect.cpp

示例14: RenderObject

void RenderManager::RenderObject(IRenderable& renderable) {
    renderable.Render(al_get_backbuffer(_display_context));
}
开发者ID:cugone,项目名称:Abrams2015,代码行数:3,代码来源:CRenderManager.cpp

示例15: inactive

// sub-space rendering - main procedure
void	R_dsgraph_structure::r_dsgraph_render_subspace	(IRender_Sector* _sector, CFrustum* _frustum, Fmatrix& mCombined, Fvector& _cop, BOOL _dynamic, BOOL _precise_portals)
{
	VERIFY							(_sector);
	RImplementation.marker			++;			// !!! critical here

	// Save and build new frustum, disable HOM
	CFrustum	ViewSave			= ViewBase;
	ViewBase						= *_frustum;
	View							= &ViewBase;

	if (_precise_portals && RImplementation.rmPortals)		{
		// Check if camera is too near to some portal - if so force DualRender
		Fvector box_radius;		box_radius.set	(EPS_L*20,EPS_L*20,EPS_L*20);
		RImplementation.Sectors_xrc.box_options	(CDB::OPT_FULL_TEST);
		RImplementation.Sectors_xrc.box_query	(RImplementation.rmPortals,_cop,box_radius);
		for (int K=0; K<RImplementation.Sectors_xrc.r_count(); K++)
		{
			CPortal*	pPortal		= (CPortal*) RImplementation.Portals[RImplementation.rmPortals->get_tris()[RImplementation.Sectors_xrc.r_begin()[K].id].dummy];
			pPortal->bDualRender	= TRUE;
		}
	}

	// Traverse sector/portal structure
	PortalTraverser.traverse		( _sector, ViewBase, _cop, mCombined, 0 );

	// Determine visibility for static geometry hierrarhy
	for (u32 s_it=0; s_it<PortalTraverser.r_sectors.size(); s_it++)
	{
		CSector*	sector		= (CSector*)PortalTraverser.r_sectors[s_it];
		IRender_Visual*	root	= sector->root();
		for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)	{
			set_Frustum			(&(sector->r_frustums[v_it]));
			add_Geometry		(root);
		}
	}

	if (_dynamic)
	{
		set_Object						(0);

		// Traverse object database
		g_SpatialSpace->q_frustum
			(
			lstRenderables,
			ISpatial_DB::O_ORDERED,
			STYPE_RENDERABLE,
			ViewBase
			);

		// Determine visibility for dynamic part of scene
		for (u32 o_it=0; o_it<lstRenderables.size(); o_it++)
		{
			ISpatial*	spatial		= lstRenderables[o_it];
			CSector*	sector		= (CSector*)spatial->spatial.sector;
			if	(0==sector)										continue;	// disassociated from S/P structure
			if	(PortalTraverser.i_marker != sector->r_marker)	continue;	// inactive (untouched) sector
			for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++)
			{
				set_Frustum			(&(sector->r_frustums[v_it]));
				if (!View->testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R))	continue;

				// renderable
				IRenderable*	renderable		= spatial->dcast_Renderable	();
				if (0==renderable)				continue;					// unknown, but renderable object (r1_glow???)

				renderable->renderable_Render	();
			}
		}
	}

	// Restore
	ViewBase						= ViewSave;
	View							= 0;
}
开发者ID:OLR-xray,项目名称:XRay-NEW,代码行数:75,代码来源:r__dsgraph_render.cpp


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